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.app.ActivityManager.UidFrozenStateChangedCallback.UID_FROZEN_STATE_FROZEN; 34 import static android.app.ActivityManager.UidFrozenStateChangedCallback.UID_FROZEN_STATE_UNFROZEN; 35 import static android.app.PendingIntent.FLAG_IMMUTABLE; 36 import static android.content.Intent.ACTION_PACKAGE_ADDED; 37 import static android.content.Intent.ACTION_PACKAGE_REMOVED; 38 import static android.content.Intent.ACTION_PACKAGE_REPLACED; 39 import static android.content.Intent.ACTION_USER_ADDED; 40 import static android.content.Intent.ACTION_USER_REMOVED; 41 import static android.content.pm.PackageInfo.REQUESTED_PERMISSION_GRANTED; 42 import static android.content.pm.PackageManager.FEATURE_ETHERNET; 43 import static android.content.pm.PackageManager.FEATURE_WIFI; 44 import static android.content.pm.PackageManager.FEATURE_WIFI_DIRECT; 45 import static android.content.pm.PackageManager.GET_PERMISSIONS; 46 import static android.content.pm.PackageManager.PERMISSION_DENIED; 47 import static android.content.pm.PackageManager.PERMISSION_GRANTED; 48 import static android.net.ConnectivityManager.ACTION_CAPTIVE_PORTAL_SIGN_IN; 49 import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_DATA_SAVER; 50 import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_MASK; 51 import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_USER_RESTRICTED; 52 import static android.net.ConnectivityManager.BLOCKED_REASON_BATTERY_SAVER; 53 import static android.net.ConnectivityManager.BLOCKED_REASON_NONE; 54 import static android.net.ConnectivityManager.CONNECTIVITY_ACTION; 55 import static android.net.ConnectivityManager.EXTRA_NETWORK_INFO; 56 import static android.net.ConnectivityManager.EXTRA_NETWORK_TYPE; 57 import static android.net.ConnectivityManager.FIREWALL_CHAIN_DOZABLE; 58 import static android.net.ConnectivityManager.FIREWALL_CHAIN_LOW_POWER_STANDBY; 59 import static android.net.ConnectivityManager.FIREWALL_CHAIN_OEM_DENY_1; 60 import static android.net.ConnectivityManager.FIREWALL_CHAIN_OEM_DENY_2; 61 import static android.net.ConnectivityManager.FIREWALL_CHAIN_OEM_DENY_3; 62 import static android.net.ConnectivityManager.FIREWALL_CHAIN_POWERSAVE; 63 import static android.net.ConnectivityManager.FIREWALL_CHAIN_RESTRICTED; 64 import static android.net.ConnectivityManager.FIREWALL_CHAIN_STANDBY; 65 import static android.net.ConnectivityManager.FIREWALL_RULE_ALLOW; 66 import static android.net.ConnectivityManager.FIREWALL_RULE_DEFAULT; 67 import static android.net.ConnectivityManager.FIREWALL_RULE_DENY; 68 import static android.net.ConnectivityManager.PROFILE_NETWORK_PREFERENCE_DEFAULT; 69 import static android.net.ConnectivityManager.PROFILE_NETWORK_PREFERENCE_ENTERPRISE; 70 import static android.net.ConnectivityManager.PROFILE_NETWORK_PREFERENCE_ENTERPRISE_BLOCKING; 71 import static android.net.ConnectivityManager.PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK; 72 import static android.net.ConnectivityManager.TYPE_ETHERNET; 73 import static android.net.ConnectivityManager.TYPE_MOBILE; 74 import static android.net.ConnectivityManager.TYPE_MOBILE_FOTA; 75 import static android.net.ConnectivityManager.TYPE_MOBILE_MMS; 76 import static android.net.ConnectivityManager.TYPE_MOBILE_SUPL; 77 import static android.net.ConnectivityManager.TYPE_PROXY; 78 import static android.net.ConnectivityManager.TYPE_VPN; 79 import static android.net.ConnectivityManager.TYPE_WIFI; 80 import static android.net.ConnectivitySettingsManager.PRIVATE_DNS_MODE_OFF; 81 import static android.net.ConnectivitySettingsManager.PRIVATE_DNS_MODE_OPPORTUNISTIC; 82 import static android.net.ConnectivitySettingsManager.PRIVATE_DNS_MODE_PROVIDER_HOSTNAME; 83 import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_DNS; 84 import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_FALLBACK; 85 import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_HTTP; 86 import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_HTTPS; 87 import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_PRIVDNS; 88 import static android.net.INetworkMonitor.NETWORK_VALIDATION_RESULT_PARTIAL; 89 import static android.net.INetworkMonitor.NETWORK_VALIDATION_RESULT_VALID; 90 import static android.net.NetworkCapabilities.NET_CAPABILITY_BIP; 91 import static android.net.NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL; 92 import static android.net.NetworkCapabilities.NET_CAPABILITY_CBS; 93 import static android.net.NetworkCapabilities.NET_CAPABILITY_DUN; 94 import static android.net.NetworkCapabilities.NET_CAPABILITY_EIMS; 95 import static android.net.NetworkCapabilities.NET_CAPABILITY_ENTERPRISE; 96 import static android.net.NetworkCapabilities.NET_CAPABILITY_FOREGROUND; 97 import static android.net.NetworkCapabilities.NET_CAPABILITY_FOTA; 98 import static android.net.NetworkCapabilities.NET_CAPABILITY_IA; 99 import static android.net.NetworkCapabilities.NET_CAPABILITY_IMS; 100 import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET; 101 import static android.net.NetworkCapabilities.NET_CAPABILITY_MMS; 102 import static android.net.NetworkCapabilities.NET_CAPABILITY_MMTEL; 103 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED; 104 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED; 105 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED; 106 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING; 107 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED; 108 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED; 109 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN; 110 import static android.net.NetworkCapabilities.NET_CAPABILITY_OEM_PAID; 111 import static android.net.NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE; 112 import static android.net.NetworkCapabilities.NET_CAPABILITY_PARTIAL_CONNECTIVITY; 113 import static android.net.NetworkCapabilities.NET_CAPABILITY_RCS; 114 import static android.net.NetworkCapabilities.NET_CAPABILITY_SUPL; 115 import static android.net.NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED; 116 import static android.net.NetworkCapabilities.NET_CAPABILITY_TRUSTED; 117 import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED; 118 import static android.net.NetworkCapabilities.NET_CAPABILITY_VSIM; 119 import static android.net.NetworkCapabilities.NET_CAPABILITY_WIFI_P2P; 120 import static android.net.NetworkCapabilities.NET_CAPABILITY_XCAP; 121 import static android.net.NetworkCapabilities.NET_ENTERPRISE_ID_1; 122 import static android.net.NetworkCapabilities.NET_ENTERPRISE_ID_2; 123 import static android.net.NetworkCapabilities.NET_ENTERPRISE_ID_3; 124 import static android.net.NetworkCapabilities.NET_ENTERPRISE_ID_4; 125 import static android.net.NetworkCapabilities.NET_ENTERPRISE_ID_5; 126 import static android.net.NetworkCapabilities.REDACT_FOR_ACCESS_FINE_LOCATION; 127 import static android.net.NetworkCapabilities.REDACT_FOR_LOCAL_MAC_ADDRESS; 128 import static android.net.NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS; 129 import static android.net.NetworkCapabilities.REDACT_NONE; 130 import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; 131 import static android.net.NetworkCapabilities.TRANSPORT_ETHERNET; 132 import static android.net.NetworkCapabilities.TRANSPORT_TEST; 133 import static android.net.NetworkCapabilities.TRANSPORT_VPN; 134 import static android.net.NetworkCapabilities.TRANSPORT_WIFI; 135 import static android.net.NetworkCapabilities.TRANSPORT_WIFI_AWARE; 136 import static android.net.NetworkScore.KEEP_CONNECTED_FOR_HANDOVER; 137 import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID; 138 import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK; 139 import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY; 140 import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY; 141 import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_TEST; 142 import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_TEST_ONLY; 143 import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_UNINITIALIZED; 144 import static android.net.Proxy.PROXY_CHANGE_ACTION; 145 import static android.net.RouteInfo.RTN_UNREACHABLE; 146 import static android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener.PREFIX_OPERATION_ADDED; 147 import static android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener.PREFIX_OPERATION_REMOVED; 148 import static android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener.VALIDATION_RESULT_FAILURE; 149 import static android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener.VALIDATION_RESULT_SUCCESS; 150 import static android.os.Process.INVALID_UID; 151 import static android.system.OsConstants.IPPROTO_TCP; 152 153 import static com.android.server.ConnectivityService.KEY_DESTROY_FROZEN_SOCKETS_VERSION; 154 import static com.android.server.ConnectivityService.MAX_NETWORK_REQUESTS_PER_SYSTEM_UID; 155 import static com.android.server.ConnectivityService.PREFERENCE_ORDER_MOBILE_DATA_PREFERERRED; 156 import static com.android.server.ConnectivityService.PREFERENCE_ORDER_OEM; 157 import static com.android.server.ConnectivityService.PREFERENCE_ORDER_PROFILE; 158 import static com.android.server.ConnectivityService.PREFERENCE_ORDER_VPN; 159 import static com.android.server.ConnectivityService.createDeliveryGroupKeyForConnectivityAction; 160 import static com.android.server.ConnectivityService.makeNflogPrefix; 161 import static com.android.server.ConnectivityServiceTestUtils.transportToLegacyType; 162 import static com.android.server.NetworkAgentWrapper.CallbackType.OnQosCallbackRegister; 163 import static com.android.server.NetworkAgentWrapper.CallbackType.OnQosCallbackUnregister; 164 import static com.android.testutils.ConcurrentUtils.await; 165 import static com.android.testutils.ConcurrentUtils.durationOf; 166 import static com.android.testutils.DevSdkIgnoreRule.IgnoreAfter; 167 import static com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo; 168 import static com.android.testutils.DevSdkIgnoreRuleKt.SC_V2; 169 import static com.android.testutils.FunctionalUtils.ignoreExceptions; 170 import static com.android.testutils.HandlerUtils.visibleOnHandlerThread; 171 import static com.android.testutils.HandlerUtils.waitForIdleSerialExecutor; 172 import static com.android.testutils.MiscAsserts.assertContainsAll; 173 import static com.android.testutils.MiscAsserts.assertContainsExactly; 174 import static com.android.testutils.MiscAsserts.assertEmpty; 175 import static com.android.testutils.MiscAsserts.assertLength; 176 import static com.android.testutils.MiscAsserts.assertRunsInAtMost; 177 import static com.android.testutils.MiscAsserts.assertSameElements; 178 import static com.android.testutils.MiscAsserts.assertThrows; 179 import static com.android.testutils.RecorderCallback.CallbackEntry.AVAILABLE; 180 import static com.android.testutils.RecorderCallback.CallbackEntry.BLOCKED_STATUS; 181 import static com.android.testutils.RecorderCallback.CallbackEntry.BLOCKED_STATUS_INT; 182 import static com.android.testutils.RecorderCallback.CallbackEntry.LINK_PROPERTIES_CHANGED; 183 import static com.android.testutils.RecorderCallback.CallbackEntry.LOSING; 184 import static com.android.testutils.RecorderCallback.CallbackEntry.LOST; 185 import static com.android.testutils.RecorderCallback.CallbackEntry.NETWORK_CAPS_UPDATED; 186 import static com.android.testutils.RecorderCallback.CallbackEntry.RESUMED; 187 import static com.android.testutils.RecorderCallback.CallbackEntry.SUSPENDED; 188 import static com.android.testutils.RecorderCallback.CallbackEntry.UNAVAILABLE; 189 import static com.android.testutils.TestPermissionUtil.runAsShell; 190 191 import static org.hamcrest.MatcherAssert.assertThat; 192 import static org.hamcrest.Matchers.containsString; 193 import static org.junit.Assert.assertEquals; 194 import static org.junit.Assert.assertFalse; 195 import static org.junit.Assert.assertNotEquals; 196 import static org.junit.Assert.assertNotNull; 197 import static org.junit.Assert.assertNull; 198 import static org.junit.Assert.assertTrue; 199 import static org.junit.Assert.fail; 200 import static org.junit.Assume.assumeFalse; 201 import static org.junit.Assume.assumeTrue; 202 import static org.mockito.AdditionalMatchers.aryEq; 203 import static org.mockito.ArgumentMatchers.anyBoolean; 204 import static org.mockito.ArgumentMatchers.anyLong; 205 import static org.mockito.ArgumentMatchers.anyString; 206 import static org.mockito.ArgumentMatchers.argThat; 207 import static org.mockito.ArgumentMatchers.eq; 208 import static org.mockito.ArgumentMatchers.isNull; 209 import static org.mockito.Matchers.anyInt; 210 import static org.mockito.Mockito.any; 211 import static org.mockito.Mockito.atLeastOnce; 212 import static org.mockito.Mockito.doAnswer; 213 import static org.mockito.Mockito.doNothing; 214 import static org.mockito.Mockito.doReturn; 215 import static org.mockito.Mockito.doThrow; 216 import static org.mockito.Mockito.inOrder; 217 import static org.mockito.Mockito.mock; 218 import static org.mockito.Mockito.never; 219 import static org.mockito.Mockito.reset; 220 import static org.mockito.Mockito.spy; 221 import static org.mockito.Mockito.timeout; 222 import static org.mockito.Mockito.times; 223 import static org.mockito.Mockito.verify; 224 import static org.mockito.Mockito.verifyNoMoreInteractions; 225 226 import static java.util.Arrays.asList; 227 228 import android.Manifest; 229 import android.annotation.NonNull; 230 import android.annotation.Nullable; 231 import android.app.ActivityManager; 232 import android.app.ActivityManager.UidFrozenStateChangedCallback; 233 import android.app.AlarmManager; 234 import android.app.AppOpsManager; 235 import android.app.BroadcastOptions; 236 import android.app.NotificationManager; 237 import android.app.PendingIntent; 238 import android.app.admin.DevicePolicyManager; 239 import android.app.usage.NetworkStatsManager; 240 import android.compat.testing.PlatformCompatChangeRule; 241 import android.content.BroadcastReceiver; 242 import android.content.ComponentName; 243 import android.content.ContentProvider; 244 import android.content.ContentResolver; 245 import android.content.Context; 246 import android.content.Intent; 247 import android.content.IntentFilter; 248 import android.content.pm.ApplicationInfo; 249 import android.content.pm.PackageInfo; 250 import android.content.pm.PackageManager; 251 import android.content.pm.ResolveInfo; 252 import android.content.pm.ServiceInfo; 253 import android.content.pm.UserInfo; 254 import android.content.res.Resources; 255 import android.location.LocationManager; 256 import android.net.CaptivePortal; 257 import android.net.CaptivePortalData; 258 import android.net.ConnectionInfo; 259 import android.net.ConnectivityDiagnosticsManager.DataStallReport; 260 import android.net.ConnectivityManager; 261 import android.net.ConnectivityManager.NetworkCallback; 262 import android.net.ConnectivityManager.PacketKeepalive; 263 import android.net.ConnectivityManager.PacketKeepaliveCallback; 264 import android.net.ConnectivityManager.TooManyRequestsException; 265 import android.net.ConnectivitySettingsManager; 266 import android.net.ConnectivityThread; 267 import android.net.DataStallReportParcelable; 268 import android.net.EthernetManager; 269 import android.net.EthernetNetworkSpecifier; 270 import android.net.IConnectivityDiagnosticsCallback; 271 import android.net.IDnsResolver; 272 import android.net.INetd; 273 import android.net.INetworkMonitor; 274 import android.net.INetworkMonitorCallbacks; 275 import android.net.IOnCompleteListener; 276 import android.net.IQosCallback; 277 import android.net.InetAddresses; 278 import android.net.InterfaceConfigurationParcel; 279 import android.net.IpPrefix; 280 import android.net.IpSecManager; 281 import android.net.IpSecManager.UdpEncapsulationSocket; 282 import android.net.LinkAddress; 283 import android.net.LinkProperties; 284 import android.net.MatchAllNetworkSpecifier; 285 import android.net.NativeNetworkConfig; 286 import android.net.NativeNetworkType; 287 import android.net.Network; 288 import android.net.NetworkAgent; 289 import android.net.NetworkAgentConfig; 290 import android.net.NetworkCapabilities; 291 import android.net.NetworkFactory; 292 import android.net.NetworkInfo; 293 import android.net.NetworkInfo.DetailedState; 294 import android.net.NetworkPolicyManager; 295 import android.net.NetworkPolicyManager.NetworkPolicyCallback; 296 import android.net.NetworkProvider; 297 import android.net.NetworkRequest; 298 import android.net.NetworkScore; 299 import android.net.NetworkSpecifier; 300 import android.net.NetworkStack; 301 import android.net.NetworkStateSnapshot; 302 import android.net.NetworkTestResultParcelable; 303 import android.net.OemNetworkPreferences; 304 import android.net.PacProxyManager; 305 import android.net.ProfileNetworkPreference; 306 import android.net.Proxy; 307 import android.net.ProxyInfo; 308 import android.net.QosCallbackException; 309 import android.net.QosFilter; 310 import android.net.QosSession; 311 import android.net.ResolverParamsParcel; 312 import android.net.RouteInfo; 313 import android.net.RouteInfoParcel; 314 import android.net.SocketKeepalive; 315 import android.net.TelephonyNetworkSpecifier; 316 import android.net.TetheringManager; 317 import android.net.TransportInfo; 318 import android.net.UidRange; 319 import android.net.UidRangeParcel; 320 import android.net.UnderlyingNetworkInfo; 321 import android.net.Uri; 322 import android.net.VpnManager; 323 import android.net.VpnTransportInfo; 324 import android.net.connectivity.ConnectivityCompatChanges; 325 import android.net.metrics.IpConnectivityLog; 326 import android.net.netd.aidl.NativeUidRangeConfig; 327 import android.net.networkstack.NetworkStackClientBase; 328 import android.net.resolv.aidl.Nat64PrefixEventParcel; 329 import android.net.resolv.aidl.PrivateDnsValidationEventParcel; 330 import android.net.shared.PrivateDnsConfig; 331 import android.net.wifi.WifiInfo; 332 import android.os.BadParcelableException; 333 import android.os.BatteryStatsManager; 334 import android.os.Binder; 335 import android.os.Build; 336 import android.os.Bundle; 337 import android.os.ConditionVariable; 338 import android.os.Handler; 339 import android.os.HandlerThread; 340 import android.os.IBinder; 341 import android.os.INetworkManagementService; 342 import android.os.Looper; 343 import android.os.Messenger; 344 import android.os.Parcel; 345 import android.os.ParcelFileDescriptor; 346 import android.os.Parcelable; 347 import android.os.PersistableBundle; 348 import android.os.Process; 349 import android.os.RemoteException; 350 import android.os.ServiceSpecificException; 351 import android.os.SystemClock; 352 import android.os.SystemConfigManager; 353 import android.os.UserHandle; 354 import android.os.UserManager; 355 import android.provider.Settings; 356 import android.security.Credentials; 357 import android.system.Os; 358 import android.telephony.SubscriptionManager; 359 import android.telephony.TelephonyManager; 360 import android.telephony.data.EpsBearerQosSessionAttributes; 361 import android.telephony.data.NrQosSessionAttributes; 362 import android.test.mock.MockContentResolver; 363 import android.text.TextUtils; 364 import android.util.ArraySet; 365 import android.util.Log; 366 import android.util.Pair; 367 import android.util.Range; 368 import android.util.SparseArray; 369 370 import androidx.test.InstrumentationRegistry; 371 import androidx.test.filters.SmallTest; 372 373 import com.android.connectivity.resources.R; 374 import com.android.internal.annotations.GuardedBy; 375 import com.android.internal.app.IBatteryStats; 376 import com.android.internal.net.VpnConfig; 377 import com.android.internal.net.VpnProfile; 378 import com.android.internal.util.WakeupMessage; 379 import com.android.internal.util.test.BroadcastInterceptingContext; 380 import com.android.internal.util.test.FakeSettingsProvider; 381 import com.android.net.module.util.ArrayTrackRecord; 382 import com.android.net.module.util.CollectionUtils; 383 import com.android.net.module.util.LocationPermissionChecker; 384 import com.android.net.module.util.NetworkMonitorUtils; 385 import com.android.networkstack.apishim.ConstantsShim; 386 import com.android.networkstack.apishim.NetworkAgentConfigShimImpl; 387 import com.android.networkstack.apishim.common.BroadcastOptionsShim; 388 import com.android.networkstack.apishim.common.UnsupportedApiLevelException; 389 import com.android.server.ConnectivityService.ConnectivityDiagnosticsCallbackInfo; 390 import com.android.server.ConnectivityService.NetworkRequestInfo; 391 import com.android.server.ConnectivityServiceTest.ConnectivityServiceDependencies.DestroySocketsWrapper; 392 import com.android.server.ConnectivityServiceTest.ConnectivityServiceDependencies.ReportedInterfaces; 393 import com.android.server.connectivity.ApplicationSelfCertifiedNetworkCapabilities; 394 import com.android.server.connectivity.AutomaticOnOffKeepaliveTracker; 395 import com.android.server.connectivity.CarrierPrivilegeAuthenticator; 396 import com.android.server.connectivity.ClatCoordinator; 397 import com.android.server.connectivity.ConnectivityFlags; 398 import com.android.server.connectivity.ConnectivityResources; 399 import com.android.server.connectivity.MultinetworkPolicyTracker; 400 import com.android.server.connectivity.MultinetworkPolicyTrackerTestDependencies; 401 import com.android.server.connectivity.Nat464Xlat; 402 import com.android.server.connectivity.NetworkAgentInfo; 403 import com.android.server.connectivity.NetworkNotificationManager; 404 import com.android.server.connectivity.NetworkNotificationManager.NotificationType; 405 import com.android.server.connectivity.ProxyTracker; 406 import com.android.server.connectivity.QosCallbackTracker; 407 import com.android.server.connectivity.UidRangeUtils; 408 import com.android.server.connectivity.Vpn; 409 import com.android.server.connectivity.VpnProfileStore; 410 import com.android.server.net.LockdownVpnTracker; 411 import com.android.server.net.NetworkPinner; 412 import com.android.testutils.DevSdkIgnoreRule; 413 import com.android.testutils.DevSdkIgnoreRunner; 414 import com.android.testutils.FunctionalUtils.Function3; 415 import com.android.testutils.FunctionalUtils.ThrowingConsumer; 416 import com.android.testutils.FunctionalUtils.ThrowingRunnable; 417 import com.android.testutils.HandlerUtils; 418 import com.android.testutils.RecorderCallback.CallbackEntry; 419 import com.android.testutils.TestableNetworkCallback; 420 import com.android.testutils.TestableNetworkOfferCallback; 421 422 import libcore.junit.util.compat.CoreCompatChangeRule.DisableCompatChanges; 423 import libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges; 424 425 import org.junit.After; 426 import org.junit.Assert; 427 import org.junit.Before; 428 import org.junit.Ignore; 429 import org.junit.Rule; 430 import org.junit.Test; 431 import org.junit.runner.RunWith; 432 import org.mockito.AdditionalAnswers; 433 import org.mockito.ArgumentCaptor; 434 import org.mockito.InOrder; 435 import org.mockito.Mock; 436 import org.mockito.MockitoAnnotations; 437 import org.mockito.Spy; 438 import org.mockito.stubbing.Answer; 439 440 import java.io.FileDescriptor; 441 import java.io.IOException; 442 import java.io.PrintWriter; 443 import java.io.StringWriter; 444 import java.net.DatagramSocket; 445 import java.net.Inet4Address; 446 import java.net.Inet6Address; 447 import java.net.InetAddress; 448 import java.net.InetSocketAddress; 449 import java.net.Socket; 450 import java.nio.charset.StandardCharsets; 451 import java.util.ArrayList; 452 import java.util.Arrays; 453 import java.util.Collection; 454 import java.util.Collections; 455 import java.util.Comparator; 456 import java.util.HashMap; 457 import java.util.HashSet; 458 import java.util.List; 459 import java.util.Map; 460 import java.util.Objects; 461 import java.util.Set; 462 import java.util.concurrent.CompletableFuture; 463 import java.util.concurrent.CountDownLatch; 464 import java.util.concurrent.Executor; 465 import java.util.concurrent.ExecutorService; 466 import java.util.concurrent.Executors; 467 import java.util.concurrent.LinkedBlockingQueue; 468 import java.util.concurrent.TimeUnit; 469 import java.util.concurrent.TimeoutException; 470 import java.util.concurrent.atomic.AtomicBoolean; 471 import java.util.concurrent.atomic.AtomicReference; 472 import java.util.function.Consumer; 473 import java.util.function.Predicate; 474 import java.util.function.Supplier; 475 import java.util.regex.Matcher; 476 import java.util.regex.Pattern; 477 import java.util.stream.Collectors; 478 479 /** 480 * Tests for {@link ConnectivityService}. 481 * 482 * Build, install and run with: 483 * runtest frameworks-net -c com.android.server.ConnectivityServiceTest 484 */ 485 @RunWith(DevSdkIgnoreRunner.class) 486 @SmallTest 487 @DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.R) 488 public class ConnectivityServiceTest { 489 private static final String TAG = "ConnectivityServiceTest"; 490 491 @Rule 492 public final DevSdkIgnoreRule ignoreRule = new DevSdkIgnoreRule(); 493 494 @Rule 495 public final PlatformCompatChangeRule compatChangeRule = new PlatformCompatChangeRule(); 496 497 private static final int TIMEOUT_MS = 2_000; 498 // Broadcasts can take a long time to be delivered. The test will not wait for that long unless 499 // there is a failure, so use a long timeout. 500 private static final int BROADCAST_TIMEOUT_MS = 30_000; 501 private static final int TEST_LINGER_DELAY_MS = 400; 502 private static final int TEST_NASCENT_DELAY_MS = 300; 503 // Chosen to be less than the linger and nascent timeout. This ensures that we can distinguish 504 // between a LOST callback that arrives immediately and a LOST callback that arrives after 505 // the linger/nascent timeout. For this, our assertions should run fast enough to leave 506 // less than (mService.mLingerDelayMs - TEST_CALLBACK_TIMEOUT_MS) between the time callbacks are 507 // supposedly fired, and the time we call expectCallback. 508 private static final int TEST_CALLBACK_TIMEOUT_MS = 250; 509 // Chosen to be less than TEST_CALLBACK_TIMEOUT_MS. This ensures that requests have time to 510 // complete before callbacks are verified. 511 private static final int TEST_REQUEST_TIMEOUT_MS = 150; 512 513 private static final int UNREASONABLY_LONG_ALARM_WAIT_MS = 2_000; 514 515 private static final long TIMESTAMP = 1234L; 516 517 private static final int NET_ID = 110; 518 private static final int OEM_PREF_ANY_NET_ID = -1; 519 // Set a non-zero value to verify the flow to set tcp init rwnd value. 520 private static final int TEST_TCP_INIT_RWND = 60; 521 522 // Used for testing the per-work-profile default network. 523 private static final int TEST_APP_ID = 103; 524 private static final int TEST_WORK_PROFILE_USER_ID = 2; 525 private static final int TEST_WORK_PROFILE_APP_UID = 526 UserHandle.getUid(TEST_WORK_PROFILE_USER_ID, TEST_APP_ID); 527 private static final int TEST_APP_ID_2 = 104; 528 private static final int TEST_WORK_PROFILE_APP_UID_2 = 529 UserHandle.getUid(TEST_WORK_PROFILE_USER_ID, TEST_APP_ID_2); 530 private static final int TEST_APP_ID_3 = 105; 531 private static final int TEST_APP_ID_4 = 106; 532 private static final int TEST_APP_ID_5 = 107; 533 534 private static final String CLAT_PREFIX = "v4-"; 535 private static final String MOBILE_IFNAME = "test_rmnet_data0"; 536 private static final String CLAT_MOBILE_IFNAME = CLAT_PREFIX + MOBILE_IFNAME; 537 private static final String WIFI_IFNAME = "test_wlan0"; 538 private static final String WIFI_WOL_IFNAME = "test_wlan_wol"; 539 private static final String VPN_IFNAME = "tun10042"; 540 private static final String TEST_PACKAGE_NAME = "com.android.test.package"; 541 private static final int TEST_PACKAGE_UID = 123; 542 private static final int TEST_PACKAGE_UID2 = 321; 543 private static final int TEST_PACKAGE_UID3 = 456; 544 545 private static final int PACKET_WAKEUP_MARK_MASK = 0x80000000; 546 547 private static final String ALWAYS_ON_PACKAGE = "com.android.test.alwaysonvpn"; 548 549 private static final String INTERFACE_NAME = "interface"; 550 551 private static final String TEST_VENUE_URL_NA_PASSPOINT = "https://android.com/"; 552 private static final String TEST_VENUE_URL_NA_OTHER = "https://example.com/"; 553 private static final String TEST_TERMS_AND_CONDITIONS_URL_NA_PASSPOINT = 554 "https://android.com/terms/"; 555 private static final String TEST_TERMS_AND_CONDITIONS_URL_NA_OTHER = 556 "https://example.com/terms/"; 557 private static final String TEST_VENUE_URL_CAPPORT = "https://android.com/capport/"; 558 private static final String TEST_USER_PORTAL_API_URL_CAPPORT = 559 "https://android.com/user/api/capport/"; 560 private static final String TEST_FRIENDLY_NAME = "Network friendly name"; 561 private static final String TEST_REDIRECT_URL = "http://example.com/firstPath"; 562 563 private MockContext mServiceContext; 564 private HandlerThread mCsHandlerThread; 565 private ConnectivityServiceDependencies mDeps; 566 private AutomaticOnOffKeepaliveTrackerDependencies mAutoOnOffKeepaliveDependencies; 567 private ConnectivityService mService; 568 private WrappedConnectivityManager mCm; 569 private TestNetworkAgentWrapper mWiFiAgent; 570 private TestNetworkAgentWrapper mCellAgent; 571 private TestNetworkAgentWrapper mEthernetAgent; 572 private MockVpn mMockVpn; 573 private Context mContext; 574 private NetworkPolicyCallback mPolicyCallback; 575 private WrappedMultinetworkPolicyTracker mPolicyTracker; 576 private ProxyTracker mProxyTracker; 577 private HandlerThread mAlarmManagerThread; 578 private TestNetIdManager mNetIdManager; 579 private QosCallbackMockHelper mQosCallbackMockHelper; 580 private QosCallbackTracker mQosCallbackTracker; 581 private TestNetworkCallback mDefaultNetworkCallback; 582 private TestNetworkCallback mSystemDefaultNetworkCallback; 583 private TestNetworkCallback mProfileDefaultNetworkCallback; 584 private TestNetworkCallback mTestPackageDefaultNetworkCallback; 585 private TestNetworkCallback mProfileDefaultNetworkCallbackAsAppUid2; 586 private TestNetworkCallback mTestPackageDefaultNetworkCallback2; 587 588 // State variables required to emulate NetworkPolicyManagerService behaviour. 589 private int mBlockedReasons = BLOCKED_REASON_NONE; 590 591 @Mock DeviceIdleInternal mDeviceIdleInternal; 592 @Mock INetworkManagementService mNetworkManagementService; 593 @Mock NetworkStatsManager mStatsManager; 594 @Mock IDnsResolver mMockDnsResolver; 595 @Mock INetd mMockNetd; 596 @Mock NetworkStackClientBase mNetworkStack; 597 @Mock PackageManager mPackageManager; 598 @Mock UserManager mUserManager; 599 @Mock NotificationManager mNotificationManager; 600 @Mock AlarmManager mAlarmManager; 601 @Mock IConnectivityDiagnosticsCallback mConnectivityDiagnosticsCallback; 602 @Mock IBinder mIBinder; 603 @Mock LocationManager mLocationManager; 604 @Mock AppOpsManager mAppOpsManager; 605 @Mock TelephonyManager mTelephonyManager; 606 @Mock EthernetManager mEthernetManager; 607 @Mock NetworkPolicyManager mNetworkPolicyManager; 608 @Mock VpnProfileStore mVpnProfileStore; 609 @Mock SystemConfigManager mSystemConfigManager; 610 @Mock DevicePolicyManager mDevicePolicyManager; 611 @Mock Resources mResources; 612 @Mock ClatCoordinator mClatCoordinator; 613 @Mock PacProxyManager mPacProxyManager; 614 @Mock BpfNetMaps mBpfNetMaps; 615 @Mock CarrierPrivilegeAuthenticator mCarrierPrivilegeAuthenticator; 616 @Mock TetheringManager mTetheringManager; 617 @Mock BroadcastOptionsShim mBroadcastOptionsShim; 618 @Mock ActivityManager mActivityManager; 619 @Mock DestroySocketsWrapper mDestroySocketsWrapper; 620 @Mock SubscriptionManager mSubscriptionManager; 621 622 // BatteryStatsManager is final and cannot be mocked with regular mockito, so just mock the 623 // underlying binder calls. 624 final BatteryStatsManager mBatteryStatsManager = 625 new BatteryStatsManager(mock(IBatteryStats.class)); 626 627 private ArgumentCaptor<ResolverParamsParcel> mResolverParamsParcelCaptor = 628 ArgumentCaptor.forClass(ResolverParamsParcel.class); 629 630 // This class exists to test bindProcessToNetwork and getBoundNetworkForProcess. These methods 631 // do not go through ConnectivityService but talk to netd directly, so they don't automatically 632 // reflect the state of our test ConnectivityService. 633 private class WrappedConnectivityManager extends ConnectivityManager { 634 private Network mFakeBoundNetwork; 635 bindProcessToNetwork(Network network)636 public synchronized boolean bindProcessToNetwork(Network network) { 637 mFakeBoundNetwork = network; 638 return true; 639 } 640 getBoundNetworkForProcess()641 public synchronized Network getBoundNetworkForProcess() { 642 return mFakeBoundNetwork; 643 } 644 WrappedConnectivityManager(Context context, ConnectivityService service)645 public WrappedConnectivityManager(Context context, ConnectivityService service) { 646 super(context, service); 647 } 648 } 649 650 private class MockContext extends BroadcastInterceptingContext { 651 private final MockContentResolver mContentResolver; 652 653 @Spy private Resources mInternalResources; 654 private final LinkedBlockingQueue<Intent> mStartedActivities = new LinkedBlockingQueue<>(); 655 656 // Map of permission name -> PermissionManager.Permission_{GRANTED|DENIED} constant 657 // For permissions granted across the board, the key is only the permission name. 658 // For permissions only granted to a combination of uid/pid, the key 659 // is "<permission name>,<pid>,<uid>". PID+UID permissons have priority over generic ones. 660 private final HashMap<String, Integer> mMockedPermissions = new HashMap<>(); 661 mockStringResource(int resId)662 private void mockStringResource(int resId) { 663 doAnswer((inv) -> { 664 return "Mock string resource ID=" + inv.getArgument(0); 665 }).when(mInternalResources).getString(resId); 666 } 667 MockContext(Context base, ContentProvider settingsProvider)668 MockContext(Context base, ContentProvider settingsProvider) { 669 super(base); 670 671 mInternalResources = spy(base.getResources()); 672 doReturn(new String[] { 673 "wifi,1,1,1,-1,true", 674 "mobile,0,0,0,-1,true", 675 "mobile_mms,2,0,2,60000,true", 676 "mobile_supl,3,0,2,60000,true", 677 }).when(mInternalResources) 678 .getStringArray(com.android.internal.R.array.networkAttributes); 679 680 final int[] stringResourcesToMock = new int[] { 681 com.android.internal.R.string.config_customVpnAlwaysOnDisconnectedDialogComponent, 682 com.android.internal.R.string.vpn_lockdown_config, 683 com.android.internal.R.string.vpn_lockdown_connected, 684 com.android.internal.R.string.vpn_lockdown_connecting, 685 com.android.internal.R.string.vpn_lockdown_disconnected, 686 com.android.internal.R.string.vpn_lockdown_error, 687 }; 688 for (int resId : stringResourcesToMock) { 689 mockStringResource(resId); 690 } 691 692 mContentResolver = new MockContentResolver(); 693 mContentResolver.addProvider(Settings.AUTHORITY, settingsProvider); 694 } 695 696 @Override startActivityAsUser(Intent intent, UserHandle handle)697 public void startActivityAsUser(Intent intent, UserHandle handle) { 698 mStartedActivities.offer(intent); 699 } 700 expectStartActivityIntent(int timeoutMs)701 public Intent expectStartActivityIntent(int timeoutMs) { 702 Intent intent = null; 703 try { 704 intent = mStartedActivities.poll(timeoutMs, TimeUnit.MILLISECONDS); 705 } catch (InterruptedException e) {} 706 assertNotNull("Did not receive sign-in intent after " + timeoutMs + "ms", intent); 707 return intent; 708 } 709 expectNoStartActivityIntent(int timeoutMs)710 public void expectNoStartActivityIntent(int timeoutMs) { 711 try { 712 assertNull("Received unexpected Intent to start activity", 713 mStartedActivities.poll(timeoutMs, TimeUnit.MILLISECONDS)); 714 } catch (InterruptedException e) {} 715 } 716 717 @Override startService(Intent service)718 public ComponentName startService(Intent service) { 719 final String action = service.getAction(); 720 if (!VpnConfig.SERVICE_INTERFACE.equals(action) 721 && !ConstantsShim.ACTION_VPN_MANAGER_EVENT.equals(action)) { 722 fail("Attempt to start unknown service, action=" + action); 723 } 724 return new ComponentName(service.getPackage(), "com.android.test.Service"); 725 } 726 727 @Override getSystemService(String name)728 public Object getSystemService(String name) { 729 if (Context.CONNECTIVITY_SERVICE.equals(name)) return mCm; 730 if (Context.NOTIFICATION_SERVICE.equals(name)) return mNotificationManager; 731 if (Context.USER_SERVICE.equals(name)) return mUserManager; 732 if (Context.ALARM_SERVICE.equals(name)) return mAlarmManager; 733 if (Context.LOCATION_SERVICE.equals(name)) return mLocationManager; 734 if (Context.APP_OPS_SERVICE.equals(name)) return mAppOpsManager; 735 if (Context.TELEPHONY_SERVICE.equals(name)) return mTelephonyManager; 736 if (Context.ETHERNET_SERVICE.equals(name)) return mEthernetManager; 737 if (Context.NETWORK_POLICY_SERVICE.equals(name)) return mNetworkPolicyManager; 738 if (Context.DEVICE_POLICY_SERVICE.equals(name)) return mDevicePolicyManager; 739 if (Context.SYSTEM_CONFIG_SERVICE.equals(name)) return mSystemConfigManager; 740 if (Context.NETWORK_STATS_SERVICE.equals(name)) return mStatsManager; 741 if (Context.BATTERY_STATS_SERVICE.equals(name)) return mBatteryStatsManager; 742 if (Context.PAC_PROXY_SERVICE.equals(name)) return mPacProxyManager; 743 if (Context.TETHERING_SERVICE.equals(name)) return mTetheringManager; 744 if (Context.ACTIVITY_SERVICE.equals(name)) return mActivityManager; 745 if (Context.TELEPHONY_SUBSCRIPTION_SERVICE.equals(name)) return mSubscriptionManager; 746 return super.getSystemService(name); 747 } 748 749 final HashMap<UserHandle, UserManager> mUserManagers = new HashMap<>(); 750 @Override createContextAsUser(UserHandle user, int flags)751 public Context createContextAsUser(UserHandle user, int flags) { 752 final Context asUser = mock(Context.class, AdditionalAnswers.delegatesTo(this)); 753 doReturn(user).when(asUser).getUser(); 754 doAnswer((inv) -> { 755 final UserManager um = mUserManagers.computeIfAbsent(user, 756 u -> mock(UserManager.class, AdditionalAnswers.delegatesTo(mUserManager))); 757 return um; 758 }).when(asUser).getSystemService(Context.USER_SERVICE); 759 return asUser; 760 } 761 setWorkProfile(@onNull final UserHandle userHandle, boolean value)762 public void setWorkProfile(@NonNull final UserHandle userHandle, boolean value) { 763 // This relies on all contexts for a given user returning the same UM mock 764 final UserManager umMock = createContextAsUser(userHandle, 0 /* flags */) 765 .getSystemService(UserManager.class); 766 doReturn(value).when(umMock).isManagedProfile(); 767 doReturn(value).when(mUserManager).isManagedProfile(eq(userHandle.getIdentifier())); 768 } 769 setDeviceOwner(@onNull final UserHandle userHandle, String value)770 public void setDeviceOwner(@NonNull final UserHandle userHandle, String value) { 771 // This relies on all contexts for a given user returning the same UM mock 772 final DevicePolicyManager dpmMock = createContextAsUser(userHandle, 0 /* flags */) 773 .getSystemService(DevicePolicyManager.class); 774 doReturn(value).when(dpmMock).getDeviceOwner(); 775 doReturn(value).when(mDevicePolicyManager).getDeviceOwner(); 776 } 777 778 @Override getContentResolver()779 public ContentResolver getContentResolver() { 780 return mContentResolver; 781 } 782 783 @Override getResources()784 public Resources getResources() { 785 return mInternalResources; 786 } 787 788 @Override getPackageManager()789 public PackageManager getPackageManager() { 790 return mPackageManager; 791 } 792 checkMockedPermission(String permission, int pid, int uid, Function3<String, Integer, Integer, Integer> ifAbsent )793 private int checkMockedPermission(String permission, int pid, int uid, 794 Function3<String, Integer, Integer, Integer> ifAbsent /* perm, uid, pid -> int */) { 795 final Integer granted = mMockedPermissions.get(permission + "," + pid + "," + uid); 796 if (null != granted) { 797 return granted; 798 } 799 final Integer allGranted = mMockedPermissions.get(permission); 800 if (null != allGranted) { 801 return allGranted; 802 } 803 return ifAbsent.apply(permission, pid, uid); 804 } 805 806 @Override checkPermission(String permission, int pid, int uid)807 public int checkPermission(String permission, int pid, int uid) { 808 return checkMockedPermission(permission, pid, uid, 809 (perm, p, u) -> super.checkPermission(perm, p, u)); 810 } 811 812 @Override checkCallingOrSelfPermission(String permission)813 public int checkCallingOrSelfPermission(String permission) { 814 return checkMockedPermission(permission, Process.myPid(), Process.myUid(), 815 (perm, p, u) -> super.checkCallingOrSelfPermission(perm)); 816 } 817 818 @Override enforceCallingOrSelfPermission(String permission, String message)819 public void enforceCallingOrSelfPermission(String permission, String message) { 820 final Integer granted = checkMockedPermission(permission, 821 Process.myPid(), Process.myUid(), 822 (perm, p, u) -> { 823 super.enforceCallingOrSelfPermission(perm, message); 824 // enforce will crash if the permission is not granted 825 return PERMISSION_GRANTED; 826 }); 827 828 if (!granted.equals(PERMISSION_GRANTED)) { 829 throw new SecurityException("[Test] permission denied: " + permission); 830 } 831 } 832 833 /** 834 * Mock checks for the specified permission, and have them behave as per {@code granted}. 835 * 836 * This will apply to all calls no matter what the checked UID and PID are. 837 * 838 * <p>Passing null reverts to default behavior, which does a real permission check on the 839 * test package. 840 * @param granted One of {@link PackageManager#PERMISSION_GRANTED} or 841 * {@link PackageManager#PERMISSION_DENIED}. 842 */ setPermission(String permission, Integer granted)843 public void setPermission(String permission, Integer granted) { 844 mMockedPermissions.put(permission, granted); 845 } 846 847 /** 848 * Mock checks for the specified permission, and have them behave as per {@code granted}. 849 * 850 * This will only apply to the passed UID and PID. 851 * 852 * <p>Passing null reverts to default behavior, which does a real permission check on the 853 * test package. 854 * @param granted One of {@link PackageManager#PERMISSION_GRANTED} or 855 * {@link PackageManager#PERMISSION_DENIED}. 856 */ setPermission(String permission, int pid, int uid, Integer granted)857 public void setPermission(String permission, int pid, int uid, Integer granted) { 858 final String key = permission + "," + pid + "," + uid; 859 mMockedPermissions.put(key, granted); 860 } 861 862 @Override registerReceiverForAllUsers(@ullable BroadcastReceiver receiver, @NonNull IntentFilter filter, @Nullable String broadcastPermission, @Nullable Handler scheduler)863 public Intent registerReceiverForAllUsers(@Nullable BroadcastReceiver receiver, 864 @NonNull IntentFilter filter, @Nullable String broadcastPermission, 865 @Nullable Handler scheduler) { 866 // TODO: ensure MultinetworkPolicyTracker's BroadcastReceiver is tested; just returning 867 // null should not pass the test 868 return null; 869 } 870 871 @Override sendStickyBroadcast(Intent intent, Bundle options)872 public void sendStickyBroadcast(Intent intent, Bundle options) { 873 // Verify that delivery group policy APIs were used on U. 874 if (mDeps.isAtLeastU() && CONNECTIVITY_ACTION.equals(intent.getAction())) { 875 final NetworkInfo ni = intent.getParcelableExtra(EXTRA_NETWORK_INFO, 876 NetworkInfo.class); 877 try { 878 verify(mBroadcastOptionsShim).setDeliveryGroupPolicy( 879 eq(ConstantsShim.DELIVERY_GROUP_POLICY_MOST_RECENT)); 880 verify(mBroadcastOptionsShim).setDeliveryGroupMatchingKey( 881 eq(CONNECTIVITY_ACTION), 882 eq(createDeliveryGroupKeyForConnectivityAction(ni))); 883 verify(mBroadcastOptionsShim).setDeferralPolicy( 884 eq(ConstantsShim.DEFERRAL_POLICY_UNTIL_ACTIVE)); 885 } catch (UnsupportedApiLevelException e) { 886 throw new RuntimeException(e); 887 } 888 } 889 super.sendStickyBroadcast(intent, options); 890 } 891 } 892 893 // This was only added in the T SDK, but this test needs to build against the R+S SDKs, too. toSdkSandboxUid(int appUid)894 private static int toSdkSandboxUid(int appUid) { 895 final int firstSdkSandboxUid = 20000; 896 return appUid + (firstSdkSandboxUid - Process.FIRST_APPLICATION_UID); 897 } 898 899 // This function assumes the UID range for user 0 ([1, 99999]) uidRangeParcelsExcludingUids(Integer... excludedUids)900 private static UidRangeParcel[] uidRangeParcelsExcludingUids(Integer... excludedUids) { 901 int start = 1; 902 Arrays.sort(excludedUids); 903 List<UidRangeParcel> parcels = new ArrayList<UidRangeParcel>(); 904 for (int excludedUid : excludedUids) { 905 if (excludedUid == start) { 906 start++; 907 } else { 908 parcels.add(new UidRangeParcel(start, excludedUid - 1)); 909 start = excludedUid + 1; 910 } 911 } 912 if (start <= 99999) { 913 parcels.add(new UidRangeParcel(start, 99999)); 914 } 915 916 return parcels.toArray(new UidRangeParcel[0]); 917 } 918 waitForIdle()919 private void waitForIdle() { 920 HandlerUtils.waitForIdle(mCsHandlerThread, TIMEOUT_MS); 921 waitForIdle(mCellAgent, TIMEOUT_MS); 922 waitForIdle(mWiFiAgent, TIMEOUT_MS); 923 waitForIdle(mEthernetAgent, TIMEOUT_MS); 924 HandlerUtils.waitForIdle(mCsHandlerThread, TIMEOUT_MS); 925 HandlerUtils.waitForIdle(ConnectivityThread.get(), TIMEOUT_MS); 926 } 927 waitForIdle(TestNetworkAgentWrapper agent, long timeoutMs)928 private void waitForIdle(TestNetworkAgentWrapper agent, long timeoutMs) { 929 if (agent == null) { 930 return; 931 } 932 agent.waitForIdle(timeoutMs); 933 } 934 935 @Test testWaitForIdle()936 public void testWaitForIdle() throws Exception { 937 final int attempts = 50; // Causes the test to take about 200ms on bullhead-eng. 938 939 // Tests that waitForIdle returns immediately if the service is already idle. 940 for (int i = 0; i < attempts; i++) { 941 waitForIdle(); 942 } 943 944 // Bring up a network that we can use to send messages to ConnectivityService. 945 ExpectedBroadcast b = expectConnectivityAction(TYPE_WIFI, DetailedState.CONNECTED); 946 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 947 mWiFiAgent.connect(false); 948 b.expectBroadcast(); 949 Network n = mWiFiAgent.getNetwork(); 950 assertNotNull(n); 951 952 // Tests that calling waitForIdle waits for messages to be processed. 953 for (int i = 0; i < attempts; i++) { 954 mWiFiAgent.setSignalStrength(i); 955 waitForIdle(); 956 assertEquals(i, mCm.getNetworkCapabilities(n).getSignalStrength()); 957 } 958 } 959 960 // This test has an inherent race condition in it, and cannot be enabled for continuous testing 961 // or presubmit tests. It is kept for manual runs and documentation purposes. 962 @Ignore verifyThatNotWaitingForIdleCausesRaceConditions()963 public void verifyThatNotWaitingForIdleCausesRaceConditions() throws Exception { 964 // Bring up a network that we can use to send messages to ConnectivityService. 965 ExpectedBroadcast b = expectConnectivityAction(TYPE_WIFI, DetailedState.CONNECTED); 966 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 967 mWiFiAgent.connect(false); 968 b.expectBroadcast(); 969 Network n = mWiFiAgent.getNetwork(); 970 assertNotNull(n); 971 972 // Ensure that not calling waitForIdle causes a race condition. 973 final int attempts = 50; // Causes the test to take about 200ms on bullhead-eng. 974 for (int i = 0; i < attempts; i++) { 975 mWiFiAgent.setSignalStrength(i); 976 if (i != mCm.getNetworkCapabilities(n).getSignalStrength()) { 977 // We hit a race condition, as expected. Pass the test. 978 return; 979 } 980 } 981 982 // No race? There is a bug in this test. 983 fail("expected race condition at least once in " + attempts + " attempts"); 984 } 985 986 private class TestNetworkAgentWrapper extends NetworkAgentWrapper { 987 private static final int VALIDATION_RESULT_INVALID = 0; 988 989 private static final long DATA_STALL_TIMESTAMP = 10L; 990 private static final int DATA_STALL_DETECTION_METHOD = 1; 991 992 private INetworkMonitor mNetworkMonitor; 993 private INetworkMonitorCallbacks mNmCallbacks; 994 private int mNmValidationResult = VALIDATION_RESULT_INVALID; 995 private int mProbesCompleted; 996 private int mProbesSucceeded; 997 private String mNmValidationRedirectUrl = null; 998 private boolean mNmProvNotificationRequested = false; 999 1000 private final ConditionVariable mNetworkStatusReceived = new ConditionVariable(); 1001 // Contains the redirectUrl from networkStatus(). Before reading, wait for 1002 // mNetworkStatusReceived. 1003 private String mRedirectUrl; 1004 TestNetworkAgentWrapper(int transport)1005 TestNetworkAgentWrapper(int transport) throws Exception { 1006 this(transport, new LinkProperties(), null /* ncTemplate */, null /* provider */, null); 1007 } 1008 TestNetworkAgentWrapper(int transport, LinkProperties linkProperties)1009 TestNetworkAgentWrapper(int transport, LinkProperties linkProperties) 1010 throws Exception { 1011 this(transport, linkProperties, null /* ncTemplate */, null /* provider */, null); 1012 } 1013 TestNetworkAgentWrapper(int transport, LinkProperties linkProperties, NetworkCapabilities ncTemplate)1014 private TestNetworkAgentWrapper(int transport, LinkProperties linkProperties, 1015 NetworkCapabilities ncTemplate) throws Exception { 1016 this(transport, linkProperties, ncTemplate, null /* provider */, null); 1017 } 1018 TestNetworkAgentWrapper(int transport, LinkProperties linkProperties, NetworkCapabilities ncTemplate, NetworkProvider provider)1019 private TestNetworkAgentWrapper(int transport, LinkProperties linkProperties, 1020 NetworkCapabilities ncTemplate, NetworkProvider provider) throws Exception { 1021 this(transport, linkProperties, ncTemplate, provider /* provider */, null); 1022 } 1023 TestNetworkAgentWrapper(int transport, NetworkAgentWrapper.Callbacks callbacks)1024 private TestNetworkAgentWrapper(int transport, NetworkAgentWrapper.Callbacks callbacks) 1025 throws Exception { 1026 this(transport, new LinkProperties(), null /* ncTemplate */, null /* provider */, 1027 callbacks); 1028 } 1029 TestNetworkAgentWrapper(int transport, LinkProperties linkProperties, NetworkCapabilities ncTemplate, NetworkProvider provider, NetworkAgentWrapper.Callbacks callbacks)1030 private TestNetworkAgentWrapper(int transport, LinkProperties linkProperties, 1031 NetworkCapabilities ncTemplate, NetworkProvider provider, 1032 NetworkAgentWrapper.Callbacks callbacks) throws Exception { 1033 super(transport, linkProperties, ncTemplate, provider, callbacks, mServiceContext); 1034 1035 // Waits for the NetworkAgent to be registered, which includes the creation of the 1036 // NetworkMonitor. 1037 waitForIdle(TIMEOUT_MS); 1038 HandlerUtils.waitForIdle(mCsHandlerThread, TIMEOUT_MS); 1039 HandlerUtils.waitForIdle(ConnectivityThread.get(), TIMEOUT_MS); 1040 } 1041 1042 class TestInstrumentedNetworkAgent extends InstrumentedNetworkAgent { TestInstrumentedNetworkAgent(NetworkAgentWrapper wrapper, LinkProperties lp, NetworkAgentConfig nac, NetworkProvider provider)1043 TestInstrumentedNetworkAgent(NetworkAgentWrapper wrapper, LinkProperties lp, 1044 NetworkAgentConfig nac, NetworkProvider provider) { 1045 super(wrapper, lp, nac, provider); 1046 } 1047 1048 @Override networkStatus(int status, String redirectUrl)1049 public void networkStatus(int status, String redirectUrl) { 1050 mRedirectUrl = redirectUrl; 1051 mNetworkStatusReceived.open(); 1052 } 1053 1054 } 1055 1056 @Override makeNetworkAgent(LinkProperties linkProperties, NetworkAgentConfig nac, NetworkProvider provider)1057 protected InstrumentedNetworkAgent makeNetworkAgent(LinkProperties linkProperties, 1058 NetworkAgentConfig nac, NetworkProvider provider) throws Exception { 1059 mNetworkMonitor = mock(INetworkMonitor.class); 1060 1061 final Answer validateAnswer = inv -> { 1062 new Thread(ignoreExceptions(this::onValidationRequested)).start(); 1063 return null; 1064 }; 1065 1066 doAnswer(validateAnswer).when(mNetworkMonitor).notifyNetworkConnected(any(), any()); 1067 doAnswer(validateAnswer).when(mNetworkMonitor).notifyNetworkConnectedParcel(any()); 1068 doAnswer(validateAnswer).when(mNetworkMonitor).forceReevaluation(anyInt()); 1069 1070 final ArgumentCaptor<Network> nmNetworkCaptor = ArgumentCaptor.forClass(Network.class); 1071 final ArgumentCaptor<INetworkMonitorCallbacks> nmCbCaptor = 1072 ArgumentCaptor.forClass(INetworkMonitorCallbacks.class); 1073 doNothing().when(mNetworkStack).makeNetworkMonitor( 1074 nmNetworkCaptor.capture(), 1075 any() /* name */, 1076 nmCbCaptor.capture()); 1077 1078 final InstrumentedNetworkAgent na = 1079 new TestInstrumentedNetworkAgent(this, linkProperties, nac, provider); 1080 1081 assertEquals(na.getNetwork().netId, nmNetworkCaptor.getValue().netId); 1082 mNmCallbacks = nmCbCaptor.getValue(); 1083 1084 mNmCallbacks.onNetworkMonitorCreated(mNetworkMonitor); 1085 1086 return na; 1087 } 1088 onValidationRequested()1089 private void onValidationRequested() throws Exception { 1090 if (mDeps.isAtLeastT()) { 1091 verify(mNetworkMonitor).notifyNetworkConnectedParcel(any()); 1092 } else { 1093 verify(mNetworkMonitor).notifyNetworkConnected(any(), any()); 1094 } 1095 if (mNmProvNotificationRequested 1096 && ((mNmValidationResult & NETWORK_VALIDATION_RESULT_VALID) != 0)) { 1097 mNmCallbacks.hideProvisioningNotification(); 1098 mNmProvNotificationRequested = false; 1099 } 1100 1101 mNmCallbacks.notifyProbeStatusChanged(mProbesCompleted, mProbesSucceeded); 1102 final NetworkTestResultParcelable p = new NetworkTestResultParcelable(); 1103 p.result = mNmValidationResult; 1104 p.probesAttempted = mProbesCompleted; 1105 p.probesSucceeded = mProbesSucceeded; 1106 p.redirectUrl = mNmValidationRedirectUrl; 1107 p.timestampMillis = TIMESTAMP; 1108 mNmCallbacks.notifyNetworkTestedWithExtras(p); 1109 1110 if (mNmValidationRedirectUrl != null) { 1111 mNmCallbacks.showProvisioningNotification( 1112 "test_provisioning_notif_action", TEST_PACKAGE_NAME); 1113 mNmProvNotificationRequested = true; 1114 } 1115 } 1116 1117 /** 1118 * Connect without adding any internet capability. 1119 */ connectWithoutInternet()1120 public void connectWithoutInternet() { 1121 super.connect(); 1122 } 1123 1124 /** 1125 * Transition this NetworkAgent to CONNECTED state with NET_CAPABILITY_INTERNET. 1126 * @param validated Indicate if network should pretend to be validated. 1127 */ connect(boolean validated)1128 public void connect(boolean validated) { 1129 connect(validated, true, false /* privateDnsProbeSent */); 1130 } 1131 1132 /** 1133 * Transition this NetworkAgent to CONNECTED state. 1134 * 1135 * @param validated Indicate if network should pretend to be validated. 1136 * Note that if this is true, this method will mock the NetworkMonitor 1137 * probes to pretend the network is invalid after it validated once, 1138 * so that subsequent attempts (with mNetworkMonitor.forceReevaluation) 1139 * will fail unless setNetworkValid is called again manually. 1140 * @param hasInternet Indicate if network should pretend to have NET_CAPABILITY_INTERNET. 1141 * @param privateDnsProbeSent whether the private DNS probe should be considered to have 1142 * been sent, assuming |validated| is true. 1143 * If |validated| is false, |privateDnsProbeSent| is not used. 1144 * If |validated| is true and |privateDnsProbeSent| is false, 1145 * the probe has not been sent. 1146 * If |validated| is true and |privateDnsProbeSent| is true, 1147 * the probe has been sent and has succeeded. When the NM probes 1148 * are mocked to be invalid, private DNS is the reason this 1149 * network is invalid ; see @param |validated|. 1150 */ connect(boolean validated, boolean hasInternet, boolean privateDnsProbeSent)1151 public void connect(boolean validated, boolean hasInternet, 1152 boolean privateDnsProbeSent) { 1153 final ConditionVariable validatedCv = new ConditionVariable(); 1154 final ConditionVariable capsChangedCv = new ConditionVariable(); 1155 final NetworkRequest request = new NetworkRequest.Builder() 1156 .addTransportType(getNetworkCapabilities().getTransportTypes()[0]) 1157 .clearCapabilities() 1158 .build(); 1159 if (validated) { 1160 setNetworkValid(privateDnsProbeSent); 1161 } 1162 final NetworkCallback callback = new NetworkCallback() { 1163 public void onCapabilitiesChanged(Network network, 1164 NetworkCapabilities networkCapabilities) { 1165 if (network.equals(getNetwork())) { 1166 capsChangedCv.open(); 1167 if (networkCapabilities.hasCapability(NET_CAPABILITY_VALIDATED)) { 1168 validatedCv.open(); 1169 } 1170 } 1171 } 1172 }; 1173 mCm.registerNetworkCallback(request, callback); 1174 1175 if (hasInternet) { 1176 addCapability(NET_CAPABILITY_INTERNET); 1177 } 1178 1179 connectWithoutInternet(); 1180 waitFor(capsChangedCv); 1181 1182 if (validated) { 1183 // Wait for network to validate. 1184 waitFor(validatedCv); 1185 setNetworkInvalid(privateDnsProbeSent); 1186 } 1187 mCm.unregisterNetworkCallback(callback); 1188 } 1189 connectWithCaptivePortal(String redirectUrl, boolean privateDnsProbeSent)1190 public void connectWithCaptivePortal(String redirectUrl, 1191 boolean privateDnsProbeSent) { 1192 setNetworkPortal(redirectUrl, privateDnsProbeSent); 1193 connect(false, true /* hasInternet */, privateDnsProbeSent); 1194 } 1195 connectWithPartialConnectivity()1196 public void connectWithPartialConnectivity() { 1197 setNetworkPartial(); 1198 connect(false); 1199 } 1200 connectWithPartialValidConnectivity(boolean privateDnsProbeSent)1201 public void connectWithPartialValidConnectivity(boolean privateDnsProbeSent) { 1202 setNetworkPartialValid(privateDnsProbeSent); 1203 connect(false, true /* hasInternet */, privateDnsProbeSent); 1204 } 1205 setNetworkValid(boolean privateDnsProbeSent)1206 void setNetworkValid(boolean privateDnsProbeSent) { 1207 mNmValidationResult = NETWORK_VALIDATION_RESULT_VALID; 1208 mNmValidationRedirectUrl = null; 1209 int probesSucceeded = NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS; 1210 if (privateDnsProbeSent) { 1211 probesSucceeded |= NETWORK_VALIDATION_PROBE_PRIVDNS; 1212 } 1213 // The probesCompleted equals to probesSucceeded for the case of valid network, so put 1214 // the same value into two different parameter of the method. 1215 setProbesStatus(probesSucceeded, probesSucceeded); 1216 } 1217 setNetworkInvalid(boolean invalidBecauseOfPrivateDns)1218 void setNetworkInvalid(boolean invalidBecauseOfPrivateDns) { 1219 mNmValidationResult = VALIDATION_RESULT_INVALID; 1220 mNmValidationRedirectUrl = null; 1221 int probesCompleted = NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS 1222 | NETWORK_VALIDATION_PROBE_HTTP; 1223 int probesSucceeded = 0; 1224 // If |invalidBecauseOfPrivateDns| is true, it means the network is invalid because 1225 // NetworkMonitor tried to validate the private DNS but failed. Therefore it 1226 // didn't get a chance to try the HTTP probe. 1227 if (invalidBecauseOfPrivateDns) { 1228 probesCompleted &= ~NETWORK_VALIDATION_PROBE_HTTP; 1229 probesSucceeded = probesCompleted; 1230 probesCompleted |= NETWORK_VALIDATION_PROBE_PRIVDNS; 1231 } 1232 setProbesStatus(probesCompleted, probesSucceeded); 1233 } 1234 setNetworkPortal(String redirectUrl, boolean privateDnsProbeSent)1235 void setNetworkPortal(String redirectUrl, boolean privateDnsProbeSent) { 1236 setNetworkInvalid(privateDnsProbeSent); 1237 mNmValidationRedirectUrl = redirectUrl; 1238 // Suppose the portal is found when NetworkMonitor probes NETWORK_VALIDATION_PROBE_HTTP 1239 // in the beginning, so the NETWORK_VALIDATION_PROBE_HTTPS hasn't probed yet. 1240 int probesCompleted = NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTP; 1241 int probesSucceeded = VALIDATION_RESULT_INVALID; 1242 if (privateDnsProbeSent) { 1243 probesCompleted |= NETWORK_VALIDATION_PROBE_PRIVDNS; 1244 } 1245 setProbesStatus(probesCompleted, probesSucceeded); 1246 } 1247 setNetworkPartial()1248 void setNetworkPartial() { 1249 mNmValidationResult = NETWORK_VALIDATION_RESULT_PARTIAL; 1250 mNmValidationRedirectUrl = null; 1251 int probesCompleted = NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS 1252 | NETWORK_VALIDATION_PROBE_FALLBACK; 1253 int probesSucceeded = NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_FALLBACK; 1254 setProbesStatus(probesCompleted, probesSucceeded); 1255 } 1256 setNetworkPartialValid(boolean privateDnsProbeSent)1257 void setNetworkPartialValid(boolean privateDnsProbeSent) { 1258 setNetworkPartial(); 1259 mNmValidationResult |= NETWORK_VALIDATION_RESULT_VALID; 1260 mNmValidationRedirectUrl = null; 1261 int probesCompleted = NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS 1262 | NETWORK_VALIDATION_PROBE_HTTP; 1263 int probesSucceeded = NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTP; 1264 // Assume the partial network cannot pass the private DNS validation as well, so only 1265 // add NETWORK_VALIDATION_PROBE_DNS in probesCompleted but not probesSucceeded. 1266 if (privateDnsProbeSent) { 1267 probesCompleted |= NETWORK_VALIDATION_PROBE_PRIVDNS; 1268 } 1269 setProbesStatus(probesCompleted, probesSucceeded); 1270 } 1271 setProbesStatus(int probesCompleted, int probesSucceeded)1272 void setProbesStatus(int probesCompleted, int probesSucceeded) { 1273 mProbesCompleted = probesCompleted; 1274 mProbesSucceeded = probesSucceeded; 1275 } 1276 notifyCapportApiDataChanged(CaptivePortalData data)1277 void notifyCapportApiDataChanged(CaptivePortalData data) { 1278 try { 1279 mNmCallbacks.notifyCaptivePortalDataChanged(data); 1280 } catch (RemoteException e) { 1281 throw new AssertionError("This cannot happen", e); 1282 } 1283 } 1284 waitForRedirectUrl()1285 public String waitForRedirectUrl() { 1286 assertTrue(mNetworkStatusReceived.block(TIMEOUT_MS)); 1287 return mRedirectUrl; 1288 } 1289 expectDisconnected()1290 public void expectDisconnected() { 1291 expectDisconnected(TIMEOUT_MS); 1292 } 1293 expectPreventReconnectReceived()1294 public void expectPreventReconnectReceived() { 1295 expectPreventReconnectReceived(TIMEOUT_MS); 1296 } 1297 notifyDataStallSuspected()1298 void notifyDataStallSuspected() throws Exception { 1299 final DataStallReportParcelable p = new DataStallReportParcelable(); 1300 p.detectionMethod = DATA_STALL_DETECTION_METHOD; 1301 p.timestampMillis = DATA_STALL_TIMESTAMP; 1302 mNmCallbacks.notifyDataStallSuspected(p); 1303 } 1304 } 1305 1306 /** 1307 * A NetworkFactory that allows to wait until any in-flight NetworkRequest add or remove 1308 * operations have been processed and test for them. 1309 */ 1310 private static class MockNetworkFactory extends NetworkFactory { 1311 private final AtomicBoolean mNetworkStarted = new AtomicBoolean(false); 1312 1313 static class RequestEntry { 1314 @NonNull 1315 public final NetworkRequest request; 1316 RequestEntry(@onNull final NetworkRequest request)1317 RequestEntry(@NonNull final NetworkRequest request) { 1318 this.request = request; 1319 } 1320 1321 static final class Add extends RequestEntry { Add(@onNull final NetworkRequest request)1322 Add(@NonNull final NetworkRequest request) { 1323 super(request); 1324 } 1325 } 1326 1327 static final class Remove extends RequestEntry { Remove(@onNull final NetworkRequest request)1328 Remove(@NonNull final NetworkRequest request) { 1329 super(request); 1330 } 1331 } 1332 1333 @Override toString()1334 public String toString() { 1335 return "RequestEntry [ " + getClass().getName() + " : " + request + " ]"; 1336 } 1337 } 1338 1339 // History of received requests adds and removes. 1340 private final ArrayTrackRecord<RequestEntry>.ReadHead mRequestHistory = 1341 new ArrayTrackRecord<RequestEntry>().newReadHead(); 1342 failIfNull(@ullable final T obj, @Nullable final String message)1343 private static <T> T failIfNull(@Nullable final T obj, @Nullable final String message) { 1344 if (null == obj) fail(null != message ? message : "Must not be null"); 1345 return obj; 1346 } 1347 expectRequestAdd()1348 public RequestEntry.Add expectRequestAdd() { 1349 return failIfNull((RequestEntry.Add) mRequestHistory.poll(TIMEOUT_MS, 1350 it -> it instanceof RequestEntry.Add), "Expected request add"); 1351 } 1352 expectRequestAdds(final int count)1353 public void expectRequestAdds(final int count) { 1354 for (int i = count; i > 0; --i) { 1355 expectRequestAdd(); 1356 } 1357 } 1358 expectRequestRemove()1359 public RequestEntry.Remove expectRequestRemove() { 1360 return failIfNull((RequestEntry.Remove) mRequestHistory.poll(TIMEOUT_MS, 1361 it -> it instanceof RequestEntry.Remove), "Expected request remove"); 1362 } 1363 expectRequestRemoves(final int count)1364 public void expectRequestRemoves(final int count) { 1365 for (int i = count; i > 0; --i) { 1366 expectRequestRemove(); 1367 } 1368 } 1369 1370 // Used to collect the networks requests managed by this factory. This is a duplicate of 1371 // the internal information stored in the NetworkFactory (which is private). 1372 private SparseArray<NetworkRequest> mNetworkRequests = new SparseArray<>(); 1373 private final HandlerThread mHandlerSendingRequests; 1374 MockNetworkFactory(Looper looper, Context context, String logTag, NetworkCapabilities filter, HandlerThread threadSendingRequests)1375 public MockNetworkFactory(Looper looper, Context context, String logTag, 1376 NetworkCapabilities filter, HandlerThread threadSendingRequests) { 1377 super(looper, context, logTag, filter); 1378 mHandlerSendingRequests = threadSendingRequests; 1379 } 1380 getMyRequestCount()1381 public int getMyRequestCount() { 1382 return getRequestCount(); 1383 } 1384 startNetwork()1385 protected void startNetwork() { 1386 mNetworkStarted.set(true); 1387 } 1388 stopNetwork()1389 protected void stopNetwork() { 1390 mNetworkStarted.set(false); 1391 } 1392 getMyStartRequested()1393 public boolean getMyStartRequested() { 1394 return mNetworkStarted.get(); 1395 } 1396 1397 1398 @Override needNetworkFor(NetworkRequest request)1399 protected void needNetworkFor(NetworkRequest request) { 1400 mNetworkRequests.put(request.requestId, request); 1401 super.needNetworkFor(request); 1402 mRequestHistory.add(new RequestEntry.Add(request)); 1403 } 1404 1405 @Override releaseNetworkFor(NetworkRequest request)1406 protected void releaseNetworkFor(NetworkRequest request) { 1407 mNetworkRequests.remove(request.requestId); 1408 super.releaseNetworkFor(request); 1409 mRequestHistory.add(new RequestEntry.Remove(request)); 1410 } 1411 assertRequestCountEquals(final int count)1412 public void assertRequestCountEquals(final int count) { 1413 assertEquals(count, getMyRequestCount()); 1414 } 1415 1416 // Trigger releasing the request as unfulfillable triggerUnfulfillable(NetworkRequest r)1417 public void triggerUnfulfillable(NetworkRequest r) { 1418 super.releaseRequestAsUnfulfillableByAnyFactory(r); 1419 } 1420 assertNoRequestChanged()1421 public void assertNoRequestChanged() { 1422 // Make sure there are no remaining requests unaccounted for. 1423 HandlerUtils.waitForIdle(mHandlerSendingRequests, TIMEOUT_MS); 1424 assertNull(mRequestHistory.poll(0, r -> true)); 1425 } 1426 } 1427 uidRangesForUids(int... uids)1428 private Set<UidRange> uidRangesForUids(int... uids) { 1429 final ArraySet<UidRange> ranges = new ArraySet<>(); 1430 for (final int uid : uids) { 1431 ranges.add(new UidRange(uid, uid)); 1432 } 1433 return ranges; 1434 } 1435 uidRangesForUids(Collection<Integer> uids)1436 private Set<UidRange> uidRangesForUids(Collection<Integer> uids) { 1437 return uidRangesForUids(CollectionUtils.toIntArray(uids)); 1438 } 1439 startHandlerThreadAndReturnLooper()1440 private static Looper startHandlerThreadAndReturnLooper() { 1441 final HandlerThread handlerThread = new HandlerThread("MockVpnThread"); 1442 handlerThread.start(); 1443 return handlerThread.getLooper(); 1444 } 1445 1446 private class MockVpn extends Vpn implements TestableNetworkCallback.HasNetwork { 1447 // Careful ! This is different from mNetworkAgent, because MockNetworkAgent does 1448 // not inherit from NetworkAgent. 1449 private TestNetworkAgentWrapper mMockNetworkAgent; 1450 private boolean mAgentRegistered = false; 1451 1452 private int mVpnType = VpnManager.TYPE_VPN_SERVICE; 1453 private UnderlyingNetworkInfo mUnderlyingNetworkInfo; 1454 1455 // These ConditionVariables allow tests to wait for LegacyVpnRunner to be stopped/started. 1456 // TODO: this scheme is ad-hoc and error-prone because it does not fail if, for example, the 1457 // test expects two starts in a row, or even if the production code calls start twice in a 1458 // row. find a better solution. Simply putting a method to create a LegacyVpnRunner into 1459 // Vpn.Dependencies doesn't work because LegacyVpnRunner is not a static class and has 1460 // extensive access into the internals of Vpn. 1461 private ConditionVariable mStartLegacyVpnCv = new ConditionVariable(); 1462 private ConditionVariable mStopVpnRunnerCv = new ConditionVariable(); 1463 MockVpn(int userId)1464 public MockVpn(int userId) { 1465 super(startHandlerThreadAndReturnLooper(), mServiceContext, 1466 new Dependencies() { 1467 @Override 1468 public boolean isCallerSystem() { 1469 return true; 1470 } 1471 1472 @Override 1473 public DeviceIdleInternal getDeviceIdleInternal() { 1474 return mDeviceIdleInternal; 1475 } 1476 }, 1477 mNetworkManagementService, mMockNetd, userId, mVpnProfileStore, 1478 new SystemServices(mServiceContext) { 1479 @Override 1480 public String settingsSecureGetStringForUser(String key, int userId) { 1481 switch (key) { 1482 // Settings keys not marked as @Readable are not readable from 1483 // non-privileged apps, unless marked as testOnly=true 1484 // (atest refuses to install testOnly=true apps), even if mocked 1485 // in the content provider, because 1486 // Settings.Secure.NameValueCache#getStringForUser checks the key 1487 // before querying the mock settings provider. 1488 case Settings.Secure.ALWAYS_ON_VPN_APP: 1489 return null; 1490 default: 1491 return super.settingsSecureGetStringForUser(key, userId); 1492 } 1493 } 1494 }, new Ikev2SessionCreator()); 1495 } 1496 setUids(Set<UidRange> uids)1497 public void setUids(Set<UidRange> uids) { 1498 mNetworkCapabilities.setUids(UidRange.toIntRanges(uids)); 1499 if (mAgentRegistered) { 1500 mMockNetworkAgent.setNetworkCapabilities(mNetworkCapabilities, true); 1501 } 1502 } 1503 setVpnType(int vpnType)1504 public void setVpnType(int vpnType) { 1505 mVpnType = vpnType; 1506 } 1507 1508 @Override getNetwork()1509 public Network getNetwork() { 1510 return (mMockNetworkAgent == null) ? null : mMockNetworkAgent.getNetwork(); 1511 } 1512 getNetworkAgentConfig()1513 public NetworkAgentConfig getNetworkAgentConfig() { 1514 return null == mMockNetworkAgent ? null : mMockNetworkAgent.getNetworkAgentConfig(); 1515 } 1516 1517 @Override getActiveVpnType()1518 public int getActiveVpnType() { 1519 return mVpnType; 1520 } 1521 makeLinkProperties()1522 private LinkProperties makeLinkProperties() { 1523 final LinkProperties lp = new LinkProperties(); 1524 lp.setInterfaceName(VPN_IFNAME); 1525 return lp; 1526 } 1527 registerAgent(boolean isAlwaysMetered, Set<UidRange> uids, LinkProperties lp)1528 private void registerAgent(boolean isAlwaysMetered, Set<UidRange> uids, LinkProperties lp) 1529 throws Exception { 1530 if (mAgentRegistered) throw new IllegalStateException("already registered"); 1531 updateState(NetworkInfo.DetailedState.CONNECTING, "registerAgent"); 1532 mConfig = new VpnConfig(); 1533 mConfig.session = "MySession12345"; 1534 setUids(uids); 1535 if (!isAlwaysMetered) mNetworkCapabilities.addCapability(NET_CAPABILITY_NOT_METERED); 1536 mInterface = VPN_IFNAME; 1537 mNetworkCapabilities.setTransportInfo(new VpnTransportInfo(getActiveVpnType(), 1538 mConfig.session)); 1539 mMockNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_VPN, lp, 1540 mNetworkCapabilities); 1541 mMockNetworkAgent.waitForIdle(TIMEOUT_MS); 1542 1543 verify(mMockNetd, times(1)).networkAddUidRangesParcel( 1544 new NativeUidRangeConfig(mMockVpn.getNetwork().getNetId(), 1545 toUidRangeStableParcels(uids), PREFERENCE_ORDER_VPN)); 1546 verify(mMockNetd, never()).networkRemoveUidRangesParcel(argThat(config -> 1547 mMockVpn.getNetwork().getNetId() == config.netId 1548 && PREFERENCE_ORDER_VPN == config.subPriority)); 1549 mAgentRegistered = true; 1550 verify(mMockNetd).networkCreate(nativeNetworkConfigVpn(getNetwork().netId, 1551 !mMockNetworkAgent.isBypassableVpn(), mVpnType)); 1552 updateState(NetworkInfo.DetailedState.CONNECTED, "registerAgent"); 1553 mNetworkCapabilities.set(mMockNetworkAgent.getNetworkCapabilities()); 1554 mNetworkAgent = mMockNetworkAgent.getNetworkAgent(); 1555 } 1556 registerAgent(Set<UidRange> uids)1557 private void registerAgent(Set<UidRange> uids) throws Exception { 1558 registerAgent(false /* isAlwaysMetered */, uids, makeLinkProperties()); 1559 } 1560 connect(boolean validated, boolean hasInternet, boolean privateDnsProbeSent)1561 private void connect(boolean validated, boolean hasInternet, 1562 boolean privateDnsProbeSent) { 1563 mMockNetworkAgent.connect(validated, hasInternet, privateDnsProbeSent); 1564 } 1565 connect(boolean validated)1566 private void connect(boolean validated) { 1567 mMockNetworkAgent.connect(validated); 1568 } 1569 getAgent()1570 private TestNetworkAgentWrapper getAgent() { 1571 return mMockNetworkAgent; 1572 } 1573 setOwnerAndAdminUid(int uid)1574 private void setOwnerAndAdminUid(int uid) throws Exception { 1575 mNetworkCapabilities.setOwnerUid(uid); 1576 mNetworkCapabilities.setAdministratorUids(new int[]{uid}); 1577 } 1578 establish(LinkProperties lp, int uid, Set<UidRange> ranges, boolean validated, boolean hasInternet, boolean privateDnsProbeSent)1579 public void establish(LinkProperties lp, int uid, Set<UidRange> ranges, boolean validated, 1580 boolean hasInternet, boolean privateDnsProbeSent) throws Exception { 1581 setOwnerAndAdminUid(uid); 1582 registerAgent(false, ranges, lp); 1583 connect(validated, hasInternet, privateDnsProbeSent); 1584 waitForIdle(); 1585 } 1586 establish(LinkProperties lp, int uid, Set<UidRange> ranges)1587 public void establish(LinkProperties lp, int uid, Set<UidRange> ranges) throws Exception { 1588 establish(lp, uid, ranges, true, true, false); 1589 } 1590 establishForMyUid(LinkProperties lp)1591 public void establishForMyUid(LinkProperties lp) throws Exception { 1592 final int uid = Process.myUid(); 1593 establish(lp, uid, uidRangesForUids(uid), true, true, false); 1594 } 1595 establishForMyUid(boolean validated, boolean hasInternet, boolean privateDnsProbeSent)1596 public void establishForMyUid(boolean validated, boolean hasInternet, 1597 boolean privateDnsProbeSent) throws Exception { 1598 final int uid = Process.myUid(); 1599 establish(makeLinkProperties(), uid, uidRangesForUids(uid), validated, hasInternet, 1600 privateDnsProbeSent); 1601 } 1602 establishForMyUid()1603 public void establishForMyUid() throws Exception { 1604 establishForMyUid(makeLinkProperties()); 1605 } 1606 sendLinkProperties(LinkProperties lp)1607 public void sendLinkProperties(LinkProperties lp) { 1608 mMockNetworkAgent.sendLinkProperties(lp); 1609 } 1610 disconnect()1611 public void disconnect() { 1612 if (mMockNetworkAgent != null) { 1613 mMockNetworkAgent.disconnect(); 1614 updateState(NetworkInfo.DetailedState.DISCONNECTED, "disconnect"); 1615 } 1616 mAgentRegistered = false; 1617 setUids(null); 1618 // Remove NET_CAPABILITY_INTERNET or MockNetworkAgent will refuse to connect later on. 1619 mNetworkCapabilities.removeCapability(NET_CAPABILITY_INTERNET); 1620 mInterface = null; 1621 } 1622 1623 @Override startLegacyVpnRunner()1624 public void startLegacyVpnRunner() { 1625 mStartLegacyVpnCv.open(); 1626 } 1627 expectStartLegacyVpnRunner()1628 public void expectStartLegacyVpnRunner() { 1629 assertTrue("startLegacyVpnRunner not called after " + TIMEOUT_MS + " ms", 1630 mStartLegacyVpnCv.block(TIMEOUT_MS)); 1631 1632 // startLegacyVpn calls stopVpnRunnerPrivileged, which will open mStopVpnRunnerCv, just 1633 // before calling startLegacyVpnRunner. Restore mStopVpnRunnerCv, so the test can expect 1634 // that the VpnRunner is stopped and immediately restarted by calling 1635 // expectStartLegacyVpnRunner() and expectStopVpnRunnerPrivileged() back-to-back. 1636 mStopVpnRunnerCv = new ConditionVariable(); 1637 } 1638 1639 @Override stopVpnRunnerPrivileged()1640 public void stopVpnRunnerPrivileged() { 1641 if (mVpnRunner != null) { 1642 super.stopVpnRunnerPrivileged(); 1643 disconnect(); 1644 mStartLegacyVpnCv = new ConditionVariable(); 1645 } 1646 mVpnRunner = null; 1647 mStopVpnRunnerCv.open(); 1648 } 1649 expectStopVpnRunnerPrivileged()1650 public void expectStopVpnRunnerPrivileged() { 1651 assertTrue("stopVpnRunnerPrivileged not called after " + TIMEOUT_MS + " ms", 1652 mStopVpnRunnerCv.block(TIMEOUT_MS)); 1653 } 1654 1655 @Override getUnderlyingNetworkInfo()1656 public synchronized UnderlyingNetworkInfo getUnderlyingNetworkInfo() { 1657 if (mUnderlyingNetworkInfo != null) return mUnderlyingNetworkInfo; 1658 1659 return super.getUnderlyingNetworkInfo(); 1660 } 1661 setUnderlyingNetworkInfo( UnderlyingNetworkInfo underlyingNetworkInfo)1662 private synchronized void setUnderlyingNetworkInfo( 1663 UnderlyingNetworkInfo underlyingNetworkInfo) { 1664 mUnderlyingNetworkInfo = underlyingNetworkInfo; 1665 } 1666 } 1667 toUidRangeStableParcels(final @NonNull Set<UidRange> ranges)1668 private UidRangeParcel[] toUidRangeStableParcels(final @NonNull Set<UidRange> ranges) { 1669 return ranges.stream().map( 1670 r -> new UidRangeParcel(r.start, r.stop)).toArray(UidRangeParcel[]::new); 1671 } 1672 intToUidRangeStableParcels(final @NonNull Set<Integer> ranges)1673 private UidRangeParcel[] intToUidRangeStableParcels(final @NonNull Set<Integer> ranges) { 1674 return ranges.stream().map(r -> new UidRangeParcel(r, r)).toArray(UidRangeParcel[]::new); 1675 } 1676 assertVpnTransportInfo(NetworkCapabilities nc, int type)1677 private void assertVpnTransportInfo(NetworkCapabilities nc, int type) { 1678 assertNotNull(nc); 1679 final TransportInfo ti = nc.getTransportInfo(); 1680 assertTrue("VPN TransportInfo is not a VpnTransportInfo: " + ti, 1681 ti instanceof VpnTransportInfo); 1682 assertEquals(type, ((VpnTransportInfo) ti).getType()); 1683 1684 } 1685 processBroadcast(Intent intent)1686 private void processBroadcast(Intent intent) { 1687 mServiceContext.sendBroadcast(intent); 1688 waitForIdle(); 1689 } 1690 mockVpn(int uid)1691 private void mockVpn(int uid) { 1692 int userId = UserHandle.getUserId(uid); 1693 mMockVpn = new MockVpn(userId); 1694 } 1695 mockUidNetworkingBlocked()1696 private void mockUidNetworkingBlocked() { 1697 doAnswer(i -> isUidBlocked(mBlockedReasons, i.getArgument(1)) 1698 ).when(mNetworkPolicyManager).isUidNetworkingBlocked(anyInt(), anyBoolean()); 1699 } 1700 isUidBlocked(int blockedReasons, boolean meteredNetwork)1701 private boolean isUidBlocked(int blockedReasons, boolean meteredNetwork) { 1702 final int blockedOnAllNetworksReason = (blockedReasons & ~BLOCKED_METERED_REASON_MASK); 1703 if (blockedOnAllNetworksReason != BLOCKED_REASON_NONE) { 1704 return true; 1705 } 1706 if (meteredNetwork) { 1707 return blockedReasons != BLOCKED_REASON_NONE; 1708 } 1709 return false; 1710 } 1711 setBlockedReasonChanged(int blockedReasons)1712 private void setBlockedReasonChanged(int blockedReasons) { 1713 mBlockedReasons = blockedReasons; 1714 mPolicyCallback.onUidBlockedReasonChanged(Process.myUid(), blockedReasons); 1715 } 1716 getNat464Xlat(NetworkAgentWrapper mna)1717 private Nat464Xlat getNat464Xlat(NetworkAgentWrapper mna) { 1718 return mService.getNetworkAgentInfoForNetwork(mna.getNetwork()).clatd; 1719 } 1720 1721 private class WrappedMultinetworkPolicyTracker extends MultinetworkPolicyTracker { 1722 volatile int mConfigMeteredMultipathPreference; 1723 WrappedMultinetworkPolicyTracker(Context c, Handler h, Runnable r)1724 WrappedMultinetworkPolicyTracker(Context c, Handler h, Runnable r) { 1725 super(c, h, r, new MultinetworkPolicyTrackerTestDependencies(mResources)); 1726 } 1727 1728 @Override configMeteredMultipathPreference()1729 public int configMeteredMultipathPreference() { 1730 return mConfigMeteredMultipathPreference; 1731 } 1732 } 1733 1734 /** 1735 * Wait up to TIMEOUT_MS for {@code conditionVariable} to open. 1736 * Fails if TIMEOUT_MS goes by before {@code conditionVariable} opens. 1737 */ waitFor(ConditionVariable conditionVariable)1738 static private void waitFor(ConditionVariable conditionVariable) { 1739 if (conditionVariable.block(TIMEOUT_MS)) { 1740 return; 1741 } 1742 fail("ConditionVariable was blocked for more than " + TIMEOUT_MS + "ms"); 1743 } 1744 doAsUid(final int uid, @NonNull final Supplier<T> what)1745 private <T> T doAsUid(final int uid, @NonNull final Supplier<T> what) { 1746 mDeps.setCallingUid(uid); 1747 try { 1748 return what.get(); 1749 } finally { 1750 mDeps.setCallingUid(null); 1751 } 1752 } 1753 doAsUid(final int uid, @NonNull final Runnable what)1754 private void doAsUid(final int uid, @NonNull final Runnable what) { 1755 doAsUid(uid, () -> { 1756 what.run(); return Void.TYPE; 1757 }); 1758 } 1759 registerNetworkCallbackAsUid(NetworkRequest request, NetworkCallback callback, int uid)1760 private void registerNetworkCallbackAsUid(NetworkRequest request, NetworkCallback callback, 1761 int uid) { 1762 doAsUid(uid, () -> { 1763 mCm.registerNetworkCallback(request, callback); 1764 }); 1765 } 1766 registerDefaultNetworkCallbackAsUid(@onNull final NetworkCallback callback, final int uid)1767 private void registerDefaultNetworkCallbackAsUid(@NonNull final NetworkCallback callback, 1768 final int uid) { 1769 doAsUid(uid, () -> { 1770 mCm.registerDefaultNetworkCallback(callback); 1771 waitForIdle(); 1772 }); 1773 } 1774 withPermission(String permission, ThrowingRunnable r)1775 private void withPermission(String permission, ThrowingRunnable r) throws Exception { 1776 try { 1777 mServiceContext.setPermission(permission, PERMISSION_GRANTED); 1778 r.run(); 1779 } finally { 1780 mServiceContext.setPermission(permission, null); 1781 } 1782 } 1783 withPermission(String permission, int pid, int uid, ThrowingRunnable r)1784 private void withPermission(String permission, int pid, int uid, ThrowingRunnable r) 1785 throws Exception { 1786 try { 1787 mServiceContext.setPermission(permission, pid, uid, PERMISSION_GRANTED); 1788 r.run(); 1789 } finally { 1790 mServiceContext.setPermission(permission, pid, uid, null); 1791 } 1792 } 1793 1794 private static final int PRIMARY_USER = 0; 1795 private static final int SECONDARY_USER = 10; 1796 private static final int TERTIARY_USER = 11; 1797 private static final UidRange PRIMARY_UIDRANGE = 1798 UidRange.createForUser(UserHandle.of(PRIMARY_USER)); 1799 private static final int APP1_UID = UserHandle.getUid(PRIMARY_USER, 10100); 1800 private static final int APP2_UID = UserHandle.getUid(PRIMARY_USER, 10101); 1801 private static final int VPN_UID = UserHandle.getUid(PRIMARY_USER, 10043); 1802 private static final UserInfo PRIMARY_USER_INFO = new UserInfo(PRIMARY_USER, "", 1803 UserInfo.FLAG_PRIMARY); 1804 private static final UserHandle PRIMARY_USER_HANDLE = new UserHandle(PRIMARY_USER); 1805 private static final UserHandle SECONDARY_USER_HANDLE = new UserHandle(SECONDARY_USER); 1806 private static final UserHandle TERTIARY_USER_HANDLE = new UserHandle(TERTIARY_USER); 1807 1808 private static final int RESTRICTED_USER = 1; 1809 private static final UserInfo RESTRICTED_USER_INFO = new UserInfo(RESTRICTED_USER, "", 1810 UserInfo.FLAG_RESTRICTED); 1811 static { 1812 RESTRICTED_USER_INFO.restrictedProfileParentId = PRIMARY_USER; 1813 } 1814 1815 @Before setUp()1816 public void setUp() throws Exception { 1817 mNetIdManager = new TestNetIdManager(); 1818 1819 mContext = InstrumentationRegistry.getContext(); 1820 1821 MockitoAnnotations.initMocks(this); 1822 1823 doReturn(asList(PRIMARY_USER_INFO)).when(mUserManager).getAliveUsers(); 1824 doReturn(asList(PRIMARY_USER_HANDLE)).when(mUserManager).getUserHandles(anyBoolean()); 1825 doReturn(PRIMARY_USER_INFO).when(mUserManager).getUserInfo(PRIMARY_USER); 1826 // canHaveRestrictedProfile does not take a userId. It applies to the userId of the context 1827 // it was started from, i.e., PRIMARY_USER. 1828 doReturn(true).when(mUserManager).canHaveRestrictedProfile(); 1829 doReturn(RESTRICTED_USER_INFO).when(mUserManager).getUserInfo(RESTRICTED_USER); 1830 1831 final ApplicationInfo applicationInfo = new ApplicationInfo(); 1832 applicationInfo.targetSdkVersion = Build.VERSION_CODES.Q; 1833 doReturn(applicationInfo).when(mPackageManager) 1834 .getApplicationInfoAsUser(anyString(), anyInt(), any()); 1835 doReturn(applicationInfo.targetSdkVersion).when(mPackageManager) 1836 .getTargetSdkVersion(anyString()); 1837 doReturn(new int[0]).when(mSystemConfigManager).getSystemPermissionUids(anyString()); 1838 1839 // InstrumentationTestRunner prepares a looper, but AndroidJUnitRunner does not. 1840 // http://b/25897652 . 1841 if (Looper.myLooper() == null) { 1842 Looper.prepare(); 1843 } 1844 mockDefaultPackages(); 1845 mockHasSystemFeature(FEATURE_WIFI, true); 1846 mockHasSystemFeature(FEATURE_WIFI_DIRECT, true); 1847 mockHasSystemFeature(FEATURE_ETHERNET, true); 1848 doReturn(true).when(mTelephonyManager).isDataCapable(); 1849 1850 FakeSettingsProvider.clearSettingsProvider(); 1851 mServiceContext = new MockContext(InstrumentationRegistry.getContext(), 1852 new FakeSettingsProvider()); 1853 mServiceContext.setUseRegisteredHandlers(true); 1854 mServiceContext.setPermission(NETWORK_FACTORY, PERMISSION_GRANTED); 1855 mServiceContext.setPermission(NETWORK_STACK, PERMISSION_GRANTED); 1856 mServiceContext.setPermission(CONTROL_OEM_PAID_NETWORK_PREFERENCE, PERMISSION_GRANTED); 1857 mServiceContext.setPermission(PACKET_KEEPALIVE_OFFLOAD, PERMISSION_GRANTED); 1858 mServiceContext.setPermission(CONNECTIVITY_USE_RESTRICTED_NETWORKS, PERMISSION_GRANTED); 1859 1860 mAlarmManagerThread = new HandlerThread("TestAlarmManager"); 1861 mAlarmManagerThread.start(); 1862 initAlarmManager(mAlarmManager, mAlarmManagerThread.getThreadHandler()); 1863 1864 mCsHandlerThread = new HandlerThread("TestConnectivityService"); 1865 mProxyTracker = new ProxyTracker(mServiceContext, mock(Handler.class), 1866 16 /* EVENT_PROXY_HAS_CHANGED */); 1867 1868 initMockedResources(); 1869 final Context mockResContext = mock(Context.class); 1870 doReturn(mResources).when(mockResContext).getResources(); 1871 ConnectivityResources.setResourcesContextForTest(mockResContext); 1872 mDeps = new ConnectivityServiceDependencies(mockResContext); 1873 mAutoOnOffKeepaliveDependencies = 1874 new AutomaticOnOffKeepaliveTrackerDependencies(mServiceContext); 1875 mService = new ConnectivityService(mServiceContext, 1876 mMockDnsResolver, 1877 mock(IpConnectivityLog.class), 1878 mMockNetd, 1879 mDeps); 1880 mService.mLingerDelayMs = TEST_LINGER_DELAY_MS; 1881 mService.mNascentDelayMs = TEST_NASCENT_DELAY_MS; 1882 1883 final ArgumentCaptor<NetworkPolicyCallback> policyCallbackCaptor = 1884 ArgumentCaptor.forClass(NetworkPolicyCallback.class); 1885 verify(mNetworkPolicyManager).registerNetworkPolicyCallback(any(), 1886 policyCallbackCaptor.capture()); 1887 mPolicyCallback = policyCallbackCaptor.getValue(); 1888 1889 // Create local CM before sending system ready so that we can answer 1890 // getSystemService() correctly. 1891 mCm = new WrappedConnectivityManager(InstrumentationRegistry.getContext(), mService); 1892 mService.systemReadyInternal(); 1893 verify(mMockDnsResolver).registerUnsolicitedEventListener(any()); 1894 1895 mockVpn(Process.myUid()); 1896 mCm.bindProcessToNetwork(null); 1897 mQosCallbackTracker = mock(QosCallbackTracker.class); 1898 1899 // Ensure that the default setting for Captive Portals is used for most tests 1900 setCaptivePortalMode(ConnectivitySettingsManager.CAPTIVE_PORTAL_MODE_PROMPT); 1901 setAlwaysOnNetworks(false); 1902 setPrivateDnsSettings(PRIVATE_DNS_MODE_OFF, "ignored.example.com"); 1903 } 1904 initMockedResources()1905 private void initMockedResources() { 1906 doReturn(60000).when(mResources).getInteger(R.integer.config_networkTransitionTimeout); 1907 doReturn("").when(mResources).getString(R.string.config_networkCaptivePortalServerUrl); 1908 doReturn(new String[]{ WIFI_WOL_IFNAME }).when(mResources).getStringArray( 1909 R.array.config_wakeonlan_supported_interfaces); 1910 doReturn(new String[] { "0,1", "1,3" }).when(mResources).getStringArray( 1911 R.array.config_networkSupportedKeepaliveCount); 1912 doReturn(new String[0]).when(mResources).getStringArray( 1913 R.array.config_networkNotifySwitches); 1914 doReturn(new int[]{10, 11, 12, 14, 15}).when(mResources).getIntArray( 1915 R.array.config_protectedNetworks); 1916 // We don't test the actual notification value strings, so just return an empty array. 1917 // It doesn't matter what the values are as long as it's not null. 1918 doReturn(new String[0]).when(mResources) 1919 .getStringArray(R.array.network_switch_type_name); 1920 1921 doReturn(R.array.config_networkSupportedKeepaliveCount).when(mResources) 1922 .getIdentifier(eq("config_networkSupportedKeepaliveCount"), eq("array"), any()); 1923 doReturn(R.array.network_switch_type_name).when(mResources) 1924 .getIdentifier(eq("network_switch_type_name"), eq("array"), any()); 1925 doReturn(1).when(mResources).getInteger(R.integer.config_networkAvoidBadWifi); 1926 doReturn(0).when(mResources).getInteger(R.integer.config_activelyPreferBadWifi); 1927 doReturn(true).when(mResources) 1928 .getBoolean(R.bool.config_cellular_radio_timesharing_capable); 1929 doReturn(PACKET_WAKEUP_MARK_MASK).when(mResources).getInteger( 1930 R.integer.config_networkWakeupPacketMask); 1931 doReturn(PACKET_WAKEUP_MARK_MASK).when(mResources).getInteger( 1932 R.integer.config_networkWakeupPacketMark); 1933 } 1934 1935 class ConnectivityServiceDependencies extends ConnectivityService.Dependencies { 1936 final ConnectivityResources mConnRes; 1937 final ArraySet<Pair<Long, Integer>> mEnabledChangeIds = new ArraySet<>(); 1938 ConnectivityServiceDependencies(final Context mockResContext)1939 ConnectivityServiceDependencies(final Context mockResContext) { 1940 mConnRes = new ConnectivityResources(mockResContext); 1941 } 1942 1943 @Override makeHandlerThread()1944 public HandlerThread makeHandlerThread() { 1945 return mCsHandlerThread; 1946 } 1947 1948 @Override getNetworkStack()1949 public NetworkStackClientBase getNetworkStack() { 1950 return mNetworkStack; 1951 } 1952 1953 @Override makeProxyTracker(final Context context, final Handler handler)1954 public ProxyTracker makeProxyTracker(final Context context, final Handler handler) { 1955 return mProxyTracker; 1956 } 1957 1958 @Override makeNetIdManager()1959 public NetIdManager makeNetIdManager() { 1960 return mNetIdManager; 1961 } 1962 1963 @Override queryUserAccess(final int uid, final Network network, final ConnectivityService cs)1964 public boolean queryUserAccess(final int uid, final Network network, 1965 final ConnectivityService cs) { 1966 return true; 1967 } 1968 1969 @Override makeMultinetworkPolicyTracker(final Context c, final Handler h, final Runnable r)1970 public MultinetworkPolicyTracker makeMultinetworkPolicyTracker(final Context c, 1971 final Handler h, final Runnable r) { 1972 if (null != mPolicyTracker) { 1973 throw new IllegalStateException("Multinetwork policy tracker already initialized"); 1974 } 1975 mPolicyTracker = new WrappedMultinetworkPolicyTracker(mServiceContext, h, r); 1976 return mPolicyTracker; 1977 } 1978 1979 @Override makeAutomaticOnOffKeepaliveTracker(final Context c, final Handler h)1980 public AutomaticOnOffKeepaliveTracker makeAutomaticOnOffKeepaliveTracker(final Context c, 1981 final Handler h) { 1982 return new AutomaticOnOffKeepaliveTracker(c, h, mAutoOnOffKeepaliveDependencies); 1983 } 1984 1985 @Override getResources(final Context ctx)1986 public ConnectivityResources getResources(final Context ctx) { 1987 return mConnRes; 1988 } 1989 1990 @Override makeLocationPermissionChecker(final Context context)1991 public LocationPermissionChecker makeLocationPermissionChecker(final Context context) { 1992 return new LocationPermissionChecker(context) { 1993 @Override 1994 protected int getCurrentUser() { 1995 return runAsShell(CREATE_USERS, () -> super.getCurrentUser()); 1996 } 1997 }; 1998 } 1999 2000 @Override makeCarrierPrivilegeAuthenticator( @onNull final Context context, @NonNull final TelephonyManager tm)2001 public CarrierPrivilegeAuthenticator makeCarrierPrivilegeAuthenticator( 2002 @NonNull final Context context, @NonNull final TelephonyManager tm) { 2003 return mDeps.isAtLeastT() ? mCarrierPrivilegeAuthenticator : null; 2004 } 2005 2006 @Override intentFilterEquals(final PendingIntent a, final PendingIntent b)2007 public boolean intentFilterEquals(final PendingIntent a, final PendingIntent b) { 2008 return runAsShell(GET_INTENT_SENDER_INTENT, () -> a.intentFilterEquals(b)); 2009 } 2010 2011 @GuardedBy("this") 2012 private Integer mCallingUid = null; 2013 2014 @Override getCallingUid()2015 public int getCallingUid() { 2016 synchronized (this) { 2017 if (null != mCallingUid) return mCallingUid; 2018 return super.getCallingUid(); 2019 } 2020 } 2021 2022 // Pass null for the real calling UID setCallingUid(final Integer uid)2023 public void setCallingUid(final Integer uid) { 2024 synchronized (this) { 2025 mCallingUid = uid; 2026 } 2027 } 2028 2029 @GuardedBy("this") 2030 private boolean mCellular464XlatEnabled = true; 2031 2032 @Override getCellular464XlatEnabled()2033 public boolean getCellular464XlatEnabled() { 2034 synchronized (this) { 2035 return mCellular464XlatEnabled; 2036 } 2037 } 2038 setCellular464XlatEnabled(final boolean enabled)2039 public void setCellular464XlatEnabled(final boolean enabled) { 2040 synchronized (this) { 2041 mCellular464XlatEnabled = enabled; 2042 } 2043 } 2044 2045 @GuardedBy("this") 2046 private Integer mConnectionOwnerUid = null; 2047 2048 @Override getConnectionOwnerUid(final int protocol, final InetSocketAddress local, final InetSocketAddress remote)2049 public int getConnectionOwnerUid(final int protocol, final InetSocketAddress local, 2050 final InetSocketAddress remote) { 2051 synchronized (this) { 2052 if (null != mConnectionOwnerUid) return mConnectionOwnerUid; 2053 return super.getConnectionOwnerUid(protocol, local, remote); 2054 } 2055 } 2056 2057 // Pass null to get the production implementation of getConnectionOwnerUid setConnectionOwnerUid(final Integer uid)2058 public void setConnectionOwnerUid(final Integer uid) { 2059 synchronized (this) { 2060 mConnectionOwnerUid = uid; 2061 } 2062 } 2063 2064 final class ReportedInterfaces { 2065 public final Context context; 2066 public final String iface; 2067 public final int[] transportTypes; ReportedInterfaces(final Context c, final String i, final int[] t)2068 ReportedInterfaces(final Context c, final String i, final int[] t) { 2069 context = c; 2070 iface = i; 2071 transportTypes = t; 2072 } 2073 contentEquals(final Context c, final String i, final int[] t)2074 public boolean contentEquals(final Context c, final String i, final int[] t) { 2075 return Objects.equals(context, c) && Objects.equals(iface, i) 2076 && Arrays.equals(transportTypes, t); 2077 } 2078 } 2079 2080 final ArrayTrackRecord<ReportedInterfaces> mReportedInterfaceHistory = 2081 new ArrayTrackRecord<>(); 2082 2083 @Override reportNetworkInterfaceForTransports(final Context context, final String iface, final int[] transportTypes)2084 public void reportNetworkInterfaceForTransports(final Context context, final String iface, 2085 final int[] transportTypes) { 2086 mReportedInterfaceHistory.add(new ReportedInterfaces(context, iface, transportTypes)); 2087 super.reportNetworkInterfaceForTransports(context, iface, transportTypes); 2088 } 2089 2090 @Override isFeatureEnabled(Context context, String name)2091 public boolean isFeatureEnabled(Context context, String name) { 2092 switch (name) { 2093 case ConnectivityFlags.NO_REMATCH_ALL_REQUESTS_ON_REGISTER: 2094 return true; 2095 case KEY_DESTROY_FROZEN_SOCKETS_VERSION: 2096 return true; 2097 default: 2098 return super.isFeatureEnabled(context, name); 2099 } 2100 } 2101 setChangeIdEnabled(final boolean enabled, final long changeId, final int uid)2102 public void setChangeIdEnabled(final boolean enabled, final long changeId, final int uid) { 2103 final Pair<Long, Integer> data = new Pair<>(changeId, uid); 2104 // mEnabledChangeIds is read on the handler thread and maybe the test thread, so 2105 // make sure both threads see it before continuing. 2106 visibleOnHandlerThread(mCsHandlerThread.getThreadHandler(), () -> { 2107 if (enabled) { 2108 mEnabledChangeIds.add(data); 2109 } else { 2110 mEnabledChangeIds.remove(data); 2111 } 2112 }); 2113 } 2114 2115 @Override isChangeEnabled(final long changeId, final int uid)2116 public boolean isChangeEnabled(final long changeId, final int uid) { 2117 return mEnabledChangeIds.contains(new Pair<>(changeId, uid)); 2118 } 2119 2120 // In AOSP, build version codes are all over the place (e.g. at the time of this writing 2121 // U == V). Define custom ones. 2122 private static final int VERSION_UNMOCKED = -1; 2123 private static final int VERSION_R = 1; 2124 private static final int VERSION_S = 2; 2125 private static final int VERSION_T = 3; 2126 private static final int VERSION_U = 4; 2127 private static final int VERSION_V = 5; 2128 private static final int VERSION_MAX = VERSION_V; 2129 private int mSdkLevel = VERSION_UNMOCKED; 2130 setBuildSdk(final int sdkLevel)2131 private void setBuildSdk(final int sdkLevel) { 2132 if (sdkLevel > VERSION_MAX) { 2133 throw new IllegalArgumentException("setBuildSdk must not be called with" 2134 + " Build.VERSION constants but Dependencies.VERSION_* constants"); 2135 } 2136 visibleOnHandlerThread(mCsHandlerThread.getThreadHandler(), () -> mSdkLevel = sdkLevel); 2137 } 2138 2139 @Override isAtLeastS()2140 public boolean isAtLeastS() { 2141 return mSdkLevel == VERSION_UNMOCKED ? super.isAtLeastS() 2142 : mSdkLevel >= VERSION_S; 2143 } 2144 2145 @Override isAtLeastT()2146 public boolean isAtLeastT() { 2147 return mSdkLevel == VERSION_UNMOCKED ? super.isAtLeastT() 2148 : mSdkLevel >= VERSION_T; 2149 } 2150 2151 @Override isAtLeastU()2152 public boolean isAtLeastU() { 2153 return mSdkLevel == VERSION_UNMOCKED ? super.isAtLeastU() 2154 : mSdkLevel >= VERSION_U; 2155 } 2156 2157 @Override getBpfNetMaps(Context context, INetd netd)2158 public BpfNetMaps getBpfNetMaps(Context context, INetd netd) { 2159 return mBpfNetMaps; 2160 } 2161 2162 @Override getClatCoordinator(INetd netd)2163 public ClatCoordinator getClatCoordinator(INetd netd) { 2164 return mClatCoordinator; 2165 } 2166 2167 final ArrayTrackRecord<Pair<String, Long>> mRateLimitHistory = new ArrayTrackRecord<>(); 2168 final Map<String, Long> mActiveRateLimit = new HashMap<>(); 2169 2170 @Override enableIngressRateLimit(final String iface, final long rateInBytesPerSecond)2171 public void enableIngressRateLimit(final String iface, final long rateInBytesPerSecond) { 2172 mRateLimitHistory.add(new Pair<>(iface, rateInBytesPerSecond)); 2173 // Due to a TC limitation, the rate limit needs to be removed before it can be 2174 // updated. Check that this happened. 2175 assertEquals(-1L, (long) mActiveRateLimit.getOrDefault(iface, -1L)); 2176 mActiveRateLimit.put(iface, rateInBytesPerSecond); 2177 // verify that clsact qdisc has already been created, otherwise attaching a tc police 2178 // filter will fail. 2179 try { 2180 verify(mMockNetd).networkAddInterface(anyInt(), eq(iface)); 2181 } catch (RemoteException e) { 2182 fail(e.getMessage()); 2183 } 2184 } 2185 2186 @Override disableIngressRateLimit(final String iface)2187 public void disableIngressRateLimit(final String iface) { 2188 mRateLimitHistory.add(new Pair<>(iface, -1L)); 2189 assertNotEquals(-1L, (long) mActiveRateLimit.getOrDefault(iface, -1L)); 2190 mActiveRateLimit.put(iface, -1L); 2191 } 2192 2193 @Override makeBroadcastOptionsShim(BroadcastOptions options)2194 public BroadcastOptionsShim makeBroadcastOptionsShim(BroadcastOptions options) { 2195 reset(mBroadcastOptionsShim); 2196 return mBroadcastOptionsShim; 2197 } 2198 2199 @GuardedBy("this") 2200 private boolean mForceDisableCompatChangeCheck = true; 2201 2202 /** 2203 * By default, the {@link #isChangeEnabled(long, String, UserHandle)} will always return 2204 * true as the mForceDisableCompatChangeCheck is true and compat change check logic is 2205 * never executed. The compat change check logic can be turned on by calling this method. 2206 * If this method is called, the 2207 * {@link libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges} or 2208 * {@link libcore.junit.util.compat.CoreCompatChangeRule.DisableCompatChanges} must be 2209 * used to turn on/off the compat change flag. 2210 */ enableCompatChangeCheck()2211 private void enableCompatChangeCheck() { 2212 synchronized (this) { 2213 mForceDisableCompatChangeCheck = false; 2214 } 2215 } 2216 2217 @Override isChangeEnabled(long changeId, @NonNull final String packageName, @NonNull final UserHandle user)2218 public boolean isChangeEnabled(long changeId, 2219 @NonNull final String packageName, 2220 @NonNull final UserHandle user) { 2221 synchronized (this) { 2222 if (mForceDisableCompatChangeCheck) { 2223 return false; 2224 } else { 2225 return super.isChangeEnabled(changeId, packageName, user); 2226 } 2227 } 2228 } 2229 2230 // Class to be mocked and used to verify destroy sockets methods call 2231 public class DestroySocketsWrapper { destroyLiveTcpSockets(final Set<Range<Integer>> ranges, final Set<Integer> exemptUids)2232 public void destroyLiveTcpSockets(final Set<Range<Integer>> ranges, 2233 final Set<Integer> exemptUids){} destroyLiveTcpSocketsByOwnerUids(final Set<Integer> ownerUids)2234 public void destroyLiveTcpSocketsByOwnerUids(final Set<Integer> ownerUids){} 2235 } 2236 2237 @Override @SuppressWarnings("DirectInvocationOnMock") destroyLiveTcpSockets(final Set<Range<Integer>> ranges, final Set<Integer> exemptUids)2238 public void destroyLiveTcpSockets(final Set<Range<Integer>> ranges, 2239 final Set<Integer> exemptUids) { 2240 // Call mocked destroyLiveTcpSockets so that test can verify this method call 2241 mDestroySocketsWrapper.destroyLiveTcpSockets(ranges, exemptUids); 2242 } 2243 2244 @Override @SuppressWarnings("DirectInvocationOnMock") destroyLiveTcpSocketsByOwnerUids(final Set<Integer> ownerUids)2245 public void destroyLiveTcpSocketsByOwnerUids(final Set<Integer> ownerUids) { 2246 // Call mocked destroyLiveTcpSocketsByOwnerUids so that test can verify this method call 2247 mDestroySocketsWrapper.destroyLiveTcpSocketsByOwnerUids(ownerUids); 2248 } 2249 2250 final ArrayTrackRecord<Pair<Integer, Long>>.ReadHead mScheduledEvaluationTimeouts = 2251 new ArrayTrackRecord<Pair<Integer, Long>>().newReadHead(); 2252 @Override scheduleEvaluationTimeout(@onNull Handler handler, @NonNull final Network network, final long delayMs)2253 public void scheduleEvaluationTimeout(@NonNull Handler handler, 2254 @NonNull final Network network, final long delayMs) { 2255 mScheduledEvaluationTimeouts.add(new Pair<>(network.netId, delayMs)); 2256 super.scheduleEvaluationTimeout(handler, network, delayMs); 2257 } 2258 } 2259 2260 private class AutomaticOnOffKeepaliveTrackerDependencies 2261 extends AutomaticOnOffKeepaliveTracker.Dependencies { 2262 AutomaticOnOffKeepaliveTrackerDependencies(Context context) { 2263 super(context); 2264 } 2265 2266 @Override 2267 public boolean isFeatureEnabled(@NonNull final String name, final boolean defaultEnabled) { 2268 // Tests for enabling the feature are verified in AutomaticOnOffKeepaliveTrackerTest. 2269 // Assuming enabled here to focus on ConnectivityService tests. 2270 return true; 2271 } 2272 } 2273 2274 private static void initAlarmManager(final AlarmManager am, final Handler alarmHandler) { 2275 doAnswer(inv -> { 2276 final long when = inv.getArgument(1); 2277 final WakeupMessage wakeupMsg = inv.getArgument(3); 2278 final Handler handler = inv.getArgument(4); 2279 2280 long delayMs = when - SystemClock.elapsedRealtime(); 2281 if (delayMs < 0) delayMs = 0; 2282 if (delayMs > UNREASONABLY_LONG_ALARM_WAIT_MS) { 2283 fail("Attempting to send msg more than " + UNREASONABLY_LONG_ALARM_WAIT_MS 2284 + "ms into the future: " + delayMs); 2285 } 2286 alarmHandler.postDelayed(() -> handler.post(wakeupMsg::onAlarm), wakeupMsg /* token */, 2287 delayMs); 2288 2289 return null; 2290 }).when(am).setExact(eq(AlarmManager.ELAPSED_REALTIME_WAKEUP), anyLong(), anyString(), 2291 any(WakeupMessage.class), any()); 2292 2293 doAnswer(inv -> { 2294 final WakeupMessage wakeupMsg = inv.getArgument(0); 2295 alarmHandler.removeCallbacksAndMessages(wakeupMsg /* token */); 2296 return null; 2297 }).when(am).cancel(any(WakeupMessage.class)); 2298 } 2299 2300 @After 2301 public void tearDown() throws Exception { 2302 unregisterDefaultNetworkCallbacks(); 2303 maybeTearDownEnterpriseNetwork(); 2304 setAlwaysOnNetworks(false); 2305 if (mCellAgent != null) { 2306 mCellAgent.disconnect(); 2307 mCellAgent = null; 2308 } 2309 if (mWiFiAgent != null) { 2310 mWiFiAgent.disconnect(); 2311 mWiFiAgent = null; 2312 } 2313 if (mEthernetAgent != null) { 2314 mEthernetAgent.disconnect(); 2315 mEthernetAgent = null; 2316 } 2317 2318 if (mQosCallbackMockHelper != null) { 2319 mQosCallbackMockHelper.tearDown(); 2320 mQosCallbackMockHelper = null; 2321 } 2322 mMockVpn.disconnect(); 2323 waitForIdle(); 2324 2325 FakeSettingsProvider.clearSettingsProvider(); 2326 ConnectivityResources.setResourcesContextForTest(null); 2327 2328 mCsHandlerThread.quitSafely(); 2329 mCsHandlerThread.join(); 2330 mAlarmManagerThread.quitSafely(); 2331 mAlarmManagerThread.join(); 2332 } 2333 2334 private void mockDefaultPackages() throws Exception { 2335 final String myPackageName = mContext.getPackageName(); 2336 final PackageInfo myPackageInfo = mContext.getPackageManager().getPackageInfo( 2337 myPackageName, PackageManager.GET_PERMISSIONS); 2338 doReturn(new String[] {myPackageName}).when(mPackageManager) 2339 .getPackagesForUid(Binder.getCallingUid()); 2340 doReturn(myPackageInfo).when(mPackageManager).getPackageInfoAsUser( 2341 eq(myPackageName), anyInt(), eq(UserHandle.getCallingUserId())); 2342 2343 doReturn(asList(new PackageInfo[] { 2344 buildPackageInfo(/* SYSTEM */ false, APP1_UID), 2345 buildPackageInfo(/* SYSTEM */ false, APP2_UID), 2346 buildPackageInfo(/* SYSTEM */ false, VPN_UID) 2347 })).when(mPackageManager).getInstalledPackagesAsUser(eq(GET_PERMISSIONS), anyInt()); 2348 2349 // Create a fake always-on VPN package. 2350 final int userId = UserHandle.getCallingUserId(); 2351 final ApplicationInfo applicationInfo = new ApplicationInfo(); 2352 applicationInfo.targetSdkVersion = Build.VERSION_CODES.R; // Always-on supported in N+. 2353 doReturn(applicationInfo).when(mPackageManager).getApplicationInfoAsUser( 2354 eq(ALWAYS_ON_PACKAGE), anyInt(), eq(userId)); 2355 2356 // Minimal mocking to keep Vpn#isAlwaysOnPackageSupported happy. 2357 ResolveInfo rInfo = new ResolveInfo(); 2358 rInfo.serviceInfo = new ServiceInfo(); 2359 rInfo.serviceInfo.metaData = new Bundle(); 2360 final List<ResolveInfo> services = asList(new ResolveInfo[]{rInfo}); 2361 doReturn(services).when(mPackageManager).queryIntentServicesAsUser( 2362 any(), eq(PackageManager.GET_META_DATA), eq(userId)); 2363 doReturn(Process.myUid()).when(mPackageManager).getPackageUidAsUser( 2364 TEST_PACKAGE_NAME, userId); 2365 doReturn(VPN_UID).when(mPackageManager).getPackageUidAsUser(ALWAYS_ON_PACKAGE, userId); 2366 } 2367 2368 private void verifyActiveNetwork(int transport) { 2369 // Test getActiveNetworkInfo() 2370 assertNotNull(mCm.getActiveNetworkInfo()); 2371 assertEquals(transportToLegacyType(transport), mCm.getActiveNetworkInfo().getType()); 2372 // Test getActiveNetwork() 2373 assertNotNull(mCm.getActiveNetwork()); 2374 assertEquals(mCm.getActiveNetwork(), mCm.getActiveNetworkForUid(Process.myUid())); 2375 if (!NetworkCapabilities.isValidTransport(transport)) { 2376 throw new IllegalStateException("Unknown transport " + transport); 2377 } 2378 switch (transport) { 2379 case TRANSPORT_WIFI: 2380 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetwork()); 2381 break; 2382 case TRANSPORT_CELLULAR: 2383 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetwork()); 2384 break; 2385 case TRANSPORT_ETHERNET: 2386 assertEquals(mEthernetAgent.getNetwork(), mCm.getActiveNetwork()); 2387 break; 2388 default: 2389 break; 2390 } 2391 // Test getNetworkInfo(Network) 2392 assertNotNull(mCm.getNetworkInfo(mCm.getActiveNetwork())); 2393 assertEquals(transportToLegacyType(transport), 2394 mCm.getNetworkInfo(mCm.getActiveNetwork()).getType()); 2395 assertNotNull(mCm.getActiveNetworkInfoForUid(Process.myUid())); 2396 // Test getNetworkCapabilities(Network) 2397 assertNotNull(mCm.getNetworkCapabilities(mCm.getActiveNetwork())); 2398 assertTrue(mCm.getNetworkCapabilities(mCm.getActiveNetwork()).hasTransport(transport)); 2399 } 2400 2401 private void verifyNoNetwork() { 2402 waitForIdle(); 2403 // Test getActiveNetworkInfo() 2404 assertNull(mCm.getActiveNetworkInfo()); 2405 // Test getActiveNetwork() 2406 assertNull(mCm.getActiveNetwork()); 2407 assertNull(mCm.getActiveNetworkForUid(Process.myUid())); 2408 // Test getAllNetworks() 2409 assertEmpty(mCm.getAllNetworks()); 2410 assertEmpty(mCm.getAllNetworkStateSnapshots()); 2411 } 2412 2413 /** 2414 * Class to simplify expecting broadcasts using BroadcastInterceptingContext. 2415 * Ensures that the receiver is unregistered after the expected broadcast is received. This 2416 * cannot be done in the BroadcastReceiver itself because BroadcastInterceptingContext runs 2417 * the receivers' receive method while iterating over the list of receivers, and unregistering 2418 * the receiver during iteration throws ConcurrentModificationException. 2419 */ 2420 private class ExpectedBroadcast extends CompletableFuture<Intent> { 2421 private final BroadcastReceiver mReceiver; 2422 2423 ExpectedBroadcast(BroadcastReceiver receiver) { 2424 mReceiver = receiver; 2425 } 2426 2427 public Intent expectBroadcast(int timeoutMs) throws Exception { 2428 try { 2429 return get(timeoutMs, TimeUnit.MILLISECONDS); 2430 } catch (TimeoutException e) { 2431 fail("Expected broadcast not received after " + timeoutMs + " ms"); 2432 return null; 2433 } finally { 2434 mServiceContext.unregisterReceiver(mReceiver); 2435 } 2436 } 2437 2438 public Intent expectBroadcast() throws Exception { 2439 return expectBroadcast(BROADCAST_TIMEOUT_MS); 2440 } 2441 2442 public void expectNoBroadcast(int timeoutMs) throws Exception { 2443 waitForIdle(); 2444 try { 2445 final Intent intent = get(timeoutMs, TimeUnit.MILLISECONDS); 2446 fail("Unexpected broadcast: " + intent.getAction() + " " + intent.getExtras()); 2447 } catch (TimeoutException expected) { 2448 } finally { 2449 mServiceContext.unregisterReceiver(mReceiver); 2450 } 2451 } 2452 } 2453 2454 private ExpectedBroadcast registerBroadcastReceiverThat(final String action, final int count, 2455 @NonNull final Predicate<Intent> filter) { 2456 final IntentFilter intentFilter = new IntentFilter(action); 2457 // AtomicReference allows receiver to access expected even though it is constructed later. 2458 final AtomicReference<ExpectedBroadcast> expectedRef = new AtomicReference<>(); 2459 final BroadcastReceiver receiver = new BroadcastReceiver() { 2460 private int mRemaining = count; 2461 public void onReceive(Context context, Intent intent) { 2462 logIntent(intent); 2463 if (!filter.test(intent)) return; 2464 if (--mRemaining == 0) { 2465 expectedRef.get().complete(intent); 2466 } 2467 } 2468 }; 2469 final ExpectedBroadcast expected = new ExpectedBroadcast(receiver); 2470 expectedRef.set(expected); 2471 mServiceContext.registerReceiver(receiver, intentFilter); 2472 return expected; 2473 } 2474 2475 private void logIntent(Intent intent) { 2476 final String action = intent.getAction(); 2477 if (CONNECTIVITY_ACTION.equals(action)) { 2478 final int type = intent.getIntExtra(EXTRA_NETWORK_TYPE, -1); 2479 final NetworkInfo ni = intent.getParcelableExtra(EXTRA_NETWORK_INFO); 2480 Log.d(TAG, "Received " + action + ", type=" + type + " ni=" + ni); 2481 } else if (PROXY_CHANGE_ACTION.equals(action)) { 2482 final ProxyInfo proxy = (ProxyInfo) intent.getExtra( 2483 Proxy.EXTRA_PROXY_INFO, ProxyInfo.buildPacProxy(Uri.EMPTY)); 2484 Log.d(TAG, "Received " + action + ", proxy = " + proxy); 2485 } else { 2486 throw new IllegalArgumentException("Unsupported logging " + action); 2487 } 2488 } 2489 2490 /** Expects that {@code count} CONNECTIVITY_ACTION broadcasts are received. */ 2491 private ExpectedBroadcast expectConnectivityAction(final int count) { 2492 return registerBroadcastReceiverThat(CONNECTIVITY_ACTION, count, intent -> true); 2493 } 2494 2495 private ExpectedBroadcast expectConnectivityAction(int type, NetworkInfo.DetailedState state) { 2496 return registerBroadcastReceiverThat(CONNECTIVITY_ACTION, 1, intent -> { 2497 final int actualType = intent.getIntExtra(EXTRA_NETWORK_TYPE, -1); 2498 final NetworkInfo ni = intent.getParcelableExtra(EXTRA_NETWORK_INFO); 2499 return type == actualType 2500 && state == ni.getDetailedState() 2501 && extraInfoInBroadcastHasExpectedNullness(ni); 2502 }); 2503 } 2504 2505 /** Expects that PROXY_CHANGE_ACTION broadcast is received. */ 2506 private ExpectedBroadcast expectProxyChangeAction() { 2507 return registerBroadcastReceiverThat(PROXY_CHANGE_ACTION, 1, intent -> true); 2508 } 2509 2510 private ExpectedBroadcast expectProxyChangeAction(ProxyInfo proxy) { 2511 return expectProxyChangeAction(actualProxy -> proxy.equals(actualProxy)); 2512 } 2513 2514 private ExpectedBroadcast expectProxyChangeAction(Predicate<ProxyInfo> tester) { 2515 return registerBroadcastReceiverThat(PROXY_CHANGE_ACTION, 1, intent -> { 2516 final ProxyInfo actualProxy = (ProxyInfo) intent.getExtra(Proxy.EXTRA_PROXY_INFO, 2517 ProxyInfo.buildPacProxy(Uri.EMPTY)); 2518 return tester.test(actualProxy); 2519 }); 2520 } 2521 2522 private boolean extraInfoInBroadcastHasExpectedNullness(NetworkInfo ni) { 2523 final DetailedState state = ni.getDetailedState(); 2524 if (state == DetailedState.CONNECTED && ni.getExtraInfo() == null) return false; 2525 // Expect a null extraInfo if the network is CONNECTING, because a CONNECTIVITY_ACTION 2526 // broadcast with a state of CONNECTING only happens due to legacy VPN lockdown, which also 2527 // nulls out extraInfo. 2528 if (state == DetailedState.CONNECTING && ni.getExtraInfo() != null) return false; 2529 // Can't make any assertions about DISCONNECTED broadcasts. When a network actually 2530 // disconnects, disconnectAndDestroyNetwork sets its state to DISCONNECTED and its extraInfo 2531 // to null. But if the DISCONNECTED broadcast is just simulated by LegacyTypeTracker due to 2532 // a network switch, extraInfo will likely be populated. 2533 // This is likely a bug in CS, but likely not one we can fix without impacting apps. 2534 return true; 2535 } 2536 2537 @Test 2538 public void testNetworkTypes() { 2539 // Ensure that our mocks for the networkAttributes config variable work as expected. If they 2540 // don't, then tests that depend on CONNECTIVITY_ACTION broadcasts for these network types 2541 // will fail. Failing here is much easier to debug. 2542 assertTrue(mCm.isNetworkSupported(TYPE_WIFI)); 2543 assertTrue(mCm.isNetworkSupported(TYPE_MOBILE)); 2544 assertTrue(mCm.isNetworkSupported(TYPE_MOBILE_MMS)); 2545 assertTrue(mCm.isNetworkSupported(TYPE_MOBILE_FOTA)); 2546 assertFalse(mCm.isNetworkSupported(TYPE_PROXY)); 2547 2548 // Check that TYPE_ETHERNET is supported. Unlike the asserts above, which only validate our 2549 // mocks, this assert exercises the ConnectivityService code path that ensures that 2550 // TYPE_ETHERNET is supported if the ethernet service is running. 2551 assertTrue(mCm.isNetworkSupported(TYPE_ETHERNET)); 2552 } 2553 2554 @Test 2555 public void testNetworkFeature() throws Exception { 2556 // Connect the cell agent and wait for the connected broadcast. 2557 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 2558 mCellAgent.addCapability(NET_CAPABILITY_SUPL); 2559 ExpectedBroadcast b = expectConnectivityAction(TYPE_MOBILE, DetailedState.CONNECTED); 2560 mCellAgent.connect(true); 2561 b.expectBroadcast(); 2562 2563 // Build legacy request for SUPL. 2564 final NetworkCapabilities legacyCaps = new NetworkCapabilities(); 2565 legacyCaps.addTransportType(TRANSPORT_CELLULAR); 2566 legacyCaps.addCapability(NET_CAPABILITY_SUPL); 2567 final NetworkRequest legacyRequest = new NetworkRequest(legacyCaps, TYPE_MOBILE_SUPL, 2568 ConnectivityManager.REQUEST_ID_UNSET, NetworkRequest.Type.REQUEST); 2569 2570 // File request, withdraw it and make sure no broadcast is sent 2571 b = expectConnectivityAction(1); 2572 final TestNetworkCallback callback = new TestNetworkCallback(); 2573 mCm.requestNetwork(legacyRequest, callback); 2574 callback.expect(AVAILABLE, mCellAgent); 2575 mCm.unregisterNetworkCallback(callback); 2576 b.expectNoBroadcast(800); // 800ms long enough to at least flake if this is sent 2577 2578 // Disconnect the network and expect mobile disconnected broadcast. 2579 b = expectConnectivityAction(TYPE_MOBILE, DetailedState.DISCONNECTED); 2580 mCellAgent.disconnect(); 2581 b.expectBroadcast(); 2582 } 2583 2584 @Test 2585 public void testLingering() throws Exception { 2586 verifyNoNetwork(); 2587 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 2588 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 2589 assertNull(mCm.getActiveNetworkInfo()); 2590 assertNull(mCm.getActiveNetwork()); 2591 // Test bringing up validated cellular. 2592 ExpectedBroadcast b = expectConnectivityAction(TYPE_MOBILE, DetailedState.CONNECTED); 2593 mCellAgent.connect(true); 2594 b.expectBroadcast(); 2595 verifyActiveNetwork(TRANSPORT_CELLULAR); 2596 assertLength(2, mCm.getAllNetworks()); 2597 assertTrue(mCm.getAllNetworks()[0].equals(mCm.getActiveNetwork()) 2598 || mCm.getAllNetworks()[1].equals(mCm.getActiveNetwork())); 2599 assertTrue(mCm.getAllNetworks()[0].equals(mWiFiAgent.getNetwork()) 2600 || mCm.getAllNetworks()[1].equals(mWiFiAgent.getNetwork())); 2601 // Test bringing up validated WiFi. 2602 b = expectConnectivityAction(2); 2603 mWiFiAgent.connect(true); 2604 b.expectBroadcast(); 2605 verifyActiveNetwork(TRANSPORT_WIFI); 2606 assertLength(2, mCm.getAllNetworks()); 2607 assertTrue(mCm.getAllNetworks()[0].equals(mCm.getActiveNetwork()) 2608 || mCm.getAllNetworks()[1].equals(mCm.getActiveNetwork())); 2609 assertTrue(mCm.getAllNetworks()[0].equals(mCellAgent.getNetwork()) 2610 || mCm.getAllNetworks()[1].equals(mCellAgent.getNetwork())); 2611 // Test cellular linger timeout. 2612 mCellAgent.expectDisconnected(); 2613 waitForIdle(); 2614 assertLength(1, mCm.getAllNetworks()); 2615 verifyActiveNetwork(TRANSPORT_WIFI); 2616 assertLength(1, mCm.getAllNetworks()); 2617 assertEquals(mCm.getAllNetworks()[0], mCm.getActiveNetwork()); 2618 // Test WiFi disconnect. 2619 b = expectConnectivityAction(1); 2620 mWiFiAgent.disconnect(); 2621 b.expectBroadcast(); 2622 verifyNoNetwork(); 2623 } 2624 2625 /** 2626 * Verify a newly created network will be inactive instead of torn down even if no one is 2627 * requesting. 2628 */ 2629 @Test 2630 public void testNewNetworkInactive() throws Exception { 2631 // Create a callback that monitoring the testing network. 2632 final TestNetworkCallback listenCallback = new TestNetworkCallback(); 2633 mCm.registerNetworkCallback(new NetworkRequest.Builder().build(), listenCallback); 2634 2635 // 1. Create a network that is not requested by anyone, and does not satisfy any of the 2636 // default requests. Verify that the network will be inactive instead of torn down. 2637 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 2638 mWiFiAgent.connectWithoutInternet(); 2639 listenCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 2640 listenCallback.assertNoCallback(); 2641 2642 // Verify that the network will be torn down after nascent expiry. A small period of time 2643 // is added in case of flakiness. 2644 final int nascentTimeoutMs = 2645 mService.mNascentDelayMs + mService.mNascentDelayMs / 4; 2646 listenCallback.expect(LOST, mWiFiAgent, nascentTimeoutMs); 2647 2648 // 2. Create a network that is satisfied by a request comes later. 2649 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 2650 mWiFiAgent.connectWithoutInternet(); 2651 listenCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 2652 final NetworkRequest wifiRequest = new NetworkRequest.Builder() 2653 .addTransportType(TRANSPORT_WIFI).build(); 2654 final TestNetworkCallback wifiCallback = new TestNetworkCallback(); 2655 mCm.requestNetwork(wifiRequest, wifiCallback); 2656 wifiCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 2657 2658 // Verify that the network will be kept since the request is still satisfied. And is able 2659 // to get disconnected as usual if the request is released after the nascent timer expires. 2660 listenCallback.assertNoCallback(nascentTimeoutMs); 2661 mCm.unregisterNetworkCallback(wifiCallback); 2662 listenCallback.expect(LOST, mWiFiAgent); 2663 2664 // 3. Create a network that is satisfied by a request comes later. 2665 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 2666 mWiFiAgent.connectWithoutInternet(); 2667 listenCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 2668 mCm.requestNetwork(wifiRequest, wifiCallback); 2669 wifiCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 2670 2671 // Verify that the network will still be torn down after the request gets removed. 2672 mCm.unregisterNetworkCallback(wifiCallback); 2673 listenCallback.expect(LOST, mWiFiAgent); 2674 2675 // There is no need to ensure that LOSING is never sent in the common case that the 2676 // network immediately satisfies a request that was already present, because it is already 2677 // verified anywhere whenever {@code TestNetworkCallback#expectAvailable*} is called. 2678 2679 mCm.unregisterNetworkCallback(listenCallback); 2680 } 2681 2682 /** 2683 * Verify a newly created network will be inactive and switch to background if only background 2684 * request is satisfied. 2685 */ 2686 @Test 2687 public void testNewNetworkInactive_bgNetwork() throws Exception { 2688 // Create a callback that monitoring the wifi network. 2689 final TestNetworkCallback wifiListenCallback = new TestNetworkCallback(); 2690 mCm.registerNetworkCallback(new NetworkRequest.Builder() 2691 .addTransportType(TRANSPORT_WIFI).build(), wifiListenCallback); 2692 2693 // Create callbacks that can monitor background and foreground mobile networks. 2694 // This is done by granting using background networks permission before registration. Thus, 2695 // the service will not add {@code NET_CAPABILITY_FOREGROUND} by default. 2696 grantUsingBackgroundNetworksPermissionForUid(Binder.getCallingUid()); 2697 final TestNetworkCallback bgMobileListenCallback = new TestNetworkCallback(); 2698 final TestNetworkCallback fgMobileListenCallback = new TestNetworkCallback(); 2699 mCm.registerNetworkCallback(new NetworkRequest.Builder() 2700 .addTransportType(TRANSPORT_CELLULAR).build(), bgMobileListenCallback); 2701 mCm.registerNetworkCallback(new NetworkRequest.Builder() 2702 .addTransportType(TRANSPORT_CELLULAR) 2703 .addCapability(NET_CAPABILITY_FOREGROUND).build(), fgMobileListenCallback); 2704 2705 // Connect wifi, which satisfies default request. 2706 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 2707 mWiFiAgent.connect(true); 2708 wifiListenCallback.expectAvailableThenValidatedCallbacks(mWiFiAgent); 2709 2710 // Connect a cellular network, verify that satisfies only the background callback. 2711 setAlwaysOnNetworks(true); 2712 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 2713 mCellAgent.connect(true); 2714 bgMobileListenCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 2715 fgMobileListenCallback.assertNoCallback(); 2716 assertFalse(isForegroundNetwork(mCellAgent)); 2717 2718 mCellAgent.disconnect(); 2719 bgMobileListenCallback.expect(LOST, mCellAgent); 2720 fgMobileListenCallback.assertNoCallback(); 2721 2722 mCm.unregisterNetworkCallback(wifiListenCallback); 2723 mCm.unregisterNetworkCallback(bgMobileListenCallback); 2724 mCm.unregisterNetworkCallback(fgMobileListenCallback); 2725 } 2726 2727 @Test 2728 public void testBinderDeathAfterUnregister() throws Exception { 2729 final NetworkCapabilities caps = new NetworkCapabilities.Builder() 2730 .addTransportType(TRANSPORT_WIFI) 2731 .build(); 2732 final Handler handler = new Handler(ConnectivityThread.getInstanceLooper()); 2733 final Messenger messenger = new Messenger(handler); 2734 final CompletableFuture<Binder.DeathRecipient> deathRecipient = new CompletableFuture<>(); 2735 final Binder binder = new Binder() { 2736 private DeathRecipient mDeathRecipient; 2737 @Override 2738 public void linkToDeath(@NonNull final DeathRecipient recipient, final int flags) { 2739 synchronized (this) { 2740 mDeathRecipient = recipient; 2741 } 2742 super.linkToDeath(recipient, flags); 2743 deathRecipient.complete(recipient); 2744 } 2745 2746 @Override 2747 public boolean unlinkToDeath(@NonNull final DeathRecipient recipient, final int flags) { 2748 synchronized (this) { 2749 if (null == mDeathRecipient) { 2750 throw new IllegalStateException(); 2751 } 2752 mDeathRecipient = null; 2753 } 2754 return super.unlinkToDeath(recipient, flags); 2755 } 2756 }; 2757 final NetworkRequest request = mService.listenForNetwork(caps, messenger, binder, 2758 NetworkCallback.FLAG_NONE, mContext.getOpPackageName(), 2759 mContext.getAttributionTag()); 2760 mService.releaseNetworkRequest(request); 2761 deathRecipient.get().binderDied(); 2762 // Wait for the release message to be processed. 2763 waitForIdle(); 2764 // After waitForIdle(), the message was processed and the service didn't crash. 2765 } 2766 2767 // TODO : migrate to @Parameterized 2768 @Test 2769 public void testValidatedCellularOutscoresUnvalidatedWiFi_CanTimeShare() throws Exception { 2770 // The behavior of this test should be the same whether the radio can time share or not. 2771 doTestValidatedCellularOutscoresUnvalidatedWiFi(true); 2772 } 2773 2774 // TODO : migrate to @Parameterized 2775 @Test 2776 public void testValidatedCellularOutscoresUnvalidatedWiFi_CannotTimeShare() throws Exception { 2777 doTestValidatedCellularOutscoresUnvalidatedWiFi(false); 2778 } 2779 2780 private void doTestValidatedCellularOutscoresUnvalidatedWiFi( 2781 final boolean cellRadioTimesharingCapable) throws Exception { 2782 mService.mCellularRadioTimesharingCapable = cellRadioTimesharingCapable; 2783 // Test bringing up unvalidated WiFi 2784 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 2785 ExpectedBroadcast b = expectConnectivityAction(1); 2786 mWiFiAgent.connect(false); 2787 b.expectBroadcast(); 2788 verifyActiveNetwork(TRANSPORT_WIFI); 2789 // Test bringing up unvalidated cellular 2790 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 2791 mCellAgent.connect(false); 2792 waitForIdle(); 2793 verifyActiveNetwork(TRANSPORT_WIFI); 2794 // Test cellular disconnect. 2795 mCellAgent.disconnect(); 2796 waitForIdle(); 2797 verifyActiveNetwork(TRANSPORT_WIFI); 2798 // Test bringing up validated cellular 2799 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 2800 b = expectConnectivityAction(2); 2801 mCellAgent.connect(true); 2802 b.expectBroadcast(); 2803 verifyActiveNetwork(TRANSPORT_CELLULAR); 2804 // Test cellular disconnect. 2805 b = expectConnectivityAction(2); 2806 mCellAgent.disconnect(); 2807 b.expectBroadcast(); 2808 verifyActiveNetwork(TRANSPORT_WIFI); 2809 // Test WiFi disconnect. 2810 b = expectConnectivityAction(1); 2811 mWiFiAgent.disconnect(); 2812 b.expectBroadcast(); 2813 verifyNoNetwork(); 2814 } 2815 2816 // TODO : migrate to @Parameterized 2817 @Test 2818 public void testUnvalidatedWifiOutscoresUnvalidatedCellular_CanTimeShare() throws Exception { 2819 doTestUnvalidatedWifiOutscoresUnvalidatedCellular(true); 2820 } 2821 2822 // TODO : migrate to @Parameterized 2823 @Test 2824 public void testUnvalidatedWifiOutscoresUnvalidatedCellular_CannotTimeShare() throws Exception { 2825 doTestUnvalidatedWifiOutscoresUnvalidatedCellular(false); 2826 } 2827 2828 private void doTestUnvalidatedWifiOutscoresUnvalidatedCellular( 2829 final boolean cellRadioTimesharingCapable) throws Exception { 2830 mService.mCellularRadioTimesharingCapable = cellRadioTimesharingCapable; 2831 // Test bringing up unvalidated cellular. 2832 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 2833 ExpectedBroadcast b = expectConnectivityAction(1); 2834 mCellAgent.connect(false); 2835 b.expectBroadcast(); 2836 verifyActiveNetwork(TRANSPORT_CELLULAR); 2837 // Test bringing up unvalidated WiFi. 2838 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 2839 b = expectConnectivityAction(2); 2840 mWiFiAgent.connect(false); 2841 b.expectBroadcast(); 2842 verifyActiveNetwork(TRANSPORT_WIFI); 2843 // Test WiFi disconnect. 2844 b = expectConnectivityAction(2); 2845 mWiFiAgent.disconnect(); 2846 b.expectBroadcast(); 2847 verifyActiveNetwork(TRANSPORT_CELLULAR); 2848 // Test cellular disconnect. 2849 b = expectConnectivityAction(1); 2850 mCellAgent.disconnect(); 2851 b.expectBroadcast(); 2852 verifyNoNetwork(); 2853 } 2854 2855 // TODO : migrate to @Parameterized 2856 @Test 2857 public void testUnlingeringDoesNotValidate_CanTimeShare() throws Exception { 2858 doTestUnlingeringDoesNotValidate(true); 2859 } 2860 2861 // TODO : migrate to @Parameterized 2862 @Test 2863 public void testUnlingeringDoesNotValidate_CannotTimeShare() throws Exception { 2864 doTestUnlingeringDoesNotValidate(false); 2865 } 2866 2867 private void doTestUnlingeringDoesNotValidate( 2868 final boolean cellRadioTimesharingCapable) throws Exception { 2869 mService.mCellularRadioTimesharingCapable = cellRadioTimesharingCapable; 2870 // Test bringing up unvalidated WiFi. 2871 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 2872 ExpectedBroadcast b = expectConnectivityAction(1); 2873 mWiFiAgent.connect(false); 2874 b.expectBroadcast(); 2875 verifyActiveNetwork(TRANSPORT_WIFI); 2876 assertFalse(mCm.getNetworkCapabilities(mWiFiAgent.getNetwork()).hasCapability( 2877 NET_CAPABILITY_VALIDATED)); 2878 // Test bringing up validated cellular. 2879 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 2880 b = expectConnectivityAction(2); 2881 mCellAgent.connect(true); 2882 b.expectBroadcast(); 2883 verifyActiveNetwork(TRANSPORT_CELLULAR); 2884 assertFalse(mCm.getNetworkCapabilities(mWiFiAgent.getNetwork()).hasCapability( 2885 NET_CAPABILITY_VALIDATED)); 2886 // Test cellular disconnect. 2887 b = expectConnectivityAction(2); 2888 mCellAgent.disconnect(); 2889 b.expectBroadcast(); 2890 verifyActiveNetwork(TRANSPORT_WIFI); 2891 // Unlingering a network should not cause it to be marked as validated. 2892 assertFalse(mCm.getNetworkCapabilities(mWiFiAgent.getNetwork()).hasCapability( 2893 NET_CAPABILITY_VALIDATED)); 2894 } 2895 2896 // TODO : migrate to @Parameterized 2897 @Test 2898 public void testRequestMigrationToSameTransport_CanTimeShare() throws Exception { 2899 // Simulate a device where the cell radio is capable of time sharing 2900 mService.mCellularRadioTimesharingCapable = true; 2901 doTestRequestMigrationToSameTransport(TRANSPORT_CELLULAR, true); 2902 doTestRequestMigrationToSameTransport(TRANSPORT_WIFI, true); 2903 doTestRequestMigrationToSameTransport(TRANSPORT_ETHERNET, true); 2904 } 2905 2906 // TODO : migrate to @Parameterized 2907 @Test 2908 public void testRequestMigrationToSameTransport_CannotTimeShare() throws Exception { 2909 // Simulate a device where the cell radio is not capable of time sharing 2910 mService.mCellularRadioTimesharingCapable = false; 2911 doTestRequestMigrationToSameTransport(TRANSPORT_CELLULAR, false); 2912 doTestRequestMigrationToSameTransport(TRANSPORT_WIFI, true); 2913 doTestRequestMigrationToSameTransport(TRANSPORT_ETHERNET, true); 2914 } 2915 2916 private void doTestRequestMigrationToSameTransport(final int transport, 2917 final boolean expectLingering) throws Exception { 2918 // To speed up tests the linger delay is very short by default in tests but this 2919 // test needs to make sure the delay is not incurred so a longer value is safer (it 2920 // reduces the risk that a bug exists but goes undetected). The alarm manager in the test 2921 // throws and crashes CS if this is set to anything more than the below constant though. 2922 mService.mLingerDelayMs = UNREASONABLY_LONG_ALARM_WAIT_MS; 2923 2924 final TestNetworkCallback generalCb = new TestNetworkCallback(); 2925 final TestNetworkCallback defaultCb = new TestNetworkCallback(); 2926 mCm.registerNetworkCallback( 2927 new NetworkRequest.Builder().addTransportType(transport).build(), 2928 generalCb); 2929 mCm.registerDefaultNetworkCallback(defaultCb); 2930 2931 // Bring up net agent 1 2932 final TestNetworkAgentWrapper net1 = new TestNetworkAgentWrapper(transport); 2933 net1.connect(true); 2934 // Make sure the default request is on net 1 2935 generalCb.expectAvailableThenValidatedCallbacks(net1); 2936 defaultCb.expectAvailableThenValidatedCallbacks(net1); 2937 2938 // Bring up net 2 with primary and mms 2939 final TestNetworkAgentWrapper net2 = new TestNetworkAgentWrapper(transport); 2940 net2.addCapability(NET_CAPABILITY_MMS); 2941 net2.setScore(new NetworkScore.Builder().setTransportPrimary(true).build()); 2942 net2.connect(true); 2943 2944 // Make sure the default request goes to net 2 2945 generalCb.expectAvailableCallbacksUnvalidated(net2); 2946 if (expectLingering) { 2947 generalCb.expectLosing(net1); 2948 } 2949 generalCb.expectCaps(net2, c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 2950 defaultCb.expectAvailableDoubleValidatedCallbacks(net2); 2951 2952 // Make sure cell 1 is unwanted immediately if the radio can't time share, but only 2953 // after some delay if it can. 2954 if (expectLingering) { 2955 net1.assertNotDisconnected(TEST_CALLBACK_TIMEOUT_MS); // always incurs the timeout 2956 generalCb.assertNoCallback(); 2957 // assertNotDisconnected waited for TEST_CALLBACK_TIMEOUT_MS, so waiting for the 2958 // linger period gives TEST_CALLBACK_TIMEOUT_MS time for the event to process. 2959 net1.expectDisconnected(UNREASONABLY_LONG_ALARM_WAIT_MS); 2960 } else { 2961 net1.expectDisconnected(TEST_CALLBACK_TIMEOUT_MS); 2962 } 2963 net1.disconnect(); 2964 generalCb.expect(LOST, net1); 2965 2966 // Remove primary from net 2 2967 net2.setScore(new NetworkScore.Builder().build()); 2968 // Request MMS 2969 final TestNetworkCallback mmsCallback = new TestNetworkCallback(); 2970 mCm.requestNetwork(new NetworkRequest.Builder().addCapability(NET_CAPABILITY_MMS).build(), 2971 mmsCallback); 2972 mmsCallback.expectAvailableCallbacksValidated(net2); 2973 2974 // Bring up net 3 with primary but without MMS 2975 final TestNetworkAgentWrapper net3 = new TestNetworkAgentWrapper(transport); 2976 net3.setScore(new NetworkScore.Builder().setTransportPrimary(true).build()); 2977 net3.connect(true); 2978 2979 // Make sure default goes to net 3, but the MMS request doesn't 2980 generalCb.expectAvailableThenValidatedCallbacks(net3); 2981 defaultCb.expectAvailableDoubleValidatedCallbacks(net3); 2982 mmsCallback.assertNoCallback(); 2983 net2.assertNotDisconnected(TEST_CALLBACK_TIMEOUT_MS); // Always incurs the timeout 2984 2985 // Revoke MMS request and make sure net 2 is torn down with the appropriate delay 2986 mCm.unregisterNetworkCallback(mmsCallback); 2987 if (expectLingering) { 2988 // If the radio can time share, the linger delay hasn't elapsed yet, so apps will 2989 // get LOSING. If the radio can't time share, this is a hard loss, since the last 2990 // request keeping up this network has been removed and the network isn't lingering 2991 // for any other request. 2992 generalCb.expectLosing(net2); 2993 net2.assertNotDisconnected(TEST_CALLBACK_TIMEOUT_MS); 2994 // Timeout 0 because after a while LOST will actually arrive 2995 generalCb.assertNoCallback(0 /* timeoutMs */); 2996 net2.expectDisconnected(UNREASONABLY_LONG_ALARM_WAIT_MS); 2997 } else { 2998 net2.expectDisconnected(TEST_CALLBACK_TIMEOUT_MS); 2999 } 3000 net2.disconnect(); 3001 generalCb.expect(LOST, net2); 3002 defaultCb.assertNoCallback(); 3003 3004 net3.disconnect(); 3005 mCm.unregisterNetworkCallback(defaultCb); 3006 mCm.unregisterNetworkCallback(generalCb); 3007 } 3008 3009 // TODO : migrate to @Parameterized 3010 @Test 3011 public void testCellularOutscoresWeakWifi_CanTimeShare() throws Exception { 3012 // The behavior of this test should be the same whether the radio can time share or not. 3013 doTestCellularOutscoresWeakWifi(true); 3014 } 3015 3016 // TODO : migrate to @Parameterized 3017 @Test 3018 public void testCellularOutscoresWeakWifi_CannotTimeShare() throws Exception { 3019 doTestCellularOutscoresWeakWifi(false); 3020 } 3021 3022 private void doTestCellularOutscoresWeakWifi( 3023 final boolean cellRadioTimesharingCapable) throws Exception { 3024 mService.mCellularRadioTimesharingCapable = cellRadioTimesharingCapable; 3025 // Test bringing up validated cellular. 3026 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 3027 ExpectedBroadcast b = expectConnectivityAction(1); 3028 mCellAgent.connect(true); 3029 b.expectBroadcast(); 3030 verifyActiveNetwork(TRANSPORT_CELLULAR); 3031 // Test bringing up validated WiFi. 3032 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3033 b = expectConnectivityAction(2); 3034 mWiFiAgent.connect(true); 3035 b.expectBroadcast(); 3036 verifyActiveNetwork(TRANSPORT_WIFI); 3037 // Test WiFi getting really weak. 3038 b = expectConnectivityAction(2); 3039 mWiFiAgent.adjustScore(-11); 3040 b.expectBroadcast(); 3041 verifyActiveNetwork(TRANSPORT_CELLULAR); 3042 // Test WiFi restoring signal strength. 3043 b = expectConnectivityAction(2); 3044 mWiFiAgent.adjustScore(11); 3045 b.expectBroadcast(); 3046 verifyActiveNetwork(TRANSPORT_WIFI); 3047 } 3048 3049 // TODO : migrate to @Parameterized 3050 @Test 3051 public void testReapingNetwork_CanTimeShare() throws Exception { 3052 doTestReapingNetwork(true); 3053 } 3054 3055 // TODO : migrate to @Parameterized 3056 @Test 3057 public void testReapingNetwork_CannotTimeShare() throws Exception { 3058 doTestReapingNetwork(false); 3059 } 3060 3061 private void doTestReapingNetwork( 3062 final boolean cellRadioTimesharingCapable) throws Exception { 3063 mService.mCellularRadioTimesharingCapable = cellRadioTimesharingCapable; 3064 // Test bringing up WiFi without NET_CAPABILITY_INTERNET. 3065 // Expect it to be torn down immediately because it satisfies no requests. 3066 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3067 mWiFiAgent.connectWithoutInternet(); 3068 mWiFiAgent.expectDisconnected(); 3069 // Test bringing up cellular without NET_CAPABILITY_INTERNET. 3070 // Expect it to be torn down immediately because it satisfies no requests. 3071 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3072 mCellAgent.connectWithoutInternet(); 3073 mCellAgent.expectDisconnected(); 3074 // Test bringing up validated WiFi. 3075 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3076 final ExpectedBroadcast b = expectConnectivityAction(TYPE_WIFI, DetailedState.CONNECTED); 3077 mWiFiAgent.connect(true); 3078 b.expectBroadcast(); 3079 verifyActiveNetwork(TRANSPORT_WIFI); 3080 // Test bringing up unvalidated cellular. 3081 // Expect it to be torn down because it could never be the highest scoring network 3082 // satisfying the default request even if it validated. 3083 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 3084 mCellAgent.connect(false); 3085 mCellAgent.expectDisconnected(); 3086 verifyActiveNetwork(TRANSPORT_WIFI); 3087 mWiFiAgent.disconnect(); 3088 mWiFiAgent.expectDisconnected(); 3089 } 3090 3091 // TODO : migrate to @Parameterized 3092 @Test 3093 public void testCellularFallback_CanTimeShare() throws Exception { 3094 doTestCellularFallback(true); 3095 } 3096 3097 // TODO : migrate to @Parameterized 3098 @Test 3099 public void testCellularFallback_CannotTimeShare() throws Exception { 3100 doTestCellularFallback(false); 3101 } 3102 3103 private void doTestCellularFallback( 3104 final boolean cellRadioTimesharingCapable) throws Exception { 3105 mService.mCellularRadioTimesharingCapable = cellRadioTimesharingCapable; 3106 // Test bringing up validated cellular. 3107 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 3108 ExpectedBroadcast b = expectConnectivityAction(1); 3109 mCellAgent.connect(true); 3110 b.expectBroadcast(); 3111 verifyActiveNetwork(TRANSPORT_CELLULAR); 3112 // Test bringing up validated WiFi. 3113 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3114 b = expectConnectivityAction(2); 3115 mWiFiAgent.connect(true); 3116 b.expectBroadcast(); 3117 verifyActiveNetwork(TRANSPORT_WIFI); 3118 // Reevaluate WiFi (it'll instantly fail DNS). 3119 b = expectConnectivityAction(2); 3120 assertTrue(mCm.getNetworkCapabilities(mWiFiAgent.getNetwork()).hasCapability( 3121 NET_CAPABILITY_VALIDATED)); 3122 mCm.reportBadNetwork(mWiFiAgent.getNetwork()); 3123 // Should quickly fall back to Cellular. 3124 b.expectBroadcast(); 3125 assertFalse(mCm.getNetworkCapabilities(mWiFiAgent.getNetwork()).hasCapability( 3126 NET_CAPABILITY_VALIDATED)); 3127 verifyActiveNetwork(TRANSPORT_CELLULAR); 3128 // Reevaluate cellular (it'll instantly fail DNS). 3129 b = expectConnectivityAction(2); 3130 assertTrue(mCm.getNetworkCapabilities(mCellAgent.getNetwork()).hasCapability( 3131 NET_CAPABILITY_VALIDATED)); 3132 mCm.reportBadNetwork(mCellAgent.getNetwork()); 3133 // Should quickly fall back to WiFi. 3134 b.expectBroadcast(); 3135 assertFalse(mCm.getNetworkCapabilities(mCellAgent.getNetwork()).hasCapability( 3136 NET_CAPABILITY_VALIDATED)); 3137 assertFalse(mCm.getNetworkCapabilities(mWiFiAgent.getNetwork()).hasCapability( 3138 NET_CAPABILITY_VALIDATED)); 3139 verifyActiveNetwork(TRANSPORT_WIFI); 3140 } 3141 3142 // TODO : migrate to @Parameterized 3143 @Test 3144 public void testWiFiFallback_CanTimeShare() throws Exception { 3145 doTestWiFiFallback(true); 3146 } 3147 3148 // TODO : migrate to @Parameterized 3149 @Test 3150 public void testWiFiFallback_CannotTimeShare() throws Exception { 3151 doTestWiFiFallback(false); 3152 } 3153 3154 private void doTestWiFiFallback( 3155 final boolean cellRadioTimesharingCapable) throws Exception { 3156 mService.mCellularRadioTimesharingCapable = cellRadioTimesharingCapable; 3157 // Test bringing up unvalidated WiFi. 3158 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3159 ExpectedBroadcast b = expectConnectivityAction(1); 3160 mWiFiAgent.connect(false); 3161 b.expectBroadcast(); 3162 verifyActiveNetwork(TRANSPORT_WIFI); 3163 // Test bringing up validated cellular. 3164 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 3165 b = expectConnectivityAction(2); 3166 mCellAgent.connect(true); 3167 b.expectBroadcast(); 3168 verifyActiveNetwork(TRANSPORT_CELLULAR); 3169 // Reevaluate cellular (it'll instantly fail DNS). 3170 b = expectConnectivityAction(2); 3171 assertTrue(mCm.getNetworkCapabilities(mCellAgent.getNetwork()).hasCapability( 3172 NET_CAPABILITY_VALIDATED)); 3173 mCm.reportBadNetwork(mCellAgent.getNetwork()); 3174 // Should quickly fall back to WiFi. 3175 b.expectBroadcast(); 3176 assertFalse(mCm.getNetworkCapabilities(mCellAgent.getNetwork()).hasCapability( 3177 NET_CAPABILITY_VALIDATED)); 3178 verifyActiveNetwork(TRANSPORT_WIFI); 3179 } 3180 3181 @Test 3182 public void testRequiresValidation() { 3183 assertTrue(NetworkMonitorUtils.isValidationRequired(false /* isDunValidationRequired */, 3184 false /* isVpnValidationRequired */, 3185 mCm.getDefaultRequest().networkCapabilities)); 3186 } 3187 3188 /** 3189 * Utility NetworkCallback for testing. The caller must explicitly test for all the callbacks 3190 * this class receives, by calling expect() exactly once each time a callback is 3191 * received. assertNoCallback may be called at any time. 3192 */ 3193 private class TestNetworkCallback extends TestableNetworkCallback { 3194 TestNetworkCallback() { 3195 // In the context of this test, the testable network callbacks should use waitForIdle 3196 // before calling assertNoCallback in an effort to detect issues where a callback is 3197 // not yet sent but a message currently in the queue of a handler will cause it to 3198 // be sent soon. 3199 super(TEST_CALLBACK_TIMEOUT_MS, TEST_CALLBACK_TIMEOUT_MS, 3200 ConnectivityServiceTest.this::waitForIdle); 3201 } 3202 3203 public CallbackEntry.Losing expectLosing(final HasNetwork n, final long timeoutMs) { 3204 final CallbackEntry.Losing losing = expect(LOSING, n, timeoutMs); 3205 final int maxMsToLive = losing.getMaxMsToLive(); 3206 if (maxMsToLive < 0 || maxMsToLive > mService.mLingerDelayMs) { 3207 // maxMsToLive is the value that was received in the onLosing callback. That must 3208 // not be negative, so check that. 3209 // Also, maxMsToLive is the remaining time until the network expires. 3210 // mService.mLingerDelayMs is how long the network takes from when it's first 3211 // detected to be unneeded to when it expires, so maxMsToLive should never 3212 // be greater than that. 3213 fail(String.format("Invalid linger time value %d, must be between %d and %d", 3214 maxMsToLive, 0, mService.mLingerDelayMs)); 3215 } 3216 return losing; 3217 } 3218 3219 public CallbackEntry.Losing expectLosing(final HasNetwork n) { 3220 return expectLosing(n, getDefaultTimeoutMs()); 3221 } 3222 } 3223 3224 // Can't be part of TestNetworkCallback because "cannot be declared static; static methods can 3225 // only be declared in a static or top level type". 3226 static void assertNoCallbacks(final long timeoutMs, TestNetworkCallback ... callbacks) { 3227 for (TestNetworkCallback c : callbacks) { 3228 c.assertNoCallback(timeoutMs); 3229 } 3230 } 3231 3232 static void assertNoCallbacks(TestNetworkCallback ... callbacks) { 3233 for (TestNetworkCallback c : callbacks) { 3234 c.assertNoCallback(); // each callback uses its own timeout 3235 } 3236 } 3237 3238 static void expectOnLost(TestNetworkAgentWrapper network, TestNetworkCallback ... callbacks) { 3239 for (TestNetworkCallback c : callbacks) { 3240 c.expect(LOST, network); 3241 } 3242 } 3243 3244 static void expectAvailableCallbacksUnvalidatedWithSpecifier(TestNetworkAgentWrapper network, 3245 NetworkSpecifier specifier, TestNetworkCallback ... callbacks) { 3246 for (TestNetworkCallback c : callbacks) { 3247 c.expect(AVAILABLE, network); 3248 c.expectCaps(network, cb -> !cb.hasCapability(NET_CAPABILITY_VALIDATED) 3249 && Objects.equals(specifier, cb.getNetworkSpecifier())); 3250 c.expect(LINK_PROPERTIES_CHANGED, network); 3251 c.expect(BLOCKED_STATUS, network); 3252 } 3253 } 3254 3255 @Test 3256 public void testNetworkDoesntMatchRequestsUntilConnected() throws Exception { 3257 final TestNetworkCallback cb = new TestNetworkCallback(); 3258 final NetworkRequest wifiRequest = new NetworkRequest.Builder() 3259 .addTransportType(TRANSPORT_WIFI).build(); 3260 mCm.requestNetwork(wifiRequest, cb); 3261 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3262 // Updating the score triggers a rematch. 3263 mWiFiAgent.setScore(new NetworkScore.Builder().build()); 3264 cb.assertNoCallback(); 3265 mWiFiAgent.connect(false); 3266 cb.expectAvailableCallbacksUnvalidated(mWiFiAgent); 3267 cb.assertNoCallback(); 3268 mCm.unregisterNetworkCallback(cb); 3269 } 3270 3271 @Test 3272 public void testNetworkNotVisibleUntilConnected() throws Exception { 3273 final TestNetworkCallback cb = new TestNetworkCallback(); 3274 final NetworkRequest wifiRequest = new NetworkRequest.Builder() 3275 .addTransportType(TRANSPORT_WIFI).build(); 3276 mCm.registerNetworkCallback(wifiRequest, cb); 3277 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3278 final NetworkCapabilities nc = mWiFiAgent.getNetworkCapabilities(); 3279 nc.addCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED); 3280 mWiFiAgent.setNetworkCapabilities(nc, true /* sendToConnectivityService */); 3281 cb.assertNoCallback(); 3282 mWiFiAgent.connect(false); 3283 cb.expectAvailableCallbacksUnvalidated(mWiFiAgent); 3284 final CallbackEntry found = CollectionUtils.findLast(cb.getHistory(), 3285 it -> it instanceof CallbackEntry.CapabilitiesChanged); 3286 assertTrue(((CallbackEntry.CapabilitiesChanged) found).getCaps() 3287 .hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED)); 3288 cb.assertNoCallback(); 3289 mCm.unregisterNetworkCallback(cb); 3290 } 3291 3292 @Test 3293 public void testStateChangeNetworkCallbacks() throws Exception { 3294 final TestNetworkCallback genericNetworkCallback = new TestNetworkCallback(); 3295 final TestNetworkCallback wifiNetworkCallback = new TestNetworkCallback(); 3296 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback(); 3297 final NetworkRequest genericRequest = new NetworkRequest.Builder() 3298 .clearCapabilities().build(); 3299 final NetworkRequest wifiRequest = new NetworkRequest.Builder() 3300 .addTransportType(TRANSPORT_WIFI).build(); 3301 final NetworkRequest cellRequest = new NetworkRequest.Builder() 3302 .addTransportType(TRANSPORT_CELLULAR).build(); 3303 mCm.registerNetworkCallback(genericRequest, genericNetworkCallback); 3304 mCm.registerNetworkCallback(wifiRequest, wifiNetworkCallback); 3305 mCm.registerNetworkCallback(cellRequest, cellNetworkCallback); 3306 3307 // Test unvalidated networks 3308 ExpectedBroadcast b = expectConnectivityAction(1); 3309 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 3310 mCellAgent.connect(false); 3311 genericNetworkCallback.expectAvailableCallbacksUnvalidated(mCellAgent); 3312 cellNetworkCallback.expectAvailableCallbacksUnvalidated(mCellAgent); 3313 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetwork()); 3314 b.expectBroadcast(); 3315 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback); 3316 3317 // This should not trigger spurious onAvailable() callbacks, b/21762680. 3318 mCellAgent.adjustScore(-1); 3319 waitForIdle(); 3320 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback); 3321 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetwork()); 3322 3323 b = expectConnectivityAction(2); 3324 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3325 mWiFiAgent.connect(false); 3326 genericNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 3327 wifiNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 3328 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetwork()); 3329 b.expectBroadcast(); 3330 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback); 3331 3332 b = expectConnectivityAction(2); 3333 mWiFiAgent.disconnect(); 3334 genericNetworkCallback.expect(CallbackEntry.LOST, mWiFiAgent); 3335 wifiNetworkCallback.expect(CallbackEntry.LOST, mWiFiAgent); 3336 cellNetworkCallback.assertNoCallback(); 3337 b.expectBroadcast(); 3338 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback); 3339 3340 b = expectConnectivityAction(1); 3341 mCellAgent.disconnect(); 3342 genericNetworkCallback.expect(CallbackEntry.LOST, mCellAgent); 3343 cellNetworkCallback.expect(CallbackEntry.LOST, mCellAgent); 3344 b.expectBroadcast(); 3345 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback); 3346 3347 // Test validated networks 3348 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 3349 mCellAgent.connect(true); 3350 genericNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 3351 cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 3352 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetwork()); 3353 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback); 3354 3355 // This should not trigger spurious onAvailable() callbacks, b/21762680. 3356 mCellAgent.adjustScore(-1); 3357 waitForIdle(); 3358 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback); 3359 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetwork()); 3360 3361 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3362 mWiFiAgent.connect(true); 3363 genericNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 3364 genericNetworkCallback.expectLosing(mCellAgent); 3365 genericNetworkCallback.expectCaps(mWiFiAgent, 3366 c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 3367 wifiNetworkCallback.expectAvailableThenValidatedCallbacks(mWiFiAgent); 3368 cellNetworkCallback.expectLosing(mCellAgent); 3369 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetwork()); 3370 // Cell will disconnect after the lingering period. Before that elapses check that 3371 // there have been no callbacks. 3372 assertNoCallbacks(0 /* timeoutMs */, 3373 genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback); 3374 3375 mWiFiAgent.disconnect(); 3376 genericNetworkCallback.expect(LOST, mWiFiAgent); 3377 wifiNetworkCallback.expect(LOST, mWiFiAgent); 3378 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback); 3379 3380 mCellAgent.disconnect(); 3381 genericNetworkCallback.expect(LOST, mCellAgent); 3382 cellNetworkCallback.expect(LOST, mCellAgent); 3383 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback); 3384 } 3385 3386 private void doNetworkCallbacksSanitizationTest(boolean sanitized) throws Exception { 3387 final TestNetworkCallback callback = new TestNetworkCallback(); 3388 final TestNetworkCallback defaultCallback = new TestNetworkCallback(); 3389 final NetworkRequest wifiRequest = new NetworkRequest.Builder() 3390 .addTransportType(TRANSPORT_WIFI).build(); 3391 mCm.registerNetworkCallback(wifiRequest, callback); 3392 mCm.registerDefaultNetworkCallback(defaultCallback); 3393 3394 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3395 mWiFiAgent.connect(false); 3396 callback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 3397 defaultCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 3398 3399 final LinkProperties newLp = new LinkProperties(); 3400 final Uri capportUrl = Uri.parse("https://capport.example.com/api"); 3401 final CaptivePortalData capportData = new CaptivePortalData.Builder() 3402 .setCaptive(true).build(); 3403 3404 final Uri expectedCapportUrl = sanitized ? null : capportUrl; 3405 newLp.setCaptivePortalApiUrl(capportUrl); 3406 mWiFiAgent.sendLinkProperties(newLp); 3407 callback.expect(LINK_PROPERTIES_CHANGED, mWiFiAgent, cb -> 3408 Objects.equals(expectedCapportUrl, cb.getLp().getCaptivePortalApiUrl())); 3409 defaultCallback.expect(LINK_PROPERTIES_CHANGED, mWiFiAgent, cb -> 3410 Objects.equals(expectedCapportUrl, cb.getLp().getCaptivePortalApiUrl())); 3411 3412 final CaptivePortalData expectedCapportData = sanitized ? null : capportData; 3413 mWiFiAgent.notifyCapportApiDataChanged(capportData); 3414 callback.expect(LINK_PROPERTIES_CHANGED, mWiFiAgent, cb -> 3415 Objects.equals(expectedCapportData, cb.getLp().getCaptivePortalData())); 3416 defaultCallback.expect(LINK_PROPERTIES_CHANGED, mWiFiAgent, cb -> 3417 Objects.equals(expectedCapportData, cb.getLp().getCaptivePortalData())); 3418 3419 final LinkProperties lp = mCm.getLinkProperties(mWiFiAgent.getNetwork()); 3420 assertEquals(expectedCapportUrl, lp.getCaptivePortalApiUrl()); 3421 assertEquals(expectedCapportData, lp.getCaptivePortalData()); 3422 } 3423 3424 @Test 3425 public void networkCallbacksSanitizationTest_Sanitize() throws Exception { 3426 mServiceContext.setPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, 3427 PERMISSION_DENIED); 3428 mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_DENIED); 3429 doNetworkCallbacksSanitizationTest(true /* sanitized */); 3430 } 3431 3432 @Test 3433 public void networkCallbacksSanitizationTest_NoSanitize_NetworkStack() throws Exception { 3434 mServiceContext.setPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, 3435 PERMISSION_GRANTED); 3436 mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_DENIED); 3437 doNetworkCallbacksSanitizationTest(false /* sanitized */); 3438 } 3439 3440 @Test 3441 public void networkCallbacksSanitizationTest_NoSanitize_Settings() throws Exception { 3442 mServiceContext.setPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, 3443 PERMISSION_DENIED); 3444 mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_GRANTED); 3445 doNetworkCallbacksSanitizationTest(false /* sanitized */); 3446 } 3447 3448 @Test 3449 public void testOwnerUidCannotChange() throws Exception { 3450 final NetworkCapabilities ncTemplate = new NetworkCapabilities(); 3451 final int originalOwnerUid = Process.myUid(); 3452 ncTemplate.setOwnerUid(originalOwnerUid); 3453 3454 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, new LinkProperties(), ncTemplate); 3455 mWiFiAgent.connect(false); 3456 waitForIdle(); 3457 3458 // Send ConnectivityService an update to the mWiFiAgent's capabilities that changes 3459 // the owner UID and an unrelated capability. 3460 NetworkCapabilities agentCapabilities = mWiFiAgent.getNetworkCapabilities(); 3461 assertEquals(originalOwnerUid, agentCapabilities.getOwnerUid()); 3462 agentCapabilities.setOwnerUid(42); 3463 assertFalse(agentCapabilities.hasCapability(NET_CAPABILITY_NOT_CONGESTED)); 3464 agentCapabilities.addCapability(NET_CAPABILITY_NOT_CONGESTED); 3465 mWiFiAgent.setNetworkCapabilities(agentCapabilities, true); 3466 waitForIdle(); 3467 3468 // Owner UIDs are not visible without location permission. 3469 setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION, 3470 Manifest.permission.ACCESS_FINE_LOCATION); 3471 3472 // Check that the capability change has been applied but the owner UID is not modified. 3473 NetworkCapabilities nc = mCm.getNetworkCapabilities(mWiFiAgent.getNetwork()); 3474 assertEquals(originalOwnerUid, nc.getOwnerUid()); 3475 assertTrue(nc.hasCapability(NET_CAPABILITY_NOT_CONGESTED)); 3476 } 3477 3478 @Test 3479 public void testMultipleLingering() throws Exception { 3480 // This test would be flaky with the default 120ms timer: that is short enough that 3481 // lingered networks are torn down before assertions can be run. We don't want to mock the 3482 // lingering timer to keep the WakeupMessage logic realistic: this has already proven useful 3483 // in detecting races. Furthermore, sometimes the test is running while Phenotype is running 3484 // so hot that the test doesn't get the CPU for multiple hundreds of milliseconds, so this 3485 // needs to be suitably long. 3486 mService.mLingerDelayMs = 2_000; 3487 3488 NetworkRequest request = new NetworkRequest.Builder() 3489 .clearCapabilities().addCapability(NET_CAPABILITY_NOT_METERED) 3490 .build(); 3491 TestNetworkCallback callback = new TestNetworkCallback(); 3492 mCm.registerNetworkCallback(request, callback); 3493 3494 TestNetworkCallback defaultCallback = new TestNetworkCallback(); 3495 mCm.registerDefaultNetworkCallback(defaultCallback); 3496 3497 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 3498 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3499 mEthernetAgent = new TestNetworkAgentWrapper(TRANSPORT_ETHERNET); 3500 3501 mCellAgent.addCapability(NET_CAPABILITY_NOT_METERED); 3502 mWiFiAgent.addCapability(NET_CAPABILITY_NOT_METERED); 3503 mEthernetAgent.addCapability(NET_CAPABILITY_NOT_METERED); 3504 3505 mCellAgent.connect(true); 3506 callback.expectAvailableThenValidatedCallbacks(mCellAgent); 3507 defaultCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 3508 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetwork()); 3509 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 3510 3511 mWiFiAgent.connect(true); 3512 // We get AVAILABLE on wifi when wifi connects and satisfies our unmetered request. 3513 // We then get LOSING when wifi validates and cell is outscored. 3514 callback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 3515 // TODO: Investigate sending validated before losing. 3516 callback.expectLosing(mCellAgent); 3517 callback.expectCaps(mWiFiAgent, c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 3518 defaultCallback.expectAvailableDoubleValidatedCallbacks(mWiFiAgent); 3519 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetwork()); 3520 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 3521 3522 mEthernetAgent.connect(true); 3523 callback.expectAvailableCallbacksUnvalidated(mEthernetAgent); 3524 // TODO: Investigate sending validated before losing. 3525 callback.expectLosing(mWiFiAgent); 3526 callback.expectCaps(mEthernetAgent, c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 3527 defaultCallback.expectAvailableDoubleValidatedCallbacks(mEthernetAgent); 3528 assertEquals(mEthernetAgent.getNetwork(), mCm.getActiveNetwork()); 3529 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 3530 3531 mEthernetAgent.disconnect(); 3532 callback.expect(LOST, mEthernetAgent); 3533 defaultCallback.expect(LOST, mEthernetAgent); 3534 defaultCallback.expectAvailableCallbacksValidated(mWiFiAgent); 3535 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 3536 3537 for (int i = 0; i < 4; i++) { 3538 TestNetworkAgentWrapper oldNetwork, newNetwork; 3539 if (i % 2 == 0) { 3540 mWiFiAgent.adjustScore(-15); 3541 oldNetwork = mWiFiAgent; 3542 newNetwork = mCellAgent; 3543 } else { 3544 mWiFiAgent.adjustScore(15); 3545 oldNetwork = mCellAgent; 3546 newNetwork = mWiFiAgent; 3547 3548 } 3549 callback.expectLosing(oldNetwork); 3550 // TODO: should we send an AVAILABLE callback to newNetwork, to indicate that it is no 3551 // longer lingering? 3552 defaultCallback.expectAvailableCallbacksValidated(newNetwork); 3553 assertEquals(newNetwork.getNetwork(), mCm.getActiveNetwork()); 3554 } 3555 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetwork()); 3556 3557 // Verify that if a network no longer satisfies a request, we send LOST and not LOSING, even 3558 // if the network is still up. 3559 mWiFiAgent.removeCapability(NET_CAPABILITY_NOT_METERED); 3560 // We expect a notification about the capabilities change, and nothing else. 3561 defaultCallback.expectCaps(mWiFiAgent, c -> !c.hasCapability(NET_CAPABILITY_NOT_METERED)); 3562 defaultCallback.assertNoCallback(); 3563 callback.expect(LOST, mWiFiAgent); 3564 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 3565 3566 // Wifi no longer satisfies our listen, which is for an unmetered network. 3567 // But because its score is 55, it's still up (and the default network). 3568 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetwork()); 3569 3570 // Disconnect our test networks. 3571 mWiFiAgent.disconnect(); 3572 defaultCallback.expect(LOST, mWiFiAgent); 3573 defaultCallback.expectAvailableCallbacksValidated(mCellAgent); 3574 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 3575 mCellAgent.disconnect(); 3576 defaultCallback.expect(LOST, mCellAgent); 3577 waitForIdle(); 3578 assertEquals(null, mCm.getActiveNetwork()); 3579 3580 mCm.unregisterNetworkCallback(callback); 3581 waitForIdle(); 3582 3583 // Check that a network is only lingered or torn down if it would not satisfy a request even 3584 // if it validated. 3585 request = new NetworkRequest.Builder().clearCapabilities().build(); 3586 callback = new TestNetworkCallback(); 3587 3588 mCm.registerNetworkCallback(request, callback); 3589 3590 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 3591 mCellAgent.connect(false); // Score: 10 3592 callback.expectAvailableCallbacksUnvalidated(mCellAgent); 3593 defaultCallback.expectAvailableCallbacksUnvalidated(mCellAgent); 3594 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetwork()); 3595 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 3596 3597 // Bring up wifi with a score of 20. 3598 // Cell stays up because it would satisfy the default request if it validated. 3599 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3600 mWiFiAgent.connect(false); // Score: 20 3601 callback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 3602 defaultCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 3603 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetwork()); 3604 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 3605 3606 mWiFiAgent.disconnect(); 3607 callback.expect(LOST, mWiFiAgent); 3608 defaultCallback.expect(LOST, mWiFiAgent); 3609 defaultCallback.expectAvailableCallbacksUnvalidated(mCellAgent); 3610 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetwork()); 3611 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 3612 3613 // Bring up wifi, then validate it. Previous versions would immediately tear down cell, but 3614 // it's arguably correct to linger it, since it was the default network before it validated. 3615 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3616 mWiFiAgent.connect(true); 3617 callback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 3618 // TODO: Investigate sending validated before losing. 3619 callback.expectLosing(mCellAgent); 3620 callback.expectCaps(mWiFiAgent, c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 3621 defaultCallback.expectAvailableThenValidatedCallbacks(mWiFiAgent); 3622 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetwork()); 3623 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 3624 3625 mWiFiAgent.disconnect(); 3626 callback.expect(LOST, mWiFiAgent); 3627 defaultCallback.expect(LOST, mWiFiAgent); 3628 defaultCallback.expectAvailableCallbacksUnvalidated(mCellAgent); 3629 mCellAgent.disconnect(); 3630 callback.expect(LOST, mCellAgent); 3631 defaultCallback.expect(LOST, mCellAgent); 3632 waitForIdle(); 3633 assertEquals(null, mCm.getActiveNetwork()); 3634 3635 // If a network is lingering, and we add and remove a request from it, resume lingering. 3636 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 3637 mCellAgent.connect(true); 3638 callback.expectAvailableThenValidatedCallbacks(mCellAgent); 3639 defaultCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 3640 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 3641 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3642 mWiFiAgent.connect(true); 3643 defaultCallback.expectAvailableDoubleValidatedCallbacks(mWiFiAgent); 3644 callback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 3645 // TODO: Investigate sending validated before losing. 3646 callback.expectLosing(mCellAgent); 3647 callback.expectCaps(mWiFiAgent, c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 3648 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 3649 3650 NetworkRequest cellRequest = new NetworkRequest.Builder() 3651 .addTransportType(TRANSPORT_CELLULAR).build(); 3652 NetworkCallback noopCallback = new NetworkCallback(); 3653 mCm.requestNetwork(cellRequest, noopCallback); 3654 // TODO: should this cause an AVAILABLE callback, to indicate that the network is no longer 3655 // lingering? 3656 mCm.unregisterNetworkCallback(noopCallback); 3657 callback.expectLosing(mCellAgent); 3658 3659 // Similar to the above: lingering can start even after the lingered request is removed. 3660 // Disconnect wifi and switch to cell. 3661 mWiFiAgent.disconnect(); 3662 callback.expect(LOST, mWiFiAgent); 3663 defaultCallback.expect(LOST, mWiFiAgent); 3664 defaultCallback.expectAvailableCallbacksValidated(mCellAgent); 3665 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 3666 3667 // Cell is now the default network. Pin it with a cell-specific request. 3668 noopCallback = new NetworkCallback(); // Can't reuse NetworkCallbacks. http://b/20701525 3669 mCm.requestNetwork(cellRequest, noopCallback); 3670 3671 // Now connect wifi, and expect it to become the default network. 3672 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3673 mWiFiAgent.connect(true); 3674 callback.expectAvailableThenValidatedCallbacks(mWiFiAgent); 3675 defaultCallback.expectAvailableDoubleValidatedCallbacks(mWiFiAgent); 3676 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 3677 // The default request is lingering on cell, but nothing happens to cell, and we send no 3678 // callbacks for it, because it's kept up by cellRequest. 3679 callback.assertNoCallback(); 3680 // Now unregister cellRequest and expect cell to start lingering. 3681 mCm.unregisterNetworkCallback(noopCallback); 3682 callback.expectLosing(mCellAgent); 3683 3684 // Let linger run its course. 3685 callback.assertNoCallback(0 /* timeoutMs */); 3686 final int lingerTimeoutMs = mService.mLingerDelayMs + mService.mLingerDelayMs / 4; 3687 callback.expect(LOST, mCellAgent, lingerTimeoutMs); 3688 3689 // Register a TRACK_DEFAULT request and check that it does not affect lingering. 3690 TestNetworkCallback trackDefaultCallback = new TestNetworkCallback(); 3691 mCm.registerDefaultNetworkCallback(trackDefaultCallback); 3692 trackDefaultCallback.expectAvailableCallbacksValidated(mWiFiAgent); 3693 mEthernetAgent = new TestNetworkAgentWrapper(TRANSPORT_ETHERNET); 3694 mEthernetAgent.connect(true); 3695 callback.expectAvailableCallbacksUnvalidated(mEthernetAgent); 3696 callback.expectLosing(mWiFiAgent); 3697 callback.expectCaps(mEthernetAgent, c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 3698 trackDefaultCallback.expectAvailableDoubleValidatedCallbacks(mEthernetAgent); 3699 defaultCallback.expectAvailableDoubleValidatedCallbacks(mEthernetAgent); 3700 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 3701 3702 // Let linger run its course. 3703 callback.expect(LOST, mWiFiAgent, lingerTimeoutMs); 3704 3705 // Clean up. 3706 mEthernetAgent.disconnect(); 3707 callback.expect(LOST, mEthernetAgent); 3708 defaultCallback.expect(LOST, mEthernetAgent); 3709 trackDefaultCallback.expect(LOST, mEthernetAgent); 3710 3711 mCm.unregisterNetworkCallback(callback); 3712 mCm.unregisterNetworkCallback(defaultCallback); 3713 mCm.unregisterNetworkCallback(trackDefaultCallback); 3714 } 3715 3716 private void grantUsingBackgroundNetworksPermissionForUid(final int uid) throws Exception { 3717 grantUsingBackgroundNetworksPermissionForUid(uid, mContext.getPackageName()); 3718 } 3719 3720 private void grantUsingBackgroundNetworksPermissionForUid( 3721 final int uid, final String packageName) throws Exception { 3722 doReturn(buildPackageInfo(true /* hasSystemPermission */, uid)).when(mPackageManager) 3723 .getPackageInfo(eq(packageName), eq(GET_PERMISSIONS)); 3724 3725 // Send a broadcast indicating a package was installed. 3726 final Intent addedIntent = new Intent(ACTION_PACKAGE_ADDED); 3727 addedIntent.putExtra(Intent.EXTRA_UID, uid); 3728 addedIntent.setData(Uri.parse("package:" + packageName)); 3729 processBroadcast(addedIntent); 3730 } 3731 3732 @Test 3733 public void testNetworkGoesIntoBackgroundAfterLinger() throws Exception { 3734 setAlwaysOnNetworks(true); 3735 grantUsingBackgroundNetworksPermissionForUid(Binder.getCallingUid()); 3736 NetworkRequest request = new NetworkRequest.Builder() 3737 .clearCapabilities() 3738 .build(); 3739 TestNetworkCallback callback = new TestNetworkCallback(); 3740 mCm.registerNetworkCallback(request, callback); 3741 3742 TestNetworkCallback defaultCallback = new TestNetworkCallback(); 3743 mCm.registerDefaultNetworkCallback(defaultCallback); 3744 3745 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 3746 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3747 3748 mCellAgent.connect(true); 3749 callback.expectAvailableThenValidatedCallbacks(mCellAgent); 3750 defaultCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 3751 3752 // Wifi comes up and cell lingers. 3753 mWiFiAgent.connect(true); 3754 defaultCallback.expectAvailableDoubleValidatedCallbacks(mWiFiAgent); 3755 callback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 3756 callback.expectLosing(mCellAgent); 3757 callback.expectCaps(mWiFiAgent, c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 3758 3759 // File a request for cellular, then release it. 3760 NetworkRequest cellRequest = new NetworkRequest.Builder() 3761 .addTransportType(TRANSPORT_CELLULAR).build(); 3762 NetworkCallback noopCallback = new NetworkCallback(); 3763 mCm.requestNetwork(cellRequest, noopCallback); 3764 mCm.unregisterNetworkCallback(noopCallback); 3765 callback.expectLosing(mCellAgent); 3766 3767 // Let linger run its course. 3768 callback.assertNoCallback(); 3769 final int lingerTimeoutMs = TEST_LINGER_DELAY_MS + TEST_LINGER_DELAY_MS / 4; 3770 callback.expectCaps(mCellAgent, lingerTimeoutMs, 3771 c -> !c.hasCapability(NET_CAPABILITY_FOREGROUND)); 3772 3773 // Clean up. 3774 mCm.unregisterNetworkCallback(defaultCallback); 3775 mCm.unregisterNetworkCallback(callback); 3776 } 3777 3778 /** Expects the specified notification and returns the notification ID. */ 3779 private int expectNotification(TestNetworkAgentWrapper agent, NotificationType type) { 3780 verify(mNotificationManager, timeout(TIMEOUT_MS)).notify( 3781 eq(NetworkNotificationManager.tagFor(agent.getNetwork().netId)), 3782 eq(type.eventId), any()); 3783 return type.eventId; 3784 } 3785 3786 private void expectNoNotification(@NonNull final TestNetworkAgentWrapper agent) { 3787 verify(mNotificationManager, never()).notifyAsUser(anyString(), anyInt(), any(), any()); 3788 } 3789 3790 /** 3791 * Expects the specified notification happens when the unvalidated prompt message arrives 3792 * 3793 * @return the notification ID. 3794 **/ 3795 private int expectUnvalidationCheckWillNotify(TestNetworkAgentWrapper agent, 3796 NotificationType type) { 3797 mService.scheduleEvaluationTimeout(agent.getNetwork(), 0 /* delayMs */); 3798 waitForIdle(); 3799 return expectNotification(agent, type); 3800 } 3801 3802 /** 3803 * Expects that the notification for the specified network is cleared. 3804 * 3805 * This generally happens when the network disconnects or when the newtwork validates. During 3806 * normal usage the notification is also cleared by the system when the notification is tapped. 3807 */ 3808 private void expectClearNotification(TestNetworkAgentWrapper agent, NotificationType type) { 3809 verify(mNotificationManager, timeout(TIMEOUT_MS)).cancel( 3810 eq(NetworkNotificationManager.tagFor(agent.getNetwork().netId)), eq(type.eventId)); 3811 } 3812 3813 /** 3814 * Expects that no notification happens when the unvalidated prompt message arrives 3815 * 3816 * @return the notification ID. 3817 **/ 3818 private void expectUnvalidationCheckWillNotNotify(TestNetworkAgentWrapper agent) { 3819 mService.scheduleEvaluationTimeout(agent.getNetwork(), 0 /*delayMs */); 3820 waitForIdle(); 3821 expectNoNotification(agent); 3822 } 3823 3824 private void expectDisconnectAndClearNotifications(TestNetworkCallback callback, 3825 TestNetworkAgentWrapper agent, NotificationType type) { 3826 callback.expect(LOST, agent); 3827 expectClearNotification(agent, type); 3828 } 3829 3830 private NativeNetworkConfig nativeNetworkConfigPhysical(int netId, int permission) { 3831 return new NativeNetworkConfig(netId, NativeNetworkType.PHYSICAL, permission, 3832 /*secure=*/ false, VpnManager.TYPE_VPN_NONE, /*excludeLocalRoutes=*/ false); 3833 } 3834 3835 private NativeNetworkConfig nativeNetworkConfigVpn(int netId, boolean secure, int vpnType) { 3836 return new NativeNetworkConfig(netId, NativeNetworkType.VIRTUAL, INetd.PERMISSION_NONE, 3837 secure, vpnType, /*excludeLocalRoutes=*/ false); 3838 } 3839 3840 @Test 3841 public void testNetworkAgentCallbacks() throws Exception { 3842 // Keeps track of the order of events that happen in this test. 3843 final LinkedBlockingQueue<String> eventOrder = new LinkedBlockingQueue<>(); 3844 3845 final NetworkRequest request = new NetworkRequest.Builder() 3846 .addTransportType(TRANSPORT_WIFI).build(); 3847 final TestNetworkCallback callback = new TestNetworkCallback(); 3848 3849 // Expectations for state when various callbacks fire. These expectations run on the handler 3850 // thread and not on the test thread because they need to prevent the handler thread from 3851 // advancing while they examine state. 3852 3853 // 1. When onCreated fires, netd has been told to create the network. 3854 final Consumer<NetworkAgent> onNetworkCreated = (agent) -> { 3855 eventOrder.offer("onNetworkCreated"); 3856 try { 3857 verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( 3858 agent.getNetwork().getNetId(), INetd.PERMISSION_NONE)); 3859 } catch (RemoteException impossible) { 3860 fail(); 3861 } 3862 }; 3863 3864 // 2. onNetworkUnwanted isn't precisely ordered with respect to any particular events. Just 3865 // check that it is fired at some point after disconnect. 3866 final Consumer<NetworkAgent> onNetworkUnwanted = (agent) -> { 3867 eventOrder.offer("onNetworkUnwanted"); 3868 }; 3869 3870 // 3. While the teardown timer is running, connectivity APIs report the network is gone, but 3871 // netd has not yet been told to destroy it. 3872 final Consumer<Network> duringTeardown = (network) -> { 3873 eventOrder.offer("timePasses"); 3874 assertNull(mCm.getLinkProperties(network)); 3875 try { 3876 verify(mMockNetd, never()).networkDestroy(network.getNetId()); 3877 } catch (RemoteException impossible) { 3878 fail(); 3879 } 3880 }; 3881 3882 // 4. After onNetworkDisconnected is called, connectivity APIs report the network is gone, 3883 // and netd has been told to destroy it. 3884 final Consumer<NetworkAgent> onNetworkDisconnected = (agent) -> { 3885 eventOrder.offer("onNetworkDisconnected"); 3886 assertNull(mCm.getLinkProperties(agent.getNetwork())); 3887 try { 3888 verify(mMockNetd).networkDestroy(agent.getNetwork().getNetId()); 3889 } catch (RemoteException impossible) { 3890 fail(); 3891 } 3892 }; 3893 3894 final NetworkAgentWrapper.Callbacks callbacks = new NetworkAgentWrapper.Callbacks( 3895 onNetworkCreated, onNetworkUnwanted, onNetworkDisconnected); 3896 3897 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, callbacks); 3898 3899 if (mService.shouldCreateNetworksImmediately()) { 3900 assertEquals("onNetworkCreated", eventOrder.poll(TIMEOUT_MS, TimeUnit.MILLISECONDS)); 3901 } else { 3902 assertNull(eventOrder.poll()); 3903 } 3904 3905 // Connect a network, and file a request for it after it has come up, to ensure the nascent 3906 // timer is cleared and the test does not have to wait for it. Filing the request after the 3907 // network has come up is necessary because ConnectivityService does not appear to clear the 3908 // nascent timer if the first request satisfied by the network was filed before the network 3909 // connected. 3910 // TODO: fix this bug, file the request before connecting, and remove the waitForIdle. 3911 mWiFiAgent.connectWithoutInternet(); 3912 if (!mService.shouldCreateNetworksImmediately()) { 3913 assertEquals("onNetworkCreated", eventOrder.poll(TIMEOUT_MS, TimeUnit.MILLISECONDS)); 3914 } else { 3915 waitForIdle(); 3916 assertNull(eventOrder.poll()); 3917 } 3918 mCm.requestNetwork(request, callback); 3919 callback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 3920 3921 // Set teardown delay and make sure CS has processed it. 3922 mWiFiAgent.getNetworkAgent().setTeardownDelayMillis(300); 3923 waitForIdle(); 3924 3925 // Post the duringTeardown lambda to the handler so it fires while teardown is in progress. 3926 // The delay must be long enough it will run after the unregisterNetworkCallback has torn 3927 // down the network and started the teardown timer, and short enough that the lambda is 3928 // scheduled to run before the teardown timer. 3929 final Handler h = new Handler(mCsHandlerThread.getLooper()); 3930 h.postDelayed(() -> duringTeardown.accept(mWiFiAgent.getNetwork()), 150); 3931 3932 // Disconnect the network and check that events happened in the right order. 3933 mCm.unregisterNetworkCallback(callback); 3934 assertEquals("onNetworkUnwanted", eventOrder.poll(TIMEOUT_MS, TimeUnit.MILLISECONDS)); 3935 assertEquals("timePasses", eventOrder.poll(TIMEOUT_MS, TimeUnit.MILLISECONDS)); 3936 assertEquals("onNetworkDisconnected", eventOrder.poll(TIMEOUT_MS, TimeUnit.MILLISECONDS)); 3937 3938 mCm.unregisterNetworkCallback(callback); 3939 } 3940 3941 @Test 3942 public void testExplicitlySelected() throws Exception { 3943 final NetworkRequest request = new NetworkRequest.Builder() 3944 .clearCapabilities().addCapability(NET_CAPABILITY_INTERNET) 3945 .build(); 3946 final TestNetworkCallback callback = new TestNetworkCallback(); 3947 mCm.registerNetworkCallback(request, callback); 3948 3949 // Bring up validated cell 3950 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 3951 mCellAgent.connect(true); 3952 callback.expectAvailableThenValidatedCallbacks(mCellAgent); 3953 3954 // Bring up unvalidated wifi with explicitlySelected=true. 3955 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3956 mWiFiAgent.explicitlySelected(true, false); 3957 mWiFiAgent.connect(false); 3958 callback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 3959 3960 // Cell remains the default. 3961 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetwork()); 3962 3963 // Expect a high-priority NO_INTERNET notification. 3964 expectUnvalidationCheckWillNotify(mWiFiAgent, NotificationType.NO_INTERNET); 3965 3966 // Lower WiFi's score to lower than cell, and check that it doesn't disconnect because 3967 // it's explicitly selected. 3968 mWiFiAgent.adjustScore(-40); 3969 mWiFiAgent.adjustScore(40); 3970 callback.assertNoCallback(); 3971 3972 // If the user chooses yes on the "No Internet access, stay connected?" dialog, we switch to 3973 // wifi even though it's unvalidated. 3974 mCm.setAcceptUnvalidated(mWiFiAgent.getNetwork(), true, false); 3975 callback.expectLosing(mCellAgent); 3976 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetwork()); 3977 3978 // Disconnect wifi, and then reconnect, again with explicitlySelected=true. 3979 mWiFiAgent.disconnect(); 3980 expectDisconnectAndClearNotifications(callback, mWiFiAgent, NotificationType.NO_INTERNET); 3981 3982 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3983 mWiFiAgent.explicitlySelected(true, false); 3984 mWiFiAgent.connect(false); 3985 callback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 3986 3987 // Expect a high-priority NO_INTERNET notification. 3988 expectUnvalidationCheckWillNotify(mWiFiAgent, NotificationType.NO_INTERNET); 3989 3990 // If the user chooses no on the "No Internet access, stay connected?" dialog, we ask the 3991 // network to disconnect. 3992 mCm.setAcceptUnvalidated(mWiFiAgent.getNetwork(), false, false); 3993 expectDisconnectAndClearNotifications(callback, mWiFiAgent, NotificationType.NO_INTERNET); 3994 reset(mNotificationManager); 3995 3996 // Reconnect, again with explicitlySelected=true, but this time validate. 3997 // Expect no notifications. 3998 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3999 mWiFiAgent.explicitlySelected(true, false); 4000 mWiFiAgent.connect(true); 4001 callback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 4002 callback.expectLosing(mCellAgent); 4003 callback.expectCaps(mWiFiAgent, c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 4004 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetwork()); 4005 expectUnvalidationCheckWillNotNotify(mWiFiAgent); 4006 4007 // Now request cell so it doesn't disconnect during the test 4008 final NetworkRequest cellRequest = new NetworkRequest.Builder() 4009 .clearCapabilities().addTransportType(TRANSPORT_CELLULAR).build(); 4010 final TestNetworkCallback cellCallback = new TestNetworkCallback(); 4011 mCm.requestNetwork(cellRequest, cellCallback); 4012 4013 mEthernetAgent = new TestNetworkAgentWrapper(TRANSPORT_ETHERNET); 4014 mEthernetAgent.connect(true); 4015 callback.expectAvailableCallbacksUnvalidated(mEthernetAgent); 4016 callback.expectLosing(mWiFiAgent); 4017 callback.expectCaps(mEthernetAgent, c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 4018 assertEquals(mEthernetAgent.getNetwork(), mCm.getActiveNetwork()); 4019 callback.assertNoCallback(); 4020 4021 // Disconnect wifi, and then reconnect as if the user had selected "yes, don't ask again" 4022 // (i.e., with explicitlySelected=true and acceptUnvalidated=true). Expect to switch to 4023 // wifi immediately. 4024 mWiFiAgent.disconnect(); 4025 callback.expect(LOST, mWiFiAgent); 4026 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4027 mWiFiAgent.explicitlySelected(true, true); 4028 mWiFiAgent.connect(false); 4029 callback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 4030 callback.expectLosing(mEthernetAgent); 4031 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetwork()); 4032 mEthernetAgent.disconnect(); 4033 callback.expect(LOST, mEthernetAgent); 4034 expectUnvalidationCheckWillNotNotify(mWiFiAgent); 4035 4036 // Disconnect and reconnect with explicitlySelected=false and acceptUnvalidated=true. 4037 // Check that the network is not scored specially and that the device prefers cell data. 4038 mWiFiAgent.disconnect(); 4039 callback.expect(LOST, mWiFiAgent); 4040 4041 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4042 mWiFiAgent.explicitlySelected(false, true); 4043 mWiFiAgent.connect(false); 4044 callback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 4045 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetwork()); 4046 expectUnvalidationCheckWillNotNotify(mWiFiAgent); 4047 4048 // Clean up. 4049 mWiFiAgent.disconnect(); 4050 mCellAgent.disconnect(); 4051 4052 callback.expect(LOST, mWiFiAgent); 4053 callback.expect(LOST, mCellAgent); 4054 mCm.unregisterNetworkCallback(cellCallback); 4055 } 4056 4057 private void doTestFirstEvaluation( 4058 @NonNull final Consumer<TestNetworkAgentWrapper> doConnect, 4059 final boolean waitForSecondCaps, 4060 final boolean evaluatedByValidation) 4061 throws Exception { 4062 final NetworkRequest request = new NetworkRequest.Builder() 4063 .addTransportType(TRANSPORT_WIFI) 4064 .build(); 4065 TestNetworkCallback callback = new TestNetworkCallback(); 4066 mCm.registerNetworkCallback(request, callback); 4067 4068 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4069 doConnect.accept(mWiFiAgent); 4070 // Expect the available callbacks, but don't require specific values for their arguments 4071 // since this method doesn't know how the network was connected. 4072 callback.expect(AVAILABLE, mWiFiAgent); 4073 callback.expect(NETWORK_CAPS_UPDATED, mWiFiAgent); 4074 callback.expect(LINK_PROPERTIES_CHANGED, mWiFiAgent); 4075 callback.expect(BLOCKED_STATUS, mWiFiAgent); 4076 if (waitForSecondCaps) { 4077 // This is necessary because of b/245893397, the same bug that happens where we use 4078 // expectAvailableDoubleValidatedCallbacks. 4079 callback.expect(NETWORK_CAPS_UPDATED, mWiFiAgent); 4080 } 4081 final NetworkAgentInfo nai = 4082 mService.getNetworkAgentInfoForNetwork(mWiFiAgent.getNetwork()); 4083 final long firstEvaluation = nai.getFirstEvaluationConcludedTime(); 4084 if (evaluatedByValidation) { 4085 assertNotEquals(0L, firstEvaluation); 4086 } else { 4087 assertEquals(0L, firstEvaluation); 4088 } 4089 mService.scheduleEvaluationTimeout(mWiFiAgent.getNetwork(), 0L /* timeout */); 4090 waitForIdle(); 4091 if (evaluatedByValidation) { 4092 assertEquals(firstEvaluation, nai.getFirstEvaluationConcludedTime()); 4093 } else { 4094 assertNotEquals(0L, nai.getFirstEvaluationConcludedTime()); 4095 } 4096 mWiFiAgent.disconnect(); 4097 callback.expect(LOST, mWiFiAgent); 4098 4099 mCm.unregisterNetworkCallback(callback); 4100 } 4101 4102 @Test 4103 public void testEverEvaluated() throws Exception { 4104 doTestFirstEvaluation(naw -> naw.connect(true /* validated */), 4105 true /* waitForSecondCaps */, true /* immediatelyEvaluated */); 4106 doTestFirstEvaluation(naw -> naw.connectWithPartialConnectivity(), 4107 true /* waitForSecondCaps */, true /* immediatelyEvaluated */); 4108 doTestFirstEvaluation(naw -> naw.connectWithCaptivePortal(TEST_REDIRECT_URL, false), 4109 true /* waitForSecondCaps */, true /* immediatelyEvaluated */); 4110 doTestFirstEvaluation(naw -> naw.connect(false /* validated */), 4111 false /* waitForSecondCaps */, false /* immediatelyEvaluated */); 4112 } 4113 4114 private void tryNetworkFactoryRequests(int capability) throws Exception { 4115 // Verify NOT_RESTRICTED is set appropriately 4116 final NetworkCapabilities nc = new NetworkRequest.Builder().addCapability(capability) 4117 .build().networkCapabilities; 4118 if (capability == NET_CAPABILITY_CBS || capability == NET_CAPABILITY_DUN 4119 || capability == NET_CAPABILITY_EIMS || capability == NET_CAPABILITY_FOTA 4120 || capability == NET_CAPABILITY_IA || capability == NET_CAPABILITY_IMS 4121 || capability == NET_CAPABILITY_RCS || capability == NET_CAPABILITY_XCAP 4122 || capability == NET_CAPABILITY_VSIM || capability == NET_CAPABILITY_BIP 4123 || capability == NET_CAPABILITY_ENTERPRISE || capability == NET_CAPABILITY_MMTEL) { 4124 assertFalse(nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)); 4125 } else { 4126 assertTrue(nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)); 4127 } 4128 4129 NetworkCapabilities filter = new NetworkCapabilities(); 4130 filter.addTransportType(TRANSPORT_CELLULAR); 4131 filter.addCapability(capability); 4132 // Add NOT_VCN_MANAGED capability into filter unconditionally since some requests will add 4133 // NOT_VCN_MANAGED automatically but not for NetworkCapabilities, 4134 // see {@code NetworkCapabilities#deduceNotVcnManagedCapability} for more details. 4135 filter.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED); 4136 final HandlerThread handlerThread = new HandlerThread("testNetworkFactoryRequests"); 4137 handlerThread.start(); 4138 final MockNetworkFactory testFactory = new MockNetworkFactory(handlerThread.getLooper(), 4139 mServiceContext, "testFactory", filter, mCsHandlerThread); 4140 testFactory.setScoreFilter(45); 4141 testFactory.register(); 4142 4143 final NetworkCallback networkCallback; 4144 if (capability != NET_CAPABILITY_INTERNET) { 4145 // If the capability passed in argument is part of the default request, then the 4146 // factory will see the default request. Otherwise the filter will prevent the 4147 // factory from seeing it. In that case, add a request so it can be tested. 4148 assertFalse(testFactory.getMyStartRequested()); 4149 NetworkRequest request = new NetworkRequest.Builder().addCapability(capability).build(); 4150 networkCallback = new NetworkCallback(); 4151 mCm.requestNetwork(request, networkCallback); 4152 } else { 4153 networkCallback = null; 4154 } 4155 testFactory.expectRequestAdd(); 4156 testFactory.assertRequestCountEquals(1); 4157 assertTrue(testFactory.getMyStartRequested()); 4158 4159 // Now bring in a higher scored network. 4160 TestNetworkAgentWrapper testAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 4161 // When testAgent connects, because of its score (50 legacy int / cell transport) 4162 // it will beat or equal the testFactory's offer, so the request will be removed. 4163 // Note the agent as validated only if the capability is INTERNET, as it's the only case 4164 // where it makes sense. 4165 testAgent.connect(NET_CAPABILITY_INTERNET == capability /* validated */); 4166 testAgent.addCapability(capability); 4167 testFactory.expectRequestRemove(); 4168 testFactory.assertRequestCountEquals(0); 4169 assertFalse(testFactory.getMyStartRequested()); 4170 4171 // Add a request and make sure it's not sent to the factory, because the agent 4172 // is satisfying it better. 4173 final NetworkCallback cb = new ConnectivityManager.NetworkCallback(); 4174 mCm.requestNetwork(new NetworkRequest.Builder().addCapability(capability).build(), cb); 4175 expectNoRequestChanged(testFactory); 4176 testFactory.assertRequestCountEquals(0); 4177 assertFalse(testFactory.getMyStartRequested()); 4178 4179 // If using legacy scores, make the test agent weak enough to have the exact same score as 4180 // the factory (50 for cell - 5 adjustment). Make sure the factory doesn't see the request. 4181 // If not using legacy score, this is a no-op and the "same score removes request" behavior 4182 // has already been tested above. 4183 testAgent.adjustScore(-5); 4184 expectNoRequestChanged(testFactory); 4185 assertFalse(testFactory.getMyStartRequested()); 4186 4187 // Make the test agent weak enough that the factory will see the two requests (the one that 4188 // was just sent, and either the default one or the one sent at the top of this test if 4189 // the default won't be seen). 4190 testAgent.setScore(new NetworkScore.Builder().setLegacyInt(2).setExiting(true).build()); 4191 testFactory.expectRequestAdds(2); 4192 testFactory.assertRequestCountEquals(2); 4193 assertTrue(testFactory.getMyStartRequested()); 4194 4195 // Now unregister and make sure the request is removed. 4196 mCm.unregisterNetworkCallback(cb); 4197 testFactory.expectRequestRemove(); 4198 4199 // Bring in a bunch of requests. 4200 assertEquals(1, testFactory.getMyRequestCount()); 4201 ConnectivityManager.NetworkCallback[] networkCallbacks = 4202 new ConnectivityManager.NetworkCallback[10]; 4203 for (int i = 0; i< networkCallbacks.length; i++) { 4204 networkCallbacks[i] = new ConnectivityManager.NetworkCallback(); 4205 NetworkRequest.Builder builder = new NetworkRequest.Builder(); 4206 builder.addCapability(capability); 4207 mCm.requestNetwork(builder.build(), networkCallbacks[i]); 4208 } 4209 testFactory.expectRequestAdds(10); 4210 testFactory.assertRequestCountEquals(11); // +1 for the default/test specific request 4211 assertTrue(testFactory.getMyStartRequested()); 4212 4213 // Remove the requests. 4214 for (int i = 0; i < networkCallbacks.length; i++) { 4215 mCm.unregisterNetworkCallback(networkCallbacks[i]); 4216 } 4217 testFactory.expectRequestRemoves(10); 4218 testFactory.assertRequestCountEquals(1); 4219 assertTrue(testFactory.getMyStartRequested()); 4220 4221 // Adjust the agent score up again. Expect the request to be withdrawn. 4222 testAgent.setScore(new NetworkScore.Builder().setLegacyInt(50).build()); 4223 testFactory.expectRequestRemove(); 4224 testFactory.assertRequestCountEquals(0); 4225 assertFalse(testFactory.getMyStartRequested()); 4226 4227 // Drop the higher scored network. 4228 testAgent.disconnect(); 4229 testFactory.expectRequestAdd(); 4230 testFactory.assertRequestCountEquals(1); 4231 assertEquals(1, testFactory.getMyRequestCount()); 4232 assertTrue(testFactory.getMyStartRequested()); 4233 4234 testFactory.terminate(); 4235 testFactory.assertNoRequestChanged(); 4236 if (networkCallback != null) mCm.unregisterNetworkCallback(networkCallback); 4237 handlerThread.quit(); 4238 } 4239 4240 @Test 4241 public void testNetworkFactoryRequests() throws Exception { 4242 tryNetworkFactoryRequests(NET_CAPABILITY_MMS); 4243 tryNetworkFactoryRequests(NET_CAPABILITY_SUPL); 4244 tryNetworkFactoryRequests(NET_CAPABILITY_DUN); 4245 tryNetworkFactoryRequests(NET_CAPABILITY_FOTA); 4246 tryNetworkFactoryRequests(NET_CAPABILITY_IMS); 4247 tryNetworkFactoryRequests(NET_CAPABILITY_CBS); 4248 tryNetworkFactoryRequests(NET_CAPABILITY_WIFI_P2P); 4249 tryNetworkFactoryRequests(NET_CAPABILITY_IA); 4250 tryNetworkFactoryRequests(NET_CAPABILITY_RCS); 4251 tryNetworkFactoryRequests(NET_CAPABILITY_MMTEL); 4252 tryNetworkFactoryRequests(NET_CAPABILITY_XCAP); 4253 tryNetworkFactoryRequests(NET_CAPABILITY_ENTERPRISE); 4254 tryNetworkFactoryRequests(NET_CAPABILITY_EIMS); 4255 tryNetworkFactoryRequests(NET_CAPABILITY_NOT_METERED); 4256 tryNetworkFactoryRequests(NET_CAPABILITY_INTERNET); 4257 tryNetworkFactoryRequests(NET_CAPABILITY_TRUSTED); 4258 tryNetworkFactoryRequests(NET_CAPABILITY_NOT_VPN); 4259 tryNetworkFactoryRequests(NET_CAPABILITY_VSIM); 4260 tryNetworkFactoryRequests(NET_CAPABILITY_BIP); 4261 // Skipping VALIDATED and CAPTIVE_PORTAL as they're disallowed. 4262 } 4263 4264 @Test 4265 public void testRegisterIgnoringScore() throws Exception { 4266 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4267 mWiFiAgent.setScore(new NetworkScore.Builder().setLegacyInt(90).build()); 4268 mWiFiAgent.connect(true /* validated */); 4269 4270 // Make sure the factory sees the default network 4271 final NetworkCapabilities filter = new NetworkCapabilities(); 4272 filter.addTransportType(TRANSPORT_CELLULAR); 4273 filter.addCapability(NET_CAPABILITY_INTERNET); 4274 filter.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED); 4275 final HandlerThread handlerThread = new HandlerThread("testNetworkFactoryRequests"); 4276 handlerThread.start(); 4277 final MockNetworkFactory testFactory = new MockNetworkFactory(handlerThread.getLooper(), 4278 mServiceContext, "testFactory", filter, mCsHandlerThread); 4279 testFactory.register(); 4280 4281 final MockNetworkFactory testFactoryAll = new MockNetworkFactory(handlerThread.getLooper(), 4282 mServiceContext, "testFactoryAll", filter, mCsHandlerThread); 4283 testFactoryAll.registerIgnoringScore(); 4284 4285 // The regular test factory should not see the request, because WiFi is stronger than cell. 4286 expectNoRequestChanged(testFactory); 4287 // With ignoringScore though the request is seen. 4288 testFactoryAll.expectRequestAdd(); 4289 4290 // The legacy int will be ignored anyway, set the only other knob to true 4291 mWiFiAgent.setScore(new NetworkScore.Builder().setLegacyInt(110) 4292 .setTransportPrimary(true).build()); 4293 4294 expectNoRequestChanged(testFactory); // still not seeing the request 4295 expectNoRequestChanged(testFactoryAll); // still seeing the request 4296 4297 mWiFiAgent.disconnect(); 4298 } 4299 4300 @Test 4301 public void testNetworkFactoryUnregister() throws Exception { 4302 // Make sure the factory sees the default network 4303 final NetworkCapabilities filter = new NetworkCapabilities(); 4304 filter.addCapability(NET_CAPABILITY_INTERNET); 4305 filter.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED); 4306 4307 final HandlerThread handlerThread = new HandlerThread("testNetworkFactoryRequests"); 4308 handlerThread.start(); 4309 4310 // Checks that calling setScoreFilter on a NetworkFactory immediately before closing it 4311 // does not crash. 4312 for (int i = 0; i < 100; i++) { 4313 final MockNetworkFactory testFactory = new MockNetworkFactory(handlerThread.getLooper(), 4314 mServiceContext, "testFactory", filter, mCsHandlerThread); 4315 // Register the factory and don't be surprised when the default request arrives. 4316 testFactory.register(); 4317 testFactory.expectRequestAdd(); 4318 4319 testFactory.setScoreFilter(42); 4320 testFactory.terminate(); 4321 testFactory.assertNoRequestChanged(); 4322 4323 if (i % 2 == 0) { 4324 try { 4325 testFactory.register(); 4326 fail("Re-registering terminated NetworkFactory should throw"); 4327 } catch (IllegalStateException expected) { 4328 } 4329 } 4330 } 4331 handlerThread.quit(); 4332 } 4333 4334 @Test 4335 public void testNoMutableNetworkRequests() throws Exception { 4336 final PendingIntent pendingIntent = PendingIntent.getBroadcast( 4337 mContext, 0 /* requestCode */, new Intent("a"), FLAG_IMMUTABLE); 4338 final NetworkRequest request1 = new NetworkRequest.Builder() 4339 .addCapability(NET_CAPABILITY_VALIDATED) 4340 .build(); 4341 final NetworkRequest request2 = new NetworkRequest.Builder() 4342 .addCapability(NET_CAPABILITY_CAPTIVE_PORTAL) 4343 .build(); 4344 4345 final Class<IllegalArgumentException> expected = IllegalArgumentException.class; 4346 assertThrows(expected, () -> mCm.requestNetwork(request1, new NetworkCallback())); 4347 assertThrows(expected, () -> mCm.requestNetwork(request1, pendingIntent)); 4348 assertThrows(expected, () -> mCm.requestNetwork(request2, new NetworkCallback())); 4349 assertThrows(expected, () -> mCm.requestNetwork(request2, pendingIntent)); 4350 } 4351 4352 @Test 4353 public void testNoAllowedUidsInNetworkRequests() throws Exception { 4354 final PendingIntent pendingIntent = PendingIntent.getBroadcast( 4355 mContext, 0 /* requestCode */, new Intent("a"), FLAG_IMMUTABLE); 4356 final NetworkRequest r = new NetworkRequest.Builder().build(); 4357 final ArraySet<Integer> allowedUids = new ArraySet<>(); 4358 allowedUids.add(6); 4359 allowedUids.add(9); 4360 r.networkCapabilities.setAllowedUids(allowedUids); 4361 4362 final Handler handler = new Handler(ConnectivityThread.getInstanceLooper()); 4363 final NetworkCallback cb = new NetworkCallback(); 4364 4365 final Class<IllegalArgumentException> expected = IllegalArgumentException.class; 4366 assertThrows(expected, () -> mCm.requestNetwork(r, cb)); 4367 assertThrows(expected, () -> mCm.requestNetwork(r, pendingIntent)); 4368 assertThrows(expected, () -> mCm.registerNetworkCallback(r, cb)); 4369 assertThrows(expected, () -> mCm.registerNetworkCallback(r, cb, handler)); 4370 assertThrows(expected, () -> mCm.registerNetworkCallback(r, pendingIntent)); 4371 assertThrows(expected, () -> mCm.registerBestMatchingNetworkCallback(r, cb, handler)); 4372 4373 // Make sure that resetting the access UIDs to the empty set will allow calling 4374 // requestNetwork and registerNetworkCallback. 4375 r.networkCapabilities.setAllowedUids(Collections.emptySet()); 4376 mCm.requestNetwork(r, cb); 4377 mCm.unregisterNetworkCallback(cb); 4378 mCm.registerNetworkCallback(r, cb); 4379 mCm.unregisterNetworkCallback(cb); 4380 } 4381 4382 @Test 4383 public void testMMSonWiFi() throws Exception { 4384 // Test bringing up cellular without MMS NetworkRequest gets reaped 4385 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 4386 mCellAgent.addCapability(NET_CAPABILITY_MMS); 4387 mCellAgent.connectWithoutInternet(); 4388 mCellAgent.expectDisconnected(); 4389 waitForIdle(); 4390 assertEmpty(mCm.getAllNetworks()); 4391 verifyNoNetwork(); 4392 4393 // Test bringing up validated WiFi. 4394 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4395 final ExpectedBroadcast b = expectConnectivityAction(TYPE_WIFI, DetailedState.CONNECTED); 4396 mWiFiAgent.connect(true); 4397 b.expectBroadcast(); 4398 verifyActiveNetwork(TRANSPORT_WIFI); 4399 4400 // Register MMS NetworkRequest 4401 NetworkRequest.Builder builder = new NetworkRequest.Builder(); 4402 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_MMS); 4403 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 4404 mCm.requestNetwork(builder.build(), networkCallback); 4405 4406 // Test bringing up unvalidated cellular with MMS 4407 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 4408 mCellAgent.addCapability(NET_CAPABILITY_MMS); 4409 mCellAgent.connectWithoutInternet(); 4410 networkCallback.expectAvailableCallbacksUnvalidated(mCellAgent); 4411 verifyActiveNetwork(TRANSPORT_WIFI); 4412 4413 // Test releasing NetworkRequest disconnects cellular with MMS 4414 mCm.unregisterNetworkCallback(networkCallback); 4415 mCellAgent.expectDisconnected(); 4416 verifyActiveNetwork(TRANSPORT_WIFI); 4417 } 4418 4419 @Test 4420 public void testMMSonCell() throws Exception { 4421 // Test bringing up cellular without MMS 4422 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 4423 ExpectedBroadcast b = expectConnectivityAction(TYPE_MOBILE, DetailedState.CONNECTED); 4424 mCellAgent.connect(false); 4425 b.expectBroadcast(); 4426 verifyActiveNetwork(TRANSPORT_CELLULAR); 4427 4428 // Register MMS NetworkRequest 4429 NetworkRequest.Builder builder = new NetworkRequest.Builder(); 4430 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_MMS); 4431 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 4432 mCm.requestNetwork(builder.build(), networkCallback); 4433 4434 // Test bringing up MMS cellular network 4435 TestNetworkAgentWrapper 4436 mmsNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 4437 mmsNetworkAgent.addCapability(NET_CAPABILITY_MMS); 4438 mmsNetworkAgent.connectWithoutInternet(); 4439 networkCallback.expectAvailableCallbacksUnvalidated(mmsNetworkAgent); 4440 verifyActiveNetwork(TRANSPORT_CELLULAR); 4441 4442 // Test releasing MMS NetworkRequest does not disconnect main cellular NetworkAgent 4443 mCm.unregisterNetworkCallback(networkCallback); 4444 mmsNetworkAgent.expectDisconnected(); 4445 verifyActiveNetwork(TRANSPORT_CELLULAR); 4446 } 4447 4448 @Test 4449 public void testPartialConnectivity() throws Exception { 4450 // Register network callback. 4451 NetworkRequest request = new NetworkRequest.Builder() 4452 .clearCapabilities().addCapability(NET_CAPABILITY_INTERNET) 4453 .build(); 4454 TestNetworkCallback callback = new TestNetworkCallback(); 4455 mCm.registerNetworkCallback(request, callback); 4456 4457 // Bring up validated mobile data. 4458 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 4459 mCellAgent.connect(true); 4460 callback.expectAvailableThenValidatedCallbacks(mCellAgent); 4461 4462 // Bring up wifi with partial connectivity. 4463 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4464 mWiFiAgent.connectWithPartialConnectivity(); 4465 callback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 4466 callback.expectCaps(mWiFiAgent, c -> c.hasCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY)); 4467 4468 // Mobile data should be the default network. 4469 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetwork()); 4470 callback.assertNoCallback(); 4471 4472 // Expect a PARTIAL_CONNECTIVITY notification. The notification appears as soon as partial 4473 // connectivity is detected, and is low priority because the network was not explicitly 4474 // selected by the user. This happens if we reconnect to a network where the user previously 4475 // accepted partial connectivity without checking "always". 4476 expectNotification(mWiFiAgent, NotificationType.PARTIAL_CONNECTIVITY); 4477 4478 // With HTTPS probe disabled, NetworkMonitor should pass the network validation with http 4479 // probe. 4480 mWiFiAgent.setNetworkPartialValid(false /* privateDnsProbeSent */); 4481 // If the user chooses yes to use this partial connectivity wifi, switch the default 4482 // network to wifi and check if wifi becomes valid or not. 4483 mCm.setAcceptPartialConnectivity(mWiFiAgent.getNetwork(), true /* accept */, 4484 false /* always */); 4485 // If user accepts partial connectivity network, 4486 // NetworkMonitor#setAcceptPartialConnectivity() should be called too. 4487 waitForIdle(); 4488 verify(mWiFiAgent.mNetworkMonitor, times(1)).setAcceptPartialConnectivity(); 4489 4490 // Need a trigger point to let NetworkMonitor tell ConnectivityService that the network is 4491 // validated. 4492 mCm.reportNetworkConnectivity(mWiFiAgent.getNetwork(), true); 4493 callback.expectLosing(mCellAgent); 4494 NetworkCapabilities nc = 4495 callback.expectCaps(mWiFiAgent, c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 4496 assertTrue(nc.hasCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY)); 4497 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetwork()); 4498 4499 // Once the network validates, the notification disappears. 4500 expectClearNotification(mWiFiAgent, NotificationType.PARTIAL_CONNECTIVITY); 4501 4502 // Disconnect and reconnect wifi with partial connectivity again. 4503 mWiFiAgent.disconnect(); 4504 callback.expect(LOST, mWiFiAgent); 4505 4506 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4507 mWiFiAgent.connectWithPartialConnectivity(); 4508 callback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 4509 callback.expectCaps(mWiFiAgent, c -> c.hasCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY)); 4510 4511 // Mobile data should be the default network. 4512 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetwork()); 4513 waitForIdle(); 4514 4515 // Expect a low-priority PARTIAL_CONNECTIVITY notification as soon as partial connectivity 4516 // is detected. 4517 expectNotification(mWiFiAgent, NotificationType.PARTIAL_CONNECTIVITY); 4518 4519 // If the user chooses no, disconnect wifi immediately. 4520 mCm.setAcceptPartialConnectivity(mWiFiAgent.getNetwork(), false /* accept */, 4521 false /* always */); 4522 callback.expect(LOST, mWiFiAgent); 4523 expectClearNotification(mWiFiAgent, NotificationType.PARTIAL_CONNECTIVITY); 4524 reset(mNotificationManager); 4525 4526 // If the user accepted partial connectivity before, and the device connects to that network 4527 // again, but now the network has full connectivity, then the network shouldn't contain 4528 // NET_CAPABILITY_PARTIAL_CONNECTIVITY. 4529 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4530 // acceptUnvalidated is also used as setting for accepting partial networks. 4531 mWiFiAgent.explicitlySelected(true /* explicitlySelected */, true /* acceptUnvalidated */); 4532 mWiFiAgent.connect(true); 4533 expectUnvalidationCheckWillNotNotify(mWiFiAgent); 4534 4535 // If user accepted partial connectivity network before, 4536 // NetworkMonitor#setAcceptPartialConnectivity() will be called in 4537 // ConnectivityService#updateNetworkInfo(). 4538 callback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 4539 verify(mWiFiAgent.mNetworkMonitor, times(1)).setAcceptPartialConnectivity(); 4540 callback.expectLosing(mCellAgent); 4541 nc = callback.expectCaps(mWiFiAgent, c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 4542 assertFalse(nc.hasCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY)); 4543 4544 // Wifi should be the default network. 4545 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetwork()); 4546 mWiFiAgent.disconnect(); 4547 callback.expect(LOST, mWiFiAgent); 4548 4549 // The user accepted partial connectivity and selected "don't ask again". Now the user 4550 // reconnects to the partial connectivity network. Switch to wifi as soon as partial 4551 // connectivity is detected. 4552 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4553 mWiFiAgent.explicitlySelected(true /* explicitlySelected */, true /* acceptUnvalidated */); 4554 mWiFiAgent.connectWithPartialConnectivity(); 4555 // If user accepted partial connectivity network before, 4556 // NetworkMonitor#setAcceptPartialConnectivity() will be called in 4557 // ConnectivityService#updateNetworkInfo(). 4558 callback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 4559 verify(mWiFiAgent.mNetworkMonitor, times(1)).setAcceptPartialConnectivity(); 4560 callback.expectLosing(mCellAgent); 4561 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetwork()); 4562 callback.expectCaps(mWiFiAgent, c -> c.hasCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY)); 4563 expectUnvalidationCheckWillNotNotify(mWiFiAgent); 4564 4565 mWiFiAgent.setNetworkValid(false /* privateDnsProbeSent */); 4566 4567 // Need a trigger point to let NetworkMonitor tell ConnectivityService that the network is 4568 // validated. 4569 mCm.reportNetworkConnectivity(mWiFiAgent.getNetwork(), true); 4570 callback.expectCaps(mWiFiAgent, c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 4571 mWiFiAgent.disconnect(); 4572 callback.expect(LOST, mWiFiAgent); 4573 4574 // If the user accepted partial connectivity, and the device auto-reconnects to the partial 4575 // connectivity network, it should contain both PARTIAL_CONNECTIVITY and VALIDATED. 4576 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4577 mWiFiAgent.explicitlySelected(false /* explicitlySelected */, true /* acceptUnvalidated */); 4578 4579 // NetworkMonitor will immediately (once the HTTPS probe fails...) report the network as 4580 // valid, because ConnectivityService calls setAcceptPartialConnectivity before it calls 4581 // notifyNetworkConnected. 4582 mWiFiAgent.connectWithPartialValidConnectivity(false /* privateDnsProbeSent */); 4583 callback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 4584 verify(mWiFiAgent.mNetworkMonitor, times(1)).setAcceptPartialConnectivity(); 4585 callback.expectLosing(mCellAgent); 4586 callback.expectCaps(mWiFiAgent, c -> c.hasCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY) 4587 && c.hasCapability(NET_CAPABILITY_VALIDATED)); 4588 expectUnvalidationCheckWillNotNotify(mWiFiAgent); 4589 mWiFiAgent.disconnect(); 4590 callback.expect(LOST, mWiFiAgent); 4591 verifyNoMoreInteractions(mNotificationManager); 4592 } 4593 4594 @Test 4595 public void testCaptivePortalOnPartialConnectivity() throws Exception { 4596 final TestNetworkCallback wifiCallback = new TestNetworkCallback(); 4597 final NetworkRequest wifiRequest = new NetworkRequest.Builder() 4598 .addTransportType(TRANSPORT_WIFI) 4599 .build(); 4600 mCm.registerNetworkCallback(wifiRequest, wifiCallback); 4601 4602 final TestNetworkCallback validatedCallback = new TestNetworkCallback(); 4603 final NetworkRequest validatedRequest = new NetworkRequest.Builder() 4604 .addCapability(NET_CAPABILITY_VALIDATED).build(); 4605 mCm.registerNetworkCallback(validatedRequest, validatedCallback); 4606 4607 // Bring up a network with a captive portal. 4608 // Expect onAvailable callback of listen for NET_CAPABILITY_CAPTIVE_PORTAL. 4609 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4610 String redirectUrl = "http://android.com/path"; 4611 mWiFiAgent.connectWithCaptivePortal(redirectUrl, false /* privateDnsProbeSent */); 4612 wifiCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 4613 assertEquals(mWiFiAgent.waitForRedirectUrl(), redirectUrl); 4614 4615 // This is necessary because of b/245893397, the same bug that happens where we use 4616 // expectAvailableDoubleValidatedCallbacks. 4617 // TODO : fix b/245893397 and remove this. 4618 wifiCallback.expectCaps(mWiFiAgent, c -> c.hasCapability(NET_CAPABILITY_CAPTIVE_PORTAL)); 4619 4620 // Check that startCaptivePortalApp sends the expected command to NetworkMonitor. 4621 mCm.startCaptivePortalApp(mWiFiAgent.getNetwork()); 4622 verify(mWiFiAgent.mNetworkMonitor, timeout(TIMEOUT_MS).times(1)).launchCaptivePortalApp(); 4623 4624 // Report that the captive portal is dismissed with partial connectivity, and check that 4625 // callbacks are fired with PARTIAL and without CAPTIVE_PORTAL. 4626 mWiFiAgent.setNetworkPartial(); 4627 mCm.reportNetworkConnectivity(mWiFiAgent.getNetwork(), true); 4628 waitForIdle(); 4629 wifiCallback.expectCaps(mWiFiAgent, 4630 c -> c.hasCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY) 4631 && !c.hasCapability(NET_CAPABILITY_CAPTIVE_PORTAL)); 4632 4633 // Report partial connectivity is accepted. 4634 mWiFiAgent.setNetworkPartialValid(false /* privateDnsProbeSent */); 4635 mCm.setAcceptPartialConnectivity(mWiFiAgent.getNetwork(), true /* accept */, 4636 false /* always */); 4637 waitForIdle(); 4638 mCm.reportNetworkConnectivity(mWiFiAgent.getNetwork(), true); 4639 wifiCallback.expectCaps(mWiFiAgent, c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 4640 validatedCallback.expectAvailableCallbacksValidated(mWiFiAgent); 4641 validatedCallback.expectCaps(mWiFiAgent, 4642 c -> c.hasCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY)); 4643 4644 mCm.unregisterNetworkCallback(wifiCallback); 4645 mCm.unregisterNetworkCallback(validatedCallback); 4646 } 4647 4648 @Test 4649 public void testCaptivePortal() throws Exception { 4650 final TestNetworkCallback captivePortalCallback = new TestNetworkCallback(); 4651 final NetworkRequest captivePortalRequest = new NetworkRequest.Builder() 4652 .addCapability(NET_CAPABILITY_CAPTIVE_PORTAL).build(); 4653 mCm.registerNetworkCallback(captivePortalRequest, captivePortalCallback); 4654 4655 final TestNetworkCallback validatedCallback = new TestNetworkCallback(); 4656 final NetworkRequest validatedRequest = new NetworkRequest.Builder() 4657 .addCapability(NET_CAPABILITY_VALIDATED).build(); 4658 mCm.registerNetworkCallback(validatedRequest, validatedCallback); 4659 4660 // Bring up a network with a captive portal. 4661 // Expect onAvailable callback of listen for NET_CAPABILITY_CAPTIVE_PORTAL. 4662 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4663 String firstRedirectUrl = "http://example.com/firstPath"; 4664 mWiFiAgent.connectWithCaptivePortal(firstRedirectUrl, false /* privateDnsProbeSent */); 4665 captivePortalCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 4666 assertEquals(mWiFiAgent.waitForRedirectUrl(), firstRedirectUrl); 4667 4668 // Take down network. 4669 // Expect onLost callback. 4670 mWiFiAgent.disconnect(); 4671 captivePortalCallback.expect(LOST, mWiFiAgent); 4672 4673 // Bring up a network with a captive portal. 4674 // Expect onAvailable callback of listen for NET_CAPABILITY_CAPTIVE_PORTAL. 4675 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4676 String secondRedirectUrl = "http://example.com/secondPath"; 4677 mWiFiAgent.connectWithCaptivePortal(secondRedirectUrl, false /* privateDnsProbeSent */); 4678 captivePortalCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 4679 assertEquals(mWiFiAgent.waitForRedirectUrl(), secondRedirectUrl); 4680 4681 // Make captive portal disappear then revalidate. 4682 // Expect onLost callback because network no longer provides NET_CAPABILITY_CAPTIVE_PORTAL. 4683 mWiFiAgent.setNetworkValid(false /* privateDnsProbeSent */); 4684 mCm.reportNetworkConnectivity(mWiFiAgent.getNetwork(), true); 4685 captivePortalCallback.expect(LOST, mWiFiAgent); 4686 4687 // Expect NET_CAPABILITY_VALIDATED onAvailable callback. 4688 validatedCallback.expectAvailableDoubleValidatedCallbacks(mWiFiAgent); 4689 4690 // Break network connectivity. 4691 // Expect NET_CAPABILITY_VALIDATED onLost callback. 4692 mWiFiAgent.setNetworkInvalid(false /* invalidBecauseOfPrivateDns */); 4693 mCm.reportNetworkConnectivity(mWiFiAgent.getNetwork(), false); 4694 validatedCallback.expect(LOST, mWiFiAgent); 4695 } 4696 4697 private Intent startCaptivePortalApp(TestNetworkAgentWrapper networkAgent) throws Exception { 4698 Network network = networkAgent.getNetwork(); 4699 // Check that startCaptivePortalApp sends the expected command to NetworkMonitor. 4700 mCm.startCaptivePortalApp(network); 4701 waitForIdle(); 4702 verify(networkAgent.mNetworkMonitor).launchCaptivePortalApp(); 4703 4704 // NetworkMonitor uses startCaptivePortal(Network, Bundle) (startCaptivePortalAppInternal) 4705 final Bundle testBundle = new Bundle(); 4706 final String testKey = "testkey"; 4707 final String testValue = "testvalue"; 4708 testBundle.putString(testKey, testValue); 4709 mServiceContext.setPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, 4710 PERMISSION_GRANTED); 4711 mCm.startCaptivePortalApp(network, testBundle); 4712 final Intent signInIntent = mServiceContext.expectStartActivityIntent(TIMEOUT_MS); 4713 assertEquals(ACTION_CAPTIVE_PORTAL_SIGN_IN, signInIntent.getAction()); 4714 assertEquals(testValue, signInIntent.getStringExtra(testKey)); 4715 return signInIntent; 4716 } 4717 4718 @Test 4719 public void testCaptivePortalApp() throws Exception { 4720 final TestNetworkCallback captivePortalCallback = new TestNetworkCallback(); 4721 final NetworkRequest captivePortalRequest = new NetworkRequest.Builder() 4722 .addCapability(NET_CAPABILITY_CAPTIVE_PORTAL).build(); 4723 mCm.registerNetworkCallback(captivePortalRequest, captivePortalCallback); 4724 4725 final TestNetworkCallback validatedCallback = new TestNetworkCallback(); 4726 final NetworkRequest validatedRequest = new NetworkRequest.Builder() 4727 .addCapability(NET_CAPABILITY_VALIDATED).build(); 4728 mCm.registerNetworkCallback(validatedRequest, validatedCallback); 4729 4730 // Bring up wifi. 4731 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4732 mWiFiAgent.connect(true); 4733 validatedCallback.expectAvailableDoubleValidatedCallbacks(mWiFiAgent); 4734 Network wifiNetwork = mWiFiAgent.getNetwork(); 4735 4736 // Check that calling startCaptivePortalApp does nothing. 4737 final int fastTimeoutMs = 100; 4738 mCm.startCaptivePortalApp(wifiNetwork); 4739 waitForIdle(); 4740 verify(mWiFiAgent.mNetworkMonitor, never()).launchCaptivePortalApp(); 4741 mServiceContext.expectNoStartActivityIntent(fastTimeoutMs); 4742 4743 // Turn into a captive portal. 4744 mWiFiAgent.setNetworkPortal("http://example.com", false /* privateDnsProbeSent */); 4745 mCm.reportNetworkConnectivity(wifiNetwork, false); 4746 captivePortalCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 4747 validatedCallback.expect(LOST, mWiFiAgent); 4748 // This is necessary because of b/245893397, the same bug that happens where we use 4749 // expectAvailableDoubleValidatedCallbacks. 4750 // TODO : fix b/245893397 and remove this. 4751 captivePortalCallback.expectCaps(mWiFiAgent); 4752 4753 startCaptivePortalApp(mWiFiAgent); 4754 4755 // Report that the captive portal is dismissed, and check that callbacks are fired 4756 mWiFiAgent.setNetworkValid(false /* privateDnsProbeSent */); 4757 mWiFiAgent.mNetworkMonitor.forceReevaluation(Process.myUid()); 4758 validatedCallback.expectAvailableCallbacksValidated(mWiFiAgent); 4759 captivePortalCallback.expect(LOST, mWiFiAgent); 4760 4761 mCm.unregisterNetworkCallback(validatedCallback); 4762 mCm.unregisterNetworkCallback(captivePortalCallback); 4763 } 4764 4765 @Test 4766 public void testCaptivePortalApp_IgnoreNetwork() throws Exception { 4767 final TestNetworkCallback captivePortalCallback = new TestNetworkCallback(); 4768 final NetworkRequest captivePortalRequest = new NetworkRequest.Builder() 4769 .addCapability(NET_CAPABILITY_CAPTIVE_PORTAL).build(); 4770 mCm.registerNetworkCallback(captivePortalRequest, captivePortalCallback); 4771 4772 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4773 mWiFiAgent.connectWithCaptivePortal(TEST_REDIRECT_URL, false); 4774 captivePortalCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 4775 4776 final Intent signInIntent = startCaptivePortalApp(mWiFiAgent); 4777 final CaptivePortal captivePortal = signInIntent 4778 .getParcelableExtra(ConnectivityManager.EXTRA_CAPTIVE_PORTAL); 4779 4780 captivePortal.ignoreNetwork(); 4781 waitForIdle(); 4782 4783 // Since network will disconnect, ensure no notification of response to NetworkMonitor 4784 verify(mWiFiAgent.mNetworkMonitor, never()) 4785 .notifyCaptivePortalAppFinished(CaptivePortal.APP_RETURN_UNWANTED); 4786 4787 // Report that the network is disconnected 4788 mWiFiAgent.expectDisconnected(); 4789 mWiFiAgent.expectPreventReconnectReceived(); 4790 verify(mWiFiAgent.mNetworkMonitor).notifyNetworkDisconnected(); 4791 captivePortalCallback.expect(LOST, mWiFiAgent); 4792 4793 mCm.unregisterNetworkCallback(captivePortalCallback); 4794 } 4795 4796 @Test 4797 public void testAvoidOrIgnoreCaptivePortals() throws Exception { 4798 final TestNetworkCallback captivePortalCallback = new TestNetworkCallback(); 4799 final NetworkRequest captivePortalRequest = new NetworkRequest.Builder() 4800 .addCapability(NET_CAPABILITY_CAPTIVE_PORTAL).build(); 4801 mCm.registerNetworkCallback(captivePortalRequest, captivePortalCallback); 4802 4803 final TestNetworkCallback validatedCallback = new TestNetworkCallback(); 4804 final NetworkRequest validatedRequest = new NetworkRequest.Builder() 4805 .addCapability(NET_CAPABILITY_VALIDATED).build(); 4806 mCm.registerNetworkCallback(validatedRequest, validatedCallback); 4807 4808 setCaptivePortalMode(ConnectivitySettingsManager.CAPTIVE_PORTAL_MODE_AVOID); 4809 // Bring up a network with a captive portal. 4810 // Expect it to fail to connect and not result in any callbacks. 4811 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4812 final String firstRedirectUrl = "http://example.com/firstPath"; 4813 4814 mWiFiAgent.connectWithCaptivePortal(firstRedirectUrl, false /* privateDnsProbeSent */); 4815 mWiFiAgent.expectDisconnected(); 4816 mWiFiAgent.expectPreventReconnectReceived(); 4817 4818 assertNoCallbacks(captivePortalCallback, validatedCallback); 4819 } 4820 4821 @Test 4822 public void testCaptivePortalApi() throws Exception { 4823 mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_GRANTED); 4824 4825 final TestNetworkCallback captivePortalCallback = new TestNetworkCallback(); 4826 final NetworkRequest captivePortalRequest = new NetworkRequest.Builder() 4827 .addCapability(NET_CAPABILITY_CAPTIVE_PORTAL).build(); 4828 mCm.registerNetworkCallback(captivePortalRequest, captivePortalCallback); 4829 4830 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4831 final String redirectUrl = "http://example.com/firstPath"; 4832 4833 mWiFiAgent.connectWithCaptivePortal(redirectUrl, 4834 false /* privateDnsProbeSent */); 4835 captivePortalCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 4836 4837 final CaptivePortalData testData = new CaptivePortalData.Builder() 4838 .setUserPortalUrl(Uri.parse(redirectUrl)) 4839 .setBytesRemaining(12345L) 4840 .build(); 4841 4842 mWiFiAgent.notifyCapportApiDataChanged(testData); 4843 4844 captivePortalCallback.expect(LINK_PROPERTIES_CHANGED, mWiFiAgent, 4845 cb -> testData.equals(cb.getLp().getCaptivePortalData())); 4846 4847 final LinkProperties newLps = new LinkProperties(); 4848 newLps.setMtu(1234); 4849 mWiFiAgent.sendLinkProperties(newLps); 4850 // CaptivePortalData is not lost and unchanged when LPs are received from the NetworkAgent 4851 captivePortalCallback.expect(LINK_PROPERTIES_CHANGED, mWiFiAgent, 4852 cb -> testData.equals(cb.getLp().getCaptivePortalData()) 4853 && cb.getLp().getMtu() == 1234); 4854 } 4855 4856 private TestNetworkCallback setupNetworkCallbackAndConnectToWifi() throws Exception { 4857 // Grant NETWORK_SETTINGS permission to be able to receive LinkProperties change callbacks 4858 // with sensitive (captive portal) data 4859 mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_GRANTED); 4860 4861 final TestNetworkCallback captivePortalCallback = new TestNetworkCallback(); 4862 final NetworkRequest captivePortalRequest = new NetworkRequest.Builder() 4863 .addCapability(NET_CAPABILITY_CAPTIVE_PORTAL).build(); 4864 mCm.registerNetworkCallback(captivePortalRequest, captivePortalCallback); 4865 4866 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4867 4868 mWiFiAgent.connectWithCaptivePortal(TEST_REDIRECT_URL, 4869 false /* privateDnsProbeSent */); 4870 captivePortalCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 4871 return captivePortalCallback; 4872 } 4873 4874 private class CaptivePortalTestData { 4875 CaptivePortalTestData(CaptivePortalData naPasspointData, CaptivePortalData capportData, 4876 CaptivePortalData naOtherData, CaptivePortalData expectedMergedPasspointData, 4877 CaptivePortalData expectedMergedOtherData) { 4878 mNaPasspointData = naPasspointData; 4879 mCapportData = capportData; 4880 mNaOtherData = naOtherData; 4881 mExpectedMergedPasspointData = expectedMergedPasspointData; 4882 mExpectedMergedOtherData = expectedMergedOtherData; 4883 } 4884 4885 public final CaptivePortalData mNaPasspointData; 4886 public final CaptivePortalData mCapportData; 4887 public final CaptivePortalData mNaOtherData; 4888 public final CaptivePortalData mExpectedMergedPasspointData; 4889 public final CaptivePortalData mExpectedMergedOtherData; 4890 4891 } 4892 4893 private CaptivePortalTestData setupCaptivePortalData() { 4894 final CaptivePortalData capportData = new CaptivePortalData.Builder() 4895 .setUserPortalUrl(Uri.parse(TEST_REDIRECT_URL)) 4896 .setVenueInfoUrl(Uri.parse(TEST_VENUE_URL_CAPPORT)) 4897 .setUserPortalUrl(Uri.parse(TEST_USER_PORTAL_API_URL_CAPPORT)) 4898 .setExpiryTime(1000000L) 4899 .setBytesRemaining(12345L) 4900 .build(); 4901 4902 final CaptivePortalData naPasspointData = new CaptivePortalData.Builder() 4903 .setBytesRemaining(80802L) 4904 .setVenueInfoUrl(Uri.parse(TEST_VENUE_URL_NA_PASSPOINT), 4905 CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT) 4906 .setUserPortalUrl(Uri.parse(TEST_TERMS_AND_CONDITIONS_URL_NA_PASSPOINT), 4907 CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT) 4908 .setVenueFriendlyName(TEST_FRIENDLY_NAME).build(); 4909 4910 final CaptivePortalData naOtherData = new CaptivePortalData.Builder() 4911 .setBytesRemaining(80802L) 4912 .setVenueInfoUrl(Uri.parse(TEST_VENUE_URL_NA_OTHER), 4913 CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_OTHER) 4914 .setUserPortalUrl(Uri.parse(TEST_TERMS_AND_CONDITIONS_URL_NA_OTHER), 4915 CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_OTHER) 4916 .setVenueFriendlyName(TEST_FRIENDLY_NAME).build(); 4917 4918 final CaptivePortalData expectedMergedPasspointData = new CaptivePortalData.Builder() 4919 .setUserPortalUrl(Uri.parse(TEST_REDIRECT_URL)) 4920 .setBytesRemaining(12345L) 4921 .setExpiryTime(1000000L) 4922 .setVenueInfoUrl(Uri.parse(TEST_VENUE_URL_NA_PASSPOINT), 4923 CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT) 4924 .setUserPortalUrl(Uri.parse(TEST_TERMS_AND_CONDITIONS_URL_NA_PASSPOINT), 4925 CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT) 4926 .setVenueFriendlyName(TEST_FRIENDLY_NAME).build(); 4927 4928 final CaptivePortalData expectedMergedOtherData = new CaptivePortalData.Builder() 4929 .setUserPortalUrl(Uri.parse(TEST_REDIRECT_URL)) 4930 .setBytesRemaining(12345L) 4931 .setExpiryTime(1000000L) 4932 .setVenueInfoUrl(Uri.parse(TEST_VENUE_URL_CAPPORT)) 4933 .setUserPortalUrl(Uri.parse(TEST_USER_PORTAL_API_URL_CAPPORT)) 4934 .setVenueFriendlyName(TEST_FRIENDLY_NAME).build(); 4935 return new CaptivePortalTestData(naPasspointData, capportData, naOtherData, 4936 expectedMergedPasspointData, expectedMergedOtherData); 4937 } 4938 4939 @Test 4940 public void testMergeCaptivePortalApiWithFriendlyNameAndVenueUrl() throws Exception { 4941 final TestNetworkCallback captivePortalCallback = setupNetworkCallbackAndConnectToWifi(); 4942 final CaptivePortalTestData captivePortalTestData = setupCaptivePortalData(); 4943 4944 // Baseline capport data 4945 mWiFiAgent.notifyCapportApiDataChanged(captivePortalTestData.mCapportData); 4946 4947 captivePortalCallback.expect(LINK_PROPERTIES_CHANGED, mWiFiAgent, 4948 cb -> captivePortalTestData.mCapportData.equals(cb.getLp().getCaptivePortalData())); 4949 4950 // Venue URL, T&C URL and friendly name from Network agent with Passpoint source, confirm 4951 // that API data gets precedence on the bytes remaining. 4952 final LinkProperties linkProperties = new LinkProperties(); 4953 linkProperties.setCaptivePortalData(captivePortalTestData.mNaPasspointData); 4954 mWiFiAgent.sendLinkProperties(linkProperties); 4955 4956 // Make sure that the capport data is merged 4957 captivePortalCallback.expect(LINK_PROPERTIES_CHANGED, mWiFiAgent, 4958 cb -> captivePortalTestData.mExpectedMergedPasspointData.equals( 4959 cb.getLp().getCaptivePortalData())); 4960 4961 // Now send this information from non-Passpoint source, confirm that Capport data takes 4962 // precedence 4963 linkProperties.setCaptivePortalData(captivePortalTestData.mNaOtherData); 4964 mWiFiAgent.sendLinkProperties(linkProperties); 4965 4966 // Make sure that the capport data is merged 4967 captivePortalCallback.expect(LINK_PROPERTIES_CHANGED, mWiFiAgent, 4968 cb -> captivePortalTestData.mExpectedMergedOtherData.equals( 4969 cb.getLp().getCaptivePortalData())); 4970 4971 // Create a new LP with no Network agent capport data 4972 final LinkProperties newLps = new LinkProperties(); 4973 newLps.setMtu(1234); 4974 mWiFiAgent.sendLinkProperties(newLps); 4975 // CaptivePortalData is not lost and has the original values when LPs are received from the 4976 // NetworkAgent 4977 captivePortalCallback.expect(LINK_PROPERTIES_CHANGED, mWiFiAgent, 4978 cb -> captivePortalTestData.mCapportData.equals(cb.getLp().getCaptivePortalData()) 4979 && cb.getLp().getMtu() == 1234); 4980 4981 // Now send capport data only from the Network agent 4982 mWiFiAgent.notifyCapportApiDataChanged(null); 4983 captivePortalCallback.expect(LINK_PROPERTIES_CHANGED, mWiFiAgent, 4984 cb -> cb.getLp().getCaptivePortalData() == null); 4985 4986 newLps.setCaptivePortalData(captivePortalTestData.mNaPasspointData); 4987 mWiFiAgent.sendLinkProperties(newLps); 4988 4989 // Make sure that only the network agent capport data is available 4990 captivePortalCallback.expect(LINK_PROPERTIES_CHANGED, mWiFiAgent, 4991 cb -> captivePortalTestData.mNaPasspointData.equals( 4992 cb.getLp().getCaptivePortalData())); 4993 } 4994 4995 @Test 4996 public void testMergeCaptivePortalDataFromNetworkAgentFirstThenCapport() throws Exception { 4997 final TestNetworkCallback captivePortalCallback = setupNetworkCallbackAndConnectToWifi(); 4998 final CaptivePortalTestData captivePortalTestData = setupCaptivePortalData(); 4999 5000 // Venue URL and friendly name from Network agent, confirm that API data gets precedence 5001 // on the bytes remaining. 5002 final LinkProperties linkProperties = new LinkProperties(); 5003 linkProperties.setCaptivePortalData(captivePortalTestData.mNaPasspointData); 5004 mWiFiAgent.sendLinkProperties(linkProperties); 5005 5006 // Make sure that the data is saved correctly 5007 captivePortalCallback.expect(LINK_PROPERTIES_CHANGED, mWiFiAgent, 5008 cb -> captivePortalTestData.mNaPasspointData.equals( 5009 cb.getLp().getCaptivePortalData())); 5010 5011 // Expected merged data: Network agent data is preferred, and values that are not used by 5012 // it are merged from capport data 5013 mWiFiAgent.notifyCapportApiDataChanged(captivePortalTestData.mCapportData); 5014 5015 // Make sure that the Capport data is merged correctly 5016 captivePortalCallback.expect(LINK_PROPERTIES_CHANGED, mWiFiAgent, 5017 cb -> captivePortalTestData.mExpectedMergedPasspointData.equals( 5018 cb.getLp().getCaptivePortalData())); 5019 5020 // Now set the naData to null 5021 linkProperties.setCaptivePortalData(null); 5022 mWiFiAgent.sendLinkProperties(linkProperties); 5023 5024 // Make sure that the Capport data is retained correctly 5025 captivePortalCallback.expect(LINK_PROPERTIES_CHANGED, mWiFiAgent, 5026 cb -> captivePortalTestData.mCapportData.equals(cb.getLp().getCaptivePortalData())); 5027 } 5028 5029 @Test 5030 public void testMergeCaptivePortalDataFromNetworkAgentOtherSourceFirstThenCapport() 5031 throws Exception { 5032 final TestNetworkCallback captivePortalCallback = setupNetworkCallbackAndConnectToWifi(); 5033 final CaptivePortalTestData captivePortalTestData = setupCaptivePortalData(); 5034 5035 // Venue URL and friendly name from Network agent, confirm that API data gets precedence 5036 // on the bytes remaining. 5037 final LinkProperties linkProperties = new LinkProperties(); 5038 linkProperties.setCaptivePortalData(captivePortalTestData.mNaOtherData); 5039 mWiFiAgent.sendLinkProperties(linkProperties); 5040 5041 // Make sure that the data is saved correctly 5042 captivePortalCallback.expect(LINK_PROPERTIES_CHANGED, mWiFiAgent, 5043 cb -> captivePortalTestData.mNaOtherData.equals(cb.getLp().getCaptivePortalData())); 5044 5045 // Expected merged data: Network agent data is preferred, and values that are not used by 5046 // it are merged from capport data 5047 mWiFiAgent.notifyCapportApiDataChanged(captivePortalTestData.mCapportData); 5048 5049 // Make sure that the Capport data is merged correctly 5050 captivePortalCallback.expect(LINK_PROPERTIES_CHANGED, mWiFiAgent, 5051 cb -> captivePortalTestData.mExpectedMergedOtherData.equals( 5052 cb.getLp().getCaptivePortalData())); 5053 } 5054 5055 private NetworkRequest.Builder newWifiRequestBuilder() { 5056 return new NetworkRequest.Builder().addTransportType(TRANSPORT_WIFI); 5057 } 5058 5059 // A NetworkSpecifier subclass that matches all networks but must not be visible to apps. 5060 static class ConfidentialMatchAllNetworkSpecifier extends NetworkSpecifier implements 5061 Parcelable { 5062 public static final Parcelable.Creator<ConfidentialMatchAllNetworkSpecifier> CREATOR = 5063 new Parcelable.Creator<ConfidentialMatchAllNetworkSpecifier>() { 5064 public ConfidentialMatchAllNetworkSpecifier createFromParcel(Parcel in) { 5065 return new ConfidentialMatchAllNetworkSpecifier(); 5066 } 5067 5068 public ConfidentialMatchAllNetworkSpecifier[] newArray(int size) { 5069 return new ConfidentialMatchAllNetworkSpecifier[size]; 5070 } 5071 }; 5072 @Override 5073 public boolean canBeSatisfiedBy(NetworkSpecifier other) { 5074 return true; 5075 } 5076 5077 @Override 5078 public int describeContents() { 5079 return 0; 5080 } 5081 5082 @Override 5083 public void writeToParcel(Parcel dest, int flags) {} 5084 5085 @Override 5086 public NetworkSpecifier redact() { 5087 return null; 5088 } 5089 } 5090 5091 // A network specifier that matches either another LocalNetworkSpecifier with the same 5092 // string or a ConfidentialMatchAllNetworkSpecifier, and can be passed to apps as is. 5093 static class LocalStringNetworkSpecifier extends NetworkSpecifier implements Parcelable { 5094 public static final Parcelable.Creator<LocalStringNetworkSpecifier> CREATOR = 5095 new Parcelable.Creator<LocalStringNetworkSpecifier>() { 5096 public LocalStringNetworkSpecifier createFromParcel(Parcel in) { 5097 return new LocalStringNetworkSpecifier(in); 5098 } 5099 5100 public LocalStringNetworkSpecifier[] newArray(int size) { 5101 return new LocalStringNetworkSpecifier[size]; 5102 } 5103 }; 5104 private String mString; 5105 5106 LocalStringNetworkSpecifier(String string) { 5107 mString = string; 5108 } 5109 5110 LocalStringNetworkSpecifier(Parcel in) { 5111 mString = in.readString(); 5112 } 5113 5114 @Override 5115 public boolean canBeSatisfiedBy(NetworkSpecifier other) { 5116 if (other instanceof LocalStringNetworkSpecifier) { 5117 return TextUtils.equals(mString, 5118 ((LocalStringNetworkSpecifier) other).mString); 5119 } 5120 if (other instanceof ConfidentialMatchAllNetworkSpecifier) return true; 5121 return false; 5122 } 5123 5124 @Override 5125 public int describeContents() { 5126 return 0; 5127 } 5128 @Override 5129 public void writeToParcel(Parcel dest, int flags) { 5130 dest.writeString(mString); 5131 } 5132 } 5133 5134 /** 5135 * Verify request matching behavior with network specifiers. 5136 * 5137 * This test does not check updating the specifier on a live network because the specifier is 5138 * immutable and this triggers a WTF in 5139 * {@link ConnectivityService#mixInCapabilities(NetworkAgentInfo, NetworkCapabilities)}. 5140 */ 5141 @Test 5142 public void testNetworkSpecifier() throws Exception { 5143 NetworkRequest rEmpty1 = newWifiRequestBuilder().build(); 5144 NetworkRequest rEmpty2 = newWifiRequestBuilder().setNetworkSpecifier((String) null).build(); 5145 NetworkRequest rEmpty3 = newWifiRequestBuilder().setNetworkSpecifier("").build(); 5146 NetworkRequest rEmpty4 = newWifiRequestBuilder().setNetworkSpecifier( 5147 (NetworkSpecifier) null).build(); 5148 NetworkRequest rFoo = newWifiRequestBuilder().setNetworkSpecifier( 5149 new LocalStringNetworkSpecifier("foo")).build(); 5150 NetworkRequest rBar = newWifiRequestBuilder().setNetworkSpecifier( 5151 new LocalStringNetworkSpecifier("bar")).build(); 5152 5153 TestNetworkCallback cEmpty1 = new TestNetworkCallback(); 5154 TestNetworkCallback cEmpty2 = new TestNetworkCallback(); 5155 TestNetworkCallback cEmpty3 = new TestNetworkCallback(); 5156 TestNetworkCallback cEmpty4 = new TestNetworkCallback(); 5157 TestNetworkCallback cFoo = new TestNetworkCallback(); 5158 TestNetworkCallback cBar = new TestNetworkCallback(); 5159 TestNetworkCallback[] emptyCallbacks = new TestNetworkCallback[] { 5160 cEmpty1, cEmpty2, cEmpty3, cEmpty4 }; 5161 5162 mCm.registerNetworkCallback(rEmpty1, cEmpty1); 5163 mCm.registerNetworkCallback(rEmpty2, cEmpty2); 5164 mCm.registerNetworkCallback(rEmpty3, cEmpty3); 5165 mCm.registerNetworkCallback(rEmpty4, cEmpty4); 5166 mCm.registerNetworkCallback(rFoo, cFoo); 5167 mCm.registerNetworkCallback(rBar, cBar); 5168 5169 LocalStringNetworkSpecifier nsFoo = new LocalStringNetworkSpecifier("foo"); 5170 LocalStringNetworkSpecifier nsBar = new LocalStringNetworkSpecifier("bar"); 5171 5172 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 5173 mWiFiAgent.connect(false); 5174 expectAvailableCallbacksUnvalidatedWithSpecifier(mWiFiAgent, null /* specifier */, 5175 cEmpty1, cEmpty2, cEmpty3, cEmpty4); 5176 assertNoCallbacks(cFoo, cBar); 5177 5178 mWiFiAgent.disconnect(); 5179 expectOnLost(mWiFiAgent, cEmpty1, cEmpty2, cEmpty3, cEmpty4); 5180 5181 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 5182 mWiFiAgent.setNetworkSpecifier(nsFoo); 5183 mWiFiAgent.connect(false); 5184 expectAvailableCallbacksUnvalidatedWithSpecifier(mWiFiAgent, nsFoo, 5185 cEmpty1, cEmpty2, cEmpty3, cEmpty4, cFoo); 5186 cBar.assertNoCallback(); 5187 assertEquals(nsFoo, 5188 mCm.getNetworkCapabilities(mWiFiAgent.getNetwork()).getNetworkSpecifier()); 5189 assertNoCallbacks(cEmpty1, cEmpty2, cEmpty3, cEmpty4, cFoo); 5190 5191 mWiFiAgent.disconnect(); 5192 expectOnLost(mWiFiAgent, cEmpty1, cEmpty2, cEmpty3, cEmpty4, cFoo); 5193 5194 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 5195 mWiFiAgent.setNetworkSpecifier(nsBar); 5196 mWiFiAgent.connect(false); 5197 expectAvailableCallbacksUnvalidatedWithSpecifier(mWiFiAgent, nsBar, 5198 cEmpty1, cEmpty2, cEmpty3, cEmpty4, cBar); 5199 cFoo.assertNoCallback(); 5200 assertEquals(nsBar, 5201 mCm.getNetworkCapabilities(mWiFiAgent.getNetwork()).getNetworkSpecifier()); 5202 5203 mWiFiAgent.disconnect(); 5204 expectOnLost(mWiFiAgent, cEmpty1, cEmpty2, cEmpty3, cEmpty4, cBar); 5205 cFoo.assertNoCallback(); 5206 5207 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 5208 mWiFiAgent.setNetworkSpecifier(new ConfidentialMatchAllNetworkSpecifier()); 5209 mWiFiAgent.connect(false); 5210 expectAvailableCallbacksUnvalidatedWithSpecifier(mWiFiAgent, null /* specifier */, 5211 cEmpty1, cEmpty2, cEmpty3, cEmpty4, cFoo, cBar); 5212 assertNull(mCm.getNetworkCapabilities(mWiFiAgent.getNetwork()).getNetworkSpecifier()); 5213 5214 mWiFiAgent.disconnect(); 5215 expectOnLost(mWiFiAgent, cEmpty1, cEmpty2, cEmpty3, cEmpty4, cFoo, cBar); 5216 } 5217 5218 /** 5219 * @return the context's attribution tag 5220 */ 5221 private String getAttributionTag() { 5222 return mContext.getAttributionTag(); 5223 } 5224 5225 static class NonParcelableSpecifier extends NetworkSpecifier { 5226 @Override 5227 public boolean canBeSatisfiedBy(NetworkSpecifier other) { 5228 return false; 5229 } 5230 } 5231 static class ParcelableSpecifier extends NonParcelableSpecifier implements Parcelable { 5232 public static final Parcelable.Creator<NonParcelableSpecifier> CREATOR = 5233 new Parcelable.Creator<NonParcelableSpecifier>() { 5234 public NonParcelableSpecifier createFromParcel(Parcel in) { 5235 return new NonParcelableSpecifier(); 5236 } 5237 5238 public NonParcelableSpecifier[] newArray(int size) { 5239 return new NonParcelableSpecifier[size]; 5240 } 5241 }; 5242 @Override public int describeContents() { 5243 return 0; 5244 } 5245 @Override public void writeToParcel(Parcel p, int flags) {} 5246 } 5247 5248 @Test 5249 public void testInvalidNetworkSpecifier() { 5250 assertThrows(IllegalArgumentException.class, () -> { 5251 NetworkRequest.Builder builder = new NetworkRequest.Builder(); 5252 builder.setNetworkSpecifier(new MatchAllNetworkSpecifier()); 5253 }); 5254 5255 assertThrows(IllegalArgumentException.class, () -> { 5256 NetworkCapabilities networkCapabilities = new NetworkCapabilities(); 5257 networkCapabilities.addTransportType(TRANSPORT_WIFI) 5258 .setNetworkSpecifier(new MatchAllNetworkSpecifier()); 5259 mService.requestNetwork(Process.INVALID_UID, networkCapabilities, 5260 NetworkRequest.Type.REQUEST.ordinal(), null, 0, null, 5261 ConnectivityManager.TYPE_WIFI, NetworkCallback.FLAG_NONE, 5262 mContext.getPackageName(), getAttributionTag()); 5263 }); 5264 5265 final NetworkRequest.Builder builder = 5266 new NetworkRequest.Builder().addTransportType(TRANSPORT_ETHERNET); 5267 assertThrows(ClassCastException.class, () -> { 5268 builder.setNetworkSpecifier(new NonParcelableSpecifier()); 5269 Parcel parcelW = Parcel.obtain(); 5270 builder.build().writeToParcel(parcelW, 0); 5271 }); 5272 5273 final NetworkRequest nr = 5274 new NetworkRequest.Builder().addTransportType(TRANSPORT_ETHERNET) 5275 .setNetworkSpecifier(new ParcelableSpecifier()) 5276 .build(); 5277 assertNotNull(nr); 5278 5279 assertThrows(BadParcelableException.class, () -> { 5280 Parcel parcelW = Parcel.obtain(); 5281 nr.writeToParcel(parcelW, 0); 5282 byte[] bytes = parcelW.marshall(); 5283 parcelW.recycle(); 5284 5285 Parcel parcelR = Parcel.obtain(); 5286 parcelR.unmarshall(bytes, 0, bytes.length); 5287 parcelR.setDataPosition(0); 5288 NetworkRequest rereadNr = NetworkRequest.CREATOR.createFromParcel(parcelR); 5289 }); 5290 } 5291 5292 @Test 5293 public void testNetworkRequestUidSpoofSecurityException() throws Exception { 5294 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 5295 mWiFiAgent.connect(false); 5296 NetworkRequest networkRequest = newWifiRequestBuilder().build(); 5297 TestNetworkCallback networkCallback = new TestNetworkCallback(); 5298 doThrow(new SecurityException()).when(mAppOpsManager).checkPackage(anyInt(), anyString()); 5299 assertThrows(SecurityException.class, () -> { 5300 mCm.requestNetwork(networkRequest, networkCallback); 5301 }); 5302 } 5303 5304 @Test 5305 public void testInvalidSignalStrength() { 5306 NetworkRequest r = new NetworkRequest.Builder() 5307 .addCapability(NET_CAPABILITY_INTERNET) 5308 .addTransportType(TRANSPORT_WIFI) 5309 .setSignalStrength(-75) 5310 .build(); 5311 // Registering a NetworkCallback with signal strength but w/o NETWORK_SIGNAL_STRENGTH_WAKEUP 5312 // permission should get SecurityException. 5313 assertThrows(SecurityException.class, () -> 5314 mCm.registerNetworkCallback(r, new NetworkCallback())); 5315 5316 assertThrows(SecurityException.class, () -> 5317 mCm.registerNetworkCallback(r, PendingIntent.getService( 5318 mServiceContext, 0 /* requestCode */, new Intent(), FLAG_IMMUTABLE))); 5319 5320 // Requesting a Network with signal strength should get IllegalArgumentException. 5321 assertThrows(IllegalArgumentException.class, () -> 5322 mCm.requestNetwork(r, new NetworkCallback())); 5323 5324 assertThrows(IllegalArgumentException.class, () -> 5325 mCm.requestNetwork(r, PendingIntent.getService( 5326 mServiceContext, 0 /* requestCode */, new Intent(), FLAG_IMMUTABLE))); 5327 } 5328 5329 @Test 5330 public void testRegisterDefaultNetworkCallback() throws Exception { 5331 final TestNetworkCallback defaultNetworkCallback = new TestNetworkCallback(); 5332 mCm.registerDefaultNetworkCallback(defaultNetworkCallback); 5333 defaultNetworkCallback.assertNoCallback(); 5334 5335 final Handler handler = new Handler(ConnectivityThread.getInstanceLooper()); 5336 final TestNetworkCallback systemDefaultCallback = new TestNetworkCallback(); 5337 mCm.registerSystemDefaultNetworkCallback(systemDefaultCallback, handler); 5338 systemDefaultCallback.assertNoCallback(); 5339 5340 // Create a TRANSPORT_CELLULAR request to keep the mobile interface up 5341 // whenever Wi-Fi is up. Without this, the mobile network agent is 5342 // reaped before any other activity can take place. 5343 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback(); 5344 final NetworkRequest cellRequest = new NetworkRequest.Builder() 5345 .addTransportType(TRANSPORT_CELLULAR).build(); 5346 mCm.requestNetwork(cellRequest, cellNetworkCallback); 5347 cellNetworkCallback.assertNoCallback(); 5348 5349 // Bring up cell and expect CALLBACK_AVAILABLE. 5350 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 5351 mCellAgent.connect(true); 5352 cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 5353 defaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 5354 systemDefaultCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 5355 assertEquals(defaultNetworkCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 5356 assertEquals(systemDefaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 5357 5358 // Bring up wifi and expect CALLBACK_AVAILABLE. 5359 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 5360 mWiFiAgent.connect(true); 5361 cellNetworkCallback.assertNoCallback(); 5362 defaultNetworkCallback.expectAvailableDoubleValidatedCallbacks(mWiFiAgent); 5363 systemDefaultCallback.expectAvailableDoubleValidatedCallbacks(mWiFiAgent); 5364 assertEquals(defaultNetworkCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 5365 assertEquals(systemDefaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 5366 5367 // Bring down cell. Expect no default network callback, since it wasn't the default. 5368 mCellAgent.disconnect(); 5369 cellNetworkCallback.expect(LOST, mCellAgent); 5370 defaultNetworkCallback.assertNoCallback(); 5371 systemDefaultCallback.assertNoCallback(); 5372 assertEquals(defaultNetworkCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 5373 assertEquals(systemDefaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 5374 5375 // Bring up cell. Expect no default network callback, since it won't be the default. 5376 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 5377 mCellAgent.connect(true); 5378 cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 5379 defaultNetworkCallback.assertNoCallback(); 5380 systemDefaultCallback.assertNoCallback(); 5381 assertEquals(defaultNetworkCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 5382 assertEquals(systemDefaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 5383 5384 // Bring down wifi. Expect the default network callback to notified of LOST wifi 5385 // followed by AVAILABLE cell. 5386 mWiFiAgent.disconnect(); 5387 cellNetworkCallback.assertNoCallback(); 5388 defaultNetworkCallback.expect(LOST, mWiFiAgent); 5389 defaultNetworkCallback.expectAvailableCallbacksValidated(mCellAgent); 5390 systemDefaultCallback.expect(LOST, mWiFiAgent); 5391 systemDefaultCallback.expectAvailableCallbacksValidated(mCellAgent); 5392 mCellAgent.disconnect(); 5393 cellNetworkCallback.expect(LOST, mCellAgent); 5394 defaultNetworkCallback.expect(LOST, mCellAgent); 5395 systemDefaultCallback.expect(LOST, mCellAgent); 5396 waitForIdle(); 5397 assertEquals(null, mCm.getActiveNetwork()); 5398 5399 mMockVpn.establishForMyUid(); 5400 assertUidRangesUpdatedForMyUid(true); 5401 defaultNetworkCallback.expectAvailableThenValidatedCallbacks(mMockVpn); 5402 systemDefaultCallback.assertNoCallback(); 5403 assertEquals(defaultNetworkCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 5404 assertEquals(null, systemDefaultCallback.getLastAvailableNetwork()); 5405 5406 mMockVpn.disconnect(); 5407 defaultNetworkCallback.expect(LOST, mMockVpn); 5408 systemDefaultCallback.assertNoCallback(); 5409 waitForIdle(); 5410 assertEquals(null, mCm.getActiveNetwork()); 5411 } 5412 5413 @Test 5414 public void testAdditionalStateCallbacks() throws Exception { 5415 // File a network request for mobile. 5416 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback(); 5417 final NetworkRequest cellRequest = new NetworkRequest.Builder() 5418 .addTransportType(TRANSPORT_CELLULAR).build(); 5419 mCm.requestNetwork(cellRequest, cellNetworkCallback); 5420 5421 // Bring up the mobile network. 5422 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 5423 mCellAgent.connect(true); 5424 5425 // We should get onAvailable(), onCapabilitiesChanged(), and 5426 // onLinkPropertiesChanged() in rapid succession. Additionally, we 5427 // should get onCapabilitiesChanged() when the mobile network validates. 5428 cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 5429 cellNetworkCallback.assertNoCallback(); 5430 5431 // Update LinkProperties. 5432 final LinkProperties lp = new LinkProperties(); 5433 lp.setInterfaceName("foonet_data0"); 5434 mCellAgent.sendLinkProperties(lp); 5435 // We should get onLinkPropertiesChanged(). 5436 cellNetworkCallback.expect(LINK_PROPERTIES_CHANGED, mCellAgent); 5437 cellNetworkCallback.assertNoCallback(); 5438 5439 // Suspend the network. 5440 mCellAgent.suspend(); 5441 cellNetworkCallback.expectCaps(mCellAgent, 5442 c -> !c.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 5443 cellNetworkCallback.expect(SUSPENDED, mCellAgent); 5444 cellNetworkCallback.assertNoCallback(); 5445 assertEquals(NetworkInfo.State.SUSPENDED, mCm.getActiveNetworkInfo().getState()); 5446 5447 // Register a garden variety default network request. 5448 TestNetworkCallback dfltNetworkCallback = new TestNetworkCallback(); 5449 mCm.registerDefaultNetworkCallback(dfltNetworkCallback); 5450 // We should get onAvailable(), onCapabilitiesChanged(), onLinkPropertiesChanged(), 5451 // as well as onNetworkSuspended() in rapid succession. 5452 dfltNetworkCallback.expectAvailableAndSuspendedCallbacks(mCellAgent, true); 5453 dfltNetworkCallback.assertNoCallback(); 5454 mCm.unregisterNetworkCallback(dfltNetworkCallback); 5455 5456 mCellAgent.resume(); 5457 cellNetworkCallback.expectCaps(mCellAgent, 5458 c -> c.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 5459 cellNetworkCallback.expect(RESUMED, mCellAgent); 5460 cellNetworkCallback.assertNoCallback(); 5461 assertEquals(NetworkInfo.State.CONNECTED, mCm.getActiveNetworkInfo().getState()); 5462 5463 dfltNetworkCallback = new TestNetworkCallback(); 5464 mCm.registerDefaultNetworkCallback(dfltNetworkCallback); 5465 // This time onNetworkSuspended should not be called. 5466 dfltNetworkCallback.expectAvailableCallbacksValidated(mCellAgent); 5467 dfltNetworkCallback.assertNoCallback(); 5468 5469 mCm.unregisterNetworkCallback(dfltNetworkCallback); 5470 mCm.unregisterNetworkCallback(cellNetworkCallback); 5471 } 5472 5473 @Test 5474 public void testRegisterPrivilegedDefaultCallbacksRequirePermissions() throws Exception { 5475 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 5476 mCellAgent.connect(false /* validated */); 5477 mServiceContext.setPermission(CONNECTIVITY_USE_RESTRICTED_NETWORKS, PERMISSION_DENIED); 5478 5479 final Handler handler = new Handler(ConnectivityThread.getInstanceLooper()); 5480 final TestNetworkCallback callback = new TestNetworkCallback(); 5481 assertThrows(SecurityException.class, 5482 () -> mCm.registerSystemDefaultNetworkCallback(callback, handler)); 5483 callback.assertNoCallback(); 5484 assertThrows(SecurityException.class, 5485 () -> mCm.registerDefaultNetworkCallbackForUid(APP1_UID, callback, handler)); 5486 callback.assertNoCallback(); 5487 5488 mServiceContext.setPermission(CONNECTIVITY_USE_RESTRICTED_NETWORKS, PERMISSION_GRANTED); 5489 mCm.registerSystemDefaultNetworkCallback(callback, handler); 5490 mServiceContext.setPermission(CONNECTIVITY_USE_RESTRICTED_NETWORKS, PERMISSION_DENIED); 5491 callback.expectAvailableCallbacksUnvalidated(mCellAgent); 5492 mCm.unregisterNetworkCallback(callback); 5493 5494 mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_GRANTED); 5495 mCm.registerSystemDefaultNetworkCallback(callback, handler); 5496 callback.expectAvailableCallbacksUnvalidated(mCellAgent); 5497 mCm.unregisterNetworkCallback(callback); 5498 5499 mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_DENIED); 5500 mServiceContext.setPermission(NETWORK_SETUP_WIZARD, PERMISSION_GRANTED); 5501 mCm.registerSystemDefaultNetworkCallback(callback, handler); 5502 callback.expectAvailableCallbacksUnvalidated(mCellAgent); 5503 mCm.unregisterNetworkCallback(callback); 5504 5505 mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_GRANTED); 5506 mCm.registerDefaultNetworkCallbackForUid(APP1_UID, callback, handler); 5507 callback.expectAvailableCallbacksUnvalidated(mCellAgent); 5508 mCm.unregisterNetworkCallback(callback); 5509 } 5510 5511 @Test 5512 public void testNetworkCallbackWithNullUids() throws Exception { 5513 final NetworkRequest request = new NetworkRequest.Builder() 5514 .removeCapability(NET_CAPABILITY_NOT_VPN) 5515 .build(); 5516 final TestNetworkCallback callback = new TestNetworkCallback(); 5517 mCm.registerNetworkCallback(request, callback); 5518 5519 // Attempt to file a callback for networks applying to another UID. This does not actually 5520 // work, because this code does not currently have permission to do so. The callback behaves 5521 // exactly the same as the one registered just above. 5522 final int otherUid = UserHandle.getUid(RESTRICTED_USER, VPN_UID); 5523 final NetworkRequest otherUidRequest = new NetworkRequest.Builder() 5524 .removeCapability(NET_CAPABILITY_NOT_VPN) 5525 .setUids(UidRange.toIntRanges(uidRangesForUids(otherUid))) 5526 .build(); 5527 final TestNetworkCallback otherUidCallback = new TestNetworkCallback(); 5528 mCm.registerNetworkCallback(otherUidRequest, otherUidCallback); 5529 5530 final NetworkRequest includeOtherUidsRequest = new NetworkRequest.Builder() 5531 .removeCapability(NET_CAPABILITY_NOT_VPN) 5532 .setIncludeOtherUidNetworks(true) 5533 .build(); 5534 final TestNetworkCallback includeOtherUidsCallback = new TestNetworkCallback(); 5535 mCm.registerNetworkCallback(includeOtherUidsRequest, includeOtherUidsCallback); 5536 5537 // Both callbacks see a network with no specifier that applies to their UID. 5538 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 5539 mWiFiAgent.connect(false /* validated */); 5540 callback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 5541 otherUidCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 5542 includeOtherUidsCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 5543 mWiFiAgent.disconnect(); 5544 callback.expect(LOST, mWiFiAgent); 5545 otherUidCallback.expect(LOST, mWiFiAgent); 5546 includeOtherUidsCallback.expect(LOST, mWiFiAgent); 5547 5548 // Only the includeOtherUidsCallback sees a VPN that does not apply to its UID. 5549 final UidRange range = UidRange.createForUser(UserHandle.of(RESTRICTED_USER)); 5550 final Set<UidRange> vpnRanges = Collections.singleton(range); 5551 mMockVpn.establish(new LinkProperties(), VPN_UID, vpnRanges); 5552 includeOtherUidsCallback.expectAvailableThenValidatedCallbacks(mMockVpn); 5553 callback.assertNoCallback(); 5554 otherUidCallback.assertNoCallback(); 5555 5556 mMockVpn.disconnect(); 5557 includeOtherUidsCallback.expect(LOST, mMockVpn); 5558 callback.assertNoCallback(); 5559 otherUidCallback.assertNoCallback(); 5560 } 5561 5562 private static class RedactableNetworkSpecifier extends NetworkSpecifier { 5563 public static final int ID_INVALID = -1; 5564 5565 public final int networkId; 5566 5567 RedactableNetworkSpecifier(int networkId) { 5568 this.networkId = networkId; 5569 } 5570 5571 @Override 5572 public boolean canBeSatisfiedBy(NetworkSpecifier other) { 5573 return other instanceof RedactableNetworkSpecifier 5574 && this.networkId == ((RedactableNetworkSpecifier) other).networkId; 5575 } 5576 5577 @Override 5578 public NetworkSpecifier redact() { 5579 return new RedactableNetworkSpecifier(ID_INVALID); 5580 } 5581 } 5582 5583 @Test 5584 public void testNetworkCallbackWithNullUidsRedactsSpecifier() throws Exception { 5585 final RedactableNetworkSpecifier specifier = new RedactableNetworkSpecifier(42); 5586 final NetworkRequest request = new NetworkRequest.Builder() 5587 .addCapability(NET_CAPABILITY_INTERNET) 5588 .addTransportType(TRANSPORT_WIFI) 5589 .setNetworkSpecifier(specifier) 5590 .build(); 5591 final TestNetworkCallback callback = new TestNetworkCallback(); 5592 mCm.registerNetworkCallback(request, callback); 5593 5594 // Attempt to file a callback for networks applying to another UID. This does not actually 5595 // work, because this code does not currently have permission to do so. The callback behaves 5596 // exactly the same as the one registered just above. 5597 final int otherUid = UserHandle.getUid(RESTRICTED_USER, VPN_UID); 5598 final NetworkRequest otherUidRequest = new NetworkRequest.Builder() 5599 .addCapability(NET_CAPABILITY_INTERNET) 5600 .addTransportType(TRANSPORT_WIFI) 5601 .setNetworkSpecifier(specifier) 5602 .setUids(UidRange.toIntRanges(uidRangesForUids(otherUid))) 5603 .build(); 5604 final TestNetworkCallback otherUidCallback = new TestNetworkCallback(); 5605 mCm.registerNetworkCallback(otherUidRequest, otherUidCallback); 5606 5607 final NetworkRequest includeOtherUidsRequest = new NetworkRequest.Builder() 5608 .addCapability(NET_CAPABILITY_INTERNET) 5609 .addTransportType(TRANSPORT_WIFI) 5610 .setNetworkSpecifier(specifier) 5611 .setIncludeOtherUidNetworks(true) 5612 .build(); 5613 final TestNetworkCallback includeOtherUidsCallback = new TestNetworkCallback(); 5614 mCm.registerNetworkCallback(includeOtherUidsRequest, callback); 5615 5616 // Only the regular callback sees the network, because callbacks filed with no UID have 5617 // their specifiers redacted. 5618 final LinkProperties emptyLp = new LinkProperties(); 5619 final NetworkCapabilities ncTemplate = new NetworkCapabilities() 5620 .addTransportType(TRANSPORT_WIFI) 5621 .setNetworkSpecifier(specifier); 5622 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, emptyLp, ncTemplate); 5623 mWiFiAgent.connect(false /* validated */); 5624 callback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 5625 otherUidCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 5626 includeOtherUidsCallback.assertNoCallback(); 5627 } 5628 5629 private void setCaptivePortalMode(int mode) { 5630 ContentResolver cr = mServiceContext.getContentResolver(); 5631 Settings.Global.putInt(cr, ConnectivitySettingsManager.CAPTIVE_PORTAL_MODE, mode); 5632 } 5633 5634 private void setAlwaysOnNetworks(boolean enable) { 5635 ContentResolver cr = mServiceContext.getContentResolver(); 5636 Settings.Global.putInt(cr, ConnectivitySettingsManager.MOBILE_DATA_ALWAYS_ON, 5637 enable ? 1 : 0); 5638 mService.updateAlwaysOnNetworks(); 5639 waitForIdle(); 5640 } 5641 5642 private void setPrivateDnsSettings(int mode, String specifier) { 5643 ConnectivitySettingsManager.setPrivateDnsMode(mServiceContext, mode); 5644 ConnectivitySettingsManager.setPrivateDnsHostname(mServiceContext, specifier); 5645 mService.updatePrivateDnsSettings(); 5646 waitForIdle(); 5647 } 5648 5649 private void setIngressRateLimit(int rateLimitInBytesPerSec) { 5650 ConnectivitySettingsManager.setIngressRateLimitInBytesPerSecond(mServiceContext, 5651 rateLimitInBytesPerSec); 5652 mService.updateIngressRateLimit(); 5653 waitForIdle(); 5654 } 5655 5656 private boolean isForegroundNetwork(TestNetworkAgentWrapper network) { 5657 NetworkCapabilities nc = mCm.getNetworkCapabilities(network.getNetwork()); 5658 assertNotNull(nc); 5659 return nc.hasCapability(NET_CAPABILITY_FOREGROUND); 5660 } 5661 5662 @Test 5663 public void testBackgroundNetworks() throws Exception { 5664 // Create a cellular background request. 5665 grantUsingBackgroundNetworksPermissionForUid(Binder.getCallingUid()); 5666 final TestNetworkCallback cellBgCallback = new TestNetworkCallback(); 5667 mCm.requestBackgroundNetwork(new NetworkRequest.Builder() 5668 .addTransportType(TRANSPORT_CELLULAR).build(), 5669 cellBgCallback, mCsHandlerThread.getThreadHandler()); 5670 5671 // Make callbacks for monitoring. 5672 final NetworkRequest request = new NetworkRequest.Builder().build(); 5673 final NetworkRequest fgRequest = new NetworkRequest.Builder() 5674 .addCapability(NET_CAPABILITY_FOREGROUND).build(); 5675 final TestNetworkCallback callback = new TestNetworkCallback(); 5676 final TestNetworkCallback fgCallback = new TestNetworkCallback(); 5677 mCm.registerNetworkCallback(request, callback); 5678 mCm.registerNetworkCallback(fgRequest, fgCallback); 5679 5680 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 5681 mCellAgent.connect(true); 5682 callback.expectAvailableThenValidatedCallbacks(mCellAgent); 5683 fgCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 5684 assertTrue(isForegroundNetwork(mCellAgent)); 5685 5686 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 5687 mWiFiAgent.connect(true); 5688 5689 // When wifi connects, cell lingers. 5690 callback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 5691 callback.expectLosing(mCellAgent); 5692 callback.expectCaps(mWiFiAgent, c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 5693 fgCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 5694 fgCallback.expectLosing(mCellAgent); 5695 fgCallback.expectCaps(mWiFiAgent, c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 5696 assertTrue(isForegroundNetwork(mCellAgent)); 5697 assertTrue(isForegroundNetwork(mWiFiAgent)); 5698 5699 // When lingering is complete, cell is still there but is now in the background. 5700 waitForIdle(); 5701 int timeoutMs = TEST_LINGER_DELAY_MS + TEST_LINGER_DELAY_MS / 4; 5702 fgCallback.expect(LOST, mCellAgent, timeoutMs); 5703 // Expect a network capabilities update sans FOREGROUND. 5704 callback.expectCaps(mCellAgent, c -> !c.hasCapability(NET_CAPABILITY_FOREGROUND)); 5705 assertFalse(isForegroundNetwork(mCellAgent)); 5706 assertTrue(isForegroundNetwork(mWiFiAgent)); 5707 5708 // File a cell request and check that cell comes into the foreground. 5709 final NetworkRequest cellRequest = new NetworkRequest.Builder() 5710 .addTransportType(TRANSPORT_CELLULAR).build(); 5711 final TestNetworkCallback cellCallback = new TestNetworkCallback(); 5712 mCm.requestNetwork(cellRequest, cellCallback); 5713 cellCallback.expectAvailableCallbacksValidated(mCellAgent); 5714 fgCallback.expectAvailableCallbacksValidated(mCellAgent); 5715 // Expect a network capabilities update with FOREGROUND, because the most recent 5716 // request causes its state to change. 5717 cellCallback.expectCaps(mCellAgent, c -> c.hasCapability(NET_CAPABILITY_FOREGROUND)); 5718 callback.expectCaps(mCellAgent, c -> c.hasCapability(NET_CAPABILITY_FOREGROUND)); 5719 assertTrue(isForegroundNetwork(mCellAgent)); 5720 assertTrue(isForegroundNetwork(mWiFiAgent)); 5721 5722 // Release the request. The network immediately goes into the background, since it was not 5723 // lingering. 5724 mCm.unregisterNetworkCallback(cellCallback); 5725 fgCallback.expect(LOST, mCellAgent); 5726 // Expect a network capabilities update sans FOREGROUND. 5727 callback.expectCaps(mCellAgent, c -> !c.hasCapability(NET_CAPABILITY_FOREGROUND)); 5728 assertFalse(isForegroundNetwork(mCellAgent)); 5729 assertTrue(isForegroundNetwork(mWiFiAgent)); 5730 5731 // Disconnect wifi and check that cell is foreground again. 5732 mWiFiAgent.disconnect(); 5733 callback.expect(LOST, mWiFiAgent); 5734 fgCallback.expect(LOST, mWiFiAgent); 5735 fgCallback.expectAvailableCallbacksValidated(mCellAgent); 5736 assertTrue(isForegroundNetwork(mCellAgent)); 5737 5738 mCm.unregisterNetworkCallback(callback); 5739 mCm.unregisterNetworkCallback(fgCallback); 5740 mCm.unregisterNetworkCallback(cellBgCallback); 5741 } 5742 5743 @Ignore // This test has instrinsic chances of spurious failures: ignore for continuous testing. 5744 public void benchmarkRequestRegistrationAndCallbackDispatch() throws Exception { 5745 // TODO: turn this unit test into a real benchmarking test. 5746 // Benchmarks connecting and switching performance in the presence of a large number of 5747 // NetworkRequests. 5748 // 1. File NUM_REQUESTS requests. 5749 // 2. Have a network connect. Wait for NUM_REQUESTS onAvailable callbacks to fire. 5750 // 3. Have a new network connect and outscore the previous. Wait for NUM_REQUESTS onLosing 5751 // and NUM_REQUESTS onAvailable callbacks to fire. 5752 // See how long it took. 5753 final int NUM_REQUESTS = 90; 5754 final int REGISTER_TIME_LIMIT_MS = 200; 5755 final int CONNECT_TIME_LIMIT_MS = 60; 5756 final int SWITCH_TIME_LIMIT_MS = 60; 5757 final int UNREGISTER_TIME_LIMIT_MS = 20; 5758 5759 final NetworkRequest request = new NetworkRequest.Builder().clearCapabilities().build(); 5760 final NetworkCallback[] callbacks = new NetworkCallback[NUM_REQUESTS]; 5761 final CountDownLatch availableLatch = new CountDownLatch(NUM_REQUESTS); 5762 final CountDownLatch losingLatch = new CountDownLatch(NUM_REQUESTS); 5763 5764 for (int i = 0; i < NUM_REQUESTS; i++) { 5765 callbacks[i] = new NetworkCallback() { 5766 @Override public void onAvailable(Network n) { availableLatch.countDown(); } 5767 @Override public void onLosing(Network n, int t) { losingLatch.countDown(); } 5768 }; 5769 } 5770 5771 assertRunsInAtMost("Registering callbacks", REGISTER_TIME_LIMIT_MS, () -> { 5772 for (NetworkCallback cb : callbacks) { 5773 mCm.registerNetworkCallback(request, cb); 5774 } 5775 }); 5776 5777 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 5778 // Don't request that the network validate, because otherwise connect() will block until 5779 // the network gets NET_CAPABILITY_VALIDATED, after all the callbacks below have fired, 5780 // and we won't actually measure anything. 5781 mCellAgent.connect(false); 5782 5783 long onAvailableDispatchingDuration = durationOf(() -> { 5784 await(availableLatch, 10 * CONNECT_TIME_LIMIT_MS); 5785 }); 5786 Log.d(TAG, String.format("Dispatched %d of %d onAvailable callbacks in %dms", 5787 NUM_REQUESTS - availableLatch.getCount(), NUM_REQUESTS, 5788 onAvailableDispatchingDuration)); 5789 assertTrue(String.format("Dispatching %d onAvailable callbacks in %dms, expected %dms", 5790 NUM_REQUESTS, onAvailableDispatchingDuration, CONNECT_TIME_LIMIT_MS), 5791 onAvailableDispatchingDuration <= CONNECT_TIME_LIMIT_MS); 5792 5793 // Give wifi a high enough score that we'll linger cell when wifi comes up. 5794 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 5795 mWiFiAgent.adjustScore(40); 5796 mWiFiAgent.connect(false); 5797 5798 long onLostDispatchingDuration = durationOf(() -> { 5799 await(losingLatch, 10 * SWITCH_TIME_LIMIT_MS); 5800 }); 5801 Log.d(TAG, String.format("Dispatched %d of %d onLosing callbacks in %dms", 5802 NUM_REQUESTS - losingLatch.getCount(), NUM_REQUESTS, onLostDispatchingDuration)); 5803 assertTrue(String.format("Dispatching %d onLosing callbacks in %dms, expected %dms", 5804 NUM_REQUESTS, onLostDispatchingDuration, SWITCH_TIME_LIMIT_MS), 5805 onLostDispatchingDuration <= SWITCH_TIME_LIMIT_MS); 5806 5807 assertRunsInAtMost("Unregistering callbacks", UNREGISTER_TIME_LIMIT_MS, () -> { 5808 for (NetworkCallback cb : callbacks) { 5809 mCm.unregisterNetworkCallback(cb); 5810 } 5811 }); 5812 } 5813 5814 @Test 5815 public void testMobileDataAlwaysOn() throws Exception { 5816 grantUsingBackgroundNetworksPermissionForUid(Binder.getCallingUid()); 5817 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback(); 5818 final NetworkRequest cellRequest = new NetworkRequest.Builder() 5819 .addTransportType(TRANSPORT_CELLULAR).build(); 5820 mCm.registerNetworkCallback(cellRequest, cellNetworkCallback); 5821 5822 final HandlerThread handlerThread = new HandlerThread("MobileDataAlwaysOnFactory"); 5823 handlerThread.start(); 5824 NetworkCapabilities filter = new NetworkCapabilities() 5825 .addTransportType(TRANSPORT_CELLULAR) 5826 .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED) 5827 .addCapability(NET_CAPABILITY_INTERNET); 5828 final MockNetworkFactory testFactory = new MockNetworkFactory(handlerThread.getLooper(), 5829 mServiceContext, "testFactory", filter, mCsHandlerThread); 5830 testFactory.setScoreFilter(40); 5831 5832 // Register the factory and expect it to start looking for a network. 5833 testFactory.register(); 5834 5835 try { 5836 // Expect the factory to receive the default network request. 5837 testFactory.expectRequestAdd(); 5838 testFactory.assertRequestCountEquals(1); 5839 assertTrue(testFactory.getMyStartRequested()); 5840 5841 // Bring up wifi. The factory stops looking for a network. 5842 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 5843 // Score 60 - 40 penalty for not validated yet, then 60 when it validates 5844 mWiFiAgent.connect(true); 5845 // The network connects with a low score, so the offer can still beat it and 5846 // nothing happens. Then the network validates, and the offer with its filter score 5847 // of 40 can no longer beat it and the request is removed. 5848 testFactory.expectRequestRemove(); 5849 testFactory.assertRequestCountEquals(0); 5850 5851 assertFalse(testFactory.getMyStartRequested()); 5852 5853 // Turn on mobile data always on. This request will not match the wifi request, so 5854 // it will be sent to the test factory whose filters allow to see it. 5855 setAlwaysOnNetworks(true); 5856 testFactory.expectRequestAdd(); 5857 testFactory.assertRequestCountEquals(1); 5858 5859 assertTrue(testFactory.getMyStartRequested()); 5860 5861 // Bring up cell data and check that the factory stops looking. 5862 assertLength(1, mCm.getAllNetworks()); 5863 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 5864 mCellAgent.connect(false); 5865 cellNetworkCallback.expectAvailableCallbacks(mCellAgent, false, false, false, 5866 TEST_CALLBACK_TIMEOUT_MS); 5867 // When cell connects, it will satisfy the "mobile always on request" right away 5868 // by virtue of being the only network that can satisfy the request. However, its 5869 // score is low (50 - 40 = 10) so the test factory can still hope to beat it. 5870 expectNoRequestChanged(testFactory); 5871 5872 // Next, cell validates. This gives it a score of 50 and the test factory can't 5873 // hope to beat that according to its filters. It will see the message that its 5874 // offer is now unnecessary. 5875 mCellAgent.setNetworkValid(true); 5876 // Need a trigger point to let NetworkMonitor tell ConnectivityService that network is 5877 // validated – see testPartialConnectivity. 5878 mCm.reportNetworkConnectivity(mCellAgent.getNetwork(), true); 5879 cellNetworkCallback.expectCaps(mCellAgent, 5880 c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 5881 testFactory.expectRequestRemove(); 5882 testFactory.assertRequestCountEquals(0); 5883 // Accordingly, the factory shouldn't be started. 5884 assertFalse(testFactory.getMyStartRequested()); 5885 5886 // Check that cell data stays up. 5887 waitForIdle(); 5888 verifyActiveNetwork(TRANSPORT_WIFI); 5889 assertLength(2, mCm.getAllNetworks()); 5890 5891 // Cell disconnects. There is still the "mobile data always on" request outstanding, 5892 // and the test factory should see it now that it isn't hopelessly outscored. 5893 mCellAgent.disconnect(); 5894 cellNetworkCallback.expect(LOST, mCellAgent); 5895 // Wait for the network to be removed from internal structures before 5896 // calling synchronous getter 5897 waitForIdle(); 5898 assertLength(1, mCm.getAllNetworks()); 5899 testFactory.expectRequestAdd(); 5900 testFactory.assertRequestCountEquals(1); 5901 5902 // Reconnect cell validated, see the request disappear again. Then withdraw the 5903 // mobile always on request. This will tear down cell, and there shouldn't be a 5904 // blip where the test factory briefly sees the request or anything. 5905 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 5906 mCellAgent.connect(true); 5907 cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 5908 waitForIdle(); 5909 assertLength(2, mCm.getAllNetworks()); 5910 testFactory.expectRequestRemove(); 5911 testFactory.assertRequestCountEquals(0); 5912 setAlwaysOnNetworks(false); 5913 expectNoRequestChanged(testFactory); 5914 testFactory.assertRequestCountEquals(0); 5915 assertFalse(testFactory.getMyStartRequested()); 5916 // ... and cell data to be torn down immediately since it is no longer nascent. 5917 cellNetworkCallback.expect(LOST, mCellAgent); 5918 waitForIdle(); 5919 assertLength(1, mCm.getAllNetworks()); 5920 testFactory.terminate(); 5921 testFactory.assertNoRequestChanged(); 5922 } finally { 5923 mCm.unregisterNetworkCallback(cellNetworkCallback); 5924 handlerThread.quit(); 5925 } 5926 } 5927 5928 @Test 5929 public void testSetAllowBadWifiUntil() throws Exception { 5930 runAsShell(NETWORK_SETTINGS, 5931 () -> mService.setTestAllowBadWifiUntil(System.currentTimeMillis() + 5_000L)); 5932 waitForIdle(); 5933 testAvoidBadWifiConfig_controlledBySettings(); 5934 5935 runAsShell(NETWORK_SETTINGS, 5936 () -> mService.setTestAllowBadWifiUntil(System.currentTimeMillis() - 5_000L)); 5937 waitForIdle(); 5938 testAvoidBadWifiConfig_ignoreSettings(); 5939 } 5940 5941 private void testAvoidBadWifiConfig_controlledBySettings() { 5942 final ContentResolver cr = mServiceContext.getContentResolver(); 5943 final String settingName = ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI; 5944 5945 Settings.Global.putString(cr, settingName, "0"); 5946 mPolicyTracker.reevaluate(); 5947 waitForIdle(); 5948 assertFalse(mService.avoidBadWifi()); 5949 assertFalse(mPolicyTracker.shouldNotifyWifiUnvalidated()); 5950 5951 Settings.Global.putString(cr, settingName, "1"); 5952 mPolicyTracker.reevaluate(); 5953 waitForIdle(); 5954 assertTrue(mService.avoidBadWifi()); 5955 assertFalse(mPolicyTracker.shouldNotifyWifiUnvalidated()); 5956 5957 Settings.Global.putString(cr, settingName, null); 5958 mPolicyTracker.reevaluate(); 5959 waitForIdle(); 5960 assertFalse(mService.avoidBadWifi()); 5961 assertTrue(mPolicyTracker.shouldNotifyWifiUnvalidated()); 5962 } 5963 5964 private void testAvoidBadWifiConfig_ignoreSettings() { 5965 final ContentResolver cr = mServiceContext.getContentResolver(); 5966 final String settingName = ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI; 5967 5968 String[] values = new String[] {null, "0", "1"}; 5969 for (int i = 0; i < values.length; i++) { 5970 Settings.Global.putString(cr, settingName, values[i]); 5971 mPolicyTracker.reevaluate(); 5972 waitForIdle(); 5973 String msg = String.format("config=false, setting=%s", values[i]); 5974 assertTrue(mService.avoidBadWifi()); 5975 assertFalse(msg, mPolicyTracker.shouldNotifyWifiUnvalidated()); 5976 } 5977 } 5978 5979 @Test 5980 public void testAvoidBadWifiSetting() throws Exception { 5981 doReturn(1).when(mResources).getInteger(R.integer.config_networkAvoidBadWifi); 5982 testAvoidBadWifiConfig_ignoreSettings(); 5983 5984 doReturn(0).when(mResources).getInteger(R.integer.config_networkAvoidBadWifi); 5985 testAvoidBadWifiConfig_controlledBySettings(); 5986 } 5987 5988 @Test 5989 public void testActivelyPreferBadWifiSetting() throws Exception { 5990 doReturn(1).when(mResources).getInteger(R.integer.config_activelyPreferBadWifi); 5991 mPolicyTracker.reevaluate(); 5992 waitForIdle(); 5993 assertTrue(mService.mNetworkRanker.getConfiguration().activelyPreferBadWifi()); 5994 5995 doReturn(0).when(mResources).getInteger(R.integer.config_activelyPreferBadWifi); 5996 mPolicyTracker.reevaluate(); 5997 waitForIdle(); 5998 if (mDeps.isAtLeastU()) { 5999 // U+ ignore the setting and always actively prefers bad wifi 6000 assertTrue(mService.mNetworkRanker.getConfiguration().activelyPreferBadWifi()); 6001 } else { 6002 assertFalse(mService.mNetworkRanker.getConfiguration().activelyPreferBadWifi()); 6003 } 6004 } 6005 6006 @Test 6007 public void testOffersAvoidsBadWifi() throws Exception { 6008 // Normal mode : the carrier doesn't restrict moving away from bad wifi. 6009 // This has getAvoidBadWifi return true. 6010 doReturn(1).when(mResources).getInteger(R.integer.config_networkAvoidBadWifi); 6011 // Don't request cell separately for the purposes of this test. 6012 setAlwaysOnNetworks(false); 6013 6014 final NetworkProvider cellProvider = new NetworkProvider(mServiceContext, 6015 mCsHandlerThread.getLooper(), "Cell provider"); 6016 final NetworkProvider wifiProvider = new NetworkProvider(mServiceContext, 6017 mCsHandlerThread.getLooper(), "Wifi provider"); 6018 6019 mCm.registerNetworkProvider(cellProvider); 6020 mCm.registerNetworkProvider(wifiProvider); 6021 6022 final NetworkScore cellScore = new NetworkScore.Builder().build(); 6023 final NetworkScore wifiScore = new NetworkScore.Builder().build(); 6024 final NetworkCapabilities defaultCaps = new NetworkCapabilities.Builder() 6025 .addCapability(NET_CAPABILITY_INTERNET) 6026 .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED) 6027 .build(); 6028 final NetworkCapabilities cellCaps = new NetworkCapabilities.Builder() 6029 .addTransportType(TRANSPORT_CELLULAR) 6030 .addCapability(NET_CAPABILITY_INTERNET) 6031 .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED) 6032 .build(); 6033 final NetworkCapabilities wifiCaps = new NetworkCapabilities.Builder() 6034 .addTransportType(TRANSPORT_WIFI) 6035 .addCapability(NET_CAPABILITY_INTERNET) 6036 .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED) 6037 .build(); 6038 final TestableNetworkOfferCallback cellCallback = new TestableNetworkOfferCallback( 6039 TIMEOUT_MS /* timeout */, TEST_CALLBACK_TIMEOUT_MS /* noCallbackTimeout */); 6040 final TestableNetworkOfferCallback wifiCallback = new TestableNetworkOfferCallback( 6041 TIMEOUT_MS /* timeout */, TEST_CALLBACK_TIMEOUT_MS /* noCallbackTimeout */); 6042 6043 // Offer callbacks will run on the CS handler thread in this test. 6044 cellProvider.registerNetworkOffer(cellScore, cellCaps, r -> r.run(), cellCallback); 6045 wifiProvider.registerNetworkOffer(wifiScore, wifiCaps, r -> r.run(), wifiCallback); 6046 6047 // Both providers see the default request. 6048 cellCallback.expectOnNetworkNeeded(defaultCaps); 6049 wifiCallback.expectOnNetworkNeeded(defaultCaps); 6050 6051 // Listen to cell and wifi to know when agents are finished processing 6052 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback(); 6053 final NetworkRequest cellRequest = new NetworkRequest.Builder() 6054 .addTransportType(TRANSPORT_CELLULAR).build(); 6055 mCm.registerNetworkCallback(cellRequest, cellNetworkCallback); 6056 final TestNetworkCallback wifiNetworkCallback = new TestNetworkCallback(); 6057 final NetworkRequest wifiRequest = new NetworkRequest.Builder() 6058 .addTransportType(TRANSPORT_WIFI).build(); 6059 mCm.registerNetworkCallback(wifiRequest, wifiNetworkCallback); 6060 6061 // Cell connects and validates. 6062 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, 6063 new LinkProperties(), null /* ncTemplate */, cellProvider); 6064 mCellAgent.connect(true); 6065 cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 6066 cellCallback.assertNoCallback(); 6067 wifiCallback.assertNoCallback(); 6068 6069 // Bring up wifi. At first it's invalidated, so cell is still needed. 6070 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, 6071 new LinkProperties(), null /* ncTemplate */, wifiProvider); 6072 mWiFiAgent.connect(false); 6073 wifiNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 6074 cellCallback.assertNoCallback(); 6075 wifiCallback.assertNoCallback(); 6076 6077 // Wifi validates. Cell is no longer needed, because it's outscored. 6078 mWiFiAgent.setNetworkValid(true /* privateDnsProbeSent */); 6079 // Have CS reconsider the network (see testPartialConnectivity) 6080 mCm.reportNetworkConnectivity(mWiFiAgent.getNetwork(), true); 6081 wifiNetworkCallback.expectCaps(mWiFiAgent, c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 6082 cellCallback.expectOnNetworkUnneeded(defaultCaps); 6083 wifiCallback.assertNoCallback(); 6084 6085 // Wifi is no longer validated. Cell is needed again. 6086 mWiFiAgent.setNetworkInvalid(true /* invalidBecauseOfPrivateDns */); 6087 mCm.reportNetworkConnectivity(mWiFiAgent.getNetwork(), false); 6088 wifiNetworkCallback.expectCaps(mWiFiAgent, 6089 c -> !c.hasCapability(NET_CAPABILITY_VALIDATED)); 6090 cellCallback.expectOnNetworkNeeded(defaultCaps); 6091 wifiCallback.assertNoCallback(); 6092 6093 // Disconnect wifi and pretend the carrier restricts moving away from bad wifi. 6094 mWiFiAgent.disconnect(); 6095 wifiNetworkCallback.expect(LOST, mWiFiAgent); 6096 // This has getAvoidBadWifi return false. This test doesn't change the value of the 6097 // associated setting. 6098 doReturn(0).when(mResources).getInteger(R.integer.config_networkAvoidBadWifi); 6099 mPolicyTracker.reevaluate(); 6100 waitForIdle(); 6101 6102 // Connect wifi again, cell is needed until wifi validates. 6103 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, 6104 new LinkProperties(), null /* ncTemplate */, wifiProvider); 6105 mWiFiAgent.connect(false); 6106 wifiNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 6107 cellCallback.assertNoCallback(); 6108 wifiCallback.assertNoCallback(); 6109 mWiFiAgent.setNetworkValid(true /* privateDnsProbeSent */); 6110 mCm.reportNetworkConnectivity(mWiFiAgent.getNetwork(), true); 6111 wifiNetworkCallback.expectCaps(mWiFiAgent, 6112 c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 6113 cellCallback.expectOnNetworkUnneeded(defaultCaps); 6114 wifiCallback.assertNoCallback(); 6115 6116 // Wifi loses validation. Because the device doesn't avoid bad wifis, cell is 6117 // not needed. 6118 mWiFiAgent.setNetworkInvalid(true /* invalidBecauseOfPrivateDns */); 6119 mCm.reportNetworkConnectivity(mWiFiAgent.getNetwork(), false); 6120 wifiNetworkCallback.expectCaps(mWiFiAgent, 6121 c -> !c.hasCapability(NET_CAPABILITY_VALIDATED)); 6122 cellCallback.assertNoCallback(); 6123 wifiCallback.assertNoCallback(); 6124 } 6125 6126 public void doTestPreferBadWifi(final boolean avoidBadWifi, 6127 final boolean preferBadWifi, final boolean explicitlySelected, 6128 @NonNull Predicate<Long> checkUnvalidationTimeout) throws Exception { 6129 // Pretend we're on a carrier that restricts switching away from bad wifi, and 6130 // depending on the parameter one that may indeed prefer bad wifi. 6131 doReturn(avoidBadWifi ? 1 : 0).when(mResources) 6132 .getInteger(R.integer.config_networkAvoidBadWifi); 6133 doReturn(preferBadWifi ? 1 : 0).when(mResources) 6134 .getInteger(R.integer.config_activelyPreferBadWifi); 6135 mPolicyTracker.reevaluate(); 6136 6137 registerDefaultNetworkCallbacks(); 6138 final NetworkRequest wifiRequest = new NetworkRequest.Builder() 6139 .clearCapabilities() 6140 .addTransportType(TRANSPORT_WIFI) 6141 .build(); 6142 final TestNetworkCallback wifiCallback = new TestNetworkCallback(); 6143 mCm.registerNetworkCallback(wifiRequest, wifiCallback); 6144 6145 // Bring up validated cell and unvalidated wifi. 6146 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 6147 mCellAgent.connect(true); 6148 mDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 6149 6150 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 6151 mWiFiAgent.explicitlySelected(explicitlySelected, false /* acceptUnvalidated */); 6152 mWiFiAgent.connect(false); 6153 wifiCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 6154 6155 assertNotNull(mDeps.mScheduledEvaluationTimeouts.poll(TIMEOUT_MS, 6156 t -> t.first == mWiFiAgent.getNetwork().netId 6157 && checkUnvalidationTimeout.test(t.second))); 6158 6159 if (!avoidBadWifi && preferBadWifi) { 6160 expectUnvalidationCheckWillNotify(mWiFiAgent, NotificationType.LOST_INTERNET); 6161 mDefaultNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 6162 } else { 6163 expectUnvalidationCheckWillNotNotify(mWiFiAgent); 6164 mDefaultNetworkCallback.assertNoCallback(); 6165 } 6166 } 6167 6168 @Test 6169 public void testPreferBadWifi_doNotAvoid_doNotPrefer() throws Exception { 6170 // Starting with U this mode is no longer supported and can't actually be tested 6171 assumeFalse(mDeps.isAtLeastU()); 6172 doTestPreferBadWifi(false /* avoidBadWifi */, false /* preferBadWifi */, 6173 false /* explicitlySelected */, timeout -> timeout < 14_000); 6174 } 6175 6176 @Test 6177 public void testPreferBadWifi_doNotAvoid_doPrefer_notExplicit() throws Exception { 6178 doTestPreferBadWifi(false /* avoidBadWifi */, true /* preferBadWifi */, 6179 false /* explicitlySelected */, timeout -> timeout > 14_000); 6180 } 6181 6182 @Test 6183 public void testPreferBadWifi_doNotAvoid_doPrefer_explicitlySelected() throws Exception { 6184 doTestPreferBadWifi(false /* avoidBadWifi */, true /* preferBadWifi */, 6185 true /* explicitlySelected */, timeout -> timeout < 14_000); 6186 } 6187 6188 @Test 6189 public void testPreferBadWifi_doAvoid_doNotPrefer() throws Exception { 6190 // If avoidBadWifi=true, then preferBadWifi should be irrelevant. Test anyway. 6191 doTestPreferBadWifi(true /* avoidBadWifi */, false /* preferBadWifi */, 6192 false /* explicitlySelected */, timeout -> timeout < 14_000); 6193 } 6194 6195 @Test 6196 public void testPreferBadWifi_doAvoid_doPrefer() throws Exception { 6197 // If avoidBadWifi=true, then preferBadWifi should be irrelevant. Test anyway. 6198 doTestPreferBadWifi(true /* avoidBadWifi */, true /* preferBadWifi */, 6199 false /* explicitlySelected */, timeout -> timeout < 14_000); 6200 } 6201 6202 @Test 6203 public void testAvoidBadWifi() throws Exception { 6204 final ContentResolver cr = mServiceContext.getContentResolver(); 6205 6206 // Pretend we're on a carrier that restricts switching away from bad wifi. 6207 doReturn(0).when(mResources).getInteger(R.integer.config_networkAvoidBadWifi); 6208 6209 // File a request for cell to ensure it doesn't go down. 6210 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback(); 6211 final NetworkRequest cellRequest = new NetworkRequest.Builder() 6212 .addTransportType(TRANSPORT_CELLULAR).build(); 6213 mCm.requestNetwork(cellRequest, cellNetworkCallback); 6214 6215 TestNetworkCallback defaultCallback = new TestNetworkCallback(); 6216 mCm.registerDefaultNetworkCallback(defaultCallback); 6217 6218 NetworkRequest validatedWifiRequest = new NetworkRequest.Builder() 6219 .addTransportType(TRANSPORT_WIFI) 6220 .addCapability(NET_CAPABILITY_VALIDATED) 6221 .build(); 6222 TestNetworkCallback validatedWifiCallback = new TestNetworkCallback(); 6223 mCm.registerNetworkCallback(validatedWifiRequest, validatedWifiCallback); 6224 6225 // Prompt mode, so notifications can be tested 6226 Settings.Global.putString(cr, ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI, null); 6227 mPolicyTracker.reevaluate(); 6228 6229 // Bring up validated cell. 6230 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 6231 mCellAgent.connect(true); 6232 cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 6233 defaultCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 6234 Network cellNetwork = mCellAgent.getNetwork(); 6235 6236 // Bring up validated wifi. 6237 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 6238 mWiFiAgent.connect(true); 6239 defaultCallback.expectAvailableDoubleValidatedCallbacks(mWiFiAgent); 6240 validatedWifiCallback.expectAvailableDoubleValidatedCallbacks(mWiFiAgent); 6241 Network wifiNetwork = mWiFiAgent.getNetwork(); 6242 6243 // Fail validation on wifi. 6244 mWiFiAgent.setNetworkInvalid(false /* invalidBecauseOfPrivateDns */); 6245 mCm.reportNetworkConnectivity(wifiNetwork, false); 6246 defaultCallback.expectCaps(mWiFiAgent, c -> !c.hasCapability(NET_CAPABILITY_VALIDATED)); 6247 validatedWifiCallback.expect(LOST, mWiFiAgent); 6248 expectNotification(mWiFiAgent, NotificationType.LOST_INTERNET); 6249 6250 // Because avoid bad wifi is off, we don't switch to cellular. 6251 defaultCallback.assertNoCallback(); 6252 assertFalse(mCm.getNetworkCapabilities(wifiNetwork).hasCapability( 6253 NET_CAPABILITY_VALIDATED)); 6254 assertTrue(mCm.getNetworkCapabilities(cellNetwork).hasCapability( 6255 NET_CAPABILITY_VALIDATED)); 6256 assertEquals(mCm.getActiveNetwork(), wifiNetwork); 6257 6258 // Simulate switching to a carrier that does not restrict avoiding bad wifi, and expect 6259 // that we switch back to cell. 6260 doReturn(1).when(mResources).getInteger(R.integer.config_networkAvoidBadWifi); 6261 mPolicyTracker.reevaluate(); 6262 defaultCallback.expectAvailableCallbacksValidated(mCellAgent); 6263 assertEquals(mCm.getActiveNetwork(), cellNetwork); 6264 expectClearNotification(mWiFiAgent, NotificationType.LOST_INTERNET); 6265 6266 // Switch back to a restrictive carrier. 6267 doReturn(0).when(mResources).getInteger(R.integer.config_networkAvoidBadWifi); 6268 mPolicyTracker.reevaluate(); 6269 defaultCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 6270 assertEquals(mCm.getActiveNetwork(), wifiNetwork); 6271 // A notification was already shown for this very network. 6272 expectNoNotification(mWiFiAgent); 6273 6274 // Simulate the user selecting "switch" on the dialog, and check that we switch to cell. 6275 // In principle this is a little bit unrealistic because the switch to a less restrictive 6276 // carrier above should have remove the notification but this doesn't matter for the 6277 // purposes of this test. 6278 mCm.setAvoidUnvalidated(wifiNetwork); 6279 defaultCallback.expectAvailableCallbacksValidated(mCellAgent); 6280 assertFalse(mCm.getNetworkCapabilities(wifiNetwork).hasCapability( 6281 NET_CAPABILITY_VALIDATED)); 6282 assertTrue(mCm.getNetworkCapabilities(cellNetwork).hasCapability( 6283 NET_CAPABILITY_VALIDATED)); 6284 assertEquals(mCm.getActiveNetwork(), cellNetwork); 6285 6286 // Disconnect and reconnect wifi to clear the one-time switch above. 6287 mWiFiAgent.disconnect(); 6288 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 6289 mWiFiAgent.connect(true); 6290 defaultCallback.expectAvailableDoubleValidatedCallbacks(mWiFiAgent); 6291 validatedWifiCallback.expectAvailableDoubleValidatedCallbacks(mWiFiAgent); 6292 wifiNetwork = mWiFiAgent.getNetwork(); 6293 6294 // Fail validation on wifi and expect the dialog to appear. 6295 mWiFiAgent.setNetworkInvalid(false /* invalidBecauseOfPrivateDns */); 6296 mCm.reportNetworkConnectivity(wifiNetwork, false); 6297 defaultCallback.expectCaps(mWiFiAgent, c -> !c.hasCapability(NET_CAPABILITY_VALIDATED)); 6298 validatedWifiCallback.expect(LOST, mWiFiAgent); 6299 expectNotification(mWiFiAgent, NotificationType.LOST_INTERNET); 6300 6301 // Simulate the user selecting "switch" and checking the don't ask again checkbox. 6302 Settings.Global.putInt(cr, ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI, 1); 6303 mPolicyTracker.reevaluate(); 6304 6305 // We now switch to cell. 6306 defaultCallback.expectAvailableCallbacksValidated(mCellAgent); 6307 assertFalse(mCm.getNetworkCapabilities(wifiNetwork).hasCapability( 6308 NET_CAPABILITY_VALIDATED)); 6309 assertTrue(mCm.getNetworkCapabilities(cellNetwork).hasCapability( 6310 NET_CAPABILITY_VALIDATED)); 6311 assertEquals(mCm.getActiveNetwork(), cellNetwork); 6312 expectClearNotification(mWiFiAgent, NotificationType.LOST_INTERNET); 6313 6314 // Simulate the user turning the cellular fallback setting off and then on. 6315 // We switch to wifi and then to cell. 6316 Settings.Global.putString(cr, ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI, null); 6317 mPolicyTracker.reevaluate(); 6318 defaultCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 6319 assertEquals(mCm.getActiveNetwork(), wifiNetwork); 6320 // Notification is cleared again because CS doesn't particularly remember that it has 6321 // cleared it before, and if it hasn't cleared it before then it should do so now. 6322 expectClearNotification(mWiFiAgent, NotificationType.LOST_INTERNET); 6323 Settings.Global.putInt(cr, ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI, 1); 6324 mPolicyTracker.reevaluate(); 6325 defaultCallback.expectAvailableCallbacksValidated(mCellAgent); 6326 assertEquals(mCm.getActiveNetwork(), cellNetwork); 6327 6328 // If cell goes down, we switch to wifi. 6329 mCellAgent.disconnect(); 6330 defaultCallback.expect(LOST, mCellAgent); 6331 defaultCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 6332 validatedWifiCallback.assertNoCallback(); 6333 // Notification is cleared yet again because the device switched to wifi. 6334 expectClearNotification(mWiFiAgent, NotificationType.LOST_INTERNET); 6335 6336 mCm.unregisterNetworkCallback(cellNetworkCallback); 6337 mCm.unregisterNetworkCallback(validatedWifiCallback); 6338 mCm.unregisterNetworkCallback(defaultCallback); 6339 } 6340 6341 @Test 6342 public void testMeteredMultipathPreferenceSetting() throws Exception { 6343 final ContentResolver cr = mServiceContext.getContentResolver(); 6344 final String settingName = ConnectivitySettingsManager.NETWORK_METERED_MULTIPATH_PREFERENCE; 6345 6346 for (int config : asList(0, 3, 2)) { 6347 for (String setting: asList(null, "0", "2", "1")) { 6348 mPolicyTracker.mConfigMeteredMultipathPreference = config; 6349 Settings.Global.putString(cr, settingName, setting); 6350 mPolicyTracker.reevaluate(); 6351 waitForIdle(); 6352 6353 final int expected = (setting != null) ? Integer.parseInt(setting) : config; 6354 String msg = String.format("config=%d, setting=%s", config, setting); 6355 assertEquals(msg, expected, mCm.getMultipathPreference(null)); 6356 } 6357 } 6358 } 6359 6360 /** 6361 * Validate that a satisfied network request does not trigger onUnavailable() once the 6362 * time-out period expires. 6363 */ 6364 @Test 6365 public void testSatisfiedNetworkRequestDoesNotTriggerOnUnavailable() throws Exception { 6366 NetworkRequest nr = new NetworkRequest.Builder().addTransportType( 6367 NetworkCapabilities.TRANSPORT_WIFI).build(); 6368 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 6369 mCm.requestNetwork(nr, networkCallback, TEST_REQUEST_TIMEOUT_MS); 6370 6371 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 6372 mWiFiAgent.connect(false); 6373 networkCallback.expectAvailableCallbacks(mWiFiAgent, false, false, false, 6374 TEST_CALLBACK_TIMEOUT_MS); 6375 6376 // pass timeout and validate that UNAVAILABLE is not called 6377 networkCallback.assertNoCallback(); 6378 } 6379 6380 /** 6381 * Validate that a satisfied network request followed by a disconnected (lost) network does 6382 * not trigger onUnavailable() once the time-out period expires. 6383 */ 6384 @Test 6385 public void testSatisfiedThenLostNetworkRequestDoesNotTriggerOnUnavailable() throws Exception { 6386 NetworkRequest nr = new NetworkRequest.Builder().addTransportType( 6387 NetworkCapabilities.TRANSPORT_WIFI).build(); 6388 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 6389 mCm.requestNetwork(nr, networkCallback, TEST_REQUEST_TIMEOUT_MS); 6390 6391 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 6392 mWiFiAgent.connect(false); 6393 networkCallback.expectAvailableCallbacks(mWiFiAgent, false, false, false, 6394 TEST_CALLBACK_TIMEOUT_MS); 6395 mWiFiAgent.disconnect(); 6396 networkCallback.expect(LOST, mWiFiAgent); 6397 6398 // Validate that UNAVAILABLE is not called 6399 networkCallback.assertNoCallback(); 6400 } 6401 6402 /** 6403 * Validate that when a time-out is specified for a network request the onUnavailable() 6404 * callback is called when time-out expires. Then validate that if network request is 6405 * (somehow) satisfied - the callback isn't called later. 6406 */ 6407 @Test 6408 public void testTimedoutNetworkRequest() throws Exception { 6409 NetworkRequest nr = new NetworkRequest.Builder().addTransportType( 6410 NetworkCapabilities.TRANSPORT_WIFI).build(); 6411 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 6412 final int timeoutMs = 10; 6413 mCm.requestNetwork(nr, networkCallback, timeoutMs); 6414 6415 // pass timeout and validate that UNAVAILABLE is called 6416 networkCallback.expect(UNAVAILABLE); 6417 6418 // create a network satisfying request - validate that request not triggered 6419 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 6420 mWiFiAgent.connect(false); 6421 networkCallback.assertNoCallback(); 6422 } 6423 6424 /** 6425 * Validate that when a network request is unregistered (cancelled), no posterior event can 6426 * trigger the callback. 6427 */ 6428 @Test 6429 public void testNoCallbackAfterUnregisteredNetworkRequest() throws Exception { 6430 NetworkRequest nr = new NetworkRequest.Builder().addTransportType( 6431 NetworkCapabilities.TRANSPORT_WIFI).build(); 6432 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 6433 final int timeoutMs = 10; 6434 6435 mCm.requestNetwork(nr, networkCallback, timeoutMs); 6436 mCm.unregisterNetworkCallback(networkCallback); 6437 // Regardless of the timeout, unregistering the callback in ConnectivityManager ensures 6438 // that this callback will not be called. 6439 networkCallback.assertNoCallback(); 6440 6441 // create a network satisfying request - validate that request not triggered 6442 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 6443 mWiFiAgent.connect(false); 6444 networkCallback.assertNoCallback(); 6445 } 6446 6447 @Test 6448 public void testUnfulfillableNetworkRequest() throws Exception { 6449 runUnfulfillableNetworkRequest(false); 6450 } 6451 6452 @Test 6453 public void testUnfulfillableNetworkRequestAfterUnregister() throws Exception { 6454 runUnfulfillableNetworkRequest(true); 6455 } 6456 6457 /** 6458 * Validate the callback flow for a factory releasing a request as unfulfillable. 6459 */ 6460 private void runUnfulfillableNetworkRequest(boolean preUnregister) throws Exception { 6461 NetworkRequest nr = new NetworkRequest.Builder().addTransportType( 6462 NetworkCapabilities.TRANSPORT_WIFI).build(); 6463 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 6464 6465 final HandlerThread handlerThread = new HandlerThread("testUnfulfillableNetworkRequest"); 6466 handlerThread.start(); 6467 NetworkCapabilities filter = new NetworkCapabilities() 6468 .addTransportType(TRANSPORT_WIFI) 6469 .addCapability(NET_CAPABILITY_INTERNET) 6470 .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED); 6471 final MockNetworkFactory testFactory = new MockNetworkFactory(handlerThread.getLooper(), 6472 mServiceContext, "testFactory", filter, mCsHandlerThread); 6473 testFactory.setScoreFilter(40); 6474 6475 // Register the factory and expect it to receive the default request. 6476 testFactory.register(); 6477 testFactory.expectRequestAdd(); 6478 6479 try { 6480 // Now file the test request and expect it. 6481 mCm.requestNetwork(nr, networkCallback); 6482 final NetworkRequest newRequest = testFactory.expectRequestAdd().request; 6483 6484 if (preUnregister) { 6485 mCm.unregisterNetworkCallback(networkCallback); 6486 6487 // The request has been released : the factory should see it removed 6488 // immediately. 6489 testFactory.expectRequestRemove(); 6490 6491 // Simulate the factory releasing the request as unfulfillable: no-op since 6492 // the callback has already been unregistered (but a test that no exceptions are 6493 // thrown). 6494 testFactory.triggerUnfulfillable(newRequest); 6495 } else { 6496 // Simulate the factory releasing the request as unfulfillable and expect 6497 // onUnavailable! 6498 testFactory.triggerUnfulfillable(newRequest); 6499 6500 networkCallback.expect(UNAVAILABLE); 6501 6502 // Declaring a request unfulfillable releases it automatically. 6503 testFactory.expectRequestRemove(); 6504 6505 // unregister network callback - a no-op (since already freed by the 6506 // on-unavailable), but should not fail or throw exceptions. 6507 mCm.unregisterNetworkCallback(networkCallback); 6508 6509 // The factory should not see any further removal, as this request has 6510 // already been removed. 6511 } 6512 } finally { 6513 testFactory.terminate(); 6514 handlerThread.quit(); 6515 } 6516 } 6517 6518 @Test 6519 @IgnoreUpTo(Build.VERSION_CODES.TIRAMISU) 6520 @DisableCompatChanges(ConnectivityCompatChanges.ENABLE_SELF_CERTIFIED_CAPABILITIES_DECLARATION) 6521 public void testSelfCertifiedCapabilitiesDisabled() 6522 throws Exception { 6523 mDeps.enableCompatChangeCheck(); 6524 final NetworkRequest networkRequest = new NetworkRequest.Builder() 6525 .addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_LATENCY) 6526 .addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_BANDWIDTH) 6527 .build(); 6528 final TestNetworkCallback cb = new TestNetworkCallback(); 6529 mCm.requestNetwork(networkRequest, cb); 6530 mCm.unregisterNetworkCallback(cb); 6531 } 6532 6533 /** Set the networkSliceResourceId to 0 will result in NameNotFoundException be thrown. */ 6534 private void setupMockForNetworkCapabilitiesResources(int networkSliceResourceId) 6535 throws PackageManager.NameNotFoundException { 6536 if (networkSliceResourceId == 0) { 6537 doThrow(new PackageManager.NameNotFoundException()).when(mPackageManager).getProperty( 6538 ConstantsShim.PROPERTY_SELF_CERTIFIED_NETWORK_CAPABILITIES, 6539 mContext.getPackageName()); 6540 } else { 6541 final PackageManager.Property property = new PackageManager.Property( 6542 ConstantsShim.PROPERTY_SELF_CERTIFIED_NETWORK_CAPABILITIES, 6543 networkSliceResourceId, 6544 true /* isResource */, 6545 mContext.getPackageName(), 6546 "dummyClass" 6547 ); 6548 doReturn(property).when(mPackageManager).getProperty( 6549 ConstantsShim.PROPERTY_SELF_CERTIFIED_NETWORK_CAPABILITIES, 6550 mContext.getPackageName()); 6551 doReturn(mContext.getResources()).when(mPackageManager).getResourcesForApplication( 6552 mContext.getPackageName()); 6553 } 6554 } 6555 6556 @Test 6557 @IgnoreUpTo(Build.VERSION_CODES.TIRAMISU) 6558 @EnableCompatChanges(ConnectivityCompatChanges.ENABLE_SELF_CERTIFIED_CAPABILITIES_DECLARATION) 6559 public void requestNetwork_withoutPrioritizeBandwidthDeclaration_shouldThrowException() 6560 throws Exception { 6561 mDeps.enableCompatChangeCheck(); 6562 setupMockForNetworkCapabilitiesResources( 6563 com.android.frameworks.tests.net.R.xml.self_certified_capabilities_latency); 6564 final NetworkRequest networkRequest = new NetworkRequest.Builder() 6565 .addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_BANDWIDTH) 6566 .build(); 6567 final TestNetworkCallback cb = new TestNetworkCallback(); 6568 final Exception e = assertThrows(SecurityException.class, 6569 () -> mCm.requestNetwork(networkRequest, cb)); 6570 assertThat(e.getMessage(), 6571 containsString(ApplicationSelfCertifiedNetworkCapabilities.PRIORITIZE_BANDWIDTH)); 6572 } 6573 6574 @Test 6575 @IgnoreUpTo(Build.VERSION_CODES.TIRAMISU) 6576 @EnableCompatChanges(ConnectivityCompatChanges.ENABLE_SELF_CERTIFIED_CAPABILITIES_DECLARATION) 6577 public void requestNetwork_withoutPrioritizeLatencyDeclaration_shouldThrowException() 6578 throws Exception { 6579 mDeps.enableCompatChangeCheck(); 6580 setupMockForNetworkCapabilitiesResources( 6581 com.android.frameworks.tests.net.R.xml.self_certified_capabilities_bandwidth); 6582 final NetworkRequest networkRequest = new NetworkRequest.Builder() 6583 .addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_LATENCY) 6584 .build(); 6585 final TestNetworkCallback cb = new TestNetworkCallback(); 6586 final Exception e = assertThrows(SecurityException.class, 6587 () -> mCm.requestNetwork(networkRequest, cb)); 6588 assertThat(e.getMessage(), 6589 containsString(ApplicationSelfCertifiedNetworkCapabilities.PRIORITIZE_LATENCY)); 6590 } 6591 6592 @Test 6593 @IgnoreUpTo(Build.VERSION_CODES.TIRAMISU) 6594 @EnableCompatChanges(ConnectivityCompatChanges.ENABLE_SELF_CERTIFIED_CAPABILITIES_DECLARATION) 6595 public void requestNetwork_withoutNetworkSliceProperty_shouldThrowException() throws Exception { 6596 mDeps.enableCompatChangeCheck(); 6597 setupMockForNetworkCapabilitiesResources(0 /* networkSliceResourceId */); 6598 final NetworkRequest networkRequest = new NetworkRequest.Builder() 6599 .addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_LATENCY) 6600 .addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_BANDWIDTH) 6601 .build(); 6602 final TestNetworkCallback cb = new TestNetworkCallback(); 6603 final Exception e = assertThrows(SecurityException.class, 6604 () -> mCm.requestNetwork(networkRequest, cb)); 6605 assertThat(e.getMessage(), 6606 containsString(ConstantsShim.PROPERTY_SELF_CERTIFIED_NETWORK_CAPABILITIES)); 6607 } 6608 6609 @Test 6610 @IgnoreUpTo(Build.VERSION_CODES.TIRAMISU) 6611 @EnableCompatChanges(ConnectivityCompatChanges.ENABLE_SELF_CERTIFIED_CAPABILITIES_DECLARATION) 6612 public void requestNetwork_withNetworkSliceDeclaration_shouldSucceed() throws Exception { 6613 mDeps.enableCompatChangeCheck(); 6614 setupMockForNetworkCapabilitiesResources( 6615 com.android.frameworks.tests.net.R.xml.self_certified_capabilities_both); 6616 6617 final NetworkRequest networkRequest = new NetworkRequest.Builder() 6618 .addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_LATENCY) 6619 .addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_BANDWIDTH) 6620 .build(); 6621 final TestNetworkCallback cb = new TestNetworkCallback(); 6622 mCm.requestNetwork(networkRequest, cb); 6623 mCm.unregisterNetworkCallback(cb); 6624 } 6625 6626 @Test 6627 @IgnoreUpTo(Build.VERSION_CODES.TIRAMISU) 6628 @EnableCompatChanges(ConnectivityCompatChanges.ENABLE_SELF_CERTIFIED_CAPABILITIES_DECLARATION) 6629 public void requestNetwork_withNetworkSliceDeclaration_shouldUseCache() throws Exception { 6630 mDeps.enableCompatChangeCheck(); 6631 setupMockForNetworkCapabilitiesResources( 6632 com.android.frameworks.tests.net.R.xml.self_certified_capabilities_both); 6633 6634 final NetworkRequest networkRequest = new NetworkRequest.Builder() 6635 .addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_LATENCY) 6636 .addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_BANDWIDTH) 6637 .build(); 6638 final TestNetworkCallback cb = new TestNetworkCallback(); 6639 mCm.requestNetwork(networkRequest, cb); 6640 mCm.unregisterNetworkCallback(cb); 6641 6642 // Second call should use caches 6643 mCm.requestNetwork(networkRequest, cb); 6644 mCm.unregisterNetworkCallback(cb); 6645 6646 // PackageManager's API only called once because the second call is using cache. 6647 verify(mPackageManager, times(1)).getProperty( 6648 ConstantsShim.PROPERTY_SELF_CERTIFIED_NETWORK_CAPABILITIES, 6649 mContext.getPackageName()); 6650 verify(mPackageManager, times(1)).getResourcesForApplication( 6651 mContext.getPackageName()); 6652 } 6653 6654 /** 6655 * Validate the service throws if request with CBS but without carrier privilege. 6656 */ 6657 @Test 6658 public void testCBSRequestWithoutCarrierPrivilege() throws Exception { 6659 final NetworkRequest nr = new NetworkRequest.Builder().addTransportType( 6660 TRANSPORT_CELLULAR).addCapability(NET_CAPABILITY_CBS).build(); 6661 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 6662 6663 mServiceContext.setPermission(CONNECTIVITY_USE_RESTRICTED_NETWORKS, PERMISSION_DENIED); 6664 // Now file the test request and expect the service throws. 6665 assertThrows(SecurityException.class, () -> mCm.requestNetwork(nr, networkCallback)); 6666 } 6667 6668 private static class TestKeepaliveCallback extends PacketKeepaliveCallback { 6669 6670 public enum CallbackType { ON_STARTED, ON_STOPPED, ON_ERROR } 6671 6672 private class CallbackValue { 6673 public CallbackType callbackType; 6674 public int error; 6675 6676 public CallbackValue(CallbackType type) { 6677 this.callbackType = type; 6678 this.error = PacketKeepalive.SUCCESS; 6679 assertTrue("onError callback must have error", type != CallbackType.ON_ERROR); 6680 } 6681 6682 public CallbackValue(CallbackType type, int error) { 6683 this.callbackType = type; 6684 this.error = error; 6685 assertEquals("error can only be set for onError", type, CallbackType.ON_ERROR); 6686 } 6687 6688 @Override 6689 public boolean equals(Object o) { 6690 return o instanceof CallbackValue && 6691 this.callbackType == ((CallbackValue) o).callbackType && 6692 this.error == ((CallbackValue) o).error; 6693 } 6694 6695 @Override 6696 public String toString() { 6697 return String.format("%s(%s, %d)", getClass().getSimpleName(), callbackType, error); 6698 } 6699 } 6700 6701 private final LinkedBlockingQueue<CallbackValue> mCallbacks = new LinkedBlockingQueue<>(); 6702 6703 @Override 6704 public void onStarted() { 6705 mCallbacks.add(new CallbackValue(CallbackType.ON_STARTED)); 6706 } 6707 6708 @Override 6709 public void onStopped() { 6710 mCallbacks.add(new CallbackValue(CallbackType.ON_STOPPED)); 6711 } 6712 6713 @Override 6714 public void onError(int error) { 6715 mCallbacks.add(new CallbackValue(CallbackType.ON_ERROR, error)); 6716 } 6717 6718 private void expect(CallbackValue callbackValue) throws InterruptedException { 6719 assertEquals(callbackValue, mCallbacks.poll(TIMEOUT_MS, TimeUnit.MILLISECONDS)); 6720 } 6721 6722 public void expectStarted() throws Exception { 6723 expect(new CallbackValue(CallbackType.ON_STARTED)); 6724 } 6725 6726 public void expectStopped() throws Exception { 6727 expect(new CallbackValue(CallbackType.ON_STOPPED)); 6728 } 6729 6730 public void expectError(int error) throws Exception { 6731 expect(new CallbackValue(CallbackType.ON_ERROR, error)); 6732 } 6733 } 6734 6735 private static class TestSocketKeepaliveCallback extends SocketKeepalive.Callback { 6736 6737 public enum CallbackType { ON_STARTED, ON_STOPPED, ON_ERROR }; 6738 6739 private class CallbackValue { 6740 public CallbackType callbackType; 6741 public int error; 6742 6743 CallbackValue(CallbackType type) { 6744 this.callbackType = type; 6745 this.error = SocketKeepalive.SUCCESS; 6746 assertTrue("onError callback must have error", type != CallbackType.ON_ERROR); 6747 } 6748 6749 CallbackValue(CallbackType type, int error) { 6750 this.callbackType = type; 6751 this.error = error; 6752 assertEquals("error can only be set for onError", type, CallbackType.ON_ERROR); 6753 } 6754 6755 @Override 6756 public boolean equals(Object o) { 6757 return o instanceof CallbackValue 6758 && this.callbackType == ((CallbackValue) o).callbackType 6759 && this.error == ((CallbackValue) o).error; 6760 } 6761 6762 @Override 6763 public String toString() { 6764 return String.format("%s(%s, %d)", getClass().getSimpleName(), callbackType, 6765 error); 6766 } 6767 } 6768 6769 private LinkedBlockingQueue<CallbackValue> mCallbacks = new LinkedBlockingQueue<>(); 6770 private final Executor mExecutor; 6771 6772 TestSocketKeepaliveCallback(@NonNull Executor executor) { 6773 mExecutor = executor; 6774 } 6775 6776 @Override 6777 public void onStarted() { 6778 mCallbacks.add(new CallbackValue(CallbackType.ON_STARTED)); 6779 } 6780 6781 @Override 6782 public void onStopped() { 6783 mCallbacks.add(new CallbackValue(CallbackType.ON_STOPPED)); 6784 } 6785 6786 @Override 6787 public void onError(int error) { 6788 mCallbacks.add(new CallbackValue(CallbackType.ON_ERROR, error)); 6789 } 6790 6791 private void expect(CallbackValue callbackValue) throws InterruptedException { 6792 assertEquals(callbackValue, mCallbacks.poll(TIMEOUT_MS, TimeUnit.MILLISECONDS)); 6793 6794 } 6795 6796 public void expectStarted() throws InterruptedException { 6797 expect(new CallbackValue(CallbackType.ON_STARTED)); 6798 } 6799 6800 public void expectStopped() throws InterruptedException { 6801 expect(new CallbackValue(CallbackType.ON_STOPPED)); 6802 } 6803 6804 public void expectError(int error) throws InterruptedException { 6805 expect(new CallbackValue(CallbackType.ON_ERROR, error)); 6806 } 6807 6808 public void assertNoCallback() { 6809 waitForIdleSerialExecutor(mExecutor, TIMEOUT_MS); 6810 CallbackValue cv = mCallbacks.peek(); 6811 assertNull("Unexpected callback: " + cv, cv); 6812 } 6813 } 6814 6815 private Network connectKeepaliveNetwork(LinkProperties lp) throws Exception { 6816 // Ensure the network is disconnected before anything else occurs 6817 if (mWiFiAgent != null) { 6818 assertNull(mCm.getNetworkCapabilities(mWiFiAgent.getNetwork())); 6819 } 6820 6821 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 6822 ExpectedBroadcast b = expectConnectivityAction(TYPE_WIFI, DetailedState.CONNECTED); 6823 mWiFiAgent.connect(true); 6824 b.expectBroadcast(); 6825 verifyActiveNetwork(TRANSPORT_WIFI); 6826 mWiFiAgent.sendLinkProperties(lp); 6827 waitForIdle(); 6828 return mWiFiAgent.getNetwork(); 6829 } 6830 6831 @Test 6832 public void testPacketKeepalives() throws Exception { 6833 InetAddress myIPv4 = InetAddress.getByName("192.0.2.129"); 6834 InetAddress notMyIPv4 = InetAddress.getByName("192.0.2.35"); 6835 InetAddress myIPv6 = InetAddress.getByName("2001:db8::1"); 6836 InetAddress dstIPv4 = InetAddress.getByName("8.8.8.8"); 6837 InetAddress dstIPv6 = InetAddress.getByName("2001:4860:4860::8888"); 6838 6839 final int validKaInterval = 15; 6840 final int invalidKaInterval = 9; 6841 6842 LinkProperties lp = new LinkProperties(); 6843 lp.setInterfaceName("wlan12"); 6844 lp.addLinkAddress(new LinkAddress(myIPv6, 64)); 6845 lp.addLinkAddress(new LinkAddress(myIPv4, 25)); 6846 lp.addRoute(new RouteInfo(InetAddress.getByName("fe80::1234"))); 6847 lp.addRoute(new RouteInfo(InetAddress.getByName("192.0.2.254"))); 6848 6849 Network notMyNet = new Network(61234); 6850 Network myNet = connectKeepaliveNetwork(lp); 6851 6852 TestKeepaliveCallback callback = new TestKeepaliveCallback(); 6853 PacketKeepalive ka; 6854 6855 // Attempt to start keepalives with invalid parameters and check for errors. 6856 ka = mCm.startNattKeepalive(notMyNet, validKaInterval, callback, myIPv4, 1234, dstIPv4); 6857 callback.expectError(PacketKeepalive.ERROR_INVALID_NETWORK); 6858 6859 ka = mCm.startNattKeepalive(myNet, invalidKaInterval, callback, myIPv4, 1234, dstIPv4); 6860 callback.expectError(PacketKeepalive.ERROR_INVALID_INTERVAL); 6861 6862 ka = mCm.startNattKeepalive(myNet, validKaInterval, callback, myIPv4, 1234, dstIPv6); 6863 callback.expectError(PacketKeepalive.ERROR_INVALID_IP_ADDRESS); 6864 6865 ka = mCm.startNattKeepalive(myNet, validKaInterval, callback, myIPv6, 1234, dstIPv4); 6866 callback.expectError(PacketKeepalive.ERROR_INVALID_IP_ADDRESS); 6867 6868 // NAT-T is only supported for IPv4. 6869 ka = mCm.startNattKeepalive(myNet, validKaInterval, callback, myIPv6, 1234, dstIPv6); 6870 callback.expectError(PacketKeepalive.ERROR_INVALID_IP_ADDRESS); 6871 6872 ka = mCm.startNattKeepalive(myNet, validKaInterval, callback, myIPv4, 123456, dstIPv4); 6873 callback.expectError(PacketKeepalive.ERROR_INVALID_PORT); 6874 6875 ka = mCm.startNattKeepalive(myNet, validKaInterval, callback, myIPv4, 123456, dstIPv4); 6876 callback.expectError(PacketKeepalive.ERROR_INVALID_PORT); 6877 6878 ka = mCm.startNattKeepalive(myNet, validKaInterval, callback, myIPv4, 12345, dstIPv4); 6879 callback.expectError(PacketKeepalive.ERROR_HARDWARE_UNSUPPORTED); 6880 6881 ka = mCm.startNattKeepalive(myNet, validKaInterval, callback, myIPv4, 12345, dstIPv4); 6882 callback.expectError(PacketKeepalive.ERROR_HARDWARE_UNSUPPORTED); 6883 6884 // Check that a started keepalive can be stopped. 6885 mWiFiAgent.setStartKeepaliveEvent(PacketKeepalive.SUCCESS); 6886 ka = mCm.startNattKeepalive(myNet, validKaInterval, callback, myIPv4, 12345, dstIPv4); 6887 callback.expectStarted(); 6888 mWiFiAgent.setStopKeepaliveEvent(PacketKeepalive.SUCCESS); 6889 ka.stop(); 6890 callback.expectStopped(); 6891 6892 // Check that deleting the IP address stops the keepalive. 6893 LinkProperties bogusLp = new LinkProperties(lp); 6894 ka = mCm.startNattKeepalive(myNet, validKaInterval, callback, myIPv4, 12345, dstIPv4); 6895 callback.expectStarted(); 6896 bogusLp.removeLinkAddress(new LinkAddress(myIPv4, 25)); 6897 bogusLp.addLinkAddress(new LinkAddress(notMyIPv4, 25)); 6898 mWiFiAgent.sendLinkProperties(bogusLp); 6899 callback.expectError(PacketKeepalive.ERROR_INVALID_IP_ADDRESS); 6900 mWiFiAgent.sendLinkProperties(lp); 6901 6902 // Check that a started keepalive is stopped correctly when the network disconnects. 6903 ka = mCm.startNattKeepalive(myNet, validKaInterval, callback, myIPv4, 12345, dstIPv4); 6904 callback.expectStarted(); 6905 mWiFiAgent.disconnect(); 6906 mWiFiAgent.expectDisconnected(); 6907 callback.expectError(PacketKeepalive.ERROR_INVALID_NETWORK); 6908 6909 // ... and that stopping it after that has no adverse effects. 6910 waitForIdle(); 6911 final Network myNetAlias = myNet; 6912 assertNull(mCm.getNetworkCapabilities(myNetAlias)); 6913 ka.stop(); 6914 6915 // Reconnect. 6916 myNet = connectKeepaliveNetwork(lp); 6917 mWiFiAgent.setStartKeepaliveEvent(PacketKeepalive.SUCCESS); 6918 6919 // Check that keepalive slots start from 1 and increment. The first one gets slot 1. 6920 mWiFiAgent.setExpectedKeepaliveSlot(1); 6921 ka = mCm.startNattKeepalive(myNet, validKaInterval, callback, myIPv4, 12345, dstIPv4); 6922 callback.expectStarted(); 6923 6924 // The second one gets slot 2. 6925 mWiFiAgent.setExpectedKeepaliveSlot(2); 6926 TestKeepaliveCallback callback2 = new TestKeepaliveCallback(); 6927 PacketKeepalive ka2 = mCm.startNattKeepalive( 6928 myNet, validKaInterval, callback2, myIPv4, 6789, dstIPv4); 6929 callback2.expectStarted(); 6930 6931 // Now stop the first one and create a third. This also gets slot 1. 6932 ka.stop(); 6933 callback.expectStopped(); 6934 6935 mWiFiAgent.setExpectedKeepaliveSlot(1); 6936 TestKeepaliveCallback callback3 = new TestKeepaliveCallback(); 6937 PacketKeepalive ka3 = mCm.startNattKeepalive( 6938 myNet, validKaInterval, callback3, myIPv4, 9876, dstIPv4); 6939 callback3.expectStarted(); 6940 6941 ka2.stop(); 6942 callback2.expectStopped(); 6943 6944 ka3.stop(); 6945 callback3.expectStopped(); 6946 } 6947 6948 // Helper method to prepare the executor and run test 6949 private void runTestWithSerialExecutors(ThrowingConsumer<Executor> functor) 6950 throws Exception { 6951 final ExecutorService executorSingleThread = Executors.newSingleThreadExecutor(); 6952 final Executor executorInline = (Runnable r) -> r.run(); 6953 functor.accept(executorSingleThread); 6954 executorSingleThread.shutdown(); 6955 functor.accept(executorInline); 6956 } 6957 6958 @Test 6959 public void testNattSocketKeepalives() throws Exception { 6960 runTestWithSerialExecutors(executor -> doTestNattSocketKeepalivesWithExecutor(executor)); 6961 runTestWithSerialExecutors(executor -> doTestNattSocketKeepalivesFdWithExecutor(executor)); 6962 } 6963 6964 private void doTestNattSocketKeepalivesWithExecutor(Executor executor) throws Exception { 6965 // TODO: 1. Move this outside of ConnectivityServiceTest. 6966 // 2. Make test to verify that Nat-T keepalive socket is created by IpSecService. 6967 // 3. Mock ipsec service. 6968 final InetAddress myIPv4 = InetAddress.getByName("192.0.2.129"); 6969 final InetAddress notMyIPv4 = InetAddress.getByName("192.0.2.35"); 6970 final InetAddress myIPv6 = InetAddress.getByName("2001:db8::1"); 6971 final InetAddress dstIPv4 = InetAddress.getByName("8.8.8.8"); 6972 final InetAddress dstIPv6 = InetAddress.getByName("2001:4860:4860::8888"); 6973 6974 final int validKaInterval = 15; 6975 final int invalidKaInterval = 9; 6976 6977 final IpSecManager mIpSec = (IpSecManager) mContext.getSystemService(Context.IPSEC_SERVICE); 6978 final UdpEncapsulationSocket testSocket = mIpSec.openUdpEncapsulationSocket(); 6979 final int srcPort = testSocket.getPort(); 6980 6981 LinkProperties lp = new LinkProperties(); 6982 lp.setInterfaceName("wlan12"); 6983 lp.addLinkAddress(new LinkAddress(myIPv6, 64)); 6984 lp.addLinkAddress(new LinkAddress(myIPv4, 25)); 6985 lp.addRoute(new RouteInfo(InetAddress.getByName("fe80::1234"))); 6986 lp.addRoute(new RouteInfo(InetAddress.getByName("192.0.2.254"))); 6987 6988 Network notMyNet = new Network(61234); 6989 Network myNet = connectKeepaliveNetwork(lp); 6990 6991 TestSocketKeepaliveCallback callback = new TestSocketKeepaliveCallback(executor); 6992 6993 // Attempt to start keepalives with invalid parameters and check for errors. 6994 // Invalid network. 6995 try (SocketKeepalive ka = mCm.createSocketKeepalive( 6996 notMyNet, testSocket, myIPv4, dstIPv4, executor, callback)) { 6997 ka.start(validKaInterval); 6998 callback.expectError(SocketKeepalive.ERROR_INVALID_NETWORK); 6999 } 7000 7001 // Invalid interval. 7002 try (SocketKeepalive ka = mCm.createSocketKeepalive( 7003 myNet, testSocket, myIPv4, dstIPv4, executor, callback)) { 7004 ka.start(invalidKaInterval); 7005 callback.expectError(SocketKeepalive.ERROR_INVALID_INTERVAL); 7006 } 7007 7008 // Invalid destination. 7009 try (SocketKeepalive ka = mCm.createSocketKeepalive( 7010 myNet, testSocket, myIPv4, dstIPv6, executor, callback)) { 7011 ka.start(validKaInterval); 7012 callback.expectError(SocketKeepalive.ERROR_INVALID_IP_ADDRESS); 7013 } 7014 7015 // Invalid source; 7016 try (SocketKeepalive ka = mCm.createSocketKeepalive( 7017 myNet, testSocket, myIPv6, dstIPv4, executor, callback)) { 7018 ka.start(validKaInterval); 7019 callback.expectError(SocketKeepalive.ERROR_INVALID_IP_ADDRESS); 7020 } 7021 7022 // NAT-T is only supported for IPv4. 7023 try (SocketKeepalive ka = mCm.createSocketKeepalive( 7024 myNet, testSocket, myIPv6, dstIPv6, executor, callback)) { 7025 ka.start(validKaInterval); 7026 callback.expectError(SocketKeepalive.ERROR_INVALID_IP_ADDRESS); 7027 } 7028 7029 // Basic check before testing started keepalive. 7030 try (SocketKeepalive ka = mCm.createSocketKeepalive( 7031 myNet, testSocket, myIPv4, dstIPv4, executor, callback)) { 7032 ka.start(validKaInterval); 7033 callback.expectError(SocketKeepalive.ERROR_UNSUPPORTED); 7034 } 7035 7036 // Check that a started keepalive can be stopped. 7037 mWiFiAgent.setStartKeepaliveEvent(SocketKeepalive.SUCCESS); 7038 try (SocketKeepalive ka = mCm.createSocketKeepalive( 7039 myNet, testSocket, myIPv4, dstIPv4, executor, callback)) { 7040 ka.start(validKaInterval); 7041 callback.expectStarted(); 7042 mWiFiAgent.setStopKeepaliveEvent(SocketKeepalive.SUCCESS); 7043 ka.stop(); 7044 callback.expectStopped(); 7045 7046 // Check that keepalive could be restarted. 7047 ka.start(validKaInterval); 7048 callback.expectStarted(); 7049 ka.stop(); 7050 callback.expectStopped(); 7051 7052 // Check that keepalive can be restarted without waiting for callback. 7053 ka.start(validKaInterval); 7054 callback.expectStarted(); 7055 ka.stop(); 7056 ka.start(validKaInterval); 7057 callback.expectStopped(); 7058 callback.expectStarted(); 7059 ka.stop(); 7060 callback.expectStopped(); 7061 } 7062 7063 // Check that deleting the IP address stops the keepalive. 7064 LinkProperties bogusLp = new LinkProperties(lp); 7065 try (SocketKeepalive ka = mCm.createSocketKeepalive( 7066 myNet, testSocket, myIPv4, dstIPv4, executor, callback)) { 7067 ka.start(validKaInterval); 7068 callback.expectStarted(); 7069 bogusLp.removeLinkAddress(new LinkAddress(myIPv4, 25)); 7070 bogusLp.addLinkAddress(new LinkAddress(notMyIPv4, 25)); 7071 mWiFiAgent.sendLinkProperties(bogusLp); 7072 callback.expectError(SocketKeepalive.ERROR_INVALID_IP_ADDRESS); 7073 mWiFiAgent.sendLinkProperties(lp); 7074 } 7075 7076 // Check that a started keepalive is stopped correctly when the network disconnects. 7077 try (SocketKeepalive ka = mCm.createSocketKeepalive( 7078 myNet, testSocket, myIPv4, dstIPv4, executor, callback)) { 7079 ka.start(validKaInterval); 7080 callback.expectStarted(); 7081 mWiFiAgent.disconnect(); 7082 mWiFiAgent.expectDisconnected(); 7083 callback.expectError(SocketKeepalive.ERROR_INVALID_NETWORK); 7084 7085 // ... and that stopping it after that has no adverse effects. 7086 waitForIdle(); 7087 assertNull(mCm.getNetworkCapabilities(myNet)); 7088 ka.stop(); 7089 callback.assertNoCallback(); 7090 } 7091 7092 // Reconnect. 7093 myNet = connectKeepaliveNetwork(lp); 7094 mWiFiAgent.setStartKeepaliveEvent(SocketKeepalive.SUCCESS); 7095 7096 // Check that a stop followed by network disconnects does not result in crash. 7097 try (SocketKeepalive ka = mCm.createSocketKeepalive( 7098 myNet, testSocket, myIPv4, dstIPv4, executor, callback)) { 7099 ka.start(validKaInterval); 7100 callback.expectStarted(); 7101 // Delay the response of keepalive events in networkAgent long enough to make sure 7102 // the follow-up network disconnection will be processed first. 7103 mWiFiAgent.setKeepaliveResponseDelay(3 * TIMEOUT_MS); 7104 ka.stop(); 7105 // Call stop() twice shouldn't result in crash, b/182586681. 7106 ka.stop(); 7107 7108 // Make sure the stop has been processed. Wait for executor idle is needed to prevent 7109 // flaky since the actual stop call to the service is delegated to executor thread. 7110 waitForIdleSerialExecutor(executor, TIMEOUT_MS); 7111 waitForIdle(); 7112 7113 mWiFiAgent.disconnect(); 7114 mWiFiAgent.expectDisconnected(); 7115 callback.expectStopped(); 7116 callback.assertNoCallback(); 7117 } 7118 7119 // Reconnect. 7120 waitForIdle(); 7121 myNet = connectKeepaliveNetwork(lp); 7122 mWiFiAgent.setStartKeepaliveEvent(SocketKeepalive.SUCCESS); 7123 7124 // Check that keepalive slots start from 1 and increment. The first one gets slot 1. 7125 mWiFiAgent.setExpectedKeepaliveSlot(1); 7126 try (SocketKeepalive ka = mCm.createSocketKeepalive( 7127 myNet, testSocket, myIPv4, dstIPv4, executor, callback)) { 7128 ka.start(validKaInterval); 7129 callback.expectStarted(); 7130 7131 // The second one gets slot 2. 7132 mWiFiAgent.setExpectedKeepaliveSlot(2); 7133 final UdpEncapsulationSocket testSocket2 = mIpSec.openUdpEncapsulationSocket(); 7134 TestSocketKeepaliveCallback callback2 = new TestSocketKeepaliveCallback(executor); 7135 try (SocketKeepalive ka2 = mCm.createSocketKeepalive( 7136 myNet, testSocket2, myIPv4, dstIPv4, executor, callback2)) { 7137 ka2.start(validKaInterval); 7138 callback2.expectStarted(); 7139 7140 ka.stop(); 7141 callback.expectStopped(); 7142 7143 ka2.stop(); 7144 callback2.expectStopped(); 7145 7146 testSocket.close(); 7147 testSocket2.close(); 7148 } 7149 } 7150 7151 // Check that there is no port leaked after all keepalives and sockets are closed. 7152 // TODO: enable this check after ensuring a valid free port. See b/129512753#comment7. 7153 // assertFalse(isUdpPortInUse(srcPort)); 7154 // assertFalse(isUdpPortInUse(srcPort2)); 7155 7156 mWiFiAgent.disconnect(); 7157 mWiFiAgent.expectDisconnected(); 7158 mWiFiAgent = null; 7159 } 7160 7161 @Test 7162 public void testTcpSocketKeepalives() throws Exception { 7163 runTestWithSerialExecutors(executor -> doTestTcpSocketKeepalivesWithExecutor(executor)); 7164 } 7165 7166 private void doTestTcpSocketKeepalivesWithExecutor(Executor executor) throws Exception { 7167 final int srcPortV4 = 12345; 7168 final int srcPortV6 = 23456; 7169 final InetAddress myIPv4 = InetAddress.getByName("127.0.0.1"); 7170 final InetAddress myIPv6 = InetAddress.getByName("::1"); 7171 7172 final int validKaInterval = 15; 7173 7174 final LinkProperties lp = new LinkProperties(); 7175 lp.setInterfaceName("wlan12"); 7176 lp.addLinkAddress(new LinkAddress(myIPv6, 64)); 7177 lp.addLinkAddress(new LinkAddress(myIPv4, 25)); 7178 lp.addRoute(new RouteInfo(InetAddress.getByName("fe80::1234"))); 7179 lp.addRoute(new RouteInfo(InetAddress.getByName("127.0.0.254"))); 7180 7181 final Network notMyNet = new Network(61234); 7182 final Network myNet = connectKeepaliveNetwork(lp); 7183 7184 final Socket testSocketV4 = new Socket(); 7185 final Socket testSocketV6 = new Socket(); 7186 7187 TestSocketKeepaliveCallback callback = new TestSocketKeepaliveCallback(executor); 7188 7189 // Attempt to start Tcp keepalives with invalid parameters and check for errors. 7190 // Invalid network. 7191 try (SocketKeepalive ka = mCm.createSocketKeepalive( 7192 notMyNet, testSocketV4, executor, callback)) { 7193 ka.start(validKaInterval); 7194 callback.expectError(SocketKeepalive.ERROR_INVALID_NETWORK); 7195 } 7196 7197 // Invalid Socket (socket is not bound with IPv4 address). 7198 try (SocketKeepalive ka = mCm.createSocketKeepalive( 7199 myNet, testSocketV4, executor, callback)) { 7200 ka.start(validKaInterval); 7201 callback.expectError(SocketKeepalive.ERROR_INVALID_SOCKET); 7202 } 7203 7204 // Invalid Socket (socket is not bound with IPv6 address). 7205 try (SocketKeepalive ka = mCm.createSocketKeepalive( 7206 myNet, testSocketV6, executor, callback)) { 7207 ka.start(validKaInterval); 7208 callback.expectError(SocketKeepalive.ERROR_INVALID_SOCKET); 7209 } 7210 7211 // Bind the socket address 7212 testSocketV4.bind(new InetSocketAddress(myIPv4, srcPortV4)); 7213 testSocketV6.bind(new InetSocketAddress(myIPv6, srcPortV6)); 7214 7215 // Invalid Socket (socket is bound with IPv4 address). 7216 try (SocketKeepalive ka = mCm.createSocketKeepalive( 7217 myNet, testSocketV4, executor, callback)) { 7218 ka.start(validKaInterval); 7219 callback.expectError(SocketKeepalive.ERROR_INVALID_SOCKET); 7220 } 7221 7222 // Invalid Socket (socket is bound with IPv6 address). 7223 try (SocketKeepalive ka = mCm.createSocketKeepalive( 7224 myNet, testSocketV6, executor, callback)) { 7225 ka.start(validKaInterval); 7226 callback.expectError(SocketKeepalive.ERROR_INVALID_SOCKET); 7227 } 7228 7229 testSocketV4.close(); 7230 testSocketV6.close(); 7231 7232 mWiFiAgent.disconnect(); 7233 mWiFiAgent.expectDisconnected(); 7234 mWiFiAgent = null; 7235 } 7236 7237 private void doTestNattSocketKeepalivesFdWithExecutor(Executor executor) throws Exception { 7238 final InetAddress myIPv4 = InetAddress.getByName("192.0.2.129"); 7239 final InetAddress anyIPv4 = InetAddress.getByName("0.0.0.0"); 7240 final InetAddress dstIPv4 = InetAddress.getByName("8.8.8.8"); 7241 final int validKaInterval = 15; 7242 7243 // Prepare the target network. 7244 LinkProperties lp = new LinkProperties(); 7245 lp.setInterfaceName("wlan12"); 7246 lp.addLinkAddress(new LinkAddress(myIPv4, 25)); 7247 lp.addRoute(new RouteInfo(InetAddress.getByName("192.0.2.254"))); 7248 Network myNet = connectKeepaliveNetwork(lp); 7249 mWiFiAgent.setStartKeepaliveEvent(SocketKeepalive.SUCCESS); 7250 mWiFiAgent.setStopKeepaliveEvent(SocketKeepalive.SUCCESS); 7251 7252 TestSocketKeepaliveCallback callback = new TestSocketKeepaliveCallback(executor); 7253 7254 // Prepare the target file descriptor, keep only one instance. 7255 final IpSecManager mIpSec = (IpSecManager) mContext.getSystemService(Context.IPSEC_SERVICE); 7256 final UdpEncapsulationSocket testSocket = mIpSec.openUdpEncapsulationSocket(); 7257 final int srcPort = testSocket.getPort(); 7258 final ParcelFileDescriptor testPfd = 7259 ParcelFileDescriptor.dup(testSocket.getFileDescriptor()); 7260 testSocket.close(); 7261 assertTrue(isUdpPortInUse(srcPort)); 7262 7263 // Start keepalive and explicit make the variable goes out of scope with try-with-resources 7264 // block. 7265 try (SocketKeepalive ka = mCm.createNattKeepalive( 7266 myNet, testPfd, myIPv4, dstIPv4, executor, callback)) { 7267 ka.start(validKaInterval); 7268 callback.expectStarted(); 7269 ka.stop(); 7270 callback.expectStopped(); 7271 } 7272 7273 // Check that the ParcelFileDescriptor is still valid after keepalive stopped, 7274 // ErrnoException with EBADF will be thrown if the socket is closed when checking local 7275 // address. 7276 assertTrue(isUdpPortInUse(srcPort)); 7277 final InetSocketAddress sa = 7278 (InetSocketAddress) Os.getsockname(testPfd.getFileDescriptor()); 7279 assertEquals(anyIPv4, sa.getAddress()); 7280 7281 testPfd.close(); 7282 // TODO: enable this check after ensuring a valid free port. See b/129512753#comment7. 7283 // assertFalse(isUdpPortInUse(srcPort)); 7284 7285 mWiFiAgent.disconnect(); 7286 mWiFiAgent.expectDisconnected(); 7287 mWiFiAgent = null; 7288 } 7289 7290 private static boolean isUdpPortInUse(int port) { 7291 try (DatagramSocket ignored = new DatagramSocket(port)) { 7292 return false; 7293 } catch (IOException alreadyInUse) { 7294 return true; 7295 } 7296 } 7297 7298 @Test 7299 public void testGetCaptivePortalServerUrl() throws Exception { 7300 String url = mCm.getCaptivePortalServerUrl(); 7301 assertEquals("http://connectivitycheck.gstatic.com/generate_204", url); 7302 } 7303 7304 private static class TestNetworkPinner extends NetworkPinner { 7305 public static boolean awaitPin(int timeoutMs) throws InterruptedException { 7306 synchronized(sLock) { 7307 if (sNetwork == null) { 7308 sLock.wait(timeoutMs); 7309 } 7310 return sNetwork != null; 7311 } 7312 } 7313 7314 public static boolean awaitUnpin(int timeoutMs) throws InterruptedException { 7315 synchronized(sLock) { 7316 if (sNetwork != null) { 7317 sLock.wait(timeoutMs); 7318 } 7319 return sNetwork == null; 7320 } 7321 } 7322 } 7323 7324 private void assertPinnedToWifiWithCellDefault() { 7325 assertEquals(mWiFiAgent.getNetwork(), mCm.getBoundNetworkForProcess()); 7326 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetwork()); 7327 } 7328 7329 private void assertPinnedToWifiWithWifiDefault() { 7330 assertEquals(mWiFiAgent.getNetwork(), mCm.getBoundNetworkForProcess()); 7331 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetwork()); 7332 } 7333 7334 private void assertNotPinnedToWifi() { 7335 assertNull(mCm.getBoundNetworkForProcess()); 7336 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetwork()); 7337 } 7338 7339 @Test 7340 public void testNetworkPinner() throws Exception { 7341 NetworkRequest wifiRequest = new NetworkRequest.Builder() 7342 .addTransportType(TRANSPORT_WIFI) 7343 .build(); 7344 assertNull(mCm.getBoundNetworkForProcess()); 7345 7346 TestNetworkPinner.pin(mServiceContext, wifiRequest); 7347 assertNull(mCm.getBoundNetworkForProcess()); 7348 7349 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 7350 mCellAgent.connect(true); 7351 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 7352 mWiFiAgent.connect(false); 7353 7354 // When wi-fi connects, expect to be pinned. 7355 assertTrue(TestNetworkPinner.awaitPin(100)); 7356 assertPinnedToWifiWithCellDefault(); 7357 7358 // Disconnect and expect the pin to drop. 7359 mWiFiAgent.disconnect(); 7360 assertTrue(TestNetworkPinner.awaitUnpin(100)); 7361 assertNotPinnedToWifi(); 7362 7363 // Reconnecting does not cause the pin to come back. 7364 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 7365 mWiFiAgent.connect(false); 7366 assertFalse(TestNetworkPinner.awaitPin(100)); 7367 assertNotPinnedToWifi(); 7368 7369 // Pinning while connected causes the pin to take effect immediately. 7370 TestNetworkPinner.pin(mServiceContext, wifiRequest); 7371 assertTrue(TestNetworkPinner.awaitPin(100)); 7372 assertPinnedToWifiWithCellDefault(); 7373 7374 // Explicitly unpin and expect to use the default network again. 7375 TestNetworkPinner.unpin(); 7376 assertNotPinnedToWifi(); 7377 7378 // Disconnect cell and wifi. 7379 ExpectedBroadcast b = expectConnectivityAction(3); // cell down, wifi up, wifi down. 7380 mCellAgent.disconnect(); 7381 mWiFiAgent.disconnect(); 7382 b.expectBroadcast(); 7383 7384 // Pinning takes effect even if the pinned network is the default when the pin is set... 7385 TestNetworkPinner.pin(mServiceContext, wifiRequest); 7386 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 7387 mWiFiAgent.connect(false); 7388 assertTrue(TestNetworkPinner.awaitPin(100)); 7389 assertPinnedToWifiWithWifiDefault(); 7390 7391 // ... and is maintained even when that network is no longer the default. 7392 b = expectConnectivityAction(1); 7393 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 7394 mCellAgent.connect(true); 7395 b.expectBroadcast(); 7396 assertPinnedToWifiWithCellDefault(); 7397 } 7398 7399 @Test 7400 public void testNetworkCallbackMaximum() throws Exception { 7401 final int MAX_REQUESTS = 100; 7402 final int CALLBACKS = 87; 7403 final int DIFF_INTENTS = 10; 7404 final int SAME_INTENTS = 10; 7405 final int SYSTEM_ONLY_MAX_REQUESTS = 250; 7406 // Assert 1 (Default request filed before testing) + CALLBACKS + DIFF_INTENTS + 7407 // 1 (same intent) = MAX_REQUESTS - 1, since the capacity is MAX_REQUEST - 1. 7408 assertEquals(MAX_REQUESTS - 1, 1 + CALLBACKS + DIFF_INTENTS + 1); 7409 7410 NetworkRequest networkRequest = new NetworkRequest.Builder().build(); 7411 ArrayList<Object> registered = new ArrayList<>(); 7412 7413 for (int j = 0; j < CALLBACKS; j++) { 7414 final NetworkCallback cb = new NetworkCallback(); 7415 if (j < CALLBACKS / 2) { 7416 mCm.requestNetwork(networkRequest, cb); 7417 } else { 7418 mCm.registerNetworkCallback(networkRequest, cb); 7419 } 7420 registered.add(cb); 7421 } 7422 7423 // Since ConnectivityService will de-duplicate the request with the same intent, 7424 // register multiple times does not really increase multiple requests. 7425 final PendingIntent same_pi = PendingIntent.getBroadcast(mContext, 0 /* requestCode */, 7426 new Intent("same"), FLAG_IMMUTABLE); 7427 for (int j = 0; j < SAME_INTENTS; j++) { 7428 mCm.registerNetworkCallback(networkRequest, same_pi); 7429 // Wait for the requests with the same intent to be de-duplicated. Because 7430 // ConnectivityService side incrementCountOrThrow in binder, decrementCount in handler 7431 // thread, waitForIdle is needed to ensure decrementCount being invoked for same intent 7432 // requests before doing further tests. 7433 waitForIdle(); 7434 } 7435 for (int j = 0; j < SAME_INTENTS; j++) { 7436 mCm.requestNetwork(networkRequest, same_pi); 7437 // Wait for the requests with the same intent to be de-duplicated. 7438 // Refer to the reason above. 7439 waitForIdle(); 7440 } 7441 registered.add(same_pi); 7442 7443 for (int j = 0; j < DIFF_INTENTS; j++) { 7444 if (j < DIFF_INTENTS / 2) { 7445 final PendingIntent pi = PendingIntent.getBroadcast(mContext, 0 /* requestCode */, 7446 new Intent("a" + j), FLAG_IMMUTABLE); 7447 mCm.requestNetwork(networkRequest, pi); 7448 registered.add(pi); 7449 } else { 7450 final PendingIntent pi = PendingIntent.getBroadcast(mContext, 0 /* requestCode */, 7451 new Intent("b" + j), FLAG_IMMUTABLE); 7452 mCm.registerNetworkCallback(networkRequest, pi); 7453 registered.add(pi); 7454 } 7455 } 7456 7457 // Test that the limit is enforced when MAX_REQUESTS simultaneous requests are added. 7458 assertThrows(TooManyRequestsException.class, () -> 7459 mCm.requestNetwork(networkRequest, new NetworkCallback()) 7460 ); 7461 assertThrows(TooManyRequestsException.class, () -> 7462 mCm.registerNetworkCallback(networkRequest, new NetworkCallback()) 7463 ); 7464 assertThrows(TooManyRequestsException.class, () -> 7465 mCm.requestNetwork(networkRequest, 7466 PendingIntent.getBroadcast(mContext, 0 /* requestCode */, 7467 new Intent("c"), FLAG_IMMUTABLE)) 7468 ); 7469 assertThrows(TooManyRequestsException.class, () -> 7470 mCm.registerNetworkCallback(networkRequest, 7471 PendingIntent.getBroadcast(mContext, 0 /* requestCode */, 7472 new Intent("d"), FLAG_IMMUTABLE)) 7473 ); 7474 7475 // The system gets another SYSTEM_ONLY_MAX_REQUESTS slots. 7476 final Handler handler = new Handler(ConnectivityThread.getInstanceLooper()); 7477 withPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, () -> { 7478 ArrayList<NetworkCallback> systemRegistered = new ArrayList<>(); 7479 for (int i = 0; i < SYSTEM_ONLY_MAX_REQUESTS - 1; i++) { 7480 NetworkCallback cb = new NetworkCallback(); 7481 if (i % 2 == 0) { 7482 mCm.registerDefaultNetworkCallbackForUid(1000000 + i, cb, handler); 7483 } else { 7484 mCm.registerNetworkCallback(networkRequest, cb); 7485 } 7486 systemRegistered.add(cb); 7487 } 7488 waitForIdle(); 7489 7490 assertThrows(TooManyRequestsException.class, () -> 7491 mCm.registerDefaultNetworkCallbackForUid(1001042, new NetworkCallback(), 7492 handler)); 7493 assertThrows(TooManyRequestsException.class, () -> 7494 mCm.registerNetworkCallback(networkRequest, new NetworkCallback())); 7495 7496 for (NetworkCallback callback : systemRegistered) { 7497 mCm.unregisterNetworkCallback(callback); 7498 } 7499 waitForIdle(); // Wait for requests to be unregistered before giving up the permission. 7500 }); 7501 7502 for (Object o : registered) { 7503 if (o instanceof NetworkCallback) { 7504 mCm.unregisterNetworkCallback((NetworkCallback) o); 7505 } 7506 if (o instanceof PendingIntent) { 7507 mCm.unregisterNetworkCallback((PendingIntent) o); 7508 } 7509 } 7510 waitForIdle(); 7511 7512 // Test that the limit is not hit when MAX_REQUESTS requests are added and removed. 7513 for (int i = 0; i < MAX_REQUESTS; i++) { 7514 NetworkCallback networkCallback = new NetworkCallback(); 7515 mCm.requestNetwork(networkRequest, networkCallback); 7516 mCm.unregisterNetworkCallback(networkCallback); 7517 } 7518 waitForIdle(); 7519 7520 for (int i = 0; i < MAX_REQUESTS; i++) { 7521 NetworkCallback networkCallback = new NetworkCallback(); 7522 mCm.registerNetworkCallback(networkRequest, networkCallback); 7523 mCm.unregisterNetworkCallback(networkCallback); 7524 } 7525 waitForIdle(); 7526 7527 for (int i = 0; i < MAX_REQUESTS; i++) { 7528 NetworkCallback networkCallback = new NetworkCallback(); 7529 mCm.registerDefaultNetworkCallback(networkCallback); 7530 mCm.unregisterNetworkCallback(networkCallback); 7531 } 7532 waitForIdle(); 7533 7534 for (int i = 0; i < MAX_REQUESTS; i++) { 7535 NetworkCallback networkCallback = new NetworkCallback(); 7536 mCm.registerDefaultNetworkCallback(networkCallback); 7537 mCm.unregisterNetworkCallback(networkCallback); 7538 } 7539 waitForIdle(); 7540 7541 withPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, () -> { 7542 for (int i = 0; i < MAX_REQUESTS; i++) { 7543 NetworkCallback networkCallback = new NetworkCallback(); 7544 mCm.registerDefaultNetworkCallbackForUid(1000000 + i, networkCallback, 7545 new Handler(ConnectivityThread.getInstanceLooper())); 7546 mCm.unregisterNetworkCallback(networkCallback); 7547 } 7548 }); 7549 waitForIdle(); 7550 7551 for (int i = 0; i < MAX_REQUESTS; i++) { 7552 final PendingIntent pendingIntent = PendingIntent.getBroadcast( 7553 mContext, 0 /* requestCode */, new Intent("e" + i), FLAG_IMMUTABLE); 7554 mCm.requestNetwork(networkRequest, pendingIntent); 7555 mCm.unregisterNetworkCallback(pendingIntent); 7556 } 7557 waitForIdle(); 7558 7559 for (int i = 0; i < MAX_REQUESTS; i++) { 7560 final PendingIntent pendingIntent = PendingIntent.getBroadcast( 7561 mContext, 0 /* requestCode */, new Intent("f" + i), FLAG_IMMUTABLE); 7562 mCm.registerNetworkCallback(networkRequest, pendingIntent); 7563 mCm.unregisterNetworkCallback(pendingIntent); 7564 } 7565 } 7566 7567 @Test 7568 public void testNetworkInfoOfTypeNone() throws Exception { 7569 ExpectedBroadcast b = expectConnectivityAction(1); 7570 7571 verifyNoNetwork(); 7572 TestNetworkAgentWrapper wifiAware = new TestNetworkAgentWrapper(TRANSPORT_WIFI_AWARE); 7573 assertNull(mCm.getActiveNetworkInfo()); 7574 7575 Network[] allNetworks = mCm.getAllNetworks(); 7576 assertLength(1, allNetworks); 7577 Network network = allNetworks[0]; 7578 NetworkCapabilities capabilities = mCm.getNetworkCapabilities(network); 7579 assertTrue(capabilities.hasTransport(TRANSPORT_WIFI_AWARE)); 7580 7581 final NetworkRequest request = 7582 new NetworkRequest.Builder().addTransportType(TRANSPORT_WIFI_AWARE).build(); 7583 final TestNetworkCallback callback = new TestNetworkCallback(); 7584 mCm.registerNetworkCallback(request, callback); 7585 7586 // Bring up wifi aware network. 7587 wifiAware.connect(false, false, false /* privateDnsProbeSent */); 7588 callback.expectAvailableCallbacksUnvalidated(wifiAware); 7589 7590 assertNull(mCm.getActiveNetworkInfo()); 7591 assertNull(mCm.getActiveNetwork()); 7592 // TODO: getAllNetworkInfo is dirty and returns a non-empty array right from the start 7593 // of this test. Fix it and uncomment the assert below. 7594 //assertEmpty(mCm.getAllNetworkInfo()); 7595 7596 // Disconnect wifi aware network. 7597 wifiAware.disconnect(); 7598 callback.expect(LOST, TIMEOUT_MS); 7599 mCm.unregisterNetworkCallback(callback); 7600 7601 verifyNoNetwork(); 7602 b.expectNoBroadcast(10); 7603 } 7604 7605 @Test 7606 public void testDeprecatedAndUnsupportedOperations() throws Exception { 7607 final int TYPE_NONE = ConnectivityManager.TYPE_NONE; 7608 assertNull(mCm.getNetworkInfo(TYPE_NONE)); 7609 assertNull(mCm.getNetworkForType(TYPE_NONE)); 7610 assertNull(mCm.getLinkProperties(TYPE_NONE)); 7611 assertFalse(mCm.isNetworkSupported(TYPE_NONE)); 7612 7613 assertThrows(IllegalArgumentException.class, 7614 () -> mCm.networkCapabilitiesForType(TYPE_NONE)); 7615 7616 Class<UnsupportedOperationException> unsupported = UnsupportedOperationException.class; 7617 assertThrows(unsupported, () -> mCm.startUsingNetworkFeature(TYPE_WIFI, "")); 7618 assertThrows(unsupported, () -> mCm.stopUsingNetworkFeature(TYPE_WIFI, "")); 7619 // TODO: let test context have configuration application target sdk version 7620 // and test that pre-M requesting for TYPE_NONE sends back APN_REQUEST_FAILED 7621 assertThrows(unsupported, () -> mCm.startUsingNetworkFeature(TYPE_NONE, "")); 7622 assertThrows(unsupported, () -> mCm.stopUsingNetworkFeature(TYPE_NONE, "")); 7623 assertThrows(unsupported, () -> mCm.requestRouteToHostAddress(TYPE_NONE, null)); 7624 } 7625 7626 @Test 7627 public void testLinkPropertiesEnsuresDirectlyConnectedRoutes() throws Exception { 7628 final NetworkRequest networkRequest = new NetworkRequest.Builder() 7629 .addTransportType(TRANSPORT_WIFI).build(); 7630 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 7631 mCm.registerNetworkCallback(networkRequest, networkCallback); 7632 7633 LinkProperties lp = new LinkProperties(); 7634 lp.setInterfaceName(WIFI_IFNAME); 7635 LinkAddress myIpv4Address = new LinkAddress("192.168.12.3/24"); 7636 RouteInfo myIpv4DefaultRoute = new RouteInfo((IpPrefix) null, 7637 InetAddresses.parseNumericAddress("192.168.12.1"), lp.getInterfaceName()); 7638 lp.addLinkAddress(myIpv4Address); 7639 lp.addRoute(myIpv4DefaultRoute); 7640 7641 // Verify direct routes are added when network agent is first registered in 7642 // ConnectivityService. 7643 TestNetworkAgentWrapper networkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, lp); 7644 networkAgent.connect(true); 7645 networkCallback.expect(AVAILABLE, networkAgent); 7646 networkCallback.expect(NETWORK_CAPS_UPDATED, networkAgent); 7647 CallbackEntry.LinkPropertiesChanged cbi = 7648 networkCallback.expect(LINK_PROPERTIES_CHANGED, networkAgent); 7649 networkCallback.expect(BLOCKED_STATUS, networkAgent); 7650 networkCallback.expectCaps(networkAgent, c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 7651 networkCallback.assertNoCallback(); 7652 checkDirectlyConnectedRoutes(cbi.getLp(), asList(myIpv4Address), 7653 asList(myIpv4DefaultRoute)); 7654 checkDirectlyConnectedRoutes(mCm.getLinkProperties(networkAgent.getNetwork()), 7655 asList(myIpv4Address), asList(myIpv4DefaultRoute)); 7656 7657 // Verify direct routes are added during subsequent link properties updates. 7658 LinkProperties newLp = new LinkProperties(lp); 7659 LinkAddress myIpv6Address1 = new LinkAddress("fe80::cafe/64"); 7660 LinkAddress myIpv6Address2 = new LinkAddress("2001:db8::2/64"); 7661 newLp.addLinkAddress(myIpv6Address1); 7662 newLp.addLinkAddress(myIpv6Address2); 7663 networkAgent.sendLinkProperties(newLp); 7664 cbi = networkCallback.expect(LINK_PROPERTIES_CHANGED, networkAgent); 7665 networkCallback.assertNoCallback(); 7666 checkDirectlyConnectedRoutes(cbi.getLp(), 7667 asList(myIpv4Address, myIpv6Address1, myIpv6Address2), 7668 asList(myIpv4DefaultRoute)); 7669 mCm.unregisterNetworkCallback(networkCallback); 7670 } 7671 7672 private void expectNotifyNetworkStatus(List<Network> allNetworks, List<Network> defaultNetworks, 7673 String defaultIface, Integer vpnUid, String vpnIfname, List<String> underlyingIfaces) 7674 throws Exception { 7675 ArgumentCaptor<List<Network>> defaultNetworksCaptor = ArgumentCaptor.forClass(List.class); 7676 ArgumentCaptor<List<UnderlyingNetworkInfo>> vpnInfosCaptor = 7677 ArgumentCaptor.forClass(List.class); 7678 ArgumentCaptor<List<NetworkStateSnapshot>> snapshotsCaptor = 7679 ArgumentCaptor.forClass(List.class); 7680 7681 verify(mStatsManager, atLeastOnce()).notifyNetworkStatus(defaultNetworksCaptor.capture(), 7682 snapshotsCaptor.capture(), eq(defaultIface), vpnInfosCaptor.capture()); 7683 7684 assertSameElements(defaultNetworks, defaultNetworksCaptor.getValue()); 7685 7686 List<Network> snapshotNetworks = new ArrayList<Network>(); 7687 for (NetworkStateSnapshot ns : snapshotsCaptor.getValue()) { 7688 snapshotNetworks.add(ns.getNetwork()); 7689 } 7690 assertSameElements(allNetworks, snapshotNetworks); 7691 7692 if (defaultIface != null) { 7693 assertNotNull( 7694 "Did not find interface " + defaultIface + " in call to notifyNetworkStatus", 7695 CollectionUtils.findFirst(snapshotsCaptor.getValue(), (ns) -> { 7696 final LinkProperties lp = ns.getLinkProperties(); 7697 if (lp != null && TextUtils.equals(defaultIface, lp.getInterfaceName())) { 7698 return true; 7699 } 7700 return false; 7701 })); 7702 } 7703 7704 List<UnderlyingNetworkInfo> infos = vpnInfosCaptor.getValue(); 7705 if (vpnUid != null) { 7706 assertEquals("Should have exactly one VPN:", 1, infos.size()); 7707 UnderlyingNetworkInfo info = infos.get(0); 7708 assertEquals("Unexpected VPN owner:", (int) vpnUid, info.getOwnerUid()); 7709 assertEquals("Unexpected VPN interface:", vpnIfname, info.getInterface()); 7710 assertSameElements(underlyingIfaces, info.getUnderlyingInterfaces()); 7711 } else { 7712 assertEquals(0, infos.size()); 7713 return; 7714 } 7715 } 7716 7717 private void expectNotifyNetworkStatus( 7718 List<Network> allNetworks, List<Network> defaultNetworks, String defaultIface) 7719 throws Exception { 7720 expectNotifyNetworkStatus(allNetworks, defaultNetworks, defaultIface, null, null, 7721 List.of()); 7722 } 7723 7724 private List<Network> onlyCell() { 7725 return List.of(mCellAgent.getNetwork()); 7726 } 7727 7728 private List<Network> onlyWifi() { 7729 return List.of(mWiFiAgent.getNetwork()); 7730 } 7731 7732 private List<Network> cellAndWifi() { 7733 return List.of(mCellAgent.getNetwork(), mWiFiAgent.getNetwork()); 7734 } 7735 7736 @Test 7737 public void testStatsIfacesChanged() throws Exception { 7738 LinkProperties cellLp = new LinkProperties(); 7739 cellLp.setInterfaceName(MOBILE_IFNAME); 7740 LinkProperties wifiLp = new LinkProperties(); 7741 wifiLp.setInterfaceName(WIFI_IFNAME); 7742 7743 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp); 7744 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 7745 7746 // Simple connection with initial LP should have updated ifaces. 7747 mCellAgent.connect(false); 7748 waitForIdle(); 7749 List<Network> allNetworks = mService.shouldCreateNetworksImmediately() 7750 ? cellAndWifi() : onlyCell(); 7751 expectNotifyNetworkStatus(allNetworks, onlyCell(), MOBILE_IFNAME); 7752 reset(mStatsManager); 7753 7754 // Verify change fields other than interfaces does not trigger a notification to NSS. 7755 cellLp.addLinkAddress(new LinkAddress("192.0.2.4/24")); 7756 cellLp.addRoute(new RouteInfo((IpPrefix) null, InetAddress.getByName("192.0.2.4"), 7757 MOBILE_IFNAME)); 7758 cellLp.setDnsServers(List.of(InetAddress.getAllByName("8.8.8.8"))); 7759 mCellAgent.sendLinkProperties(cellLp); 7760 verifyNoMoreInteractions(mStatsManager); 7761 reset(mStatsManager); 7762 7763 // Default network switch should update ifaces. 7764 mWiFiAgent.connect(false); 7765 mWiFiAgent.sendLinkProperties(wifiLp); 7766 waitForIdle(); 7767 assertEquals(wifiLp, mService.getActiveLinkProperties()); 7768 expectNotifyNetworkStatus(cellAndWifi(), onlyWifi(), WIFI_IFNAME); 7769 reset(mStatsManager); 7770 7771 // Disconnecting a network updates ifaces again. The soon-to-be disconnected interface is 7772 // still in the list to ensure that stats are counted on that interface. 7773 // TODO: this means that if anything else uses that interface for any other reason before 7774 // notifyNetworkStatus is called again, traffic on that interface will be accounted to the 7775 // disconnected network. This is likely a bug in ConnectivityService; it should probably 7776 // call notifyNetworkStatus again without the disconnected network. 7777 mCellAgent.disconnect(); 7778 waitForIdle(); 7779 expectNotifyNetworkStatus(cellAndWifi(), onlyWifi(), WIFI_IFNAME); 7780 verifyNoMoreInteractions(mStatsManager); 7781 reset(mStatsManager); 7782 7783 // Connecting a network updates ifaces even if the network doesn't become default. 7784 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp); 7785 mCellAgent.connect(false); 7786 waitForIdle(); 7787 expectNotifyNetworkStatus(cellAndWifi(), onlyWifi(), WIFI_IFNAME); 7788 reset(mStatsManager); 7789 7790 // Disconnect should update ifaces. 7791 mWiFiAgent.disconnect(); 7792 waitForIdle(); 7793 expectNotifyNetworkStatus(onlyCell(), onlyCell(), MOBILE_IFNAME); 7794 reset(mStatsManager); 7795 7796 // Metered change should update ifaces 7797 mCellAgent.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED); 7798 waitForIdle(); 7799 expectNotifyNetworkStatus(onlyCell(), onlyCell(), MOBILE_IFNAME); 7800 reset(mStatsManager); 7801 7802 mCellAgent.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED); 7803 waitForIdle(); 7804 expectNotifyNetworkStatus(onlyCell(), onlyCell(), MOBILE_IFNAME); 7805 reset(mStatsManager); 7806 7807 // Temp metered change shouldn't update ifaces 7808 mCellAgent.addCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED); 7809 waitForIdle(); 7810 verify(mStatsManager, never()).notifyNetworkStatus(eq(onlyCell()), 7811 any(List.class), eq(MOBILE_IFNAME), any(List.class)); 7812 reset(mStatsManager); 7813 7814 // Congested change shouldn't update ifaces 7815 mCellAgent.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED); 7816 waitForIdle(); 7817 verify(mStatsManager, never()).notifyNetworkStatus(eq(onlyCell()), 7818 any(List.class), eq(MOBILE_IFNAME), any(List.class)); 7819 reset(mStatsManager); 7820 7821 // Roaming change should update ifaces 7822 mCellAgent.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING); 7823 waitForIdle(); 7824 expectNotifyNetworkStatus(onlyCell(), onlyCell(), MOBILE_IFNAME); 7825 reset(mStatsManager); 7826 7827 // Test VPNs. 7828 final LinkProperties lp = new LinkProperties(); 7829 lp.setInterfaceName(VPN_IFNAME); 7830 7831 mMockVpn.establishForMyUid(lp); 7832 assertUidRangesUpdatedForMyUid(true); 7833 7834 final List<Network> cellAndVpn = List.of(mCellAgent.getNetwork(), mMockVpn.getNetwork()); 7835 7836 // A VPN with default (null) underlying networks sets the underlying network's interfaces... 7837 expectNotifyNetworkStatus(cellAndVpn, cellAndVpn, MOBILE_IFNAME, Process.myUid(), 7838 VPN_IFNAME, List.of(MOBILE_IFNAME)); 7839 7840 // ...and updates them as the default network switches. 7841 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 7842 mWiFiAgent.connect(false); 7843 mWiFiAgent.sendLinkProperties(wifiLp); 7844 final Network[] onlyNull = new Network[]{null}; 7845 final List<Network> wifiAndVpn = List.of(mWiFiAgent.getNetwork(), mMockVpn.getNetwork()); 7846 final List<Network> cellWifiAndVpn = List.of(mCellAgent.getNetwork(), 7847 mWiFiAgent.getNetwork(), mMockVpn.getNetwork()); 7848 final Network[] cellNullAndWifi = 7849 new Network[] { mCellAgent.getNetwork(), null, mWiFiAgent.getNetwork() }; 7850 7851 waitForIdle(); 7852 assertEquals(wifiLp, mService.getActiveLinkProperties()); 7853 expectNotifyNetworkStatus(cellWifiAndVpn, wifiAndVpn, WIFI_IFNAME, Process.myUid(), 7854 VPN_IFNAME, List.of(WIFI_IFNAME)); 7855 reset(mStatsManager); 7856 7857 // A VPN that sets its underlying networks passes the underlying interfaces, and influences 7858 // the default interface sent to NetworkStatsService by virtue of applying to the system 7859 // server UID (or, in this test, to the test's UID). This is the reason for sending 7860 // MOBILE_IFNAME even though the default network is wifi. 7861 // TODO: fix this to pass in the actual default network interface. Whether or not the VPN 7862 // applies to the system server UID should not have any bearing on network stats. 7863 mMockVpn.setUnderlyingNetworks(onlyCell().toArray(new Network[0])); 7864 waitForIdle(); 7865 expectNotifyNetworkStatus(cellWifiAndVpn, wifiAndVpn, MOBILE_IFNAME, Process.myUid(), 7866 VPN_IFNAME, List.of(MOBILE_IFNAME)); 7867 reset(mStatsManager); 7868 7869 mMockVpn.setUnderlyingNetworks(cellAndWifi().toArray(new Network[0])); 7870 waitForIdle(); 7871 expectNotifyNetworkStatus(cellWifiAndVpn, wifiAndVpn, MOBILE_IFNAME, Process.myUid(), 7872 VPN_IFNAME, List.of(MOBILE_IFNAME, WIFI_IFNAME)); 7873 reset(mStatsManager); 7874 7875 // Null underlying networks are ignored. 7876 mMockVpn.setUnderlyingNetworks(cellNullAndWifi); 7877 waitForIdle(); 7878 expectNotifyNetworkStatus(cellWifiAndVpn, wifiAndVpn, MOBILE_IFNAME, Process.myUid(), 7879 VPN_IFNAME, List.of(MOBILE_IFNAME, WIFI_IFNAME)); 7880 reset(mStatsManager); 7881 7882 // If an underlying network disconnects, that interface should no longer be underlying. 7883 // This doesn't actually work because disconnectAndDestroyNetwork only notifies 7884 // NetworkStatsService before the underlying network is actually removed. So the underlying 7885 // network will only be removed if notifyIfacesChangedForNetworkStats is called again. This 7886 // could result in incorrect data usage measurements if the interface used by the 7887 // disconnected network is reused by a system component that does not register an agent for 7888 // it (e.g., tethering). 7889 mCellAgent.disconnect(); 7890 waitForIdle(); 7891 assertNull(mService.getLinkProperties(mCellAgent.getNetwork())); 7892 expectNotifyNetworkStatus(cellWifiAndVpn, wifiAndVpn, MOBILE_IFNAME, Process.myUid(), 7893 VPN_IFNAME, List.of(MOBILE_IFNAME, WIFI_IFNAME)); 7894 7895 // Confirm that we never tell NetworkStatsService that cell is no longer the underlying 7896 // network for the VPN... 7897 verify(mStatsManager, never()).notifyNetworkStatus(any(List.class), 7898 any(List.class), any() /* anyString() doesn't match null */, 7899 argThat(infos -> infos.get(0).getUnderlyingInterfaces().size() == 1 7900 && WIFI_IFNAME.equals(infos.get(0).getUnderlyingInterfaces().get(0)))); 7901 verifyNoMoreInteractions(mStatsManager); 7902 reset(mStatsManager); 7903 7904 // ... but if something else happens that causes notifyIfacesChangedForNetworkStats to be 7905 // called again, it does. For example, connect Ethernet, but with a low score, such that it 7906 // does not become the default network. 7907 mEthernetAgent = new TestNetworkAgentWrapper(TRANSPORT_ETHERNET); 7908 mEthernetAgent.setScore( 7909 new NetworkScore.Builder().setLegacyInt(30).setExiting(true).build()); 7910 mEthernetAgent.connect(false); 7911 waitForIdle(); 7912 verify(mStatsManager).notifyNetworkStatus(any(List.class), 7913 any(List.class), any() /* anyString() doesn't match null */, 7914 argThat(vpnInfos -> vpnInfos.get(0).getUnderlyingInterfaces().size() == 1 7915 && WIFI_IFNAME.equals(vpnInfos.get(0).getUnderlyingInterfaces().get(0)))); 7916 mEthernetAgent.disconnect(); 7917 waitForIdle(); 7918 reset(mStatsManager); 7919 7920 // When a VPN declares no underlying networks (i.e., no connectivity), getAllVpnInfo 7921 // does not return the VPN, so CS does not pass it to NetworkStatsService. This causes 7922 // NetworkStatsFactory#adjustForTunAnd464Xlat not to attempt any VPN data migration, which 7923 // is probably a performance improvement (though it's very unlikely that a VPN would declare 7924 // no underlying networks). 7925 // Also, for the same reason as above, the active interface passed in is null. 7926 mMockVpn.setUnderlyingNetworks(new Network[0]); 7927 waitForIdle(); 7928 expectNotifyNetworkStatus(wifiAndVpn, wifiAndVpn, null); 7929 reset(mStatsManager); 7930 7931 // Specifying only a null underlying network is the same as no networks. 7932 mMockVpn.setUnderlyingNetworks(onlyNull); 7933 waitForIdle(); 7934 expectNotifyNetworkStatus(wifiAndVpn, wifiAndVpn, null); 7935 reset(mStatsManager); 7936 7937 // Specifying networks that are all disconnected is the same as specifying no networks. 7938 mMockVpn.setUnderlyingNetworks(onlyCell().toArray(new Network[0])); 7939 waitForIdle(); 7940 expectNotifyNetworkStatus(wifiAndVpn, wifiAndVpn, null); 7941 reset(mStatsManager); 7942 7943 // Passing in null again means follow the default network again. 7944 mMockVpn.setUnderlyingNetworks(null); 7945 waitForIdle(); 7946 expectNotifyNetworkStatus(wifiAndVpn, wifiAndVpn, WIFI_IFNAME, Process.myUid(), VPN_IFNAME, 7947 List.of(WIFI_IFNAME)); 7948 reset(mStatsManager); 7949 } 7950 7951 @Test 7952 public void testAdminUidsRedacted() throws Exception { 7953 final int[] adminUids = new int[] {Process.myUid() + 1}; 7954 final NetworkCapabilities ncTemplate = new NetworkCapabilities(); 7955 ncTemplate.setAdministratorUids(adminUids); 7956 mCellAgent = 7957 new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, new LinkProperties(), ncTemplate); 7958 mCellAgent.connect(false /* validated */); 7959 7960 // Verify case where caller has permission 7961 mServiceContext.setPermission( 7962 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, PERMISSION_GRANTED); 7963 TestNetworkCallback callback = new TestNetworkCallback(); 7964 mCm.registerDefaultNetworkCallback(callback); 7965 callback.expect(AVAILABLE, mCellAgent); 7966 callback.expectCaps(mCellAgent, c -> Arrays.equals(adminUids, c.getAdministratorUids())); 7967 mCm.unregisterNetworkCallback(callback); 7968 7969 // Verify case where caller does NOT have permission 7970 mServiceContext.setPermission( 7971 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, PERMISSION_DENIED); 7972 mServiceContext.setPermission(NETWORK_STACK, PERMISSION_DENIED); 7973 callback = new TestNetworkCallback(); 7974 mCm.registerDefaultNetworkCallback(callback); 7975 callback.expect(AVAILABLE, mCellAgent); 7976 callback.expectCaps(mCellAgent, c -> c.getAdministratorUids().length == 0); 7977 } 7978 7979 @Test 7980 public void testNonVpnUnderlyingNetworks() throws Exception { 7981 // Ensure wifi and cellular are not torn down. 7982 for (int transport : new int[]{TRANSPORT_CELLULAR, TRANSPORT_WIFI}) { 7983 final NetworkRequest request = new NetworkRequest.Builder() 7984 .addTransportType(transport) 7985 .removeCapability(NET_CAPABILITY_NOT_VCN_MANAGED) 7986 .build(); 7987 mCm.requestNetwork(request, new NetworkCallback()); 7988 } 7989 7990 // Connect a VCN-managed wifi network. 7991 final LinkProperties wifiLp = new LinkProperties(); 7992 wifiLp.setInterfaceName(WIFI_IFNAME); 7993 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, wifiLp); 7994 mWiFiAgent.removeCapability(NET_CAPABILITY_NOT_VCN_MANAGED); 7995 mWiFiAgent.addCapability(NET_CAPABILITY_NOT_METERED); 7996 mWiFiAgent.connect(true /* validated */); 7997 7998 final List<Network> none = List.of(); 7999 expectNotifyNetworkStatus(onlyWifi(), none, null); // Wifi is not the default network 8000 8001 // Create a virtual network based on the wifi network. 8002 final int ownerUid = 10042; 8003 NetworkCapabilities nc = new NetworkCapabilities.Builder() 8004 .setOwnerUid(ownerUid) 8005 .setAdministratorUids(new int[]{ownerUid}) 8006 .build(); 8007 final String vcnIface = "ipsec42"; 8008 final LinkProperties lp = new LinkProperties(); 8009 lp.setInterfaceName(vcnIface); 8010 final TestNetworkAgentWrapper vcn = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, lp, nc); 8011 vcn.setUnderlyingNetworks(List.of(mWiFiAgent.getNetwork())); 8012 vcn.connect(false /* validated */); 8013 8014 final TestNetworkCallback callback = new TestNetworkCallback(); 8015 mCm.registerDefaultNetworkCallback(callback); 8016 callback.expectAvailableCallbacksUnvalidated(vcn); 8017 8018 // The underlying wifi network's capabilities are not propagated to the virtual network, 8019 // but NetworkStatsService is informed of the underlying interface. 8020 nc = mCm.getNetworkCapabilities(vcn.getNetwork()); 8021 assertFalse(nc.hasTransport(TRANSPORT_WIFI)); 8022 assertFalse(nc.hasCapability(NET_CAPABILITY_NOT_METERED)); 8023 final List<Network> onlyVcn = List.of(vcn.getNetwork()); 8024 final List<Network> vcnAndWifi = List.of(vcn.getNetwork(), mWiFiAgent.getNetwork()); 8025 expectNotifyNetworkStatus(vcnAndWifi, onlyVcn, vcnIface, ownerUid, vcnIface, 8026 List.of(WIFI_IFNAME)); 8027 8028 // Add NOT_METERED to the underlying network, check that it is not propagated. 8029 mWiFiAgent.addCapability(NET_CAPABILITY_NOT_METERED); 8030 callback.assertNoCallback(); 8031 nc = mCm.getNetworkCapabilities(vcn.getNetwork()); 8032 assertFalse(nc.hasCapability(NET_CAPABILITY_NOT_METERED)); 8033 8034 // Switch underlying networks. 8035 final LinkProperties cellLp = new LinkProperties(); 8036 cellLp.setInterfaceName(MOBILE_IFNAME); 8037 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp); 8038 mCellAgent.removeCapability(NET_CAPABILITY_NOT_VCN_MANAGED); 8039 mCellAgent.addCapability(NET_CAPABILITY_NOT_ROAMING); 8040 mCellAgent.connect(false /* validated */); 8041 vcn.setUnderlyingNetworks(List.of(mCellAgent.getNetwork())); 8042 8043 // The underlying capability changes do not propagate to the virtual network, but 8044 // NetworkStatsService is informed of the new underlying interface. 8045 callback.assertNoCallback(); 8046 nc = mCm.getNetworkCapabilities(vcn.getNetwork()); 8047 assertFalse(nc.hasTransport(TRANSPORT_WIFI)); 8048 assertFalse(nc.hasCapability(NET_CAPABILITY_NOT_ROAMING)); 8049 final List<Network> vcnWifiAndCell = List.of(vcn.getNetwork(), 8050 mWiFiAgent.getNetwork(), mCellAgent.getNetwork()); 8051 expectNotifyNetworkStatus(vcnWifiAndCell, onlyVcn, vcnIface, ownerUid, vcnIface, 8052 List.of(MOBILE_IFNAME)); 8053 } 8054 8055 @Test 8056 public void testBasicDnsConfigurationPushed() throws Exception { 8057 setPrivateDnsSettings(PRIVATE_DNS_MODE_OPPORTUNISTIC, "ignored.example.com"); 8058 8059 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 8060 final int netId = mCellAgent.getNetwork().netId; 8061 waitForIdle(); 8062 if (mService.shouldCreateNetworksImmediately()) { 8063 verify(mMockDnsResolver, times(1)).createNetworkCache(netId); 8064 } else { 8065 verify(mMockDnsResolver, never()).setResolverConfiguration(any()); 8066 } 8067 8068 final LinkProperties cellLp = new LinkProperties(); 8069 cellLp.setInterfaceName(MOBILE_IFNAME); 8070 // Add IPv4 and IPv6 default routes, because DNS-over-TLS code does 8071 // "is-reachable" testing in order to not program netd with unreachable 8072 // nameservers that it might try repeated to validate. 8073 cellLp.addLinkAddress(new LinkAddress("192.0.2.4/24")); 8074 cellLp.addRoute(new RouteInfo((IpPrefix) null, InetAddress.getByName("192.0.2.4"), 8075 MOBILE_IFNAME)); 8076 cellLp.addLinkAddress(new LinkAddress("2001:db8:1::1/64")); 8077 cellLp.addRoute(new RouteInfo((IpPrefix) null, InetAddress.getByName("2001:db8:1::1"), 8078 MOBILE_IFNAME)); 8079 mCellAgent.sendLinkProperties(cellLp); 8080 mCellAgent.connect(false); 8081 waitForIdle(); 8082 if (!mService.shouldCreateNetworksImmediately()) { 8083 // CS tells dnsresolver about the empty DNS config for this network. 8084 verify(mMockDnsResolver, times(1)).createNetworkCache(netId); 8085 } 8086 verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration(any()); 8087 8088 verifyNoMoreInteractions(mMockDnsResolver); 8089 reset(mMockDnsResolver); 8090 8091 cellLp.addDnsServer(InetAddress.getByName("2001:db8::1")); 8092 mCellAgent.sendLinkProperties(cellLp); 8093 waitForIdle(); 8094 verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration( 8095 mResolverParamsParcelCaptor.capture()); 8096 ResolverParamsParcel resolvrParams = mResolverParamsParcelCaptor.getValue(); 8097 assertEquals(1, resolvrParams.servers.length); 8098 assertTrue(CollectionUtils.contains(resolvrParams.servers, "2001:db8::1")); 8099 // Opportunistic mode. 8100 assertTrue(CollectionUtils.contains(resolvrParams.tlsServers, "2001:db8::1")); 8101 reset(mMockDnsResolver); 8102 8103 cellLp.addDnsServer(InetAddress.getByName("192.0.2.1")); 8104 mCellAgent.sendLinkProperties(cellLp); 8105 waitForIdle(); 8106 verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration( 8107 mResolverParamsParcelCaptor.capture()); 8108 resolvrParams = mResolverParamsParcelCaptor.getValue(); 8109 assertEquals(2, resolvrParams.servers.length); 8110 assertTrue(new ArraySet<>(resolvrParams.servers).containsAll( 8111 asList("2001:db8::1", "192.0.2.1"))); 8112 // Opportunistic mode. 8113 assertEquals(2, resolvrParams.tlsServers.length); 8114 assertTrue(new ArraySet<>(resolvrParams.tlsServers).containsAll( 8115 asList("2001:db8::1", "192.0.2.1"))); 8116 reset(mMockDnsResolver); 8117 8118 final String TLS_SPECIFIER = "tls.example.com"; 8119 final String TLS_SERVER6 = "2001:db8:53::53"; 8120 final InetAddress[] TLS_IPS = new InetAddress[]{ InetAddress.getByName(TLS_SERVER6) }; 8121 final String[] TLS_SERVERS = new String[]{ TLS_SERVER6 }; 8122 mCellAgent.mNmCallbacks.notifyPrivateDnsConfigResolved( 8123 new PrivateDnsConfig(TLS_SPECIFIER, TLS_IPS).toParcel()); 8124 8125 waitForIdle(); 8126 verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration( 8127 mResolverParamsParcelCaptor.capture()); 8128 resolvrParams = mResolverParamsParcelCaptor.getValue(); 8129 assertEquals(2, resolvrParams.servers.length); 8130 assertTrue(new ArraySet<>(resolvrParams.servers).containsAll( 8131 asList("2001:db8::1", "192.0.2.1"))); 8132 reset(mMockDnsResolver); 8133 } 8134 8135 @Test 8136 public void testDnsConfigurationTransTypesPushed() throws Exception { 8137 final NetworkRequest request = new NetworkRequest.Builder() 8138 .clearCapabilities().addCapability(NET_CAPABILITY_INTERNET) 8139 .build(); 8140 final TestNetworkCallback callback = new TestNetworkCallback(); 8141 mCm.registerNetworkCallback(request, callback); 8142 8143 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 8144 mWiFiAgent.connect(false); 8145 callback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 8146 verify(mMockDnsResolver, times(1)).createNetworkCache(eq(mWiFiAgent.getNetwork().netId)); 8147 verify(mMockDnsResolver, times(2)).setResolverConfiguration( 8148 mResolverParamsParcelCaptor.capture()); 8149 final ResolverParamsParcel resolverParams = mResolverParamsParcelCaptor.getValue(); 8150 assertContainsExactly(resolverParams.transportTypes, TRANSPORT_WIFI); 8151 reset(mMockDnsResolver); 8152 } 8153 8154 @Test 8155 public void testPrivateDnsNotification() throws Exception { 8156 NetworkRequest request = new NetworkRequest.Builder() 8157 .clearCapabilities().addCapability(NET_CAPABILITY_INTERNET) 8158 .build(); 8159 TestNetworkCallback callback = new TestNetworkCallback(); 8160 mCm.registerNetworkCallback(request, callback); 8161 // Bring up wifi. 8162 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 8163 mWiFiAgent.connect(false); 8164 callback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 8165 // Private DNS resolution failed, checking if the notification will be shown or not. 8166 mWiFiAgent.setNetworkInvalid(true /* invalidBecauseOfPrivateDns */); 8167 mWiFiAgent.mNetworkMonitor.forceReevaluation(Process.myUid()); 8168 waitForIdle(); 8169 // If network validation failed, NetworkMonitor will re-evaluate the network. 8170 // ConnectivityService should filter the redundant notification. This part is trying to 8171 // simulate that situation and check if ConnectivityService could filter that case. 8172 mWiFiAgent.mNetworkMonitor.forceReevaluation(Process.myUid()); 8173 waitForIdle(); 8174 verify(mNotificationManager, timeout(TIMEOUT_MS).times(1)).notify(anyString(), 8175 eq(NotificationType.PRIVATE_DNS_BROKEN.eventId), any()); 8176 // If private DNS resolution successful, the PRIVATE_DNS_BROKEN notification shouldn't be 8177 // shown. 8178 mWiFiAgent.setNetworkValid(true /* privateDnsProbeSent */); 8179 mWiFiAgent.mNetworkMonitor.forceReevaluation(Process.myUid()); 8180 waitForIdle(); 8181 verify(mNotificationManager, timeout(TIMEOUT_MS).times(1)).cancel(anyString(), 8182 eq(NotificationType.PRIVATE_DNS_BROKEN.eventId)); 8183 // If private DNS resolution failed again, the PRIVATE_DNS_BROKEN notification should be 8184 // shown again. 8185 mWiFiAgent.setNetworkInvalid(true /* invalidBecauseOfPrivateDns */); 8186 mWiFiAgent.mNetworkMonitor.forceReevaluation(Process.myUid()); 8187 waitForIdle(); 8188 verify(mNotificationManager, timeout(TIMEOUT_MS).times(2)).notify(anyString(), 8189 eq(NotificationType.PRIVATE_DNS_BROKEN.eventId), any()); 8190 } 8191 8192 @Test 8193 public void testPrivateDnsSettingsChange() throws Exception { 8194 // The default on Android is opportunistic mode ("Automatic"). 8195 setPrivateDnsSettings(PRIVATE_DNS_MODE_OPPORTUNISTIC, "ignored.example.com"); 8196 8197 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback(); 8198 final NetworkRequest cellRequest = new NetworkRequest.Builder() 8199 .addTransportType(TRANSPORT_CELLULAR).build(); 8200 mCm.requestNetwork(cellRequest, cellNetworkCallback); 8201 8202 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 8203 final int netId = mCellAgent.getNetwork().netId; 8204 waitForIdle(); 8205 if (mService.shouldCreateNetworksImmediately()) { 8206 verify(mMockDnsResolver, times(1)).createNetworkCache(netId); 8207 } else { 8208 verify(mMockDnsResolver, never()).setResolverConfiguration(any()); 8209 } 8210 8211 final LinkProperties cellLp = new LinkProperties(); 8212 cellLp.setInterfaceName(MOBILE_IFNAME); 8213 // Add IPv4 and IPv6 default routes, because DNS-over-TLS code does 8214 // "is-reachable" testing in order to not program netd with unreachable 8215 // nameservers that it might try repeated to validate. 8216 cellLp.addLinkAddress(new LinkAddress("192.0.2.4/24")); 8217 cellLp.addRoute(new RouteInfo((IpPrefix) null, InetAddress.getByName("192.0.2.4"), 8218 MOBILE_IFNAME)); 8219 cellLp.addLinkAddress(new LinkAddress("2001:db8:1::1/64")); 8220 cellLp.addRoute(new RouteInfo((IpPrefix) null, InetAddress.getByName("2001:db8:1::1"), 8221 MOBILE_IFNAME)); 8222 cellLp.addDnsServer(InetAddress.getByName("2001:db8::1")); 8223 cellLp.addDnsServer(InetAddress.getByName("192.0.2.1")); 8224 8225 mCellAgent.sendLinkProperties(cellLp); 8226 mCellAgent.connect(false); 8227 waitForIdle(); 8228 if (!mService.shouldCreateNetworksImmediately()) { 8229 verify(mMockDnsResolver, times(1)).createNetworkCache(netId); 8230 } 8231 verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration( 8232 mResolverParamsParcelCaptor.capture()); 8233 ResolverParamsParcel resolvrParams = mResolverParamsParcelCaptor.getValue(); 8234 assertEquals(2, resolvrParams.tlsServers.length); 8235 assertTrue(new ArraySet<>(resolvrParams.tlsServers).containsAll( 8236 asList("2001:db8::1", "192.0.2.1"))); 8237 // Opportunistic mode. 8238 assertEquals(2, resolvrParams.tlsServers.length); 8239 assertTrue(new ArraySet<>(resolvrParams.tlsServers).containsAll( 8240 asList("2001:db8::1", "192.0.2.1"))); 8241 verifyNoMoreInteractions(mMockDnsResolver); 8242 reset(mMockDnsResolver); 8243 cellNetworkCallback.expect(AVAILABLE, mCellAgent); 8244 cellNetworkCallback.expect(NETWORK_CAPS_UPDATED, mCellAgent); 8245 CallbackEntry.LinkPropertiesChanged cbi = cellNetworkCallback.expect( 8246 LINK_PROPERTIES_CHANGED, mCellAgent); 8247 cellNetworkCallback.expect(BLOCKED_STATUS, mCellAgent); 8248 cellNetworkCallback.assertNoCallback(); 8249 assertFalse(cbi.getLp().isPrivateDnsActive()); 8250 assertNull(cbi.getLp().getPrivateDnsServerName()); 8251 8252 setPrivateDnsSettings(PRIVATE_DNS_MODE_OFF, "ignored.example.com"); 8253 verify(mMockDnsResolver, times(1)).setResolverConfiguration( 8254 mResolverParamsParcelCaptor.capture()); 8255 resolvrParams = mResolverParamsParcelCaptor.getValue(); 8256 assertEquals(2, resolvrParams.servers.length); 8257 assertTrue(new ArraySet<>(resolvrParams.servers).containsAll( 8258 asList("2001:db8::1", "192.0.2.1"))); 8259 reset(mMockDnsResolver); 8260 cellNetworkCallback.assertNoCallback(); 8261 8262 setPrivateDnsSettings(PRIVATE_DNS_MODE_OPPORTUNISTIC, "ignored.example.com"); 8263 verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration( 8264 mResolverParamsParcelCaptor.capture()); 8265 resolvrParams = mResolverParamsParcelCaptor.getValue(); 8266 assertEquals(2, resolvrParams.servers.length); 8267 assertTrue(new ArraySet<>(resolvrParams.servers).containsAll( 8268 asList("2001:db8::1", "192.0.2.1"))); 8269 assertEquals(2, resolvrParams.tlsServers.length); 8270 assertTrue(new ArraySet<>(resolvrParams.tlsServers).containsAll( 8271 asList("2001:db8::1", "192.0.2.1"))); 8272 reset(mMockDnsResolver); 8273 cellNetworkCallback.assertNoCallback(); 8274 8275 setPrivateDnsSettings(PRIVATE_DNS_MODE_PROVIDER_HOSTNAME, "strict.example.com"); 8276 // Can't test dns configuration for strict mode without properly mocking 8277 // out the DNS lookups, but can test that LinkProperties is updated. 8278 cbi = cellNetworkCallback.expect(LINK_PROPERTIES_CHANGED, mCellAgent); 8279 cellNetworkCallback.assertNoCallback(); 8280 assertTrue(cbi.getLp().isPrivateDnsActive()); 8281 assertEquals("strict.example.com", cbi.getLp().getPrivateDnsServerName()); 8282 } 8283 8284 private PrivateDnsValidationEventParcel makePrivateDnsValidationEvent( 8285 final int netId, final String ipAddress, final String hostname, final int validation) { 8286 final PrivateDnsValidationEventParcel event = new PrivateDnsValidationEventParcel(); 8287 event.netId = netId; 8288 event.ipAddress = ipAddress; 8289 event.hostname = hostname; 8290 event.validation = validation; 8291 return event; 8292 } 8293 8294 @Test 8295 public void testLinkPropertiesWithPrivateDnsValidationEvents() throws Exception { 8296 // The default on Android is opportunistic mode ("Automatic"). 8297 setPrivateDnsSettings(PRIVATE_DNS_MODE_OPPORTUNISTIC, "ignored.example.com"); 8298 8299 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback(); 8300 final NetworkRequest cellRequest = new NetworkRequest.Builder() 8301 .addTransportType(TRANSPORT_CELLULAR).build(); 8302 mCm.requestNetwork(cellRequest, cellNetworkCallback); 8303 8304 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 8305 waitForIdle(); 8306 LinkProperties lp = new LinkProperties(); 8307 mCellAgent.sendLinkProperties(lp); 8308 mCellAgent.connect(false); 8309 waitForIdle(); 8310 cellNetworkCallback.expect(AVAILABLE, mCellAgent); 8311 cellNetworkCallback.expect(NETWORK_CAPS_UPDATED, mCellAgent); 8312 CallbackEntry.LinkPropertiesChanged cbi = cellNetworkCallback.expect( 8313 LINK_PROPERTIES_CHANGED, mCellAgent); 8314 cellNetworkCallback.expect(BLOCKED_STATUS, mCellAgent); 8315 cellNetworkCallback.assertNoCallback(); 8316 assertFalse(cbi.getLp().isPrivateDnsActive()); 8317 assertNull(cbi.getLp().getPrivateDnsServerName()); 8318 Set<InetAddress> dnsServers = new HashSet<>(); 8319 checkDnsServers(cbi.getLp(), dnsServers); 8320 8321 // Send a validation event for a server that is not part of the current 8322 // resolver config. The validation event should be ignored. 8323 mService.mResolverUnsolEventCallback.onPrivateDnsValidationEvent( 8324 makePrivateDnsValidationEvent(mCellAgent.getNetwork().netId, "", 8325 "145.100.185.18", VALIDATION_RESULT_SUCCESS)); 8326 cellNetworkCallback.assertNoCallback(); 8327 8328 // Add a dns server to the LinkProperties. 8329 LinkProperties lp2 = new LinkProperties(lp); 8330 lp2.addDnsServer(InetAddress.getByName("145.100.185.16")); 8331 mCellAgent.sendLinkProperties(lp2); 8332 cbi = cellNetworkCallback.expect(LINK_PROPERTIES_CHANGED, mCellAgent); 8333 cellNetworkCallback.assertNoCallback(); 8334 assertFalse(cbi.getLp().isPrivateDnsActive()); 8335 assertNull(cbi.getLp().getPrivateDnsServerName()); 8336 dnsServers.add(InetAddress.getByName("145.100.185.16")); 8337 checkDnsServers(cbi.getLp(), dnsServers); 8338 8339 // Send a validation event containing a hostname that is not part of 8340 // the current resolver config. The validation event should be ignored. 8341 mService.mResolverUnsolEventCallback.onPrivateDnsValidationEvent( 8342 makePrivateDnsValidationEvent(mCellAgent.getNetwork().netId, 8343 "145.100.185.16", "hostname", VALIDATION_RESULT_SUCCESS)); 8344 cellNetworkCallback.assertNoCallback(); 8345 8346 // Send a validation event where validation failed. 8347 mService.mResolverUnsolEventCallback.onPrivateDnsValidationEvent( 8348 makePrivateDnsValidationEvent(mCellAgent.getNetwork().netId, 8349 "145.100.185.16", "", VALIDATION_RESULT_FAILURE)); 8350 cellNetworkCallback.assertNoCallback(); 8351 8352 // Send a validation event where validation succeeded for a server in 8353 // the current resolver config. A LinkProperties callback with updated 8354 // private dns fields should be sent. 8355 mService.mResolverUnsolEventCallback.onPrivateDnsValidationEvent( 8356 makePrivateDnsValidationEvent(mCellAgent.getNetwork().netId, 8357 "145.100.185.16", "", VALIDATION_RESULT_SUCCESS)); 8358 cbi = cellNetworkCallback.expect(LINK_PROPERTIES_CHANGED, mCellAgent); 8359 cellNetworkCallback.assertNoCallback(); 8360 assertTrue(cbi.getLp().isPrivateDnsActive()); 8361 assertNull(cbi.getLp().getPrivateDnsServerName()); 8362 checkDnsServers(cbi.getLp(), dnsServers); 8363 8364 // The private dns fields in LinkProperties should be preserved when 8365 // the network agent sends unrelated changes. 8366 LinkProperties lp3 = new LinkProperties(lp2); 8367 lp3.setMtu(1300); 8368 mCellAgent.sendLinkProperties(lp3); 8369 cbi = cellNetworkCallback.expect(LINK_PROPERTIES_CHANGED, mCellAgent); 8370 cellNetworkCallback.assertNoCallback(); 8371 assertTrue(cbi.getLp().isPrivateDnsActive()); 8372 assertNull(cbi.getLp().getPrivateDnsServerName()); 8373 checkDnsServers(cbi.getLp(), dnsServers); 8374 assertEquals(1300, cbi.getLp().getMtu()); 8375 8376 // Removing the only validated server should affect the private dns 8377 // fields in LinkProperties. 8378 LinkProperties lp4 = new LinkProperties(lp3); 8379 lp4.removeDnsServer(InetAddress.getByName("145.100.185.16")); 8380 mCellAgent.sendLinkProperties(lp4); 8381 cbi = cellNetworkCallback.expect(LINK_PROPERTIES_CHANGED, mCellAgent); 8382 cellNetworkCallback.assertNoCallback(); 8383 assertFalse(cbi.getLp().isPrivateDnsActive()); 8384 assertNull(cbi.getLp().getPrivateDnsServerName()); 8385 dnsServers.remove(InetAddress.getByName("145.100.185.16")); 8386 checkDnsServers(cbi.getLp(), dnsServers); 8387 assertEquals(1300, cbi.getLp().getMtu()); 8388 } 8389 8390 private void checkDirectlyConnectedRoutes(Object callbackObj, 8391 Collection<LinkAddress> linkAddresses, Collection<RouteInfo> otherRoutes) { 8392 assertTrue(callbackObj instanceof LinkProperties); 8393 LinkProperties lp = (LinkProperties) callbackObj; 8394 8395 Set<RouteInfo> expectedRoutes = new ArraySet<>(); 8396 expectedRoutes.addAll(otherRoutes); 8397 for (LinkAddress address : linkAddresses) { 8398 RouteInfo localRoute = new RouteInfo(address, null, lp.getInterfaceName()); 8399 // Duplicates in linkAddresses are considered failures 8400 assertTrue(expectedRoutes.add(localRoute)); 8401 } 8402 List<RouteInfo> observedRoutes = lp.getRoutes(); 8403 assertEquals(expectedRoutes.size(), observedRoutes.size()); 8404 assertTrue(observedRoutes.containsAll(expectedRoutes)); 8405 } 8406 8407 private static void checkDnsServers(Object callbackObj, Set<InetAddress> dnsServers) { 8408 assertTrue(callbackObj instanceof LinkProperties); 8409 LinkProperties lp = (LinkProperties) callbackObj; 8410 assertEquals(dnsServers.size(), lp.getDnsServers().size()); 8411 assertTrue(lp.getDnsServers().containsAll(dnsServers)); 8412 } 8413 8414 @Test 8415 public void testApplyUnderlyingCapabilities() throws Exception { 8416 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 8417 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 8418 mCellAgent.connect(false /* validated */); 8419 mWiFiAgent.connect(false /* validated */); 8420 8421 final NetworkCapabilities cellNc = new NetworkCapabilities() 8422 .addTransportType(TRANSPORT_CELLULAR) 8423 .addCapability(NET_CAPABILITY_INTERNET) 8424 .addCapability(NET_CAPABILITY_NOT_CONGESTED) 8425 .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED) 8426 .setLinkDownstreamBandwidthKbps(10); 8427 final NetworkCapabilities wifiNc = new NetworkCapabilities() 8428 .addTransportType(TRANSPORT_WIFI) 8429 .addCapability(NET_CAPABILITY_INTERNET) 8430 .addCapability(NET_CAPABILITY_NOT_METERED) 8431 .addCapability(NET_CAPABILITY_NOT_ROAMING) 8432 .addCapability(NET_CAPABILITY_NOT_CONGESTED) 8433 .addCapability(NET_CAPABILITY_NOT_SUSPENDED) 8434 .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED) 8435 .setLinkUpstreamBandwidthKbps(20); 8436 mCellAgent.setNetworkCapabilities(cellNc, true /* sendToConnectivityService */); 8437 mWiFiAgent.setNetworkCapabilities(wifiNc, true /* sendToConnectivityService */); 8438 waitForIdle(); 8439 8440 final Network mobile = mCellAgent.getNetwork(); 8441 final Network wifi = mWiFiAgent.getNetwork(); 8442 8443 final NetworkCapabilities initialCaps = new NetworkCapabilities(); 8444 initialCaps.addTransportType(TRANSPORT_VPN); 8445 initialCaps.addCapability(NET_CAPABILITY_INTERNET); 8446 initialCaps.removeCapability(NET_CAPABILITY_NOT_VPN); 8447 final ArrayList<Network> emptyUnderlyingNetworks = new ArrayList<Network>(); 8448 final ArrayList<Network> underlyingNetworksContainMobile = new ArrayList<Network>(); 8449 underlyingNetworksContainMobile.add(mobile); 8450 final ArrayList<Network> underlyingNetworksContainWifi = new ArrayList<Network>(); 8451 underlyingNetworksContainWifi.add(wifi); 8452 final ArrayList<Network> underlyingNetworksContainMobileAndMobile = 8453 new ArrayList<Network>(); 8454 underlyingNetworksContainMobileAndMobile.add(mobile); 8455 underlyingNetworksContainMobileAndMobile.add(wifi); 8456 8457 final NetworkCapabilities withNoUnderlying = new NetworkCapabilities(); 8458 withNoUnderlying.addCapability(NET_CAPABILITY_INTERNET); 8459 withNoUnderlying.addCapability(NET_CAPABILITY_NOT_CONGESTED); 8460 withNoUnderlying.addCapability(NET_CAPABILITY_NOT_ROAMING); 8461 withNoUnderlying.addCapability(NET_CAPABILITY_NOT_SUSPENDED); 8462 withNoUnderlying.addTransportType(TRANSPORT_VPN); 8463 withNoUnderlying.removeCapability(NET_CAPABILITY_NOT_VPN); 8464 withNoUnderlying.setUnderlyingNetworks(emptyUnderlyingNetworks); 8465 8466 final NetworkCapabilities withMobileUnderlying = new NetworkCapabilities(withNoUnderlying); 8467 withMobileUnderlying.addTransportType(TRANSPORT_CELLULAR); 8468 withMobileUnderlying.removeCapability(NET_CAPABILITY_NOT_ROAMING); 8469 withMobileUnderlying.removeCapability(NET_CAPABILITY_NOT_SUSPENDED); 8470 withMobileUnderlying.setLinkDownstreamBandwidthKbps(10); 8471 withMobileUnderlying.setUnderlyingNetworks(underlyingNetworksContainMobile); 8472 8473 final NetworkCapabilities withWifiUnderlying = new NetworkCapabilities(withNoUnderlying); 8474 withWifiUnderlying.addTransportType(TRANSPORT_WIFI); 8475 withWifiUnderlying.addCapability(NET_CAPABILITY_NOT_METERED); 8476 withWifiUnderlying.setLinkUpstreamBandwidthKbps(20); 8477 withWifiUnderlying.setUnderlyingNetworks(underlyingNetworksContainWifi); 8478 8479 final NetworkCapabilities withWifiAndMobileUnderlying = 8480 new NetworkCapabilities(withNoUnderlying); 8481 withWifiAndMobileUnderlying.addTransportType(TRANSPORT_CELLULAR); 8482 withWifiAndMobileUnderlying.addTransportType(TRANSPORT_WIFI); 8483 withWifiAndMobileUnderlying.removeCapability(NET_CAPABILITY_NOT_METERED); 8484 withWifiAndMobileUnderlying.removeCapability(NET_CAPABILITY_NOT_ROAMING); 8485 withWifiAndMobileUnderlying.setLinkDownstreamBandwidthKbps(10); 8486 withWifiAndMobileUnderlying.setLinkUpstreamBandwidthKbps(20); 8487 withWifiAndMobileUnderlying.setUnderlyingNetworks(underlyingNetworksContainMobileAndMobile); 8488 8489 final NetworkCapabilities initialCapsNotMetered = new NetworkCapabilities(initialCaps); 8490 initialCapsNotMetered.addCapability(NET_CAPABILITY_NOT_METERED); 8491 8492 NetworkCapabilities caps = new NetworkCapabilities(initialCaps); 8493 mService.applyUnderlyingCapabilities(new Network[]{}, initialCapsNotMetered, caps); 8494 assertEquals(withNoUnderlying, caps); 8495 assertEquals(0, new ArrayList<>(caps.getUnderlyingNetworks()).size()); 8496 8497 caps = new NetworkCapabilities(initialCaps); 8498 mService.applyUnderlyingCapabilities(new Network[]{null}, initialCapsNotMetered, caps); 8499 assertEquals(withNoUnderlying, caps); 8500 assertEquals(0, new ArrayList<>(caps.getUnderlyingNetworks()).size()); 8501 8502 caps = new NetworkCapabilities(initialCaps); 8503 mService.applyUnderlyingCapabilities(new Network[]{mobile}, initialCapsNotMetered, caps); 8504 assertEquals(withMobileUnderlying, caps); 8505 assertEquals(1, new ArrayList<>(caps.getUnderlyingNetworks()).size()); 8506 assertEquals(mobile, new ArrayList<>(caps.getUnderlyingNetworks()).get(0)); 8507 8508 caps = new NetworkCapabilities(initialCaps); 8509 mService.applyUnderlyingCapabilities(new Network[]{wifi}, initialCapsNotMetered, caps); 8510 assertEquals(withWifiUnderlying, caps); 8511 assertEquals(1, new ArrayList<>(caps.getUnderlyingNetworks()).size()); 8512 assertEquals(wifi, new ArrayList<>(caps.getUnderlyingNetworks()).get(0)); 8513 8514 withWifiUnderlying.removeCapability(NET_CAPABILITY_NOT_METERED); 8515 caps = new NetworkCapabilities(initialCaps); 8516 mService.applyUnderlyingCapabilities(new Network[]{wifi}, initialCaps, caps); 8517 assertEquals(withWifiUnderlying, caps); 8518 assertEquals(1, new ArrayList<>(caps.getUnderlyingNetworks()).size()); 8519 assertEquals(wifi, new ArrayList<>(caps.getUnderlyingNetworks()).get(0)); 8520 8521 caps = new NetworkCapabilities(initialCaps); 8522 mService.applyUnderlyingCapabilities(new Network[]{mobile, wifi}, initialCaps, caps); 8523 assertEquals(withWifiAndMobileUnderlying, caps); 8524 assertEquals(2, new ArrayList<>(caps.getUnderlyingNetworks()).size()); 8525 assertEquals(mobile, new ArrayList<>(caps.getUnderlyingNetworks()).get(0)); 8526 assertEquals(wifi, new ArrayList<>(caps.getUnderlyingNetworks()).get(1)); 8527 8528 withWifiUnderlying.addCapability(NET_CAPABILITY_NOT_METERED); 8529 caps = new NetworkCapabilities(initialCaps); 8530 mService.applyUnderlyingCapabilities(new Network[]{null, mobile, null, wifi}, 8531 initialCapsNotMetered, caps); 8532 assertEquals(withWifiAndMobileUnderlying, caps); 8533 assertEquals(2, new ArrayList<>(caps.getUnderlyingNetworks()).size()); 8534 assertEquals(mobile, new ArrayList<>(caps.getUnderlyingNetworks()).get(0)); 8535 assertEquals(wifi, new ArrayList<>(caps.getUnderlyingNetworks()).get(1)); 8536 8537 caps = new NetworkCapabilities(initialCaps); 8538 mService.applyUnderlyingCapabilities(new Network[]{null, mobile, null, wifi}, 8539 initialCapsNotMetered, caps); 8540 assertEquals(withWifiAndMobileUnderlying, caps); 8541 assertEquals(2, new ArrayList<>(caps.getUnderlyingNetworks()).size()); 8542 assertEquals(mobile, new ArrayList<>(caps.getUnderlyingNetworks()).get(0)); 8543 assertEquals(wifi, new ArrayList<>(caps.getUnderlyingNetworks()).get(1)); 8544 8545 caps = new NetworkCapabilities(initialCaps); 8546 mService.applyUnderlyingCapabilities(null, initialCapsNotMetered, caps); 8547 assertEquals(withWifiUnderlying, caps); 8548 assertEquals(1, new ArrayList<>(caps.getUnderlyingNetworks()).size()); 8549 assertEquals(wifi, new ArrayList<>(caps.getUnderlyingNetworks()).get(0)); 8550 } 8551 8552 @Test 8553 public void testVpnConnectDisconnectUnderlyingNetwork() throws Exception { 8554 final TestNetworkCallback callback = new TestNetworkCallback(); 8555 final NetworkRequest request = new NetworkRequest.Builder() 8556 .removeCapability(NET_CAPABILITY_NOT_VPN).build(); 8557 8558 runAsShell(NETWORK_SETTINGS, () -> { 8559 mCm.registerNetworkCallback(request, callback); 8560 8561 // Bring up a VPN that specifies an underlying network that does not exist yet. 8562 // Note: it's sort of meaningless for a VPN app to declare a network that doesn't exist 8563 // yet, (and doing so is difficult without using reflection) but it's good to test that 8564 // the code behaves approximately correctly. 8565 mMockVpn.establishForMyUid(false, true, false); 8566 callback.expectAvailableCallbacksUnvalidated(mMockVpn); 8567 assertUidRangesUpdatedForMyUid(true); 8568 final Network wifiNetwork = new Network(mNetIdManager.peekNextNetId()); 8569 mMockVpn.setUnderlyingNetworks(new Network[]{wifiNetwork}); 8570 // onCapabilitiesChanged() should be called because 8571 // NetworkCapabilities#mUnderlyingNetworks is updated. 8572 final NetworkCapabilities vpnNc1 = callback.expectCaps(mMockVpn); 8573 // Since the wifi network hasn't brought up, 8574 // ConnectivityService#applyUnderlyingCapabilities cannot find it. Update 8575 // NetworkCapabilities#mUnderlyingNetworks to an empty array, and it will be updated to 8576 // the correct underlying networks once the wifi network brings up. But this case 8577 // shouldn't happen in reality since no one could get the network which hasn't brought 8578 // up. For the empty array of underlying networks, it should be happened for 2 cases, 8579 // the first one is that the VPN app declares an empty array for its underlying 8580 // networks, the second one is that the underlying networks are torn down. 8581 // 8582 // It shouldn't be null since the null value means the underlying networks of this 8583 // network should follow the default network. 8584 final ArrayList<Network> underlyingNetwork = new ArrayList<>(); 8585 assertEquals(underlyingNetwork, vpnNc1.getUnderlyingNetworks()); 8586 // Since the wifi network isn't exist, applyUnderlyingCapabilities() 8587 assertTrue(mCm.getNetworkCapabilities(mMockVpn.getNetwork()) 8588 .hasTransport(TRANSPORT_VPN)); 8589 assertFalse(mCm.getNetworkCapabilities(mMockVpn.getNetwork()) 8590 .hasTransport(TRANSPORT_WIFI)); 8591 8592 // Make that underlying network connect, and expect to see its capabilities immediately 8593 // reflected in the VPN's capabilities. 8594 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 8595 assertEquals(wifiNetwork, mWiFiAgent.getNetwork()); 8596 mWiFiAgent.connect(false); 8597 // TODO: the callback for the VPN happens before any callbacks are called for the wifi 8598 // network that has just connected. There appear to be two issues here: 8599 // 1. The VPN code will accept an underlying network as soon as getNetworkCapabilities() 8600 // for it returns non-null (which happens very early, during 8601 // handleRegisterNetworkAgent). 8602 // This is not correct because that that point the network is not connected and 8603 // cannot pass any traffic. 8604 // 2. When a network connects, updateNetworkInfo propagates underlying network 8605 // capabilities before rematching networks. 8606 // Given that this scenario can't really happen, this is probably fine for now. 8607 final NetworkCapabilities vpnNc2 = callback.expectCaps(mMockVpn); 8608 // The wifi network is brought up, NetworkCapabilities#mUnderlyingNetworks is updated to 8609 // it. 8610 underlyingNetwork.add(wifiNetwork); 8611 assertEquals(underlyingNetwork, vpnNc2.getUnderlyingNetworks()); 8612 callback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 8613 assertTrue(mCm.getNetworkCapabilities(mMockVpn.getNetwork()) 8614 .hasTransport(TRANSPORT_VPN)); 8615 assertTrue(mCm.getNetworkCapabilities(mMockVpn.getNetwork()) 8616 .hasTransport(TRANSPORT_WIFI)); 8617 8618 // Disconnect the network, and expect to see the VPN capabilities change accordingly. 8619 mWiFiAgent.disconnect(); 8620 callback.expect(LOST, mWiFiAgent); 8621 callback.expectCaps(mMockVpn, c -> c.getTransportTypes().length == 1 8622 && c.hasTransport(TRANSPORT_VPN)); 8623 8624 mMockVpn.disconnect(); 8625 mCm.unregisterNetworkCallback(callback); 8626 }); 8627 } 8628 8629 private void assertGetNetworkInfoOfGetActiveNetworkIsConnected(boolean expectedConnectivity) { 8630 // What Chromium used to do before https://chromium-review.googlesource.com/2605304 8631 assertEquals("Unexpected result for getActiveNetworkInfo(getActiveNetwork())", 8632 expectedConnectivity, mCm.getNetworkInfo(mCm.getActiveNetwork()).isConnected()); 8633 } 8634 8635 @Test 8636 public void testVpnUnderlyingNetworkSuspended() throws Exception { 8637 final TestNetworkCallback callback = new TestNetworkCallback(); 8638 mCm.registerDefaultNetworkCallback(callback); 8639 8640 // Connect a VPN. 8641 mMockVpn.establishForMyUid(false /* validated */, true /* hasInternet */, 8642 false /* privateDnsProbeSent */); 8643 callback.expectAvailableCallbacksUnvalidated(mMockVpn); 8644 8645 // Connect cellular data. 8646 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 8647 mCellAgent.connect(false /* validated */); 8648 callback.expectCaps(mMockVpn, c -> c.hasCapability(NET_CAPABILITY_NOT_SUSPENDED) 8649 && c.hasTransport(TRANSPORT_CELLULAR)); 8650 callback.assertNoCallback(); 8651 8652 assertTrue(mCm.getNetworkCapabilities(mMockVpn.getNetwork()) 8653 .hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 8654 assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 8655 assertNetworkInfo(TYPE_WIFI, DetailedState.DISCONNECTED); 8656 assertNetworkInfo(TYPE_VPN, DetailedState.CONNECTED); 8657 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 8658 assertGetNetworkInfoOfGetActiveNetworkIsConnected(true); 8659 8660 // Suspend the cellular network and expect the VPN to be suspended. 8661 mCellAgent.suspend(); 8662 callback.expectCaps(mMockVpn, c -> !c.hasCapability(NET_CAPABILITY_NOT_SUSPENDED) 8663 && c.hasTransport(TRANSPORT_CELLULAR)); 8664 callback.expect(SUSPENDED, mMockVpn); 8665 callback.assertNoCallback(); 8666 8667 assertFalse(mCm.getNetworkCapabilities(mMockVpn.getNetwork()) 8668 .hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 8669 assertNetworkInfo(TYPE_MOBILE, DetailedState.SUSPENDED); 8670 assertNetworkInfo(TYPE_WIFI, DetailedState.DISCONNECTED); 8671 assertNetworkInfo(TYPE_VPN, DetailedState.SUSPENDED); 8672 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.SUSPENDED); 8673 // VPN's main underlying network is suspended, so no connectivity. 8674 assertGetNetworkInfoOfGetActiveNetworkIsConnected(false); 8675 8676 // Switch to another network. The VPN should no longer be suspended. 8677 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 8678 mWiFiAgent.connect(false /* validated */); 8679 callback.expectCaps(mMockVpn, c -> c.hasCapability(NET_CAPABILITY_NOT_SUSPENDED) 8680 && c.hasTransport(TRANSPORT_WIFI)); 8681 callback.expect(RESUMED, mMockVpn); 8682 callback.assertNoCallback(); 8683 8684 assertTrue(mCm.getNetworkCapabilities(mMockVpn.getNetwork()) 8685 .hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 8686 assertNetworkInfo(TYPE_MOBILE, DetailedState.DISCONNECTED); 8687 assertNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 8688 assertNetworkInfo(TYPE_VPN, DetailedState.CONNECTED); 8689 assertActiveNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 8690 assertGetNetworkInfoOfGetActiveNetworkIsConnected(true); 8691 8692 // Unsuspend cellular and then switch back to it. The VPN remains not suspended. 8693 mCellAgent.resume(); 8694 callback.assertNoCallback(); 8695 mWiFiAgent.disconnect(); 8696 callback.expectCaps(mMockVpn, c -> c.hasCapability(NET_CAPABILITY_NOT_SUSPENDED) 8697 && c.hasTransport(TRANSPORT_CELLULAR)); 8698 // Spurious double callback? 8699 callback.expectCaps(mMockVpn, c -> c.hasCapability(NET_CAPABILITY_NOT_SUSPENDED) 8700 && c.hasTransport(TRANSPORT_CELLULAR)); 8701 callback.assertNoCallback(); 8702 8703 assertTrue(mCm.getNetworkCapabilities(mMockVpn.getNetwork()) 8704 .hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 8705 assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 8706 assertNetworkInfo(TYPE_WIFI, DetailedState.DISCONNECTED); 8707 assertNetworkInfo(TYPE_VPN, DetailedState.CONNECTED); 8708 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 8709 assertGetNetworkInfoOfGetActiveNetworkIsConnected(true); 8710 8711 // Suspend cellular and expect no connectivity. 8712 mCellAgent.suspend(); 8713 callback.expectCaps(mMockVpn, c -> !c.hasCapability(NET_CAPABILITY_NOT_SUSPENDED) 8714 && c.hasTransport(TRANSPORT_CELLULAR)); 8715 callback.expect(SUSPENDED, mMockVpn); 8716 callback.assertNoCallback(); 8717 8718 assertFalse(mCm.getNetworkCapabilities(mMockVpn.getNetwork()) 8719 .hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 8720 assertNetworkInfo(TYPE_MOBILE, DetailedState.SUSPENDED); 8721 assertNetworkInfo(TYPE_WIFI, DetailedState.DISCONNECTED); 8722 assertNetworkInfo(TYPE_VPN, DetailedState.SUSPENDED); 8723 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.SUSPENDED); 8724 assertGetNetworkInfoOfGetActiveNetworkIsConnected(false); 8725 8726 // Resume cellular and expect that connectivity comes back. 8727 mCellAgent.resume(); 8728 callback.expectCaps(mMockVpn, c -> c.hasCapability(NET_CAPABILITY_NOT_SUSPENDED) 8729 && c.hasTransport(TRANSPORT_CELLULAR)); 8730 callback.expect(RESUMED, mMockVpn); 8731 callback.assertNoCallback(); 8732 8733 assertTrue(mCm.getNetworkCapabilities(mMockVpn.getNetwork()) 8734 .hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 8735 assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 8736 assertNetworkInfo(TYPE_WIFI, DetailedState.DISCONNECTED); 8737 assertNetworkInfo(TYPE_VPN, DetailedState.CONNECTED); 8738 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 8739 assertGetNetworkInfoOfGetActiveNetworkIsConnected(true); 8740 } 8741 8742 @Test 8743 public void testVpnNetworkActive() throws Exception { 8744 final int uid = Process.myUid(); 8745 8746 final TestNetworkCallback genericNetworkCallback = new TestNetworkCallback(); 8747 final TestNetworkCallback genericNotVpnNetworkCallback = new TestNetworkCallback(); 8748 final TestNetworkCallback wifiNetworkCallback = new TestNetworkCallback(); 8749 final TestNetworkCallback vpnNetworkCallback = new TestNetworkCallback(); 8750 final TestNetworkCallback defaultCallback = new TestNetworkCallback(); 8751 final TestNetworkCallback systemDefaultCallback = new TestNetworkCallback(); 8752 final NetworkRequest genericNotVpnRequest = new NetworkRequest.Builder().build(); 8753 final NetworkRequest genericRequest = new NetworkRequest.Builder() 8754 .removeCapability(NET_CAPABILITY_NOT_VPN).build(); 8755 final NetworkRequest wifiRequest = new NetworkRequest.Builder() 8756 .addTransportType(TRANSPORT_WIFI).build(); 8757 final NetworkRequest vpnNetworkRequest = new NetworkRequest.Builder() 8758 .removeCapability(NET_CAPABILITY_NOT_VPN) 8759 .addTransportType(TRANSPORT_VPN).build(); 8760 mCm.registerNetworkCallback(genericRequest, genericNetworkCallback); 8761 mCm.registerNetworkCallback(genericNotVpnRequest, genericNotVpnNetworkCallback); 8762 mCm.registerNetworkCallback(wifiRequest, wifiNetworkCallback); 8763 mCm.registerNetworkCallback(vpnNetworkRequest, vpnNetworkCallback); 8764 mCm.registerDefaultNetworkCallback(defaultCallback); 8765 mCm.registerSystemDefaultNetworkCallback(systemDefaultCallback, 8766 new Handler(ConnectivityThread.getInstanceLooper())); 8767 defaultCallback.assertNoCallback(); 8768 8769 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 8770 mWiFiAgent.connect(false); 8771 8772 genericNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 8773 genericNotVpnNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 8774 wifiNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 8775 defaultCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 8776 systemDefaultCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 8777 vpnNetworkCallback.assertNoCallback(); 8778 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 8779 8780 final Set<UidRange> ranges = uidRangesForUids(uid); 8781 mMockVpn.registerAgent(ranges); 8782 mMockVpn.setUnderlyingNetworks(new Network[0]); 8783 8784 // VPN networks do not satisfy the default request and are automatically validated 8785 // by NetworkMonitor 8786 assertFalse(NetworkMonitorUtils.isValidationRequired( 8787 false /* isDunValidationRequired */, 8788 NetworkAgentConfigShimImpl.newInstance(mMockVpn.getNetworkAgentConfig()) 8789 .isVpnValidationRequired(), 8790 mMockVpn.getAgent().getNetworkCapabilities())); 8791 mMockVpn.getAgent().setNetworkValid(false /* privateDnsProbeSent */); 8792 8793 mMockVpn.connect(false); 8794 8795 genericNetworkCallback.expectAvailableThenValidatedCallbacks(mMockVpn); 8796 genericNotVpnNetworkCallback.assertNoCallback(); 8797 wifiNetworkCallback.assertNoCallback(); 8798 vpnNetworkCallback.expectAvailableThenValidatedCallbacks(mMockVpn); 8799 defaultCallback.expectAvailableThenValidatedCallbacks(mMockVpn); 8800 systemDefaultCallback.assertNoCallback(); 8801 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 8802 assertEquals(mWiFiAgent.getNetwork(), systemDefaultCallback.getLastAvailableNetwork()); 8803 8804 ranges.clear(); 8805 mMockVpn.setUids(ranges); 8806 8807 genericNetworkCallback.expect(LOST, mMockVpn); 8808 genericNotVpnNetworkCallback.assertNoCallback(); 8809 wifiNetworkCallback.assertNoCallback(); 8810 vpnNetworkCallback.expect(LOST, mMockVpn); 8811 8812 // TODO : The default network callback should actually get a LOST call here (also see the 8813 // comment below for AVAILABLE). This is because ConnectivityService does not look at UID 8814 // ranges at all when determining whether a network should be rematched. In practice, VPNs 8815 // can't currently update their UIDs without disconnecting, so this does not matter too 8816 // much, but that is the reason the test here has to check for an update to the 8817 // capabilities instead of the expected LOST then AVAILABLE. 8818 defaultCallback.expectCaps(mMockVpn); 8819 systemDefaultCallback.assertNoCallback(); 8820 8821 ranges.add(new UidRange(uid, uid)); 8822 mMockVpn.setUids(ranges); 8823 8824 genericNetworkCallback.expectAvailableCallbacksValidated(mMockVpn); 8825 genericNotVpnNetworkCallback.assertNoCallback(); 8826 wifiNetworkCallback.assertNoCallback(); 8827 vpnNetworkCallback.expectAvailableCallbacksValidated(mMockVpn); 8828 // TODO : Here like above, AVAILABLE would be correct, but because this can't actually 8829 // happen outside of the test, ConnectivityService does not rematch callbacks. 8830 defaultCallback.expectCaps(mMockVpn); 8831 systemDefaultCallback.assertNoCallback(); 8832 8833 mWiFiAgent.disconnect(); 8834 8835 genericNetworkCallback.expect(LOST, mWiFiAgent); 8836 genericNotVpnNetworkCallback.expect(LOST, mWiFiAgent); 8837 wifiNetworkCallback.expect(LOST, mWiFiAgent); 8838 vpnNetworkCallback.assertNoCallback(); 8839 defaultCallback.assertNoCallback(); 8840 systemDefaultCallback.expect(LOST, mWiFiAgent); 8841 8842 mMockVpn.disconnect(); 8843 8844 genericNetworkCallback.expect(LOST, mMockVpn); 8845 genericNotVpnNetworkCallback.assertNoCallback(); 8846 wifiNetworkCallback.assertNoCallback(); 8847 vpnNetworkCallback.expect(LOST, mMockVpn); 8848 defaultCallback.expect(LOST, mMockVpn); 8849 systemDefaultCallback.assertNoCallback(); 8850 assertEquals(null, mCm.getActiveNetwork()); 8851 8852 mCm.unregisterNetworkCallback(genericNetworkCallback); 8853 mCm.unregisterNetworkCallback(wifiNetworkCallback); 8854 mCm.unregisterNetworkCallback(vpnNetworkCallback); 8855 mCm.unregisterNetworkCallback(defaultCallback); 8856 mCm.unregisterNetworkCallback(systemDefaultCallback); 8857 } 8858 8859 @Test 8860 public void testVpnWithoutInternet() throws Exception { 8861 final int uid = Process.myUid(); 8862 8863 final TestNetworkCallback defaultCallback = new TestNetworkCallback(); 8864 mCm.registerDefaultNetworkCallback(defaultCallback); 8865 8866 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 8867 mWiFiAgent.connect(true); 8868 8869 defaultCallback.expectAvailableThenValidatedCallbacks(mWiFiAgent); 8870 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 8871 8872 mMockVpn.establishForMyUid(true /* validated */, false /* hasInternet */, 8873 false /* privateDnsProbeSent */); 8874 assertUidRangesUpdatedForMyUid(true); 8875 8876 defaultCallback.assertNoCallback(); 8877 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 8878 8879 mMockVpn.disconnect(); 8880 defaultCallback.assertNoCallback(); 8881 8882 mCm.unregisterNetworkCallback(defaultCallback); 8883 } 8884 8885 @Test 8886 public void testVpnWithInternet() throws Exception { 8887 final int uid = Process.myUid(); 8888 8889 final TestNetworkCallback defaultCallback = new TestNetworkCallback(); 8890 mCm.registerDefaultNetworkCallback(defaultCallback); 8891 8892 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 8893 mWiFiAgent.connect(true); 8894 8895 defaultCallback.expectAvailableThenValidatedCallbacks(mWiFiAgent); 8896 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 8897 8898 mMockVpn.establishForMyUid(true /* validated */, true /* hasInternet */, 8899 false /* privateDnsProbeSent */); 8900 assertUidRangesUpdatedForMyUid(true); 8901 8902 defaultCallback.expectAvailableThenValidatedCallbacks(mMockVpn); 8903 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 8904 8905 mMockVpn.disconnect(); 8906 defaultCallback.expect(LOST, mMockVpn); 8907 defaultCallback.expectAvailableCallbacksValidated(mWiFiAgent); 8908 8909 mCm.unregisterNetworkCallback(defaultCallback); 8910 } 8911 8912 @Test 8913 public void testVpnUnvalidated() throws Exception { 8914 final TestNetworkCallback callback = new TestNetworkCallback(); 8915 mCm.registerDefaultNetworkCallback(callback); 8916 8917 // Bring up Ethernet. 8918 mEthernetAgent = new TestNetworkAgentWrapper(TRANSPORT_ETHERNET); 8919 mEthernetAgent.connect(true); 8920 callback.expectAvailableThenValidatedCallbacks(mEthernetAgent); 8921 callback.assertNoCallback(); 8922 8923 // Bring up a VPN that has the INTERNET capability, initially unvalidated. 8924 mMockVpn.establishForMyUid(false /* validated */, true /* hasInternet */, 8925 false /* privateDnsProbeSent */); 8926 assertUidRangesUpdatedForMyUid(true); 8927 8928 // Even though the VPN is unvalidated, it becomes the default network for our app. 8929 callback.expectAvailableCallbacksUnvalidated(mMockVpn); 8930 callback.assertNoCallback(); 8931 8932 assertEquals(mMockVpn.getNetwork(), mCm.getActiveNetwork()); 8933 8934 NetworkCapabilities nc = mCm.getNetworkCapabilities(mMockVpn.getNetwork()); 8935 assertFalse(nc.hasCapability(NET_CAPABILITY_VALIDATED)); 8936 assertTrue(nc.hasCapability(NET_CAPABILITY_INTERNET)); 8937 8938 assertFalse(NetworkMonitorUtils.isValidationRequired( 8939 false /* isDunValidationRequired */, 8940 NetworkAgentConfigShimImpl.newInstance(mMockVpn.getNetworkAgentConfig()) 8941 .isVpnValidationRequired(), 8942 mMockVpn.getAgent().getNetworkCapabilities())); 8943 assertTrue(NetworkMonitorUtils.isPrivateDnsValidationRequired( 8944 mMockVpn.getAgent().getNetworkCapabilities())); 8945 8946 // Pretend that the VPN network validates. 8947 mMockVpn.getAgent().setNetworkValid(false /* privateDnsProbeSent */); 8948 mMockVpn.getAgent().mNetworkMonitor.forceReevaluation(Process.myUid()); 8949 // Expect to see the validated capability, but no other changes, because the VPN is already 8950 // the default network for the app. 8951 callback.expectCaps(mMockVpn, c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 8952 callback.assertNoCallback(); 8953 8954 mMockVpn.disconnect(); 8955 callback.expect(LOST, mMockVpn); 8956 callback.expectAvailableCallbacksValidated(mEthernetAgent); 8957 } 8958 8959 @Test 8960 public void testVpnStartsWithUnderlyingCaps() throws Exception { 8961 final int uid = Process.myUid(); 8962 8963 final TestNetworkCallback vpnNetworkCallback = new TestNetworkCallback(); 8964 final NetworkRequest vpnNetworkRequest = new NetworkRequest.Builder() 8965 .removeCapability(NET_CAPABILITY_NOT_VPN) 8966 .addTransportType(TRANSPORT_VPN) 8967 .build(); 8968 mCm.registerNetworkCallback(vpnNetworkRequest, vpnNetworkCallback); 8969 vpnNetworkCallback.assertNoCallback(); 8970 8971 // Connect cell. It will become the default network, and in the absence of setting 8972 // underlying networks explicitly it will become the sole underlying network for the vpn. 8973 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 8974 mCellAgent.addCapability(NET_CAPABILITY_NOT_SUSPENDED); 8975 mCellAgent.connect(true); 8976 8977 mMockVpn.establishForMyUid(true /* validated */, false /* hasInternet */, 8978 false /* privateDnsProbeSent */); 8979 assertUidRangesUpdatedForMyUid(true); 8980 8981 vpnNetworkCallback.expectAvailableCallbacks(mMockVpn.getNetwork(), 8982 false /* suspended */, false /* validated */, false /* blocked */, TIMEOUT_MS); 8983 vpnNetworkCallback.expectCaps(mMockVpn.getNetwork(), TIMEOUT_MS, 8984 c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 8985 8986 final NetworkCapabilities nc = mCm.getNetworkCapabilities(mMockVpn.getNetwork()); 8987 assertTrue(nc.hasTransport(TRANSPORT_VPN)); 8988 assertTrue(nc.hasTransport(TRANSPORT_CELLULAR)); 8989 assertFalse(nc.hasTransport(TRANSPORT_WIFI)); 8990 assertTrue(nc.hasCapability(NET_CAPABILITY_VALIDATED)); 8991 assertFalse(nc.hasCapability(NET_CAPABILITY_NOT_METERED)); 8992 assertTrue(nc.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 8993 8994 assertVpnTransportInfo(nc, VpnManager.TYPE_VPN_SERVICE); 8995 } 8996 8997 private void assertDefaultNetworkCapabilities(int userId, NetworkAgentWrapper... networks) { 8998 final NetworkCapabilities[] defaultCaps = mService.getDefaultNetworkCapabilitiesForUser( 8999 userId, "com.android.calling.package", "com.test"); 9000 final String defaultCapsString = Arrays.toString(defaultCaps); 9001 assertEquals(defaultCapsString, defaultCaps.length, networks.length); 9002 final Set<NetworkCapabilities> defaultCapsSet = new ArraySet<>(defaultCaps); 9003 for (NetworkAgentWrapper network : networks) { 9004 final NetworkCapabilities nc = mCm.getNetworkCapabilities(network.getNetwork()); 9005 final String msg = "Did not find " + nc + " in " + Arrays.toString(defaultCaps); 9006 assertTrue(msg, defaultCapsSet.contains(nc)); 9007 } 9008 } 9009 9010 @Test 9011 public void testVpnSetUnderlyingNetworks() throws Exception { 9012 final TestNetworkCallback vpnNetworkCallback = new TestNetworkCallback(); 9013 final NetworkRequest vpnNetworkRequest = new NetworkRequest.Builder() 9014 .removeCapability(NET_CAPABILITY_NOT_VPN) 9015 .addTransportType(TRANSPORT_VPN) 9016 .build(); 9017 NetworkCapabilities nc; 9018 mCm.registerNetworkCallback(vpnNetworkRequest, vpnNetworkCallback); 9019 vpnNetworkCallback.assertNoCallback(); 9020 9021 mMockVpn.establishForMyUid(true /* validated */, false /* hasInternet */, 9022 false /* privateDnsProbeSent */); 9023 assertUidRangesUpdatedForMyUid(true); 9024 9025 vpnNetworkCallback.expectAvailableThenValidatedCallbacks(mMockVpn); 9026 nc = mCm.getNetworkCapabilities(mMockVpn.getNetwork()); 9027 assertTrue(nc.hasTransport(TRANSPORT_VPN)); 9028 assertFalse(nc.hasTransport(TRANSPORT_CELLULAR)); 9029 assertFalse(nc.hasTransport(TRANSPORT_WIFI)); 9030 // For safety reasons a VPN without underlying networks is considered metered. 9031 assertFalse(nc.hasCapability(NET_CAPABILITY_NOT_METERED)); 9032 // A VPN without underlying networks is not suspended. 9033 assertTrue(nc.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 9034 assertVpnTransportInfo(nc, VpnManager.TYPE_VPN_SERVICE); 9035 9036 final int userId = UserHandle.getUserId(Process.myUid()); 9037 assertDefaultNetworkCapabilities(userId /* no networks */); 9038 9039 // Connect cell and use it as an underlying network. 9040 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 9041 mCellAgent.addCapability(NET_CAPABILITY_NOT_SUSPENDED); 9042 mCellAgent.connect(true); 9043 9044 mMockVpn.setUnderlyingNetworks(new Network[] { mCellAgent.getNetwork() }); 9045 9046 vpnNetworkCallback.expectCaps(mMockVpn, 9047 c -> c.hasTransport(TRANSPORT_VPN) 9048 && c.hasTransport(TRANSPORT_CELLULAR) 9049 && !c.hasTransport(TRANSPORT_WIFI) 9050 && !c.hasCapability(NET_CAPABILITY_NOT_METERED) 9051 && c.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 9052 assertDefaultNetworkCapabilities(userId, mCellAgent); 9053 9054 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 9055 mWiFiAgent.addCapability(NET_CAPABILITY_NOT_METERED); 9056 mWiFiAgent.addCapability(NET_CAPABILITY_NOT_SUSPENDED); 9057 mWiFiAgent.connect(true); 9058 9059 mMockVpn.setUnderlyingNetworks( 9060 new Network[] { mCellAgent.getNetwork(), mWiFiAgent.getNetwork() }); 9061 9062 vpnNetworkCallback.expectCaps(mMockVpn, 9063 c -> c.hasTransport(TRANSPORT_VPN) 9064 && c.hasTransport(TRANSPORT_CELLULAR) 9065 && c.hasTransport(TRANSPORT_WIFI) 9066 && !c.hasCapability(NET_CAPABILITY_NOT_METERED) 9067 && c.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 9068 assertDefaultNetworkCapabilities(userId, mCellAgent, mWiFiAgent); 9069 9070 // Don't disconnect, but note the VPN is not using wifi any more. 9071 mMockVpn.setUnderlyingNetworks(new Network[] { mCellAgent.getNetwork() }); 9072 9073 vpnNetworkCallback.expectCaps(mMockVpn, 9074 c -> c.hasTransport(TRANSPORT_VPN) 9075 && c.hasTransport(TRANSPORT_CELLULAR) 9076 && !c.hasTransport(TRANSPORT_WIFI) 9077 && !c.hasCapability(NET_CAPABILITY_NOT_METERED) 9078 && c.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 9079 // The return value of getDefaultNetworkCapabilitiesForUser always includes the default 9080 // network (wifi) as well as the underlying networks (cell). 9081 assertDefaultNetworkCapabilities(userId, mCellAgent, mWiFiAgent); 9082 9083 // Remove NOT_SUSPENDED from the only network and observe VPN is now suspended. 9084 mCellAgent.removeCapability(NET_CAPABILITY_NOT_SUSPENDED); 9085 vpnNetworkCallback.expectCaps(mMockVpn, 9086 c -> c.hasTransport(TRANSPORT_VPN) 9087 && c.hasTransport(TRANSPORT_CELLULAR) 9088 && !c.hasTransport(TRANSPORT_WIFI) 9089 && !c.hasCapability(NET_CAPABILITY_NOT_METERED) 9090 && !c.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 9091 vpnNetworkCallback.expect(SUSPENDED, mMockVpn); 9092 9093 // Add NOT_SUSPENDED again and observe VPN is no longer suspended. 9094 mCellAgent.addCapability(NET_CAPABILITY_NOT_SUSPENDED); 9095 vpnNetworkCallback.expectCaps(mMockVpn, 9096 c -> c.hasTransport(TRANSPORT_VPN) 9097 && c.hasTransport(TRANSPORT_CELLULAR) 9098 && !c.hasTransport(TRANSPORT_WIFI) 9099 && !c.hasCapability(NET_CAPABILITY_NOT_METERED) 9100 && c.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 9101 vpnNetworkCallback.expect(RESUMED, mMockVpn); 9102 9103 // Use Wifi but not cell. Note the VPN is now unmetered and not suspended. 9104 mMockVpn.setUnderlyingNetworks(new Network[] { mWiFiAgent.getNetwork() }); 9105 9106 vpnNetworkCallback.expectCaps(mMockVpn, 9107 c -> c.hasTransport(TRANSPORT_VPN) 9108 && !c.hasTransport(TRANSPORT_CELLULAR) 9109 && c.hasTransport(TRANSPORT_WIFI) 9110 && c.hasCapability(NET_CAPABILITY_NOT_METERED) 9111 && c.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 9112 assertDefaultNetworkCapabilities(userId, mWiFiAgent); 9113 9114 // Use both again. 9115 mMockVpn.setUnderlyingNetworks( 9116 new Network[] { mCellAgent.getNetwork(), mWiFiAgent.getNetwork() }); 9117 9118 vpnNetworkCallback.expectCaps(mMockVpn, 9119 c -> c.hasTransport(TRANSPORT_VPN) 9120 && c.hasTransport(TRANSPORT_CELLULAR) 9121 && c.hasTransport(TRANSPORT_WIFI) 9122 && !c.hasCapability(NET_CAPABILITY_NOT_METERED) 9123 && c.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 9124 assertDefaultNetworkCapabilities(userId, mCellAgent, mWiFiAgent); 9125 9126 // Cell is suspended again. As WiFi is not, this should not cause a callback. 9127 mCellAgent.removeCapability(NET_CAPABILITY_NOT_SUSPENDED); 9128 vpnNetworkCallback.assertNoCallback(); 9129 9130 // Stop using WiFi. The VPN is suspended again. 9131 mMockVpn.setUnderlyingNetworks(new Network[] { mCellAgent.getNetwork() }); 9132 vpnNetworkCallback.expectCaps(mMockVpn, 9133 c -> c.hasTransport(TRANSPORT_VPN) 9134 && c.hasTransport(TRANSPORT_CELLULAR) 9135 && !c.hasCapability(NET_CAPABILITY_NOT_METERED) 9136 && !c.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 9137 vpnNetworkCallback.expect(SUSPENDED, mMockVpn); 9138 assertDefaultNetworkCapabilities(userId, mCellAgent, mWiFiAgent); 9139 9140 // Use both again. 9141 mMockVpn.setUnderlyingNetworks( 9142 new Network[] { mCellAgent.getNetwork(), mWiFiAgent.getNetwork() }); 9143 9144 vpnNetworkCallback.expectCaps(mMockVpn, 9145 c -> c.hasTransport(TRANSPORT_VPN) 9146 && c.hasTransport(TRANSPORT_CELLULAR) 9147 && c.hasTransport(TRANSPORT_WIFI) 9148 && !c.hasCapability(NET_CAPABILITY_NOT_METERED) 9149 && c.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 9150 vpnNetworkCallback.expect(RESUMED, mMockVpn); 9151 assertDefaultNetworkCapabilities(userId, mCellAgent, mWiFiAgent); 9152 9153 // Disconnect cell. Receive update without even removing the dead network from the 9154 // underlying networks – it's dead anyway. Not metered any more. 9155 mCellAgent.disconnect(); 9156 vpnNetworkCallback.expectCaps(mMockVpn, 9157 c -> c.hasTransport(TRANSPORT_VPN) 9158 && !c.hasTransport(TRANSPORT_CELLULAR) 9159 && c.hasTransport(TRANSPORT_WIFI) 9160 && c.hasCapability(NET_CAPABILITY_NOT_METERED)); 9161 assertDefaultNetworkCapabilities(userId, mWiFiAgent); 9162 9163 // Disconnect wifi too. No underlying networks means this is now metered. 9164 mWiFiAgent.disconnect(); 9165 vpnNetworkCallback.expectCaps(mMockVpn, 9166 c -> c.hasTransport(TRANSPORT_VPN) 9167 && !c.hasTransport(TRANSPORT_CELLULAR) 9168 && !c.hasTransport(TRANSPORT_WIFI) 9169 && !c.hasCapability(NET_CAPABILITY_NOT_METERED)); 9170 // When a network disconnects, the callbacks are fired before all state is updated, so for a 9171 // short time, synchronous calls will behave as if the network is still connected. Wait for 9172 // things to settle. 9173 waitForIdle(); 9174 assertDefaultNetworkCapabilities(userId /* no networks */); 9175 9176 mMockVpn.disconnect(); 9177 } 9178 9179 @Test 9180 public void testNullUnderlyingNetworks() throws Exception { 9181 final int uid = Process.myUid(); 9182 9183 final TestNetworkCallback vpnNetworkCallback = new TestNetworkCallback(); 9184 final NetworkRequest vpnNetworkRequest = new NetworkRequest.Builder() 9185 .removeCapability(NET_CAPABILITY_NOT_VPN) 9186 .addTransportType(TRANSPORT_VPN) 9187 .build(); 9188 NetworkCapabilities nc; 9189 mCm.registerNetworkCallback(vpnNetworkRequest, vpnNetworkCallback); 9190 vpnNetworkCallback.assertNoCallback(); 9191 9192 mMockVpn.establishForMyUid(true /* validated */, false /* hasInternet */, 9193 false /* privateDnsProbeSent */); 9194 assertUidRangesUpdatedForMyUid(true); 9195 9196 vpnNetworkCallback.expectAvailableThenValidatedCallbacks(mMockVpn); 9197 nc = mCm.getNetworkCapabilities(mMockVpn.getNetwork()); 9198 assertTrue(nc.hasTransport(TRANSPORT_VPN)); 9199 assertFalse(nc.hasTransport(TRANSPORT_CELLULAR)); 9200 assertFalse(nc.hasTransport(TRANSPORT_WIFI)); 9201 // By default, VPN is set to track default network (i.e. its underlying networks is null). 9202 // In case of no default network, VPN is considered metered. 9203 assertFalse(nc.hasCapability(NET_CAPABILITY_NOT_METERED)); 9204 assertVpnTransportInfo(nc, VpnManager.TYPE_VPN_SERVICE); 9205 9206 // Connect to Cell; Cell is the default network. 9207 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 9208 mCellAgent.connect(true); 9209 9210 vpnNetworkCallback.expectCaps(mMockVpn, 9211 c -> c.hasTransport(TRANSPORT_VPN) 9212 && c.hasTransport(TRANSPORT_CELLULAR) 9213 && !c.hasTransport(TRANSPORT_WIFI) 9214 && !c.hasCapability(NET_CAPABILITY_NOT_METERED)); 9215 9216 // Connect to WiFi; WiFi is the new default. 9217 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 9218 mWiFiAgent.addCapability(NET_CAPABILITY_NOT_METERED); 9219 mWiFiAgent.connect(true); 9220 9221 vpnNetworkCallback.expectCaps(mMockVpn, 9222 c -> c.hasTransport(TRANSPORT_VPN) 9223 && !c.hasTransport(TRANSPORT_CELLULAR) 9224 && c.hasTransport(TRANSPORT_WIFI) 9225 && c.hasCapability(NET_CAPABILITY_NOT_METERED)); 9226 9227 // Disconnect Cell. The default network did not change, so there shouldn't be any changes in 9228 // the capabilities. 9229 mCellAgent.disconnect(); 9230 9231 // Disconnect wifi too. Now we have no default network. 9232 mWiFiAgent.disconnect(); 9233 9234 vpnNetworkCallback.expectCaps(mMockVpn, 9235 c -> c.hasTransport(TRANSPORT_VPN) 9236 && !c.hasTransport(TRANSPORT_CELLULAR) 9237 && !c.hasTransport(TRANSPORT_WIFI) 9238 && !c.hasCapability(NET_CAPABILITY_NOT_METERED)); 9239 9240 mMockVpn.disconnect(); 9241 } 9242 9243 @Test 9244 public void testRestrictedProfileAffectsVpnUidRanges() throws Exception { 9245 // NETWORK_SETTINGS is necessary to see the UID ranges in NetworkCapabilities. 9246 mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_GRANTED); 9247 9248 final NetworkRequest request = new NetworkRequest.Builder() 9249 .removeCapability(NET_CAPABILITY_NOT_VPN) 9250 .build(); 9251 final TestNetworkCallback callback = new TestNetworkCallback(); 9252 mCm.registerNetworkCallback(request, callback); 9253 9254 // File a VPN request to prevent VPN network being lingered. 9255 final NetworkRequest vpnRequest = new NetworkRequest.Builder() 9256 .addTransportType(TRANSPORT_VPN) 9257 .removeCapability(NET_CAPABILITY_NOT_VPN) 9258 .build(); 9259 final TestNetworkCallback vpnCallback = new TestNetworkCallback(); 9260 mCm.requestNetwork(vpnRequest, vpnCallback); 9261 9262 // Bring up a VPN 9263 mMockVpn.establishForMyUid(); 9264 assertUidRangesUpdatedForMyUid(true); 9265 callback.expectAvailableThenValidatedCallbacks(mMockVpn); 9266 callback.assertNoCallback(); 9267 9268 final int uid = Process.myUid(); 9269 NetworkCapabilities nc = mCm.getNetworkCapabilities(mMockVpn.getNetwork()); 9270 assertNotNull("nc=" + nc, nc.getUids()); 9271 assertEquals(nc.getUids(), UidRange.toIntRanges(uidRangesForUids(uid))); 9272 assertVpnTransportInfo(nc, VpnManager.TYPE_VPN_SERVICE); 9273 9274 // Set an underlying network and expect to see the VPN transports change. 9275 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 9276 mWiFiAgent.connect(true); 9277 callback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 9278 callback.expectCaps(mMockVpn, c -> c.hasTransport(TRANSPORT_VPN) 9279 && c.hasTransport(TRANSPORT_WIFI)); 9280 callback.expectCaps(mWiFiAgent, c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 9281 9282 doReturn(UserHandle.getUid(RESTRICTED_USER, VPN_UID)).when(mPackageManager) 9283 .getPackageUidAsUser(ALWAYS_ON_PACKAGE, RESTRICTED_USER); 9284 9285 // New user added 9286 mMockVpn.onUserAdded(RESTRICTED_USER); 9287 9288 // Expect that the VPN UID ranges contain both |uid| and the UID range for the newly-added 9289 // restricted user. 9290 final UidRange rRange = UidRange.createForUser(UserHandle.of(RESTRICTED_USER)); 9291 final Range<Integer> restrictUidRange = new Range<>(rRange.start, rRange.stop); 9292 final Range<Integer> singleUidRange = new Range<>(uid, uid); 9293 callback.expectCaps(mMockVpn, c -> 9294 c.getUids().size() == 2 9295 && c.getUids().contains(singleUidRange) 9296 && c.getUids().contains(restrictUidRange) 9297 && c.hasTransport(TRANSPORT_VPN) 9298 && c.hasTransport(TRANSPORT_WIFI)); 9299 9300 // Change the VPN's capabilities somehow (specifically, disconnect wifi). 9301 mWiFiAgent.disconnect(); 9302 callback.expect(LOST, mWiFiAgent); 9303 callback.expectCaps(mMockVpn, c -> 9304 c.getUids().size() == 2 9305 && c.getUids().contains(singleUidRange) 9306 && c.getUids().contains(restrictUidRange) 9307 && c.hasTransport(TRANSPORT_VPN) 9308 && !c.hasTransport(TRANSPORT_WIFI)); 9309 9310 // User removed and expect to lose the UID range for the restricted user. 9311 mMockVpn.onUserRemoved(RESTRICTED_USER); 9312 9313 // Expect that the VPN gains the UID range for the restricted user, and that the capability 9314 // change made just before that (i.e., loss of TRANSPORT_WIFI) is preserved. 9315 callback.expectCaps(mMockVpn, c -> 9316 c.getUids().size() == 1 9317 && c.getUids().contains(singleUidRange) 9318 && c.hasTransport(TRANSPORT_VPN) 9319 && !c.hasTransport(TRANSPORT_WIFI)); 9320 9321 mCm.unregisterNetworkCallback(callback); 9322 mCm.unregisterNetworkCallback(vpnCallback); 9323 } 9324 9325 @Test 9326 public void testLockdownVpnWithRestrictedProfiles() throws Exception { 9327 // For ConnectivityService#setAlwaysOnVpnPackage. 9328 mServiceContext.setPermission( 9329 Manifest.permission.CONTROL_ALWAYS_ON_VPN, PERMISSION_GRANTED); 9330 // For call Vpn#setAlwaysOnPackage. 9331 mServiceContext.setPermission( 9332 Manifest.permission.CONTROL_VPN, PERMISSION_GRANTED); 9333 // Necessary to see the UID ranges in NetworkCapabilities. 9334 mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_GRANTED); 9335 9336 final NetworkRequest request = new NetworkRequest.Builder() 9337 .removeCapability(NET_CAPABILITY_NOT_VPN) 9338 .build(); 9339 final TestNetworkCallback callback = new TestNetworkCallback(); 9340 mCm.registerNetworkCallback(request, callback); 9341 9342 final int uid = Process.myUid(); 9343 9344 // Connect wifi and check that UIDs in the main and restricted profiles have network access. 9345 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 9346 mWiFiAgent.connect(true /* validated */); 9347 final int restrictedUid = UserHandle.getUid(RESTRICTED_USER, 42 /* appId */); 9348 assertNotNull(mCm.getActiveNetworkForUid(uid)); 9349 assertNotNull(mCm.getActiveNetworkForUid(restrictedUid)); 9350 9351 // Enable always-on VPN lockdown. The main user loses network access because no VPN is up. 9352 final ArrayList<String> allowList = new ArrayList<>(); 9353 mMockVpn.setAlwaysOnPackage(ALWAYS_ON_PACKAGE, true /* lockdown */, allowList); 9354 waitForIdle(); 9355 assertNull(mCm.getActiveNetworkForUid(uid)); 9356 // This is arguably overspecified: a UID that is not running doesn't have an active network. 9357 // But it's useful to check that non-default users do not lose network access, and to prove 9358 // that the loss of connectivity below is indeed due to the restricted profile coming up. 9359 assertNotNull(mCm.getActiveNetworkForUid(restrictedUid)); 9360 9361 // Start the restricted profile, and check that the UID within it loses network access. 9362 doReturn(UserHandle.getUid(RESTRICTED_USER, VPN_UID)).when(mPackageManager) 9363 .getPackageUidAsUser(ALWAYS_ON_PACKAGE, RESTRICTED_USER); 9364 doReturn(asList(PRIMARY_USER_INFO, RESTRICTED_USER_INFO)).when(mUserManager) 9365 .getAliveUsers(); 9366 // TODO: check that VPN app within restricted profile still has access, etc. 9367 mMockVpn.onUserAdded(RESTRICTED_USER); 9368 final Intent addedIntent = new Intent(ACTION_USER_ADDED); 9369 addedIntent.putExtra(Intent.EXTRA_USER, UserHandle.of(RESTRICTED_USER)); 9370 addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, RESTRICTED_USER); 9371 processBroadcast(addedIntent); 9372 assertNull(mCm.getActiveNetworkForUid(uid)); 9373 assertNull(mCm.getActiveNetworkForUid(restrictedUid)); 9374 9375 // Stop the restricted profile, and check that the UID within it has network access again. 9376 doReturn(asList(PRIMARY_USER_INFO)).when(mUserManager).getAliveUsers(); 9377 9378 // Send a USER_REMOVED broadcast and expect to lose the UID range for the restricted user. 9379 mMockVpn.onUserRemoved(RESTRICTED_USER); 9380 final Intent removedIntent = new Intent(ACTION_USER_REMOVED); 9381 removedIntent.putExtra(Intent.EXTRA_USER, UserHandle.of(RESTRICTED_USER)); 9382 removedIntent.putExtra(Intent.EXTRA_USER_HANDLE, RESTRICTED_USER); 9383 processBroadcast(removedIntent); 9384 assertNull(mCm.getActiveNetworkForUid(uid)); 9385 assertNotNull(mCm.getActiveNetworkForUid(restrictedUid)); 9386 9387 mMockVpn.setAlwaysOnPackage(null, false /* lockdown */, allowList); 9388 waitForIdle(); 9389 } 9390 9391 @Test 9392 public void testIsActiveNetworkMeteredOverWifi() throws Exception { 9393 // Returns true by default when no network is available. 9394 assertTrue(mCm.isActiveNetworkMetered()); 9395 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 9396 mWiFiAgent.addCapability(NET_CAPABILITY_NOT_METERED); 9397 mWiFiAgent.connect(true); 9398 waitForIdle(); 9399 9400 assertFalse(mCm.isActiveNetworkMetered()); 9401 } 9402 9403 @Test 9404 public void testIsActiveNetworkMeteredOverCell() throws Exception { 9405 // Returns true by default when no network is available. 9406 assertTrue(mCm.isActiveNetworkMetered()); 9407 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 9408 mCellAgent.removeCapability(NET_CAPABILITY_NOT_METERED); 9409 mCellAgent.connect(true); 9410 waitForIdle(); 9411 9412 assertTrue(mCm.isActiveNetworkMetered()); 9413 } 9414 9415 @Test 9416 public void testIsActiveNetworkMeteredOverVpnTrackingPlatformDefault() throws Exception { 9417 // Returns true by default when no network is available. 9418 assertTrue(mCm.isActiveNetworkMetered()); 9419 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 9420 mCellAgent.removeCapability(NET_CAPABILITY_NOT_METERED); 9421 mCellAgent.connect(true); 9422 waitForIdle(); 9423 assertTrue(mCm.isActiveNetworkMetered()); 9424 9425 // Connect VPN network. By default it is using current default network (Cell). 9426 mMockVpn.establishForMyUid(); 9427 assertUidRangesUpdatedForMyUid(true); 9428 9429 // Ensure VPN is now the active network. 9430 assertEquals(mMockVpn.getNetwork(), mCm.getActiveNetwork()); 9431 9432 // Expect VPN to be metered. 9433 assertTrue(mCm.isActiveNetworkMetered()); 9434 9435 // Connect WiFi. 9436 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 9437 mWiFiAgent.addCapability(NET_CAPABILITY_NOT_METERED); 9438 mWiFiAgent.connect(true); 9439 waitForIdle(); 9440 // VPN should still be the active network. 9441 assertEquals(mMockVpn.getNetwork(), mCm.getActiveNetwork()); 9442 9443 // Expect VPN to be unmetered as it should now be using WiFi (new default). 9444 assertFalse(mCm.isActiveNetworkMetered()); 9445 9446 // Disconnecting Cell should not affect VPN's meteredness. 9447 mCellAgent.disconnect(); 9448 waitForIdle(); 9449 9450 assertFalse(mCm.isActiveNetworkMetered()); 9451 9452 // Disconnect WiFi; Now there is no platform default network. 9453 mWiFiAgent.disconnect(); 9454 waitForIdle(); 9455 9456 // VPN without any underlying networks is treated as metered. 9457 assertTrue(mCm.isActiveNetworkMetered()); 9458 9459 mMockVpn.disconnect(); 9460 } 9461 9462 @Test 9463 public void testIsActiveNetworkMeteredOverVpnSpecifyingUnderlyingNetworks() throws Exception { 9464 // Returns true by default when no network is available. 9465 assertTrue(mCm.isActiveNetworkMetered()); 9466 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 9467 mCellAgent.removeCapability(NET_CAPABILITY_NOT_METERED); 9468 mCellAgent.connect(true); 9469 waitForIdle(); 9470 assertTrue(mCm.isActiveNetworkMetered()); 9471 9472 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 9473 mWiFiAgent.addCapability(NET_CAPABILITY_NOT_METERED); 9474 mWiFiAgent.connect(true); 9475 waitForIdle(); 9476 assertFalse(mCm.isActiveNetworkMetered()); 9477 9478 // Connect VPN network. 9479 mMockVpn.establishForMyUid(); 9480 assertUidRangesUpdatedForMyUid(true); 9481 9482 // Ensure VPN is now the active network. 9483 assertEquals(mMockVpn.getNetwork(), mCm.getActiveNetwork()); 9484 // VPN is using Cell 9485 mMockVpn.setUnderlyingNetworks(new Network[] { mCellAgent.getNetwork() }); 9486 waitForIdle(); 9487 9488 // Expect VPN to be metered. 9489 assertTrue(mCm.isActiveNetworkMetered()); 9490 9491 // VPN is now using WiFi 9492 mMockVpn.setUnderlyingNetworks(new Network[] { mWiFiAgent.getNetwork() }); 9493 waitForIdle(); 9494 9495 // Expect VPN to be unmetered 9496 assertFalse(mCm.isActiveNetworkMetered()); 9497 9498 // VPN is using Cell | WiFi. 9499 mMockVpn.setUnderlyingNetworks( 9500 new Network[] { mCellAgent.getNetwork(), mWiFiAgent.getNetwork() }); 9501 waitForIdle(); 9502 9503 // Expect VPN to be metered. 9504 assertTrue(mCm.isActiveNetworkMetered()); 9505 9506 // VPN is using WiFi | Cell. 9507 mMockVpn.setUnderlyingNetworks( 9508 new Network[] { mWiFiAgent.getNetwork(), mCellAgent.getNetwork() }); 9509 waitForIdle(); 9510 9511 // Order should not matter and VPN should still be metered. 9512 assertTrue(mCm.isActiveNetworkMetered()); 9513 9514 // VPN is not using any underlying networks. 9515 mMockVpn.setUnderlyingNetworks(new Network[0]); 9516 waitForIdle(); 9517 9518 // VPN without underlying networks is treated as metered. 9519 assertTrue(mCm.isActiveNetworkMetered()); 9520 9521 mMockVpn.disconnect(); 9522 } 9523 9524 @Test 9525 public void testIsActiveNetworkMeteredOverAlwaysMeteredVpn() throws Exception { 9526 // Returns true by default when no network is available. 9527 assertTrue(mCm.isActiveNetworkMetered()); 9528 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 9529 mWiFiAgent.addCapability(NET_CAPABILITY_NOT_METERED); 9530 mWiFiAgent.connect(true); 9531 waitForIdle(); 9532 assertFalse(mCm.isActiveNetworkMetered()); 9533 9534 // Connect VPN network. 9535 mMockVpn.registerAgent(true /* isAlwaysMetered */, uidRangesForUids(Process.myUid()), 9536 new LinkProperties()); 9537 mMockVpn.connect(true); 9538 waitForIdle(); 9539 assertEquals(mMockVpn.getNetwork(), mCm.getActiveNetwork()); 9540 9541 // VPN is tracking current platform default (WiFi). 9542 mMockVpn.setUnderlyingNetworks(null); 9543 waitForIdle(); 9544 9545 // Despite VPN using WiFi (which is unmetered), VPN itself is marked as always metered. 9546 assertTrue(mCm.isActiveNetworkMetered()); 9547 9548 9549 // VPN explicitly declares WiFi as its underlying network. 9550 mMockVpn.setUnderlyingNetworks(new Network[] { mWiFiAgent.getNetwork() }); 9551 waitForIdle(); 9552 9553 // Doesn't really matter whether VPN declares its underlying networks explicitly. 9554 assertTrue(mCm.isActiveNetworkMetered()); 9555 9556 // With WiFi lost, VPN is basically without any underlying networks. And in that case it is 9557 // anyways suppose to be metered. 9558 mWiFiAgent.disconnect(); 9559 waitForIdle(); 9560 9561 assertTrue(mCm.isActiveNetworkMetered()); 9562 9563 mMockVpn.disconnect(); 9564 } 9565 9566 private class DetailedBlockedStatusCallback extends TestNetworkCallback { 9567 public void expectAvailableThenValidatedCallbacks(HasNetwork n, int blockedStatus) { 9568 super.expectAvailableThenValidatedCallbacks(n.getNetwork(), blockedStatus, TIMEOUT_MS); 9569 } 9570 public void onBlockedStatusChanged(Network network, int blockedReasons) { 9571 getHistory().add(new CallbackEntry.BlockedStatusInt(network, blockedReasons)); 9572 } 9573 } 9574 9575 @Test 9576 public void testNetworkBlockedStatus() throws Exception { 9577 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback(); 9578 final NetworkRequest cellRequest = new NetworkRequest.Builder() 9579 .addTransportType(TRANSPORT_CELLULAR) 9580 .build(); 9581 mCm.registerNetworkCallback(cellRequest, cellNetworkCallback); 9582 final DetailedBlockedStatusCallback detailedCallback = new DetailedBlockedStatusCallback(); 9583 mCm.registerNetworkCallback(cellRequest, detailedCallback); 9584 9585 mockUidNetworkingBlocked(); 9586 9587 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 9588 mCellAgent.connect(true); 9589 cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 9590 detailedCallback.expectAvailableThenValidatedCallbacks(mCellAgent, BLOCKED_REASON_NONE); 9591 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetwork()); 9592 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 9593 assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 9594 assertExtraInfoFromCmPresent(mCellAgent); 9595 9596 setBlockedReasonChanged(BLOCKED_REASON_BATTERY_SAVER); 9597 cellNetworkCallback.expect(BLOCKED_STATUS, mCellAgent, cb -> cb.getBlocked()); 9598 detailedCallback.expect(BLOCKED_STATUS_INT, mCellAgent, 9599 cb -> cb.getReason() == BLOCKED_REASON_BATTERY_SAVER); 9600 assertNull(mCm.getActiveNetwork()); 9601 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); 9602 assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); 9603 assertExtraInfoFromCmBlocked(mCellAgent); 9604 9605 // If blocked state does not change but blocked reason does, the boolean callback is called. 9606 // TODO: investigate de-duplicating. 9607 setBlockedReasonChanged(BLOCKED_METERED_REASON_USER_RESTRICTED); 9608 cellNetworkCallback.expect(BLOCKED_STATUS, mCellAgent, cb -> cb.getBlocked()); 9609 detailedCallback.expect(BLOCKED_STATUS_INT, mCellAgent, 9610 cb -> cb.getReason() == BLOCKED_METERED_REASON_USER_RESTRICTED); 9611 9612 setBlockedReasonChanged(BLOCKED_REASON_NONE); 9613 cellNetworkCallback.expect(BLOCKED_STATUS, mCellAgent, cb -> !cb.getBlocked()); 9614 detailedCallback.expect(BLOCKED_STATUS_INT, mCellAgent, 9615 cb -> cb.getReason() == BLOCKED_REASON_NONE); 9616 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetwork()); 9617 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 9618 assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 9619 assertExtraInfoFromCmPresent(mCellAgent); 9620 9621 setBlockedReasonChanged(BLOCKED_METERED_REASON_DATA_SAVER); 9622 cellNetworkCallback.expect(BLOCKED_STATUS, mCellAgent, cb -> cb.getBlocked()); 9623 detailedCallback.expect(BLOCKED_STATUS_INT, mCellAgent, 9624 cb -> cb.getReason() == BLOCKED_METERED_REASON_DATA_SAVER); 9625 assertNull(mCm.getActiveNetwork()); 9626 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); 9627 assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); 9628 assertExtraInfoFromCmBlocked(mCellAgent); 9629 9630 // Restrict the network based on UID rule and NOT_METERED capability change. 9631 mCellAgent.addCapability(NET_CAPABILITY_NOT_METERED); 9632 cellNetworkCallback.expectCaps(mCellAgent, 9633 c -> c.hasCapability(NET_CAPABILITY_NOT_METERED)); 9634 cellNetworkCallback.expect(BLOCKED_STATUS, mCellAgent, cb -> !cb.getBlocked()); 9635 detailedCallback.expectCaps(mCellAgent, c -> c.hasCapability(NET_CAPABILITY_NOT_METERED)); 9636 detailedCallback.expect(BLOCKED_STATUS_INT, mCellAgent, 9637 cb -> cb.getReason() == BLOCKED_REASON_NONE); 9638 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetwork()); 9639 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 9640 assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 9641 assertExtraInfoFromCmPresent(mCellAgent); 9642 9643 mCellAgent.removeCapability(NET_CAPABILITY_NOT_METERED); 9644 cellNetworkCallback.expectCaps(mCellAgent, 9645 c -> !c.hasCapability(NET_CAPABILITY_NOT_METERED)); 9646 cellNetworkCallback.expect(BLOCKED_STATUS, mCellAgent, cb -> cb.getBlocked()); 9647 detailedCallback.expectCaps(mCellAgent, 9648 c -> !c.hasCapability(NET_CAPABILITY_NOT_METERED)); 9649 detailedCallback.expect(BLOCKED_STATUS_INT, mCellAgent, 9650 cb -> cb.getReason() == BLOCKED_METERED_REASON_DATA_SAVER); 9651 assertNull(mCm.getActiveNetwork()); 9652 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); 9653 assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); 9654 assertExtraInfoFromCmBlocked(mCellAgent); 9655 9656 setBlockedReasonChanged(BLOCKED_REASON_NONE); 9657 cellNetworkCallback.expect(BLOCKED_STATUS, mCellAgent, cb -> !cb.getBlocked()); 9658 detailedCallback.expect(BLOCKED_STATUS_INT, mCellAgent, 9659 cb -> cb.getReason() == BLOCKED_REASON_NONE); 9660 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetwork()); 9661 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 9662 assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 9663 assertExtraInfoFromCmPresent(mCellAgent); 9664 9665 setBlockedReasonChanged(BLOCKED_REASON_NONE); 9666 cellNetworkCallback.assertNoCallback(); 9667 detailedCallback.assertNoCallback(); 9668 9669 // Restrict background data. Networking is not blocked because the network is unmetered. 9670 setBlockedReasonChanged(BLOCKED_METERED_REASON_DATA_SAVER); 9671 cellNetworkCallback.expect(BLOCKED_STATUS, mCellAgent, cb -> cb.getBlocked()); 9672 detailedCallback.expect(BLOCKED_STATUS_INT, mCellAgent, 9673 cb -> cb.getReason() == BLOCKED_METERED_REASON_DATA_SAVER); 9674 assertNull(mCm.getActiveNetwork()); 9675 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); 9676 assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); 9677 assertExtraInfoFromCmBlocked(mCellAgent); 9678 setBlockedReasonChanged(BLOCKED_METERED_REASON_DATA_SAVER); 9679 cellNetworkCallback.assertNoCallback(); 9680 9681 setBlockedReasonChanged(BLOCKED_REASON_NONE); 9682 cellNetworkCallback.expect(BLOCKED_STATUS, mCellAgent, cb -> !cb.getBlocked()); 9683 detailedCallback.expect(BLOCKED_STATUS_INT, mCellAgent, 9684 cb -> cb.getReason() == BLOCKED_REASON_NONE); 9685 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 9686 assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 9687 assertExtraInfoFromCmPresent(mCellAgent); 9688 9689 setBlockedReasonChanged(BLOCKED_REASON_NONE); 9690 cellNetworkCallback.assertNoCallback(); 9691 detailedCallback.assertNoCallback(); 9692 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetwork()); 9693 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 9694 assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 9695 assertExtraInfoFromCmPresent(mCellAgent); 9696 9697 mCm.unregisterNetworkCallback(cellNetworkCallback); 9698 } 9699 9700 @Test 9701 public void testNetworkBlockedStatusBeforeAndAfterConnect() throws Exception { 9702 final TestNetworkCallback defaultCallback = new TestNetworkCallback(); 9703 mCm.registerDefaultNetworkCallback(defaultCallback); 9704 mockUidNetworkingBlocked(); 9705 9706 // No Networkcallbacks invoked before any network is active. 9707 setBlockedReasonChanged(BLOCKED_REASON_BATTERY_SAVER); 9708 setBlockedReasonChanged(BLOCKED_REASON_NONE); 9709 setBlockedReasonChanged(BLOCKED_METERED_REASON_DATA_SAVER); 9710 defaultCallback.assertNoCallback(); 9711 9712 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 9713 mCellAgent.connect(true); 9714 defaultCallback.expectAvailableCallbacksUnvalidatedAndBlocked(mCellAgent); 9715 defaultCallback.expectCaps(mCellAgent, c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 9716 9717 // Allow to use the network after switching to NOT_METERED network. 9718 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 9719 mWiFiAgent.addCapability(NET_CAPABILITY_NOT_METERED); 9720 mWiFiAgent.connect(true); 9721 defaultCallback.expectAvailableDoubleValidatedCallbacks(mWiFiAgent); 9722 9723 // Switch to METERED network. Restrict the use of the network. 9724 mWiFiAgent.disconnect(); 9725 defaultCallback.expect(LOST, mWiFiAgent); 9726 defaultCallback.expectAvailableCallbacksValidatedAndBlocked(mCellAgent); 9727 9728 // Network becomes NOT_METERED. 9729 mCellAgent.addCapability(NET_CAPABILITY_NOT_METERED); 9730 defaultCallback.expectCaps(mCellAgent, c -> c.hasCapability(NET_CAPABILITY_NOT_METERED)); 9731 defaultCallback.expect(BLOCKED_STATUS, mCellAgent, cb -> !cb.getBlocked()); 9732 9733 // Verify there's no Networkcallbacks invoked after data saver on/off. 9734 setBlockedReasonChanged(BLOCKED_METERED_REASON_DATA_SAVER); 9735 setBlockedReasonChanged(BLOCKED_REASON_NONE); 9736 defaultCallback.assertNoCallback(); 9737 9738 mCellAgent.disconnect(); 9739 defaultCallback.expect(LOST, mCellAgent); 9740 defaultCallback.assertNoCallback(); 9741 9742 mCm.unregisterNetworkCallback(defaultCallback); 9743 } 9744 9745 private void expectNetworkRejectNonSecureVpn(InOrder inOrder, boolean add, 9746 UidRangeParcel... expected) throws Exception { 9747 inOrder.verify(mMockNetd).networkRejectNonSecureVpn(eq(add), aryEq(expected)); 9748 } 9749 9750 private void checkNetworkInfo(NetworkInfo ni, int type, DetailedState state) { 9751 assertNotNull(ni); 9752 assertEquals(type, ni.getType()); 9753 assertEquals(ConnectivityManager.getNetworkTypeName(type), state, ni.getDetailedState()); 9754 if (state == DetailedState.CONNECTED || state == DetailedState.SUSPENDED) { 9755 assertNotNull(ni.getExtraInfo()); 9756 } else { 9757 // Technically speaking, a network that's in CONNECTING state will generally have a 9758 // non-null extraInfo. This doesn't actually happen in this test because it never calls 9759 // a legacy API while a network is connecting. When a network is in CONNECTING state 9760 // because of legacy lockdown VPN, its extraInfo is always null. 9761 assertNull(ni.getExtraInfo()); 9762 } 9763 } 9764 9765 private void assertActiveNetworkInfo(int type, DetailedState state) { 9766 checkNetworkInfo(mCm.getActiveNetworkInfo(), type, state); 9767 } 9768 private void assertNetworkInfo(int type, DetailedState state) { 9769 checkNetworkInfo(mCm.getNetworkInfo(type), type, state); 9770 } 9771 9772 private void assertExtraInfoFromCm(TestNetworkAgentWrapper network, boolean present) { 9773 final NetworkInfo niForNetwork = mCm.getNetworkInfo(network.getNetwork()); 9774 final NetworkInfo niForType = mCm.getNetworkInfo(network.getLegacyType()); 9775 if (present) { 9776 assertEquals(network.getExtraInfo(), niForNetwork.getExtraInfo()); 9777 assertEquals(network.getExtraInfo(), niForType.getExtraInfo()); 9778 } else { 9779 assertNull(niForNetwork.getExtraInfo()); 9780 assertNull(niForType.getExtraInfo()); 9781 } 9782 } 9783 9784 private void assertExtraInfoFromCmBlocked(TestNetworkAgentWrapper network) { 9785 assertExtraInfoFromCm(network, false); 9786 } 9787 9788 private void assertExtraInfoFromCmPresent(TestNetworkAgentWrapper network) { 9789 assertExtraInfoFromCm(network, true); 9790 } 9791 9792 // Checks that each of the |agents| receive a blocked status change callback with the specified 9793 // |blocked| value, in any order. This is needed because when an event affects multiple 9794 // networks, ConnectivityService does not guarantee the order in which callbacks are fired. 9795 private void assertBlockedCallbackInAnyOrder(TestNetworkCallback callback, boolean blocked, 9796 TestNetworkAgentWrapper... agents) { 9797 final List<Network> expectedNetworks = asList(agents).stream() 9798 .map((agent) -> agent.getNetwork()) 9799 .collect(Collectors.toList()); 9800 9801 // Expect exactly one blocked callback for each agent. 9802 for (int i = 0; i < agents.length; i++) { 9803 final CallbackEntry e = callback.expect(BLOCKED_STATUS, TIMEOUT_MS, 9804 c -> c.getBlocked() == blocked); 9805 final Network network = e.getNetwork(); 9806 assertTrue("Received unexpected blocked callback for network " + network, 9807 expectedNetworks.remove(network)); 9808 } 9809 } 9810 9811 @Test 9812 public void testNetworkBlockedStatusAlwaysOnVpn() throws Exception { 9813 mServiceContext.setPermission( 9814 Manifest.permission.CONTROL_ALWAYS_ON_VPN, PERMISSION_GRANTED); 9815 mServiceContext.setPermission( 9816 Manifest.permission.CONTROL_VPN, PERMISSION_GRANTED); 9817 mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_GRANTED); 9818 9819 final TestNetworkCallback callback = new TestNetworkCallback(); 9820 final NetworkRequest request = new NetworkRequest.Builder() 9821 .removeCapability(NET_CAPABILITY_NOT_VPN) 9822 .build(); 9823 mCm.registerNetworkCallback(request, callback); 9824 9825 final TestNetworkCallback defaultCallback = new TestNetworkCallback(); 9826 mCm.registerDefaultNetworkCallback(defaultCallback); 9827 9828 final TestNetworkCallback vpnUidCallback = new TestNetworkCallback(); 9829 final NetworkRequest vpnUidRequest = new NetworkRequest.Builder().build(); 9830 registerNetworkCallbackAsUid(vpnUidRequest, vpnUidCallback, VPN_UID); 9831 9832 final TestNetworkCallback vpnUidDefaultCallback = new TestNetworkCallback(); 9833 registerDefaultNetworkCallbackAsUid(vpnUidDefaultCallback, VPN_UID); 9834 9835 final TestNetworkCallback vpnDefaultCallbackAsUid = new TestNetworkCallback(); 9836 mCm.registerDefaultNetworkCallbackForUid(VPN_UID, vpnDefaultCallbackAsUid, 9837 new Handler(ConnectivityThread.getInstanceLooper())); 9838 9839 final int uid = Process.myUid(); 9840 final ArrayList<String> allowList = new ArrayList<>(); 9841 mMockVpn.setAlwaysOnPackage(ALWAYS_ON_PACKAGE, true /* lockdown */, allowList); 9842 waitForIdle(); 9843 9844 final Set<Integer> excludedUids = new ArraySet<Integer>(); 9845 excludedUids.add(VPN_UID); 9846 if (mDeps.isAtLeastT()) { 9847 // On T onwards, the corresponding SDK sandbox UID should also be excluded 9848 excludedUids.add(toSdkSandboxUid(VPN_UID)); 9849 } 9850 final UidRangeParcel[] uidRangeParcels = uidRangeParcelsExcludingUids( 9851 excludedUids.toArray(new Integer[0])); 9852 InOrder inOrder = inOrder(mMockNetd); 9853 expectNetworkRejectNonSecureVpn(inOrder, true, uidRangeParcels); 9854 9855 // Connect a network when lockdown is active, expect to see it blocked. 9856 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 9857 mWiFiAgent.connect(false /* validated */); 9858 callback.expectAvailableCallbacksUnvalidatedAndBlocked(mWiFiAgent); 9859 defaultCallback.expectAvailableCallbacksUnvalidatedAndBlocked(mWiFiAgent); 9860 vpnUidCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 9861 vpnUidDefaultCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 9862 vpnDefaultCallbackAsUid.expectAvailableCallbacksUnvalidated(mWiFiAgent); 9863 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetworkForUid(VPN_UID)); 9864 assertNull(mCm.getActiveNetwork()); 9865 assertActiveNetworkInfo(TYPE_WIFI, DetailedState.BLOCKED); 9866 // Mobile is BLOCKED even though it's not actually connected. 9867 assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); 9868 assertNetworkInfo(TYPE_WIFI, DetailedState.BLOCKED); 9869 9870 // Disable lockdown, expect to see the network unblocked. 9871 mMockVpn.setAlwaysOnPackage(null, false /* lockdown */, allowList); 9872 callback.expect(BLOCKED_STATUS, mWiFiAgent, cb -> !cb.getBlocked()); 9873 defaultCallback.expect(BLOCKED_STATUS, mWiFiAgent, cb -> !cb.getBlocked()); 9874 vpnUidCallback.assertNoCallback(); 9875 vpnUidDefaultCallback.assertNoCallback(); 9876 vpnDefaultCallbackAsUid.assertNoCallback(); 9877 expectNetworkRejectNonSecureVpn(inOrder, false, uidRangeParcels); 9878 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetworkForUid(VPN_UID)); 9879 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetwork()); 9880 assertActiveNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 9881 assertNetworkInfo(TYPE_MOBILE, DetailedState.DISCONNECTED); 9882 assertNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 9883 9884 // Add our UID to the allowlist and re-enable lockdown, expect network is not blocked. 9885 allowList.add(TEST_PACKAGE_NAME); 9886 mMockVpn.setAlwaysOnPackage(ALWAYS_ON_PACKAGE, true /* lockdown */, allowList); 9887 callback.assertNoCallback(); 9888 defaultCallback.assertNoCallback(); 9889 vpnUidCallback.assertNoCallback(); 9890 vpnUidDefaultCallback.assertNoCallback(); 9891 vpnDefaultCallbackAsUid.assertNoCallback(); 9892 9893 excludedUids.add(uid); 9894 if (mDeps.isAtLeastT()) { 9895 // On T onwards, the corresponding SDK sandbox UID should also be excluded 9896 excludedUids.add(toSdkSandboxUid(uid)); 9897 } 9898 final UidRangeParcel[] uidRangeParcelsAlsoExcludingUs = uidRangeParcelsExcludingUids( 9899 excludedUids.toArray(new Integer[0])); 9900 expectNetworkRejectNonSecureVpn(inOrder, true, uidRangeParcelsAlsoExcludingUs); 9901 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetworkForUid(VPN_UID)); 9902 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetwork()); 9903 assertActiveNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 9904 assertNetworkInfo(TYPE_MOBILE, DetailedState.DISCONNECTED); 9905 assertNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 9906 9907 // Connect a new network, expect it to be unblocked. 9908 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 9909 mCellAgent.connect(false /* validated */); 9910 callback.expectAvailableCallbacksUnvalidated(mCellAgent); 9911 defaultCallback.assertNoCallback(); 9912 vpnUidCallback.expectAvailableCallbacksUnvalidated(mCellAgent); 9913 vpnUidDefaultCallback.assertNoCallback(); 9914 vpnDefaultCallbackAsUid.assertNoCallback(); 9915 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetworkForUid(VPN_UID)); 9916 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetwork()); 9917 assertActiveNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 9918 // Cellular is DISCONNECTED because it's not the default and there are no requests for it. 9919 assertNetworkInfo(TYPE_MOBILE, DetailedState.DISCONNECTED); 9920 assertNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 9921 9922 // Disable lockdown, remove our UID from the allowlist, and re-enable lockdown. 9923 // Everything should now be blocked. 9924 mMockVpn.setAlwaysOnPackage(null, false /* lockdown */, allowList); 9925 waitForIdle(); 9926 expectNetworkRejectNonSecureVpn(inOrder, false, uidRangeParcelsAlsoExcludingUs); 9927 allowList.clear(); 9928 mMockVpn.setAlwaysOnPackage(ALWAYS_ON_PACKAGE, true /* lockdown */, allowList); 9929 waitForIdle(); 9930 expectNetworkRejectNonSecureVpn(inOrder, true, uidRangeParcels); 9931 defaultCallback.expect(BLOCKED_STATUS, mWiFiAgent, cb -> cb.getBlocked()); 9932 assertBlockedCallbackInAnyOrder(callback, true, mWiFiAgent, mCellAgent); 9933 vpnUidCallback.assertNoCallback(); 9934 vpnUidDefaultCallback.assertNoCallback(); 9935 vpnDefaultCallbackAsUid.assertNoCallback(); 9936 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetworkForUid(VPN_UID)); 9937 assertNull(mCm.getActiveNetwork()); 9938 assertActiveNetworkInfo(TYPE_WIFI, DetailedState.BLOCKED); 9939 assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); 9940 assertNetworkInfo(TYPE_WIFI, DetailedState.BLOCKED); 9941 9942 // Disable lockdown. Everything is unblocked. 9943 mMockVpn.setAlwaysOnPackage(null, false /* lockdown */, allowList); 9944 defaultCallback.expect(BLOCKED_STATUS, mWiFiAgent, cb -> !cb.getBlocked()); 9945 assertBlockedCallbackInAnyOrder(callback, false, mWiFiAgent, mCellAgent); 9946 vpnUidCallback.assertNoCallback(); 9947 vpnUidDefaultCallback.assertNoCallback(); 9948 vpnDefaultCallbackAsUid.assertNoCallback(); 9949 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetworkForUid(VPN_UID)); 9950 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetwork()); 9951 assertActiveNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 9952 assertNetworkInfo(TYPE_MOBILE, DetailedState.DISCONNECTED); 9953 assertNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 9954 9955 // Enable and disable an always-on VPN package without lockdown. Expect no changes. 9956 reset(mMockNetd); 9957 mMockVpn.setAlwaysOnPackage(ALWAYS_ON_PACKAGE, false /* lockdown */, allowList); 9958 inOrder.verify(mMockNetd, never()).networkRejectNonSecureVpn(anyBoolean(), any()); 9959 callback.assertNoCallback(); 9960 defaultCallback.assertNoCallback(); 9961 vpnUidCallback.assertNoCallback(); 9962 vpnUidDefaultCallback.assertNoCallback(); 9963 vpnDefaultCallbackAsUid.assertNoCallback(); 9964 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetworkForUid(VPN_UID)); 9965 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetwork()); 9966 assertActiveNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 9967 assertNetworkInfo(TYPE_MOBILE, DetailedState.DISCONNECTED); 9968 assertNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 9969 9970 mMockVpn.setAlwaysOnPackage(null, false /* lockdown */, allowList); 9971 inOrder.verify(mMockNetd, never()).networkRejectNonSecureVpn(anyBoolean(), any()); 9972 callback.assertNoCallback(); 9973 defaultCallback.assertNoCallback(); 9974 vpnUidCallback.assertNoCallback(); 9975 vpnUidDefaultCallback.assertNoCallback(); 9976 vpnDefaultCallbackAsUid.assertNoCallback(); 9977 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetworkForUid(VPN_UID)); 9978 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetwork()); 9979 assertActiveNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 9980 assertNetworkInfo(TYPE_MOBILE, DetailedState.DISCONNECTED); 9981 assertNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 9982 9983 // Enable lockdown and connect a VPN. The VPN is not blocked. 9984 mMockVpn.setAlwaysOnPackage(ALWAYS_ON_PACKAGE, true /* lockdown */, allowList); 9985 defaultCallback.expect(BLOCKED_STATUS, mWiFiAgent, cb -> cb.getBlocked()); 9986 assertBlockedCallbackInAnyOrder(callback, true, mWiFiAgent, mCellAgent); 9987 vpnUidCallback.assertNoCallback(); 9988 vpnUidDefaultCallback.assertNoCallback(); 9989 vpnDefaultCallbackAsUid.assertNoCallback(); 9990 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetworkForUid(VPN_UID)); 9991 assertNull(mCm.getActiveNetwork()); 9992 assertActiveNetworkInfo(TYPE_WIFI, DetailedState.BLOCKED); 9993 assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); 9994 assertNetworkInfo(TYPE_WIFI, DetailedState.BLOCKED); 9995 9996 mMockVpn.establishForMyUid(); 9997 assertUidRangesUpdatedForMyUid(true); 9998 defaultCallback.expectAvailableThenValidatedCallbacks(mMockVpn); 9999 vpnUidCallback.assertNoCallback(); // vpnUidCallback has NOT_VPN capability. 10000 vpnUidDefaultCallback.assertNoCallback(); // VPN does not apply to VPN_UID 10001 vpnDefaultCallbackAsUid.assertNoCallback(); 10002 assertEquals(mMockVpn.getNetwork(), mCm.getActiveNetwork()); 10003 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetworkForUid(VPN_UID)); 10004 assertActiveNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 10005 assertNetworkInfo(TYPE_MOBILE, DetailedState.DISCONNECTED); 10006 assertNetworkInfo(TYPE_VPN, DetailedState.CONNECTED); 10007 assertNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 10008 10009 mMockVpn.disconnect(); 10010 defaultCallback.expect(LOST, mMockVpn); 10011 defaultCallback.expectAvailableCallbacksUnvalidatedAndBlocked(mWiFiAgent); 10012 vpnUidCallback.assertNoCallback(); 10013 vpnUidDefaultCallback.assertNoCallback(); 10014 vpnDefaultCallbackAsUid.assertNoCallback(); 10015 assertNull(mCm.getActiveNetwork()); 10016 10017 mCm.unregisterNetworkCallback(callback); 10018 mCm.unregisterNetworkCallback(defaultCallback); 10019 mCm.unregisterNetworkCallback(vpnUidCallback); 10020 mCm.unregisterNetworkCallback(vpnUidDefaultCallback); 10021 mCm.unregisterNetworkCallback(vpnDefaultCallbackAsUid); 10022 } 10023 10024 @Test 10025 public void testVpnExcludesOwnUid() throws Exception { 10026 // required for registerDefaultNetworkCallbackForUid. 10027 mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_GRANTED); 10028 10029 // Connect Wi-Fi. 10030 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 10031 mWiFiAgent.connect(true /* validated */); 10032 10033 // Connect a VPN that excludes its UID from its UID ranges. 10034 final LinkProperties lp = new LinkProperties(); 10035 lp.setInterfaceName(VPN_IFNAME); 10036 final int myUid = Process.myUid(); 10037 final Set<UidRange> ranges = new ArraySet<>(); 10038 ranges.add(new UidRange(0, myUid - 1)); 10039 ranges.add(new UidRange(myUid + 1, UserHandle.PER_USER_RANGE - 1)); 10040 mMockVpn.setUnderlyingNetworks(new Network[] { mWiFiAgent.getNetwork() }); 10041 mMockVpn.establish(lp, myUid, ranges); 10042 10043 // Wait for validation before registering callbacks. 10044 waitForIdle(); 10045 10046 final int otherUid = myUid + 1; 10047 final Handler h = new Handler(ConnectivityThread.getInstanceLooper()); 10048 final TestNetworkCallback otherUidCb = new TestNetworkCallback(); 10049 final TestNetworkCallback defaultCb = new TestNetworkCallback(); 10050 final TestNetworkCallback perUidCb = new TestNetworkCallback(); 10051 registerDefaultNetworkCallbackAsUid(otherUidCb, otherUid); 10052 mCm.registerDefaultNetworkCallback(defaultCb, h); 10053 doAsUid(Process.SYSTEM_UID, 10054 () -> mCm.registerDefaultNetworkCallbackForUid(myUid, perUidCb, h)); 10055 10056 otherUidCb.expectAvailableCallbacksValidated(mMockVpn); 10057 // BUG (b/195265065): the default network for the VPN app is actually Wi-Fi, not the VPN. 10058 defaultCb.expectAvailableCallbacksValidated(mMockVpn); 10059 perUidCb.expectAvailableCallbacksValidated(mMockVpn); 10060 // getActiveNetwork is not affected by this bug. 10061 assertEquals(mMockVpn.getNetwork(), mCm.getActiveNetworkForUid(myUid + 1)); 10062 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetwork()); 10063 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetworkForUid(myUid)); 10064 10065 doAsUid(otherUid, () -> mCm.unregisterNetworkCallback(otherUidCb)); 10066 mCm.unregisterNetworkCallback(defaultCb); 10067 doAsUid(Process.SYSTEM_UID, () -> mCm.unregisterNetworkCallback(perUidCb)); 10068 } 10069 10070 private VpnProfile setupLegacyLockdownVpn() { 10071 final String profileName = "testVpnProfile"; 10072 final byte[] profileTag = profileName.getBytes(StandardCharsets.UTF_8); 10073 doReturn(profileTag).when(mVpnProfileStore).get(Credentials.LOCKDOWN_VPN); 10074 10075 final VpnProfile profile = new VpnProfile(profileName); 10076 profile.name = "My VPN"; 10077 profile.server = "192.0.2.1"; 10078 profile.dnsServers = "8.8.8.8"; 10079 profile.type = VpnProfile.TYPE_IPSEC_XAUTH_PSK; 10080 final byte[] encodedProfile = profile.encode(); 10081 doReturn(encodedProfile).when(mVpnProfileStore).get(Credentials.VPN + profileName); 10082 10083 return profile; 10084 } 10085 10086 private void establishLegacyLockdownVpn(Network underlying) throws Exception { 10087 // The legacy lockdown VPN only supports userId 0, and must have an underlying network. 10088 assertNotNull(underlying); 10089 mMockVpn.setVpnType(VpnManager.TYPE_VPN_LEGACY); 10090 // The legacy lockdown VPN only supports userId 0. 10091 final Set<UidRange> ranges = Collections.singleton(PRIMARY_UIDRANGE); 10092 mMockVpn.registerAgent(ranges); 10093 mMockVpn.setUnderlyingNetworks(new Network[]{underlying}); 10094 mMockVpn.connect(true); 10095 } 10096 10097 @Test 10098 public void testLegacyLockdownVpn() throws Exception { 10099 mServiceContext.setPermission( 10100 Manifest.permission.CONTROL_VPN, PERMISSION_GRANTED); 10101 10102 final NetworkRequest request = new NetworkRequest.Builder().clearCapabilities().build(); 10103 final TestNetworkCallback callback = new TestNetworkCallback(); 10104 mCm.registerNetworkCallback(request, callback); 10105 10106 final TestNetworkCallback defaultCallback = new TestNetworkCallback(); 10107 mCm.registerDefaultNetworkCallback(defaultCallback); 10108 10109 final TestNetworkCallback systemDefaultCallback = new TestNetworkCallback(); 10110 mCm.registerSystemDefaultNetworkCallback(systemDefaultCallback, 10111 new Handler(ConnectivityThread.getInstanceLooper())); 10112 10113 // Pretend lockdown VPN was configured. 10114 final VpnProfile profile = setupLegacyLockdownVpn(); 10115 10116 // LockdownVpnTracker disables the Vpn teardown code and enables lockdown. 10117 // Check the VPN's state before it does so. 10118 assertTrue(mMockVpn.getEnableTeardown()); 10119 assertFalse(mMockVpn.getLockdown()); 10120 10121 // VMSHandlerThread was used inside VpnManagerService and taken into LockDownVpnTracker. 10122 // VpnManagerService was decoupled from this test but this handlerThread is still required 10123 // in LockDownVpnTracker. Keep it until LockDownVpnTracker related verification is moved to 10124 // its own test. 10125 final HandlerThread VMSHandlerThread = new HandlerThread("TestVpnManagerService"); 10126 VMSHandlerThread.start(); 10127 10128 // LockdownVpnTracker is created from VpnManagerService but VpnManagerService is decoupled 10129 // from ConnectivityServiceTest. Create it directly to simulate LockdownVpnTracker is 10130 // created. 10131 // TODO: move LockdownVpnTracker related tests to its own test. 10132 // Lockdown VPN disables teardown and enables lockdown. 10133 final LockdownVpnTracker lockdownVpnTracker = new LockdownVpnTracker(mServiceContext, 10134 VMSHandlerThread.getThreadHandler(), mMockVpn, profile); 10135 lockdownVpnTracker.init(); 10136 assertFalse(mMockVpn.getEnableTeardown()); 10137 assertTrue(mMockVpn.getLockdown()); 10138 10139 // Bring up a network. 10140 // Expect nothing to happen because the network does not have an IPv4 default route: legacy 10141 // VPN only supports IPv4. 10142 final LinkProperties cellLp = new LinkProperties(); 10143 cellLp.setInterfaceName("rmnet0"); 10144 cellLp.addLinkAddress(new LinkAddress("2001:db8::1/64")); 10145 cellLp.addRoute(new RouteInfo(new IpPrefix("::/0"), null, "rmnet0")); 10146 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp); 10147 mCellAgent.connect(false /* validated */); 10148 callback.expectAvailableCallbacksUnvalidatedAndBlocked(mCellAgent); 10149 defaultCallback.expectAvailableCallbacksUnvalidatedAndBlocked(mCellAgent); 10150 systemDefaultCallback.expectAvailableCallbacksUnvalidatedAndBlocked(mCellAgent); 10151 waitForIdle(); 10152 assertNull(mMockVpn.getAgent()); 10153 10154 // Add an IPv4 address. Ideally the VPN should start, but it doesn't because nothing calls 10155 // LockdownVpnTracker#handleStateChangedLocked. This is a bug. 10156 // TODO: consider fixing this. 10157 cellLp.addLinkAddress(new LinkAddress("192.0.2.2/25")); 10158 cellLp.addRoute(new RouteInfo(new IpPrefix("0.0.0.0/0"), null, "rmnet0")); 10159 mCellAgent.sendLinkProperties(cellLp); 10160 callback.expect(LINK_PROPERTIES_CHANGED, mCellAgent); 10161 defaultCallback.expect(LINK_PROPERTIES_CHANGED, mCellAgent); 10162 systemDefaultCallback.expect(LINK_PROPERTIES_CHANGED, mCellAgent); 10163 waitForIdle(); 10164 assertNull(mMockVpn.getAgent()); 10165 10166 // Disconnect, then try again with a network that supports IPv4 at connection time. 10167 // Expect lockdown VPN to come up. 10168 ExpectedBroadcast b1 = expectConnectivityAction(TYPE_MOBILE, DetailedState.DISCONNECTED); 10169 mCellAgent.disconnect(); 10170 callback.expect(LOST, mCellAgent); 10171 defaultCallback.expect(LOST, mCellAgent); 10172 systemDefaultCallback.expect(LOST, mCellAgent); 10173 b1.expectBroadcast(); 10174 10175 // When lockdown VPN is active, the NetworkInfo state in CONNECTIVITY_ACTION is overwritten 10176 // with the state of the VPN network. So expect a CONNECTING broadcast. 10177 b1 = expectConnectivityAction(TYPE_MOBILE, DetailedState.CONNECTING); 10178 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp); 10179 mCellAgent.connect(false /* validated */); 10180 callback.expectAvailableCallbacksUnvalidatedAndBlocked(mCellAgent); 10181 defaultCallback.expectAvailableCallbacksUnvalidatedAndBlocked(mCellAgent); 10182 systemDefaultCallback.expectAvailableCallbacksUnvalidatedAndBlocked(mCellAgent); 10183 b1.expectBroadcast(); 10184 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); 10185 assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); 10186 assertNetworkInfo(TYPE_WIFI, DetailedState.BLOCKED); 10187 assertNetworkInfo(TYPE_VPN, DetailedState.BLOCKED); 10188 assertExtraInfoFromCmBlocked(mCellAgent); 10189 10190 // TODO: it would be nice if we could simply rely on the production code here, and have 10191 // LockdownVpnTracker start the VPN, have the VPN code register its NetworkAgent with 10192 // ConnectivityService, etc. That would require duplicating a fair bit of code from the 10193 // Vpn tests around how to mock out LegacyVpnRunner. But even if we did that, this does not 10194 // work for at least two reasons: 10195 // 1. In this test, calling registerNetworkAgent does not actually result in an agent being 10196 // registered. This is because nothing calls onNetworkMonitorCreated, which is what 10197 // actually ends up causing handleRegisterNetworkAgent to be called. Code in this test 10198 // that wants to register an agent must use TestNetworkAgentWrapper. 10199 // 2. Even if we exposed Vpn#agentConnect to the test, and made MockVpn#agentConnect call 10200 // the TestNetworkAgentWrapper code, this would deadlock because the 10201 // TestNetworkAgentWrapper code cannot be called on the handler thread since it calls 10202 // waitForIdle(). 10203 mMockVpn.expectStartLegacyVpnRunner(); 10204 b1 = expectConnectivityAction(TYPE_VPN, DetailedState.CONNECTED); 10205 ExpectedBroadcast b2 = expectConnectivityAction(TYPE_MOBILE, DetailedState.CONNECTED); 10206 establishLegacyLockdownVpn(mCellAgent.getNetwork()); 10207 callback.expectAvailableThenValidatedCallbacks(mMockVpn); 10208 defaultCallback.expectAvailableThenValidatedCallbacks(mMockVpn); 10209 systemDefaultCallback.assertNoCallback(); 10210 NetworkCapabilities vpnNc = mCm.getNetworkCapabilities(mMockVpn.getNetwork()); 10211 b1.expectBroadcast(); 10212 b2.expectBroadcast(); 10213 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 10214 assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 10215 assertNetworkInfo(TYPE_WIFI, DetailedState.DISCONNECTED); 10216 assertNetworkInfo(TYPE_VPN, DetailedState.CONNECTED); 10217 assertExtraInfoFromCmPresent(mCellAgent); 10218 assertTrue(vpnNc.hasTransport(TRANSPORT_VPN)); 10219 assertTrue(vpnNc.hasTransport(TRANSPORT_CELLULAR)); 10220 assertFalse(vpnNc.hasTransport(TRANSPORT_WIFI)); 10221 assertFalse(vpnNc.hasCapability(NET_CAPABILITY_NOT_METERED)); 10222 assertVpnTransportInfo(vpnNc, VpnManager.TYPE_VPN_LEGACY); 10223 10224 // Switch default network from cell to wifi. Expect VPN to disconnect and reconnect. 10225 final LinkProperties wifiLp = new LinkProperties(); 10226 wifiLp.setInterfaceName("wlan0"); 10227 wifiLp.addLinkAddress(new LinkAddress("192.0.2.163/25")); 10228 wifiLp.addRoute(new RouteInfo(new IpPrefix("0.0.0.0/0"), null, "wlan0")); 10229 final NetworkCapabilities wifiNc = new NetworkCapabilities(); 10230 wifiNc.addTransportType(TRANSPORT_WIFI); 10231 wifiNc.addCapability(NET_CAPABILITY_NOT_METERED); 10232 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, wifiLp, wifiNc); 10233 10234 b1 = expectConnectivityAction(TYPE_MOBILE, DetailedState.DISCONNECTED); 10235 // Wifi is CONNECTING because the VPN isn't up yet. 10236 b2 = expectConnectivityAction(TYPE_WIFI, DetailedState.CONNECTING); 10237 ExpectedBroadcast b3 = expectConnectivityAction(TYPE_VPN, DetailedState.DISCONNECTED); 10238 mWiFiAgent.connect(false /* validated */); 10239 b1.expectBroadcast(); 10240 b2.expectBroadcast(); 10241 b3.expectBroadcast(); 10242 mMockVpn.expectStopVpnRunnerPrivileged(); 10243 mMockVpn.expectStartLegacyVpnRunner(); 10244 10245 // TODO: why is wifi not blocked? Is it because when this callback is sent, the VPN is still 10246 // connected, so the network is not considered blocked by the lockdown UID ranges? But the 10247 // fact that a VPN is connected should only result in the VPN itself being unblocked, not 10248 // any other network. Bug in isUidBlockedByVpn? 10249 callback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 10250 callback.expect(LOST, mMockVpn); 10251 defaultCallback.expect(LOST, mMockVpn); 10252 defaultCallback.expectAvailableCallbacksUnvalidatedAndBlocked(mWiFiAgent); 10253 systemDefaultCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 10254 10255 // While the VPN is reconnecting on the new network, everything is blocked. 10256 assertActiveNetworkInfo(TYPE_WIFI, DetailedState.BLOCKED); 10257 assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); 10258 assertNetworkInfo(TYPE_WIFI, DetailedState.BLOCKED); 10259 assertNetworkInfo(TYPE_VPN, DetailedState.BLOCKED); 10260 assertExtraInfoFromCmBlocked(mWiFiAgent); 10261 10262 // The VPN comes up again on wifi. 10263 b1 = expectConnectivityAction(TYPE_VPN, DetailedState.CONNECTED); 10264 b2 = expectConnectivityAction(TYPE_WIFI, DetailedState.CONNECTED); 10265 establishLegacyLockdownVpn(mWiFiAgent.getNetwork()); 10266 callback.expectAvailableThenValidatedCallbacks(mMockVpn); 10267 defaultCallback.expectAvailableThenValidatedCallbacks(mMockVpn); 10268 systemDefaultCallback.assertNoCallback(); 10269 b1.expectBroadcast(); 10270 b2.expectBroadcast(); 10271 assertActiveNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 10272 assertNetworkInfo(TYPE_MOBILE, DetailedState.DISCONNECTED); 10273 assertNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 10274 assertNetworkInfo(TYPE_VPN, DetailedState.CONNECTED); 10275 assertExtraInfoFromCmPresent(mWiFiAgent); 10276 vpnNc = mCm.getNetworkCapabilities(mMockVpn.getNetwork()); 10277 assertTrue(vpnNc.hasTransport(TRANSPORT_VPN)); 10278 assertTrue(vpnNc.hasTransport(TRANSPORT_WIFI)); 10279 assertFalse(vpnNc.hasTransport(TRANSPORT_CELLULAR)); 10280 assertTrue(vpnNc.hasCapability(NET_CAPABILITY_NOT_METERED)); 10281 10282 // Disconnect cell. Nothing much happens since it's not the default network. 10283 mCellAgent.disconnect(); 10284 callback.expect(LOST, mCellAgent); 10285 defaultCallback.assertNoCallback(); 10286 systemDefaultCallback.assertNoCallback(); 10287 10288 assertActiveNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 10289 assertNetworkInfo(TYPE_MOBILE, DetailedState.DISCONNECTED); 10290 assertNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 10291 assertNetworkInfo(TYPE_VPN, DetailedState.CONNECTED); 10292 assertExtraInfoFromCmPresent(mWiFiAgent); 10293 10294 b1 = expectConnectivityAction(TYPE_WIFI, DetailedState.DISCONNECTED); 10295 b2 = expectConnectivityAction(TYPE_VPN, DetailedState.DISCONNECTED); 10296 mWiFiAgent.disconnect(); 10297 callback.expect(LOST, mWiFiAgent); 10298 systemDefaultCallback.expect(LOST, mWiFiAgent); 10299 b1.expectBroadcast(); 10300 callback.expectCaps(mMockVpn, c -> !c.hasTransport(TRANSPORT_WIFI)); 10301 mMockVpn.expectStopVpnRunnerPrivileged(); 10302 callback.expect(LOST, mMockVpn); 10303 b2.expectBroadcast(); 10304 10305 VMSHandlerThread.quitSafely(); 10306 VMSHandlerThread.join(); 10307 } 10308 10309 @Test @IgnoreUpTo(Build.VERSION_CODES.S_V2) 10310 public void testLockdownSetFirewallUidRule() throws Exception { 10311 final Set<Range<Integer>> lockdownRange = UidRange.toIntRanges(Set.of(PRIMARY_UIDRANGE)); 10312 // Enable Lockdown 10313 mCm.setRequireVpnForUids(true /* requireVpn */, lockdownRange); 10314 waitForIdle(); 10315 10316 // Lockdown rule is set to apps uids 10317 verify(mBpfNetMaps, times(3)).updateUidLockdownRule(anyInt(), eq(true) /* add */); 10318 verify(mBpfNetMaps).updateUidLockdownRule(APP1_UID, true /* add */); 10319 verify(mBpfNetMaps).updateUidLockdownRule(APP2_UID, true /* add */); 10320 verify(mBpfNetMaps).updateUidLockdownRule(VPN_UID, true /* add */); 10321 10322 reset(mBpfNetMaps); 10323 10324 // Disable lockdown 10325 mCm.setRequireVpnForUids(false /* requireVPN */, lockdownRange); 10326 waitForIdle(); 10327 10328 // Lockdown rule is removed from apps uids 10329 verify(mBpfNetMaps, times(3)).updateUidLockdownRule(anyInt(), eq(false) /* add */); 10330 verify(mBpfNetMaps).updateUidLockdownRule(APP1_UID, false /* add */); 10331 verify(mBpfNetMaps).updateUidLockdownRule(APP2_UID, false /* add */); 10332 verify(mBpfNetMaps).updateUidLockdownRule(VPN_UID, false /* add */); 10333 10334 // Interface rules are not changed by Lockdown mode enable/disable 10335 verify(mBpfNetMaps, never()).addUidInterfaceRules(any(), any()); 10336 verify(mBpfNetMaps, never()).removeUidInterfaceRules(any()); 10337 } 10338 10339 private void doTestSetUidFirewallRule(final int chain, final int defaultRule) { 10340 final int uid = 1001; 10341 mCm.setUidFirewallRule(chain, uid, FIREWALL_RULE_ALLOW); 10342 verify(mBpfNetMaps).setUidRule(chain, uid, FIREWALL_RULE_ALLOW); 10343 reset(mBpfNetMaps); 10344 10345 mCm.setUidFirewallRule(chain, uid, FIREWALL_RULE_DENY); 10346 verify(mBpfNetMaps).setUidRule(chain, uid, FIREWALL_RULE_DENY); 10347 reset(mBpfNetMaps); 10348 10349 mCm.setUidFirewallRule(chain, uid, FIREWALL_RULE_DEFAULT); 10350 verify(mBpfNetMaps).setUidRule(chain, uid, defaultRule); 10351 reset(mBpfNetMaps); 10352 } 10353 10354 @Test @IgnoreUpTo(SC_V2) 10355 public void testSetUidFirewallRule() throws Exception { 10356 doTestSetUidFirewallRule(FIREWALL_CHAIN_DOZABLE, FIREWALL_RULE_DENY); 10357 doTestSetUidFirewallRule(FIREWALL_CHAIN_STANDBY, FIREWALL_RULE_ALLOW); 10358 doTestSetUidFirewallRule(FIREWALL_CHAIN_POWERSAVE, FIREWALL_RULE_DENY); 10359 doTestSetUidFirewallRule(FIREWALL_CHAIN_RESTRICTED, FIREWALL_RULE_DENY); 10360 doTestSetUidFirewallRule(FIREWALL_CHAIN_LOW_POWER_STANDBY, FIREWALL_RULE_DENY); 10361 doTestSetUidFirewallRule(FIREWALL_CHAIN_OEM_DENY_1, FIREWALL_RULE_ALLOW); 10362 doTestSetUidFirewallRule(FIREWALL_CHAIN_OEM_DENY_2, FIREWALL_RULE_ALLOW); 10363 doTestSetUidFirewallRule(FIREWALL_CHAIN_OEM_DENY_3, FIREWALL_RULE_ALLOW); 10364 } 10365 10366 @Test @IgnoreUpTo(SC_V2) 10367 public void testSetFirewallChainEnabled() throws Exception { 10368 final List<Integer> firewallChains = Arrays.asList( 10369 FIREWALL_CHAIN_DOZABLE, 10370 FIREWALL_CHAIN_STANDBY, 10371 FIREWALL_CHAIN_POWERSAVE, 10372 FIREWALL_CHAIN_RESTRICTED, 10373 FIREWALL_CHAIN_LOW_POWER_STANDBY, 10374 FIREWALL_CHAIN_OEM_DENY_1, 10375 FIREWALL_CHAIN_OEM_DENY_2, 10376 FIREWALL_CHAIN_OEM_DENY_3); 10377 for (final int chain: firewallChains) { 10378 mCm.setFirewallChainEnabled(chain, true /* enabled */); 10379 verify(mBpfNetMaps).setChildChain(chain, true /* enable */); 10380 reset(mBpfNetMaps); 10381 10382 mCm.setFirewallChainEnabled(chain, false /* enabled */); 10383 verify(mBpfNetMaps).setChildChain(chain, false /* enable */); 10384 reset(mBpfNetMaps); 10385 } 10386 } 10387 10388 private void doTestSetFirewallChainEnabledCloseSocket(final int chain, 10389 final boolean isAllowList) throws Exception { 10390 reset(mDestroySocketsWrapper); 10391 10392 mCm.setFirewallChainEnabled(chain, true /* enabled */); 10393 final Set<Integer> uids = 10394 new ArraySet<>(List.of(TEST_PACKAGE_UID, TEST_PACKAGE_UID2)); 10395 if (isAllowList) { 10396 final Set<Range<Integer>> range = new ArraySet<>( 10397 List.of(new Range<>(Process.FIRST_APPLICATION_UID, Integer.MAX_VALUE))); 10398 verify(mDestroySocketsWrapper).destroyLiveTcpSockets(range, uids); 10399 } else { 10400 verify(mDestroySocketsWrapper).destroyLiveTcpSocketsByOwnerUids(uids); 10401 } 10402 10403 mCm.setFirewallChainEnabled(chain, false /* enabled */); 10404 verifyNoMoreInteractions(mDestroySocketsWrapper); 10405 } 10406 10407 @Test @IgnoreUpTo(Build.VERSION_CODES.TIRAMISU) 10408 public void testSetFirewallChainEnabledCloseSocket() throws Exception { 10409 doReturn(new ArraySet<>(Arrays.asList(TEST_PACKAGE_UID, TEST_PACKAGE_UID2))) 10410 .when(mBpfNetMaps) 10411 .getUidsWithDenyRuleOnDenyListChain(anyInt()); 10412 doReturn(new ArraySet<>(Arrays.asList(TEST_PACKAGE_UID, TEST_PACKAGE_UID2))) 10413 .when(mBpfNetMaps) 10414 .getUidsWithAllowRuleOnAllowListChain(anyInt()); 10415 10416 final boolean allowlist = true; 10417 final boolean denylist = false; 10418 10419 doReturn(true).when(mBpfNetMaps).isFirewallAllowList(anyInt()); 10420 doTestSetFirewallChainEnabledCloseSocket(FIREWALL_CHAIN_DOZABLE, allowlist); 10421 doTestSetFirewallChainEnabledCloseSocket(FIREWALL_CHAIN_POWERSAVE, allowlist); 10422 doTestSetFirewallChainEnabledCloseSocket(FIREWALL_CHAIN_RESTRICTED, allowlist); 10423 doTestSetFirewallChainEnabledCloseSocket(FIREWALL_CHAIN_LOW_POWER_STANDBY, allowlist); 10424 10425 doReturn(false).when(mBpfNetMaps).isFirewallAllowList(anyInt()); 10426 doTestSetFirewallChainEnabledCloseSocket(FIREWALL_CHAIN_STANDBY, denylist); 10427 doTestSetFirewallChainEnabledCloseSocket(FIREWALL_CHAIN_OEM_DENY_1, denylist); 10428 doTestSetFirewallChainEnabledCloseSocket(FIREWALL_CHAIN_OEM_DENY_2, denylist); 10429 doTestSetFirewallChainEnabledCloseSocket(FIREWALL_CHAIN_OEM_DENY_3, denylist); 10430 } 10431 10432 private void doTestReplaceFirewallChain(final int chain) { 10433 final int[] uids = new int[] {1001, 1002}; 10434 mCm.replaceFirewallChain(chain, uids); 10435 verify(mBpfNetMaps).replaceUidChain(chain, uids); 10436 reset(mBpfNetMaps); 10437 } 10438 10439 @Test @IgnoreUpTo(SC_V2) 10440 public void testReplaceFirewallChain() { 10441 doTestReplaceFirewallChain(FIREWALL_CHAIN_DOZABLE); 10442 doTestReplaceFirewallChain(FIREWALL_CHAIN_STANDBY); 10443 doTestReplaceFirewallChain(FIREWALL_CHAIN_POWERSAVE); 10444 doTestReplaceFirewallChain(FIREWALL_CHAIN_RESTRICTED); 10445 doTestReplaceFirewallChain(FIREWALL_CHAIN_LOW_POWER_STANDBY); 10446 doTestReplaceFirewallChain(FIREWALL_CHAIN_OEM_DENY_1); 10447 doTestReplaceFirewallChain(FIREWALL_CHAIN_OEM_DENY_2); 10448 doTestReplaceFirewallChain(FIREWALL_CHAIN_OEM_DENY_3); 10449 } 10450 10451 @Test @IgnoreUpTo(SC_V2) 10452 public void testInvalidFirewallChain() throws Exception { 10453 final int uid = 1001; 10454 final Class<IllegalArgumentException> expected = IllegalArgumentException.class; 10455 assertThrows(expected, 10456 () -> mCm.setUidFirewallRule(-1 /* chain */, uid, FIREWALL_RULE_ALLOW)); 10457 assertThrows(expected, 10458 () -> mCm.setUidFirewallRule(100 /* chain */, uid, FIREWALL_RULE_ALLOW)); 10459 } 10460 10461 @Test @IgnoreUpTo(SC_V2) 10462 public void testInvalidFirewallRule() throws Exception { 10463 final Class<IllegalArgumentException> expected = IllegalArgumentException.class; 10464 assertThrows(expected, 10465 () -> mCm.setUidFirewallRule(FIREWALL_CHAIN_DOZABLE, 10466 1001 /* uid */, -1 /* rule */)); 10467 assertThrows(expected, 10468 () -> mCm.setUidFirewallRule(FIREWALL_CHAIN_DOZABLE, 10469 1001 /* uid */, 100 /* rule */)); 10470 } 10471 10472 /** 10473 * Test mutable and requestable network capabilities such as 10474 * {@link NetworkCapabilities#NET_CAPABILITY_TRUSTED} and 10475 * {@link NetworkCapabilities#NET_CAPABILITY_NOT_VCN_MANAGED}. Verify that the 10476 * {@code ConnectivityService} re-assign the networks accordingly. 10477 */ 10478 @Test 10479 public final void testLoseMutableAndRequestableCaps() throws Exception { 10480 final int[] testCaps = new int [] { 10481 NET_CAPABILITY_TRUSTED, 10482 NET_CAPABILITY_NOT_VCN_MANAGED 10483 }; 10484 for (final int testCap : testCaps) { 10485 // Create requests with and without the testing capability. 10486 final TestNetworkCallback callbackWithCap = new TestNetworkCallback(); 10487 final TestNetworkCallback callbackWithoutCap = new TestNetworkCallback(); 10488 mCm.requestNetwork(new NetworkRequest.Builder().addCapability(testCap).build(), 10489 callbackWithCap); 10490 mCm.requestNetwork(new NetworkRequest.Builder().removeCapability(testCap).build(), 10491 callbackWithoutCap); 10492 10493 // Setup networks with testing capability and verify the default network changes. 10494 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 10495 mCellAgent.addCapability(testCap); 10496 mCellAgent.connect(true); 10497 callbackWithCap.expectAvailableThenValidatedCallbacks(mCellAgent); 10498 callbackWithoutCap.expectAvailableThenValidatedCallbacks(mCellAgent); 10499 verify(mMockNetd).networkSetDefault(eq(mCellAgent.getNetwork().netId)); 10500 reset(mMockNetd); 10501 10502 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 10503 mWiFiAgent.addCapability(testCap); 10504 mWiFiAgent.connect(true); 10505 callbackWithCap.expectAvailableDoubleValidatedCallbacks(mWiFiAgent); 10506 callbackWithoutCap.expectAvailableDoubleValidatedCallbacks(mWiFiAgent); 10507 verify(mMockNetd).networkSetDefault(eq(mWiFiAgent.getNetwork().netId)); 10508 reset(mMockNetd); 10509 10510 // Remove the testing capability on wifi, verify the callback and default network 10511 // changes back to cellular. 10512 mWiFiAgent.removeCapability(testCap); 10513 callbackWithCap.expectAvailableCallbacksValidated(mCellAgent); 10514 callbackWithoutCap.expectCaps(mWiFiAgent, c -> !c.hasCapability(testCap)); 10515 verify(mMockNetd).networkSetDefault(eq(mCellAgent.getNetwork().netId)); 10516 reset(mMockNetd); 10517 10518 mCellAgent.removeCapability(testCap); 10519 callbackWithCap.expect(LOST, mCellAgent); 10520 callbackWithoutCap.assertNoCallback(); 10521 verify(mMockNetd).networkClearDefault(); 10522 10523 mCm.unregisterNetworkCallback(callbackWithCap); 10524 mCm.unregisterNetworkCallback(callbackWithoutCap); 10525 } 10526 } 10527 10528 @Test 10529 public final void testBatteryStatsNetworkType() throws Exception { 10530 final LinkProperties cellLp = new LinkProperties(); 10531 cellLp.setInterfaceName("cell0"); 10532 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp); 10533 mCellAgent.connect(true); 10534 waitForIdle(); 10535 final ArrayTrackRecord<ReportedInterfaces>.ReadHead readHead = 10536 mDeps.mReportedInterfaceHistory.newReadHead(); 10537 assertNotNull(readHead.poll(TIMEOUT_MS, ri -> ri.contentEquals(mServiceContext, 10538 cellLp.getInterfaceName(), 10539 new int[] { TRANSPORT_CELLULAR }))); 10540 10541 final LinkProperties wifiLp = new LinkProperties(); 10542 wifiLp.setInterfaceName("wifi0"); 10543 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, wifiLp); 10544 mWiFiAgent.connect(true); 10545 waitForIdle(); 10546 assertNotNull(readHead.poll(TIMEOUT_MS, ri -> ri.contentEquals(mServiceContext, 10547 wifiLp.getInterfaceName(), 10548 new int[] { TRANSPORT_WIFI }))); 10549 10550 mCellAgent.disconnect(); 10551 mWiFiAgent.disconnect(); 10552 10553 cellLp.setInterfaceName("wifi0"); 10554 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp); 10555 mCellAgent.connect(true); 10556 waitForIdle(); 10557 assertNotNull(readHead.poll(TIMEOUT_MS, ri -> ri.contentEquals(mServiceContext, 10558 cellLp.getInterfaceName(), 10559 new int[] { TRANSPORT_CELLULAR }))); 10560 mCellAgent.disconnect(); 10561 } 10562 10563 /** 10564 * Make simulated InterfaceConfigParcel for Nat464Xlat to query clat lower layer info. 10565 */ 10566 private InterfaceConfigurationParcel getClatInterfaceConfigParcel(LinkAddress la) { 10567 final InterfaceConfigurationParcel cfg = new InterfaceConfigurationParcel(); 10568 cfg.hwAddr = "11:22:33:44:55:66"; 10569 cfg.ipv4Addr = la.getAddress().getHostAddress(); 10570 cfg.prefixLength = la.getPrefixLength(); 10571 return cfg; 10572 } 10573 10574 /** 10575 * Make expected stack link properties, copied from Nat464Xlat. 10576 */ 10577 private LinkProperties makeClatLinkProperties(LinkAddress la) { 10578 LinkAddress clatAddress = la; 10579 LinkProperties stacked = new LinkProperties(); 10580 stacked.setInterfaceName(CLAT_MOBILE_IFNAME); 10581 RouteInfo ipv4Default = new RouteInfo( 10582 new LinkAddress(Inet4Address.ANY, 0), 10583 clatAddress.getAddress(), CLAT_MOBILE_IFNAME); 10584 stacked.addRoute(ipv4Default); 10585 stacked.addLinkAddress(clatAddress); 10586 return stacked; 10587 } 10588 10589 private Nat64PrefixEventParcel makeNat64PrefixEvent(final int netId, final int prefixOperation, 10590 final String prefixAddress, final int prefixLength) { 10591 final Nat64PrefixEventParcel event = new Nat64PrefixEventParcel(); 10592 event.netId = netId; 10593 event.prefixOperation = prefixOperation; 10594 event.prefixAddress = prefixAddress; 10595 event.prefixLength = prefixLength; 10596 return event; 10597 } 10598 10599 private void verifyWakeupModifyInterface(String iface, boolean add) throws RemoteException { 10600 if (add) { 10601 verify(mMockNetd).wakeupAddInterface(eq(iface), anyString(), anyInt(), 10602 anyInt()); 10603 } else { 10604 verify(mMockNetd).wakeupDelInterface(eq(iface), anyString(), anyInt(), 10605 anyInt()); 10606 } 10607 } 10608 10609 private <T> T verifyWithOrder(@Nullable InOrder inOrder, @NonNull T t) { 10610 if (inOrder != null) { 10611 return inOrder.verify(t); 10612 } else { 10613 // times(1) for consistency with the above. InOrder#verify always implies times(1). 10614 return verify(t, times(1)); 10615 } 10616 } 10617 10618 private <T> T verifyNeverWithOrder(@Nullable InOrder inOrder, @NonNull T t) { 10619 if (inOrder != null) { 10620 return inOrder.verify(t, never()); 10621 } else { 10622 return verify(t, never()); 10623 } 10624 } 10625 10626 private void verifyClatdStart(@Nullable InOrder inOrder, @NonNull String iface, int netId, 10627 @NonNull String nat64Prefix) throws Exception { 10628 if (mDeps.isAtLeastT()) { 10629 verifyWithOrder(inOrder, mClatCoordinator) 10630 .clatStart(eq(iface), eq(netId), eq(new IpPrefix(nat64Prefix))); 10631 } else { 10632 verifyWithOrder(inOrder, mMockNetd).clatdStart(eq(iface), eq(nat64Prefix)); 10633 } 10634 } 10635 10636 private void verifyNeverClatdStart(@Nullable InOrder inOrder, @NonNull String iface) 10637 throws Exception { 10638 if (mDeps.isAtLeastT()) { 10639 verifyNeverWithOrder(inOrder, mClatCoordinator).clatStart(eq(iface), anyInt(), any()); 10640 } else { 10641 verifyNeverWithOrder(inOrder, mMockNetd).clatdStart(eq(iface), anyString()); 10642 } 10643 } 10644 10645 private void verifyClatdStop(@Nullable InOrder inOrder, @NonNull String iface) 10646 throws Exception { 10647 if (mDeps.isAtLeastT()) { 10648 verifyWithOrder(inOrder, mClatCoordinator).clatStop(); 10649 } else { 10650 verifyWithOrder(inOrder, mMockNetd).clatdStop(eq(iface)); 10651 } 10652 } 10653 10654 private void verifyNeverClatdStop(@Nullable InOrder inOrder, @NonNull String iface) 10655 throws Exception { 10656 if (mDeps.isAtLeastT()) { 10657 verifyNeverWithOrder(inOrder, mClatCoordinator).clatStop(); 10658 } else { 10659 verifyNeverWithOrder(inOrder, mMockNetd).clatdStop(eq(iface)); 10660 } 10661 } 10662 10663 private void expectNativeNetworkCreated(int netId, int permission, String iface, 10664 InOrder inOrder) throws Exception { 10665 verifyWithOrder(inOrder, mMockNetd).networkCreate(nativeNetworkConfigPhysical(netId, 10666 permission)); 10667 verifyWithOrder(inOrder, mMockDnsResolver).createNetworkCache(eq(netId)); 10668 if (iface != null) { 10669 verifyWithOrder(inOrder, mMockNetd).networkAddInterface(netId, iface); 10670 } 10671 } 10672 10673 private void expectNativeNetworkCreated(int netId, int permission, String iface) 10674 throws Exception { 10675 expectNativeNetworkCreated(netId, permission, iface, null /* inOrder */); 10676 } 10677 10678 @Test 10679 public void testStackedLinkProperties() throws Exception { 10680 final LinkAddress myIpv4 = new LinkAddress("1.2.3.4/24"); 10681 final LinkAddress myIpv6 = new LinkAddress("2001:db8:1::1/64"); 10682 final String kNat64PrefixString = "2001:db8:64:64:64:64::"; 10683 final IpPrefix kNat64Prefix = new IpPrefix(InetAddress.getByName(kNat64PrefixString), 96); 10684 final String kOtherNat64PrefixString = "64:ff9b::"; 10685 final IpPrefix kOtherNat64Prefix = new IpPrefix( 10686 InetAddress.getByName(kOtherNat64PrefixString), 96); 10687 final RouteInfo ipv6Default = 10688 new RouteInfo((IpPrefix) null, myIpv6.getAddress(), MOBILE_IFNAME); 10689 final RouteInfo ipv6Subnet = new RouteInfo(myIpv6, null, MOBILE_IFNAME); 10690 final RouteInfo ipv4Subnet = new RouteInfo(myIpv4, null, MOBILE_IFNAME); 10691 final RouteInfo stackedDefault = 10692 new RouteInfo((IpPrefix) null, myIpv4.getAddress(), CLAT_MOBILE_IFNAME); 10693 10694 final NetworkRequest networkRequest = new NetworkRequest.Builder() 10695 .addTransportType(TRANSPORT_CELLULAR) 10696 .addCapability(NET_CAPABILITY_INTERNET) 10697 .build(); 10698 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 10699 mCm.registerNetworkCallback(networkRequest, networkCallback); 10700 10701 // Prepare ipv6 only link properties. 10702 final LinkProperties cellLp = new LinkProperties(); 10703 cellLp.setInterfaceName(MOBILE_IFNAME); 10704 cellLp.addLinkAddress(myIpv6); 10705 cellLp.addRoute(ipv6Default); 10706 cellLp.addRoute(ipv6Subnet); 10707 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp); 10708 reset(mClatCoordinator); 10709 10710 // Connect with ipv6 link properties. Expect prefix discovery to be started. 10711 mCellAgent.connect(true); 10712 int cellNetId = mCellAgent.getNetwork().netId; 10713 waitForIdle(); 10714 10715 expectNativeNetworkCreated(cellNetId, INetd.PERMISSION_NONE, MOBILE_IFNAME); 10716 assertRoutesAdded(cellNetId, ipv6Subnet, ipv6Default); 10717 final ArrayTrackRecord<ReportedInterfaces>.ReadHead readHead = 10718 mDeps.mReportedInterfaceHistory.newReadHead(); 10719 assertNotNull(readHead.poll(TIMEOUT_MS, ri -> ri.contentEquals(mServiceContext, 10720 cellLp.getInterfaceName(), 10721 new int[] { TRANSPORT_CELLULAR }))); 10722 10723 networkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 10724 verify(mMockDnsResolver, times(1)).startPrefix64Discovery(cellNetId); 10725 10726 // Switching default network updates TCP buffer sizes. 10727 verifyTcpBufferSizeChange(ConnectivityService.DEFAULT_TCP_BUFFER_SIZES); 10728 // Add an IPv4 address. Expect prefix discovery to be stopped. Netd doesn't tell us that 10729 // the NAT64 prefix was removed because one was never discovered. 10730 cellLp.addLinkAddress(myIpv4); 10731 mCellAgent.sendLinkProperties(cellLp); 10732 networkCallback.expect(LINK_PROPERTIES_CHANGED, mCellAgent); 10733 assertRoutesAdded(cellNetId, ipv4Subnet); 10734 verify(mMockDnsResolver, times(1)).stopPrefix64Discovery(cellNetId); 10735 verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration(any()); 10736 10737 // Make sure BatteryStats was not told about any v4- interfaces, as none should have 10738 // come online yet. 10739 waitForIdle(); 10740 assertNull(readHead.poll(0 /* timeout */, ri -> mServiceContext.equals(ri.context) 10741 && ri.iface != null && ri.iface.startsWith("v4-"))); 10742 10743 verifyNoMoreInteractions(mMockNetd); 10744 verifyNoMoreInteractions(mClatCoordinator); 10745 verifyNoMoreInteractions(mMockDnsResolver); 10746 reset(mMockNetd); 10747 reset(mClatCoordinator); 10748 reset(mMockDnsResolver); 10749 doReturn(getClatInterfaceConfigParcel(myIpv4)).when(mMockNetd) 10750 .interfaceGetCfg(CLAT_MOBILE_IFNAME); 10751 10752 // Remove IPv4 address. Expect prefix discovery to be started again. 10753 cellLp.removeLinkAddress(myIpv4); 10754 mCellAgent.sendLinkProperties(cellLp); 10755 networkCallback.expect(LINK_PROPERTIES_CHANGED, mCellAgent); 10756 verify(mMockDnsResolver, times(1)).startPrefix64Discovery(cellNetId); 10757 assertRoutesRemoved(cellNetId, ipv4Subnet); 10758 10759 // When NAT64 prefix discovery succeeds, LinkProperties are updated and clatd is started. 10760 Nat464Xlat clat = getNat464Xlat(mCellAgent); 10761 assertNull(mCm.getLinkProperties(mCellAgent.getNetwork()).getNat64Prefix()); 10762 mService.mResolverUnsolEventCallback.onNat64PrefixEvent( 10763 makeNat64PrefixEvent(cellNetId, PREFIX_OPERATION_ADDED, kNat64PrefixString, 96)); 10764 LinkProperties lpBeforeClat = networkCallback.expect( 10765 LINK_PROPERTIES_CHANGED, mCellAgent).getLp(); 10766 assertEquals(0, lpBeforeClat.getStackedLinks().size()); 10767 assertEquals(kNat64Prefix, lpBeforeClat.getNat64Prefix()); 10768 verifyClatdStart(null /* inOrder */, MOBILE_IFNAME, cellNetId, kNat64Prefix.toString()); 10769 10770 // Clat iface comes up. Expect stacked link to be added. 10771 clat.interfaceLinkStateChanged(CLAT_MOBILE_IFNAME, true); 10772 networkCallback.expect(LINK_PROPERTIES_CHANGED, mCellAgent); 10773 List<LinkProperties> stackedLps = mCm.getLinkProperties(mCellAgent.getNetwork()) 10774 .getStackedLinks(); 10775 assertEquals(makeClatLinkProperties(myIpv4), stackedLps.get(0)); 10776 assertRoutesAdded(cellNetId, stackedDefault); 10777 verify(mMockNetd, times(1)).networkAddInterface(cellNetId, CLAT_MOBILE_IFNAME); 10778 // Change trivial linkproperties and see if stacked link is preserved. 10779 cellLp.addDnsServer(InetAddress.getByName("8.8.8.8")); 10780 mCellAgent.sendLinkProperties(cellLp); 10781 networkCallback.expect(LINK_PROPERTIES_CHANGED, mCellAgent); 10782 10783 List<LinkProperties> stackedLpsAfterChange = 10784 mCm.getLinkProperties(mCellAgent.getNetwork()).getStackedLinks(); 10785 assertNotEquals(stackedLpsAfterChange, Collections.EMPTY_LIST); 10786 assertEquals(makeClatLinkProperties(myIpv4), stackedLpsAfterChange.get(0)); 10787 10788 verify(mMockDnsResolver, times(1)).setResolverConfiguration( 10789 mResolverParamsParcelCaptor.capture()); 10790 ResolverParamsParcel resolvrParams = mResolverParamsParcelCaptor.getValue(); 10791 assertEquals(1, resolvrParams.servers.length); 10792 assertTrue(CollectionUtils.contains(resolvrParams.servers, "8.8.8.8")); 10793 10794 for (final LinkProperties stackedLp : stackedLpsAfterChange) { 10795 assertNotNull(readHead.poll(TIMEOUT_MS, ri -> ri.contentEquals(mServiceContext, 10796 stackedLp.getInterfaceName(), 10797 new int[] { TRANSPORT_CELLULAR }))); 10798 } 10799 reset(mMockNetd); 10800 reset(mClatCoordinator); 10801 doReturn(getClatInterfaceConfigParcel(myIpv4)).when(mMockNetd) 10802 .interfaceGetCfg(CLAT_MOBILE_IFNAME); 10803 // Change the NAT64 prefix without first removing it. 10804 // Expect clatd to be stopped and started with the new prefix. 10805 mService.mResolverUnsolEventCallback.onNat64PrefixEvent(makeNat64PrefixEvent( 10806 cellNetId, PREFIX_OPERATION_ADDED, kOtherNat64PrefixString, 96)); 10807 networkCallback.expect(LINK_PROPERTIES_CHANGED, mCellAgent, 10808 cb -> cb.getLp().getStackedLinks().size() == 0); 10809 verifyClatdStop(null /* inOrder */, MOBILE_IFNAME); 10810 assertRoutesRemoved(cellNetId, stackedDefault); 10811 verify(mMockNetd, times(1)).networkRemoveInterface(cellNetId, CLAT_MOBILE_IFNAME); 10812 10813 verifyClatdStart(null /* inOrder */, MOBILE_IFNAME, cellNetId, 10814 kOtherNat64Prefix.toString()); 10815 networkCallback.expect(LINK_PROPERTIES_CHANGED, mCellAgent, 10816 cb -> cb.getLp().getNat64Prefix().equals(kOtherNat64Prefix)); 10817 clat.interfaceLinkStateChanged(CLAT_MOBILE_IFNAME, true); 10818 networkCallback.expect(LINK_PROPERTIES_CHANGED, mCellAgent, 10819 cb -> cb.getLp().getStackedLinks().size() == 1); 10820 assertRoutesAdded(cellNetId, stackedDefault); 10821 verify(mMockNetd, times(1)).networkAddInterface(cellNetId, CLAT_MOBILE_IFNAME); 10822 reset(mMockNetd); 10823 reset(mClatCoordinator); 10824 10825 // Add ipv4 address, expect that clatd and prefix discovery are stopped and stacked 10826 // linkproperties are cleaned up. 10827 cellLp.addLinkAddress(myIpv4); 10828 cellLp.addRoute(ipv4Subnet); 10829 mCellAgent.sendLinkProperties(cellLp); 10830 networkCallback.expect(LINK_PROPERTIES_CHANGED, mCellAgent); 10831 assertRoutesAdded(cellNetId, ipv4Subnet); 10832 verifyClatdStop(null /* inOrder */, MOBILE_IFNAME); 10833 verify(mMockDnsResolver, times(1)).stopPrefix64Discovery(cellNetId); 10834 10835 // As soon as stop is called, the linkproperties lose the stacked interface. 10836 networkCallback.expect(LINK_PROPERTIES_CHANGED, mCellAgent); 10837 LinkProperties actualLpAfterIpv4 = mCm.getLinkProperties(mCellAgent.getNetwork()); 10838 LinkProperties expected = new LinkProperties(cellLp); 10839 expected.setNat64Prefix(kOtherNat64Prefix); 10840 assertEquals(expected, actualLpAfterIpv4); 10841 assertEquals(0, actualLpAfterIpv4.getStackedLinks().size()); 10842 assertRoutesRemoved(cellNetId, stackedDefault); 10843 10844 // The interface removed callback happens but has no effect after stop is called. 10845 clat.interfaceRemoved(CLAT_MOBILE_IFNAME); 10846 networkCallback.assertNoCallback(); 10847 verify(mMockNetd, times(1)).networkRemoveInterface(cellNetId, CLAT_MOBILE_IFNAME); 10848 10849 if (mDeps.isAtLeastU()) { 10850 verifyWakeupModifyInterface(CLAT_MOBILE_IFNAME, false); 10851 } 10852 10853 verifyNoMoreInteractions(mMockNetd); 10854 verifyNoMoreInteractions(mClatCoordinator); 10855 verifyNoMoreInteractions(mMockDnsResolver); 10856 reset(mMockNetd); 10857 reset(mClatCoordinator); 10858 reset(mMockDnsResolver); 10859 doReturn(getClatInterfaceConfigParcel(myIpv4)).when(mMockNetd) 10860 .interfaceGetCfg(CLAT_MOBILE_IFNAME); 10861 10862 // Stopping prefix discovery causes netd to tell us that the NAT64 prefix is gone. 10863 mService.mResolverUnsolEventCallback.onNat64PrefixEvent(makeNat64PrefixEvent( 10864 cellNetId, PREFIX_OPERATION_REMOVED, kOtherNat64PrefixString, 96)); 10865 networkCallback.expect(LINK_PROPERTIES_CHANGED, mCellAgent, 10866 cb -> cb.getLp().getNat64Prefix() == null); 10867 10868 // Remove IPv4 address and expect prefix discovery and clatd to be started again. 10869 cellLp.removeLinkAddress(myIpv4); 10870 cellLp.removeRoute(new RouteInfo(myIpv4, null, MOBILE_IFNAME)); 10871 cellLp.removeDnsServer(InetAddress.getByName("8.8.8.8")); 10872 mCellAgent.sendLinkProperties(cellLp); 10873 networkCallback.expect(LINK_PROPERTIES_CHANGED, mCellAgent); 10874 assertRoutesRemoved(cellNetId, ipv4Subnet); // Directly-connected routes auto-added. 10875 verify(mMockDnsResolver, times(1)).startPrefix64Discovery(cellNetId); 10876 mService.mResolverUnsolEventCallback.onNat64PrefixEvent(makeNat64PrefixEvent( 10877 cellNetId, PREFIX_OPERATION_ADDED, kNat64PrefixString, 96)); 10878 networkCallback.expect(LINK_PROPERTIES_CHANGED, mCellAgent); 10879 verifyClatdStart(null /* inOrder */, MOBILE_IFNAME, cellNetId, kNat64Prefix.toString()); 10880 10881 // Clat iface comes up. Expect stacked link to be added. 10882 clat.interfaceLinkStateChanged(CLAT_MOBILE_IFNAME, true); 10883 networkCallback.expect(LINK_PROPERTIES_CHANGED, mCellAgent, 10884 cb -> cb.getLp().getStackedLinks().size() == 1 10885 && cb.getLp().getNat64Prefix() != null); 10886 assertRoutesAdded(cellNetId, stackedDefault); 10887 verify(mMockNetd, times(1)).networkAddInterface(cellNetId, CLAT_MOBILE_IFNAME); 10888 10889 if (mDeps.isAtLeastU()) { 10890 verifyWakeupModifyInterface(CLAT_MOBILE_IFNAME, true); 10891 } 10892 10893 // NAT64 prefix is removed. Expect that clat is stopped. 10894 mService.mResolverUnsolEventCallback.onNat64PrefixEvent(makeNat64PrefixEvent( 10895 cellNetId, PREFIX_OPERATION_REMOVED, kNat64PrefixString, 96)); 10896 networkCallback.expect(LINK_PROPERTIES_CHANGED, mCellAgent, 10897 cb -> cb.getLp().getStackedLinks().size() == 0 10898 && cb.getLp().getNat64Prefix() == null); 10899 assertRoutesRemoved(cellNetId, ipv4Subnet, stackedDefault); 10900 10901 // Stop has no effect because clat is already stopped. 10902 verifyClatdStop(null /* inOrder */, MOBILE_IFNAME); 10903 networkCallback.expect(LINK_PROPERTIES_CHANGED, mCellAgent, 10904 cb -> cb.getLp().getStackedLinks().size() == 0); 10905 verify(mMockNetd, times(1)).networkRemoveInterface(cellNetId, CLAT_MOBILE_IFNAME); 10906 verify(mMockNetd, times(1)).interfaceGetCfg(CLAT_MOBILE_IFNAME); 10907 10908 if (mDeps.isAtLeastU()) { 10909 verifyWakeupModifyInterface(CLAT_MOBILE_IFNAME, false); 10910 } 10911 10912 // Clean up. 10913 mCellAgent.disconnect(); 10914 networkCallback.expect(LOST, mCellAgent); 10915 networkCallback.assertNoCallback(); 10916 verify(mMockNetd, times(1)).idletimerRemoveInterface(eq(MOBILE_IFNAME), anyInt(), 10917 eq(Integer.toString(TRANSPORT_CELLULAR))); 10918 verify(mMockNetd).networkDestroy(cellNetId); 10919 if (mDeps.isAtLeastU()) { 10920 verify(mMockNetd).setNetworkAllowlist(any()); 10921 } else { 10922 verify(mMockNetd, never()).setNetworkAllowlist(any()); 10923 } 10924 10925 if (mDeps.isAtLeastU()) { 10926 verifyWakeupModifyInterface(MOBILE_IFNAME, false); 10927 } 10928 10929 verifyNoMoreInteractions(mMockNetd); 10930 verifyNoMoreInteractions(mClatCoordinator); 10931 reset(mMockNetd); 10932 reset(mClatCoordinator); 10933 10934 // Test disconnecting a network that is running 464xlat. 10935 10936 // Connect a network with a NAT64 prefix. 10937 doReturn(getClatInterfaceConfigParcel(myIpv4)).when(mMockNetd) 10938 .interfaceGetCfg(CLAT_MOBILE_IFNAME); 10939 cellLp.setNat64Prefix(kNat64Prefix); 10940 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp); 10941 mCellAgent.connect(false /* validated */); 10942 networkCallback.expectAvailableCallbacksUnvalidated(mCellAgent); 10943 cellNetId = mCellAgent.getNetwork().netId; 10944 verify(mMockNetd, times(1)).networkCreate(nativeNetworkConfigPhysical(cellNetId, 10945 INetd.PERMISSION_NONE)); 10946 assertRoutesAdded(cellNetId, ipv6Subnet, ipv6Default); 10947 10948 // Clatd is started and clat iface comes up. Expect stacked link to be added. 10949 verifyClatdStart(null /* inOrder */, MOBILE_IFNAME, cellNetId, kNat64Prefix.toString()); 10950 clat = getNat464Xlat(mCellAgent); 10951 clat.interfaceLinkStateChanged(CLAT_MOBILE_IFNAME, true /* up */); 10952 networkCallback.expect(LINK_PROPERTIES_CHANGED, mCellAgent, 10953 cb -> cb.getLp().getStackedLinks().size() == 1 10954 && cb.getLp().getNat64Prefix().equals(kNat64Prefix)); 10955 verify(mMockNetd).networkAddInterface(cellNetId, CLAT_MOBILE_IFNAME); 10956 // assertRoutesAdded sees all calls since last mMockNetd reset, so expect IPv6 routes again. 10957 assertRoutesAdded(cellNetId, ipv6Subnet, ipv6Default, stackedDefault); 10958 10959 if (mDeps.isAtLeastU()) { 10960 verifyWakeupModifyInterface(MOBILE_IFNAME, true); 10961 } 10962 10963 reset(mMockNetd); 10964 reset(mClatCoordinator); 10965 10966 // Disconnect the network. clat is stopped and the network is destroyed. 10967 mCellAgent.disconnect(); 10968 networkCallback.expect(LOST, mCellAgent); 10969 networkCallback.assertNoCallback(); 10970 verifyClatdStop(null /* inOrder */, MOBILE_IFNAME); 10971 10972 if (mDeps.isAtLeastU()) { 10973 verifyWakeupModifyInterface(CLAT_MOBILE_IFNAME, false); 10974 } 10975 10976 verify(mMockNetd).idletimerRemoveInterface(eq(MOBILE_IFNAME), anyInt(), 10977 eq(Integer.toString(TRANSPORT_CELLULAR))); 10978 verify(mMockNetd).networkDestroy(cellNetId); 10979 if (mDeps.isAtLeastU()) { 10980 verify(mMockNetd).setNetworkAllowlist(any()); 10981 } else { 10982 verify(mMockNetd, never()).setNetworkAllowlist(any()); 10983 } 10984 10985 if (mDeps.isAtLeastU()) { 10986 verifyWakeupModifyInterface(MOBILE_IFNAME, false); 10987 } 10988 10989 verifyNoMoreInteractions(mMockNetd); 10990 verifyNoMoreInteractions(mClatCoordinator); 10991 10992 mCm.unregisterNetworkCallback(networkCallback); 10993 } 10994 10995 private void expectNat64PrefixChange(TestNetworkCallback callback, 10996 TestNetworkAgentWrapper agent, IpPrefix prefix) { 10997 callback.expect(LINK_PROPERTIES_CHANGED, agent, 10998 x -> Objects.equals(x.getLp().getNat64Prefix(), prefix)); 10999 } 11000 11001 @Test 11002 public void testNat64PrefixMultipleSources() throws Exception { 11003 final String iface = "wlan0"; 11004 final String pref64FromRaStr = "64:ff9b::"; 11005 final String pref64FromDnsStr = "2001:db8:64::"; 11006 final IpPrefix pref64FromRa = new IpPrefix(InetAddress.getByName(pref64FromRaStr), 96); 11007 final IpPrefix pref64FromDns = new IpPrefix(InetAddress.getByName(pref64FromDnsStr), 96); 11008 final IpPrefix newPref64FromRa = new IpPrefix("2001:db8:64:64:64:64::/96"); 11009 11010 final NetworkRequest request = new NetworkRequest.Builder() 11011 .addCapability(NET_CAPABILITY_INTERNET) 11012 .build(); 11013 final TestNetworkCallback callback = new TestNetworkCallback(); 11014 mCm.registerNetworkCallback(request, callback); 11015 11016 final LinkProperties baseLp = new LinkProperties(); 11017 baseLp.setInterfaceName(iface); 11018 baseLp.addLinkAddress(new LinkAddress("2001:db8:1::1/64")); 11019 baseLp.addDnsServer(InetAddress.getByName("2001:4860:4860::6464")); 11020 11021 reset(mMockNetd, mMockDnsResolver); 11022 InOrder inOrder = inOrder(mMockNetd, mMockDnsResolver, mClatCoordinator); 11023 11024 // If a network already has a NAT64 prefix on connect, clatd is started immediately and 11025 // prefix discovery is never started. 11026 LinkProperties lp = new LinkProperties(baseLp); 11027 lp.setNat64Prefix(pref64FromRa); 11028 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, lp); 11029 mWiFiAgent.connect(false); 11030 final Network network = mWiFiAgent.getNetwork(); 11031 int netId = network.getNetId(); 11032 callback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 11033 verifyClatdStart(inOrder, iface, netId, pref64FromRa.toString()); 11034 inOrder.verify(mMockDnsResolver).setPrefix64(netId, pref64FromRa.toString()); 11035 inOrder.verify(mMockDnsResolver, never()).startPrefix64Discovery(netId); 11036 callback.assertNoCallback(); 11037 assertEquals(pref64FromRa, mCm.getLinkProperties(network).getNat64Prefix()); 11038 11039 // If the RA prefix is withdrawn, clatd is stopped and prefix discovery is started. 11040 lp.setNat64Prefix(null); 11041 mWiFiAgent.sendLinkProperties(lp); 11042 expectNat64PrefixChange(callback, mWiFiAgent, null); 11043 verifyClatdStop(inOrder, iface); 11044 inOrder.verify(mMockDnsResolver).setPrefix64(netId, ""); 11045 inOrder.verify(mMockDnsResolver).startPrefix64Discovery(netId); 11046 11047 // If the RA prefix appears while DNS discovery is in progress, discovery is stopped and 11048 // clatd is started with the prefix from the RA. 11049 lp.setNat64Prefix(pref64FromRa); 11050 mWiFiAgent.sendLinkProperties(lp); 11051 expectNat64PrefixChange(callback, mWiFiAgent, pref64FromRa); 11052 verifyClatdStart(inOrder, iface, netId, pref64FromRa.toString()); 11053 inOrder.verify(mMockDnsResolver).stopPrefix64Discovery(netId); 11054 inOrder.verify(mMockDnsResolver).setPrefix64(netId, pref64FromRa.toString()); 11055 11056 // Withdraw the RA prefix so we can test the case where an RA prefix appears after DNS 11057 // discovery has succeeded. 11058 lp.setNat64Prefix(null); 11059 mWiFiAgent.sendLinkProperties(lp); 11060 expectNat64PrefixChange(callback, mWiFiAgent, null); 11061 verifyClatdStop(inOrder, iface); 11062 inOrder.verify(mMockDnsResolver).setPrefix64(netId, ""); 11063 inOrder.verify(mMockDnsResolver).startPrefix64Discovery(netId); 11064 11065 mService.mResolverUnsolEventCallback.onNat64PrefixEvent( 11066 makeNat64PrefixEvent(netId, PREFIX_OPERATION_ADDED, pref64FromDnsStr, 96)); 11067 expectNat64PrefixChange(callback, mWiFiAgent, pref64FromDns); 11068 verifyClatdStart(inOrder, iface, netId, pref64FromDns.toString()); 11069 11070 // If an RA advertises the same prefix that was discovered by DNS, nothing happens: prefix 11071 // discovery is not stopped, and there are no callbacks. 11072 lp.setNat64Prefix(pref64FromDns); 11073 mWiFiAgent.sendLinkProperties(lp); 11074 callback.assertNoCallback(); 11075 verifyNeverClatdStop(inOrder, iface); 11076 verifyNeverClatdStart(inOrder, iface); 11077 inOrder.verify(mMockDnsResolver, never()).stopPrefix64Discovery(netId); 11078 inOrder.verify(mMockDnsResolver, never()).startPrefix64Discovery(netId); 11079 inOrder.verify(mMockDnsResolver, never()).setPrefix64(eq(netId), anyString()); 11080 11081 // If the RA is later withdrawn, nothing happens again. 11082 lp.setNat64Prefix(null); 11083 mWiFiAgent.sendLinkProperties(lp); 11084 callback.assertNoCallback(); 11085 verifyNeverClatdStop(inOrder, iface); 11086 verifyNeverClatdStart(inOrder, iface); 11087 inOrder.verify(mMockDnsResolver, never()).stopPrefix64Discovery(netId); 11088 inOrder.verify(mMockDnsResolver, never()).startPrefix64Discovery(netId); 11089 inOrder.verify(mMockDnsResolver, never()).setPrefix64(eq(netId), anyString()); 11090 11091 // If the RA prefix changes, clatd is restarted and prefix discovery is stopped. 11092 lp.setNat64Prefix(pref64FromRa); 11093 mWiFiAgent.sendLinkProperties(lp); 11094 expectNat64PrefixChange(callback, mWiFiAgent, pref64FromRa); 11095 verifyClatdStop(inOrder, iface); 11096 inOrder.verify(mMockDnsResolver).stopPrefix64Discovery(netId); 11097 11098 // Stopping prefix discovery results in a prefix removed notification. 11099 mService.mResolverUnsolEventCallback.onNat64PrefixEvent( 11100 makeNat64PrefixEvent(netId, PREFIX_OPERATION_REMOVED, pref64FromDnsStr, 96)); 11101 11102 verifyClatdStart(inOrder, iface, netId, pref64FromRa.toString()); 11103 inOrder.verify(mMockDnsResolver).setPrefix64(netId, pref64FromRa.toString()); 11104 inOrder.verify(mMockDnsResolver, never()).startPrefix64Discovery(netId); 11105 11106 // If the RA prefix changes, clatd is restarted and prefix discovery is not started. 11107 lp.setNat64Prefix(newPref64FromRa); 11108 mWiFiAgent.sendLinkProperties(lp); 11109 expectNat64PrefixChange(callback, mWiFiAgent, newPref64FromRa); 11110 verifyClatdStop(inOrder, iface); 11111 inOrder.verify(mMockDnsResolver).setPrefix64(netId, ""); 11112 verifyClatdStart(inOrder, iface, netId, newPref64FromRa.toString()); 11113 inOrder.verify(mMockDnsResolver).setPrefix64(netId, newPref64FromRa.toString()); 11114 inOrder.verify(mMockDnsResolver, never()).stopPrefix64Discovery(netId); 11115 inOrder.verify(mMockDnsResolver, never()).startPrefix64Discovery(netId); 11116 11117 // If the RA prefix changes to the same value, nothing happens. 11118 lp.setNat64Prefix(newPref64FromRa); 11119 mWiFiAgent.sendLinkProperties(lp); 11120 callback.assertNoCallback(); 11121 assertEquals(newPref64FromRa, mCm.getLinkProperties(network).getNat64Prefix()); 11122 verifyNeverClatdStop(inOrder, iface); 11123 verifyNeverClatdStart(inOrder, iface); 11124 inOrder.verify(mMockDnsResolver, never()).stopPrefix64Discovery(netId); 11125 inOrder.verify(mMockDnsResolver, never()).startPrefix64Discovery(netId); 11126 inOrder.verify(mMockDnsResolver, never()).setPrefix64(eq(netId), anyString()); 11127 11128 // The transition between no prefix and DNS prefix is tested in testStackedLinkProperties. 11129 11130 // If the same prefix is learned first by DNS and then by RA, and clat is later stopped, 11131 // (e.g., because the network disconnects) setPrefix64(netid, "") is never called. 11132 lp.setNat64Prefix(null); 11133 mWiFiAgent.sendLinkProperties(lp); 11134 expectNat64PrefixChange(callback, mWiFiAgent, null); 11135 verifyClatdStop(inOrder, iface); 11136 inOrder.verify(mMockDnsResolver).setPrefix64(netId, ""); 11137 inOrder.verify(mMockDnsResolver).startPrefix64Discovery(netId); 11138 mService.mResolverUnsolEventCallback.onNat64PrefixEvent( 11139 makeNat64PrefixEvent(netId, PREFIX_OPERATION_ADDED, pref64FromDnsStr, 96)); 11140 expectNat64PrefixChange(callback, mWiFiAgent, pref64FromDns); 11141 verifyClatdStart(inOrder, iface, netId, pref64FromDns.toString()); 11142 inOrder.verify(mMockDnsResolver, never()).setPrefix64(eq(netId), any()); 11143 11144 lp.setNat64Prefix(pref64FromDns); 11145 mWiFiAgent.sendLinkProperties(lp); 11146 callback.assertNoCallback(); 11147 verifyNeverClatdStop(inOrder, iface); 11148 verifyNeverClatdStart(inOrder, iface); 11149 inOrder.verify(mMockDnsResolver, never()).stopPrefix64Discovery(netId); 11150 inOrder.verify(mMockDnsResolver, never()).startPrefix64Discovery(netId); 11151 inOrder.verify(mMockDnsResolver, never()).setPrefix64(eq(netId), anyString()); 11152 11153 // When tearing down a network, clat state is only updated after CALLBACK_LOST is fired, but 11154 // before CONNECTIVITY_ACTION is sent. Wait for CONNECTIVITY_ACTION before verifying that 11155 // clat has been stopped, or the test will be flaky. 11156 ExpectedBroadcast b = expectConnectivityAction(TYPE_WIFI, DetailedState.DISCONNECTED); 11157 mWiFiAgent.disconnect(); 11158 callback.expect(LOST, mWiFiAgent); 11159 b.expectBroadcast(); 11160 11161 verifyClatdStop(inOrder, iface); 11162 inOrder.verify(mMockDnsResolver).stopPrefix64Discovery(netId); 11163 inOrder.verify(mMockDnsResolver, never()).setPrefix64(eq(netId), anyString()); 11164 11165 mCm.unregisterNetworkCallback(callback); 11166 } 11167 11168 @Test 11169 public void testWith464XlatDisable() throws Exception { 11170 mDeps.setCellular464XlatEnabled(false); 11171 11172 final TestNetworkCallback callback = new TestNetworkCallback(); 11173 final TestNetworkCallback defaultCallback = new TestNetworkCallback(); 11174 final NetworkRequest networkRequest = new NetworkRequest.Builder() 11175 .addCapability(NET_CAPABILITY_INTERNET) 11176 .build(); 11177 mCm.registerNetworkCallback(networkRequest, callback); 11178 mCm.registerDefaultNetworkCallback(defaultCallback); 11179 11180 // Bring up validated cell. 11181 final LinkProperties cellLp = new LinkProperties(); 11182 cellLp.setInterfaceName(MOBILE_IFNAME); 11183 cellLp.addLinkAddress(new LinkAddress("2001:db8:1::1/64")); 11184 cellLp.addRoute(new RouteInfo(new IpPrefix("::/0"), null, MOBILE_IFNAME)); 11185 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 11186 11187 mCellAgent.sendLinkProperties(cellLp); 11188 mCellAgent.connect(true); 11189 callback.expectAvailableThenValidatedCallbacks(mCellAgent); 11190 defaultCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 11191 final int cellNetId = mCellAgent.getNetwork().netId; 11192 waitForIdle(); 11193 11194 verify(mMockDnsResolver, never()).startPrefix64Discovery(cellNetId); 11195 Nat464Xlat clat = getNat464Xlat(mCellAgent); 11196 assertTrue("Nat464Xlat was not IDLE", !clat.isStarted()); 11197 11198 // This cannot happen because prefix discovery cannot succeed if it is never started. 11199 mService.mResolverUnsolEventCallback.onNat64PrefixEvent( 11200 makeNat64PrefixEvent(cellNetId, PREFIX_OPERATION_ADDED, "64:ff9b::", 96)); 11201 11202 // ... but still, check that even if it did, clatd would not be started. 11203 verify(mMockNetd, never()).clatdStart(anyString(), anyString()); 11204 assertTrue("Nat464Xlat was not IDLE", !clat.isStarted()); 11205 } 11206 11207 @Test 11208 public void testDataActivityTracking() throws Exception { 11209 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 11210 final NetworkRequest networkRequest = new NetworkRequest.Builder() 11211 .addCapability(NET_CAPABILITY_INTERNET) 11212 .build(); 11213 mCm.registerNetworkCallback(networkRequest, networkCallback); 11214 11215 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 11216 final LinkProperties cellLp = new LinkProperties(); 11217 cellLp.setInterfaceName(MOBILE_IFNAME); 11218 mCellAgent.sendLinkProperties(cellLp); 11219 mCellAgent.connect(true); 11220 networkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 11221 verify(mMockNetd, times(1)).idletimerAddInterface(eq(MOBILE_IFNAME), anyInt(), 11222 eq(Integer.toString(TRANSPORT_CELLULAR))); 11223 11224 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 11225 final LinkProperties wifiLp = new LinkProperties(); 11226 wifiLp.setInterfaceName(WIFI_IFNAME); 11227 mWiFiAgent.sendLinkProperties(wifiLp); 11228 11229 // Network switch 11230 mWiFiAgent.connect(true); 11231 networkCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 11232 networkCallback.expectLosing(mCellAgent); 11233 networkCallback.expectCaps(mWiFiAgent, c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 11234 verify(mMockNetd, times(1)).idletimerAddInterface(eq(WIFI_IFNAME), anyInt(), 11235 eq(Integer.toString(TRANSPORT_WIFI))); 11236 verify(mMockNetd, times(1)).idletimerRemoveInterface(eq(MOBILE_IFNAME), anyInt(), 11237 eq(Integer.toString(TRANSPORT_CELLULAR))); 11238 11239 // Disconnect wifi and switch back to cell 11240 reset(mMockNetd); 11241 mWiFiAgent.disconnect(); 11242 networkCallback.expect(LOST, mWiFiAgent); 11243 assertNoCallbacks(networkCallback); 11244 verify(mMockNetd, times(1)).idletimerRemoveInterface(eq(WIFI_IFNAME), anyInt(), 11245 eq(Integer.toString(TRANSPORT_WIFI))); 11246 verify(mMockNetd, times(1)).idletimerAddInterface(eq(MOBILE_IFNAME), anyInt(), 11247 eq(Integer.toString(TRANSPORT_CELLULAR))); 11248 11249 // reconnect wifi 11250 reset(mMockNetd); 11251 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 11252 wifiLp.setInterfaceName(WIFI_IFNAME); 11253 mWiFiAgent.sendLinkProperties(wifiLp); 11254 mWiFiAgent.connect(true); 11255 networkCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 11256 networkCallback.expectLosing(mCellAgent); 11257 networkCallback.expectCaps(mWiFiAgent, c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 11258 verify(mMockNetd, times(1)).idletimerAddInterface(eq(WIFI_IFNAME), anyInt(), 11259 eq(Integer.toString(TRANSPORT_WIFI))); 11260 verify(mMockNetd, times(1)).idletimerRemoveInterface(eq(MOBILE_IFNAME), anyInt(), 11261 eq(Integer.toString(TRANSPORT_CELLULAR))); 11262 11263 // Disconnect cell 11264 reset(mMockNetd); 11265 mCellAgent.disconnect(); 11266 networkCallback.expect(LOST, mCellAgent); 11267 // LOST callback is triggered earlier than removing idle timer. Broadcast should also be 11268 // sent as network being switched. Ensure rule removal for cell will not be triggered 11269 // unexpectedly before network being removed. 11270 waitForIdle(); 11271 verify(mMockNetd, times(0)).idletimerRemoveInterface(eq(MOBILE_IFNAME), anyInt(), 11272 eq(Integer.toString(TRANSPORT_CELLULAR))); 11273 verify(mMockNetd, times(1)).networkDestroy(eq(mCellAgent.getNetwork().netId)); 11274 verify(mMockDnsResolver, times(1)).destroyNetworkCache(eq(mCellAgent.getNetwork().netId)); 11275 11276 // Disconnect wifi 11277 ExpectedBroadcast b = expectConnectivityAction(TYPE_WIFI, DetailedState.DISCONNECTED); 11278 mWiFiAgent.disconnect(); 11279 b.expectBroadcast(); 11280 verify(mMockNetd, times(1)).idletimerRemoveInterface(eq(WIFI_IFNAME), anyInt(), 11281 eq(Integer.toString(TRANSPORT_WIFI))); 11282 11283 // Clean up 11284 mCm.unregisterNetworkCallback(networkCallback); 11285 } 11286 11287 private void verifyTcpBufferSizeChange(String tcpBufferSizes) throws Exception { 11288 String[] values = tcpBufferSizes.split(","); 11289 String rmemValues = String.join(" ", values[0], values[1], values[2]); 11290 String wmemValues = String.join(" ", values[3], values[4], values[5]); 11291 verify(mMockNetd, atLeastOnce()).setTcpRWmemorySize(rmemValues, wmemValues); 11292 reset(mMockNetd); 11293 } 11294 11295 @Test 11296 public void testTcpBufferReset() throws Exception { 11297 final String testTcpBufferSizes = "1,2,3,4,5,6"; 11298 final NetworkRequest networkRequest = new NetworkRequest.Builder() 11299 .addTransportType(TRANSPORT_CELLULAR) 11300 .addCapability(NET_CAPABILITY_INTERNET) 11301 .build(); 11302 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 11303 mCm.registerNetworkCallback(networkRequest, networkCallback); 11304 11305 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 11306 reset(mMockNetd); 11307 // Switching default network updates TCP buffer sizes. 11308 mCellAgent.connect(false); 11309 networkCallback.expectAvailableCallbacksUnvalidated(mCellAgent); 11310 verifyTcpBufferSizeChange(ConnectivityService.DEFAULT_TCP_BUFFER_SIZES); 11311 // Change link Properties should have updated tcp buffer size. 11312 LinkProperties lp = new LinkProperties(); 11313 lp.setTcpBufferSizes(testTcpBufferSizes); 11314 mCellAgent.sendLinkProperties(lp); 11315 networkCallback.expect(LINK_PROPERTIES_CHANGED, mCellAgent); 11316 verifyTcpBufferSizeChange(testTcpBufferSizes); 11317 // Clean up. 11318 mCellAgent.disconnect(); 11319 networkCallback.expect(LOST, mCellAgent); 11320 networkCallback.assertNoCallback(); 11321 mCm.unregisterNetworkCallback(networkCallback); 11322 } 11323 11324 @Test 11325 public void testGetGlobalProxyForNetwork() throws Exception { 11326 final ProxyInfo testProxyInfo = ProxyInfo.buildDirectProxy("test", 8888); 11327 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 11328 final Network wifiNetwork = mWiFiAgent.getNetwork(); 11329 mProxyTracker.setGlobalProxy(testProxyInfo); 11330 assertEquals(testProxyInfo, mService.getProxyForNetwork(wifiNetwork)); 11331 } 11332 11333 @Test 11334 public void testGetProxyForActiveNetwork() throws Exception { 11335 final ProxyInfo testProxyInfo = ProxyInfo.buildDirectProxy("test", 8888); 11336 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 11337 mWiFiAgent.connect(true); 11338 waitForIdle(); 11339 assertNull(mService.getProxyForNetwork(null)); 11340 11341 final LinkProperties testLinkProperties = new LinkProperties(); 11342 testLinkProperties.setHttpProxy(testProxyInfo); 11343 11344 mWiFiAgent.sendLinkProperties(testLinkProperties); 11345 waitForIdle(); 11346 11347 assertEquals(testProxyInfo, mService.getProxyForNetwork(null)); 11348 } 11349 11350 /* 11351 * Note for maintainers about how PAC proxies are implemented in Android. 11352 * 11353 * Generally, a proxy is just a hostname and a port to which requests are sent, instead of 11354 * sending them directly. Most HTTP libraries know to use this protocol, and the Java 11355 * language has properties to help handling these : 11356 * https://docs.oracle.com/javase/8/docs/technotes/guides/net/proxies.html 11357 * Unfortunately these properties are very old and do not take multi-networking into account. 11358 * 11359 * A PAC proxy consists of a javascript file stored on a server, and the client is expected to 11360 * download the file and interpret the javascript for each HTTP request to know where to direct 11361 * it. The device must therefore run code (namely, a javascript interpreter) to interpret the 11362 * PAC file correctly. Most HTTP libraries do not know how to do this, since they do not 11363 * embark a javascript interpreter (and it would be generally unreasonable for them to do 11364 * so). Some apps, notably browsers, do know how to do this, but they are the exception rather 11365 * than the rule. 11366 * So to support most apps, Android embarks the javascript interpreter. When a network is 11367 * configured to have a PAC proxy, Android will first set the ProxyInfo object to an object 11368 * that contains the PAC URL (to communicate that to apps that know how to use it), then 11369 * download the PAC file and start a native process which will open a server on localhost, 11370 * and uses the interpreter inside WebView to interpret the PAC file. This server takes 11371 * a little bit of time to start and will listen on a random port. When the port is known, 11372 * the framework receives a notification and it updates the ProxyInfo in LinkProperties 11373 * as well as send a broadcast to inform apps. This new ProxyInfo still contains the PAC URL, 11374 * but it also contains "localhost" as the host and the port that the server listens to as 11375 * the port. This will let HTTP libraries that don't have a javascript interpreter work, 11376 * because they'll send the requests to this server running on localhost on the correct port, 11377 * and this server will do what is appropriate with each request according to the PAC file. 11378 * 11379 * Note that at the time of this writing, Android does not support starting multiple local 11380 * PAC servers, though this would be possible in theory by just starting multiple instances 11381 * of this process running their server on different ports. As a stopgap measure, Android 11382 * keeps one local server which is always the one for the default network. If a non-default 11383 * network has a PAC proxy, it will have a LinkProperties with a port of -1, which means it 11384 * could still be used by apps that know how to use the PAC URL directly, but not by HTTP 11385 * libs that don't know how to do that. When a network with a PAC proxy becomes the default, 11386 * the local server is started. When a network without a PAC proxy becomes the default, the 11387 * local server is stopped if it is running (and the LP for the old default network should 11388 * be reset to have a port of -1). 11389 * 11390 * In principle, each network can be configured with a different proxy (typically in the 11391 * network settings for a Wi-Fi network). These end up exposed in the LinkProperties of the 11392 * relevant network. 11393 * Android also exposes ConnectivityManager#getDefaultProxy, which is simply the proxy for 11394 * the default network. This was retrofitted from a time where Android did not support multiple 11395 * concurrent networks, hence the difficult architecture. 11396 * Note that there is also a "global" proxy that can be set by the DPM. When this is set, 11397 * it overrides the proxy settings for every single network at the same time – that is, the 11398 * system behaves as if the global proxy is the configured proxy for each network. 11399 * 11400 * Generally there are four ways for apps to look up the proxy. 11401 * - Looking up the ProxyInfo in the LinkProperties for a network. 11402 * - Listening to the PROXY_CHANGED_ACTION broadcast 11403 * - Calling ConnectivityManager#getDefaultProxy, or ConnectivityManager#getProxyForNetwork 11404 * which can be used to retrieve the proxy for any given network or the default network by 11405 * passing null. 11406 * - Reading the standard JVM properties (http{s,}.proxy{Host,Port}). See the Java 11407 * distribution documentation for details on how these are supposed to work : 11408 * https://docs.oracle.com/javase/8/docs/technotes/guides/net/proxies.html 11409 * In Android, these are set by ActivityThread in each process in response to the broadcast. 11410 * Many apps actually use these, and it's important they work because it's part of the 11411 * Java standard, meaning they need to be set for existing Java libs to work on Android. 11412 */ 11413 @Test 11414 public void testPacProxy() throws Exception { 11415 final Uri pacUrl = Uri.parse("https://pac-url"); 11416 11417 final TestNetworkCallback cellCallback = new TestNetworkCallback(); 11418 final NetworkRequest cellRequest = new NetworkRequest.Builder() 11419 .addTransportType(TRANSPORT_CELLULAR).build(); 11420 // Request cell to make sure it doesn't disconnect at an arbitrary point in the test, 11421 // which would make testing the callbacks on it difficult. 11422 mCm.requestNetwork(cellRequest, cellCallback); 11423 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 11424 mCellAgent.connect(true); 11425 cellCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 11426 11427 final TestNetworkCallback wifiCallback = new TestNetworkCallback(); 11428 final NetworkRequest wifiRequest = new NetworkRequest.Builder() 11429 .addTransportType(TRANSPORT_WIFI).build(); 11430 mCm.registerNetworkCallback(wifiRequest, wifiCallback); 11431 11432 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 11433 mWiFiAgent.connect(true); 11434 wifiCallback.expectAvailableThenValidatedCallbacks(mWiFiAgent); 11435 cellCallback.assertNoCallback(); 11436 11437 final ProxyInfo initialProxyInfo = ProxyInfo.buildPacProxy(pacUrl); 11438 final LinkProperties testLinkProperties = new LinkProperties(); 11439 testLinkProperties.setHttpProxy(initialProxyInfo); 11440 mWiFiAgent.sendLinkProperties(testLinkProperties); 11441 wifiCallback.expect(CallbackEntry.LINK_PROPERTIES_CHANGED, mWiFiAgent); 11442 cellCallback.assertNoCallback(); 11443 11444 // At first the local PAC proxy server is unstarted (see the description of what the local 11445 // server is in the comment at the top of this method). It will contain the PAC URL and a 11446 // port of -1 because it is unstarted. Check that all ways of getting that proxy info 11447 // returns the same object that was initially created. 11448 final ProxyInfo unstartedDefaultProxyInfo = mService.getProxyForNetwork(null); 11449 final ProxyInfo unstartedWifiProxyInfo = mService.getProxyForNetwork( 11450 mWiFiAgent.getNetwork()); 11451 final LinkProperties unstartedLp = 11452 mService.getLinkProperties(mWiFiAgent.getNetwork()); 11453 11454 assertEquals(initialProxyInfo, unstartedDefaultProxyInfo); 11455 assertEquals(initialProxyInfo, unstartedWifiProxyInfo); 11456 assertEquals(initialProxyInfo, unstartedLp.getHttpProxy()); 11457 11458 // Make sure the cell network is unaffected. The LP are per-network and each network has 11459 // its own configuration. The default proxy and broadcast are system-wide, and the JVM 11460 // properties are per-process, and therefore can have only one value at any given time, 11461 // so the code sets them to the proxy of the default network (TODO : really, since the 11462 // default process is per-network, the JVM properties (http.proxyHost family – see 11463 // the comment at the top of the method for details about these) also should be per-network 11464 // and even the broadcast contents should be but none of this is implemented). The LP are 11465 // still per-network, and a process that wants to use a non-default network is supposed to 11466 // look up the proxy in its LP and it has to be correct. 11467 assertNull(mService.getLinkProperties(mCellAgent.getNetwork()).getHttpProxy()); 11468 assertNull(mService.getProxyForNetwork(mCellAgent.getNetwork())); 11469 11470 // Simulate PacManager sending the notification that the local server has started 11471 final ProxyInfo servingProxyInfo = new ProxyInfo(pacUrl, 2097); 11472 final ExpectedBroadcast servingProxyBroadcast = expectProxyChangeAction(servingProxyInfo); 11473 mService.simulateUpdateProxyInfo(mWiFiAgent.getNetwork(), servingProxyInfo); 11474 wifiCallback.expect(CallbackEntry.LINK_PROPERTIES_CHANGED, mWiFiAgent); 11475 cellCallback.assertNoCallback(); 11476 servingProxyBroadcast.expectBroadcast(); 11477 11478 final ProxyInfo startedDefaultProxyInfo = mService.getProxyForNetwork(null); 11479 final ProxyInfo startedWifiProxyInfo = mService.getProxyForNetwork( 11480 mWiFiAgent.getNetwork()); 11481 final LinkProperties startedLp = mService.getLinkProperties(mWiFiAgent.getNetwork()); 11482 assertEquals(servingProxyInfo, startedDefaultProxyInfo); 11483 assertEquals(servingProxyInfo, startedWifiProxyInfo); 11484 assertEquals(servingProxyInfo, startedLp.getHttpProxy()); 11485 // Make sure the cell network is still unaffected 11486 assertNull(mService.getLinkProperties(mCellAgent.getNetwork()).getHttpProxy()); 11487 assertNull(mService.getProxyForNetwork(mCellAgent.getNetwork())); 11488 11489 // Start an ethernet network which will become the default, in order to test what happens 11490 // to the proxy of wifi while manipulating the proxy of ethernet. 11491 final Uri ethPacUrl = Uri.parse("https://ethernet-pac-url"); 11492 final TestableNetworkCallback ethernetCallback = new TestableNetworkCallback(); 11493 final NetworkRequest ethernetRequest = new NetworkRequest.Builder() 11494 .addTransportType(TRANSPORT_ETHERNET).build(); 11495 mEthernetAgent = new TestNetworkAgentWrapper(TRANSPORT_ETHERNET); 11496 mCm.registerNetworkCallback(ethernetRequest, ethernetCallback); 11497 mEthernetAgent.connect(true); 11498 ethernetCallback.expectAvailableThenValidatedCallbacks(mEthernetAgent); 11499 11500 // Wifi is no longer the default, so it should get a callback to LP changed with a PAC 11501 // proxy but a port of -1 (since the local proxy doesn't serve wifi now) 11502 wifiCallback.expect(LINK_PROPERTIES_CHANGED, mWiFiAgent, 11503 lp -> lp.getLp().getHttpProxy().getPort() == -1 11504 && lp.getLp().getHttpProxy().isPacProxy()); 11505 // Wifi is lingered as it was the default but is no longer serving any request. 11506 wifiCallback.expect(CallbackEntry.LOSING, mWiFiAgent); 11507 11508 // Now arrange for Ethernet to have a PAC proxy. 11509 final ProxyInfo ethProxy = ProxyInfo.buildPacProxy(ethPacUrl); 11510 final LinkProperties ethLinkProperties = new LinkProperties(); 11511 ethLinkProperties.setHttpProxy(ethProxy); 11512 mEthernetAgent.sendLinkProperties(ethLinkProperties); 11513 ethernetCallback.expect(CallbackEntry.LINK_PROPERTIES_CHANGED, mEthernetAgent); 11514 // Default network is Ethernet 11515 assertEquals(ethProxy, mService.getProxyForNetwork(null)); 11516 assertEquals(ethProxy, mService.getProxyForNetwork(mEthernetAgent.getNetwork())); 11517 // Proxy info for WiFi ideally should be the old one with the old server still running, 11518 // but as the PAC code only handles one server at any given time, this can't work. Wifi 11519 // having null as a proxy also won't work (apps using WiFi will try to access the network 11520 // without proxy) but is not as bad as having the new proxy (that would send requests 11521 // over the default network). 11522 assertEquals(initialProxyInfo, mService.getProxyForNetwork(mWiFiAgent.getNetwork())); 11523 assertNull(mService.getProxyForNetwork(mCellAgent.getNetwork())); 11524 11525 // Expect the local PAC proxy server starts to serve the proxy on Ethernet. Use 11526 // simulateUpdateProxyInfo to simulate this, and check that the callback is called to 11527 // inform apps of the port and that the various networks have the expected proxies in 11528 // their link properties. 11529 final ProxyInfo servingEthProxy = new ProxyInfo(ethPacUrl, 2099); 11530 final ExpectedBroadcast servingEthProxyBroadcast = expectProxyChangeAction(servingEthProxy); 11531 final ExpectedBroadcast servingProxyBroadcast2 = expectProxyChangeAction(servingProxyInfo); 11532 mService.simulateUpdateProxyInfo(mEthernetAgent.getNetwork(), servingEthProxy); 11533 ethernetCallback.expect(CallbackEntry.LINK_PROPERTIES_CHANGED, mEthernetAgent); 11534 assertEquals(servingEthProxy, mService.getProxyForNetwork(null)); 11535 assertEquals(servingEthProxy, mService.getProxyForNetwork(mEthernetAgent.getNetwork())); 11536 assertEquals(initialProxyInfo, mService.getProxyForNetwork(mWiFiAgent.getNetwork())); 11537 assertNull(mService.getProxyForNetwork(mCellAgent.getNetwork())); 11538 servingEthProxyBroadcast.expectBroadcast(); 11539 11540 // Ethernet disconnects, back to WiFi 11541 mEthernetAgent.disconnect(); 11542 ethernetCallback.expect(CallbackEntry.LOST, mEthernetAgent); 11543 11544 // WiFi is now the default network again. However, the local proxy server does not serve 11545 // WiFi at this time, so at this time a proxy with port -1 is still the correct value. 11546 // In time, the local proxy server for ethernet will be downed and the local proxy server 11547 // for WiFi will be restarted, and WiFi will see an update to its LP with the new port, 11548 // but in this test this won't happen until the test simulates the local proxy starting 11549 // up for WiFi (which is done just a few lines below). This is therefore the perfect place 11550 // to check that WiFi is unaffected until the new local proxy starts up. 11551 wifiCallback.assertNoCallback(); 11552 assertEquals(initialProxyInfo, mService.getProxyForNetwork(null)); 11553 assertEquals(initialProxyInfo, mService.getProxyForNetwork(mWiFiAgent.getNetwork())); 11554 assertNull(mService.getProxyForNetwork(mCellAgent.getNetwork())); 11555 // Note : strictly speaking, for correctness here apps should expect a broadcast with a 11556 // port of -1, since that's the current default proxy. The code does not send this 11557 // broadcast. In practice though, not sending it is more useful since the new proxy will 11558 // start momentarily, so broadcasting and getting all apps to update and retry once now 11559 // and again in 250ms is kind of counter-productive, so don't fix this bug. 11560 11561 // After a while the PAC file for wifi is resolved again and the local proxy server 11562 // starts up. This should cause a LP event to inform clients of the port to access the 11563 // proxy server for wifi. 11564 mService.simulateUpdateProxyInfo(mWiFiAgent.getNetwork(), servingProxyInfo); 11565 wifiCallback.expect(CallbackEntry.LINK_PROPERTIES_CHANGED, mWiFiAgent); 11566 assertEquals(servingProxyInfo, mService.getProxyForNetwork(null)); 11567 assertEquals(servingProxyInfo, mService.getProxyForNetwork(mWiFiAgent.getNetwork())); 11568 assertNull(mService.getProxyForNetwork(mCellAgent.getNetwork())); 11569 servingProxyBroadcast2.expectBroadcast(); 11570 11571 // Expect a broadcast for an empty proxy after wifi disconnected, because cell is now 11572 // the default network and it doesn't have a proxy. Whether "no proxy" is a null pointer 11573 // or a ProxyInfo with an empty host doesn't matter because both are correct, so this test 11574 // accepts both. 11575 final ExpectedBroadcast emptyProxyBroadcast = expectProxyChangeAction( 11576 proxy -> proxy == null || TextUtils.isEmpty(proxy.getHost())); 11577 mWiFiAgent.disconnect(); 11578 emptyProxyBroadcast.expectBroadcast(); 11579 wifiCallback.expect(CallbackEntry.LOST, mWiFiAgent); 11580 assertNull(mService.getProxyForNetwork(null)); 11581 assertNull(mService.getLinkProperties(mCellAgent.getNetwork()).getHttpProxy()); 11582 assertNull(mService.getGlobalProxy()); 11583 11584 mCm.unregisterNetworkCallback(cellCallback); 11585 } 11586 11587 @Test 11588 public void testPacProxy_NetworkDisconnects_BroadcastSent() throws Exception { 11589 // Make a WiFi network with a PAC URI. 11590 final Uri pacUrl = Uri.parse("https://pac-url"); 11591 final ProxyInfo initialProxyInfo = ProxyInfo.buildPacProxy(pacUrl); 11592 final LinkProperties testLinkProperties = new LinkProperties(); 11593 testLinkProperties.setHttpProxy(initialProxyInfo); 11594 11595 final TestNetworkCallback wifiCallback = new TestNetworkCallback(); 11596 final NetworkRequest wifiRequest = new NetworkRequest.Builder() 11597 .addTransportType(TRANSPORT_WIFI).build(); 11598 mCm.registerNetworkCallback(wifiRequest, wifiCallback); 11599 11600 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, testLinkProperties); 11601 mWiFiAgent.connect(true); 11602 // Wifi is up, but the local proxy server hasn't started yet. 11603 wifiCallback.expectAvailableThenValidatedCallbacks(mWiFiAgent); 11604 11605 // Simulate PacManager sending the notification that the local server has started 11606 final ProxyInfo servingProxyInfo = new ProxyInfo(pacUrl, 2097); 11607 final ExpectedBroadcast servingProxyBroadcast = expectProxyChangeAction(servingProxyInfo); 11608 mService.simulateUpdateProxyInfo(mWiFiAgent.getNetwork(), servingProxyInfo); 11609 wifiCallback.expect(CallbackEntry.LINK_PROPERTIES_CHANGED, mWiFiAgent); 11610 servingProxyBroadcast.expectBroadcast(); 11611 11612 // Now disconnect Wi-Fi and make sure there is a broadcast for some empty proxy. Whether 11613 // the "empty" proxy is a null pointer or a ProxyInfo with an empty host doesn't matter 11614 // because both are correct, so this test accepts both. 11615 final ExpectedBroadcast emptyProxyBroadcast = expectProxyChangeAction( 11616 proxy -> proxy == null || TextUtils.isEmpty(proxy.getHost())); 11617 mWiFiAgent.disconnect(); 11618 wifiCallback.expect(CallbackEntry.LOST, mWiFiAgent); 11619 emptyProxyBroadcast.expectBroadcast(); 11620 } 11621 11622 @Test 11623 public void testGetProxyForVPN() throws Exception { 11624 final ProxyInfo testProxyInfo = ProxyInfo.buildDirectProxy("test", 8888); 11625 11626 // Set up a WiFi network with no proxy 11627 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 11628 mWiFiAgent.connect(true); 11629 waitForIdle(); 11630 assertNull(mService.getProxyForNetwork(null)); 11631 11632 // Connect a VPN network with a proxy. 11633 LinkProperties testLinkProperties = new LinkProperties(); 11634 testLinkProperties.setHttpProxy(testProxyInfo); 11635 mMockVpn.establishForMyUid(testLinkProperties); 11636 assertUidRangesUpdatedForMyUid(true); 11637 11638 // Test that the VPN network returns a proxy, and the WiFi does not. 11639 assertEquals(testProxyInfo, mService.getProxyForNetwork(mMockVpn.getNetwork())); 11640 assertEquals(testProxyInfo, mService.getProxyForNetwork(null)); 11641 assertNull(mService.getProxyForNetwork(mWiFiAgent.getNetwork())); 11642 11643 // Test that the VPN network returns no proxy when it is set to null. 11644 testLinkProperties.setHttpProxy(null); 11645 mMockVpn.sendLinkProperties(testLinkProperties); 11646 waitForIdle(); 11647 assertNull(mService.getProxyForNetwork(mMockVpn.getNetwork())); 11648 assertNull(mService.getProxyForNetwork(null)); 11649 11650 // Set WiFi proxy and check that the vpn proxy is still null. 11651 testLinkProperties.setHttpProxy(testProxyInfo); 11652 mWiFiAgent.sendLinkProperties(testLinkProperties); 11653 waitForIdle(); 11654 assertNull(mService.getProxyForNetwork(null)); 11655 11656 // Disconnect from VPN and check that the active network, which is now the WiFi, has the 11657 // correct proxy setting. 11658 mMockVpn.disconnect(); 11659 waitForIdle(); 11660 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetwork()); 11661 assertEquals(testProxyInfo, mService.getProxyForNetwork(mWiFiAgent.getNetwork())); 11662 assertEquals(testProxyInfo, mService.getProxyForNetwork(null)); 11663 } 11664 11665 @Test 11666 public void testFullyRoutedVpnResultsInInterfaceFilteringRules() throws Exception { 11667 LinkProperties lp = new LinkProperties(); 11668 lp.setInterfaceName("tun0"); 11669 lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), null)); 11670 lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), RTN_UNREACHABLE)); 11671 // The uid range needs to cover the test app so the network is visible to it. 11672 final Set<UidRange> vpnRange = Collections.singleton(PRIMARY_UIDRANGE); 11673 mMockVpn.establish(lp, VPN_UID, vpnRange); 11674 assertVpnUidRangesUpdated(true, vpnRange, VPN_UID); 11675 11676 // A connected VPN should have interface rules set up. There are two expected invocations, 11677 // one during the VPN initial connection, one during the VPN LinkProperties update. 11678 ArgumentCaptor<int[]> uidCaptor = ArgumentCaptor.forClass(int[].class); 11679 verify(mBpfNetMaps, times(2)).addUidInterfaceRules(eq("tun0"), uidCaptor.capture()); 11680 assertContainsExactly(uidCaptor.getAllValues().get(0), APP1_UID, APP2_UID); 11681 assertContainsExactly(uidCaptor.getAllValues().get(1), APP1_UID, APP2_UID); 11682 11683 mMockVpn.disconnect(); 11684 waitForIdle(); 11685 11686 // Disconnected VPN should have interface rules removed 11687 verify(mBpfNetMaps).removeUidInterfaceRules(uidCaptor.capture()); 11688 assertContainsExactly(uidCaptor.getValue(), APP1_UID, APP2_UID); 11689 } 11690 11691 private void checkInterfaceFilteringRuleWithNullInterface(final LinkProperties lp, 11692 final int uid) throws Exception { 11693 // The uid range needs to cover the test app so the network is visible to it. 11694 final Set<UidRange> vpnRange = Collections.singleton(PRIMARY_UIDRANGE); 11695 mMockVpn.establish(lp, uid, vpnRange); 11696 assertVpnUidRangesUpdated(true, vpnRange, uid); 11697 11698 if (mDeps.isAtLeastT()) { 11699 // On T and above, VPN should have rules for null interface. Null Interface is a 11700 // wildcard and this accepts traffic from all the interfaces. 11701 // There are two expected invocations, one during the VPN initial 11702 // connection, one during the VPN LinkProperties update. 11703 ArgumentCaptor<int[]> uidCaptor = ArgumentCaptor.forClass(int[].class); 11704 verify(mBpfNetMaps, times(2)).addUidInterfaceRules( 11705 eq(null) /* iface */, uidCaptor.capture()); 11706 if (uid == VPN_UID) { 11707 assertContainsExactly(uidCaptor.getAllValues().get(0), APP1_UID, APP2_UID); 11708 assertContainsExactly(uidCaptor.getAllValues().get(1), APP1_UID, APP2_UID); 11709 } else { 11710 assertContainsExactly(uidCaptor.getAllValues().get(0), APP1_UID, APP2_UID, VPN_UID); 11711 assertContainsExactly(uidCaptor.getAllValues().get(1), APP1_UID, APP2_UID, VPN_UID); 11712 } 11713 11714 mMockVpn.disconnect(); 11715 waitForIdle(); 11716 11717 // Disconnected VPN should have interface rules removed 11718 verify(mBpfNetMaps).removeUidInterfaceRules(uidCaptor.capture()); 11719 if (uid == VPN_UID) { 11720 assertContainsExactly(uidCaptor.getValue(), APP1_UID, APP2_UID); 11721 } else { 11722 assertContainsExactly(uidCaptor.getValue(), APP1_UID, APP2_UID, VPN_UID); 11723 } 11724 } else { 11725 // Before T, rules are not configured for null interface. 11726 verify(mBpfNetMaps, never()).addUidInterfaceRules(any(), any()); 11727 } 11728 } 11729 11730 @Test 11731 public void testLegacyVpnInterfaceFilteringRule() throws Exception { 11732 LinkProperties lp = new LinkProperties(); 11733 lp.setInterfaceName("tun0"); 11734 lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), null)); 11735 lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), null)); 11736 // Legacy VPN should have interface filtering with null interface. 11737 checkInterfaceFilteringRuleWithNullInterface(lp, Process.SYSTEM_UID); 11738 } 11739 11740 @Test 11741 public void testLocalIpv4OnlyVpnInterfaceFilteringRule() throws Exception { 11742 LinkProperties lp = new LinkProperties(); 11743 lp.setInterfaceName("tun0"); 11744 lp.addRoute(new RouteInfo(new IpPrefix("192.0.2.0/24"), null, "tun0")); 11745 lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), RTN_UNREACHABLE)); 11746 // VPN that does not provide a default route should have interface filtering with null 11747 // interface. 11748 checkInterfaceFilteringRuleWithNullInterface(lp, VPN_UID); 11749 } 11750 11751 @Test 11752 public void testVpnHandoverChangesInterfaceFilteringRule() throws Exception { 11753 LinkProperties lp = new LinkProperties(); 11754 lp.setInterfaceName("tun0"); 11755 lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), null)); 11756 lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), null)); 11757 // The uid range needs to cover the test app so the network is visible to it. 11758 final Set<UidRange> vpnRange = Collections.singleton(PRIMARY_UIDRANGE); 11759 mMockVpn.establish(lp, VPN_UID, vpnRange); 11760 assertVpnUidRangesUpdated(true, vpnRange, VPN_UID); 11761 11762 // Connected VPN should have interface rules set up. There are two expected invocations, 11763 // one during VPN uid update, one during VPN LinkProperties update 11764 ArgumentCaptor<int[]> uidCaptor = ArgumentCaptor.forClass(int[].class); 11765 verify(mBpfNetMaps, times(2)).addUidInterfaceRules(eq("tun0"), uidCaptor.capture()); 11766 assertContainsExactly(uidCaptor.getAllValues().get(0), APP1_UID, APP2_UID); 11767 assertContainsExactly(uidCaptor.getAllValues().get(1), APP1_UID, APP2_UID); 11768 11769 reset(mBpfNetMaps); 11770 InOrder inOrder = inOrder(mBpfNetMaps); 11771 lp.setInterfaceName("tun1"); 11772 mMockVpn.sendLinkProperties(lp); 11773 waitForIdle(); 11774 // VPN handover (switch to a new interface) should result in rules being updated (old rules 11775 // removed first, then new rules added) 11776 inOrder.verify(mBpfNetMaps).removeUidInterfaceRules(uidCaptor.capture()); 11777 assertContainsExactly(uidCaptor.getValue(), APP1_UID, APP2_UID); 11778 inOrder.verify(mBpfNetMaps).addUidInterfaceRules(eq("tun1"), uidCaptor.capture()); 11779 assertContainsExactly(uidCaptor.getValue(), APP1_UID, APP2_UID); 11780 11781 reset(mBpfNetMaps); 11782 lp = new LinkProperties(); 11783 lp.setInterfaceName("tun1"); 11784 lp.addRoute(new RouteInfo(new IpPrefix("192.0.2.0/24"), null, "tun1")); 11785 mMockVpn.sendLinkProperties(lp); 11786 waitForIdle(); 11787 // VPN not routing everything should no longer have interface filtering rules 11788 verify(mBpfNetMaps).removeUidInterfaceRules(uidCaptor.capture()); 11789 assertContainsExactly(uidCaptor.getValue(), APP1_UID, APP2_UID); 11790 11791 reset(mBpfNetMaps); 11792 lp = new LinkProperties(); 11793 lp.setInterfaceName("tun1"); 11794 lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), RTN_UNREACHABLE)); 11795 lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), null)); 11796 mMockVpn.sendLinkProperties(lp); 11797 waitForIdle(); 11798 // Back to routing all IPv6 traffic should have filtering rules 11799 verify(mBpfNetMaps).addUidInterfaceRules(eq("tun1"), uidCaptor.capture()); 11800 assertContainsExactly(uidCaptor.getValue(), APP1_UID, APP2_UID); 11801 } 11802 11803 @Test 11804 public void testUidUpdateChangesInterfaceFilteringRule() throws Exception { 11805 LinkProperties lp = new LinkProperties(); 11806 lp.setInterfaceName("tun0"); 11807 lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), RTN_UNREACHABLE)); 11808 lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), null)); 11809 // The uid range needs to cover the test app so the network is visible to it. 11810 final UidRange vpnRange = PRIMARY_UIDRANGE; 11811 final Set<UidRange> vpnRanges = Collections.singleton(vpnRange); 11812 mMockVpn.establish(lp, VPN_UID, vpnRanges); 11813 assertVpnUidRangesUpdated(true, vpnRanges, VPN_UID); 11814 11815 reset(mBpfNetMaps); 11816 InOrder inOrder = inOrder(mBpfNetMaps); 11817 11818 // Update to new range which is old range minus APP1, i.e. only APP2 11819 final Set<UidRange> newRanges = new HashSet<>(asList( 11820 new UidRange(vpnRange.start, APP1_UID - 1), 11821 new UidRange(APP1_UID + 1, vpnRange.stop))); 11822 mMockVpn.setUids(newRanges); 11823 waitForIdle(); 11824 11825 ArgumentCaptor<int[]> uidCaptor = ArgumentCaptor.forClass(int[].class); 11826 // Verify old rules are removed before new rules are added 11827 inOrder.verify(mBpfNetMaps).removeUidInterfaceRules(uidCaptor.capture()); 11828 assertContainsExactly(uidCaptor.getValue(), APP1_UID, APP2_UID); 11829 inOrder.verify(mBpfNetMaps).addUidInterfaceRules(eq("tun0"), uidCaptor.capture()); 11830 assertContainsExactly(uidCaptor.getValue(), APP2_UID); 11831 } 11832 11833 @Test 11834 public void testLinkPropertiesWithWakeOnLanForActiveNetwork() throws Exception { 11835 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 11836 11837 LinkProperties wifiLp = new LinkProperties(); 11838 wifiLp.setInterfaceName(WIFI_WOL_IFNAME); 11839 wifiLp.setWakeOnLanSupported(false); 11840 11841 // Default network switch should update ifaces. 11842 mWiFiAgent.connect(false); 11843 mWiFiAgent.sendLinkProperties(wifiLp); 11844 waitForIdle(); 11845 11846 // ConnectivityService should have changed the WakeOnLanSupported to true 11847 wifiLp.setWakeOnLanSupported(true); 11848 assertEquals(wifiLp, mService.getActiveLinkProperties()); 11849 } 11850 11851 @Test 11852 public void testLegacyExtraInfoSentToNetworkMonitor() throws Exception { 11853 class TestNetworkAgent extends NetworkAgent { 11854 TestNetworkAgent(Context context, Looper looper, NetworkAgentConfig config) { 11855 super(context, looper, "MockAgent", new NetworkCapabilities(), 11856 new LinkProperties(), 40 , config, null /* provider */); 11857 } 11858 } 11859 final NetworkAgent naNoExtraInfo = new TestNetworkAgent( 11860 mServiceContext, mCsHandlerThread.getLooper(), new NetworkAgentConfig()); 11861 naNoExtraInfo.register(); 11862 verify(mNetworkStack).makeNetworkMonitor(any(), isNull(String.class), any()); 11863 naNoExtraInfo.unregister(); 11864 11865 reset(mNetworkStack); 11866 final NetworkAgentConfig config = 11867 new NetworkAgentConfig.Builder().setLegacyExtraInfo("legacyinfo").build(); 11868 final NetworkAgent naExtraInfo = new TestNetworkAgent( 11869 mServiceContext, mCsHandlerThread.getLooper(), config); 11870 naExtraInfo.register(); 11871 verify(mNetworkStack).makeNetworkMonitor(any(), eq("legacyinfo"), any()); 11872 naExtraInfo.unregister(); 11873 } 11874 11875 // To avoid granting location permission bypass. 11876 private void denyAllLocationPrivilegedPermissions() { 11877 mServiceContext.setPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, 11878 PERMISSION_DENIED); 11879 mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_DENIED); 11880 mServiceContext.setPermission(NETWORK_STACK, PERMISSION_DENIED); 11881 mServiceContext.setPermission(Manifest.permission.NETWORK_SETUP_WIZARD, 11882 PERMISSION_DENIED); 11883 } 11884 11885 private void setupLocationPermissions( 11886 int targetSdk, boolean locationToggle, String op, String perm) throws Exception { 11887 denyAllLocationPrivilegedPermissions(); 11888 11889 final ApplicationInfo applicationInfo = new ApplicationInfo(); 11890 applicationInfo.targetSdkVersion = targetSdk; 11891 doReturn(applicationInfo).when(mPackageManager) 11892 .getApplicationInfoAsUser(anyString(), anyInt(), any()); 11893 doReturn(targetSdk).when(mPackageManager).getTargetSdkVersion(any()); 11894 11895 doReturn(locationToggle).when(mLocationManager).isLocationEnabledForUser(any()); 11896 11897 if (op != null) { 11898 doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager).noteOp( 11899 eq(op), eq(Process.myUid()), eq(mContext.getPackageName()), 11900 eq(getAttributionTag()), anyString()); 11901 } 11902 11903 if (perm != null) { 11904 mServiceContext.setPermission(perm, PERMISSION_GRANTED); 11905 } 11906 } 11907 11908 private int getOwnerUidNetCapsPermission(int ownerUid, int callerUid, 11909 boolean includeLocationSensitiveInfo) { 11910 final NetworkCapabilities netCap = new NetworkCapabilities().setOwnerUid(ownerUid); 11911 11912 return mService.createWithLocationInfoSanitizedIfNecessaryWhenParceled( 11913 netCap, includeLocationSensitiveInfo, Process.myUid(), callerUid, 11914 mContext.getPackageName(), getAttributionTag()) 11915 .getOwnerUid(); 11916 } 11917 11918 private void verifyTransportInfoCopyNetCapsPermission( 11919 int callerUid, boolean includeLocationSensitiveInfo, 11920 boolean shouldMakeCopyWithLocationSensitiveFieldsParcelable) { 11921 final TransportInfo transportInfo = mock(TransportInfo.class); 11922 doReturn(REDACT_FOR_ACCESS_FINE_LOCATION).when(transportInfo).getApplicableRedactions(); 11923 final NetworkCapabilities netCap = 11924 new NetworkCapabilities().setTransportInfo(transportInfo); 11925 11926 mService.createWithLocationInfoSanitizedIfNecessaryWhenParceled( 11927 netCap, includeLocationSensitiveInfo, Process.myPid(), callerUid, 11928 mContext.getPackageName(), getAttributionTag()); 11929 if (shouldMakeCopyWithLocationSensitiveFieldsParcelable) { 11930 verify(transportInfo).makeCopy(REDACT_NONE); 11931 } else { 11932 verify(transportInfo).makeCopy(REDACT_FOR_ACCESS_FINE_LOCATION); 11933 } 11934 } 11935 11936 private void verifyOwnerUidAndTransportInfoNetCapsPermission( 11937 boolean shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag, 11938 boolean shouldInclLocationSensitiveOwnerUidWithIncludeFlag, 11939 boolean shouldInclLocationSensitiveTransportInfoWithoutIncludeFlag, 11940 boolean shouldInclLocationSensitiveTransportInfoWithIncludeFlag) { 11941 final int myUid = Process.myUid(); 11942 11943 final int expectedOwnerUidWithoutIncludeFlag = 11944 shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag 11945 ? myUid : INVALID_UID; 11946 assertEquals(expectedOwnerUidWithoutIncludeFlag, getOwnerUidNetCapsPermission( 11947 myUid, myUid, false /* includeLocationSensitiveInfo */)); 11948 11949 final int expectedOwnerUidWithIncludeFlag = 11950 shouldInclLocationSensitiveOwnerUidWithIncludeFlag ? myUid : INVALID_UID; 11951 assertEquals(expectedOwnerUidWithIncludeFlag, getOwnerUidNetCapsPermission( 11952 myUid, myUid, true /* includeLocationSensitiveInfo */)); 11953 11954 verifyTransportInfoCopyNetCapsPermission(myUid, 11955 false, /* includeLocationSensitiveInfo */ 11956 shouldInclLocationSensitiveTransportInfoWithoutIncludeFlag); 11957 11958 verifyTransportInfoCopyNetCapsPermission(myUid, 11959 true, /* includeLocationSensitiveInfo */ 11960 shouldInclLocationSensitiveTransportInfoWithIncludeFlag); 11961 11962 } 11963 11964 private void verifyOwnerUidAndTransportInfoNetCapsPermissionPreS() { 11965 verifyOwnerUidAndTransportInfoNetCapsPermission( 11966 // Ensure that owner uid is included even if the request asks to remove it (which is 11967 // the default) since the app has necessary permissions and targetSdk < S. 11968 true, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */ 11969 true, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */ 11970 // Ensure that location info is removed if the request asks to remove it even if the 11971 // app has necessary permissions. 11972 false, /* shouldInclLocationSensitiveTransportInfoWithoutIncludeFlag */ 11973 true /* shouldInclLocationSensitiveTransportInfoWithIncludeFlag */ 11974 ); 11975 } 11976 11977 @Test 11978 public void testCreateWithLocationInfoSanitizedWithFineLocationAfterQPreS() 11979 throws Exception { 11980 setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION, 11981 Manifest.permission.ACCESS_FINE_LOCATION); 11982 11983 verifyOwnerUidAndTransportInfoNetCapsPermissionPreS(); 11984 } 11985 11986 @Test 11987 public void testCreateWithLocationInfoSanitizedWithFineLocationPreSWithAndWithoutCallbackFlag() 11988 throws Exception { 11989 setupLocationPermissions(Build.VERSION_CODES.R, true, AppOpsManager.OPSTR_FINE_LOCATION, 11990 Manifest.permission.ACCESS_FINE_LOCATION); 11991 11992 verifyOwnerUidAndTransportInfoNetCapsPermissionPreS(); 11993 } 11994 11995 @Test 11996 public void 11997 testCreateWithLocationInfoSanitizedWithFineLocationAfterSWithAndWithoutCallbackFlag() 11998 throws Exception { 11999 setupLocationPermissions(Build.VERSION_CODES.S, true, AppOpsManager.OPSTR_FINE_LOCATION, 12000 Manifest.permission.ACCESS_FINE_LOCATION); 12001 12002 verifyOwnerUidAndTransportInfoNetCapsPermission( 12003 // Ensure that the owner UID is removed if the request asks us to remove it even 12004 // if the app has necessary permissions since targetSdk >= S. 12005 false, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */ 12006 true, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */ 12007 // Ensure that location info is removed if the request asks to remove it even if the 12008 // app has necessary permissions. 12009 false, /* shouldInclLocationSensitiveTransportInfoWithoutIncludeFlag */ 12010 true /* shouldInclLocationSensitiveTransportInfoWithIncludeFlag */ 12011 ); 12012 } 12013 12014 @Test 12015 public void testCreateWithLocationInfoSanitizedWithCoarseLocationPreQ() 12016 throws Exception { 12017 setupLocationPermissions(Build.VERSION_CODES.P, true, AppOpsManager.OPSTR_COARSE_LOCATION, 12018 Manifest.permission.ACCESS_COARSE_LOCATION); 12019 12020 verifyOwnerUidAndTransportInfoNetCapsPermissionPreS(); 12021 } 12022 12023 private void verifyOwnerUidAndTransportInfoNetCapsNotIncluded() { 12024 verifyOwnerUidAndTransportInfoNetCapsPermission( 12025 false, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */ 12026 false, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */ 12027 false, /* shouldInclLocationSensitiveTransportInfoWithoutIncludeFlag */ 12028 false /* shouldInclLocationSensitiveTransportInfoWithIncludeFlag */ 12029 ); 12030 } 12031 12032 @Test 12033 public void testCreateWithLocationInfoSanitizedLocationOff() throws Exception { 12034 // Test that even with fine location permission, and UIDs matching, the UID is sanitized. 12035 setupLocationPermissions(Build.VERSION_CODES.Q, false, AppOpsManager.OPSTR_FINE_LOCATION, 12036 Manifest.permission.ACCESS_FINE_LOCATION); 12037 12038 verifyOwnerUidAndTransportInfoNetCapsNotIncluded(); 12039 } 12040 12041 @Test 12042 public void testCreateWithLocationInfoSanitizedWrongUid() throws Exception { 12043 // Test that even with fine location permission, not being the owner leads to sanitization. 12044 setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION, 12045 Manifest.permission.ACCESS_FINE_LOCATION); 12046 12047 final int myUid = Process.myUid(); 12048 assertEquals(Process.INVALID_UID, 12049 getOwnerUidNetCapsPermission(myUid + 1, myUid, 12050 true /* includeLocationSensitiveInfo */)); 12051 } 12052 12053 @Test 12054 public void testCreateWithLocationInfoSanitizedWithCoarseLocationAfterQ() 12055 throws Exception { 12056 // Test that not having fine location permission leads to sanitization. 12057 setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_COARSE_LOCATION, 12058 Manifest.permission.ACCESS_COARSE_LOCATION); 12059 12060 verifyOwnerUidAndTransportInfoNetCapsNotIncluded(); 12061 } 12062 12063 @Test 12064 public void testCreateWithLocationInfoSanitizedWithCoarseLocationAfterS() 12065 throws Exception { 12066 // Test that not having fine location permission leads to sanitization. 12067 setupLocationPermissions(Build.VERSION_CODES.S, true, AppOpsManager.OPSTR_COARSE_LOCATION, 12068 Manifest.permission.ACCESS_COARSE_LOCATION); 12069 12070 verifyOwnerUidAndTransportInfoNetCapsNotIncluded(); 12071 } 12072 12073 @Test 12074 public void testCreateForCallerWithLocalMacAddressSanitizedWithLocalMacAddressPermission() 12075 throws Exception { 12076 mServiceContext.setPermission(Manifest.permission.LOCAL_MAC_ADDRESS, PERMISSION_GRANTED); 12077 12078 final TransportInfo transportInfo = mock(TransportInfo.class); 12079 doReturn(REDACT_FOR_ACCESS_FINE_LOCATION | REDACT_FOR_LOCAL_MAC_ADDRESS) 12080 .when(transportInfo).getApplicableRedactions(); 12081 final NetworkCapabilities netCap = 12082 new NetworkCapabilities().setTransportInfo(transportInfo); 12083 12084 mService.createWithLocationInfoSanitizedIfNecessaryWhenParceled( 12085 netCap, false /* includeLocationSensitiveInfoInTransportInfo */, 12086 Process.myPid(), Process.myUid(), 12087 mContext.getPackageName(), getAttributionTag()); 12088 // don't redact MAC_ADDRESS fields, only location sensitive fields. 12089 verify(transportInfo).makeCopy(REDACT_FOR_ACCESS_FINE_LOCATION); 12090 } 12091 12092 @Test 12093 public void testCreateForCallerWithLocalMacAddressSanitizedWithoutLocalMacAddressPermission() 12094 throws Exception { 12095 mServiceContext.setPermission(Manifest.permission.LOCAL_MAC_ADDRESS, PERMISSION_DENIED); 12096 12097 final TransportInfo transportInfo = mock(TransportInfo.class); 12098 doReturn(REDACT_FOR_ACCESS_FINE_LOCATION | REDACT_FOR_LOCAL_MAC_ADDRESS) 12099 .when(transportInfo).getApplicableRedactions(); 12100 final NetworkCapabilities netCap = 12101 new NetworkCapabilities().setTransportInfo(transportInfo); 12102 12103 mService.createWithLocationInfoSanitizedIfNecessaryWhenParceled( 12104 netCap, false /* includeLocationSensitiveInfoInTransportInfo */, 12105 Process.myPid(), Process.myUid(), 12106 mContext.getPackageName(), getAttributionTag()); 12107 // redact both MAC_ADDRESS & location sensitive fields. 12108 verify(transportInfo).makeCopy(REDACT_FOR_ACCESS_FINE_LOCATION 12109 | REDACT_FOR_LOCAL_MAC_ADDRESS); 12110 } 12111 12112 @Test 12113 public void testCreateForCallerWithLocalMacAddressSanitizedWithSettingsPermission() 12114 throws Exception { 12115 mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_GRANTED); 12116 12117 final TransportInfo transportInfo = mock(TransportInfo.class); 12118 doReturn(REDACT_FOR_ACCESS_FINE_LOCATION | REDACT_FOR_NETWORK_SETTINGS) 12119 .when(transportInfo).getApplicableRedactions(); 12120 final NetworkCapabilities netCap = 12121 new NetworkCapabilities().setTransportInfo(transportInfo); 12122 12123 mService.createWithLocationInfoSanitizedIfNecessaryWhenParceled( 12124 netCap, false /* includeLocationSensitiveInfoInTransportInfo */, 12125 Process.myPid(), Process.myUid(), 12126 mContext.getPackageName(), getAttributionTag()); 12127 // don't redact NETWORK_SETTINGS fields, only location sensitive fields. 12128 verify(transportInfo).makeCopy(REDACT_FOR_ACCESS_FINE_LOCATION); 12129 } 12130 12131 @Test 12132 public void testCreateForCallerWithLocalMacAddressSanitizedWithoutSettingsPermission() 12133 throws Exception { 12134 mServiceContext.setPermission(Manifest.permission.LOCAL_MAC_ADDRESS, PERMISSION_DENIED); 12135 12136 final TransportInfo transportInfo = mock(TransportInfo.class); 12137 doReturn(REDACT_FOR_ACCESS_FINE_LOCATION | REDACT_FOR_NETWORK_SETTINGS) 12138 .when(transportInfo).getApplicableRedactions(); 12139 final NetworkCapabilities netCap = 12140 new NetworkCapabilities().setTransportInfo(transportInfo); 12141 12142 mService.createWithLocationInfoSanitizedIfNecessaryWhenParceled( 12143 netCap, false /* includeLocationSensitiveInfoInTransportInfo */, 12144 Process.myPid(), Process.myUid(), 12145 mContext.getPackageName(), getAttributionTag()); 12146 // redact both NETWORK_SETTINGS & location sensitive fields. 12147 verify(transportInfo).makeCopy( 12148 REDACT_FOR_ACCESS_FINE_LOCATION | REDACT_FOR_NETWORK_SETTINGS); 12149 } 12150 12151 /** 12152 * Test TransportInfo to verify redaction mechanism. 12153 */ 12154 private static class TestTransportInfo implements TransportInfo { 12155 public final boolean locationRedacted; 12156 public final boolean localMacAddressRedacted; 12157 public final boolean settingsRedacted; 12158 12159 TestTransportInfo() { 12160 locationRedacted = false; 12161 localMacAddressRedacted = false; 12162 settingsRedacted = false; 12163 } 12164 12165 TestTransportInfo(boolean locationRedacted, boolean localMacAddressRedacted, 12166 boolean settingsRedacted) { 12167 this.locationRedacted = locationRedacted; 12168 this.localMacAddressRedacted = 12169 localMacAddressRedacted; 12170 this.settingsRedacted = settingsRedacted; 12171 } 12172 12173 @Override 12174 public TransportInfo makeCopy(@NetworkCapabilities.RedactionType long redactions) { 12175 return new TestTransportInfo( 12176 locationRedacted | (redactions & REDACT_FOR_ACCESS_FINE_LOCATION) != 0, 12177 localMacAddressRedacted | (redactions & REDACT_FOR_LOCAL_MAC_ADDRESS) != 0, 12178 settingsRedacted | (redactions & REDACT_FOR_NETWORK_SETTINGS) != 0 12179 ); 12180 } 12181 12182 @Override 12183 public @NetworkCapabilities.RedactionType long getApplicableRedactions() { 12184 return REDACT_FOR_ACCESS_FINE_LOCATION | REDACT_FOR_LOCAL_MAC_ADDRESS 12185 | REDACT_FOR_NETWORK_SETTINGS; 12186 } 12187 12188 @Override 12189 public boolean equals(Object other) { 12190 if (!(other instanceof TestTransportInfo)) return false; 12191 TestTransportInfo that = (TestTransportInfo) other; 12192 return that.locationRedacted == this.locationRedacted 12193 && that.localMacAddressRedacted == this.localMacAddressRedacted 12194 && that.settingsRedacted == this.settingsRedacted; 12195 } 12196 12197 @Override 12198 public int hashCode() { 12199 return Objects.hash(locationRedacted, localMacAddressRedacted, settingsRedacted); 12200 } 12201 12202 @Override 12203 public String toString() { 12204 return String.format( 12205 "TestTransportInfo{locationRedacted=%s macRedacted=%s settingsRedacted=%s}", 12206 locationRedacted, localMacAddressRedacted, settingsRedacted); 12207 } 12208 } 12209 12210 private TestTransportInfo getTestTransportInfo(NetworkCapabilities nc) { 12211 return (TestTransportInfo) nc.getTransportInfo(); 12212 } 12213 12214 private TestTransportInfo getTestTransportInfo(TestNetworkAgentWrapper n) { 12215 final NetworkCapabilities nc = mCm.getNetworkCapabilities(n.getNetwork()); 12216 assertNotNull(nc); 12217 return getTestTransportInfo(nc); 12218 } 12219 12220 12221 private void verifyNetworkCallbackLocationDataInclusionUsingTransportInfoAndOwnerUidInNetCaps( 12222 @NonNull TestNetworkCallback wifiNetworkCallback, int actualOwnerUid, 12223 @NonNull TransportInfo actualTransportInfo, int expectedOwnerUid, 12224 @NonNull TransportInfo expectedTransportInfo) throws Exception { 12225 doReturn(Build.VERSION_CODES.S).when(mPackageManager).getTargetSdkVersion(anyString()); 12226 final NetworkCapabilities ncTemplate = 12227 new NetworkCapabilities() 12228 .addTransportType(TRANSPORT_WIFI) 12229 .setOwnerUid(actualOwnerUid); 12230 12231 final NetworkRequest wifiRequest = new NetworkRequest.Builder() 12232 .addTransportType(TRANSPORT_WIFI).build(); 12233 mCm.registerNetworkCallback(wifiRequest, wifiNetworkCallback); 12234 12235 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, new LinkProperties(), 12236 ncTemplate); 12237 mWiFiAgent.connect(false); 12238 12239 wifiNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 12240 12241 // Send network capabilities update with TransportInfo to trigger capabilities changed 12242 // callback. 12243 mWiFiAgent.setNetworkCapabilities(ncTemplate.setTransportInfo(actualTransportInfo), true); 12244 12245 wifiNetworkCallback.expectCaps(mWiFiAgent, 12246 c -> Objects.equals(expectedOwnerUid, c.getOwnerUid()) 12247 && Objects.equals(expectedTransportInfo, c.getTransportInfo())); 12248 } 12249 12250 @Test 12251 public void testVerifyLocationDataIsNotIncludedWhenInclFlagNotSet() throws Exception { 12252 final TestNetworkCallback wifiNetworkCallack = new TestNetworkCallback(); 12253 final int ownerUid = Process.myUid(); 12254 final TransportInfo transportInfo = new TestTransportInfo(); 12255 // Even though the test uid holds privileged permissions, mask location fields since 12256 // the callback did not explicitly opt-in to get location data. 12257 final TransportInfo sanitizedTransportInfo = new TestTransportInfo( 12258 true, /* locationRedacted */ 12259 true, /* localMacAddressRedacted */ 12260 true /* settingsRedacted */ 12261 ); 12262 // Should not expect location data since the callback does not set the flag for including 12263 // location data. 12264 verifyNetworkCallbackLocationDataInclusionUsingTransportInfoAndOwnerUidInNetCaps( 12265 wifiNetworkCallack, ownerUid, transportInfo, INVALID_UID, sanitizedTransportInfo); 12266 } 12267 12268 @Test 12269 public void testTransportInfoRedactionInSynchronousCalls() throws Exception { 12270 final NetworkCapabilities ncTemplate = new NetworkCapabilities() 12271 .addTransportType(TRANSPORT_WIFI) 12272 .setTransportInfo(new TestTransportInfo()); 12273 12274 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, new LinkProperties(), ncTemplate); 12275 mWiFiAgent.connect(true /* validated; waits for callback */); 12276 12277 // NETWORK_SETTINGS redaction is controlled by the NETWORK_SETTINGS permission 12278 assertTrue(getTestTransportInfo(mWiFiAgent).settingsRedacted); 12279 withPermission(NETWORK_SETTINGS, () -> { 12280 assertFalse(getTestTransportInfo(mWiFiAgent).settingsRedacted); 12281 }); 12282 assertTrue(getTestTransportInfo(mWiFiAgent).settingsRedacted); 12283 12284 // LOCAL_MAC_ADDRESS redaction is controlled by the LOCAL_MAC_ADDRESS permission 12285 assertTrue(getTestTransportInfo(mWiFiAgent).localMacAddressRedacted); 12286 withPermission(LOCAL_MAC_ADDRESS, () -> { 12287 assertFalse(getTestTransportInfo(mWiFiAgent).localMacAddressRedacted); 12288 }); 12289 assertTrue(getTestTransportInfo(mWiFiAgent).localMacAddressRedacted); 12290 12291 // Synchronous getNetworkCapabilities calls never return unredacted location-sensitive 12292 // information. 12293 assertTrue(getTestTransportInfo(mWiFiAgent).locationRedacted); 12294 setupLocationPermissions(Build.VERSION_CODES.S, true, AppOpsManager.OPSTR_FINE_LOCATION, 12295 Manifest.permission.ACCESS_FINE_LOCATION); 12296 assertTrue(getTestTransportInfo(mWiFiAgent).locationRedacted); 12297 denyAllLocationPrivilegedPermissions(); 12298 assertTrue(getTestTransportInfo(mWiFiAgent).locationRedacted); 12299 } 12300 12301 private void setupConnectionOwnerUid(int vpnOwnerUid, @VpnManager.VpnType int vpnType) 12302 throws Exception { 12303 final Set<UidRange> vpnRange = Collections.singleton(PRIMARY_UIDRANGE); 12304 mMockVpn.setVpnType(vpnType); 12305 mMockVpn.establish(new LinkProperties(), vpnOwnerUid, vpnRange); 12306 assertVpnUidRangesUpdated(true, vpnRange, vpnOwnerUid); 12307 12308 final UnderlyingNetworkInfo underlyingNetworkInfo = 12309 new UnderlyingNetworkInfo(vpnOwnerUid, VPN_IFNAME, new ArrayList<>()); 12310 mMockVpn.setUnderlyingNetworkInfo(underlyingNetworkInfo); 12311 mDeps.setConnectionOwnerUid(42); 12312 } 12313 12314 private void setupConnectionOwnerUidAsVpnApp(int vpnOwnerUid, @VpnManager.VpnType int vpnType) 12315 throws Exception { 12316 setupConnectionOwnerUid(vpnOwnerUid, vpnType); 12317 12318 // Test as VPN app 12319 mServiceContext.setPermission(NETWORK_STACK, PERMISSION_DENIED); 12320 mServiceContext.setPermission( 12321 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, PERMISSION_DENIED); 12322 } 12323 12324 private ConnectionInfo getTestConnectionInfo() throws Exception { 12325 return new ConnectionInfo( 12326 IPPROTO_TCP, 12327 new InetSocketAddress(InetAddresses.parseNumericAddress("1.2.3.4"), 1234), 12328 new InetSocketAddress(InetAddresses.parseNumericAddress("2.3.4.5"), 2345)); 12329 } 12330 12331 @Test 12332 public void testGetConnectionOwnerUidPlatformVpn() throws Exception { 12333 final int myUid = Process.myUid(); 12334 setupConnectionOwnerUidAsVpnApp(myUid, VpnManager.TYPE_VPN_PLATFORM); 12335 12336 assertEquals(INVALID_UID, mService.getConnectionOwnerUid(getTestConnectionInfo())); 12337 } 12338 12339 @Test 12340 public void testGetConnectionOwnerUidVpnServiceWrongUser() throws Exception { 12341 final int myUid = Process.myUid(); 12342 setupConnectionOwnerUidAsVpnApp(myUid + 1, VpnManager.TYPE_VPN_SERVICE); 12343 12344 assertEquals(INVALID_UID, mService.getConnectionOwnerUid(getTestConnectionInfo())); 12345 } 12346 12347 @Test 12348 public void testGetConnectionOwnerUidVpnServiceDoesNotThrow() throws Exception { 12349 final int myUid = Process.myUid(); 12350 setupConnectionOwnerUidAsVpnApp(myUid, VpnManager.TYPE_VPN_SERVICE); 12351 12352 assertEquals(42, mService.getConnectionOwnerUid(getTestConnectionInfo())); 12353 } 12354 12355 @Test 12356 public void testGetConnectionOwnerUidVpnServiceNetworkStackDoesNotThrow() throws Exception { 12357 final int myUid = Process.myUid(); 12358 setupConnectionOwnerUid(myUid, VpnManager.TYPE_VPN_SERVICE); 12359 mServiceContext.setPermission(NETWORK_STACK, PERMISSION_GRANTED); 12360 12361 assertEquals(42, mService.getConnectionOwnerUid(getTestConnectionInfo())); 12362 } 12363 12364 @Test 12365 public void testGetConnectionOwnerUidVpnServiceMainlineNetworkStackDoesNotThrow() 12366 throws Exception { 12367 final int myUid = Process.myUid(); 12368 setupConnectionOwnerUid(myUid, VpnManager.TYPE_VPN_SERVICE); 12369 mServiceContext.setPermission( 12370 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, PERMISSION_GRANTED); 12371 12372 assertEquals(42, mService.getConnectionOwnerUid(getTestConnectionInfo())); 12373 } 12374 12375 private static PackageInfo buildPackageInfo(boolean hasSystemPermission, int uid) { 12376 final PackageInfo packageInfo = new PackageInfo(); 12377 if (hasSystemPermission) { 12378 packageInfo.requestedPermissions = new String[] { 12379 CHANGE_NETWORK_STATE, CONNECTIVITY_USE_RESTRICTED_NETWORKS }; 12380 packageInfo.requestedPermissionsFlags = new int[] { 12381 REQUESTED_PERMISSION_GRANTED, REQUESTED_PERMISSION_GRANTED }; 12382 } else { 12383 packageInfo.requestedPermissions = new String[0]; 12384 } 12385 packageInfo.applicationInfo = new ApplicationInfo(); 12386 packageInfo.applicationInfo.privateFlags = 0; 12387 packageInfo.applicationInfo.uid = UserHandle.getUid(UserHandle.USER_SYSTEM, 12388 UserHandle.getAppId(uid)); 12389 return packageInfo; 12390 } 12391 12392 @Test 12393 public void testRegisterConnectivityDiagnosticsCallbackInvalidRequest() throws Exception { 12394 final NetworkRequest request = 12395 new NetworkRequest( 12396 new NetworkCapabilities(), TYPE_ETHERNET, 0, NetworkRequest.Type.NONE); 12397 try { 12398 mService.registerConnectivityDiagnosticsCallback( 12399 mConnectivityDiagnosticsCallback, request, mContext.getPackageName()); 12400 fail("registerConnectivityDiagnosticsCallback should throw on invalid NetworkRequest"); 12401 } catch (IllegalArgumentException expected) { 12402 } 12403 } 12404 12405 private void assertRouteInfoParcelMatches(RouteInfo route, RouteInfoParcel parcel) { 12406 assertEquals(route.getDestination().toString(), parcel.destination); 12407 assertEquals(route.getInterface(), parcel.ifName); 12408 assertEquals(route.getMtu(), parcel.mtu); 12409 12410 switch (route.getType()) { 12411 case RouteInfo.RTN_UNICAST: 12412 if (route.hasGateway()) { 12413 assertEquals(route.getGateway().getHostAddress(), parcel.nextHop); 12414 } else { 12415 assertEquals(INetd.NEXTHOP_NONE, parcel.nextHop); 12416 } 12417 break; 12418 case RouteInfo.RTN_UNREACHABLE: 12419 assertEquals(INetd.NEXTHOP_UNREACHABLE, parcel.nextHop); 12420 break; 12421 case RouteInfo.RTN_THROW: 12422 assertEquals(INetd.NEXTHOP_THROW, parcel.nextHop); 12423 break; 12424 default: 12425 assertEquals(INetd.NEXTHOP_NONE, parcel.nextHop); 12426 break; 12427 } 12428 } 12429 12430 private void assertRoutesAdded(int netId, RouteInfo... routes) throws Exception { 12431 // TODO: add @JavaDerive(equals=true) to RouteInfoParcel, use eq() directly, and delete 12432 // assertRouteInfoParcelMatches above. 12433 ArgumentCaptor<RouteInfoParcel> captor = ArgumentCaptor.forClass(RouteInfoParcel.class); 12434 verify(mMockNetd, times(routes.length)).networkAddRouteParcel(eq(netId), captor.capture()); 12435 for (int i = 0; i < routes.length; i++) { 12436 assertRouteInfoParcelMatches(routes[i], captor.getAllValues().get(i)); 12437 } 12438 } 12439 12440 private void assertRoutesRemoved(int netId, RouteInfo... routes) throws Exception { 12441 ArgumentCaptor<RouteInfoParcel> captor = ArgumentCaptor.forClass(RouteInfoParcel.class); 12442 verify(mMockNetd, times(routes.length)).networkRemoveRouteParcel(eq(netId), 12443 captor.capture()); 12444 for (int i = 0; i < routes.length; i++) { 12445 assertRouteInfoParcelMatches(routes[i], captor.getAllValues().get(i)); 12446 } 12447 } 12448 12449 @Test 12450 public void testRegisterUnregisterConnectivityDiagnosticsCallback() throws Exception { 12451 final NetworkRequest wifiRequest = 12452 new NetworkRequest.Builder().addTransportType(TRANSPORT_WIFI).build(); 12453 doReturn(mIBinder).when(mConnectivityDiagnosticsCallback).asBinder(); 12454 12455 mService.registerConnectivityDiagnosticsCallback( 12456 mConnectivityDiagnosticsCallback, wifiRequest, mContext.getPackageName()); 12457 12458 // Block until all other events are done processing. 12459 HandlerUtils.waitForIdle(mCsHandlerThread, TIMEOUT_MS); 12460 12461 verify(mIBinder).linkToDeath(any(ConnectivityDiagnosticsCallbackInfo.class), anyInt()); 12462 verify(mConnectivityDiagnosticsCallback).asBinder(); 12463 assertTrue(mService.mConnectivityDiagnosticsCallbacks.containsKey(mIBinder)); 12464 12465 mService.unregisterConnectivityDiagnosticsCallback(mConnectivityDiagnosticsCallback); 12466 verify(mIBinder, timeout(TIMEOUT_MS)) 12467 .unlinkToDeath(any(ConnectivityDiagnosticsCallbackInfo.class), anyInt()); 12468 assertFalse(mService.mConnectivityDiagnosticsCallbacks.containsKey(mIBinder)); 12469 verify(mConnectivityDiagnosticsCallback, atLeastOnce()).asBinder(); 12470 } 12471 12472 @Test 12473 public void testRegisterDuplicateConnectivityDiagnosticsCallback() throws Exception { 12474 final NetworkRequest wifiRequest = 12475 new NetworkRequest.Builder().addTransportType(TRANSPORT_WIFI).build(); 12476 doReturn(mIBinder).when(mConnectivityDiagnosticsCallback).asBinder(); 12477 12478 mService.registerConnectivityDiagnosticsCallback( 12479 mConnectivityDiagnosticsCallback, wifiRequest, mContext.getPackageName()); 12480 12481 // Block until all other events are done processing. 12482 HandlerUtils.waitForIdle(mCsHandlerThread, TIMEOUT_MS); 12483 12484 verify(mIBinder).linkToDeath(any(ConnectivityDiagnosticsCallbackInfo.class), anyInt()); 12485 verify(mConnectivityDiagnosticsCallback).asBinder(); 12486 assertTrue(mService.mConnectivityDiagnosticsCallbacks.containsKey(mIBinder)); 12487 12488 // Register the same callback again 12489 mService.registerConnectivityDiagnosticsCallback( 12490 mConnectivityDiagnosticsCallback, wifiRequest, mContext.getPackageName()); 12491 12492 // Block until all other events are done processing. 12493 HandlerUtils.waitForIdle(mCsHandlerThread, TIMEOUT_MS); 12494 12495 assertTrue(mService.mConnectivityDiagnosticsCallbacks.containsKey(mIBinder)); 12496 } 12497 12498 @Test(expected = NullPointerException.class) 12499 public void testRegisterConnectivityDiagnosticsCallbackNullCallback() { 12500 mService.registerConnectivityDiagnosticsCallback( 12501 null /* callback */, 12502 new NetworkRequest.Builder().build(), 12503 mContext.getPackageName()); 12504 } 12505 12506 @Test(expected = NullPointerException.class) 12507 public void testRegisterConnectivityDiagnosticsCallbackNullNetworkRequest() { 12508 mService.registerConnectivityDiagnosticsCallback( 12509 mConnectivityDiagnosticsCallback, 12510 null /* request */, 12511 mContext.getPackageName()); 12512 } 12513 12514 @Test(expected = NullPointerException.class) 12515 public void testRegisterConnectivityDiagnosticsCallbackNullPackageName() { 12516 mService.registerConnectivityDiagnosticsCallback( 12517 mConnectivityDiagnosticsCallback, 12518 new NetworkRequest.Builder().build(), 12519 null /* callingPackageName */); 12520 } 12521 12522 @Test(expected = NullPointerException.class) 12523 public void testUnregisterConnectivityDiagnosticsCallbackNullPackageName() { 12524 mService.unregisterConnectivityDiagnosticsCallback(null /* callback */); 12525 } 12526 12527 public NetworkAgentInfo fakeMobileNai(NetworkCapabilities nc) { 12528 final NetworkCapabilities cellNc = new NetworkCapabilities.Builder(nc) 12529 .addTransportType(TRANSPORT_CELLULAR).build(); 12530 final NetworkInfo info = new NetworkInfo(TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_LTE, 12531 ConnectivityManager.getNetworkTypeName(TYPE_MOBILE), 12532 TelephonyManager.getNetworkTypeName(TelephonyManager.NETWORK_TYPE_LTE)); 12533 return fakeNai(cellNc, info); 12534 } 12535 12536 private NetworkAgentInfo fakeWifiNai(NetworkCapabilities nc) { 12537 final NetworkCapabilities wifiNc = new NetworkCapabilities.Builder(nc) 12538 .addTransportType(TRANSPORT_WIFI).build(); 12539 final NetworkInfo info = new NetworkInfo(TYPE_WIFI, 0 /* subtype */, 12540 ConnectivityManager.getNetworkTypeName(TYPE_WIFI), "" /* subtypeName */); 12541 return fakeNai(wifiNc, info); 12542 } 12543 12544 private NetworkAgentInfo fakeVpnNai(NetworkCapabilities nc) { 12545 final NetworkCapabilities vpnNc = new NetworkCapabilities.Builder(nc) 12546 .addTransportType(TRANSPORT_VPN).build(); 12547 final NetworkInfo info = new NetworkInfo(TYPE_VPN, 0 /* subtype */, 12548 ConnectivityManager.getNetworkTypeName(TYPE_VPN), "" /* subtypeName */); 12549 return fakeNai(vpnNc, info); 12550 } 12551 12552 private NetworkAgentInfo fakeNai(NetworkCapabilities nc, NetworkInfo networkInfo) { 12553 return new NetworkAgentInfo(null, new Network(NET_ID), networkInfo, new LinkProperties(), 12554 nc, new NetworkScore.Builder().setLegacyInt(0).build(), 12555 mServiceContext, null, new NetworkAgentConfig(), mService, null, null, 0, 12556 INVALID_UID, TEST_LINGER_DELAY_MS, mQosCallbackTracker, 12557 new ConnectivityService.Dependencies()); 12558 } 12559 12560 @Test 12561 public void testCheckConnectivityDiagnosticsPermissionsNetworkStack() throws Exception { 12562 final NetworkAgentInfo naiWithoutUid = fakeMobileNai(new NetworkCapabilities()); 12563 12564 mServiceContext.setPermission(NETWORK_STACK, PERMISSION_GRANTED); 12565 assertTrue( 12566 "NetworkStack permission not applied", 12567 mService.checkConnectivityDiagnosticsPermissions( 12568 Process.myPid(), Process.myUid(), naiWithoutUid, 12569 mContext.getOpPackageName())); 12570 } 12571 12572 @Test 12573 public void testCheckConnectivityDiagnosticsPermissionsWrongUidPackageName() throws Exception { 12574 final int wrongUid = Process.myUid() + 1; 12575 12576 final NetworkCapabilities nc = new NetworkCapabilities(); 12577 nc.setAdministratorUids(new int[] {wrongUid}); 12578 final NetworkAgentInfo naiWithUid = fakeWifiNai(nc); 12579 12580 mServiceContext.setPermission(NETWORK_STACK, PERMISSION_DENIED); 12581 12582 assertFalse( 12583 "Mismatched uid/package name should not pass the location permission check", 12584 mService.checkConnectivityDiagnosticsPermissions( 12585 Process.myPid() + 1, wrongUid, naiWithUid, mContext.getOpPackageName())); 12586 } 12587 12588 private void verifyConnectivityDiagnosticsPermissionsWithNetworkAgentInfo( 12589 NetworkAgentInfo info, boolean expectPermission) { 12590 mServiceContext.setPermission(NETWORK_STACK, PERMISSION_DENIED); 12591 12592 assertEquals( 12593 "Unexpected ConnDiags permission", 12594 expectPermission, 12595 mService.checkConnectivityDiagnosticsPermissions( 12596 Process.myPid(), Process.myUid(), info, mContext.getOpPackageName())); 12597 } 12598 12599 @Test 12600 public void testCheckConnectivityDiagnosticsPermissionsCellularNoLocationPermission() 12601 throws Exception { 12602 final NetworkCapabilities nc = new NetworkCapabilities(); 12603 nc.setAdministratorUids(new int[] {Process.myUid()}); 12604 final NetworkAgentInfo naiWithUid = fakeMobileNai(nc); 12605 12606 verifyConnectivityDiagnosticsPermissionsWithNetworkAgentInfo(naiWithUid, 12607 true /* expectPermission */); 12608 } 12609 12610 @Test 12611 public void testCheckConnectivityDiagnosticsPermissionsWifiNoLocationPermission() 12612 throws Exception { 12613 final NetworkCapabilities nc = new NetworkCapabilities(); 12614 nc.setAdministratorUids(new int[] {Process.myUid()}); 12615 final NetworkAgentInfo naiWithUid = fakeWifiNai(nc); 12616 12617 verifyConnectivityDiagnosticsPermissionsWithNetworkAgentInfo(naiWithUid, 12618 false /* expectPermission */); 12619 } 12620 12621 @Test 12622 public void testCheckConnectivityDiagnosticsPermissionsActiveVpn() throws Exception { 12623 final NetworkAgentInfo naiWithoutUid = fakeMobileNai(new NetworkCapabilities()); 12624 12625 mMockVpn.establishForMyUid(); 12626 assertUidRangesUpdatedForMyUid(true); 12627 12628 // Wait for networks to connect and broadcasts to be sent before removing permissions. 12629 waitForIdle(); 12630 setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION, 12631 Manifest.permission.ACCESS_FINE_LOCATION); 12632 12633 assertTrue(mMockVpn.setUnderlyingNetworks(new Network[] {naiWithoutUid.network})); 12634 waitForIdle(); 12635 assertTrue( 12636 "Active VPN permission not applied", 12637 mService.checkConnectivityDiagnosticsPermissions( 12638 Process.myPid(), Process.myUid(), naiWithoutUid, 12639 mContext.getOpPackageName())); 12640 12641 assertTrue(mMockVpn.setUnderlyingNetworks(null)); 12642 waitForIdle(); 12643 assertFalse( 12644 "VPN shouldn't receive callback on non-underlying network", 12645 mService.checkConnectivityDiagnosticsPermissions( 12646 Process.myPid(), Process.myUid(), naiWithoutUid, 12647 mContext.getOpPackageName())); 12648 } 12649 12650 @Test 12651 public void testCheckConnectivityDiagnosticsPermissionsNetworkAdministrator() throws Exception { 12652 final NetworkCapabilities nc = new NetworkCapabilities(); 12653 nc.setAdministratorUids(new int[] {Process.myUid()}); 12654 final NetworkAgentInfo naiWithUid = fakeMobileNai(nc); 12655 12656 setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION, 12657 Manifest.permission.ACCESS_FINE_LOCATION); 12658 mServiceContext.setPermission(NETWORK_STACK, PERMISSION_DENIED); 12659 12660 assertTrue( 12661 "NetworkCapabilities administrator uid permission not applied", 12662 mService.checkConnectivityDiagnosticsPermissions( 12663 Process.myPid(), Process.myUid(), naiWithUid, mContext.getOpPackageName())); 12664 } 12665 12666 @Test 12667 public void testCheckConnectivityDiagnosticsPermissionsFails() throws Exception { 12668 final NetworkCapabilities nc = new NetworkCapabilities(); 12669 nc.setOwnerUid(Process.myUid()); 12670 nc.setAdministratorUids(new int[] {Process.myUid()}); 12671 final NetworkAgentInfo naiWithUid = fakeMobileNai(nc); 12672 12673 setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION, 12674 Manifest.permission.ACCESS_FINE_LOCATION); 12675 mServiceContext.setPermission(NETWORK_STACK, PERMISSION_DENIED); 12676 12677 // Use wrong pid and uid 12678 assertFalse( 12679 "Permissions allowed when they shouldn't be granted", 12680 mService.checkConnectivityDiagnosticsPermissions( 12681 Process.myPid() + 1, Process.myUid() + 1, naiWithUid, 12682 mContext.getOpPackageName())); 12683 } 12684 12685 @Test 12686 public void testUnderlyingNetworksWillBeSetInNetworkAgentInfoConstructor() throws Exception { 12687 assumeTrue(mDeps.isAtLeastT()); 12688 final Network network1 = new Network(100); 12689 final Network network2 = new Network(101); 12690 final List<Network> underlyingNetworks = new ArrayList<>(); 12691 final NetworkCapabilities ncWithEmptyUnderlyingNetworks = new NetworkCapabilities.Builder() 12692 .setUnderlyingNetworks(underlyingNetworks) 12693 .build(); 12694 final NetworkAgentInfo vpnNaiWithEmptyUnderlyingNetworks = 12695 fakeVpnNai(ncWithEmptyUnderlyingNetworks); 12696 assertEquals(underlyingNetworks, 12697 Arrays.asList(vpnNaiWithEmptyUnderlyingNetworks.declaredUnderlyingNetworks)); 12698 12699 underlyingNetworks.add(network1); 12700 underlyingNetworks.add(network2); 12701 final NetworkCapabilities ncWithUnderlyingNetworks = new NetworkCapabilities.Builder() 12702 .setUnderlyingNetworks(underlyingNetworks) 12703 .build(); 12704 final NetworkAgentInfo vpnNaiWithUnderlyingNetwokrs = fakeVpnNai(ncWithUnderlyingNetworks); 12705 assertEquals(underlyingNetworks, 12706 Arrays.asList(vpnNaiWithUnderlyingNetwokrs.declaredUnderlyingNetworks)); 12707 12708 final NetworkCapabilities ncWithoutUnderlyingNetworks = new NetworkCapabilities.Builder() 12709 .build(); 12710 final NetworkAgentInfo vpnNaiWithoutUnderlyingNetwokrs = 12711 fakeVpnNai(ncWithoutUnderlyingNetworks); 12712 assertNull(vpnNaiWithoutUnderlyingNetwokrs.declaredUnderlyingNetworks); 12713 } 12714 12715 @Test 12716 public void testRegisterConnectivityDiagnosticsCallbackCallsOnConnectivityReport() 12717 throws Exception { 12718 // Set up the Network, which leads to a ConnectivityReport being cached for the network. 12719 final TestNetworkCallback callback = new TestNetworkCallback(); 12720 mCm.registerDefaultNetworkCallback(callback); 12721 final LinkProperties linkProperties = new LinkProperties(); 12722 linkProperties.setInterfaceName(INTERFACE_NAME); 12723 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, linkProperties); 12724 mCellAgent.connect(true); 12725 callback.expectAvailableThenValidatedCallbacks(mCellAgent); 12726 callback.assertNoCallback(); 12727 12728 final NetworkRequest request = new NetworkRequest.Builder().build(); 12729 doReturn(mIBinder).when(mConnectivityDiagnosticsCallback).asBinder(); 12730 12731 mServiceContext.setPermission(NETWORK_STACK, PERMISSION_GRANTED); 12732 12733 mService.registerConnectivityDiagnosticsCallback( 12734 mConnectivityDiagnosticsCallback, request, mContext.getPackageName()); 12735 12736 verify(mConnectivityDiagnosticsCallback, timeout(TIMEOUT_MS)) 12737 .onConnectivityReportAvailable(argThat(report -> { 12738 return INTERFACE_NAME.equals(report.getLinkProperties().getInterfaceName()) 12739 && report.getNetworkCapabilities().hasTransport(TRANSPORT_CELLULAR); 12740 })); 12741 } 12742 12743 private void setUpConnectivityDiagnosticsCallback() throws Exception { 12744 final NetworkRequest request = new NetworkRequest.Builder().build(); 12745 doReturn(mIBinder).when(mConnectivityDiagnosticsCallback).asBinder(); 12746 12747 mServiceContext.setPermission(NETWORK_STACK, PERMISSION_GRANTED); 12748 12749 mService.registerConnectivityDiagnosticsCallback( 12750 mConnectivityDiagnosticsCallback, request, mContext.getPackageName()); 12751 12752 // Block until all other events are done processing. 12753 HandlerUtils.waitForIdle(mCsHandlerThread, TIMEOUT_MS); 12754 12755 // Connect the cell agent verify that it notifies TestNetworkCallback that it is available 12756 final TestNetworkCallback callback = new TestNetworkCallback(); 12757 mCm.registerDefaultNetworkCallback(callback); 12758 12759 final NetworkCapabilities ncTemplate = new NetworkCapabilities() 12760 .addTransportType(TRANSPORT_CELLULAR) 12761 .setTransportInfo(new TestTransportInfo()); 12762 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, new LinkProperties(), 12763 ncTemplate); 12764 mCellAgent.connect(true); 12765 callback.expectAvailableThenValidatedCallbacks(mCellAgent); 12766 callback.assertNoCallback(); 12767 12768 // Make sure a report is sent and that the caps are suitably redacted. 12769 verify(mConnectivityDiagnosticsCallback, timeout(TIMEOUT_MS)) 12770 .onConnectivityReportAvailable(argThat(report -> 12771 areConnDiagCapsRedacted(report.getNetworkCapabilities()))); 12772 reset(mConnectivityDiagnosticsCallback); 12773 } 12774 12775 private boolean areConnDiagCapsRedacted(NetworkCapabilities nc) { 12776 TestTransportInfo ti = getTestTransportInfo(nc); 12777 return nc.getUids() == null 12778 && nc.getAdministratorUids().length == 0 12779 && nc.getOwnerUid() == Process.INVALID_UID 12780 && ti.locationRedacted 12781 && ti.localMacAddressRedacted 12782 && ti.settingsRedacted; 12783 } 12784 12785 @Test 12786 public void testConnectivityDiagnosticsCallbackOnDataStallSuspected() throws Exception { 12787 setUpConnectivityDiagnosticsCallback(); 12788 12789 // Trigger notifyDataStallSuspected() on the INetworkMonitorCallbacks instance in the 12790 // cellular network agent 12791 mCellAgent.notifyDataStallSuspected(); 12792 12793 // Verify onDataStallSuspected fired 12794 verify(mConnectivityDiagnosticsCallback, timeout(TIMEOUT_MS)).onDataStallSuspected( 12795 argThat(report -> areConnDiagCapsRedacted(report.getNetworkCapabilities()))); 12796 } 12797 12798 @Test 12799 public void testConnectivityDiagnosticsCallbackOnConnectivityReported() throws Exception { 12800 setUpConnectivityDiagnosticsCallback(); 12801 12802 final Network n = mCellAgent.getNetwork(); 12803 final boolean hasConnectivity = true; 12804 mService.reportNetworkConnectivity(n, hasConnectivity); 12805 12806 // Verify onNetworkConnectivityReported fired 12807 verify(mConnectivityDiagnosticsCallback, timeout(TIMEOUT_MS)) 12808 .onNetworkConnectivityReported(eq(n), eq(hasConnectivity)); 12809 verify(mConnectivityDiagnosticsCallback, timeout(TIMEOUT_MS)) 12810 .onConnectivityReportAvailable( 12811 argThat(report -> 12812 areConnDiagCapsRedacted(report.getNetworkCapabilities()))); 12813 12814 final boolean noConnectivity = false; 12815 mService.reportNetworkConnectivity(n, noConnectivity); 12816 12817 // Wait for onNetworkConnectivityReported to fire 12818 verify(mConnectivityDiagnosticsCallback, timeout(TIMEOUT_MS)) 12819 .onNetworkConnectivityReported(eq(n), eq(noConnectivity)); 12820 12821 // Also expect a ConnectivityReport after NetworkMonitor asynchronously re-validates 12822 verify(mConnectivityDiagnosticsCallback, timeout(TIMEOUT_MS).times(2)) 12823 .onConnectivityReportAvailable( 12824 argThat(report -> 12825 areConnDiagCapsRedacted(report.getNetworkCapabilities()))); 12826 } 12827 12828 @Test 12829 public void testConnectivityDiagnosticsCallbackOnConnectivityReportedSeparateUid() 12830 throws Exception { 12831 setUpConnectivityDiagnosticsCallback(); 12832 12833 // report known Connectivity from a different uid. Verify that network is not re-validated 12834 // and this callback is not notified. 12835 final Network n = mCellAgent.getNetwork(); 12836 final boolean hasConnectivity = true; 12837 doAsUid(Process.myUid() + 1, () -> mService.reportNetworkConnectivity(n, hasConnectivity)); 12838 12839 // Block until all other events are done processing. 12840 HandlerUtils.waitForIdle(mCsHandlerThread, TIMEOUT_MS); 12841 12842 // Verify onNetworkConnectivityReported did not fire 12843 verify(mConnectivityDiagnosticsCallback, never()) 12844 .onNetworkConnectivityReported(any(), anyBoolean()); 12845 verify(mConnectivityDiagnosticsCallback, never()) 12846 .onConnectivityReportAvailable(any()); 12847 12848 // report different Connectivity from a different uid. Verify that network is re-validated 12849 // and that this callback is notified. 12850 final boolean noConnectivity = false; 12851 doAsUid(Process.myUid() + 1, () -> mService.reportNetworkConnectivity(n, noConnectivity)); 12852 12853 // Wait for onNetworkConnectivityReported to fire 12854 verify(mConnectivityDiagnosticsCallback, timeout(TIMEOUT_MS)) 12855 .onNetworkConnectivityReported(eq(n), eq(noConnectivity)); 12856 12857 // Also expect a ConnectivityReport after NetworkMonitor asynchronously re-validates 12858 verify(mConnectivityDiagnosticsCallback, timeout(TIMEOUT_MS)) 12859 .onConnectivityReportAvailable( 12860 argThat(report -> 12861 areConnDiagCapsRedacted(report.getNetworkCapabilities()))); 12862 } 12863 12864 @Test(expected = NullPointerException.class) 12865 public void testSimulateDataStallNullNetwork() { 12866 mService.simulateDataStall( 12867 DataStallReport.DETECTION_METHOD_DNS_EVENTS, 12868 0L /* timestampMillis */, 12869 null /* network */, 12870 new PersistableBundle()); 12871 } 12872 12873 @Test(expected = NullPointerException.class) 12874 public void testSimulateDataStallNullPersistableBundle() { 12875 mService.simulateDataStall( 12876 DataStallReport.DETECTION_METHOD_DNS_EVENTS, 12877 0L /* timestampMillis */, 12878 mock(Network.class), 12879 null /* extras */); 12880 } 12881 12882 @Test 12883 public void testRouteAddDeleteUpdate() throws Exception { 12884 final NetworkRequest request = new NetworkRequest.Builder().build(); 12885 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 12886 mCm.registerNetworkCallback(request, networkCallback); 12887 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 12888 reset(mMockNetd); 12889 mCellAgent.connect(false); 12890 networkCallback.expectAvailableCallbacksUnvalidated(mCellAgent); 12891 final int netId = mCellAgent.getNetwork().netId; 12892 12893 final String iface = "rmnet_data0"; 12894 final InetAddress gateway = InetAddress.getByName("fe80::5678"); 12895 RouteInfo direct = RouteInfo.makeHostRoute(gateway, iface); 12896 RouteInfo rio1 = new RouteInfo(new IpPrefix("2001:db8:1::/48"), gateway, iface); 12897 RouteInfo rio2 = new RouteInfo(new IpPrefix("2001:db8:2::/48"), gateway, iface); 12898 RouteInfo defaultRoute = new RouteInfo((IpPrefix) null, gateway, iface); 12899 RouteInfo defaultWithMtu = new RouteInfo(null, gateway, iface, RouteInfo.RTN_UNICAST, 12900 1280 /* mtu */); 12901 12902 // Send LinkProperties and check that we ask netd to add routes. 12903 LinkProperties lp = new LinkProperties(); 12904 lp.setInterfaceName(iface); 12905 lp.addRoute(direct); 12906 lp.addRoute(rio1); 12907 lp.addRoute(defaultRoute); 12908 mCellAgent.sendLinkProperties(lp); 12909 networkCallback.expect(LINK_PROPERTIES_CHANGED, mCellAgent, 12910 x -> x.getLp().getRoutes().size() == 3); 12911 12912 assertRoutesAdded(netId, direct, rio1, defaultRoute); 12913 reset(mMockNetd); 12914 12915 // Send updated LinkProperties and check that we ask netd to add, remove, update routes. 12916 assertTrue(lp.getRoutes().contains(defaultRoute)); 12917 lp.removeRoute(rio1); 12918 lp.addRoute(rio2); 12919 lp.addRoute(defaultWithMtu); 12920 // Ensure adding the same route with a different MTU replaces the previous route. 12921 assertFalse(lp.getRoutes().contains(defaultRoute)); 12922 assertTrue(lp.getRoutes().contains(defaultWithMtu)); 12923 12924 mCellAgent.sendLinkProperties(lp); 12925 networkCallback.expect(LINK_PROPERTIES_CHANGED, mCellAgent, 12926 x -> x.getLp().getRoutes().contains(rio2)); 12927 12928 assertRoutesRemoved(netId, rio1); 12929 assertRoutesAdded(netId, rio2); 12930 12931 ArgumentCaptor<RouteInfoParcel> captor = ArgumentCaptor.forClass(RouteInfoParcel.class); 12932 verify(mMockNetd).networkUpdateRouteParcel(eq(netId), captor.capture()); 12933 assertRouteInfoParcelMatches(defaultWithMtu, captor.getValue()); 12934 12935 12936 mCm.unregisterNetworkCallback(networkCallback); 12937 } 12938 12939 private void verifyDump(String[] args) { 12940 final StringWriter stringWriter = new StringWriter(); 12941 mService.dump(new FileDescriptor(), new PrintWriter(stringWriter), args); 12942 assertFalse(stringWriter.toString().isEmpty()); 12943 } 12944 12945 @Test 12946 public void testDumpDoesNotCrash() { 12947 mServiceContext.setPermission(DUMP, PERMISSION_GRANTED); 12948 // Filing a couple requests prior to testing the dump. 12949 final TestNetworkCallback genericNetworkCallback = new TestNetworkCallback(); 12950 final TestNetworkCallback wifiNetworkCallback = new TestNetworkCallback(); 12951 final NetworkRequest genericRequest = new NetworkRequest.Builder() 12952 .clearCapabilities().build(); 12953 final NetworkRequest wifiRequest = new NetworkRequest.Builder() 12954 .addTransportType(TRANSPORT_WIFI).build(); 12955 mCm.registerNetworkCallback(genericRequest, genericNetworkCallback); 12956 mCm.registerNetworkCallback(wifiRequest, wifiNetworkCallback); 12957 12958 verifyDump(new String[0]); 12959 12960 // Verify dump with arguments. 12961 final String dumpPrio = "--dump-priority"; 12962 final String[] dumpArgs = {dumpPrio}; 12963 verifyDump(dumpArgs); 12964 12965 final String[] highDumpArgs = {dumpPrio, "HIGH"}; 12966 verifyDump(highDumpArgs); 12967 12968 final String[] normalDumpArgs = {dumpPrio, "NORMAL"}; 12969 verifyDump(normalDumpArgs); 12970 12971 // Invalid args should do dumpNormal w/o exception 12972 final String[] unknownDumpArgs = {dumpPrio, "UNKNOWN"}; 12973 verifyDump(unknownDumpArgs); 12974 12975 final String[] invalidDumpArgs = {"UNKNOWN"}; 12976 verifyDump(invalidDumpArgs); 12977 } 12978 12979 @Test 12980 public void testRequestsSortedByIdSortsCorrectly() { 12981 final TestNetworkCallback genericNetworkCallback = new TestNetworkCallback(); 12982 final TestNetworkCallback wifiNetworkCallback = new TestNetworkCallback(); 12983 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback(); 12984 final NetworkRequest genericRequest = new NetworkRequest.Builder() 12985 .clearCapabilities().build(); 12986 final NetworkRequest wifiRequest = new NetworkRequest.Builder() 12987 .addTransportType(TRANSPORT_WIFI).build(); 12988 final NetworkRequest cellRequest = new NetworkRequest.Builder() 12989 .addTransportType(TRANSPORT_CELLULAR).build(); 12990 mCm.registerNetworkCallback(genericRequest, genericNetworkCallback); 12991 mCm.registerNetworkCallback(wifiRequest, wifiNetworkCallback); 12992 mCm.registerNetworkCallback(cellRequest, cellNetworkCallback); 12993 waitForIdle(); 12994 12995 final NetworkRequestInfo[] nriOutput = mService.requestsSortedById(); 12996 12997 assertTrue(nriOutput.length > 1); 12998 for (int i = 0; i < nriOutput.length - 1; i++) { 12999 final boolean isRequestIdInOrder = 13000 nriOutput[i].mRequests.get(0).requestId 13001 < nriOutput[i + 1].mRequests.get(0).requestId; 13002 assertTrue(isRequestIdInOrder); 13003 } 13004 } 13005 13006 private void assertUidRangesUpdatedForMyUid(boolean add) throws Exception { 13007 final int uid = Process.myUid(); 13008 assertVpnUidRangesUpdated(add, uidRangesForUids(uid), uid); 13009 } 13010 13011 private void assertVpnUidRangesUpdated(boolean add, Set<UidRange> vpnRanges, int exemptUid) 13012 throws Exception { 13013 InOrder inOrder = inOrder(mMockNetd, mDestroySocketsWrapper); 13014 final Set<Integer> exemptUidSet = new ArraySet<>(List.of(exemptUid, Process.VPN_UID)); 13015 ArgumentCaptor<int[]> exemptUidCaptor = ArgumentCaptor.forClass(int[].class); 13016 13017 if (mDeps.isAtLeastU()) { 13018 inOrder.verify(mDestroySocketsWrapper).destroyLiveTcpSockets( 13019 UidRange.toIntRanges(vpnRanges), exemptUidSet); 13020 } else { 13021 inOrder.verify(mMockNetd).socketDestroy(eq(toUidRangeStableParcels(vpnRanges)), 13022 exemptUidCaptor.capture()); 13023 assertContainsExactly(exemptUidCaptor.getValue(), Process.VPN_UID, exemptUid); 13024 } 13025 13026 if (add) { 13027 inOrder.verify(mMockNetd, times(1)).networkAddUidRangesParcel( 13028 new NativeUidRangeConfig(mMockVpn.getNetwork().getNetId(), 13029 toUidRangeStableParcels(vpnRanges), PREFERENCE_ORDER_VPN)); 13030 } else { 13031 inOrder.verify(mMockNetd, times(1)).networkRemoveUidRangesParcel( 13032 new NativeUidRangeConfig(mMockVpn.getNetwork().getNetId(), 13033 toUidRangeStableParcels(vpnRanges), PREFERENCE_ORDER_VPN)); 13034 } 13035 13036 if (mDeps.isAtLeastU()) { 13037 inOrder.verify(mDestroySocketsWrapper).destroyLiveTcpSockets( 13038 UidRange.toIntRanges(vpnRanges), exemptUidSet); 13039 } else { 13040 inOrder.verify(mMockNetd).socketDestroy(eq(toUidRangeStableParcels(vpnRanges)), 13041 exemptUidCaptor.capture()); 13042 assertContainsExactly(exemptUidCaptor.getValue(), Process.VPN_UID, exemptUid); 13043 } 13044 } 13045 13046 @Test 13047 public void testVpnUidRangesUpdate() throws Exception { 13048 // Set up a WiFi network without proxy. 13049 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 13050 mWiFiAgent.connect(true); 13051 assertNull(mService.getProxyForNetwork(null)); 13052 assertNull(mCm.getDefaultProxy()); 13053 13054 final ExpectedBroadcast b1 = expectProxyChangeAction(); 13055 final LinkProperties lp = new LinkProperties(); 13056 lp.setInterfaceName("tun0"); 13057 lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), null)); 13058 lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), null)); 13059 final UidRange vpnRange = PRIMARY_UIDRANGE; 13060 final Set<UidRange> vpnRanges = Collections.singleton(vpnRange); 13061 mMockVpn.establish(lp, VPN_UID, vpnRanges); 13062 assertVpnUidRangesUpdated(true, vpnRanges, VPN_UID); 13063 // VPN is connected but proxy is not set, so there is no need to send proxy broadcast. 13064 b1.expectNoBroadcast(500); 13065 13066 // Update to new range which is old range minus APP1, i.e. only APP2 13067 final ExpectedBroadcast b2 = expectProxyChangeAction(); 13068 final Set<UidRange> newRanges = new HashSet<>(asList( 13069 new UidRange(vpnRange.start, APP1_UID - 1), 13070 new UidRange(APP1_UID + 1, vpnRange.stop))); 13071 mMockVpn.setUids(newRanges); 13072 waitForIdle(); 13073 13074 assertVpnUidRangesUpdated(true, newRanges, VPN_UID); 13075 assertVpnUidRangesUpdated(false, vpnRanges, VPN_UID); 13076 13077 // Uid has changed but proxy is not set, so there is no need to send proxy broadcast. 13078 b2.expectNoBroadcast(500); 13079 13080 final ProxyInfo testProxyInfo = ProxyInfo.buildDirectProxy("test", 8888); 13081 final ExpectedBroadcast b3 = expectProxyChangeAction(); 13082 lp.setHttpProxy(testProxyInfo); 13083 mMockVpn.sendLinkProperties(lp); 13084 waitForIdle(); 13085 // Proxy is set, so send a proxy broadcast. 13086 b3.expectBroadcast(); 13087 13088 final ExpectedBroadcast b4 = expectProxyChangeAction(); 13089 mMockVpn.setUids(vpnRanges); 13090 waitForIdle(); 13091 // Uid has changed and proxy is already set, so send a proxy broadcast. 13092 b4.expectBroadcast(); 13093 13094 final ExpectedBroadcast b5 = expectProxyChangeAction(); 13095 // Proxy is removed, send a proxy broadcast. 13096 lp.setHttpProxy(null); 13097 mMockVpn.sendLinkProperties(lp); 13098 waitForIdle(); 13099 b5.expectBroadcast(); 13100 13101 // Proxy is added in WiFi(default network), setDefaultProxy will be called. 13102 final LinkProperties wifiLp = mCm.getLinkProperties(mWiFiAgent.getNetwork()); 13103 assertNotNull(wifiLp); 13104 final ExpectedBroadcast b6 = expectProxyChangeAction(testProxyInfo); 13105 wifiLp.setHttpProxy(testProxyInfo); 13106 mWiFiAgent.sendLinkProperties(wifiLp); 13107 waitForIdle(); 13108 b6.expectBroadcast(); 13109 } 13110 13111 @Test 13112 public void testProxyBroadcastWillBeSentWhenVpnHasProxyAndConnects() throws Exception { 13113 // Set up a WiFi network without proxy. 13114 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 13115 mWiFiAgent.connect(true); 13116 assertNull(mService.getProxyForNetwork(null)); 13117 assertNull(mCm.getDefaultProxy()); 13118 13119 final LinkProperties lp = new LinkProperties(); 13120 lp.setInterfaceName("tun0"); 13121 lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), null)); 13122 lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), null)); 13123 final ProxyInfo testProxyInfo = ProxyInfo.buildDirectProxy("test", 8888); 13124 lp.setHttpProxy(testProxyInfo); 13125 final UidRange vpnRange = PRIMARY_UIDRANGE; 13126 final Set<UidRange> vpnRanges = Collections.singleton(vpnRange); 13127 final ExpectedBroadcast b1 = expectProxyChangeAction(); 13128 mMockVpn.setOwnerAndAdminUid(VPN_UID); 13129 mMockVpn.registerAgent(false, vpnRanges, lp); 13130 // In any case, the proxy broadcast won't be sent before VPN goes into CONNECTED state. 13131 // Otherwise, the app that calls ConnectivityManager#getDefaultProxy() when it receives the 13132 // proxy broadcast will get null. 13133 b1.expectNoBroadcast(500); 13134 13135 final ExpectedBroadcast b2 = expectProxyChangeAction(); 13136 mMockVpn.connect(true /* validated */, true /* hasInternet */, 13137 false /* privateDnsProbeSent */); 13138 waitForIdle(); 13139 assertVpnUidRangesUpdated(true, vpnRanges, VPN_UID); 13140 // Vpn is connected with proxy, so the proxy broadcast will be sent to inform the apps to 13141 // update their proxy data. 13142 b2.expectBroadcast(); 13143 } 13144 13145 @Test 13146 public void testProxyBroadcastWillBeSentWhenTheProxyOfNonDefaultNetworkHasChanged() 13147 throws Exception { 13148 // Set up a CELLULAR network without proxy. 13149 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 13150 mCellAgent.connect(true); 13151 assertNull(mService.getProxyForNetwork(null)); 13152 assertNull(mCm.getDefaultProxy()); 13153 // CELLULAR network should be the default network. 13154 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetwork()); 13155 13156 // Set up a WiFi network without proxy. 13157 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 13158 mWiFiAgent.connect(true); 13159 assertNull(mService.getProxyForNetwork(null)); 13160 assertNull(mCm.getDefaultProxy()); 13161 // WiFi network should be the default network. 13162 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetwork()); 13163 // CELLULAR network is not the default network. 13164 assertNotEquals(mCellAgent.getNetwork(), mCm.getActiveNetwork()); 13165 13166 // CELLULAR network is not the system default network, but it might be a per-app default 13167 // network. The proxy broadcast should be sent once its proxy has changed. 13168 final LinkProperties cellularLp = new LinkProperties(); 13169 cellularLp.setInterfaceName(MOBILE_IFNAME); 13170 final ProxyInfo testProxyInfo = ProxyInfo.buildDirectProxy("test", 8888); 13171 final ExpectedBroadcast b = expectProxyChangeAction(); 13172 cellularLp.setHttpProxy(testProxyInfo); 13173 mCellAgent.sendLinkProperties(cellularLp); 13174 b.expectBroadcast(); 13175 } 13176 13177 @Test 13178 public void testInvalidRequestTypes() { 13179 final int[] invalidReqTypeInts = new int[]{-1, NetworkRequest.Type.NONE.ordinal(), 13180 NetworkRequest.Type.LISTEN.ordinal(), NetworkRequest.Type.values().length}; 13181 final NetworkCapabilities nc = new NetworkCapabilities().addTransportType(TRANSPORT_WIFI); 13182 13183 for (int reqTypeInt : invalidReqTypeInts) { 13184 assertThrows("Expect throws for invalid request type " + reqTypeInt, 13185 IllegalArgumentException.class, 13186 () -> mService.requestNetwork(Process.INVALID_UID, nc, reqTypeInt, null, 0, 13187 null, ConnectivityManager.TYPE_NONE, NetworkCallback.FLAG_NONE, 13188 mContext.getPackageName(), getAttributionTag()) 13189 ); 13190 } 13191 } 13192 13193 @Test 13194 public void testKeepConnected() throws Exception { 13195 setAlwaysOnNetworks(false); 13196 registerDefaultNetworkCallbacks(); 13197 final TestNetworkCallback allNetworksCb = new TestNetworkCallback(); 13198 final NetworkRequest allNetworksRequest = new NetworkRequest.Builder().clearCapabilities() 13199 .build(); 13200 mCm.registerNetworkCallback(allNetworksRequest, allNetworksCb); 13201 13202 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 13203 mCellAgent.connect(true /* validated */); 13204 13205 mDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 13206 allNetworksCb.expectAvailableThenValidatedCallbacks(mCellAgent); 13207 13208 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 13209 mWiFiAgent.connect(true /* validated */); 13210 13211 mDefaultNetworkCallback.expectAvailableDoubleValidatedCallbacks(mWiFiAgent); 13212 // While the default callback doesn't see the network before it's validated, the listen 13213 // sees the network come up and validate later 13214 allNetworksCb.expectAvailableCallbacksUnvalidated(mWiFiAgent); 13215 allNetworksCb.expectLosing(mCellAgent); 13216 allNetworksCb.expectCaps(mWiFiAgent, c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 13217 allNetworksCb.expect(LOST, mCellAgent, TEST_LINGER_DELAY_MS * 2); 13218 13219 // The cell network has disconnected (see LOST above) because it was outscored and 13220 // had no requests (see setAlwaysOnNetworks(false) above) 13221 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 13222 final NetworkScore score = new NetworkScore.Builder().setLegacyInt(30).build(); 13223 mCellAgent.setScore(score); 13224 mCellAgent.connect(false /* validated */); 13225 13226 // The cell network gets torn down right away. 13227 allNetworksCb.expectAvailableCallbacksUnvalidated(mCellAgent); 13228 allNetworksCb.expect(LOST, mCellAgent, TEST_NASCENT_DELAY_MS * 2); 13229 allNetworksCb.assertNoCallback(); 13230 13231 // Now create a cell network with KEEP_CONNECTED_FOR_HANDOVER and make sure it's 13232 // not disconnected immediately when outscored. 13233 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 13234 final NetworkScore scoreKeepup = new NetworkScore.Builder().setLegacyInt(30) 13235 .setKeepConnectedReason(KEEP_CONNECTED_FOR_HANDOVER).build(); 13236 mCellAgent.setScore(scoreKeepup); 13237 mCellAgent.connect(true /* validated */); 13238 13239 allNetworksCb.expectAvailableThenValidatedCallbacks(mCellAgent); 13240 mDefaultNetworkCallback.assertNoCallback(); 13241 13242 mWiFiAgent.disconnect(); 13243 13244 allNetworksCb.expect(LOST, mWiFiAgent); 13245 mDefaultNetworkCallback.expect(LOST, mWiFiAgent); 13246 mDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellAgent); 13247 13248 // Reconnect a WiFi network and make sure the cell network is still not torn down. 13249 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 13250 mWiFiAgent.connect(true /* validated */); 13251 13252 allNetworksCb.expectAvailableThenValidatedCallbacks(mWiFiAgent); 13253 mDefaultNetworkCallback.expectAvailableDoubleValidatedCallbacks(mWiFiAgent); 13254 13255 // Now remove the reason to keep connected and make sure the network lingers and is 13256 // torn down. 13257 mCellAgent.setScore(new NetworkScore.Builder().setLegacyInt(30).build()); 13258 allNetworksCb.expectLosing(mCellAgent, TEST_NASCENT_DELAY_MS * 2); 13259 allNetworksCb.expect(LOST, mCellAgent, TEST_LINGER_DELAY_MS * 2); 13260 mDefaultNetworkCallback.assertNoCallback(); 13261 13262 mCm.unregisterNetworkCallback(allNetworksCb); 13263 // mDefaultNetworkCallback will be unregistered by tearDown() 13264 } 13265 13266 private class QosCallbackMockHelper { 13267 @NonNull public final QosFilter mFilter; 13268 @NonNull public final IQosCallback mCallback; 13269 @NonNull public final TestNetworkAgentWrapper mAgentWrapper; 13270 @NonNull private final List<IQosCallback> mCallbacks = new ArrayList(); 13271 13272 QosCallbackMockHelper() throws Exception { 13273 Log.d(TAG, "QosCallbackMockHelper: "); 13274 mFilter = mock(QosFilter.class); 13275 13276 // Ensure the network is disconnected before anything else occurs 13277 assertNull(mCellAgent); 13278 13279 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 13280 mCellAgent.connect(true); 13281 13282 verifyActiveNetwork(TRANSPORT_CELLULAR); 13283 waitForIdle(); 13284 final Network network = mCellAgent.getNetwork(); 13285 13286 final Pair<IQosCallback, IBinder> pair = createQosCallback(); 13287 mCallback = pair.first; 13288 13289 doReturn(network).when(mFilter).getNetwork(); 13290 doReturn(QosCallbackException.EX_TYPE_FILTER_NONE).when(mFilter).validate(); 13291 mAgentWrapper = mCellAgent; 13292 } 13293 13294 void registerQosCallback(@NonNull final QosFilter filter, 13295 @NonNull final IQosCallback callback) { 13296 mCallbacks.add(callback); 13297 final NetworkAgentInfo nai = 13298 mService.getNetworkAgentInfoForNetwork(filter.getNetwork()); 13299 mService.registerQosCallbackInternal(filter, callback, nai); 13300 } 13301 13302 void tearDown() { 13303 for (int i = 0; i < mCallbacks.size(); i++) { 13304 mService.unregisterQosCallback(mCallbacks.get(i)); 13305 } 13306 } 13307 } 13308 13309 private Pair<IQosCallback, IBinder> createQosCallback() { 13310 final IQosCallback callback = mock(IQosCallback.class); 13311 final IBinder binder = mock(Binder.class); 13312 doReturn(binder).when(callback).asBinder(); 13313 doReturn(true).when(binder).isBinderAlive(); 13314 return new Pair<>(callback, binder); 13315 } 13316 13317 13318 @Test 13319 public void testQosCallbackRegistration() throws Exception { 13320 mQosCallbackMockHelper = new QosCallbackMockHelper(); 13321 final NetworkAgentWrapper wrapper = mQosCallbackMockHelper.mAgentWrapper; 13322 13323 doReturn(QosCallbackException.EX_TYPE_FILTER_NONE) 13324 .when(mQosCallbackMockHelper.mFilter).validate(); 13325 mQosCallbackMockHelper.registerQosCallback( 13326 mQosCallbackMockHelper.mFilter, mQosCallbackMockHelper.mCallback); 13327 13328 final OnQosCallbackRegister cbRegister1 = 13329 (OnQosCallbackRegister) wrapper.getCallbackHistory().poll(1000, x -> true); 13330 assertNotNull(cbRegister1); 13331 13332 final int registerCallbackId = cbRegister1.mQosCallbackId; 13333 mService.unregisterQosCallback(mQosCallbackMockHelper.mCallback); 13334 final OnQosCallbackUnregister cbUnregister = 13335 (OnQosCallbackUnregister) wrapper.getCallbackHistory().poll(1000, x -> true); 13336 assertNotNull(cbUnregister); 13337 assertEquals(registerCallbackId, cbUnregister.mQosCallbackId); 13338 assertNull(wrapper.getCallbackHistory().poll(200, x -> true)); 13339 } 13340 13341 @Test 13342 public void testQosCallbackNoRegistrationOnValidationError() throws Exception { 13343 mQosCallbackMockHelper = new QosCallbackMockHelper(); 13344 13345 doReturn(QosCallbackException.EX_TYPE_FILTER_NETWORK_RELEASED) 13346 .when(mQosCallbackMockHelper.mFilter).validate(); 13347 mQosCallbackMockHelper.registerQosCallback( 13348 mQosCallbackMockHelper.mFilter, mQosCallbackMockHelper.mCallback); 13349 waitForIdle(); 13350 verify(mQosCallbackMockHelper.mCallback) 13351 .onError(eq(QosCallbackException.EX_TYPE_FILTER_NETWORK_RELEASED)); 13352 } 13353 13354 @Test 13355 public void testQosCallbackAvailableAndLost() throws Exception { 13356 mQosCallbackMockHelper = new QosCallbackMockHelper(); 13357 final int sessionId = 10; 13358 final int qosCallbackId = 1; 13359 13360 doReturn(QosCallbackException.EX_TYPE_FILTER_NONE) 13361 .when(mQosCallbackMockHelper.mFilter).validate(); 13362 mQosCallbackMockHelper.registerQosCallback( 13363 mQosCallbackMockHelper.mFilter, mQosCallbackMockHelper.mCallback); 13364 waitForIdle(); 13365 13366 final EpsBearerQosSessionAttributes attributes = new EpsBearerQosSessionAttributes( 13367 1, 2, 3, 4, 5, new ArrayList<>()); 13368 mQosCallbackMockHelper.mAgentWrapper.getNetworkAgent() 13369 .sendQosSessionAvailable(qosCallbackId, sessionId, attributes); 13370 waitForIdle(); 13371 13372 verify(mQosCallbackMockHelper.mCallback).onQosEpsBearerSessionAvailable(argThat(session -> 13373 session.getSessionId() == sessionId 13374 && session.getSessionType() == QosSession.TYPE_EPS_BEARER), eq(attributes)); 13375 13376 mQosCallbackMockHelper.mAgentWrapper.getNetworkAgent() 13377 .sendQosSessionLost(qosCallbackId, sessionId, QosSession.TYPE_EPS_BEARER); 13378 waitForIdle(); 13379 verify(mQosCallbackMockHelper.mCallback).onQosSessionLost(argThat(session -> 13380 session.getSessionId() == sessionId 13381 && session.getSessionType() == QosSession.TYPE_EPS_BEARER)); 13382 } 13383 13384 @Test 13385 public void testNrQosCallbackAvailableAndLost() throws Exception { 13386 mQosCallbackMockHelper = new QosCallbackMockHelper(); 13387 final int sessionId = 10; 13388 final int qosCallbackId = 1; 13389 13390 doReturn(QosCallbackException.EX_TYPE_FILTER_NONE) 13391 .when(mQosCallbackMockHelper.mFilter).validate(); 13392 mQosCallbackMockHelper.registerQosCallback( 13393 mQosCallbackMockHelper.mFilter, mQosCallbackMockHelper.mCallback); 13394 waitForIdle(); 13395 13396 final NrQosSessionAttributes attributes = new NrQosSessionAttributes( 13397 1, 2, 3, 4, 5, 6, 7, new ArrayList<>()); 13398 mQosCallbackMockHelper.mAgentWrapper.getNetworkAgent() 13399 .sendQosSessionAvailable(qosCallbackId, sessionId, attributes); 13400 waitForIdle(); 13401 13402 verify(mQosCallbackMockHelper.mCallback).onNrQosSessionAvailable(argThat(session -> 13403 session.getSessionId() == sessionId 13404 && session.getSessionType() == QosSession.TYPE_NR_BEARER), eq(attributes)); 13405 13406 mQosCallbackMockHelper.mAgentWrapper.getNetworkAgent() 13407 .sendQosSessionLost(qosCallbackId, sessionId, QosSession.TYPE_NR_BEARER); 13408 waitForIdle(); 13409 verify(mQosCallbackMockHelper.mCallback).onQosSessionLost(argThat(session -> 13410 session.getSessionId() == sessionId 13411 && session.getSessionType() == QosSession.TYPE_NR_BEARER)); 13412 } 13413 13414 @Test @IgnoreUpTo(SC_V2) 13415 public void testQosCallbackAvailableOnValidationError() throws Exception { 13416 mQosCallbackMockHelper = new QosCallbackMockHelper(); 13417 final NetworkAgentWrapper wrapper = mQosCallbackMockHelper.mAgentWrapper; 13418 final int sessionId = 10; 13419 final int qosCallbackId = 1; 13420 13421 doReturn(QosCallbackException.EX_TYPE_FILTER_NONE) 13422 .when(mQosCallbackMockHelper.mFilter).validate(); 13423 mQosCallbackMockHelper.registerQosCallback( 13424 mQosCallbackMockHelper.mFilter, mQosCallbackMockHelper.mCallback); 13425 OnQosCallbackRegister cbRegister1 = 13426 (OnQosCallbackRegister) wrapper.getCallbackHistory().poll(1000, x -> true); 13427 assertNotNull(cbRegister1); 13428 final int registerCallbackId = cbRegister1.mQosCallbackId; 13429 13430 waitForIdle(); 13431 13432 doReturn(QosCallbackException.EX_TYPE_FILTER_SOCKET_REMOTE_ADDRESS_CHANGED) 13433 .when(mQosCallbackMockHelper.mFilter).validate(); 13434 final EpsBearerQosSessionAttributes attributes = new EpsBearerQosSessionAttributes( 13435 1, 2, 3, 4, 5, new ArrayList<>()); 13436 mQosCallbackMockHelper.mAgentWrapper.getNetworkAgent() 13437 .sendQosSessionAvailable(qosCallbackId, sessionId, attributes); 13438 waitForIdle(); 13439 13440 final NetworkAgentWrapper.CallbackType.OnQosCallbackUnregister cbUnregister; 13441 cbUnregister = (NetworkAgentWrapper.CallbackType.OnQosCallbackUnregister) 13442 wrapper.getCallbackHistory().poll(1000, x -> true); 13443 assertNotNull(cbUnregister); 13444 assertEquals(registerCallbackId, cbUnregister.mQosCallbackId); 13445 waitForIdle(); 13446 verify(mQosCallbackMockHelper.mCallback) 13447 .onError(eq(QosCallbackException.EX_TYPE_FILTER_SOCKET_REMOTE_ADDRESS_CHANGED)); 13448 } 13449 13450 @Test @IgnoreUpTo(SC_V2) 13451 public void testQosCallbackLostOnValidationError() throws Exception { 13452 mQosCallbackMockHelper = new QosCallbackMockHelper(); 13453 final int sessionId = 10; 13454 final int qosCallbackId = 1; 13455 13456 doReturn(QosCallbackException.EX_TYPE_FILTER_NONE) 13457 .when(mQosCallbackMockHelper.mFilter).validate(); 13458 mQosCallbackMockHelper.registerQosCallback( 13459 mQosCallbackMockHelper.mFilter, mQosCallbackMockHelper.mCallback); 13460 waitForIdle(); 13461 EpsBearerQosSessionAttributes attributes = 13462 sendQosSessionEvent(qosCallbackId, sessionId, true); 13463 waitForIdle(); 13464 13465 verify(mQosCallbackMockHelper.mCallback).onQosEpsBearerSessionAvailable(argThat(session -> 13466 session.getSessionId() == sessionId 13467 && session.getSessionType() == QosSession.TYPE_EPS_BEARER), eq(attributes)); 13468 13469 doReturn(QosCallbackException.EX_TYPE_FILTER_SOCKET_REMOTE_ADDRESS_CHANGED) 13470 .when(mQosCallbackMockHelper.mFilter).validate(); 13471 13472 sendQosSessionEvent(qosCallbackId, sessionId, false); 13473 waitForIdle(); 13474 verify(mQosCallbackMockHelper.mCallback) 13475 .onError(eq(QosCallbackException.EX_TYPE_FILTER_SOCKET_REMOTE_ADDRESS_CHANGED)); 13476 } 13477 13478 private EpsBearerQosSessionAttributes sendQosSessionEvent( 13479 int qosCallbackId, int sessionId, boolean available) { 13480 if (available) { 13481 final EpsBearerQosSessionAttributes attributes = new EpsBearerQosSessionAttributes( 13482 1, 2, 3, 4, 5, new ArrayList<>()); 13483 mQosCallbackMockHelper.mAgentWrapper.getNetworkAgent() 13484 .sendQosSessionAvailable(qosCallbackId, sessionId, attributes); 13485 return attributes; 13486 } else { 13487 mQosCallbackMockHelper.mAgentWrapper.getNetworkAgent() 13488 .sendQosSessionLost(qosCallbackId, sessionId, QosSession.TYPE_EPS_BEARER); 13489 return null; 13490 } 13491 13492 } 13493 13494 @Test 13495 public void testQosCallbackTooManyRequests() throws Exception { 13496 mQosCallbackMockHelper = new QosCallbackMockHelper(); 13497 13498 doReturn(QosCallbackException.EX_TYPE_FILTER_NONE) 13499 .when(mQosCallbackMockHelper.mFilter).validate(); 13500 for (int i = 0; i < 100; i++) { 13501 final Pair<IQosCallback, IBinder> pair = createQosCallback(); 13502 13503 try { 13504 mQosCallbackMockHelper.registerQosCallback( 13505 mQosCallbackMockHelper.mFilter, pair.first); 13506 } catch (ServiceSpecificException e) { 13507 assertEquals(e.errorCode, ConnectivityManager.Errors.TOO_MANY_REQUESTS); 13508 if (i < 50) { 13509 fail("TOO_MANY_REQUESTS thrown too early, the count is " + i); 13510 } 13511 13512 // As long as there is at least 50 requests, it is safe to assume it works. 13513 // Note: The count isn't being tested precisely against 100 because the counter 13514 // is shared with request network. 13515 return; 13516 } 13517 } 13518 fail("TOO_MANY_REQUESTS never thrown"); 13519 } 13520 13521 private void mockGetApplicationInfo(@NonNull final String packageName, final int uid) { 13522 mockGetApplicationInfo(packageName, uid, PRIMARY_USER_HANDLE); 13523 } 13524 13525 private void mockGetApplicationInfo(@NonNull final String packageName, final int uid, 13526 @NonNull final UserHandle user) { 13527 final ApplicationInfo applicationInfo = new ApplicationInfo(); 13528 applicationInfo.uid = uid; 13529 try { 13530 doReturn(applicationInfo).when(mPackageManager).getApplicationInfoAsUser( 13531 eq(packageName), anyInt(), eq(user)); 13532 } catch (Exception e) { 13533 fail(e.getMessage()); 13534 } 13535 } 13536 13537 private void mockGetApplicationInfoThrowsNameNotFound(@NonNull final String packageName, 13538 @NonNull final UserHandle user) 13539 throws Exception { 13540 doThrow(new PackageManager.NameNotFoundException(packageName)).when( 13541 mPackageManager).getApplicationInfoAsUser(eq(packageName), anyInt(), eq(user)); 13542 } 13543 13544 private void mockHasSystemFeature(@NonNull final String featureName, final boolean hasFeature) { 13545 doReturn(hasFeature).when(mPackageManager).hasSystemFeature(eq(featureName)); 13546 } 13547 13548 private Range<Integer> getNriFirstUidRange(@NonNull final NetworkRequestInfo nri) { 13549 return nri.mRequests.get(0).networkCapabilities.getUids().iterator().next(); 13550 } 13551 13552 private OemNetworkPreferences createDefaultOemNetworkPreferences( 13553 @OemNetworkPreferences.OemNetworkPreference final int preference) { 13554 // Arrange PackageManager mocks 13555 mockGetApplicationInfo(TEST_PACKAGE_NAME, TEST_PACKAGE_UID); 13556 13557 // Build OemNetworkPreferences object 13558 return new OemNetworkPreferences.Builder() 13559 .addNetworkPreference(TEST_PACKAGE_NAME, preference) 13560 .build(); 13561 } 13562 13563 @Test 13564 public void testOemNetworkRequestFactoryPreferenceUninitializedThrowsError() { 13565 @OemNetworkPreferences.OemNetworkPreference final int prefToTest = 13566 OEM_NETWORK_PREFERENCE_UNINITIALIZED; 13567 13568 // Act on OemNetworkRequestFactory.createNrisFromOemNetworkPreferences() 13569 assertThrows(IllegalArgumentException.class, 13570 () -> mService.new OemNetworkRequestFactory() 13571 .createNrisFromOemNetworkPreferences( 13572 createDefaultOemNetworkPreferences(prefToTest))); 13573 } 13574 13575 @Test 13576 public void testOemNetworkRequestFactoryPreferenceOemPaid() 13577 throws Exception { 13578 // Expectations 13579 final int expectedNumOfNris = 1; 13580 final int expectedNumOfRequests = 3; 13581 13582 @OemNetworkPreferences.OemNetworkPreference final int prefToTest = 13583 OEM_NETWORK_PREFERENCE_OEM_PAID; 13584 13585 // Act on OemNetworkRequestFactory.createNrisFromOemNetworkPreferences() 13586 final ArraySet<NetworkRequestInfo> nris = 13587 mService.new OemNetworkRequestFactory() 13588 .createNrisFromOemNetworkPreferences( 13589 createDefaultOemNetworkPreferences(prefToTest)); 13590 final NetworkRequestInfo nri = nris.iterator().next(); 13591 assertEquals(PREFERENCE_ORDER_OEM, nri.mPreferenceOrder); 13592 final List<NetworkRequest> mRequests = nri.mRequests; 13593 assertEquals(expectedNumOfNris, nris.size()); 13594 assertEquals(expectedNumOfRequests, mRequests.size()); 13595 assertTrue(mRequests.get(0).isListen()); 13596 assertTrue(mRequests.get(0).hasCapability(NET_CAPABILITY_NOT_METERED)); 13597 assertTrue(mRequests.get(0).hasCapability(NET_CAPABILITY_VALIDATED)); 13598 assertTrue(mRequests.get(1).isRequest()); 13599 assertTrue(mRequests.get(1).hasCapability(NET_CAPABILITY_OEM_PAID)); 13600 assertEquals(NetworkRequest.Type.TRACK_DEFAULT, mRequests.get(2).type); 13601 assertTrue(mService.getDefaultRequest().networkCapabilities.equalsNetCapabilities( 13602 mRequests.get(2).networkCapabilities)); 13603 } 13604 13605 @Test 13606 public void testOemNetworkRequestFactoryPreferenceOemPaidNoFallback() 13607 throws Exception { 13608 // Expectations 13609 final int expectedNumOfNris = 1; 13610 final int expectedNumOfRequests = 2; 13611 13612 @OemNetworkPreferences.OemNetworkPreference final int prefToTest = 13613 OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK; 13614 13615 // Act on OemNetworkRequestFactory.createNrisFromOemNetworkPreferences() 13616 final ArraySet<NetworkRequestInfo> nris = 13617 mService.new OemNetworkRequestFactory() 13618 .createNrisFromOemNetworkPreferences( 13619 createDefaultOemNetworkPreferences(prefToTest)); 13620 final NetworkRequestInfo nri = nris.iterator().next(); 13621 assertEquals(PREFERENCE_ORDER_OEM, nri.mPreferenceOrder); 13622 final List<NetworkRequest> mRequests = nri.mRequests; 13623 assertEquals(expectedNumOfNris, nris.size()); 13624 assertEquals(expectedNumOfRequests, mRequests.size()); 13625 assertTrue(mRequests.get(0).isListen()); 13626 assertTrue(mRequests.get(0).hasCapability(NET_CAPABILITY_NOT_METERED)); 13627 assertTrue(mRequests.get(0).hasCapability(NET_CAPABILITY_VALIDATED)); 13628 assertTrue(mRequests.get(1).isRequest()); 13629 assertTrue(mRequests.get(1).hasCapability(NET_CAPABILITY_OEM_PAID)); 13630 } 13631 13632 @Test 13633 public void testOemNetworkRequestFactoryPreferenceOemPaidOnly() 13634 throws Exception { 13635 // Expectations 13636 final int expectedNumOfNris = 1; 13637 final int expectedNumOfRequests = 1; 13638 13639 @OemNetworkPreferences.OemNetworkPreference final int prefToTest = 13640 OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY; 13641 13642 // Act on OemNetworkRequestFactory.createNrisFromOemNetworkPreferences() 13643 final ArraySet<NetworkRequestInfo> nris = 13644 mService.new OemNetworkRequestFactory() 13645 .createNrisFromOemNetworkPreferences( 13646 createDefaultOemNetworkPreferences(prefToTest)); 13647 final NetworkRequestInfo nri = nris.iterator().next(); 13648 assertEquals(PREFERENCE_ORDER_OEM, nri.mPreferenceOrder); 13649 final List<NetworkRequest> mRequests = nri.mRequests; 13650 assertEquals(expectedNumOfNris, nris.size()); 13651 assertEquals(expectedNumOfRequests, mRequests.size()); 13652 assertTrue(mRequests.get(0).isRequest()); 13653 assertTrue(mRequests.get(0).hasCapability(NET_CAPABILITY_OEM_PAID)); 13654 } 13655 13656 @Test 13657 public void testOemNetworkRequestFactoryPreferenceOemPrivateOnly() 13658 throws Exception { 13659 // Expectations 13660 final int expectedNumOfNris = 1; 13661 final int expectedNumOfRequests = 1; 13662 13663 @OemNetworkPreferences.OemNetworkPreference final int prefToTest = 13664 OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY; 13665 13666 // Act on OemNetworkRequestFactory.createNrisFromOemNetworkPreferences() 13667 final ArraySet<NetworkRequestInfo> nris = 13668 mService.new OemNetworkRequestFactory() 13669 .createNrisFromOemNetworkPreferences( 13670 createDefaultOemNetworkPreferences(prefToTest)); 13671 final NetworkRequestInfo nri = nris.iterator().next(); 13672 assertEquals(PREFERENCE_ORDER_OEM, nri.mPreferenceOrder); 13673 final List<NetworkRequest> mRequests = nri.mRequests; 13674 assertEquals(expectedNumOfNris, nris.size()); 13675 assertEquals(expectedNumOfRequests, mRequests.size()); 13676 assertTrue(mRequests.get(0).isRequest()); 13677 assertTrue(mRequests.get(0).hasCapability(NET_CAPABILITY_OEM_PRIVATE)); 13678 assertFalse(mRequests.get(0).hasCapability(NET_CAPABILITY_OEM_PAID)); 13679 } 13680 13681 @Test 13682 public void testOemNetworkRequestFactoryCreatesCorrectNumOfNris() 13683 throws Exception { 13684 // Expectations 13685 final int expectedNumOfNris = 2; 13686 13687 // Arrange PackageManager mocks 13688 final String testPackageName2 = "com.google.apps.dialer"; 13689 mockGetApplicationInfo(TEST_PACKAGE_NAME, TEST_PACKAGE_UID); 13690 mockGetApplicationInfo(testPackageName2, TEST_PACKAGE_UID); 13691 13692 // Build OemNetworkPreferences object 13693 final int testOemPref = OEM_NETWORK_PREFERENCE_OEM_PAID; 13694 final int testOemPref2 = OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK; 13695 final OemNetworkPreferences pref = new OemNetworkPreferences.Builder() 13696 .addNetworkPreference(TEST_PACKAGE_NAME, testOemPref) 13697 .addNetworkPreference(testPackageName2, testOemPref2) 13698 .build(); 13699 13700 // Act on OemNetworkRequestFactory.createNrisFromOemNetworkPreferences() 13701 final ArraySet<NetworkRequestInfo> nris = 13702 mService.new OemNetworkRequestFactory().createNrisFromOemNetworkPreferences(pref); 13703 13704 assertNotNull(nris); 13705 assertEquals(expectedNumOfNris, nris.size()); 13706 } 13707 13708 @Test 13709 public void testOemNetworkRequestFactoryMultiplePrefsCorrectlySetsUids() 13710 throws Exception { 13711 // Arrange PackageManager mocks 13712 final String testPackageName2 = "com.google.apps.dialer"; 13713 final int testPackageNameUid2 = 456; 13714 mockGetApplicationInfo(TEST_PACKAGE_NAME, TEST_PACKAGE_UID); 13715 mockGetApplicationInfo(testPackageName2, testPackageNameUid2); 13716 13717 // Build OemNetworkPreferences object 13718 final int testOemPref = OEM_NETWORK_PREFERENCE_OEM_PAID; 13719 final int testOemPref2 = OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK; 13720 final OemNetworkPreferences pref = new OemNetworkPreferences.Builder() 13721 .addNetworkPreference(TEST_PACKAGE_NAME, testOemPref) 13722 .addNetworkPreference(testPackageName2, testOemPref2) 13723 .build(); 13724 13725 // Act on OemNetworkRequestFactory.createNrisFromOemNetworkPreferences() 13726 final List<NetworkRequestInfo> nris = 13727 new ArrayList<>( 13728 mService.new OemNetworkRequestFactory().createNrisFromOemNetworkPreferences( 13729 pref)); 13730 13731 // Sort by uid to access nris by index 13732 nris.sort(Comparator.comparingInt(nri -> getNriFirstUidRange(nri).getLower())); 13733 assertEquals(TEST_PACKAGE_UID, (int) getNriFirstUidRange(nris.get(0)).getLower()); 13734 assertEquals(TEST_PACKAGE_UID, (int) getNriFirstUidRange(nris.get(0)).getUpper()); 13735 assertEquals(testPackageNameUid2, (int) getNriFirstUidRange(nris.get(1)).getLower()); 13736 assertEquals(testPackageNameUid2, (int) getNriFirstUidRange(nris.get(1)).getUpper()); 13737 } 13738 13739 @Test 13740 public void testOemNetworkRequestFactoryMultipleUsersSetsUids() 13741 throws Exception { 13742 // Arrange users 13743 final int secondUserTestPackageUid = UserHandle.getUid(SECONDARY_USER, TEST_PACKAGE_UID); 13744 final int thirdUserTestPackageUid = UserHandle.getUid(TERTIARY_USER, TEST_PACKAGE_UID); 13745 doReturn(asList(PRIMARY_USER_HANDLE, SECONDARY_USER_HANDLE, TERTIARY_USER_HANDLE)) 13746 .when(mUserManager).getUserHandles(anyBoolean()); 13747 13748 // Arrange PackageManager mocks testing for users who have and don't have a package. 13749 mockGetApplicationInfoThrowsNameNotFound(TEST_PACKAGE_NAME, PRIMARY_USER_HANDLE); 13750 mockGetApplicationInfo(TEST_PACKAGE_NAME, secondUserTestPackageUid, SECONDARY_USER_HANDLE); 13751 mockGetApplicationInfo(TEST_PACKAGE_NAME, thirdUserTestPackageUid, TERTIARY_USER_HANDLE); 13752 13753 // Build OemNetworkPreferences object 13754 final int testOemPref = OEM_NETWORK_PREFERENCE_OEM_PAID; 13755 final OemNetworkPreferences pref = new OemNetworkPreferences.Builder() 13756 .addNetworkPreference(TEST_PACKAGE_NAME, testOemPref) 13757 .build(); 13758 13759 // Act on OemNetworkRequestFactory.createNrisFromOemNetworkPreferences() 13760 final List<NetworkRequestInfo> nris = 13761 new ArrayList<>( 13762 mService.new OemNetworkRequestFactory().createNrisFromOemNetworkPreferences( 13763 pref)); 13764 13765 // UIDs for users with installed packages should be present. 13766 // Three users exist, but only two have the test package installed. 13767 final int expectedUidSize = 2; 13768 final List<Range<Integer>> uids = 13769 new ArrayList<>(nris.get(0).mRequests.get(0).networkCapabilities.getUids()); 13770 assertEquals(expectedUidSize, uids.size()); 13771 13772 // Sort by uid to access nris by index 13773 uids.sort(Comparator.comparingInt(uid -> uid.getLower())); 13774 assertEquals(secondUserTestPackageUid, (int) uids.get(0).getLower()); 13775 assertEquals(secondUserTestPackageUid, (int) uids.get(0).getUpper()); 13776 assertEquals(thirdUserTestPackageUid, (int) uids.get(1).getLower()); 13777 assertEquals(thirdUserTestPackageUid, (int) uids.get(1).getUpper()); 13778 } 13779 13780 @Test 13781 public void testOemNetworkRequestFactoryAddsPackagesToCorrectPreference() 13782 throws Exception { 13783 // Expectations 13784 final int expectedNumOfNris = 1; 13785 final int expectedNumOfAppUids = 2; 13786 13787 // Arrange PackageManager mocks 13788 final String testPackageName2 = "com.google.apps.dialer"; 13789 final int testPackageNameUid2 = 456; 13790 mockGetApplicationInfo(TEST_PACKAGE_NAME, TEST_PACKAGE_UID); 13791 mockGetApplicationInfo(testPackageName2, testPackageNameUid2); 13792 13793 // Build OemNetworkPreferences object 13794 final int testOemPref = OEM_NETWORK_PREFERENCE_OEM_PAID; 13795 final OemNetworkPreferences pref = new OemNetworkPreferences.Builder() 13796 .addNetworkPreference(TEST_PACKAGE_NAME, testOemPref) 13797 .addNetworkPreference(testPackageName2, testOemPref) 13798 .build(); 13799 13800 // Act on OemNetworkRequestFactory.createNrisFromOemNetworkPreferences() 13801 final ArraySet<NetworkRequestInfo> nris = 13802 mService.new OemNetworkRequestFactory().createNrisFromOemNetworkPreferences(pref); 13803 13804 assertEquals(expectedNumOfNris, nris.size()); 13805 assertEquals(expectedNumOfAppUids, 13806 nris.iterator().next().mRequests.get(0).networkCapabilities.getUids().size()); 13807 } 13808 13809 @Test 13810 public void testSetOemNetworkPreferenceNullListenerAndPrefParamThrowsNpe() { 13811 mockHasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, true); 13812 13813 // Act on ConnectivityService.setOemNetworkPreference() 13814 assertThrows(NullPointerException.class, 13815 () -> mService.setOemNetworkPreference( 13816 null, 13817 null)); 13818 } 13819 13820 @Test 13821 public void testSetOemNetworkPreferenceFailsForNonAutomotive() 13822 throws Exception { 13823 mockHasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, false); 13824 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 13825 OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY; 13826 13827 // Act on ConnectivityService.setOemNetworkPreference() 13828 assertThrows(UnsupportedOperationException.class, 13829 () -> mService.setOemNetworkPreference( 13830 createDefaultOemNetworkPreferences(networkPref), 13831 null)); 13832 } 13833 13834 @Test 13835 public void testSetOemNetworkPreferenceFailsForTestRequestWithoutPermission() { 13836 // Calling setOemNetworkPreference() with a test pref requires the permission 13837 // MANAGE_TEST_NETWORKS. 13838 mockHasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, false); 13839 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 13840 OEM_NETWORK_PREFERENCE_TEST; 13841 13842 // Act on ConnectivityService.setOemNetworkPreference() 13843 assertThrows(SecurityException.class, 13844 () -> mService.setOemNetworkPreference( 13845 createDefaultOemNetworkPreferences(networkPref), 13846 null)); 13847 } 13848 13849 @Test 13850 public void testSetOemNetworkPreferenceFailsForInvalidTestRequest() { 13851 assertSetOemNetworkPreferenceFailsForInvalidTestRequest(OEM_NETWORK_PREFERENCE_TEST); 13852 } 13853 13854 @Test 13855 public void testSetOemNetworkPreferenceFailsForInvalidTestOnlyRequest() { 13856 assertSetOemNetworkPreferenceFailsForInvalidTestRequest(OEM_NETWORK_PREFERENCE_TEST_ONLY); 13857 } 13858 13859 private void assertSetOemNetworkPreferenceFailsForInvalidTestRequest( 13860 @OemNetworkPreferences.OemNetworkPreference final int oemNetworkPreferenceForTest) { 13861 mockHasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, true); 13862 final String secondPackage = "does.not.matter"; 13863 13864 // A valid test request would only have a single mapping. 13865 final OemNetworkPreferences pref = new OemNetworkPreferences.Builder() 13866 .addNetworkPreference(TEST_PACKAGE_NAME, oemNetworkPreferenceForTest) 13867 .addNetworkPreference(secondPackage, oemNetworkPreferenceForTest) 13868 .build(); 13869 13870 // Act on ConnectivityService.setOemNetworkPreference() 13871 assertThrows(IllegalArgumentException.class, 13872 () -> mService.setOemNetworkPreference(pref, null)); 13873 } 13874 13875 private void setOemNetworkPreferenceAgentConnected(final int transportType, 13876 final boolean connectAgent) throws Exception { 13877 switch(transportType) { 13878 // Corresponds to a metered cellular network. Will be used for the default network. 13879 case TRANSPORT_CELLULAR: 13880 if (!connectAgent) { 13881 mCellAgent.disconnect(); 13882 break; 13883 } 13884 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 13885 mCellAgent.removeCapability(NET_CAPABILITY_NOT_METERED); 13886 mCellAgent.connect(true); 13887 break; 13888 // Corresponds to a restricted ethernet network with OEM_PAID/OEM_PRIVATE. 13889 case TRANSPORT_ETHERNET: 13890 if (!connectAgent) { 13891 stopOemManagedNetwork(); 13892 break; 13893 } 13894 startOemManagedNetwork(true); 13895 break; 13896 // Corresponds to unmetered Wi-Fi. 13897 case TRANSPORT_WIFI: 13898 if (!connectAgent) { 13899 mWiFiAgent.disconnect(); 13900 break; 13901 } 13902 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 13903 mWiFiAgent.addCapability(NET_CAPABILITY_NOT_METERED); 13904 mWiFiAgent.connect(true); 13905 break; 13906 default: 13907 throw new AssertionError("Unsupported transport type passed in."); 13908 13909 } 13910 waitForIdle(); 13911 } 13912 13913 private void startOemManagedNetwork(final boolean isOemPaid) throws Exception { 13914 mEthernetAgent = new TestNetworkAgentWrapper(TRANSPORT_ETHERNET); 13915 mEthernetAgent.addCapability( 13916 isOemPaid ? NET_CAPABILITY_OEM_PAID : NET_CAPABILITY_OEM_PRIVATE); 13917 mEthernetAgent.removeCapability(NET_CAPABILITY_NOT_RESTRICTED); 13918 mEthernetAgent.connect(true); 13919 } 13920 13921 private void stopOemManagedNetwork() { 13922 mEthernetAgent.disconnect(); 13923 waitForIdle(); 13924 } 13925 13926 private void verifyMultipleDefaultNetworksTracksCorrectly( 13927 final int expectedOemRequestsSize, 13928 @NonNull final Network expectedDefaultNetwork, 13929 @NonNull final Network expectedPerAppNetwork) { 13930 // The current test setup assumes two tracked default network requests; one for the default 13931 // network and the other for the OEM network preference being tested. This will be validated 13932 // each time to confirm it doesn't change under test. 13933 final int expectedDefaultNetworkRequestsSize = 2; 13934 assertEquals(expectedDefaultNetworkRequestsSize, mService.mDefaultNetworkRequests.size()); 13935 for (final NetworkRequestInfo defaultRequest : mService.mDefaultNetworkRequests) { 13936 final Network defaultNetwork = defaultRequest.getSatisfier() == null 13937 ? null : defaultRequest.getSatisfier().network(); 13938 // If this is the default request. 13939 if (defaultRequest == mService.mDefaultRequest) { 13940 assertEquals( 13941 expectedDefaultNetwork, 13942 defaultNetwork); 13943 // Make sure this value doesn't change. 13944 assertEquals(1, defaultRequest.mRequests.size()); 13945 continue; 13946 } 13947 assertEquals(expectedPerAppNetwork, defaultNetwork); 13948 assertEquals(expectedOemRequestsSize, defaultRequest.mRequests.size()); 13949 } 13950 verifyMultipleDefaultCallbacks(expectedDefaultNetwork, expectedPerAppNetwork); 13951 } 13952 13953 /** 13954 * Verify default callbacks for 'available' fire as expected. This will only run if 13955 * registerDefaultNetworkCallbacks() was executed prior and will only be different if the 13956 * setOemNetworkPreference() per-app API was used for the current process. 13957 * @param expectedSystemDefault the expected network for the system default. 13958 * @param expectedPerAppDefault the expected network for the current process's default. 13959 */ 13960 private void verifyMultipleDefaultCallbacks( 13961 @NonNull final Network expectedSystemDefault, 13962 @NonNull final Network expectedPerAppDefault) { 13963 if (null != mSystemDefaultNetworkCallback && null != expectedSystemDefault 13964 && mService.mNoServiceNetwork.network() != expectedSystemDefault) { 13965 // getLastAvailableNetwork() is used as this method can be called successively with 13966 // the same network to validate therefore expectAvailableThenValidatedCallbacks 13967 // can't be used. 13968 assertEquals(mSystemDefaultNetworkCallback.getLastAvailableNetwork(), 13969 expectedSystemDefault); 13970 } 13971 if (null != mDefaultNetworkCallback && null != expectedPerAppDefault 13972 && mService.mNoServiceNetwork.network() != expectedPerAppDefault) { 13973 assertEquals(mDefaultNetworkCallback.getLastAvailableNetwork(), 13974 expectedPerAppDefault); 13975 } 13976 } 13977 13978 private void registerDefaultNetworkCallbacks() { 13979 if (mSystemDefaultNetworkCallback != null || mDefaultNetworkCallback != null 13980 || mProfileDefaultNetworkCallback != null 13981 || mProfileDefaultNetworkCallbackAsAppUid2 != null 13982 || mTestPackageDefaultNetworkCallback2 != null 13983 || mTestPackageDefaultNetworkCallback != null) { 13984 throw new IllegalStateException("Default network callbacks already registered"); 13985 } 13986 13987 mSystemDefaultNetworkCallback = new TestNetworkCallback(); 13988 mDefaultNetworkCallback = new TestNetworkCallback(); 13989 mProfileDefaultNetworkCallback = new TestNetworkCallback(); 13990 mTestPackageDefaultNetworkCallback = new TestNetworkCallback(); 13991 mProfileDefaultNetworkCallbackAsAppUid2 = new TestNetworkCallback(); 13992 mTestPackageDefaultNetworkCallback2 = new TestNetworkCallback(); 13993 mCm.registerSystemDefaultNetworkCallback(mSystemDefaultNetworkCallback, 13994 new Handler(ConnectivityThread.getInstanceLooper())); 13995 mCm.registerDefaultNetworkCallback(mDefaultNetworkCallback); 13996 registerDefaultNetworkCallbackAsUid(mProfileDefaultNetworkCallback, 13997 TEST_WORK_PROFILE_APP_UID); 13998 registerDefaultNetworkCallbackAsUid(mTestPackageDefaultNetworkCallback, TEST_PACKAGE_UID); 13999 registerDefaultNetworkCallbackAsUid(mProfileDefaultNetworkCallbackAsAppUid2, 14000 TEST_WORK_PROFILE_APP_UID_2); 14001 registerDefaultNetworkCallbackAsUid(mTestPackageDefaultNetworkCallback2, 14002 TEST_PACKAGE_UID2); 14003 // TODO: test using ConnectivityManager#registerDefaultNetworkCallbackAsUid as well. 14004 mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_DENIED); 14005 } 14006 14007 private void unregisterDefaultNetworkCallbacks() { 14008 if (null != mDefaultNetworkCallback) { 14009 mCm.unregisterNetworkCallback(mDefaultNetworkCallback); 14010 } 14011 if (null != mSystemDefaultNetworkCallback) { 14012 mCm.unregisterNetworkCallback(mSystemDefaultNetworkCallback); 14013 } 14014 if (null != mProfileDefaultNetworkCallback) { 14015 mCm.unregisterNetworkCallback(mProfileDefaultNetworkCallback); 14016 } 14017 if (null != mTestPackageDefaultNetworkCallback) { 14018 mCm.unregisterNetworkCallback(mTestPackageDefaultNetworkCallback); 14019 } 14020 if (null != mProfileDefaultNetworkCallbackAsAppUid2) { 14021 mCm.unregisterNetworkCallback(mProfileDefaultNetworkCallbackAsAppUid2); 14022 } 14023 if (null != mTestPackageDefaultNetworkCallback2) { 14024 mCm.unregisterNetworkCallback(mTestPackageDefaultNetworkCallback2); 14025 } 14026 mSystemDefaultNetworkCallback = null; 14027 mDefaultNetworkCallback = null; 14028 mProfileDefaultNetworkCallback = null; 14029 mTestPackageDefaultNetworkCallback = null; 14030 mProfileDefaultNetworkCallbackAsAppUid2 = null; 14031 mTestPackageDefaultNetworkCallback2 = null; 14032 } 14033 14034 private void setupMultipleDefaultNetworksForOemNetworkPreferenceNotCurrentUidTest( 14035 @OemNetworkPreferences.OemNetworkPreference final int networkPrefToSetup) 14036 throws Exception { 14037 final int testPackageNameUid = TEST_PACKAGE_UID; 14038 final String testPackageName = "per.app.defaults.package"; 14039 setupMultipleDefaultNetworksForOemNetworkPreferenceTest( 14040 networkPrefToSetup, testPackageNameUid, testPackageName); 14041 } 14042 14043 private void setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest( 14044 @OemNetworkPreferences.OemNetworkPreference final int networkPrefToSetup) 14045 throws Exception { 14046 final int testPackageNameUid = Process.myUid(); 14047 final String testPackageName = "per.app.defaults.package"; 14048 setupMultipleDefaultNetworksForOemNetworkPreferenceTest( 14049 networkPrefToSetup, testPackageNameUid, testPackageName); 14050 } 14051 14052 private void setupMultipleDefaultNetworksForOemNetworkPreferenceTest( 14053 @OemNetworkPreferences.OemNetworkPreference final int networkPrefToSetup, 14054 final int testPackageUid, @NonNull final String testPackageName) throws Exception { 14055 // Only the default request should be included at start. 14056 assertEquals(1, mService.mDefaultNetworkRequests.size()); 14057 14058 final UidRangeParcel[] uidRanges = 14059 toUidRangeStableParcels(uidRangesForUids(testPackageUid)); 14060 setupSetOemNetworkPreferenceForPreferenceTest( 14061 networkPrefToSetup, uidRanges, testPackageName); 14062 } 14063 14064 private void setupSetOemNetworkPreferenceForPreferenceTest( 14065 @OemNetworkPreferences.OemNetworkPreference final int networkPrefToSetup, 14066 @NonNull final UidRangeParcel[] uidRanges, 14067 @NonNull final String testPackageName) throws Exception { 14068 setupSetOemNetworkPreferenceForPreferenceTest(networkPrefToSetup, uidRanges, 14069 testPackageName, PRIMARY_USER_HANDLE, true /* hasAutomotiveFeature */); 14070 } 14071 14072 private void setupSetOemNetworkPreferenceForPreferenceTest( 14073 @OemNetworkPreferences.OemNetworkPreference final int networkPrefToSetup, 14074 @NonNull final UidRangeParcel[] uidRanges, 14075 @NonNull final String testPackageName, 14076 @NonNull final UserHandle user) throws Exception { 14077 setupSetOemNetworkPreferenceForPreferenceTest(networkPrefToSetup, uidRanges, 14078 testPackageName, user, true /* hasAutomotiveFeature */); 14079 } 14080 14081 private void setupSetOemNetworkPreferenceForPreferenceTest( 14082 @OemNetworkPreferences.OemNetworkPreference final int networkPrefToSetup, 14083 @NonNull final UidRangeParcel[] uidRanges, 14084 @NonNull final String testPackageName, 14085 @NonNull final UserHandle user, 14086 final boolean hasAutomotiveFeature) throws Exception { 14087 mockHasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, hasAutomotiveFeature); 14088 14089 // These tests work off a single UID therefore using 'start' is valid. 14090 mockGetApplicationInfo(testPackageName, uidRanges[0].start, user); 14091 14092 setOemNetworkPreference(networkPrefToSetup, testPackageName); 14093 } 14094 14095 private void setOemNetworkPreference(final int networkPrefToSetup, 14096 @NonNull final String... testPackageNames) 14097 throws Exception { 14098 mockHasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, true); 14099 14100 // Build OemNetworkPreferences object 14101 final OemNetworkPreferences.Builder builder = new OemNetworkPreferences.Builder(); 14102 for (final String packageName : testPackageNames) { 14103 builder.addNetworkPreference(packageName, networkPrefToSetup); 14104 } 14105 final OemNetworkPreferences pref = builder.build(); 14106 14107 // Act on ConnectivityService.setOemNetworkPreference() 14108 final TestOemListenerCallback oemPrefListener = new TestOemListenerCallback(); 14109 mService.setOemNetworkPreference(pref, oemPrefListener); 14110 14111 // Verify call returned successfully 14112 oemPrefListener.expectOnComplete(); 14113 } 14114 14115 private static class TestOemListenerCallback implements IOnCompleteListener { 14116 final CompletableFuture<Object> mDone = new CompletableFuture<>(); 14117 14118 @Override 14119 public void onComplete() { 14120 mDone.complete(new Object()); 14121 } 14122 14123 void expectOnComplete() { 14124 try { 14125 mDone.get(TIMEOUT_MS, TimeUnit.MILLISECONDS); 14126 } catch (TimeoutException e) { 14127 fail("Expected onComplete() not received after " + TIMEOUT_MS + " ms"); 14128 } catch (Exception e) { 14129 fail(e.getMessage()); 14130 } 14131 } 14132 14133 @Override 14134 public IBinder asBinder() { 14135 return null; 14136 } 14137 } 14138 14139 @Test 14140 public void testMultiDefaultGetActiveNetworkIsCorrect() throws Exception { 14141 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 14142 OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY; 14143 final int expectedOemPrefRequestSize = 1; 14144 registerDefaultNetworkCallbacks(); 14145 14146 // Setup the test process to use networkPref for their default network. 14147 setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest(networkPref); 14148 14149 // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID. 14150 // The active network for the default should be null at this point as this is a retricted 14151 // network. 14152 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true); 14153 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 14154 null, 14155 mEthernetAgent.getNetwork()); 14156 14157 // Verify that the active network is correct 14158 verifyActiveNetwork(TRANSPORT_ETHERNET); 14159 // default NCs will be unregistered in tearDown 14160 } 14161 14162 @Test 14163 public void testMultiDefaultIsActiveNetworkMeteredIsCorrect() throws Exception { 14164 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 14165 OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY; 14166 final int expectedOemPrefRequestSize = 1; 14167 registerDefaultNetworkCallbacks(); 14168 14169 // Setup the test process to use networkPref for their default network. 14170 setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest(networkPref); 14171 14172 // Returns true by default when no network is available. 14173 assertTrue(mCm.isActiveNetworkMetered()); 14174 14175 // Connect to an unmetered restricted network that will only be available to the OEM pref. 14176 mEthernetAgent = new TestNetworkAgentWrapper(TRANSPORT_ETHERNET); 14177 mEthernetAgent.addCapability(NET_CAPABILITY_OEM_PAID); 14178 mEthernetAgent.addCapability(NET_CAPABILITY_NOT_METERED); 14179 mEthernetAgent.removeCapability(NET_CAPABILITY_NOT_RESTRICTED); 14180 mEthernetAgent.connect(true); 14181 waitForIdle(); 14182 14183 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 14184 null, 14185 mEthernetAgent.getNetwork()); 14186 14187 assertFalse(mCm.isActiveNetworkMetered()); 14188 // default NCs will be unregistered in tearDown 14189 } 14190 14191 @Test 14192 public void testPerAppDefaultRegisterDefaultNetworkCallback() throws Exception { 14193 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 14194 OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY; 14195 final int expectedOemPrefRequestSize = 1; 14196 final TestNetworkCallback defaultNetworkCallback = new TestNetworkCallback(); 14197 14198 // Register the default network callback before the pref is already set. This means that 14199 // the policy will be applied to the callback on setOemNetworkPreference(). 14200 mCm.registerDefaultNetworkCallback(defaultNetworkCallback); 14201 defaultNetworkCallback.assertNoCallback(); 14202 14203 final TestNetworkCallback otherUidDefaultCallback = new TestNetworkCallback(); 14204 withPermission(NETWORK_SETTINGS, () -> 14205 mCm.registerDefaultNetworkCallbackForUid(TEST_PACKAGE_UID, otherUidDefaultCallback, 14206 new Handler(ConnectivityThread.getInstanceLooper()))); 14207 14208 // Setup the test process to use networkPref for their default network. 14209 setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest(networkPref); 14210 14211 // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID. 14212 // The active nai for the default is null at this point as this is a restricted network. 14213 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true); 14214 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 14215 null, 14216 mEthernetAgent.getNetwork()); 14217 14218 // At this point with a restricted network used, the available callback should trigger. 14219 defaultNetworkCallback.expectAvailableThenValidatedCallbacks(mEthernetAgent); 14220 assertEquals(defaultNetworkCallback.getLastAvailableNetwork(), mEthernetAgent.getNetwork()); 14221 otherUidDefaultCallback.assertNoCallback(); 14222 14223 // Now bring down the default network which should trigger a LOST callback. 14224 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, false); 14225 14226 // At this point, with no network is available, the lost callback should trigger 14227 defaultNetworkCallback.expect(LOST, mEthernetAgent); 14228 otherUidDefaultCallback.assertNoCallback(); 14229 14230 // Confirm we can unregister without issues. 14231 mCm.unregisterNetworkCallback(defaultNetworkCallback); 14232 mCm.unregisterNetworkCallback(otherUidDefaultCallback); 14233 } 14234 14235 @Test 14236 public void testPerAppDefaultRegisterDefaultNetworkCallbackAfterPrefSet() throws Exception { 14237 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 14238 OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY; 14239 final int expectedOemPrefRequestSize = 1; 14240 final TestNetworkCallback defaultNetworkCallback = new TestNetworkCallback(); 14241 14242 // Setup the test process to use networkPref for their default network. 14243 setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest(networkPref); 14244 14245 // Register the default network callback after the pref is already set. This means that 14246 // the policy will be applied to the callback on requestNetwork(). 14247 mCm.registerDefaultNetworkCallback(defaultNetworkCallback); 14248 defaultNetworkCallback.assertNoCallback(); 14249 14250 final TestNetworkCallback otherUidDefaultCallback = new TestNetworkCallback(); 14251 withPermission(NETWORK_SETTINGS, () -> 14252 mCm.registerDefaultNetworkCallbackForUid(TEST_PACKAGE_UID, otherUidDefaultCallback, 14253 new Handler(ConnectivityThread.getInstanceLooper()))); 14254 14255 // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID. 14256 // The active nai for the default is null at this point as this is a restricted network. 14257 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true); 14258 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 14259 null, 14260 mEthernetAgent.getNetwork()); 14261 14262 // At this point with a restricted network used, the available callback should trigger 14263 defaultNetworkCallback.expectAvailableThenValidatedCallbacks(mEthernetAgent); 14264 assertEquals(defaultNetworkCallback.getLastAvailableNetwork(), mEthernetAgent.getNetwork()); 14265 otherUidDefaultCallback.assertNoCallback(); 14266 14267 // Now bring down the default network which should trigger a LOST callback. 14268 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, false); 14269 otherUidDefaultCallback.assertNoCallback(); 14270 14271 // At this point, with no network is available, the lost callback should trigger 14272 defaultNetworkCallback.expect(LOST, mEthernetAgent); 14273 otherUidDefaultCallback.assertNoCallback(); 14274 14275 // Confirm we can unregister without issues. 14276 mCm.unregisterNetworkCallback(defaultNetworkCallback); 14277 mCm.unregisterNetworkCallback(otherUidDefaultCallback); 14278 } 14279 14280 @Test 14281 public void testPerAppDefaultRegisterDefaultNetworkCallbackDoesNotFire() throws Exception { 14282 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 14283 OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY; 14284 final int expectedOemPrefRequestSize = 1; 14285 final TestNetworkCallback defaultNetworkCallback = new TestNetworkCallback(); 14286 final int userId = UserHandle.getUserId(Process.myUid()); 14287 14288 mCm.registerDefaultNetworkCallback(defaultNetworkCallback); 14289 defaultNetworkCallback.assertNoCallback(); 14290 14291 final TestNetworkCallback otherUidDefaultCallback = new TestNetworkCallback(); 14292 withPermission(NETWORK_SETTINGS, () -> 14293 mCm.registerDefaultNetworkCallbackForUid(TEST_PACKAGE_UID, otherUidDefaultCallback, 14294 new Handler(ConnectivityThread.getInstanceLooper()))); 14295 14296 // Setup a process different than the test process to use the default network. This means 14297 // that the defaultNetworkCallback won't be tracked by the per-app policy. 14298 setupMultipleDefaultNetworksForOemNetworkPreferenceNotCurrentUidTest(networkPref); 14299 14300 // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID. 14301 // The active nai for the default is null at this point as this is a restricted network. 14302 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true); 14303 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 14304 null, 14305 mEthernetAgent.getNetwork()); 14306 14307 // As this callback does not have access to the OEM_PAID network, it will not fire. 14308 defaultNetworkCallback.assertNoCallback(); 14309 assertDefaultNetworkCapabilities(userId /* no networks */); 14310 14311 // The other UID does have access, and gets a callback. 14312 otherUidDefaultCallback.expectAvailableThenValidatedCallbacks(mEthernetAgent); 14313 14314 // Bring up unrestricted cellular. This should now satisfy the default network. 14315 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); 14316 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 14317 mCellAgent.getNetwork(), 14318 mEthernetAgent.getNetwork()); 14319 14320 // At this point with an unrestricted network used, the available callback should trigger 14321 // The other UID is unaffected and remains on the paid network. 14322 defaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 14323 assertEquals(defaultNetworkCallback.getLastAvailableNetwork(), mCellAgent.getNetwork()); 14324 assertDefaultNetworkCapabilities(userId, mCellAgent); 14325 otherUidDefaultCallback.assertNoCallback(); 14326 14327 // Now bring down the per-app network. 14328 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, false); 14329 14330 // Since the callback didn't use the per-app network, only the other UID gets a callback. 14331 // Because the preference specifies no fallback, it does not switch to cellular. 14332 defaultNetworkCallback.assertNoCallback(); 14333 otherUidDefaultCallback.expect(LOST, mEthernetAgent); 14334 14335 // Now bring down the default network. 14336 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, false); 14337 14338 // As this callback was tracking the default, this should now trigger. 14339 defaultNetworkCallback.expect(LOST, mCellAgent); 14340 otherUidDefaultCallback.assertNoCallback(); 14341 14342 // Confirm we can unregister without issues. 14343 mCm.unregisterNetworkCallback(defaultNetworkCallback); 14344 mCm.unregisterNetworkCallback(otherUidDefaultCallback); 14345 } 14346 14347 /** 14348 * This method assumes that the same uidRanges input will be used to verify that dependencies 14349 * are called as expected. 14350 */ 14351 private void verifySetOemNetworkPreferenceForPreference( 14352 @NonNull final UidRangeParcel[] uidRanges, 14353 final int addUidRangesNetId, 14354 final int addUidRangesTimes, 14355 final int removeUidRangesNetId, 14356 final int removeUidRangesTimes, 14357 final boolean shouldDestroyNetwork) throws RemoteException { 14358 verifySetOemNetworkPreferenceForPreference(uidRanges, uidRanges, 14359 addUidRangesNetId, addUidRangesTimes, removeUidRangesNetId, removeUidRangesTimes, 14360 shouldDestroyNetwork); 14361 } 14362 14363 private void verifySetOemNetworkPreferenceForPreference( 14364 @NonNull final UidRangeParcel[] addedUidRanges, 14365 @NonNull final UidRangeParcel[] removedUidRanges, 14366 final int addUidRangesNetId, 14367 final int addUidRangesTimes, 14368 final int removeUidRangesNetId, 14369 final int removeUidRangesTimes, 14370 final boolean shouldDestroyNetwork) throws RemoteException { 14371 final boolean useAnyIdForAdd = OEM_PREF_ANY_NET_ID == addUidRangesNetId; 14372 final boolean useAnyIdForRemove = OEM_PREF_ANY_NET_ID == removeUidRangesNetId; 14373 14374 // Validate that add/remove uid range (with oem priority) to/from netd. 14375 verify(mMockNetd, times(addUidRangesTimes)).networkAddUidRangesParcel(argThat(config -> 14376 (useAnyIdForAdd ? true : addUidRangesNetId == config.netId) 14377 && Arrays.equals(addedUidRanges, config.uidRanges) 14378 && PREFERENCE_ORDER_OEM == config.subPriority)); 14379 verify(mMockNetd, times(removeUidRangesTimes)).networkRemoveUidRangesParcel( 14380 argThat(config -> (useAnyIdForRemove ? true : removeUidRangesNetId == config.netId) 14381 && Arrays.equals(removedUidRanges, config.uidRanges) 14382 && PREFERENCE_ORDER_OEM == config.subPriority)); 14383 if (shouldDestroyNetwork) { 14384 verify(mMockNetd, times(1)) 14385 .networkDestroy((useAnyIdForRemove ? anyInt() : eq(removeUidRangesNetId))); 14386 } 14387 reset(mMockNetd); 14388 } 14389 14390 /** 14391 * Test the tracked default requests allows test requests without standard setup. 14392 */ 14393 @Test 14394 public void testSetOemNetworkPreferenceAllowsValidTestRequestWithoutChecks() throws Exception { 14395 @OemNetworkPreferences.OemNetworkPreference int networkPref = 14396 OEM_NETWORK_PREFERENCE_TEST; 14397 validateSetOemNetworkPreferenceAllowsValidTestPrefRequest(networkPref); 14398 } 14399 14400 /** 14401 * Test the tracked default requests allows test only requests without standard setup. 14402 */ 14403 @Test 14404 public void testSetOemNetworkPreferenceAllowsValidTestOnlyRequestWithoutChecks() 14405 throws Exception { 14406 @OemNetworkPreferences.OemNetworkPreference int networkPref = 14407 OEM_NETWORK_PREFERENCE_TEST_ONLY; 14408 validateSetOemNetworkPreferenceAllowsValidTestPrefRequest(networkPref); 14409 } 14410 14411 private void validateSetOemNetworkPreferenceAllowsValidTestPrefRequest(int networkPref) 14412 throws Exception { 14413 // The caller must have the MANAGE_TEST_NETWORKS permission. 14414 final int testPackageUid = 123; 14415 final String validTestPackageName = "does.not.matter"; 14416 final UidRangeParcel[] uidRanges = 14417 toUidRangeStableParcels(uidRangesForUids(testPackageUid)); 14418 mServiceContext.setPermission( 14419 Manifest.permission.MANAGE_TEST_NETWORKS, PERMISSION_GRANTED); 14420 14421 // Put the system into a state in which setOemNetworkPreference() would normally fail. This 14422 // will confirm that a valid test request can bypass these checks. 14423 mockHasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, false); 14424 mServiceContext.setPermission( 14425 Manifest.permission.CONTROL_OEM_PAID_NETWORK_PREFERENCE, PERMISSION_DENIED); 14426 14427 // Validate the starting requests only includes the system default request. 14428 assertEquals(1, mService.mDefaultNetworkRequests.size()); 14429 14430 // Add an OEM default network request to track. 14431 setupSetOemNetworkPreferenceForPreferenceTest( 14432 networkPref, uidRanges, validTestPackageName, PRIMARY_USER_HANDLE, 14433 false /* hasAutomotiveFeature */); 14434 14435 // Two requests should now exist; the system default and the test request. 14436 assertEquals(2, mService.mDefaultNetworkRequests.size()); 14437 } 14438 14439 /** 14440 * Test the tracked default requests clear previous OEM requests on setOemNetworkPreference(). 14441 */ 14442 @Test 14443 public void testSetOemNetworkPreferenceClearPreviousOemValues() throws Exception { 14444 @OemNetworkPreferences.OemNetworkPreference int networkPref = 14445 OEM_NETWORK_PREFERENCE_OEM_PAID; 14446 final int testPackageUid = 123; 14447 final String testPackageName = "com.google.apps.contacts"; 14448 final UidRangeParcel[] uidRanges = 14449 toUidRangeStableParcels(uidRangesForUids(testPackageUid)); 14450 14451 // Validate the starting requests only includes the system default request. 14452 assertEquals(1, mService.mDefaultNetworkRequests.size()); 14453 14454 // Add an OEM default network request to track. 14455 setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges, testPackageName); 14456 14457 // Two requests should exist, one for the fallback and one for the pref. 14458 assertEquals(2, mService.mDefaultNetworkRequests.size()); 14459 14460 networkPref = OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY; 14461 setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges, testPackageName); 14462 14463 // Two requests should still exist validating the previous per-app request was replaced. 14464 assertEquals(2, mService.mDefaultNetworkRequests.size()); 14465 } 14466 14467 /** 14468 * Test network priority for preference OEM_NETWORK_PREFERENCE_OEM_PAID in the following order: 14469 * NET_CAPABILITY_NOT_METERED -> NET_CAPABILITY_OEM_PAID -> fallback 14470 */ 14471 @Test 14472 public void testMultilayerForPreferenceOemPaidEvaluatesCorrectly() 14473 throws Exception { 14474 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 14475 OEM_NETWORK_PREFERENCE_OEM_PAID; 14476 14477 // Arrange PackageManager mocks 14478 final UidRangeParcel[] uidRanges = 14479 toUidRangeStableParcels(uidRangesForUids(TEST_PACKAGE_UID)); 14480 setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges, TEST_PACKAGE_NAME); 14481 14482 // Verify the starting state. No networks should be connected. 14483 verifySetOemNetworkPreferenceForPreference(uidRanges, 14484 OEM_PREF_ANY_NET_ID, 0 /* times */, 14485 OEM_PREF_ANY_NET_ID, 0 /* times */, 14486 false /* shouldDestroyNetwork */); 14487 14488 // Test lowest to highest priority requests. 14489 // Bring up metered cellular. This will satisfy the fallback network. 14490 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); 14491 verifySetOemNetworkPreferenceForPreference(uidRanges, 14492 mCellAgent.getNetwork().netId, 1 /* times */, 14493 OEM_PREF_ANY_NET_ID, 0 /* times */, 14494 false /* shouldDestroyNetwork */); 14495 14496 // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID. 14497 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true); 14498 verifySetOemNetworkPreferenceForPreference(uidRanges, 14499 mEthernetAgent.getNetwork().netId, 1 /* times */, 14500 mCellAgent.getNetwork().netId, 1 /* times */, 14501 false /* shouldDestroyNetwork */); 14502 14503 // Bring up unmetered Wi-Fi. This will satisfy NET_CAPABILITY_NOT_METERED. 14504 setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, true); 14505 verifySetOemNetworkPreferenceForPreference(uidRanges, 14506 mWiFiAgent.getNetwork().netId, 1 /* times */, 14507 mEthernetAgent.getNetwork().netId, 1 /* times */, 14508 false /* shouldDestroyNetwork */); 14509 14510 // Disconnecting OEM_PAID should have no effect as it is lower in priority then unmetered. 14511 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, false); 14512 // netd should not be called as default networks haven't changed. 14513 verifySetOemNetworkPreferenceForPreference(uidRanges, 14514 OEM_PREF_ANY_NET_ID, 0 /* times */, 14515 OEM_PREF_ANY_NET_ID, 0 /* times */, 14516 false /* shouldDestroyNetwork */); 14517 14518 // Disconnecting unmetered should put PANS on lowest priority fallback request. 14519 setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, false); 14520 verifySetOemNetworkPreferenceForPreference(uidRanges, 14521 mCellAgent.getNetwork().netId, 1 /* times */, 14522 mWiFiAgent.getNetwork().netId, 0 /* times */, 14523 true /* shouldDestroyNetwork */); 14524 14525 // Disconnecting the fallback network should result in no connectivity. 14526 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, false); 14527 verifySetOemNetworkPreferenceForPreference(uidRanges, 14528 OEM_PREF_ANY_NET_ID, 0 /* times */, 14529 mCellAgent.getNetwork().netId, 0 /* times */, 14530 true /* shouldDestroyNetwork */); 14531 } 14532 14533 /** 14534 * Test network priority for OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK in the following order: 14535 * NET_CAPABILITY_NOT_METERED -> NET_CAPABILITY_OEM_PAID 14536 */ 14537 @Test 14538 public void testMultilayerForPreferenceOemPaidNoFallbackEvaluatesCorrectly() 14539 throws Exception { 14540 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 14541 OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK; 14542 14543 // Arrange PackageManager mocks 14544 final UidRangeParcel[] uidRanges = 14545 toUidRangeStableParcels(uidRangesForUids(TEST_PACKAGE_UID)); 14546 setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges, TEST_PACKAGE_NAME); 14547 14548 // Verify the starting state. This preference doesn't support using the fallback network 14549 // therefore should be on the disconnected network as it has no networks to connect to. 14550 verifySetOemNetworkPreferenceForPreference(uidRanges, 14551 mService.mNoServiceNetwork.network.getNetId(), 1 /* times */, 14552 OEM_PREF_ANY_NET_ID, 0 /* times */, 14553 false /* shouldDestroyNetwork */); 14554 14555 // Test lowest to highest priority requests. 14556 // Bring up metered cellular. This will satisfy the fallback network. 14557 // This preference should not use this network as it doesn't support fallback usage. 14558 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); 14559 verifySetOemNetworkPreferenceForPreference(uidRanges, 14560 OEM_PREF_ANY_NET_ID, 0 /* times */, 14561 OEM_PREF_ANY_NET_ID, 0 /* times */, 14562 false /* shouldDestroyNetwork */); 14563 14564 // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID. 14565 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true); 14566 verifySetOemNetworkPreferenceForPreference(uidRanges, 14567 mEthernetAgent.getNetwork().netId, 1 /* times */, 14568 mService.mNoServiceNetwork.network.getNetId(), 1 /* times */, 14569 false /* shouldDestroyNetwork */); 14570 14571 // Bring up unmetered Wi-Fi. This will satisfy NET_CAPABILITY_NOT_METERED. 14572 setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, true); 14573 verifySetOemNetworkPreferenceForPreference(uidRanges, 14574 mWiFiAgent.getNetwork().netId, 1 /* times */, 14575 mEthernetAgent.getNetwork().netId, 1 /* times */, 14576 false /* shouldDestroyNetwork */); 14577 14578 // Disconnecting unmetered should put PANS on OEM_PAID. 14579 setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, false); 14580 verifySetOemNetworkPreferenceForPreference(uidRanges, 14581 mEthernetAgent.getNetwork().netId, 1 /* times */, 14582 mWiFiAgent.getNetwork().netId, 0 /* times */, 14583 true /* shouldDestroyNetwork */); 14584 14585 // Disconnecting OEM_PAID should result in no connectivity. 14586 // OEM_PAID_NO_FALLBACK not supporting a fallback now uses the disconnected network. 14587 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, false); 14588 verifySetOemNetworkPreferenceForPreference(uidRanges, 14589 mService.mNoServiceNetwork.network.getNetId(), 1 /* times */, 14590 mEthernetAgent.getNetwork().netId, 0 /* times */, 14591 true /* shouldDestroyNetwork */); 14592 } 14593 14594 /** 14595 * Test network priority for OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY in the following order: 14596 * NET_CAPABILITY_OEM_PAID 14597 * This preference should only apply to OEM_PAID networks. 14598 */ 14599 @Test 14600 public void testMultilayerForPreferenceOemPaidOnlyEvaluatesCorrectly() 14601 throws Exception { 14602 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 14603 OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY; 14604 14605 // Arrange PackageManager mocks 14606 final UidRangeParcel[] uidRanges = 14607 toUidRangeStableParcels(uidRangesForUids(TEST_PACKAGE_UID)); 14608 setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges, TEST_PACKAGE_NAME); 14609 14610 // Verify the starting state. This preference doesn't support using the fallback network 14611 // therefore should be on the disconnected network as it has no networks to connect to. 14612 verifySetOemNetworkPreferenceForPreference(uidRanges, 14613 mService.mNoServiceNetwork.network.getNetId(), 1 /* times */, 14614 OEM_PREF_ANY_NET_ID, 0 /* times */, 14615 false /* shouldDestroyNetwork */); 14616 14617 // Bring up metered cellular. This should not apply to this preference. 14618 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); 14619 verifySetOemNetworkPreferenceForPreference(uidRanges, 14620 OEM_PREF_ANY_NET_ID, 0 /* times */, 14621 OEM_PREF_ANY_NET_ID, 0 /* times */, 14622 false /* shouldDestroyNetwork */); 14623 14624 // Bring up unmetered Wi-Fi. This should not apply to this preference. 14625 setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, true); 14626 verifySetOemNetworkPreferenceForPreference(uidRanges, 14627 OEM_PREF_ANY_NET_ID, 0 /* times */, 14628 OEM_PREF_ANY_NET_ID, 0 /* times */, 14629 false /* shouldDestroyNetwork */); 14630 14631 // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID. 14632 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true); 14633 verifySetOemNetworkPreferenceForPreference(uidRanges, 14634 mEthernetAgent.getNetwork().netId, 1 /* times */, 14635 mService.mNoServiceNetwork.network.getNetId(), 1 /* times */, 14636 false /* shouldDestroyNetwork */); 14637 14638 // Disconnecting OEM_PAID should result in no connectivity. 14639 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, false); 14640 verifySetOemNetworkPreferenceForPreference(uidRanges, 14641 mService.mNoServiceNetwork.network.getNetId(), 1 /* times */, 14642 mEthernetAgent.getNetwork().netId, 0 /* times */, 14643 true /* shouldDestroyNetwork */); 14644 } 14645 14646 /** 14647 * Test network priority for OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY in the following order: 14648 * NET_CAPABILITY_OEM_PRIVATE 14649 * This preference should only apply to OEM_PRIVATE networks. 14650 */ 14651 @Test 14652 public void testMultilayerForPreferenceOemPrivateOnlyEvaluatesCorrectly() 14653 throws Exception { 14654 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 14655 OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY; 14656 14657 // Arrange PackageManager mocks 14658 final UidRangeParcel[] uidRanges = 14659 toUidRangeStableParcels(uidRangesForUids(TEST_PACKAGE_UID)); 14660 setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges, TEST_PACKAGE_NAME); 14661 14662 // Verify the starting state. This preference doesn't support using the fallback network 14663 // therefore should be on the disconnected network as it has no networks to connect to. 14664 verifySetOemNetworkPreferenceForPreference(uidRanges, 14665 mService.mNoServiceNetwork.network.getNetId(), 1 /* times */, 14666 OEM_PREF_ANY_NET_ID, 0 /* times */, 14667 false /* shouldDestroyNetwork */); 14668 14669 // Bring up metered cellular. This should not apply to this preference. 14670 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); 14671 verifySetOemNetworkPreferenceForPreference(uidRanges, 14672 OEM_PREF_ANY_NET_ID, 0 /* times */, 14673 OEM_PREF_ANY_NET_ID, 0 /* times */, 14674 false /* shouldDestroyNetwork */); 14675 14676 // Bring up unmetered Wi-Fi. This should not apply to this preference. 14677 setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, true); 14678 verifySetOemNetworkPreferenceForPreference(uidRanges, 14679 OEM_PREF_ANY_NET_ID, 0 /* times */, 14680 OEM_PREF_ANY_NET_ID, 0 /* times */, 14681 false /* shouldDestroyNetwork */); 14682 14683 // Bring up ethernet with OEM_PRIVATE. This will satisfy NET_CAPABILITY_OEM_PRIVATE. 14684 startOemManagedNetwork(false); 14685 verifySetOemNetworkPreferenceForPreference(uidRanges, 14686 mEthernetAgent.getNetwork().netId, 1 /* times */, 14687 mService.mNoServiceNetwork.network.getNetId(), 1 /* times */, 14688 false /* shouldDestroyNetwork */); 14689 14690 // Disconnecting OEM_PRIVATE should result in no connectivity. 14691 stopOemManagedNetwork(); 14692 verifySetOemNetworkPreferenceForPreference(uidRanges, 14693 mService.mNoServiceNetwork.network.getNetId(), 1 /* times */, 14694 mEthernetAgent.getNetwork().netId, 0 /* times */, 14695 true /* shouldDestroyNetwork */); 14696 } 14697 14698 @Test 14699 public void testMultilayerForMultipleUsersEvaluatesCorrectly() 14700 throws Exception { 14701 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 14702 OEM_NETWORK_PREFERENCE_OEM_PAID; 14703 14704 // Arrange users 14705 final int secondUser = 10; 14706 final UserHandle secondUserHandle = new UserHandle(secondUser); 14707 doReturn(asList(PRIMARY_USER_HANDLE, secondUserHandle)).when(mUserManager) 14708 .getUserHandles(anyBoolean()); 14709 14710 // Arrange PackageManager mocks 14711 final int secondUserTestPackageUid = UserHandle.getUid(secondUser, TEST_PACKAGE_UID); 14712 final UidRangeParcel[] uidRanges = 14713 toUidRangeStableParcels( 14714 uidRangesForUids(TEST_PACKAGE_UID, secondUserTestPackageUid)); 14715 mockGetApplicationInfo(TEST_PACKAGE_NAME, secondUserTestPackageUid, secondUserHandle); 14716 setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges, TEST_PACKAGE_NAME); 14717 14718 // Verify the starting state. No networks should be connected. 14719 verifySetOemNetworkPreferenceForPreference(uidRanges, 14720 OEM_PREF_ANY_NET_ID, 0 /* times */, 14721 OEM_PREF_ANY_NET_ID, 0 /* times */, 14722 false /* shouldDestroyNetwork */); 14723 14724 // Test that we correctly add the expected values for multiple users. 14725 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); 14726 verifySetOemNetworkPreferenceForPreference(uidRanges, 14727 mCellAgent.getNetwork().netId, 1 /* times */, 14728 OEM_PREF_ANY_NET_ID, 0 /* times */, 14729 false /* shouldDestroyNetwork */); 14730 14731 // Test that we correctly remove the expected values for multiple users. 14732 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, false); 14733 verifySetOemNetworkPreferenceForPreference(uidRanges, 14734 OEM_PREF_ANY_NET_ID, 0 /* times */, 14735 mCellAgent.getNetwork().netId, 0 /* times */, 14736 true /* shouldDestroyNetwork */); 14737 } 14738 14739 @Test 14740 public void testMultilayerForBroadcastedUsersEvaluatesCorrectly() 14741 throws Exception { 14742 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 14743 OEM_NETWORK_PREFERENCE_OEM_PAID; 14744 14745 // Arrange users 14746 final int secondUser = 10; 14747 final UserHandle secondUserHandle = new UserHandle(secondUser); 14748 doReturn(asList(PRIMARY_USER_HANDLE)).when(mUserManager).getUserHandles(anyBoolean()); 14749 14750 // Arrange PackageManager mocks 14751 final int secondUserTestPackageUid = UserHandle.getUid(secondUser, TEST_PACKAGE_UID); 14752 final UidRangeParcel[] uidRangesSingleUser = 14753 toUidRangeStableParcels(uidRangesForUids(TEST_PACKAGE_UID)); 14754 final UidRangeParcel[] uidRangesBothUsers = 14755 toUidRangeStableParcels( 14756 uidRangesForUids(TEST_PACKAGE_UID, secondUserTestPackageUid)); 14757 mockGetApplicationInfo(TEST_PACKAGE_NAME, secondUserTestPackageUid, secondUserHandle); 14758 setupSetOemNetworkPreferenceForPreferenceTest( 14759 networkPref, uidRangesSingleUser, TEST_PACKAGE_NAME); 14760 14761 // Verify the starting state. No networks should be connected. 14762 verifySetOemNetworkPreferenceForPreference(uidRangesSingleUser, 14763 OEM_PREF_ANY_NET_ID, 0 /* times */, 14764 OEM_PREF_ANY_NET_ID, 0 /* times */, 14765 false /* shouldDestroyNetwork */); 14766 14767 // Test that we correctly add the expected values for multiple users. 14768 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); 14769 verifySetOemNetworkPreferenceForPreference(uidRangesSingleUser, 14770 mCellAgent.getNetwork().netId, 1 /* times */, 14771 OEM_PREF_ANY_NET_ID, 0 /* times */, 14772 false /* shouldDestroyNetwork */); 14773 14774 // Send a broadcast indicating a user was added. 14775 doReturn(asList(PRIMARY_USER_HANDLE, secondUserHandle)).when(mUserManager) 14776 .getUserHandles(anyBoolean()); 14777 final Intent addedIntent = new Intent(ACTION_USER_ADDED); 14778 addedIntent.putExtra(Intent.EXTRA_USER, UserHandle.of(secondUser)); 14779 processBroadcast(addedIntent); 14780 14781 // Test that we correctly add values for all users and remove for the single user. 14782 verifySetOemNetworkPreferenceForPreference(uidRangesBothUsers, uidRangesSingleUser, 14783 mCellAgent.getNetwork().netId, 1 /* times */, 14784 mCellAgent.getNetwork().netId, 1 /* times */, 14785 false /* shouldDestroyNetwork */); 14786 14787 // Send a broadcast indicating a user was removed. 14788 doReturn(asList(PRIMARY_USER_HANDLE)).when(mUserManager).getUserHandles(anyBoolean()); 14789 final Intent removedIntent = new Intent(ACTION_USER_REMOVED); 14790 removedIntent.putExtra(Intent.EXTRA_USER, UserHandle.of(secondUser)); 14791 processBroadcast(removedIntent); 14792 14793 // Test that we correctly add values for the single user and remove for the all users. 14794 verifySetOemNetworkPreferenceForPreference(uidRangesSingleUser, uidRangesBothUsers, 14795 mCellAgent.getNetwork().netId, 1 /* times */, 14796 mCellAgent.getNetwork().netId, 1 /* times */, 14797 false /* shouldDestroyNetwork */); 14798 } 14799 14800 @Test 14801 public void testMultilayerForPackageChangesEvaluatesCorrectly() 14802 throws Exception { 14803 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 14804 OEM_NETWORK_PREFERENCE_OEM_PAID; 14805 final String packageScheme = "package:"; 14806 14807 // Arrange PackageManager mocks 14808 final String packageToInstall = "package.to.install"; 14809 final int packageToInstallUid = 81387; 14810 final UidRangeParcel[] uidRangesSinglePackage = 14811 toUidRangeStableParcels(uidRangesForUids(TEST_PACKAGE_UID)); 14812 mockGetApplicationInfo(TEST_PACKAGE_NAME, TEST_PACKAGE_UID); 14813 mockGetApplicationInfoThrowsNameNotFound(packageToInstall, PRIMARY_USER_HANDLE); 14814 setOemNetworkPreference(networkPref, TEST_PACKAGE_NAME, packageToInstall); 14815 grantUsingBackgroundNetworksPermissionForUid(Binder.getCallingUid(), packageToInstall); 14816 14817 // Verify the starting state. No networks should be connected. 14818 verifySetOemNetworkPreferenceForPreference(uidRangesSinglePackage, 14819 OEM_PREF_ANY_NET_ID, 0 /* times */, 14820 OEM_PREF_ANY_NET_ID, 0 /* times */, 14821 false /* shouldDestroyNetwork */); 14822 14823 // Test that we correctly add the expected values for installed packages. 14824 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); 14825 verifySetOemNetworkPreferenceForPreference(uidRangesSinglePackage, 14826 mCellAgent.getNetwork().netId, 1 /* times */, 14827 OEM_PREF_ANY_NET_ID, 0 /* times */, 14828 false /* shouldDestroyNetwork */); 14829 14830 // Set the system to recognize the package to be installed 14831 mockGetApplicationInfo(packageToInstall, packageToInstallUid); 14832 final UidRangeParcel[] uidRangesAllPackages = 14833 toUidRangeStableParcels(uidRangesForUids(TEST_PACKAGE_UID, packageToInstallUid)); 14834 14835 // Send a broadcast indicating a package was installed. 14836 final Intent addedIntent = new Intent(ACTION_PACKAGE_ADDED); 14837 addedIntent.setData(Uri.parse(packageScheme + packageToInstall)); 14838 processBroadcast(addedIntent); 14839 14840 // Test the single package is removed and the combined packages are added. 14841 verifySetOemNetworkPreferenceForPreference(uidRangesAllPackages, uidRangesSinglePackage, 14842 mCellAgent.getNetwork().netId, 1 /* times */, 14843 mCellAgent.getNetwork().netId, 1 /* times */, 14844 false /* shouldDestroyNetwork */); 14845 14846 // Set the system to no longer recognize the package to be installed 14847 mockGetApplicationInfoThrowsNameNotFound(packageToInstall, PRIMARY_USER_HANDLE); 14848 14849 // Send a broadcast indicating a package was removed. 14850 final Intent removedIntent = new Intent(ACTION_PACKAGE_REMOVED); 14851 removedIntent.setData(Uri.parse(packageScheme + packageToInstall)); 14852 processBroadcast(removedIntent); 14853 14854 // Test the combined packages are removed and the single package is added. 14855 verifySetOemNetworkPreferenceForPreference(uidRangesSinglePackage, uidRangesAllPackages, 14856 mCellAgent.getNetwork().netId, 1 /* times */, 14857 mCellAgent.getNetwork().netId, 1 /* times */, 14858 false /* shouldDestroyNetwork */); 14859 14860 // Set the system to change the installed package's uid 14861 final int replacedTestPackageUid = TEST_PACKAGE_UID + 1; 14862 mockGetApplicationInfo(TEST_PACKAGE_NAME, replacedTestPackageUid); 14863 final UidRangeParcel[] uidRangesReplacedPackage = 14864 toUidRangeStableParcels(uidRangesForUids(replacedTestPackageUid)); 14865 14866 // Send a broadcast indicating a package was replaced. 14867 final Intent replacedIntent = new Intent(ACTION_PACKAGE_REPLACED); 14868 replacedIntent.setData(Uri.parse(packageScheme + TEST_PACKAGE_NAME)); 14869 processBroadcast(replacedIntent); 14870 14871 // Test the original uid is removed and is replaced with the new uid. 14872 verifySetOemNetworkPreferenceForPreference(uidRangesReplacedPackage, uidRangesSinglePackage, 14873 mCellAgent.getNetwork().netId, 1 /* times */, 14874 mCellAgent.getNetwork().netId, 1 /* times */, 14875 false /* shouldDestroyNetwork */); 14876 } 14877 14878 /** 14879 * Test network priority for preference OEM_NETWORK_PREFERENCE_OEM_PAID in the following order: 14880 * NET_CAPABILITY_NOT_METERED -> NET_CAPABILITY_OEM_PAID -> fallback 14881 */ 14882 @Test 14883 public void testMultipleDefaultNetworksTracksOemNetworkPreferenceOemPaidCorrectly() 14884 throws Exception { 14885 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 14886 OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID; 14887 setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest(networkPref); 14888 final int expectedDefaultRequestSize = 2; 14889 final int expectedOemPrefRequestSize = 3; 14890 registerDefaultNetworkCallbacks(); 14891 14892 // The fallback as well as the OEM preference should now be tracked. 14893 assertEquals(expectedDefaultRequestSize, mService.mDefaultNetworkRequests.size()); 14894 14895 // Test lowest to highest priority requests. 14896 // Bring up metered cellular. This will satisfy the fallback network. 14897 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); 14898 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 14899 mCellAgent.getNetwork(), 14900 mCellAgent.getNetwork()); 14901 14902 // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID. 14903 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true); 14904 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 14905 mCellAgent.getNetwork(), 14906 mEthernetAgent.getNetwork()); 14907 14908 // Bring up unmetered Wi-Fi. This will satisfy NET_CAPABILITY_NOT_METERED. 14909 setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, true); 14910 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 14911 mWiFiAgent.getNetwork(), 14912 mWiFiAgent.getNetwork()); 14913 14914 // Disconnecting unmetered Wi-Fi will put the pref on OEM_PAID and fallback on cellular. 14915 setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, false); 14916 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 14917 mCellAgent.getNetwork(), 14918 mEthernetAgent.getNetwork()); 14919 14920 // Disconnecting cellular should keep OEM network on OEM_PAID and fallback will be null. 14921 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, false); 14922 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 14923 null, 14924 mEthernetAgent.getNetwork()); 14925 14926 // Disconnecting OEM_PAID will put both on null as it is the last network. 14927 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, false); 14928 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 14929 null, 14930 null); 14931 14932 // default callbacks will be unregistered in tearDown 14933 } 14934 14935 @Test 14936 public void testNetworkFactoryRequestsWithMultilayerRequest() 14937 throws Exception { 14938 // First use OEM_PAID preference to create a multi-layer request : 1. listen for 14939 // unmetered, 2. request network with cap OEM_PAID, 3, request the default network for 14940 // fallback. 14941 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 14942 OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID; 14943 setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest(networkPref); 14944 14945 final HandlerThread handlerThread = new HandlerThread("MockFactory"); 14946 handlerThread.start(); 14947 NetworkCapabilities internetFilter = new NetworkCapabilities() 14948 .addCapability(NET_CAPABILITY_INTERNET) 14949 .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED); 14950 final MockNetworkFactory internetFactory = new MockNetworkFactory(handlerThread.getLooper(), 14951 mServiceContext, "internetFactory", internetFilter, mCsHandlerThread); 14952 internetFactory.setScoreFilter(40); 14953 internetFactory.register(); 14954 // Default internet request only. The unmetered request is never sent to factories (it's a 14955 // LISTEN, not requestable). The 3rd (fallback) request in OEM_PAID NRI is TRACK_DEFAULT 14956 // which is also not sent to factories. Finally, the OEM_PAID request doesn't match the 14957 // internetFactory filter. 14958 internetFactory.expectRequestAdds(1); 14959 internetFactory.assertRequestCountEquals(1); 14960 14961 NetworkCapabilities oemPaidFilter = new NetworkCapabilities() 14962 .addCapability(NET_CAPABILITY_INTERNET) 14963 .addCapability(NET_CAPABILITY_OEM_PAID) 14964 .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED) 14965 .removeCapability(NET_CAPABILITY_NOT_RESTRICTED); 14966 final MockNetworkFactory oemPaidFactory = new MockNetworkFactory(handlerThread.getLooper(), 14967 mServiceContext, "oemPaidFactory", oemPaidFilter, mCsHandlerThread); 14968 oemPaidFactory.setScoreFilter(40); 14969 oemPaidFactory.register(); 14970 oemPaidFactory.expectRequestAdd(); // Because nobody satisfies the request 14971 14972 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 14973 mCellAgent.connect(true); 14974 14975 // A network connected that satisfies the default internet request. For the OEM_PAID 14976 // preference, this is not as good as an OEM_PAID network, so even if the score of 14977 // the network is better than the factory announced, it still should try to bring up 14978 // the network. 14979 expectNoRequestChanged(oemPaidFactory); 14980 oemPaidFactory.assertRequestCountEquals(1); 14981 // The internet factory however is outscored, and should lose its requests. 14982 internetFactory.expectRequestRemove(); 14983 internetFactory.assertRequestCountEquals(0); 14984 14985 final NetworkCapabilities oemPaidNc = new NetworkCapabilities(); 14986 oemPaidNc.addCapability(NET_CAPABILITY_OEM_PAID); 14987 oemPaidNc.removeCapability(NET_CAPABILITY_NOT_RESTRICTED); 14988 final TestNetworkAgentWrapper oemPaidAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, 14989 new LinkProperties(), oemPaidNc); 14990 oemPaidAgent.connect(true); 14991 14992 // The oemPaidAgent has score 50/cell transport, so it beats what the oemPaidFactory can 14993 // provide, therefore it loses the request. 14994 oemPaidFactory.expectRequestRemove(); 14995 oemPaidFactory.assertRequestCountEquals(0); 14996 expectNoRequestChanged(internetFactory); 14997 internetFactory.assertRequestCountEquals(0); 14998 14999 oemPaidAgent.setScore(new NetworkScore.Builder().setLegacyInt(20).setExiting(true).build()); 15000 // Now the that the agent is weak, the oemPaidFactory can beat the existing network for the 15001 // OEM_PAID request. The internet factory however can't beat a network that has OEM_PAID 15002 // for the preference request, so it doesn't see the request. 15003 oemPaidFactory.expectRequestAdd(); 15004 oemPaidFactory.assertRequestCountEquals(1); 15005 expectNoRequestChanged(internetFactory); 15006 internetFactory.assertRequestCountEquals(0); 15007 15008 mCellAgent.disconnect(); 15009 // The network satisfying the default internet request has disconnected, so the 15010 // internetFactory sees the default request again. However there is a network with OEM_PAID 15011 // connected, so the 2nd OEM_PAID req is already satisfied, so the oemPaidFactory doesn't 15012 // care about networks that don't have OEM_PAID. 15013 expectNoRequestChanged(oemPaidFactory); 15014 oemPaidFactory.assertRequestCountEquals(1); 15015 internetFactory.expectRequestAdd(); 15016 internetFactory.assertRequestCountEquals(1); 15017 15018 // Cell connects again, still with score 50. Back to the previous state. 15019 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 15020 mCellAgent.connect(true); 15021 expectNoRequestChanged(oemPaidFactory); 15022 oemPaidFactory.assertRequestCountEquals(1); 15023 internetFactory.expectRequestRemove(); 15024 internetFactory.assertRequestCountEquals(0); 15025 15026 // Create a request that holds the upcoming wifi network. 15027 final TestNetworkCallback wifiCallback = new TestNetworkCallback(); 15028 mCm.requestNetwork(new NetworkRequest.Builder().addTransportType(TRANSPORT_WIFI).build(), 15029 wifiCallback); 15030 15031 // Now WiFi connects and it's unmetered, but it's weaker than cell. 15032 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 15033 mWiFiAgent.addCapability(NET_CAPABILITY_NOT_METERED); 15034 mWiFiAgent.setScore(new NetworkScore.Builder().setLegacyInt(30).setExiting(true) 15035 .build()); // Not the best Internet network, but unmetered 15036 mWiFiAgent.connect(true); 15037 15038 // The OEM_PAID preference prefers an unmetered network to an OEM_PAID network, so 15039 // the oemPaidFactory can't beat wifi no matter how high its score. 15040 oemPaidFactory.expectRequestRemove(); 15041 expectNoRequestChanged(internetFactory); 15042 15043 mCellAgent.disconnect(); 15044 // Now that the best internet network (cell, with its 50 score compared to 30 for WiFi 15045 // at this point), the default internet request is satisfied by a network worse than 15046 // the internetFactory announced, so it gets the request. However, there is still an 15047 // unmetered network, so the oemPaidNetworkFactory still can't beat this. 15048 expectNoRequestChanged(oemPaidFactory); 15049 internetFactory.expectRequestAdd(); 15050 mCm.unregisterNetworkCallback(wifiCallback); 15051 } 15052 15053 /** 15054 * Test network priority for OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK in the following order: 15055 * NET_CAPABILITY_NOT_METERED -> NET_CAPABILITY_OEM_PAID 15056 */ 15057 @Test 15058 public void testMultipleDefaultNetworksTracksOemNetworkPreferenceOemPaidNoFallbackCorrectly() 15059 throws Exception { 15060 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 15061 OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK; 15062 setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest(networkPref); 15063 final int expectedDefaultRequestSize = 2; 15064 final int expectedOemPrefRequestSize = 2; 15065 registerDefaultNetworkCallbacks(); 15066 15067 // The fallback as well as the OEM preference should now be tracked. 15068 assertEquals(expectedDefaultRequestSize, mService.mDefaultNetworkRequests.size()); 15069 15070 // Test lowest to highest priority requests. 15071 // Bring up metered cellular. This will satisfy the fallback network but not the pref. 15072 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); 15073 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 15074 mCellAgent.getNetwork(), 15075 mService.mNoServiceNetwork.network()); 15076 15077 // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID. 15078 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true); 15079 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 15080 mCellAgent.getNetwork(), 15081 mEthernetAgent.getNetwork()); 15082 15083 // Bring up unmetered Wi-Fi. This will satisfy NET_CAPABILITY_NOT_METERED. 15084 setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, true); 15085 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 15086 mWiFiAgent.getNetwork(), 15087 mWiFiAgent.getNetwork()); 15088 15089 // Disconnecting unmetered Wi-Fi will put the OEM pref on OEM_PAID and fallback on cellular. 15090 setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, false); 15091 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 15092 mCellAgent.getNetwork(), 15093 mEthernetAgent.getNetwork()); 15094 15095 // Disconnecting cellular should keep OEM network on OEM_PAID and fallback will be null. 15096 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, false); 15097 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 15098 null, 15099 mEthernetAgent.getNetwork()); 15100 15101 // Disconnecting OEM_PAID puts the fallback on null and the pref on the disconnected net. 15102 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, false); 15103 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 15104 null, 15105 mService.mNoServiceNetwork.network()); 15106 15107 // default callbacks will be unregistered in tearDown 15108 } 15109 15110 /** 15111 * Test network priority for OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY in the following order: 15112 * NET_CAPABILITY_OEM_PAID 15113 * This preference should only apply to OEM_PAID networks. 15114 */ 15115 @Test 15116 public void testMultipleDefaultNetworksTracksOemNetworkPreferenceOemPaidOnlyCorrectly() 15117 throws Exception { 15118 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 15119 OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY; 15120 setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest(networkPref); 15121 final int expectedDefaultRequestSize = 2; 15122 final int expectedOemPrefRequestSize = 1; 15123 registerDefaultNetworkCallbacks(); 15124 15125 // The fallback as well as the OEM preference should now be tracked. 15126 assertEquals(expectedDefaultRequestSize, mService.mDefaultNetworkRequests.size()); 15127 15128 // Test lowest to highest priority requests. 15129 // Bring up metered cellular. This will satisfy the fallback network. 15130 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); 15131 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 15132 mCellAgent.getNetwork(), 15133 mService.mNoServiceNetwork.network()); 15134 15135 // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID. 15136 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true); 15137 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 15138 mCellAgent.getNetwork(), 15139 mEthernetAgent.getNetwork()); 15140 15141 // Bring up unmetered Wi-Fi. The OEM network shouldn't change, the fallback will take Wi-Fi. 15142 setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, true); 15143 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 15144 mWiFiAgent.getNetwork(), 15145 mEthernetAgent.getNetwork()); 15146 15147 // Disconnecting unmetered Wi-Fi shouldn't change the OEM network with fallback on cellular. 15148 setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, false); 15149 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 15150 mCellAgent.getNetwork(), 15151 mEthernetAgent.getNetwork()); 15152 15153 // Disconnecting OEM_PAID will keep the fallback on cellular and nothing for OEM_PAID. 15154 // OEM_PAID_ONLY not supporting a fallback now uses the disconnected network. 15155 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, false); 15156 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 15157 mCellAgent.getNetwork(), 15158 mService.mNoServiceNetwork.network()); 15159 15160 // Disconnecting cellular will put the fallback on null and the pref on disconnected. 15161 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, false); 15162 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 15163 null, 15164 mService.mNoServiceNetwork.network()); 15165 15166 // default callbacks will be unregistered in tearDown 15167 } 15168 15169 /** 15170 * Test network priority for OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY in the following order: 15171 * NET_CAPABILITY_OEM_PRIVATE 15172 * This preference should only apply to OEM_PRIVATE networks. 15173 */ 15174 @Test 15175 public void testMultipleDefaultNetworksTracksOemNetworkPreferenceOemPrivateOnlyCorrectly() 15176 throws Exception { 15177 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 15178 OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY; 15179 setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest(networkPref); 15180 final int expectedDefaultRequestSize = 2; 15181 final int expectedOemPrefRequestSize = 1; 15182 registerDefaultNetworkCallbacks(); 15183 15184 // The fallback as well as the OEM preference should now be tracked. 15185 assertEquals(expectedDefaultRequestSize, mService.mDefaultNetworkRequests.size()); 15186 15187 // Test lowest to highest priority requests. 15188 // Bring up metered cellular. This will satisfy the fallback network. 15189 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); 15190 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 15191 mCellAgent.getNetwork(), 15192 mService.mNoServiceNetwork.network()); 15193 15194 // Bring up ethernet with OEM_PRIVATE. This will satisfy NET_CAPABILITY_OEM_PRIVATE. 15195 startOemManagedNetwork(false); 15196 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 15197 mCellAgent.getNetwork(), 15198 mEthernetAgent.getNetwork()); 15199 15200 // Bring up unmetered Wi-Fi. The OEM network shouldn't change, the fallback will take Wi-Fi. 15201 setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, true); 15202 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 15203 mWiFiAgent.getNetwork(), 15204 mEthernetAgent.getNetwork()); 15205 15206 // Disconnecting unmetered Wi-Fi shouldn't change the OEM network with fallback on cellular. 15207 setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, false); 15208 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 15209 mCellAgent.getNetwork(), 15210 mEthernetAgent.getNetwork()); 15211 15212 // Disconnecting OEM_PRIVATE will keep the fallback on cellular. 15213 // OEM_PRIVATE_ONLY not supporting a fallback now uses to the disconnected network. 15214 stopOemManagedNetwork(); 15215 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 15216 mCellAgent.getNetwork(), 15217 mService.mNoServiceNetwork.network()); 15218 15219 // Disconnecting cellular will put the fallback on null and pref on disconnected. 15220 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, false); 15221 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 15222 null, 15223 mService.mNoServiceNetwork.network()); 15224 15225 // default callbacks will be unregistered in tearDown 15226 } 15227 15228 @Test 15229 public void testCapabilityWithOemNetworkPreference() throws Exception { 15230 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 15231 OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY; 15232 setupMultipleDefaultNetworksForOemNetworkPreferenceNotCurrentUidTest(networkPref); 15233 registerDefaultNetworkCallbacks(); 15234 15235 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); 15236 15237 mSystemDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 15238 mDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 15239 15240 mCellAgent.addCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED); 15241 mSystemDefaultNetworkCallback.expectCaps(mCellAgent, 15242 c -> c.hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED)); 15243 mDefaultNetworkCallback.expectCaps(mCellAgent, 15244 c -> c.hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED)); 15245 15246 // default callbacks will be unregistered in tearDown 15247 } 15248 15249 @Test 15250 public void testSetOemNetworkPreferenceLogsRequest() throws Exception { 15251 mServiceContext.setPermission(DUMP, PERMISSION_GRANTED); 15252 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 15253 OEM_NETWORK_PREFERENCE_OEM_PAID; 15254 final StringWriter stringWriter = new StringWriter(); 15255 final String logIdentifier = "UPDATE INITIATED: OemNetworkPreferences"; 15256 final Pattern pattern = Pattern.compile(logIdentifier); 15257 15258 final int expectedNumLogs = 2; 15259 final UidRangeParcel[] uidRanges = 15260 toUidRangeStableParcels(uidRangesForUids(TEST_PACKAGE_UID)); 15261 15262 // Call twice to generate two logs. 15263 setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges, TEST_PACKAGE_NAME); 15264 setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges, TEST_PACKAGE_NAME); 15265 mService.dump(new FileDescriptor(), new PrintWriter(stringWriter), new String[0]); 15266 15267 final String dumpOutput = stringWriter.toString(); 15268 final Matcher matcher = pattern.matcher(dumpOutput); 15269 int count = 0; 15270 while (matcher.find()) { 15271 count++; 15272 } 15273 assertEquals(expectedNumLogs, count); 15274 } 15275 15276 @Test 15277 public void testGetAllNetworkStateSnapshots() throws Exception { 15278 verifyNoNetwork(); 15279 15280 // Setup test cellular network with specified LinkProperties and NetworkCapabilities, 15281 // verify the content of the snapshot matches. 15282 final LinkProperties cellLp = new LinkProperties(); 15283 final LinkAddress myIpv4Addr = new LinkAddress(InetAddress.getByName("192.0.2.129"), 25); 15284 final LinkAddress myIpv6Addr = new LinkAddress(InetAddress.getByName("2001:db8::1"), 64); 15285 cellLp.setInterfaceName("test01"); 15286 cellLp.addLinkAddress(myIpv4Addr); 15287 cellLp.addLinkAddress(myIpv6Addr); 15288 cellLp.addRoute(new RouteInfo(InetAddress.getByName("fe80::1234"))); 15289 cellLp.addRoute(new RouteInfo(InetAddress.getByName("192.0.2.254"))); 15290 cellLp.addRoute(new RouteInfo(myIpv4Addr, null)); 15291 cellLp.addRoute(new RouteInfo(myIpv6Addr, null)); 15292 final NetworkCapabilities cellNcTemplate = new NetworkCapabilities.Builder() 15293 .addTransportType(TRANSPORT_CELLULAR).addCapability(NET_CAPABILITY_MMS).build(); 15294 15295 final TestNetworkCallback cellCb = new TestNetworkCallback(); 15296 mCm.requestNetwork(new NetworkRequest.Builder().addCapability(NET_CAPABILITY_MMS).build(), 15297 cellCb); 15298 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp, cellNcTemplate); 15299 mCellAgent.connect(true); 15300 cellCb.expectAvailableCallbacksUnvalidated(mCellAgent); 15301 List<NetworkStateSnapshot> snapshots = mCm.getAllNetworkStateSnapshots(); 15302 assertLength(1, snapshots); 15303 15304 // Compose the expected cellular snapshot for verification. 15305 final NetworkCapabilities cellNc = 15306 mCm.getNetworkCapabilities(mCellAgent.getNetwork()); 15307 final NetworkStateSnapshot cellSnapshot = new NetworkStateSnapshot( 15308 mCellAgent.getNetwork(), cellNc, cellLp, 15309 null, ConnectivityManager.TYPE_MOBILE); 15310 assertEquals(cellSnapshot, snapshots.get(0)); 15311 15312 // Connect wifi and verify the snapshots. 15313 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 15314 mWiFiAgent.connect(true); 15315 waitForIdle(); 15316 // Compose the expected wifi snapshot for verification. 15317 final NetworkCapabilities wifiNc = 15318 mCm.getNetworkCapabilities(mWiFiAgent.getNetwork()); 15319 final NetworkStateSnapshot wifiSnapshot = new NetworkStateSnapshot( 15320 mWiFiAgent.getNetwork(), wifiNc, new LinkProperties(), null, 15321 ConnectivityManager.TYPE_WIFI); 15322 15323 snapshots = mCm.getAllNetworkStateSnapshots(); 15324 assertLength(2, snapshots); 15325 assertContainsAll(snapshots, cellSnapshot, wifiSnapshot); 15326 15327 // Set cellular as suspended, verify the snapshots will contain suspended networks. 15328 mCellAgent.suspend(); 15329 waitForIdle(); 15330 final NetworkCapabilities cellSuspendedNc = 15331 mCm.getNetworkCapabilities(mCellAgent.getNetwork()); 15332 assertFalse(cellSuspendedNc.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 15333 final NetworkStateSnapshot cellSuspendedSnapshot = new NetworkStateSnapshot( 15334 mCellAgent.getNetwork(), cellSuspendedNc, cellLp, 15335 null, ConnectivityManager.TYPE_MOBILE); 15336 snapshots = mCm.getAllNetworkStateSnapshots(); 15337 assertLength(2, snapshots); 15338 assertContainsAll(snapshots, cellSuspendedSnapshot, wifiSnapshot); 15339 15340 // Disconnect wifi, verify the snapshots contain only cellular. 15341 mWiFiAgent.disconnect(); 15342 waitForIdle(); 15343 snapshots = mCm.getAllNetworkStateSnapshots(); 15344 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetwork()); 15345 assertLength(1, snapshots); 15346 assertEquals(cellSuspendedSnapshot, snapshots.get(0)); 15347 15348 mCellAgent.resume(); 15349 waitForIdle(); 15350 snapshots = mCm.getAllNetworkStateSnapshots(); 15351 assertLength(1, snapshots); 15352 assertEquals(cellSnapshot, snapshots.get(0)); 15353 15354 mCellAgent.disconnect(); 15355 waitForIdle(); 15356 verifyNoNetwork(); 15357 mCm.unregisterNetworkCallback(cellCb); 15358 } 15359 15360 // Cannot be part of MockNetworkFactory since it requires method of the test. 15361 private void expectNoRequestChanged(@NonNull MockNetworkFactory factory) { 15362 waitForIdle(); 15363 factory.assertNoRequestChanged(); 15364 } 15365 15366 @Test 15367 public void testRegisterBestMatchingNetworkCallback_noIssueToFactory() throws Exception { 15368 // Prepare mock mms factory. 15369 final HandlerThread handlerThread = new HandlerThread("MockCellularFactory"); 15370 handlerThread.start(); 15371 NetworkCapabilities filter = new NetworkCapabilities() 15372 .addTransportType(TRANSPORT_CELLULAR) 15373 .addCapability(NET_CAPABILITY_MMS); 15374 final MockNetworkFactory testFactory = new MockNetworkFactory(handlerThread.getLooper(), 15375 mServiceContext, "testFactory", filter, mCsHandlerThread); 15376 testFactory.setScoreFilter(40); 15377 15378 try { 15379 // Register the factory. It doesn't see the default request because its filter does 15380 // not include INTERNET. 15381 testFactory.register(); 15382 expectNoRequestChanged(testFactory); 15383 testFactory.assertRequestCountEquals(0); 15384 // The factory won't try to start the network since the default request doesn't 15385 // match the filter (no INTERNET capability). 15386 assertFalse(testFactory.getMyStartRequested()); 15387 15388 // Register callback for listening best matching network. Verify that the request won't 15389 // be sent to factory. 15390 final TestNetworkCallback bestMatchingCb = new TestNetworkCallback(); 15391 mCm.registerBestMatchingNetworkCallback( 15392 new NetworkRequest.Builder().addCapability(NET_CAPABILITY_MMS).build(), 15393 bestMatchingCb, mCsHandlerThread.getThreadHandler()); 15394 bestMatchingCb.assertNoCallback(); 15395 expectNoRequestChanged(testFactory); 15396 testFactory.assertRequestCountEquals(0); 15397 assertFalse(testFactory.getMyStartRequested()); 15398 15399 // Fire a normal mms request, verify the factory will only see the request. 15400 final TestNetworkCallback mmsNetworkCallback = new TestNetworkCallback(); 15401 final NetworkRequest mmsRequest = new NetworkRequest.Builder() 15402 .addCapability(NET_CAPABILITY_MMS).build(); 15403 mCm.requestNetwork(mmsRequest, mmsNetworkCallback); 15404 testFactory.expectRequestAdd(); 15405 testFactory.assertRequestCountEquals(1); 15406 assertTrue(testFactory.getMyStartRequested()); 15407 15408 // Unregister best matching callback, verify factory see no change. 15409 mCm.unregisterNetworkCallback(bestMatchingCb); 15410 expectNoRequestChanged(testFactory); 15411 testFactory.assertRequestCountEquals(1); 15412 assertTrue(testFactory.getMyStartRequested()); 15413 } finally { 15414 testFactory.terminate(); 15415 } 15416 } 15417 15418 @Test 15419 public void testRegisterBestMatchingNetworkCallback_trackBestNetwork() throws Exception { 15420 final TestNetworkCallback bestMatchingCb = new TestNetworkCallback(); 15421 mCm.registerBestMatchingNetworkCallback( 15422 new NetworkRequest.Builder().addCapability(NET_CAPABILITY_TRUSTED).build(), 15423 bestMatchingCb, mCsHandlerThread.getThreadHandler()); 15424 15425 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 15426 mCellAgent.connect(true); 15427 bestMatchingCb.expectAvailableThenValidatedCallbacks(mCellAgent); 15428 15429 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 15430 mWiFiAgent.connect(true); 15431 bestMatchingCb.expectAvailableDoubleValidatedCallbacks(mWiFiAgent); 15432 15433 // Change something on cellular to trigger capabilities changed, since the callback 15434 // only cares about the best network, verify it received nothing from cellular. 15435 mCellAgent.addCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED); 15436 bestMatchingCb.assertNoCallback(); 15437 15438 // Make cellular the best network again, verify the callback now tracks cellular. 15439 mWiFiAgent.adjustScore(-50); 15440 bestMatchingCb.expectAvailableCallbacksValidated(mCellAgent); 15441 15442 // Make cellular temporary non-trusted, which will not satisfying the request. 15443 // Verify the callback switch from/to the other network accordingly. 15444 mCellAgent.removeCapability(NET_CAPABILITY_TRUSTED); 15445 bestMatchingCb.expectAvailableCallbacksValidated(mWiFiAgent); 15446 mCellAgent.addCapability(NET_CAPABILITY_TRUSTED); 15447 bestMatchingCb.expectAvailableDoubleValidatedCallbacks(mCellAgent); 15448 15449 // Verify the callback doesn't care about wifi disconnect. 15450 mWiFiAgent.disconnect(); 15451 bestMatchingCb.assertNoCallback(); 15452 mCellAgent.disconnect(); 15453 bestMatchingCb.expect(LOST, mCellAgent); 15454 } 15455 15456 private UidRangeParcel[] uidRangeFor(final UserHandle handle) { 15457 final UidRange range = UidRange.createForUser(handle); 15458 return new UidRangeParcel[] { new UidRangeParcel(range.start, range.stop) }; 15459 } 15460 15461 private UidRangeParcel[] uidRangeFor(final UserHandle handle, 15462 ProfileNetworkPreference profileNetworkPreference) { 15463 final Set<UidRange> uidRangeSet; 15464 UidRange range = UidRange.createForUser(handle); 15465 if (profileNetworkPreference.getIncludedUids().length != 0) { 15466 uidRangeSet = UidRangeUtils.convertArrayToUidRange( 15467 profileNetworkPreference.getIncludedUids()); 15468 15469 } else if (profileNetworkPreference.getExcludedUids().length != 0) { 15470 uidRangeSet = UidRangeUtils.removeRangeSetFromUidRange( 15471 range, UidRangeUtils.convertArrayToUidRange( 15472 profileNetworkPreference.getExcludedUids())); 15473 } else { 15474 uidRangeSet = new ArraySet<>(); 15475 uidRangeSet.add(range); 15476 } 15477 UidRangeParcel[] uidRangeParcels = new UidRangeParcel[uidRangeSet.size()]; 15478 int i = 0; 15479 for (UidRange range1 : uidRangeSet) { 15480 uidRangeParcels[i] = new UidRangeParcel(range1.start, range1.stop); 15481 i++; 15482 } 15483 return uidRangeParcels; 15484 } 15485 15486 private static class TestOnCompleteListener implements Runnable { 15487 final class OnComplete {} 15488 final ArrayTrackRecord<OnComplete>.ReadHead mHistory = 15489 new ArrayTrackRecord<OnComplete>().newReadHead(); 15490 15491 @Override 15492 public void run() { 15493 mHistory.add(new OnComplete()); 15494 } 15495 15496 public void expectOnComplete() { 15497 assertNotNull(mHistory.poll(TIMEOUT_MS, it -> true)); 15498 } 15499 } 15500 15501 private TestNetworkAgentWrapper makeEnterpriseNetworkAgent() throws Exception { 15502 final NetworkCapabilities workNc = new NetworkCapabilities(); 15503 workNc.addCapability(NET_CAPABILITY_ENTERPRISE); 15504 workNc.removeCapability(NET_CAPABILITY_NOT_RESTRICTED); 15505 return new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, new LinkProperties(), workNc); 15506 } 15507 15508 private TestNetworkAgentWrapper makeEnterpriseNetworkAgent(int enterpriseId) throws Exception { 15509 final NetworkCapabilities workNc = new NetworkCapabilities(); 15510 workNc.addCapability(NET_CAPABILITY_ENTERPRISE); 15511 workNc.removeCapability(NET_CAPABILITY_NOT_RESTRICTED); 15512 workNc.addEnterpriseId(enterpriseId); 15513 return new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, new LinkProperties(), workNc); 15514 } 15515 15516 private TestNetworkCallback mEnterpriseCallback; 15517 private UserHandle setupEnterpriseNetwork() { 15518 final UserHandle userHandle = UserHandle.of(TEST_WORK_PROFILE_USER_ID); 15519 mServiceContext.setWorkProfile(userHandle, true); 15520 15521 // File a request to avoid the enterprise network being disconnected as soon as the default 15522 // request goes away – it would make impossible to test that networkRemoveUidRanges 15523 // is called, as the network would disconnect first for lack of a request. 15524 mEnterpriseCallback = new TestNetworkCallback(); 15525 final NetworkRequest keepUpRequest = new NetworkRequest.Builder() 15526 .addCapability(NET_CAPABILITY_ENTERPRISE) 15527 .build(); 15528 mCm.requestNetwork(keepUpRequest, mEnterpriseCallback); 15529 return userHandle; 15530 } 15531 15532 private void maybeTearDownEnterpriseNetwork() { 15533 if (null != mEnterpriseCallback) { 15534 mCm.unregisterNetworkCallback(mEnterpriseCallback); 15535 } 15536 } 15537 15538 /** 15539 * Make sure per profile network preferences behave as expected for a given 15540 * profile network preference. 15541 */ 15542 private void doTestPreferenceForUserNetworkUpDownForGivenPreference( 15543 ProfileNetworkPreference profileNetworkPreference, 15544 boolean connectWorkProfileAgentAhead, 15545 UserHandle testHandle, 15546 TestNetworkCallback profileDefaultNetworkCallback, 15547 TestNetworkCallback disAllowProfileDefaultNetworkCallback) throws Exception { 15548 final InOrder inOrder = inOrder(mMockNetd, mMockDnsResolver); 15549 15550 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 15551 mCellAgent.connect(true); 15552 15553 mSystemDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 15554 mDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 15555 profileDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 15556 if (disAllowProfileDefaultNetworkCallback != null) { 15557 disAllowProfileDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 15558 } 15559 inOrder.verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( 15560 mCellAgent.getNetwork().netId, INetd.PERMISSION_NONE)); 15561 15562 final TestNetworkAgentWrapper workAgent = 15563 makeEnterpriseNetworkAgent(profileNetworkPreference.getPreferenceEnterpriseId()); 15564 if (mService.shouldCreateNetworksImmediately()) { 15565 expectNativeNetworkCreated(workAgent.getNetwork().netId, INetd.PERMISSION_SYSTEM, 15566 null /* iface */, inOrder); 15567 } 15568 if (connectWorkProfileAgentAhead) { 15569 workAgent.connect(false); 15570 if (!mService.shouldCreateNetworksImmediately()) { 15571 expectNativeNetworkCreated(workAgent.getNetwork().netId, INetd.PERMISSION_SYSTEM, 15572 null /* iface */, inOrder); 15573 } 15574 } 15575 15576 final TestOnCompleteListener listener = new TestOnCompleteListener(); 15577 mCm.setProfileNetworkPreferences(testHandle, List.of(profileNetworkPreference), 15578 r -> r.run(), listener); 15579 listener.expectOnComplete(); 15580 boolean allowFallback = true; 15581 if (profileNetworkPreference.getPreference() 15582 == PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK) { 15583 allowFallback = false; 15584 } 15585 if (allowFallback && !connectWorkProfileAgentAhead) { 15586 // Setting a network preference for this user will create a new set of routing rules for 15587 // the UID range that corresponds to this user, inorder to define the default network 15588 // for these apps separately. This is true because the multi-layer request relevant to 15589 // this UID range contains a TRACK_DEFAULT, so the range will be moved through 15590 // UID-specific rules to the correct network – in this case the system default network. 15591 // The case where the default network for the profile happens to be the same as the 15592 // system default is not handled specially, the rules are always active as long as 15593 // a preference is set. 15594 inOrder.verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 15595 mCellAgent.getNetwork().netId, 15596 uidRangeFor(testHandle, profileNetworkPreference), 15597 PREFERENCE_ORDER_PROFILE)); 15598 } 15599 15600 // The enterprise network is not ready yet. 15601 assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback); 15602 if (allowFallback && !connectWorkProfileAgentAhead) { 15603 assertNoCallbacks(profileDefaultNetworkCallback); 15604 } else if (!connectWorkProfileAgentAhead) { 15605 profileDefaultNetworkCallback.expect(LOST, mCellAgent); 15606 if (disAllowProfileDefaultNetworkCallback != null) { 15607 assertNoCallbacks(disAllowProfileDefaultNetworkCallback); 15608 } 15609 } 15610 15611 if (!connectWorkProfileAgentAhead) { 15612 workAgent.connect(false); 15613 if (!mService.shouldCreateNetworksImmediately()) { 15614 inOrder.verify(mMockNetd).networkCreate( 15615 nativeNetworkConfigPhysical(workAgent.getNetwork().netId, 15616 INetd.PERMISSION_SYSTEM)); 15617 } 15618 } 15619 15620 profileDefaultNetworkCallback.expectAvailableCallbacksUnvalidated(workAgent); 15621 if (disAllowProfileDefaultNetworkCallback != null) { 15622 disAllowProfileDefaultNetworkCallback.assertNoCallback(); 15623 } 15624 mSystemDefaultNetworkCallback.assertNoCallback(); 15625 mDefaultNetworkCallback.assertNoCallback(); 15626 inOrder.verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 15627 workAgent.getNetwork().netId, 15628 uidRangeFor(testHandle, profileNetworkPreference), 15629 PREFERENCE_ORDER_PROFILE)); 15630 15631 if (allowFallback && !connectWorkProfileAgentAhead) { 15632 inOrder.verify(mMockNetd).networkRemoveUidRangesParcel(new NativeUidRangeConfig( 15633 mCellAgent.getNetwork().netId, 15634 uidRangeFor(testHandle, profileNetworkPreference), 15635 PREFERENCE_ORDER_PROFILE)); 15636 } 15637 15638 // Make sure changes to the work agent send callbacks to the app in the work profile, but 15639 // not to the other apps. 15640 workAgent.setNetworkValid(true /* privateDnsProbeSent */); 15641 workAgent.mNetworkMonitor.forceReevaluation(Process.myUid()); 15642 profileDefaultNetworkCallback.expectCaps(workAgent, 15643 c -> c.hasCapability(NET_CAPABILITY_VALIDATED) 15644 && c.hasCapability(NET_CAPABILITY_ENTERPRISE) 15645 && c.hasEnterpriseId(profileNetworkPreference.getPreferenceEnterpriseId()) 15646 && c.getEnterpriseIds().length == 1); 15647 if (disAllowProfileDefaultNetworkCallback != null) { 15648 assertNoCallbacks(disAllowProfileDefaultNetworkCallback); 15649 } 15650 assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback); 15651 15652 workAgent.addCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED); 15653 profileDefaultNetworkCallback.expectCaps(workAgent, 15654 c -> c.hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED)); 15655 if (disAllowProfileDefaultNetworkCallback != null) { 15656 assertNoCallbacks(disAllowProfileDefaultNetworkCallback); 15657 } 15658 assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback); 15659 15660 // Conversely, change a capability on the system-wide default network and make sure 15661 // that only the apps outside of the work profile receive the callbacks. 15662 mCellAgent.addCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED); 15663 mSystemDefaultNetworkCallback.expectCaps(mCellAgent, 15664 c -> c.hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED)); 15665 mDefaultNetworkCallback.expectCaps(mCellAgent, 15666 c -> c.hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED)); 15667 if (disAllowProfileDefaultNetworkCallback != null) { 15668 disAllowProfileDefaultNetworkCallback.expectCaps(mCellAgent, 15669 c -> c.hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED)); 15670 } 15671 profileDefaultNetworkCallback.assertNoCallback(); 15672 15673 // Disconnect and reconnect the system-wide default network and make sure that the 15674 // apps on this network see the appropriate callbacks, and the app on the work profile 15675 // doesn't because it continues to use the enterprise network. 15676 mCellAgent.disconnect(); 15677 mSystemDefaultNetworkCallback.expect(LOST, mCellAgent); 15678 mDefaultNetworkCallback.expect(LOST, mCellAgent); 15679 if (disAllowProfileDefaultNetworkCallback != null) { 15680 disAllowProfileDefaultNetworkCallback.expect(LOST, mCellAgent); 15681 } 15682 profileDefaultNetworkCallback.assertNoCallback(); 15683 inOrder.verify(mMockNetd).networkDestroy(mCellAgent.getNetwork().netId); 15684 15685 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 15686 mCellAgent.connect(true); 15687 mSystemDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 15688 mDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 15689 if (disAllowProfileDefaultNetworkCallback != null) { 15690 disAllowProfileDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 15691 15692 } 15693 profileDefaultNetworkCallback.assertNoCallback(); 15694 inOrder.verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( 15695 mCellAgent.getNetwork().netId, INetd.PERMISSION_NONE)); 15696 15697 // When the agent disconnects, test that the app on the work profile falls back to the 15698 // default network. 15699 workAgent.disconnect(); 15700 profileDefaultNetworkCallback.expect(LOST, workAgent); 15701 if (allowFallback) { 15702 profileDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellAgent); 15703 if (disAllowProfileDefaultNetworkCallback != null) { 15704 assertNoCallbacks(disAllowProfileDefaultNetworkCallback); 15705 } 15706 } 15707 assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback); 15708 if (allowFallback) { 15709 inOrder.verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 15710 mCellAgent.getNetwork().netId, 15711 uidRangeFor(testHandle, profileNetworkPreference), 15712 PREFERENCE_ORDER_PROFILE)); 15713 } 15714 inOrder.verify(mMockNetd).networkDestroy(workAgent.getNetwork().netId); 15715 15716 mCellAgent.disconnect(); 15717 mSystemDefaultNetworkCallback.expect(LOST, mCellAgent); 15718 mDefaultNetworkCallback.expect(LOST, mCellAgent); 15719 if (disAllowProfileDefaultNetworkCallback != null) { 15720 disAllowProfileDefaultNetworkCallback.expect(LOST, mCellAgent); 15721 } 15722 if (allowFallback) { 15723 profileDefaultNetworkCallback.expect(LOST, mCellAgent); 15724 } 15725 15726 // Waiting for the handler to be idle before checking for networkDestroy is necessary 15727 // here because ConnectivityService calls onLost before the network is fully torn down. 15728 waitForIdle(); 15729 inOrder.verify(mMockNetd).networkDestroy(mCellAgent.getNetwork().netId); 15730 15731 // If the control comes here, callbacks seem to behave correctly in the presence of 15732 // a default network when the enterprise network goes up and down. Now, make sure they 15733 // also behave correctly in the absence of a system-wide default network. 15734 final TestNetworkAgentWrapper workAgent2 = 15735 makeEnterpriseNetworkAgent(profileNetworkPreference.getPreferenceEnterpriseId()); 15736 workAgent2.connect(false); 15737 15738 profileDefaultNetworkCallback.expectAvailableCallbacksUnvalidated(workAgent2); 15739 if (disAllowProfileDefaultNetworkCallback != null) { 15740 assertNoCallbacks(disAllowProfileDefaultNetworkCallback); 15741 } 15742 assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback); 15743 inOrder.verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( 15744 workAgent2.getNetwork().netId, INetd.PERMISSION_SYSTEM)); 15745 inOrder.verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 15746 workAgent2.getNetwork().netId, 15747 uidRangeFor(testHandle, profileNetworkPreference), PREFERENCE_ORDER_PROFILE)); 15748 15749 workAgent2.setNetworkValid(true /* privateDnsProbeSent */); 15750 workAgent2.mNetworkMonitor.forceReevaluation(Process.myUid()); 15751 profileDefaultNetworkCallback.expectCaps(workAgent2, 15752 c -> c.hasCapability(NET_CAPABILITY_ENTERPRISE) 15753 && !c.hasCapability(NET_CAPABILITY_NOT_RESTRICTED) 15754 && c.hasEnterpriseId(profileNetworkPreference.getPreferenceEnterpriseId()) 15755 && c.getEnterpriseIds().length == 1); 15756 if (disAllowProfileDefaultNetworkCallback != null) { 15757 assertNoCallbacks(disAllowProfileDefaultNetworkCallback); 15758 } 15759 assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback); 15760 inOrder.verify(mMockNetd, never()).networkAddUidRangesParcel(any()); 15761 15762 // When the agent disconnects, test that the app on the work profile fall back to the 15763 // default network. 15764 workAgent2.disconnect(); 15765 profileDefaultNetworkCallback.expect(LOST, workAgent2); 15766 if (disAllowProfileDefaultNetworkCallback != null) { 15767 assertNoCallbacks(disAllowProfileDefaultNetworkCallback); 15768 } 15769 assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback); 15770 inOrder.verify(mMockNetd).networkDestroy(workAgent2.getNetwork().netId); 15771 15772 assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback, 15773 profileDefaultNetworkCallback); 15774 15775 // Callbacks will be unregistered by tearDown() 15776 } 15777 15778 /** 15779 * Make sure per-profile networking preference behaves as expected when the enterprise network 15780 * goes up and down while the preference is active. Make sure they behave as expected whether 15781 * there is a general default network or not. 15782 */ 15783 @Test 15784 public void testPreferenceForUserNetworkUpDown() throws Exception { 15785 final UserHandle testHandle = setupEnterpriseNetwork(); 15786 registerDefaultNetworkCallbacks(); 15787 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder = 15788 new ProfileNetworkPreference.Builder(); 15789 profileNetworkPreferenceBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE); 15790 profileNetworkPreferenceBuilder.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1); 15791 doTestPreferenceForUserNetworkUpDownForGivenPreference( 15792 profileNetworkPreferenceBuilder.build(), false, 15793 testHandle, mProfileDefaultNetworkCallback, null); 15794 } 15795 15796 /** 15797 * Make sure per-profile networking preference behaves as expected when the enterprise network 15798 * goes up and down while the preference is active. Make sure they behave as expected whether 15799 * there is a general default network or not when configured to not fallback to default network. 15800 */ 15801 @Test 15802 public void testPreferenceForUserNetworkUpDownWithNoFallback() throws Exception { 15803 final UserHandle testHandle = setupEnterpriseNetwork(); 15804 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder = 15805 new ProfileNetworkPreference.Builder(); 15806 profileNetworkPreferenceBuilder.setPreference( 15807 PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK); 15808 profileNetworkPreferenceBuilder.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1); 15809 registerDefaultNetworkCallbacks(); 15810 doTestPreferenceForUserNetworkUpDownForGivenPreference( 15811 profileNetworkPreferenceBuilder.build(), false, 15812 testHandle, mProfileDefaultNetworkCallback, null); 15813 } 15814 15815 /** 15816 * Make sure per-profile networking preference behaves as expected when the enterprise network 15817 * goes up and down while the preference is active. Make sure they behave as expected whether 15818 * there is a general default network or not when configured to not fallback to default network 15819 * along with already connected enterprise work agent 15820 */ 15821 @Test 15822 public void testPreferenceForUserNetworkUpDownWithNoFallbackWithAlreadyConnectedWorkAgent() 15823 throws Exception { 15824 final UserHandle testHandle = setupEnterpriseNetwork(); 15825 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder = 15826 new ProfileNetworkPreference.Builder(); 15827 profileNetworkPreferenceBuilder.setPreference( 15828 PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK); 15829 profileNetworkPreferenceBuilder.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1); 15830 registerDefaultNetworkCallbacks(); 15831 doTestPreferenceForUserNetworkUpDownForGivenPreference( 15832 profileNetworkPreferenceBuilder.build(), true, testHandle, 15833 mProfileDefaultNetworkCallback, null); 15834 } 15835 15836 /** 15837 * Make sure per-profile networking preference for specific uid of test handle 15838 * behaves as expected 15839 */ 15840 @Test 15841 public void testPreferenceForDefaultUidOfTestHandle() throws Exception { 15842 final UserHandle testHandle = setupEnterpriseNetwork(); 15843 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder = 15844 new ProfileNetworkPreference.Builder(); 15845 profileNetworkPreferenceBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE); 15846 profileNetworkPreferenceBuilder.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1); 15847 profileNetworkPreferenceBuilder.setIncludedUids( 15848 new int[]{testHandle.getUid(TEST_WORK_PROFILE_APP_UID)}); 15849 registerDefaultNetworkCallbacks(); 15850 doTestPreferenceForUserNetworkUpDownForGivenPreference( 15851 profileNetworkPreferenceBuilder.build(), false, testHandle, 15852 mProfileDefaultNetworkCallback, null); 15853 } 15854 15855 /** 15856 * Make sure per-profile networking preference for specific uid of test handle 15857 * behaves as expected 15858 */ 15859 @Test 15860 public void testPreferenceForSpecificUidOfOnlyOneApp() throws Exception { 15861 final UserHandle testHandle = setupEnterpriseNetwork(); 15862 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder = 15863 new ProfileNetworkPreference.Builder(); 15864 profileNetworkPreferenceBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE); 15865 profileNetworkPreferenceBuilder.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1); 15866 profileNetworkPreferenceBuilder.setIncludedUids( 15867 new int[]{testHandle.getUid(TEST_WORK_PROFILE_APP_UID_2)}); 15868 registerDefaultNetworkCallbacks(); 15869 doTestPreferenceForUserNetworkUpDownForGivenPreference( 15870 profileNetworkPreferenceBuilder.build(), false, 15871 testHandle, mProfileDefaultNetworkCallbackAsAppUid2, null); 15872 } 15873 15874 /** 15875 * Make sure per-profile networking preference for specific uid of test handle 15876 * behaves as expected 15877 */ 15878 @Test 15879 public void testPreferenceForDisallowSpecificUidOfApp() throws Exception { 15880 final UserHandle testHandle = setupEnterpriseNetwork(); 15881 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder = 15882 new ProfileNetworkPreference.Builder(); 15883 profileNetworkPreferenceBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE); 15884 profileNetworkPreferenceBuilder.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1); 15885 profileNetworkPreferenceBuilder.setExcludedUids( 15886 new int[]{testHandle.getUid(TEST_WORK_PROFILE_APP_UID_2)}); 15887 registerDefaultNetworkCallbacks(); 15888 doTestPreferenceForUserNetworkUpDownForGivenPreference( 15889 profileNetworkPreferenceBuilder.build(), false, 15890 testHandle, mProfileDefaultNetworkCallback, 15891 mProfileDefaultNetworkCallbackAsAppUid2); 15892 } 15893 15894 /** 15895 * Make sure per-profile networking preference for specific uid of test handle 15896 * invalid uid inputs 15897 */ 15898 @Test 15899 public void testPreferenceForInvalidUids() throws Exception { 15900 final UserHandle testHandle = setupEnterpriseNetwork(); 15901 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder = 15902 new ProfileNetworkPreference.Builder(); 15903 profileNetworkPreferenceBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE); 15904 profileNetworkPreferenceBuilder.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1); 15905 profileNetworkPreferenceBuilder.setExcludedUids( 15906 new int[]{testHandle.getUid(0) - 1}); 15907 final TestOnCompleteListener listener = new TestOnCompleteListener(); 15908 Assert.assertThrows(IllegalArgumentException.class, () -> mCm.setProfileNetworkPreferences( 15909 testHandle, List.of(profileNetworkPreferenceBuilder.build()), 15910 r -> r.run(), listener)); 15911 15912 profileNetworkPreferenceBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE); 15913 profileNetworkPreferenceBuilder.setIncludedUids( 15914 new int[]{testHandle.getUid(0) - 1}); 15915 Assert.assertThrows(IllegalArgumentException.class, 15916 () -> mCm.setProfileNetworkPreferences( 15917 testHandle, List.of(profileNetworkPreferenceBuilder.build()), 15918 r -> r.run(), listener)); 15919 15920 15921 profileNetworkPreferenceBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE); 15922 profileNetworkPreferenceBuilder.setIncludedUids( 15923 new int[]{testHandle.getUid(0) - 1}); 15924 profileNetworkPreferenceBuilder.setExcludedUids( 15925 new int[]{testHandle.getUid(TEST_WORK_PROFILE_APP_UID_2)}); 15926 Assert.assertThrows(IllegalArgumentException.class, 15927 () -> mCm.setProfileNetworkPreferences( 15928 testHandle, List.of(profileNetworkPreferenceBuilder.build()), 15929 r -> r.run(), listener)); 15930 15931 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder2 = 15932 new ProfileNetworkPreference.Builder(); 15933 profileNetworkPreferenceBuilder2.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE); 15934 profileNetworkPreferenceBuilder2.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1); 15935 profileNetworkPreferenceBuilder2.setIncludedUids( 15936 new int[]{testHandle.getUid(TEST_WORK_PROFILE_APP_UID_2)}); 15937 profileNetworkPreferenceBuilder.setIncludedUids( 15938 new int[]{testHandle.getUid(TEST_WORK_PROFILE_APP_UID_2)}); 15939 Assert.assertThrows(IllegalArgumentException.class, 15940 () -> mCm.setProfileNetworkPreferences( 15941 testHandle, List.of(profileNetworkPreferenceBuilder.build(), 15942 profileNetworkPreferenceBuilder2.build()), 15943 r -> r.run(), listener)); 15944 15945 profileNetworkPreferenceBuilder2.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE); 15946 profileNetworkPreferenceBuilder2.setExcludedUids( 15947 new int[]{testHandle.getUid(TEST_WORK_PROFILE_APP_UID_2)}); 15948 profileNetworkPreferenceBuilder.setExcludedUids( 15949 new int[]{testHandle.getUid(TEST_WORK_PROFILE_APP_UID_2)}); 15950 Assert.assertThrows(IllegalArgumentException.class, 15951 () -> mCm.setProfileNetworkPreferences( 15952 testHandle, List.of(profileNetworkPreferenceBuilder.build(), 15953 profileNetworkPreferenceBuilder2.build()), 15954 r -> r.run(), listener)); 15955 15956 profileNetworkPreferenceBuilder2.setPreference( 15957 PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK); 15958 profileNetworkPreferenceBuilder2.setExcludedUids( 15959 new int[]{testHandle.getUid(TEST_WORK_PROFILE_APP_UID_2)}); 15960 profileNetworkPreferenceBuilder.setExcludedUids( 15961 new int[]{testHandle.getUid(TEST_WORK_PROFILE_APP_UID_2)}); 15962 Assert.assertThrows(IllegalArgumentException.class, 15963 () -> mCm.setProfileNetworkPreferences( 15964 testHandle, List.of(profileNetworkPreferenceBuilder.build(), 15965 profileNetworkPreferenceBuilder2.build()), 15966 r -> r.run(), listener)); 15967 } 15968 15969 /** 15970 * Make sure per-profile networking preference behaves as expected when the enterprise network 15971 * goes up and down while the preference is active. Make sure they behave as expected whether 15972 * there is a general default network or not when configured to fallback to default network 15973 * along with already connected enterprise work agent 15974 */ 15975 @Test 15976 public void testPreferenceForUserNetworkUpDownWithFallbackWithAlreadyConnectedWorkAgent() 15977 throws Exception { 15978 final UserHandle testHandle = setupEnterpriseNetwork(); 15979 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder = 15980 new ProfileNetworkPreference.Builder(); 15981 profileNetworkPreferenceBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE); 15982 profileNetworkPreferenceBuilder.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1); 15983 registerDefaultNetworkCallbacks(); 15984 doTestPreferenceForUserNetworkUpDownForGivenPreference( 15985 profileNetworkPreferenceBuilder.build(), true, 15986 testHandle, mProfileDefaultNetworkCallback, 15987 null); 15988 } 15989 15990 /** 15991 * Make sure per-profile networking preference behaves as expected when the enterprise network 15992 * goes up and down while the preference is active for a given enterprise identifier 15993 */ 15994 @Test 15995 public void testPreferenceForUserNetworkUpDownWithDefaultEnterpriseId() 15996 throws Exception { 15997 final UserHandle testHandle = setupEnterpriseNetwork(); 15998 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder = 15999 new ProfileNetworkPreference.Builder(); 16000 profileNetworkPreferenceBuilder.setPreference( 16001 PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK); 16002 profileNetworkPreferenceBuilder.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1); 16003 registerDefaultNetworkCallbacks(); 16004 doTestPreferenceForUserNetworkUpDownForGivenPreference( 16005 profileNetworkPreferenceBuilder.build(), true, 16006 testHandle, mProfileDefaultNetworkCallback, 16007 null); 16008 } 16009 16010 /** 16011 * Make sure per-profile networking preference behaves as expected when the enterprise network 16012 * goes up and down while the preference is active for a given enterprise identifier 16013 */ 16014 @Test 16015 public void testPreferenceForUserNetworkUpDownWithId2() 16016 throws Exception { 16017 final UserHandle testHandle = setupEnterpriseNetwork(); 16018 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder = 16019 new ProfileNetworkPreference.Builder(); 16020 profileNetworkPreferenceBuilder.setPreference( 16021 PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK); 16022 profileNetworkPreferenceBuilder.setPreferenceEnterpriseId( 16023 NET_ENTERPRISE_ID_2); 16024 registerDefaultNetworkCallbacks(); 16025 doTestPreferenceForUserNetworkUpDownForGivenPreference( 16026 profileNetworkPreferenceBuilder.build(), true, 16027 testHandle, mProfileDefaultNetworkCallback, null); 16028 } 16029 16030 /** 16031 * Make sure per-profile networking preference behaves as expected when the enterprise network 16032 * goes up and down while the preference is active for a given enterprise identifier 16033 */ 16034 @Test 16035 public void testPreferenceForUserNetworkUpDownWithInvalidId() 16036 throws Exception { 16037 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder = 16038 new ProfileNetworkPreference.Builder(); 16039 profileNetworkPreferenceBuilder.setPreference( 16040 PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK); 16041 profileNetworkPreferenceBuilder.setPreferenceEnterpriseId(0); 16042 registerDefaultNetworkCallbacks(); 16043 assertThrows("Should not be able to set invalid enterprise id", 16044 IllegalStateException.class, () -> profileNetworkPreferenceBuilder.build()); 16045 } 16046 16047 /** 16048 * Make sure per-profile networking preference throws exception when default preference 16049 * is set along with enterprise preference. 16050 */ 16051 @Test 16052 public void testPreferenceWithInvalidPreferenceDefaultAndEnterpriseTogether() 16053 throws Exception { 16054 final UserHandle testHandle = setupEnterpriseNetwork(); 16055 mServiceContext.setWorkProfile(testHandle, true); 16056 16057 final int testWorkProfileAppUid1 = 16058 UserHandle.getUid(testHandle.getIdentifier(), TEST_APP_ID); 16059 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder1 = 16060 new ProfileNetworkPreference.Builder(); 16061 profileNetworkPreferenceBuilder1.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE); 16062 profileNetworkPreferenceBuilder1.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1); 16063 profileNetworkPreferenceBuilder1.setIncludedUids(new int[]{testWorkProfileAppUid1}); 16064 16065 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder2 = 16066 new ProfileNetworkPreference.Builder(); 16067 profileNetworkPreferenceBuilder2.setPreference(PROFILE_NETWORK_PREFERENCE_DEFAULT); 16068 final TestOnCompleteListener listener = new TestOnCompleteListener(); 16069 Assert.assertThrows(IllegalArgumentException.class, 16070 () -> mCm.setProfileNetworkPreferences( 16071 testHandle, List.of(profileNetworkPreferenceBuilder1.build(), 16072 profileNetworkPreferenceBuilder2.build()), 16073 r -> r.run(), listener)); 16074 Assert.assertThrows(IllegalArgumentException.class, 16075 () -> mCm.setProfileNetworkPreferences( 16076 testHandle, List.of(profileNetworkPreferenceBuilder2.build(), 16077 profileNetworkPreferenceBuilder1.build()), 16078 r -> r.run(), listener)); 16079 } 16080 16081 /** 16082 * Make sure per profile network preferences behave as expected when two slices with 16083 * two different apps within same user profile is configured 16084 * Make sure per profile network preferences overrides with latest preference when 16085 * same user preference is set twice 16086 */ 16087 @Test 16088 public void testSetPreferenceWithOverridingPreference() 16089 throws Exception { 16090 final InOrder inOrder = inOrder(mMockNetd); 16091 final UserHandle testHandle = setupEnterpriseNetwork(); 16092 mServiceContext.setWorkProfile(testHandle, true); 16093 registerDefaultNetworkCallbacks(); 16094 16095 final TestNetworkCallback appCb1 = new TestNetworkCallback(); 16096 final TestNetworkCallback appCb2 = new TestNetworkCallback(); 16097 final TestNetworkCallback appCb3 = new TestNetworkCallback(); 16098 16099 final int testWorkProfileAppUid1 = 16100 UserHandle.getUid(testHandle.getIdentifier(), TEST_APP_ID); 16101 final int testWorkProfileAppUid2 = 16102 UserHandle.getUid(testHandle.getIdentifier(), TEST_APP_ID_2); 16103 final int testWorkProfileAppUid3 = 16104 UserHandle.getUid(testHandle.getIdentifier(), TEST_APP_ID_3); 16105 16106 registerDefaultNetworkCallbackAsUid(appCb1, testWorkProfileAppUid1); 16107 registerDefaultNetworkCallbackAsUid(appCb2, testWorkProfileAppUid2); 16108 registerDefaultNetworkCallbackAsUid(appCb3, testWorkProfileAppUid3); 16109 16110 // Connect both a regular cell agent and an enterprise network first. 16111 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 16112 mCellAgent.connect(true); 16113 16114 final TestNetworkAgentWrapper workAgent1 = makeEnterpriseNetworkAgent(NET_ENTERPRISE_ID_1); 16115 final TestNetworkAgentWrapper workAgent2 = makeEnterpriseNetworkAgent(NET_ENTERPRISE_ID_2); 16116 workAgent1.connect(true); 16117 workAgent2.connect(true); 16118 16119 mSystemDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 16120 mDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 16121 16122 appCb1.expectAvailableThenValidatedCallbacks(mCellAgent); 16123 appCb2.expectAvailableThenValidatedCallbacks(mCellAgent); 16124 appCb3.expectAvailableThenValidatedCallbacks(mCellAgent); 16125 16126 verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( 16127 mCellAgent.getNetwork().netId, INetd.PERMISSION_NONE)); 16128 verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( 16129 workAgent1.getNetwork().netId, INetd.PERMISSION_SYSTEM)); 16130 verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( 16131 workAgent2.getNetwork().netId, INetd.PERMISSION_SYSTEM)); 16132 16133 final TestOnCompleteListener listener = new TestOnCompleteListener(); 16134 16135 // Set preferences for testHandle to map testWorkProfileAppUid1 to 16136 // NET_ENTERPRISE_ID_1 and testWorkProfileAppUid2 to NET_ENTERPRISE_ID_2. 16137 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder1 = 16138 new ProfileNetworkPreference.Builder(); 16139 profileNetworkPreferenceBuilder1.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE); 16140 profileNetworkPreferenceBuilder1.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1); 16141 profileNetworkPreferenceBuilder1.setIncludedUids(new int[]{testWorkProfileAppUid1}); 16142 16143 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder2 = 16144 new ProfileNetworkPreference.Builder(); 16145 profileNetworkPreferenceBuilder2.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE); 16146 profileNetworkPreferenceBuilder2.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_2); 16147 profileNetworkPreferenceBuilder2.setIncludedUids(new int[]{testWorkProfileAppUid2}); 16148 16149 mCm.setProfileNetworkPreferences(testHandle, 16150 List.of(profileNetworkPreferenceBuilder1.build(), 16151 profileNetworkPreferenceBuilder2.build()), 16152 r -> r.run(), listener); 16153 listener.expectOnComplete(); 16154 verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 16155 workAgent2.getNetwork().netId, 16156 uidRangeFor(testHandle, profileNetworkPreferenceBuilder2.build()), 16157 PREFERENCE_ORDER_PROFILE)); 16158 verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 16159 workAgent1.getNetwork().netId, 16160 uidRangeFor(testHandle, profileNetworkPreferenceBuilder1.build()), 16161 PREFERENCE_ORDER_PROFILE)); 16162 16163 assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback); 16164 appCb1.expectAvailableCallbacksValidated(workAgent1); 16165 appCb2.expectAvailableCallbacksValidated(workAgent2); 16166 16167 // Set preferences for testHandle to map testWorkProfileAppUid3 to 16168 // to NET_ENTERPRISE_ID_1. 16169 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder3 = 16170 new ProfileNetworkPreference.Builder(); 16171 profileNetworkPreferenceBuilder3.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE); 16172 profileNetworkPreferenceBuilder3.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1); 16173 profileNetworkPreferenceBuilder3.setIncludedUids(new int[]{testWorkProfileAppUid3}); 16174 16175 mCm.setProfileNetworkPreferences(testHandle, 16176 List.of(profileNetworkPreferenceBuilder3.build()), 16177 r -> r.run(), listener); 16178 listener.expectOnComplete(); 16179 verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 16180 workAgent1.getNetwork().netId, 16181 uidRangeFor(testHandle, profileNetworkPreferenceBuilder3.build()), 16182 PREFERENCE_ORDER_PROFILE)); 16183 verify(mMockNetd).networkRemoveUidRangesParcel(new NativeUidRangeConfig( 16184 workAgent2.getNetwork().netId, 16185 uidRangeFor(testHandle, profileNetworkPreferenceBuilder2.build()), 16186 PREFERENCE_ORDER_PROFILE)); 16187 verify(mMockNetd).networkRemoveUidRangesParcel(new NativeUidRangeConfig( 16188 workAgent1.getNetwork().netId, 16189 uidRangeFor(testHandle, profileNetworkPreferenceBuilder1.build()), 16190 PREFERENCE_ORDER_PROFILE)); 16191 16192 assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback); 16193 appCb3.expectAvailableCallbacksValidated(workAgent1); 16194 appCb2.expectAvailableCallbacksValidated(mCellAgent); 16195 appCb1.expectAvailableCallbacksValidated(mCellAgent); 16196 16197 // Set the preferences for testHandle to default. 16198 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder = 16199 new ProfileNetworkPreference.Builder(); 16200 profileNetworkPreferenceBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_DEFAULT); 16201 16202 mCm.setProfileNetworkPreferences(testHandle, 16203 List.of(profileNetworkPreferenceBuilder.build()), 16204 r -> r.run(), listener); 16205 listener.expectOnComplete(); 16206 verify(mMockNetd).networkRemoveUidRangesParcel(new NativeUidRangeConfig( 16207 workAgent1.getNetwork().netId, 16208 uidRangeFor(testHandle, profileNetworkPreferenceBuilder3.build()), 16209 PREFERENCE_ORDER_PROFILE)); 16210 16211 assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback, appCb1, appCb2); 16212 appCb3.expectAvailableCallbacksValidated(mCellAgent); 16213 workAgent2.disconnect(); 16214 mCellAgent.disconnect(); 16215 16216 mCm.unregisterNetworkCallback(appCb1); 16217 mCm.unregisterNetworkCallback(appCb2); 16218 mCm.unregisterNetworkCallback(appCb3); 16219 // Other callbacks will be unregistered by tearDown() 16220 } 16221 16222 /** 16223 * Make sure per profile network preferences behave as expected when multiple slices with 16224 * multiple different apps within same user profile is configured. 16225 */ 16226 @Test 16227 public void testSetPreferenceWithMultiplePreferences() 16228 throws Exception { 16229 final InOrder inOrder = inOrder(mMockNetd); 16230 16231 final UserHandle testHandle = setupEnterpriseNetwork(); 16232 mServiceContext.setWorkProfile(testHandle, true); 16233 registerDefaultNetworkCallbacks(); 16234 16235 final TestNetworkCallback appCb1 = new TestNetworkCallback(); 16236 final TestNetworkCallback appCb2 = new TestNetworkCallback(); 16237 final TestNetworkCallback appCb3 = new TestNetworkCallback(); 16238 final TestNetworkCallback appCb4 = new TestNetworkCallback(); 16239 final TestNetworkCallback appCb5 = new TestNetworkCallback(); 16240 16241 final int testWorkProfileAppUid1 = 16242 UserHandle.getUid(testHandle.getIdentifier(), TEST_APP_ID); 16243 final int testWorkProfileAppUid2 = 16244 UserHandle.getUid(testHandle.getIdentifier(), TEST_APP_ID_2); 16245 final int testWorkProfileAppUid3 = 16246 UserHandle.getUid(testHandle.getIdentifier(), TEST_APP_ID_3); 16247 final int testWorkProfileAppUid4 = 16248 UserHandle.getUid(testHandle.getIdentifier(), TEST_APP_ID_4); 16249 final int testWorkProfileAppUid5 = 16250 UserHandle.getUid(testHandle.getIdentifier(), TEST_APP_ID_5); 16251 16252 registerDefaultNetworkCallbackAsUid(appCb1, testWorkProfileAppUid1); 16253 registerDefaultNetworkCallbackAsUid(appCb2, testWorkProfileAppUid2); 16254 registerDefaultNetworkCallbackAsUid(appCb3, testWorkProfileAppUid3); 16255 registerDefaultNetworkCallbackAsUid(appCb4, testWorkProfileAppUid4); 16256 registerDefaultNetworkCallbackAsUid(appCb5, testWorkProfileAppUid5); 16257 16258 // Connect both a regular cell agent and an enterprise network first. 16259 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 16260 mCellAgent.connect(true); 16261 16262 final TestNetworkAgentWrapper workAgent1 = makeEnterpriseNetworkAgent(NET_ENTERPRISE_ID_1); 16263 final TestNetworkAgentWrapper workAgent2 = makeEnterpriseNetworkAgent(NET_ENTERPRISE_ID_2); 16264 final TestNetworkAgentWrapper workAgent3 = makeEnterpriseNetworkAgent(NET_ENTERPRISE_ID_3); 16265 final TestNetworkAgentWrapper workAgent4 = makeEnterpriseNetworkAgent(NET_ENTERPRISE_ID_4); 16266 final TestNetworkAgentWrapper workAgent5 = makeEnterpriseNetworkAgent(NET_ENTERPRISE_ID_5); 16267 16268 workAgent1.connect(true); 16269 workAgent2.connect(true); 16270 workAgent3.connect(true); 16271 workAgent4.connect(true); 16272 workAgent5.connect(true); 16273 16274 mSystemDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 16275 mDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 16276 appCb1.expectAvailableThenValidatedCallbacks(mCellAgent); 16277 appCb2.expectAvailableThenValidatedCallbacks(mCellAgent); 16278 appCb3.expectAvailableThenValidatedCallbacks(mCellAgent); 16279 appCb4.expectAvailableThenValidatedCallbacks(mCellAgent); 16280 appCb5.expectAvailableThenValidatedCallbacks(mCellAgent); 16281 16282 verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( 16283 mCellAgent.getNetwork().netId, INetd.PERMISSION_NONE)); 16284 verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( 16285 workAgent1.getNetwork().netId, INetd.PERMISSION_SYSTEM)); 16286 verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( 16287 workAgent2.getNetwork().netId, INetd.PERMISSION_SYSTEM)); 16288 verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( 16289 workAgent3.getNetwork().netId, INetd.PERMISSION_SYSTEM)); 16290 verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( 16291 workAgent4.getNetwork().netId, INetd.PERMISSION_SYSTEM)); 16292 verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( 16293 workAgent5.getNetwork().netId, INetd.PERMISSION_SYSTEM)); 16294 16295 final TestOnCompleteListener listener = new TestOnCompleteListener(); 16296 16297 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder1 = 16298 new ProfileNetworkPreference.Builder(); 16299 profileNetworkPreferenceBuilder1.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE); 16300 profileNetworkPreferenceBuilder1.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1); 16301 profileNetworkPreferenceBuilder1.setIncludedUids(new int[]{testWorkProfileAppUid1}); 16302 16303 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder2 = 16304 new ProfileNetworkPreference.Builder(); 16305 profileNetworkPreferenceBuilder2.setPreference( 16306 PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK); 16307 profileNetworkPreferenceBuilder2.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_2); 16308 profileNetworkPreferenceBuilder2.setIncludedUids(new int[]{testWorkProfileAppUid2}); 16309 16310 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder3 = 16311 new ProfileNetworkPreference.Builder(); 16312 profileNetworkPreferenceBuilder3.setPreference( 16313 PROFILE_NETWORK_PREFERENCE_ENTERPRISE); 16314 profileNetworkPreferenceBuilder3.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_3); 16315 profileNetworkPreferenceBuilder3.setIncludedUids(new int[]{testWorkProfileAppUid3}); 16316 16317 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder4 = 16318 new ProfileNetworkPreference.Builder(); 16319 profileNetworkPreferenceBuilder4.setPreference( 16320 PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK); 16321 profileNetworkPreferenceBuilder4.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_4); 16322 profileNetworkPreferenceBuilder4.setIncludedUids(new int[]{testWorkProfileAppUid4}); 16323 16324 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder5 = 16325 new ProfileNetworkPreference.Builder(); 16326 profileNetworkPreferenceBuilder5.setPreference( 16327 PROFILE_NETWORK_PREFERENCE_ENTERPRISE); 16328 profileNetworkPreferenceBuilder5.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_5); 16329 profileNetworkPreferenceBuilder5.setIncludedUids(new int[]{testWorkProfileAppUid5}); 16330 16331 mCm.setProfileNetworkPreferences(testHandle, 16332 List.of(profileNetworkPreferenceBuilder1.build(), 16333 profileNetworkPreferenceBuilder2.build(), 16334 profileNetworkPreferenceBuilder3.build(), 16335 profileNetworkPreferenceBuilder4.build(), 16336 profileNetworkPreferenceBuilder5.build()), 16337 r -> r.run(), listener); 16338 16339 listener.expectOnComplete(); 16340 16341 verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 16342 workAgent1.getNetwork().netId, 16343 uidRangeFor(testHandle, profileNetworkPreferenceBuilder1.build()), 16344 PREFERENCE_ORDER_PROFILE)); 16345 verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 16346 workAgent2.getNetwork().netId, 16347 uidRangeFor(testHandle, profileNetworkPreferenceBuilder2.build()), 16348 PREFERENCE_ORDER_PROFILE)); 16349 verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 16350 workAgent3.getNetwork().netId, 16351 uidRangeFor(testHandle, profileNetworkPreferenceBuilder3.build()), 16352 PREFERENCE_ORDER_PROFILE)); 16353 verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 16354 workAgent4.getNetwork().netId, 16355 uidRangeFor(testHandle, profileNetworkPreferenceBuilder4.build()), 16356 PREFERENCE_ORDER_PROFILE)); 16357 verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 16358 workAgent5.getNetwork().netId, 16359 uidRangeFor(testHandle, profileNetworkPreferenceBuilder5.build()), 16360 PREFERENCE_ORDER_PROFILE)); 16361 16362 assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback); 16363 appCb1.expectAvailableCallbacksValidated(workAgent1); 16364 appCb2.expectAvailableCallbacksValidated(workAgent2); 16365 appCb3.expectAvailableCallbacksValidated(workAgent3); 16366 appCb4.expectAvailableCallbacksValidated(workAgent4); 16367 appCb5.expectAvailableCallbacksValidated(workAgent5); 16368 16369 workAgent1.disconnect(); 16370 workAgent2.disconnect(); 16371 workAgent3.disconnect(); 16372 workAgent4.disconnect(); 16373 workAgent5.disconnect(); 16374 16375 appCb1.expect(LOST, workAgent1); 16376 appCb2.expect(LOST, workAgent2); 16377 appCb3.expect(LOST, workAgent3); 16378 appCb4.expect(LOST, workAgent4); 16379 appCb5.expect(LOST, workAgent5); 16380 16381 appCb1.expectAvailableCallbacksValidated(mCellAgent); 16382 appCb2.assertNoCallback(); 16383 appCb3.expectAvailableCallbacksValidated(mCellAgent); 16384 appCb4.assertNoCallback(); 16385 appCb5.expectAvailableCallbacksValidated(mCellAgent); 16386 16387 verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 16388 mCellAgent.getNetwork().netId, 16389 uidRangeFor(testHandle, profileNetworkPreferenceBuilder1.build()), 16390 PREFERENCE_ORDER_PROFILE)); 16391 verify(mMockNetd, never()).networkAddUidRangesParcel(new NativeUidRangeConfig( 16392 mCellAgent.getNetwork().netId, 16393 uidRangeFor(testHandle, profileNetworkPreferenceBuilder2.build()), 16394 PREFERENCE_ORDER_PROFILE)); 16395 verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 16396 mCellAgent.getNetwork().netId, 16397 uidRangeFor(testHandle, profileNetworkPreferenceBuilder3.build()), 16398 PREFERENCE_ORDER_PROFILE)); 16399 verify(mMockNetd, never()).networkAddUidRangesParcel(new NativeUidRangeConfig( 16400 mCellAgent.getNetwork().netId, 16401 uidRangeFor(testHandle, profileNetworkPreferenceBuilder4.build()), 16402 PREFERENCE_ORDER_PROFILE)); 16403 verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 16404 mCellAgent.getNetwork().netId, 16405 uidRangeFor(testHandle, profileNetworkPreferenceBuilder5.build()), 16406 PREFERENCE_ORDER_PROFILE)); 16407 16408 mSystemDefaultNetworkCallback.assertNoCallback(); 16409 mDefaultNetworkCallback.assertNoCallback(); 16410 16411 // Set the preferences for testHandle to default. 16412 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder = 16413 new ProfileNetworkPreference.Builder(); 16414 profileNetworkPreferenceBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_DEFAULT); 16415 16416 mCm.setProfileNetworkPreferences(testHandle, 16417 List.of(profileNetworkPreferenceBuilder.build()), 16418 r -> r.run(), listener); 16419 listener.expectOnComplete(); 16420 assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback, appCb1, appCb3, 16421 appCb5); 16422 appCb2.expectAvailableCallbacksValidated(mCellAgent); 16423 appCb4.expectAvailableCallbacksValidated(mCellAgent); 16424 mCellAgent.disconnect(); 16425 16426 mCm.unregisterNetworkCallback(appCb1); 16427 mCm.unregisterNetworkCallback(appCb2); 16428 mCm.unregisterNetworkCallback(appCb3); 16429 mCm.unregisterNetworkCallback(appCb4); 16430 mCm.unregisterNetworkCallback(appCb5); 16431 // Other callbacks will be unregistered by tearDown() 16432 } 16433 16434 /** 16435 * Test that, in a given networking context, calling setPreferenceForUser to set per-profile 16436 * defaults on then off works as expected. 16437 */ 16438 @Test 16439 public void testSetPreferenceForUserOnOff() throws Exception { 16440 final InOrder inOrder = inOrder(mMockNetd); 16441 final UserHandle testHandle = setupEnterpriseNetwork(); 16442 16443 // Connect both a regular cell agent and an enterprise network first. 16444 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 16445 mCellAgent.connect(true); 16446 16447 final TestNetworkAgentWrapper workAgent = makeEnterpriseNetworkAgent(); 16448 workAgent.connect(true); 16449 16450 final TestOnCompleteListener listener = new TestOnCompleteListener(); 16451 mCm.setProfileNetworkPreference(testHandle, PROFILE_NETWORK_PREFERENCE_ENTERPRISE, 16452 r -> r.run(), listener); 16453 listener.expectOnComplete(); 16454 inOrder.verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( 16455 mCellAgent.getNetwork().netId, INetd.PERMISSION_NONE)); 16456 inOrder.verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 16457 workAgent.getNetwork().netId, uidRangeFor(testHandle), PREFERENCE_ORDER_PROFILE)); 16458 16459 registerDefaultNetworkCallbacks(); 16460 16461 mSystemDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellAgent); 16462 mDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellAgent); 16463 mProfileDefaultNetworkCallback.expectAvailableCallbacksValidated(workAgent); 16464 16465 mCm.setProfileNetworkPreference(testHandle, PROFILE_NETWORK_PREFERENCE_DEFAULT, 16466 r -> r.run(), listener); 16467 listener.expectOnComplete(); 16468 16469 mProfileDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellAgent); 16470 assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback); 16471 inOrder.verify(mMockNetd).networkRemoveUidRangesParcel(new NativeUidRangeConfig( 16472 workAgent.getNetwork().netId, uidRangeFor(testHandle), PREFERENCE_ORDER_PROFILE)); 16473 16474 workAgent.disconnect(); 16475 mCellAgent.disconnect(); 16476 16477 // Callbacks will be unregistered by tearDown() 16478 } 16479 16480 /** 16481 * Test per-profile default networks for two different profiles concurrently. 16482 */ 16483 @Test 16484 public void testSetPreferenceForTwoProfiles() throws Exception { 16485 final InOrder inOrder = inOrder(mMockNetd); 16486 final UserHandle testHandle2 = setupEnterpriseNetwork(); 16487 final UserHandle testHandle4 = UserHandle.of(TEST_WORK_PROFILE_USER_ID + 2); 16488 mServiceContext.setWorkProfile(testHandle4, true); 16489 registerDefaultNetworkCallbacks(); 16490 16491 final TestNetworkCallback app4Cb = new TestNetworkCallback(); 16492 final int testWorkProfileAppUid4 = 16493 UserHandle.getUid(testHandle4.getIdentifier(), TEST_APP_ID); 16494 registerDefaultNetworkCallbackAsUid(app4Cb, testWorkProfileAppUid4); 16495 16496 // Connect both a regular cell agent and an enterprise network first. 16497 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 16498 mCellAgent.connect(true); 16499 16500 final TestNetworkAgentWrapper workAgent = makeEnterpriseNetworkAgent(); 16501 workAgent.connect(true); 16502 16503 mSystemDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 16504 mDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 16505 mProfileDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 16506 app4Cb.expectAvailableThenValidatedCallbacks(mCellAgent); 16507 inOrder.verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( 16508 mCellAgent.getNetwork().netId, INetd.PERMISSION_NONE)); 16509 inOrder.verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( 16510 workAgent.getNetwork().netId, INetd.PERMISSION_SYSTEM)); 16511 16512 final TestOnCompleteListener listener = new TestOnCompleteListener(); 16513 mCm.setProfileNetworkPreference(testHandle2, PROFILE_NETWORK_PREFERENCE_ENTERPRISE, 16514 r -> r.run(), listener); 16515 listener.expectOnComplete(); 16516 inOrder.verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 16517 workAgent.getNetwork().netId, uidRangeFor(testHandle2), PREFERENCE_ORDER_PROFILE)); 16518 16519 mProfileDefaultNetworkCallback.expectAvailableCallbacksValidated(workAgent); 16520 assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback, 16521 app4Cb); 16522 16523 mCm.setProfileNetworkPreference(testHandle4, PROFILE_NETWORK_PREFERENCE_ENTERPRISE, 16524 r -> r.run(), listener); 16525 listener.expectOnComplete(); 16526 inOrder.verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 16527 workAgent.getNetwork().netId, uidRangeFor(testHandle4), PREFERENCE_ORDER_PROFILE)); 16528 16529 app4Cb.expectAvailableCallbacksValidated(workAgent); 16530 assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback, 16531 mProfileDefaultNetworkCallback); 16532 16533 mCm.setProfileNetworkPreference(testHandle2, PROFILE_NETWORK_PREFERENCE_DEFAULT, 16534 r -> r.run(), listener); 16535 listener.expectOnComplete(); 16536 inOrder.verify(mMockNetd).networkRemoveUidRangesParcel(new NativeUidRangeConfig( 16537 workAgent.getNetwork().netId, uidRangeFor(testHandle2), PREFERENCE_ORDER_PROFILE)); 16538 16539 mProfileDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellAgent); 16540 assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback, 16541 app4Cb); 16542 16543 workAgent.disconnect(); 16544 mCellAgent.disconnect(); 16545 16546 mCm.unregisterNetworkCallback(app4Cb); 16547 // Other callbacks will be unregistered by tearDown() 16548 } 16549 16550 @Test 16551 public void testProfilePreferenceRemovedUponUserRemoved() throws Exception { 16552 final InOrder inOrder = inOrder(mMockNetd); 16553 final UserHandle testHandle = setupEnterpriseNetwork(); 16554 16555 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 16556 mCellAgent.connect(true); 16557 16558 final TestOnCompleteListener listener = new TestOnCompleteListener(); 16559 mCm.setProfileNetworkPreference(testHandle, PROFILE_NETWORK_PREFERENCE_ENTERPRISE, 16560 r -> r.run(), listener); 16561 listener.expectOnComplete(); 16562 inOrder.verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( 16563 mCellAgent.getNetwork().netId, INetd.PERMISSION_NONE)); 16564 inOrder.verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 16565 mCellAgent.getNetwork().netId, uidRangeFor(testHandle), 16566 PREFERENCE_ORDER_PROFILE)); 16567 16568 final Intent removedIntent = new Intent(ACTION_USER_REMOVED); 16569 removedIntent.putExtra(Intent.EXTRA_USER, testHandle); 16570 processBroadcast(removedIntent); 16571 16572 inOrder.verify(mMockNetd).networkRemoveUidRangesParcel(new NativeUidRangeConfig( 16573 mCellAgent.getNetwork().netId, uidRangeFor(testHandle), 16574 PREFERENCE_ORDER_PROFILE)); 16575 } 16576 16577 @Test 16578 public void testProfileNetworkPreferenceBlocking_addUser() throws Exception { 16579 final InOrder inOrder = inOrder(mMockNetd); 16580 doReturn(asList(PRIMARY_USER_HANDLE)).when(mUserManager).getUserHandles(anyBoolean()); 16581 16582 // Only one network 16583 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 16584 mCellAgent.connect(true); 16585 16586 // Verify uid ranges 0~99999 are allowed 16587 final ArraySet<UidRange> allowedRanges = new ArraySet<>(); 16588 allowedRanges.add(PRIMARY_UIDRANGE); 16589 final NativeUidRangeConfig config1User = new NativeUidRangeConfig( 16590 mCellAgent.getNetwork().netId, 16591 toUidRangeStableParcels(allowedRanges), 16592 0 /* subPriority */); 16593 if (mDeps.isAtLeastU()) { 16594 inOrder.verify(mMockNetd).setNetworkAllowlist(new NativeUidRangeConfig[]{config1User}); 16595 } else { 16596 inOrder.verify(mMockNetd, never()).setNetworkAllowlist(any()); 16597 } 16598 16599 doReturn(asList(PRIMARY_USER_HANDLE, SECONDARY_USER_HANDLE)) 16600 .when(mUserManager).getUserHandles(anyBoolean()); 16601 final Intent addedIntent = new Intent(ACTION_USER_ADDED); 16602 addedIntent.putExtra(Intent.EXTRA_USER, UserHandle.of(SECONDARY_USER)); 16603 processBroadcast(addedIntent); 16604 16605 // Make sure the allow list has been updated. 16606 allowedRanges.add(UidRange.createForUser(SECONDARY_USER_HANDLE)); 16607 final NativeUidRangeConfig config2Users = new NativeUidRangeConfig( 16608 mCellAgent.getNetwork().netId, 16609 toUidRangeStableParcels(allowedRanges), 16610 0 /* subPriority */); 16611 if (mDeps.isAtLeastU()) { 16612 inOrder.verify(mMockNetd).setNetworkAllowlist(new NativeUidRangeConfig[]{config2Users}); 16613 } else { 16614 inOrder.verify(mMockNetd, never()).setNetworkAllowlist(any()); 16615 } 16616 } 16617 16618 @Test 16619 public void testProfileNetworkPreferenceBlocking_changePreference() throws Exception { 16620 final InOrder inOrder = inOrder(mMockNetd); 16621 final UserHandle testHandle = setupEnterpriseNetwork(); 16622 doReturn(asList(PRIMARY_USER_HANDLE, testHandle)) 16623 .when(mUserManager).getUserHandles(anyBoolean()); 16624 16625 // Start with 1 default network and 1 enterprise network, both networks should 16626 // not be restricted since the blocking preference is not set yet. 16627 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 16628 mCellAgent.connect(true); 16629 16630 // Verify uid ranges 0~99999, 200000~299999 are all allowed for cellular. 16631 final UidRange profileUidRange = 16632 UidRange.createForUser(UserHandle.of(TEST_WORK_PROFILE_USER_ID)); 16633 ArraySet<UidRange> allowedAllUidRanges = new ArraySet<>(); 16634 allowedAllUidRanges.add(PRIMARY_UIDRANGE); 16635 allowedAllUidRanges.add(profileUidRange); 16636 final UidRangeParcel[] allowAllUidRangesParcel = toUidRangeStableParcels( 16637 allowedAllUidRanges); 16638 final NativeUidRangeConfig cellAllAllowedConfig = new NativeUidRangeConfig( 16639 mCellAgent.getNetwork().netId, 16640 allowAllUidRangesParcel, 16641 0 /* subPriority */); 16642 if (mDeps.isAtLeastU()) { 16643 inOrder.verify(mMockNetd).setNetworkAllowlist( 16644 new NativeUidRangeConfig[]{cellAllAllowedConfig}); 16645 } else { 16646 inOrder.verify(mMockNetd, never()).setNetworkAllowlist(any()); 16647 } 16648 16649 // Verify the same uid ranges are also applied for enterprise network. 16650 final TestNetworkAgentWrapper enterpriseAgent = makeEnterpriseNetworkAgent( 16651 NET_ENTERPRISE_ID_1); 16652 enterpriseAgent.connect(true); 16653 final NativeUidRangeConfig enterpriseAllAllowedConfig = new NativeUidRangeConfig( 16654 enterpriseAgent.getNetwork().netId, 16655 allowAllUidRangesParcel, 16656 0 /* subPriority */); 16657 // Network agents are stored in an ArraySet which does not guarantee the order and 16658 // making the order of the list undeterministic. Thus, verify this in order insensitive way. 16659 final ArgumentCaptor<NativeUidRangeConfig[]> configsCaptor = ArgumentCaptor.forClass( 16660 NativeUidRangeConfig[].class); 16661 if (mDeps.isAtLeastU()) { 16662 inOrder.verify(mMockNetd).setNetworkAllowlist(configsCaptor.capture()); 16663 assertContainsAll(List.of(configsCaptor.getValue()), 16664 List.of(cellAllAllowedConfig, enterpriseAllAllowedConfig)); 16665 } else { 16666 inOrder.verify(mMockNetd, never()).setNetworkAllowlist(any()); 16667 } 16668 16669 // Setup profile preference which only applies to test app uid on the managed profile. 16670 ProfileNetworkPreference.Builder prefBuilder = new ProfileNetworkPreference.Builder(); 16671 prefBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE_BLOCKING) 16672 .setIncludedUids(new int[]{testHandle.getUid(TEST_WORK_PROFILE_APP_UID)}) 16673 .setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1); 16674 final TestOnCompleteListener listener = new TestOnCompleteListener(); 16675 mCm.setProfileNetworkPreferences(testHandle, 16676 List.of(prefBuilder.build()), 16677 r -> r.run(), listener); 16678 listener.expectOnComplete(); 16679 16680 // Verify Netd is called for the preferences changed. 16681 // Cell: 0~99999, 200000~TEST_APP_UID-1, TEST_APP_UID+1~299999 16682 // Enterprise: 0~99999, 200000~299999 16683 final ArraySet<UidRange> excludeAppRanges = new ArraySet<>(); 16684 excludeAppRanges.add(PRIMARY_UIDRANGE); 16685 excludeAppRanges.addAll(UidRangeUtils.removeRangeSetFromUidRange( 16686 profileUidRange, 16687 new ArraySet(new UidRange[]{ 16688 (new UidRange(TEST_WORK_PROFILE_APP_UID, TEST_WORK_PROFILE_APP_UID))}) 16689 )); 16690 final UidRangeParcel[] excludeAppRangesParcel = toUidRangeStableParcels(excludeAppRanges); 16691 final NativeUidRangeConfig cellExcludeAppConfig = new NativeUidRangeConfig( 16692 mCellAgent.getNetwork().netId, 16693 excludeAppRangesParcel, 16694 0 /* subPriority */); 16695 if (mDeps.isAtLeastU()) { 16696 inOrder.verify(mMockNetd).setNetworkAllowlist(configsCaptor.capture()); 16697 assertContainsAll(List.of(configsCaptor.getValue()), 16698 List.of(cellExcludeAppConfig, enterpriseAllAllowedConfig)); 16699 } else { 16700 inOrder.verify(mMockNetd, never()).setNetworkAllowlist(any()); 16701 } 16702 16703 // Verify unset by giving all allowed set for all users when the preference got removed. 16704 mCm.setProfileNetworkPreference(testHandle, PROFILE_NETWORK_PREFERENCE_ENTERPRISE, 16705 r -> r.run(), listener); 16706 listener.expectOnComplete(); 16707 if (mDeps.isAtLeastU()) { 16708 inOrder.verify(mMockNetd).setNetworkAllowlist(configsCaptor.capture()); 16709 assertContainsAll(List.of(configsCaptor.getValue()), 16710 List.of(cellAllAllowedConfig, enterpriseAllAllowedConfig)); 16711 } else { 16712 inOrder.verify(mMockNetd, never()).setNetworkAllowlist(any()); 16713 } 16714 16715 // Verify issuing with cellular set only when a network with enterprise capability 16716 // disconnects. 16717 enterpriseAgent.disconnect(); 16718 waitForIdle(); 16719 if (mDeps.isAtLeastU()) { 16720 inOrder.verify(mMockNetd).setNetworkAllowlist( 16721 new NativeUidRangeConfig[]{cellAllAllowedConfig}); 16722 } else { 16723 inOrder.verify(mMockNetd, never()).setNetworkAllowlist(any()); 16724 } 16725 } 16726 16727 @Test 16728 public void testProfileNetworkPreferenceBlocking_networkChanges() throws Exception { 16729 final InOrder inOrder = inOrder(mMockNetd); 16730 final UserHandle testHandle = setupEnterpriseNetwork(); 16731 doReturn(asList(PRIMARY_USER_HANDLE, testHandle)) 16732 .when(mUserManager).getUserHandles(anyBoolean()); 16733 16734 // Setup profile preference which only applies to test app uid on the managed profile. 16735 ProfileNetworkPreference.Builder prefBuilder = new ProfileNetworkPreference.Builder(); 16736 prefBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE_BLOCKING) 16737 .setIncludedUids(new int[]{testHandle.getUid(TEST_WORK_PROFILE_APP_UID)}) 16738 .setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1); 16739 final TestOnCompleteListener listener = new TestOnCompleteListener(); 16740 mCm.setProfileNetworkPreferences(testHandle, 16741 List.of(prefBuilder.build()), 16742 r -> r.run(), listener); 16743 listener.expectOnComplete(); 16744 if (mDeps.isAtLeastU()) { 16745 inOrder.verify(mMockNetd).setNetworkAllowlist(new NativeUidRangeConfig[]{}); 16746 } else { 16747 inOrder.verify(mMockNetd, never()).setNetworkAllowlist(any()); 16748 } 16749 16750 // Start with 1 default network, which should be restricted since the blocking 16751 // preference is already set. 16752 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 16753 mCellAgent.connect(true); 16754 16755 // Verify cellular network applies to the allow list. 16756 // Cell: 0~99999, 200000~TEST_APP_UID-1, TEST_APP_UID+1~299999 16757 // Enterprise: 0~99999, 200000~299999 16758 final ArraySet<UidRange> excludeAppRanges = new ArraySet<>(); 16759 final UidRange profileUidRange = 16760 UidRange.createForUser(UserHandle.of(TEST_WORK_PROFILE_USER_ID)); 16761 excludeAppRanges.add(PRIMARY_UIDRANGE); 16762 excludeAppRanges.addAll(UidRangeUtils.removeRangeSetFromUidRange( 16763 profileUidRange, 16764 new ArraySet(new UidRange[]{ 16765 (new UidRange(TEST_WORK_PROFILE_APP_UID, TEST_WORK_PROFILE_APP_UID))}) 16766 )); 16767 final UidRangeParcel[] excludeAppRangesParcel = toUidRangeStableParcels(excludeAppRanges); 16768 final NativeUidRangeConfig cellExcludeAppConfig = new NativeUidRangeConfig( 16769 mCellAgent.getNetwork().netId, 16770 excludeAppRangesParcel, 16771 0 /* subPriority */); 16772 if (mDeps.isAtLeastU()) { 16773 inOrder.verify(mMockNetd).setNetworkAllowlist( 16774 new NativeUidRangeConfig[]{cellExcludeAppConfig}); 16775 } else { 16776 inOrder.verify(mMockNetd, never()).setNetworkAllowlist(any()); 16777 } 16778 16779 // Verify enterprise network is not blocked for test app. 16780 final TestNetworkAgentWrapper enterpriseAgent = makeEnterpriseNetworkAgent( 16781 NET_ENTERPRISE_ID_1); 16782 enterpriseAgent.connect(true); 16783 ArraySet<UidRange> allowedAllUidRanges = new ArraySet<>(); 16784 allowedAllUidRanges.add(PRIMARY_UIDRANGE); 16785 allowedAllUidRanges.add(profileUidRange); 16786 final UidRangeParcel[] allowAllUidRangesParcel = toUidRangeStableParcels( 16787 allowedAllUidRanges); 16788 final NativeUidRangeConfig enterpriseAllAllowedConfig = new NativeUidRangeConfig( 16789 enterpriseAgent.getNetwork().netId, 16790 allowAllUidRangesParcel, 16791 0 /* subPriority */); 16792 // Network agents are stored in an ArraySet which does not guarantee the order and 16793 // making the order of the list undeterministic. Thus, verify this in order insensitive way. 16794 final ArgumentCaptor<NativeUidRangeConfig[]> configsCaptor = ArgumentCaptor.forClass( 16795 NativeUidRangeConfig[].class); 16796 if (mDeps.isAtLeastU()) { 16797 inOrder.verify(mMockNetd).setNetworkAllowlist(configsCaptor.capture()); 16798 assertContainsAll(List.of(configsCaptor.getValue()), 16799 List.of(enterpriseAllAllowedConfig, cellExcludeAppConfig)); 16800 } else { 16801 inOrder.verify(mMockNetd, never()).setNetworkAllowlist(any()); 16802 } 16803 16804 // Verify issuing with cellular set only when enterprise network disconnects. 16805 enterpriseAgent.disconnect(); 16806 waitForIdle(); 16807 if (mDeps.isAtLeastU()) { 16808 inOrder.verify(mMockNetd).setNetworkAllowlist( 16809 new NativeUidRangeConfig[]{cellExcludeAppConfig}); 16810 } else { 16811 inOrder.verify(mMockNetd, never()).setNetworkAllowlist(any()); 16812 } 16813 16814 mCellAgent.disconnect(); 16815 waitForIdle(); 16816 if (mDeps.isAtLeastU()) { 16817 inOrder.verify(mMockNetd).setNetworkAllowlist(new NativeUidRangeConfig[]{}); 16818 } else { 16819 inOrder.verify(mMockNetd, never()).setNetworkAllowlist(any()); 16820 } 16821 } 16822 16823 /** 16824 * Make sure wrong preferences for per-profile default networking are rejected. 16825 */ 16826 @Test 16827 public void testProfileNetworkPrefWrongPreference() throws Exception { 16828 final UserHandle testHandle = UserHandle.of(TEST_WORK_PROFILE_USER_ID); 16829 mServiceContext.setWorkProfile(testHandle, true); 16830 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder = 16831 new ProfileNetworkPreference.Builder(); 16832 profileNetworkPreferenceBuilder.setPreference( 16833 PROFILE_NETWORK_PREFERENCE_ENTERPRISE_BLOCKING + 1); 16834 profileNetworkPreferenceBuilder.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1); 16835 assertThrows("Should not be able to set an illegal preference", 16836 IllegalArgumentException.class, 16837 () -> mCm.setProfileNetworkPreferences(testHandle, 16838 List.of(profileNetworkPreferenceBuilder.build()), 16839 null, null)); 16840 } 16841 16842 /** 16843 * Make sure requests for per-profile default networking for a non-work profile are 16844 * rejected 16845 */ 16846 @Test 16847 public void testProfileNetworkPrefWrongProfile() throws Exception { 16848 final UserHandle testHandle = UserHandle.of(TEST_WORK_PROFILE_USER_ID); 16849 mServiceContext.setWorkProfile(testHandle, false); 16850 mServiceContext.setDeviceOwner(testHandle, null); 16851 assertThrows("Should not be able to set a user pref for a non-work profile " 16852 + "and non device owner", 16853 IllegalArgumentException.class , () -> 16854 mCm.setProfileNetworkPreference(testHandle, 16855 PROFILE_NETWORK_PREFERENCE_ENTERPRISE, null, null)); 16856 } 16857 16858 /** 16859 * Make sure requests for per-profile default networking for a device owner is 16860 * accepted on T and not accepted on S 16861 */ 16862 @Test 16863 public void testProfileNetworkDeviceOwner() throws Exception { 16864 final UserHandle testHandle = UserHandle.of(TEST_WORK_PROFILE_USER_ID); 16865 mServiceContext.setWorkProfile(testHandle, false); 16866 mServiceContext.setDeviceOwner(testHandle, "deviceOwnerPackage"); 16867 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder = 16868 new ProfileNetworkPreference.Builder(); 16869 profileNetworkPreferenceBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE); 16870 profileNetworkPreferenceBuilder.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1); 16871 final TestOnCompleteListener listener = new TestOnCompleteListener(); 16872 if (mDeps.isAtLeastT()) { 16873 mCm.setProfileNetworkPreferences(testHandle, 16874 List.of(profileNetworkPreferenceBuilder.build()), 16875 r -> r.run(), listener); 16876 } else { 16877 // S should not allow setting preference on device owner 16878 assertThrows("Should not be able to set a user pref for a non-work profile on S", 16879 IllegalArgumentException.class , () -> 16880 mCm.setProfileNetworkPreferences(testHandle, 16881 List.of(profileNetworkPreferenceBuilder.build()), 16882 r -> r.run(), listener)); 16883 } 16884 } 16885 16886 @Test 16887 public void testSubIdsClearedWithoutNetworkFactoryPermission() throws Exception { 16888 mServiceContext.setPermission(NETWORK_FACTORY, PERMISSION_DENIED); 16889 final NetworkCapabilities nc = new NetworkCapabilities(); 16890 nc.setSubscriptionIds(Collections.singleton(Process.myUid())); 16891 16892 final NetworkCapabilities result = 16893 mService.networkCapabilitiesRestrictedForCallerPermissions( 16894 nc, Process.myPid(), Process.myUid()); 16895 assertTrue(result.getSubscriptionIds().isEmpty()); 16896 } 16897 16898 @Test 16899 public void testSubIdsExistWithNetworkFactoryPermission() throws Exception { 16900 mServiceContext.setPermission(NETWORK_FACTORY, PERMISSION_GRANTED); 16901 16902 final Set<Integer> subIds = Collections.singleton(Process.myUid()); 16903 final NetworkCapabilities nc = new NetworkCapabilities(); 16904 nc.setSubscriptionIds(subIds); 16905 16906 final NetworkCapabilities result = 16907 mService.networkCapabilitiesRestrictedForCallerPermissions( 16908 nc, Process.myPid(), Process.myUid()); 16909 assertEquals(subIds, result.getSubscriptionIds()); 16910 } 16911 16912 private NetworkRequest getRequestWithSubIds() { 16913 return new NetworkRequest.Builder() 16914 .setSubscriptionIds(Collections.singleton(Process.myUid())) 16915 .build(); 16916 } 16917 16918 @Test 16919 public void testNetworkRequestWithSubIdsWithNetworkFactoryPermission() throws Exception { 16920 mServiceContext.setPermission(NETWORK_FACTORY, PERMISSION_GRANTED); 16921 final PendingIntent pendingIntent = PendingIntent.getBroadcast( 16922 mContext, 0 /* requestCode */, new Intent("a"), FLAG_IMMUTABLE); 16923 final NetworkCallback networkCallback1 = new NetworkCallback(); 16924 final NetworkCallback networkCallback2 = new NetworkCallback(); 16925 16926 mCm.requestNetwork(getRequestWithSubIds(), networkCallback1); 16927 mCm.requestNetwork(getRequestWithSubIds(), pendingIntent); 16928 mCm.registerNetworkCallback(getRequestWithSubIds(), networkCallback2); 16929 16930 mCm.unregisterNetworkCallback(networkCallback1); 16931 mCm.releaseNetworkRequest(pendingIntent); 16932 mCm.unregisterNetworkCallback(networkCallback2); 16933 } 16934 16935 @Test 16936 public void testNetworkRequestWithSubIdsWithoutNetworkFactoryPermission() throws Exception { 16937 mServiceContext.setPermission(NETWORK_FACTORY, PERMISSION_DENIED); 16938 final PendingIntent pendingIntent = PendingIntent.getBroadcast( 16939 mContext, 0 /* requestCode */, new Intent("a"), FLAG_IMMUTABLE); 16940 16941 final Class<SecurityException> expected = SecurityException.class; 16942 assertThrows( 16943 expected, () -> mCm.requestNetwork(getRequestWithSubIds(), new NetworkCallback())); 16944 assertThrows(expected, () -> mCm.requestNetwork(getRequestWithSubIds(), pendingIntent)); 16945 assertThrows( 16946 expected, 16947 () -> mCm.registerNetworkCallback(getRequestWithSubIds(), new NetworkCallback())); 16948 } 16949 16950 @Test 16951 public void testAllowedUids() throws Exception { 16952 final int preferenceOrder = 16953 ConnectivityService.PREFERENCE_ORDER_IRRELEVANT_BECAUSE_NOT_DEFAULT; 16954 mServiceContext.setPermission(NETWORK_FACTORY, PERMISSION_GRANTED); 16955 mServiceContext.setPermission(MANAGE_TEST_NETWORKS, PERMISSION_GRANTED); 16956 final TestNetworkCallback cb = new TestNetworkCallback(); 16957 mCm.requestNetwork(new NetworkRequest.Builder() 16958 .clearCapabilities() 16959 .addTransportType(TRANSPORT_TEST) 16960 .build(), 16961 cb); 16962 16963 final ArraySet<Integer> uids = new ArraySet<>(); 16964 uids.add(200); 16965 final NetworkCapabilities nc = new NetworkCapabilities.Builder() 16966 .addTransportType(TRANSPORT_TEST) 16967 .removeCapability(NET_CAPABILITY_NOT_RESTRICTED) 16968 .setAllowedUids(uids) 16969 .build(); 16970 final TestNetworkAgentWrapper agent = new TestNetworkAgentWrapper(TRANSPORT_TEST, 16971 new LinkProperties(), nc); 16972 agent.connect(true); 16973 cb.expectAvailableThenValidatedCallbacks(agent); 16974 16975 final InOrder inOrder = inOrder(mMockNetd); 16976 final NativeUidRangeConfig uids200Parcel = new NativeUidRangeConfig( 16977 agent.getNetwork().getNetId(), 16978 intToUidRangeStableParcels(uids), 16979 preferenceOrder); 16980 if (mDeps.isAtLeastT()) { 16981 inOrder.verify(mMockNetd, times(1)).networkAddUidRangesParcel(uids200Parcel); 16982 } 16983 16984 uids.add(300); 16985 uids.add(400); 16986 nc.setAllowedUids(uids); 16987 agent.setNetworkCapabilities(nc, true /* sendToConnectivityService */); 16988 if (mDeps.isAtLeastT()) { 16989 cb.expectCaps(agent, c -> c.getAllowedUids().equals(uids)); 16990 } else { 16991 cb.assertNoCallback(); 16992 } 16993 16994 uids.remove(200); 16995 final NativeUidRangeConfig uids300400Parcel = new NativeUidRangeConfig( 16996 agent.getNetwork().getNetId(), 16997 intToUidRangeStableParcels(uids), 16998 preferenceOrder); 16999 if (mDeps.isAtLeastT()) { 17000 inOrder.verify(mMockNetd, times(1)).networkAddUidRangesParcel(uids300400Parcel); 17001 } 17002 17003 nc.setAllowedUids(uids); 17004 agent.setNetworkCapabilities(nc, true /* sendToConnectivityService */); 17005 if (mDeps.isAtLeastT()) { 17006 cb.expectCaps(agent, c -> c.getAllowedUids().equals(uids)); 17007 inOrder.verify(mMockNetd, times(1)).networkRemoveUidRangesParcel(uids200Parcel); 17008 } else { 17009 cb.assertNoCallback(); 17010 } 17011 17012 uids.clear(); 17013 uids.add(600); 17014 nc.setAllowedUids(uids); 17015 agent.setNetworkCapabilities(nc, true /* sendToConnectivityService */); 17016 if (mDeps.isAtLeastT()) { 17017 cb.expectCaps(agent, c -> c.getAllowedUids().equals(uids)); 17018 } else { 17019 cb.assertNoCallback(); 17020 } 17021 final NativeUidRangeConfig uids600Parcel = new NativeUidRangeConfig( 17022 agent.getNetwork().getNetId(), 17023 intToUidRangeStableParcels(uids), 17024 preferenceOrder); 17025 if (mDeps.isAtLeastT()) { 17026 inOrder.verify(mMockNetd, times(1)).networkAddUidRangesParcel(uids600Parcel); 17027 inOrder.verify(mMockNetd, times(1)).networkRemoveUidRangesParcel(uids300400Parcel); 17028 } 17029 17030 uids.clear(); 17031 nc.setAllowedUids(uids); 17032 agent.setNetworkCapabilities(nc, true /* sendToConnectivityService */); 17033 if (mDeps.isAtLeastT()) { 17034 cb.expectCaps(agent, c -> c.getAllowedUids().isEmpty()); 17035 inOrder.verify(mMockNetd, times(1)).networkRemoveUidRangesParcel(uids600Parcel); 17036 } else { 17037 cb.assertNoCallback(); 17038 verify(mMockNetd, never()).networkAddUidRangesParcel(any()); 17039 verify(mMockNetd, never()).networkRemoveUidRangesParcel(any()); 17040 } 17041 17042 } 17043 17044 @Test 17045 public void testAutomotiveEthernetAllowedUids() throws Exception { 17046 mServiceContext.setPermission(NETWORK_FACTORY, PERMISSION_GRANTED); 17047 mServiceContext.setPermission(MANAGE_TEST_NETWORKS, PERMISSION_GRANTED); 17048 17049 // Has automotive feature. 17050 validateAutomotiveEthernetAllowedUids(true); 17051 17052 // No automotive feature. 17053 validateAutomotiveEthernetAllowedUids(false); 17054 } 17055 17056 private void validateAutomotiveEthernetAllowedUids(final boolean hasAutomotiveFeature) 17057 throws Exception { 17058 mockHasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, hasAutomotiveFeature); 17059 17060 // Simulate a restricted ethernet network. 17061 final NetworkCapabilities.Builder ncb = new NetworkCapabilities.Builder() 17062 .addTransportType(TRANSPORT_ETHERNET) 17063 .addCapability(NET_CAPABILITY_INTERNET) 17064 .addCapability(NET_CAPABILITY_NOT_SUSPENDED) 17065 .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED) 17066 .removeCapability(NET_CAPABILITY_NOT_RESTRICTED); 17067 17068 mEthernetAgent = new TestNetworkAgentWrapper(TRANSPORT_ETHERNET, 17069 new LinkProperties(), ncb.build()); 17070 17071 final ArraySet<Integer> serviceUidSet = new ArraySet<>(); 17072 serviceUidSet.add(TEST_PACKAGE_UID); 17073 17074 final TestNetworkCallback cb = new TestNetworkCallback(); 17075 17076 mCm.requestNetwork(new NetworkRequest.Builder() 17077 .addTransportType(TRANSPORT_ETHERNET) 17078 .removeCapability(NET_CAPABILITY_NOT_RESTRICTED) 17079 .build(), cb); 17080 mEthernetAgent.connect(true); 17081 cb.expectAvailableThenValidatedCallbacks(mEthernetAgent); 17082 17083 // Cell gets to set the service UID as access UID 17084 ncb.setAllowedUids(serviceUidSet); 17085 mEthernetAgent.setNetworkCapabilities(ncb.build(), true /* sendToCS */); 17086 if (mDeps.isAtLeastT() && hasAutomotiveFeature) { 17087 cb.expectCaps(mEthernetAgent, c -> c.getAllowedUids().equals(serviceUidSet)); 17088 } else { 17089 // S and no automotive feature must ignore access UIDs. 17090 cb.assertNoCallback(TEST_CALLBACK_TIMEOUT_MS); 17091 } 17092 17093 mEthernetAgent.disconnect(); 17094 cb.expect(LOST, mEthernetAgent); 17095 mCm.unregisterNetworkCallback(cb); 17096 } 17097 17098 @Test 17099 public void testCbsAllowedUids() throws Exception { 17100 mServiceContext.setPermission(NETWORK_FACTORY, PERMISSION_GRANTED); 17101 mServiceContext.setPermission(MANAGE_TEST_NETWORKS, PERMISSION_GRANTED); 17102 17103 // In this test TEST_PACKAGE_UID will be the UID of the carrier service UID. 17104 doReturn(true).when(mCarrierPrivilegeAuthenticator) 17105 .hasCarrierPrivilegeForNetworkCapabilities(eq(TEST_PACKAGE_UID), any()); 17106 17107 // Simulate a restricted telephony network. The telephony factory is entitled to set 17108 // the access UID to the service package on any of its restricted networks. 17109 final NetworkCapabilities.Builder ncb = new NetworkCapabilities.Builder() 17110 .addTransportType(TRANSPORT_CELLULAR) 17111 .addCapability(NET_CAPABILITY_INTERNET) 17112 .addCapability(NET_CAPABILITY_NOT_SUSPENDED) 17113 .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED) 17114 .removeCapability(NET_CAPABILITY_NOT_RESTRICTED) 17115 .setNetworkSpecifier(new TelephonyNetworkSpecifier(1 /* subid */)); 17116 17117 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, 17118 new LinkProperties(), ncb.build()); 17119 17120 final ArraySet<Integer> serviceUidSet = new ArraySet<>(); 17121 serviceUidSet.add(TEST_PACKAGE_UID); 17122 final ArraySet<Integer> nonServiceUidSet = new ArraySet<>(); 17123 nonServiceUidSet.add(TEST_PACKAGE_UID2); 17124 final ArraySet<Integer> serviceUidSetPlus = new ArraySet<>(); 17125 serviceUidSetPlus.add(TEST_PACKAGE_UID); 17126 serviceUidSetPlus.add(TEST_PACKAGE_UID2); 17127 17128 final TestNetworkCallback cb = new TestNetworkCallback(); 17129 17130 // Cell gets to set the service UID as access UID 17131 mCm.requestNetwork(new NetworkRequest.Builder() 17132 .addTransportType(TRANSPORT_CELLULAR) 17133 .removeCapability(NET_CAPABILITY_NOT_RESTRICTED) 17134 .build(), cb); 17135 mCellAgent.connect(true); 17136 cb.expectAvailableThenValidatedCallbacks(mCellAgent); 17137 ncb.setAllowedUids(serviceUidSet); 17138 mCellAgent.setNetworkCapabilities(ncb.build(), true /* sendToCS */); 17139 if (mDeps.isAtLeastT()) { 17140 cb.expectCaps(mCellAgent, c -> c.getAllowedUids().equals(serviceUidSet)); 17141 } else { 17142 // S must ignore access UIDs. 17143 cb.assertNoCallback(TEST_CALLBACK_TIMEOUT_MS); 17144 } 17145 17146 // ...but not to some other UID. Rejection sets UIDs to the empty set 17147 ncb.setAllowedUids(nonServiceUidSet); 17148 mCellAgent.setNetworkCapabilities(ncb.build(), true /* sendToCS */); 17149 if (mDeps.isAtLeastT()) { 17150 cb.expectCaps(mCellAgent, c -> c.getAllowedUids().isEmpty()); 17151 } else { 17152 // S must ignore access UIDs. 17153 cb.assertNoCallback(TEST_CALLBACK_TIMEOUT_MS); 17154 } 17155 17156 // ...and also not to multiple UIDs even including the service UID 17157 ncb.setAllowedUids(serviceUidSetPlus); 17158 mCellAgent.setNetworkCapabilities(ncb.build(), true /* sendToCS */); 17159 cb.assertNoCallback(TEST_CALLBACK_TIMEOUT_MS); 17160 17161 mCellAgent.disconnect(); 17162 cb.expect(LOST, mCellAgent); 17163 mCm.unregisterNetworkCallback(cb); 17164 17165 // Must be unset before touching the transports, because remove and add transport types 17166 // check the specifier on the builder immediately, contradicting normal builder semantics 17167 // TODO : fix the builder 17168 ncb.setNetworkSpecifier(null); 17169 ncb.removeTransportType(TRANSPORT_CELLULAR); 17170 ncb.addTransportType(TRANSPORT_WIFI); 17171 // Wifi does not get to set access UID, even to the correct UID 17172 mCm.requestNetwork(new NetworkRequest.Builder() 17173 .addTransportType(TRANSPORT_WIFI) 17174 .removeCapability(NET_CAPABILITY_NOT_RESTRICTED) 17175 .build(), cb); 17176 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, new LinkProperties(), ncb.build()); 17177 mWiFiAgent.connect(true); 17178 cb.expectAvailableThenValidatedCallbacks(mWiFiAgent); 17179 ncb.setAllowedUids(serviceUidSet); 17180 mWiFiAgent.setNetworkCapabilities(ncb.build(), true /* sendToCS */); 17181 cb.assertNoCallback(TEST_CALLBACK_TIMEOUT_MS); 17182 mCm.unregisterNetworkCallback(cb); 17183 } 17184 17185 @Test 17186 public void testSanitizedCapabilitiesFromAgentDoesNotMutateArgument() 17187 throws Exception { 17188 // This NetworkCapabilities builds an usual object to maximize the chance that this requires 17189 // sanitization, so we have a high chance to detect any changes to the original. 17190 final NetworkCapabilities unsanitized = new NetworkCapabilities.Builder() 17191 .withoutDefaultCapabilities() 17192 .addTransportType(TRANSPORT_WIFI) 17193 .addCapability(NET_CAPABILITY_INTERNET) 17194 .setOwnerUid(12345) 17195 .setAdministratorUids(new int[] {12345, 23456, 34567}) 17196 .setLinkUpstreamBandwidthKbps(20) 17197 .setLinkDownstreamBandwidthKbps(10) 17198 .setNetworkSpecifier(new EthernetNetworkSpecifier("foobar")) 17199 .setTransportInfo(new WifiInfo.Builder().setBssid("AA:AA:AA:AA:AA:AA").build()) 17200 .setSignalStrength(-75) 17201 .setSsid("SSID1") 17202 .setRequestorUid(98765) 17203 .setRequestorPackageName("TestPackage") 17204 .setSubscriptionIds(Collections.singleton(Process.myUid())) 17205 .setUids(UidRange.toIntRanges(uidRangesForUids( 17206 UserHandle.getUid(PRIMARY_USER, 10100), 17207 UserHandle.getUid(SECONDARY_USER, 10101), 17208 UserHandle.getUid(TERTIARY_USER, 10043)))) 17209 .setAllowedUids(Set.of(45678, 56789, 65432)) 17210 .setUnderlyingNetworks(List.of(new Network(99999))) 17211 .build(); 17212 final NetworkCapabilities copyOfUnsanitized = new NetworkCapabilities(unsanitized); 17213 final NetworkInfo info = new NetworkInfo(TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_LTE, 17214 ConnectivityManager.getNetworkTypeName(TYPE_MOBILE), 17215 TelephonyManager.getNetworkTypeName(TelephonyManager.NETWORK_TYPE_LTE)); 17216 final NetworkAgentInfo agent = fakeNai(unsanitized, info); 17217 agent.setDeclaredCapabilities(unsanitized); 17218 final NetworkCapabilities sanitized = agent.getDeclaredCapabilitiesSanitized( 17219 null /* carrierPrivilegeAuthenticator */); 17220 assertEquals(copyOfUnsanitized, unsanitized); 17221 assertNotEquals(sanitized, unsanitized); 17222 } 17223 17224 /** 17225 * Validate request counts are counted accurately on setProfileNetworkPreference on set/replace. 17226 */ 17227 @Test 17228 public void testProfileNetworkPrefCountsRequestsCorrectlyOnSet() throws Exception { 17229 final UserHandle testHandle = setupEnterpriseNetwork(); 17230 final TestOnCompleteListener listener = new TestOnCompleteListener(); 17231 // Leave one request available so the profile preference can be set. 17232 withRequestCountersAcquired(1 /* countToLeaveAvailable */, () -> { 17233 withPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, 17234 Process.myPid(), Process.myUid(), () -> { 17235 // Set initially to test the limit prior to having existing requests. 17236 mCm.setProfileNetworkPreference(testHandle, 17237 PROFILE_NETWORK_PREFERENCE_ENTERPRISE, 17238 Runnable::run, listener); 17239 }); 17240 listener.expectOnComplete(); 17241 17242 // Simulate filing requests as some app on the work profile 17243 final int otherAppUid = UserHandle.getUid(TEST_WORK_PROFILE_USER_ID, 17244 UserHandle.getAppId(Process.myUid() + 1)); 17245 final int remainingCount = ConnectivityService.MAX_NETWORK_REQUESTS_PER_UID 17246 - mService.mNetworkRequestCounter.get(otherAppUid) 17247 - 1; 17248 final NetworkCallback[] callbacks = new NetworkCallback[remainingCount]; 17249 doAsUid(otherAppUid, () -> { 17250 for (int i = 0; i < remainingCount; ++i) { 17251 callbacks[i] = new TestNetworkCallback(); 17252 mCm.registerDefaultNetworkCallback(callbacks[i]); 17253 } 17254 }); 17255 17256 withPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, 17257 Process.myPid(), Process.myUid(), () -> { 17258 // re-set so as to test the limit as part of replacing existing requests. 17259 mCm.setProfileNetworkPreference(testHandle, 17260 PROFILE_NETWORK_PREFERENCE_ENTERPRISE, Runnable::run, listener); 17261 }); 17262 listener.expectOnComplete(); 17263 17264 doAsUid(otherAppUid, () -> { 17265 for (final NetworkCallback callback : callbacks) { 17266 mCm.unregisterNetworkCallback(callback); 17267 } 17268 }); 17269 }); 17270 } 17271 17272 /** 17273 * Validate request counts are counted accurately on setOemNetworkPreference on set/replace. 17274 */ 17275 @Test 17276 public void testSetOemNetworkPreferenceCountsRequestsCorrectlyOnSet() throws Exception { 17277 mockHasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, true); 17278 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 17279 OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY; 17280 // Leave one request available so the OEM preference can be set. 17281 withRequestCountersAcquired(1 /* countToLeaveAvailable */, () -> 17282 withPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, () -> { 17283 // Set initially to test the limit prior to having existing requests. 17284 final TestOemListenerCallback listener = new TestOemListenerCallback(); 17285 mService.setOemNetworkPreference( 17286 createDefaultOemNetworkPreferences(networkPref), listener); 17287 listener.expectOnComplete(); 17288 17289 // re-set so as to test the limit as part of replacing existing requests. 17290 mService.setOemNetworkPreference( 17291 createDefaultOemNetworkPreferences(networkPref), listener); 17292 listener.expectOnComplete(); 17293 })); 17294 } 17295 17296 private void withRequestCountersAcquired(final int countToLeaveAvailable, 17297 @NonNull final ThrowingRunnable r) throws Exception { 17298 final ArraySet<TestNetworkCallback> callbacks = new ArraySet<>(); 17299 try { 17300 final int requestCount = mService.mSystemNetworkRequestCounter.get(Process.myUid()); 17301 // The limit is hit when total requests = limit - 1, and exceeded with a crash when 17302 // total requests >= limit. 17303 final int countToFile = 17304 MAX_NETWORK_REQUESTS_PER_SYSTEM_UID - requestCount - countToLeaveAvailable; 17305 // Need permission so registerDefaultNetworkCallback uses mSystemNetworkRequestCounter 17306 withPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, () -> { 17307 for (int i = 1; i < countToFile; i++) { 17308 final TestNetworkCallback cb = new TestNetworkCallback(); 17309 mCm.registerDefaultNetworkCallback(cb); 17310 callbacks.add(cb); 17311 } 17312 assertEquals(MAX_NETWORK_REQUESTS_PER_SYSTEM_UID - 1 - countToLeaveAvailable, 17313 mService.mSystemNetworkRequestCounter.get(Process.myUid())); 17314 }); 17315 // Code to run to check if it triggers a max request count limit error. 17316 r.run(); 17317 } finally { 17318 for (final TestNetworkCallback cb : callbacks) { 17319 mCm.unregisterNetworkCallback(cb); 17320 } 17321 } 17322 } 17323 17324 private void assertCreateNrisFromMobileDataPreferredUids(Set<Integer> uids) { 17325 final Set<NetworkRequestInfo> nris = 17326 mService.createNrisFromMobileDataPreferredUids(uids); 17327 final NetworkRequestInfo nri = nris.iterator().next(); 17328 // Verify that one NRI is created with multilayer requests. Because one NRI can contain 17329 // multiple uid ranges, so it only need create one NRI here. 17330 assertEquals(1, nris.size()); 17331 assertTrue(nri.isMultilayerRequest()); 17332 assertEquals(nri.getUids(), uidRangesForUids(uids)); 17333 assertEquals(PREFERENCE_ORDER_MOBILE_DATA_PREFERERRED, nri.mPreferenceOrder); 17334 } 17335 17336 /** 17337 * Test createNrisFromMobileDataPreferredUids returns correct NetworkRequestInfo. 17338 */ 17339 @Test 17340 public void testCreateNrisFromMobileDataPreferredUids() { 17341 // Verify that empty uid set should not create any NRI for it. 17342 final Set<NetworkRequestInfo> nrisNoUid = 17343 mService.createNrisFromMobileDataPreferredUids(new ArraySet<>()); 17344 assertEquals(0, nrisNoUid.size()); 17345 17346 final int uid1 = PRIMARY_USER_HANDLE.getUid(TEST_PACKAGE_UID); 17347 final int uid2 = PRIMARY_USER_HANDLE.getUid(TEST_PACKAGE_UID2); 17348 final int uid3 = SECONDARY_USER_HANDLE.getUid(TEST_PACKAGE_UID); 17349 assertCreateNrisFromMobileDataPreferredUids(Set.of(uid1)); 17350 assertCreateNrisFromMobileDataPreferredUids(Set.of(uid1, uid3)); 17351 assertCreateNrisFromMobileDataPreferredUids(Set.of(uid1, uid2)); 17352 } 17353 17354 private void setAndUpdateMobileDataPreferredUids(Set<Integer> uids) { 17355 ConnectivitySettingsManager.setMobileDataPreferredUids(mServiceContext, uids); 17356 mService.updateMobileDataPreferredUids(); 17357 waitForIdle(); 17358 } 17359 17360 /** 17361 * Test that MOBILE_DATA_PREFERRED_UIDS changes will send correct net id and uid ranges to netd. 17362 */ 17363 @Test 17364 public void testMobileDataPreferredUidsChanged() throws Exception { 17365 final InOrder inorder = inOrder(mMockNetd); 17366 registerDefaultNetworkCallbacks(); 17367 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 17368 mCellAgent.connect(true); 17369 mDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 17370 mTestPackageDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 17371 17372 final int cellNetId = mCellAgent.getNetwork().netId; 17373 inorder.verify(mMockNetd, times(1)).networkCreate(nativeNetworkConfigPhysical( 17374 cellNetId, INetd.PERMISSION_NONE)); 17375 17376 // Initial mobile data preferred uids status. 17377 setAndUpdateMobileDataPreferredUids(Set.of()); 17378 inorder.verify(mMockNetd, never()).networkAddUidRangesParcel(any()); 17379 inorder.verify(mMockNetd, never()).networkRemoveUidRangesParcel(any()); 17380 17381 // Set MOBILE_DATA_PREFERRED_UIDS setting and verify that net id and uid ranges send to netd 17382 final Set<Integer> uids1 = Set.of(PRIMARY_USER_HANDLE.getUid(TEST_PACKAGE_UID)); 17383 final UidRangeParcel[] uidRanges1 = toUidRangeStableParcels(uidRangesForUids(uids1)); 17384 final NativeUidRangeConfig config1 = new NativeUidRangeConfig(cellNetId, uidRanges1, 17385 PREFERENCE_ORDER_MOBILE_DATA_PREFERERRED); 17386 setAndUpdateMobileDataPreferredUids(uids1); 17387 inorder.verify(mMockNetd, times(1)).networkAddUidRangesParcel(config1); 17388 inorder.verify(mMockNetd, never()).networkRemoveUidRangesParcel(any()); 17389 17390 // Set MOBILE_DATA_PREFERRED_UIDS setting again and verify that old rules are removed and 17391 // new rules are added. 17392 final Set<Integer> uids2 = Set.of(PRIMARY_USER_HANDLE.getUid(TEST_PACKAGE_UID), 17393 PRIMARY_USER_HANDLE.getUid(TEST_PACKAGE_UID2), 17394 SECONDARY_USER_HANDLE.getUid(TEST_PACKAGE_UID)); 17395 final UidRangeParcel[] uidRanges2 = toUidRangeStableParcels(uidRangesForUids(uids2)); 17396 final NativeUidRangeConfig config2 = new NativeUidRangeConfig(cellNetId, uidRanges2, 17397 PREFERENCE_ORDER_MOBILE_DATA_PREFERERRED); 17398 setAndUpdateMobileDataPreferredUids(uids2); 17399 inorder.verify(mMockNetd, times(1)).networkRemoveUidRangesParcel(config1); 17400 inorder.verify(mMockNetd, times(1)).networkAddUidRangesParcel(config2); 17401 17402 // Clear MOBILE_DATA_PREFERRED_UIDS setting again and verify that old rules are removed and 17403 // new rules are not added. 17404 setAndUpdateMobileDataPreferredUids(Set.of()); 17405 inorder.verify(mMockNetd, times(1)).networkRemoveUidRangesParcel(config2); 17406 inorder.verify(mMockNetd, never()).networkAddUidRangesParcel(any()); 17407 } 17408 17409 /** 17410 * Make sure mobile data preferred uids feature behaves as expected when the mobile network 17411 * goes up and down while the uids is set. Make sure they behave as expected whether 17412 * there is a general default network or not. 17413 */ 17414 @Test 17415 public void testMobileDataPreferenceForMobileNetworkUpDown() throws Exception { 17416 final InOrder inorder = inOrder(mMockNetd); 17417 // File a request for cell to ensure it doesn't go down. 17418 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback(); 17419 final NetworkRequest cellRequest = new NetworkRequest.Builder() 17420 .addTransportType(TRANSPORT_CELLULAR).build(); 17421 mCm.requestNetwork(cellRequest, cellNetworkCallback); 17422 cellNetworkCallback.assertNoCallback(); 17423 17424 registerDefaultNetworkCallbacks(); 17425 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 17426 mWiFiAgent.connect(true); 17427 mDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mWiFiAgent); 17428 mTestPackageDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mWiFiAgent); 17429 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetworkForUid(TEST_PACKAGE_UID)); 17430 17431 final int wifiNetId = mWiFiAgent.getNetwork().netId; 17432 inorder.verify(mMockNetd, times(1)).networkCreate(nativeNetworkConfigPhysical( 17433 wifiNetId, INetd.PERMISSION_NONE)); 17434 17435 // Initial mobile data preferred uids status. 17436 setAndUpdateMobileDataPreferredUids(Set.of()); 17437 inorder.verify(mMockNetd, never()).networkAddUidRangesParcel(any()); 17438 inorder.verify(mMockNetd, never()).networkRemoveUidRangesParcel(any()); 17439 17440 // Set MOBILE_DATA_PREFERRED_UIDS setting and verify that wifi net id and uid ranges send to 17441 // netd. 17442 final Set<Integer> uids = Set.of(PRIMARY_USER_HANDLE.getUid(TEST_PACKAGE_UID)); 17443 final UidRangeParcel[] uidRanges = toUidRangeStableParcels(uidRangesForUids(uids)); 17444 final NativeUidRangeConfig wifiConfig = new NativeUidRangeConfig(wifiNetId, uidRanges, 17445 PREFERENCE_ORDER_MOBILE_DATA_PREFERERRED); 17446 setAndUpdateMobileDataPreferredUids(uids); 17447 inorder.verify(mMockNetd, times(1)).networkAddUidRangesParcel(wifiConfig); 17448 inorder.verify(mMockNetd, never()).networkRemoveUidRangesParcel(any()); 17449 17450 // Cellular network connected. mTestPackageDefaultNetworkCallback should receive 17451 // callback with cellular network and net id and uid ranges should be updated to netd. 17452 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 17453 mCellAgent.connect(true); 17454 cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 17455 mDefaultNetworkCallback.assertNoCallback(); 17456 mTestPackageDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 17457 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetworkForUid(TEST_PACKAGE_UID)); 17458 17459 final int cellNetId = mCellAgent.getNetwork().netId; 17460 final NativeUidRangeConfig cellConfig = new NativeUidRangeConfig(cellNetId, uidRanges, 17461 PREFERENCE_ORDER_MOBILE_DATA_PREFERERRED); 17462 inorder.verify(mMockNetd, times(1)).networkCreate(nativeNetworkConfigPhysical( 17463 cellNetId, INetd.PERMISSION_NONE)); 17464 inorder.verify(mMockNetd, times(1)).networkAddUidRangesParcel(cellConfig); 17465 inorder.verify(mMockNetd, times(1)).networkRemoveUidRangesParcel(wifiConfig); 17466 17467 // Cellular network disconnected. mTestPackageDefaultNetworkCallback should receive 17468 // callback with wifi network from fallback request. 17469 mCellAgent.disconnect(); 17470 mDefaultNetworkCallback.assertNoCallback(); 17471 cellNetworkCallback.expect(LOST, mCellAgent); 17472 mTestPackageDefaultNetworkCallback.expect(LOST, mCellAgent); 17473 mTestPackageDefaultNetworkCallback.expectAvailableCallbacksValidated(mWiFiAgent); 17474 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetworkForUid(TEST_PACKAGE_UID)); 17475 inorder.verify(mMockNetd, times(1)).networkAddUidRangesParcel(wifiConfig); 17476 inorder.verify(mMockNetd, never()).networkRemoveUidRangesParcel(any()); 17477 inorder.verify(mMockNetd).networkDestroy(cellNetId); 17478 17479 // Cellular network comes back. mTestPackageDefaultNetworkCallback should receive 17480 // callback with cellular network. 17481 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 17482 mCellAgent.connect(true); 17483 cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 17484 mDefaultNetworkCallback.assertNoCallback(); 17485 mTestPackageDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 17486 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetworkForUid(TEST_PACKAGE_UID)); 17487 17488 final int cellNetId2 = mCellAgent.getNetwork().netId; 17489 final NativeUidRangeConfig cellConfig2 = new NativeUidRangeConfig(cellNetId2, uidRanges, 17490 PREFERENCE_ORDER_MOBILE_DATA_PREFERERRED); 17491 inorder.verify(mMockNetd, times(1)).networkCreate(nativeNetworkConfigPhysical( 17492 cellNetId2, INetd.PERMISSION_NONE)); 17493 inorder.verify(mMockNetd, times(1)).networkAddUidRangesParcel(cellConfig2); 17494 inorder.verify(mMockNetd, times(1)).networkRemoveUidRangesParcel(wifiConfig); 17495 17496 // Wifi network disconnected. mTestPackageDefaultNetworkCallback should not receive 17497 // any callback. 17498 mWiFiAgent.disconnect(); 17499 mDefaultNetworkCallback.expect(LOST, mWiFiAgent); 17500 mDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellAgent); 17501 mTestPackageDefaultNetworkCallback.assertNoCallback(); 17502 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetworkForUid(TEST_PACKAGE_UID)); 17503 waitForIdle(); 17504 inorder.verify(mMockNetd, never()).networkAddUidRangesParcel(any()); 17505 inorder.verify(mMockNetd, never()).networkRemoveUidRangesParcel(any()); 17506 inorder.verify(mMockNetd).networkDestroy(wifiNetId); 17507 17508 mCm.unregisterNetworkCallback(cellNetworkCallback); 17509 } 17510 17511 @Test 17512 public void testMultilayerRequestsOfSetMobileDataPreferredUids() throws Exception { 17513 // First set mobile data preferred uid to create a multi-layer requests: 1. request for 17514 // cellular, 2. track the default network for fallback. 17515 setAndUpdateMobileDataPreferredUids( 17516 Set.of(PRIMARY_USER_HANDLE.getUid(TEST_PACKAGE_UID))); 17517 17518 final HandlerThread handlerThread = new HandlerThread("MockFactory"); 17519 handlerThread.start(); 17520 final NetworkCapabilities cellFilter = new NetworkCapabilities() 17521 .addTransportType(TRANSPORT_CELLULAR) 17522 .addCapability(NET_CAPABILITY_INTERNET) 17523 .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED); 17524 final MockNetworkFactory cellFactory = new MockNetworkFactory(handlerThread.getLooper(), 17525 mServiceContext, "cellFactory", cellFilter, mCsHandlerThread); 17526 cellFactory.setScoreFilter(40); 17527 17528 try { 17529 cellFactory.register(); 17530 // Default internet request and the mobile data preferred request. 17531 cellFactory.expectRequestAdds(2); 17532 cellFactory.assertRequestCountEquals(2); 17533 17534 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 17535 mWiFiAgent.connect(true); 17536 17537 // The cellFactory however is outscored, and should lose default internet request. 17538 // But it should still see mobile data preferred request. 17539 cellFactory.expectRequestRemove(); 17540 cellFactory.assertRequestCountEquals(1); 17541 17542 mWiFiAgent.disconnect(); 17543 // The network satisfying the default internet request has disconnected, so the 17544 // cellFactory sees the default internet requests again. 17545 cellFactory.expectRequestAdd(); 17546 cellFactory.assertRequestCountEquals(2); 17547 } finally { 17548 cellFactory.terminate(); 17549 handlerThread.quitSafely(); 17550 handlerThread.join(); 17551 } 17552 } 17553 17554 /** 17555 * Validate request counts are counted accurately on MOBILE_DATA_PREFERRED_UIDS change 17556 * on set/replace. 17557 */ 17558 @Test 17559 public void testMobileDataPreferredUidsChangedCountsRequestsCorrectlyOnSet() throws Exception { 17560 ConnectivitySettingsManager.setMobileDataPreferredUids(mServiceContext, 17561 Set.of(PRIMARY_USER_HANDLE.getUid(TEST_PACKAGE_UID))); 17562 // Leave one request available so MDO preference set up above can be set. 17563 withRequestCountersAcquired(1 /* countToLeaveAvailable */, () -> 17564 withPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, 17565 Process.myPid(), Process.myUid(), () -> { 17566 // Set initially to test the limit prior to having existing requests. 17567 mService.updateMobileDataPreferredUids(); 17568 waitForIdle(); 17569 17570 // re-set so as to test the limit as part of replacing existing requests 17571 mService.updateMobileDataPreferredUids(); 17572 waitForIdle(); 17573 })); 17574 } 17575 17576 @Test 17577 public void testAllNetworkPreferencesCanCoexist() 17578 throws Exception { 17579 final InOrder inorder = inOrder(mMockNetd); 17580 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 17581 OEM_NETWORK_PREFERENCE_OEM_PAID; 17582 final UserHandle testHandle = setupEnterpriseNetwork(); 17583 17584 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); 17585 final int cellNetId = mCellAgent.getNetwork().netId; 17586 inorder.verify(mMockNetd, times(1)).networkCreate(nativeNetworkConfigPhysical( 17587 cellNetId, INetd.PERMISSION_NONE)); 17588 17589 // Set oem network preference 17590 final int[] uids1 = new int[] { PRIMARY_USER_HANDLE.getUid(TEST_PACKAGE_UID) }; 17591 final UidRangeParcel[] uidRanges1 = toUidRangeStableParcels(uidRangesForUids(uids1)); 17592 final NativeUidRangeConfig config1 = new NativeUidRangeConfig(cellNetId, uidRanges1, 17593 PREFERENCE_ORDER_OEM); 17594 setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges1, TEST_PACKAGE_NAME); 17595 inorder.verify(mMockNetd, times(1)).networkAddUidRangesParcel(config1); 17596 inorder.verify(mMockNetd, never()).networkRemoveUidRangesParcel(any()); 17597 17598 // Set user profile network preference 17599 final TestNetworkAgentWrapper workAgent = makeEnterpriseNetworkAgent(); 17600 workAgent.connect(true); 17601 17602 final TestOnCompleteListener listener = new TestOnCompleteListener(); 17603 mCm.setProfileNetworkPreference(testHandle, PROFILE_NETWORK_PREFERENCE_ENTERPRISE, 17604 r -> r.run(), listener); 17605 listener.expectOnComplete(); 17606 final NativeUidRangeConfig config2 = new NativeUidRangeConfig(workAgent.getNetwork().netId, 17607 uidRangeFor(testHandle), PREFERENCE_ORDER_PROFILE); 17608 inorder.verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( 17609 workAgent.getNetwork().netId, INetd.PERMISSION_SYSTEM)); 17610 inorder.verify(mMockNetd, never()).networkRemoveUidRangesParcel(any()); 17611 inorder.verify(mMockNetd).networkAddUidRangesParcel(config2); 17612 17613 // Set MOBILE_DATA_PREFERRED_UIDS setting 17614 final Set<Integer> uids2 = Set.of(PRIMARY_USER_HANDLE.getUid(TEST_PACKAGE_UID2)); 17615 final UidRangeParcel[] uidRanges2 = toUidRangeStableParcels(uidRangesForUids(uids2)); 17616 final NativeUidRangeConfig config3 = new NativeUidRangeConfig(cellNetId, uidRanges2, 17617 PREFERENCE_ORDER_MOBILE_DATA_PREFERERRED); 17618 setAndUpdateMobileDataPreferredUids(uids2); 17619 inorder.verify(mMockNetd, never()).networkRemoveUidRangesParcel(any()); 17620 inorder.verify(mMockNetd, times(1)).networkAddUidRangesParcel(config3); 17621 17622 // Set oem network preference again with different uid. 17623 final Set<Integer> uids3 = Set.of(PRIMARY_USER_HANDLE.getUid(TEST_PACKAGE_UID3)); 17624 final UidRangeParcel[] uidRanges3 = toUidRangeStableParcels(uidRangesForUids(uids3)); 17625 final NativeUidRangeConfig config4 = new NativeUidRangeConfig(cellNetId, uidRanges3, 17626 PREFERENCE_ORDER_OEM); 17627 setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges3, "com.android.test"); 17628 inorder.verify(mMockNetd, times(1)).networkRemoveUidRangesParcel(config1); 17629 inorder.verify(mMockNetd, times(1)).networkAddUidRangesParcel(config4); 17630 17631 // Remove user profile network preference 17632 mCm.setProfileNetworkPreference(testHandle, PROFILE_NETWORK_PREFERENCE_DEFAULT, 17633 r -> r.run(), listener); 17634 listener.expectOnComplete(); 17635 inorder.verify(mMockNetd, times(1)).networkRemoveUidRangesParcel(config2); 17636 inorder.verify(mMockNetd, never()).networkAddUidRangesParcel(any()); 17637 17638 // Set MOBILE_DATA_PREFERRED_UIDS setting again with same uid as oem network preference. 17639 final NativeUidRangeConfig config6 = new NativeUidRangeConfig(cellNetId, uidRanges3, 17640 PREFERENCE_ORDER_MOBILE_DATA_PREFERERRED); 17641 setAndUpdateMobileDataPreferredUids(uids3); 17642 inorder.verify(mMockNetd, times(1)).networkRemoveUidRangesParcel(config3); 17643 inorder.verify(mMockNetd, times(1)).networkAddUidRangesParcel(config6); 17644 } 17645 17646 @Test 17647 public void testNetworkCallbackAndActiveNetworkForUid_AllNetworkPreferencesEnabled() 17648 throws Exception { 17649 // File a request for cell to ensure it doesn't go down. 17650 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback(); 17651 final NetworkRequest cellRequest = new NetworkRequest.Builder() 17652 .addTransportType(TRANSPORT_CELLULAR).build(); 17653 mCm.requestNetwork(cellRequest, cellNetworkCallback); 17654 cellNetworkCallback.assertNoCallback(); 17655 17656 // Register callbacks and have wifi network as default network. 17657 registerDefaultNetworkCallbacks(); 17658 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 17659 mWiFiAgent.connect(true); 17660 mDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mWiFiAgent); 17661 mProfileDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mWiFiAgent); 17662 mTestPackageDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mWiFiAgent); 17663 assertEquals(mWiFiAgent.getNetwork(), 17664 mCm.getActiveNetworkForUid(TEST_WORK_PROFILE_APP_UID)); 17665 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetworkForUid(TEST_PACKAGE_UID)); 17666 17667 // Set MOBILE_DATA_PREFERRED_UIDS setting with TEST_WORK_PROFILE_APP_UID and 17668 // TEST_PACKAGE_UID. Both mProfileDefaultNetworkCallback and 17669 // mTestPackageDefaultNetworkCallback should receive callback with cell network. 17670 setAndUpdateMobileDataPreferredUids(Set.of(TEST_WORK_PROFILE_APP_UID, TEST_PACKAGE_UID)); 17671 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 17672 mCellAgent.connect(true); 17673 cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 17674 mDefaultNetworkCallback.assertNoCallback(); 17675 mProfileDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 17676 mTestPackageDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 17677 assertEquals(mCellAgent.getNetwork(), 17678 mCm.getActiveNetworkForUid(TEST_WORK_PROFILE_APP_UID)); 17679 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetworkForUid(TEST_PACKAGE_UID)); 17680 17681 // Set user profile network preference with test profile. mProfileDefaultNetworkCallback 17682 // should receive callback with higher priority network preference (enterprise network). 17683 // The others should have no callbacks. 17684 final UserHandle testHandle = setupEnterpriseNetwork(); 17685 final TestNetworkAgentWrapper workAgent = makeEnterpriseNetworkAgent(); 17686 workAgent.connect(true); 17687 final TestOnCompleteListener listener = new TestOnCompleteListener(); 17688 mCm.setProfileNetworkPreference(testHandle, PROFILE_NETWORK_PREFERENCE_ENTERPRISE, 17689 r -> r.run(), listener); 17690 listener.expectOnComplete(); 17691 assertNoCallbacks(mDefaultNetworkCallback, mTestPackageDefaultNetworkCallback); 17692 mProfileDefaultNetworkCallback.expectAvailableCallbacksValidated(workAgent); 17693 assertEquals(workAgent.getNetwork(), mCm.getActiveNetworkForUid(TEST_WORK_PROFILE_APP_UID)); 17694 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetworkForUid(TEST_PACKAGE_UID)); 17695 17696 // Set oem network preference with TEST_PACKAGE_UID. mTestPackageDefaultNetworkCallback 17697 // should receive callback with higher priority network preference (current default network) 17698 // and the others should have no callbacks. 17699 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 17700 OEM_NETWORK_PREFERENCE_OEM_PAID; 17701 final int[] uids1 = new int[] { TEST_PACKAGE_UID }; 17702 final UidRangeParcel[] uidRanges1 = toUidRangeStableParcels(uidRangesForUids(uids1)); 17703 setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges1, TEST_PACKAGE_NAME); 17704 assertNoCallbacks(mDefaultNetworkCallback, mProfileDefaultNetworkCallback); 17705 mTestPackageDefaultNetworkCallback.expectAvailableCallbacksValidated(mWiFiAgent); 17706 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetworkForUid(TEST_PACKAGE_UID)); 17707 assertEquals(workAgent.getNetwork(), mCm.getActiveNetworkForUid(TEST_WORK_PROFILE_APP_UID)); 17708 17709 // Set oem network preference with TEST_WORK_PROFILE_APP_UID. Both 17710 // mProfileDefaultNetworkCallback and mTestPackageDefaultNetworkCallback should receive 17711 // callback. 17712 final int[] uids2 = new int[] { TEST_WORK_PROFILE_APP_UID }; 17713 final UidRangeParcel[] uidRanges2 = toUidRangeStableParcels(uidRangesForUids(uids2)); 17714 doReturn(Arrays.asList(testHandle)).when(mUserManager).getUserHandles(anyBoolean()); 17715 setupSetOemNetworkPreferenceForPreferenceTest( 17716 networkPref, uidRanges2, "com.android.test", testHandle); 17717 mDefaultNetworkCallback.assertNoCallback(); 17718 mProfileDefaultNetworkCallback.expectAvailableCallbacksValidated(mWiFiAgent); 17719 mTestPackageDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellAgent); 17720 assertEquals(mWiFiAgent.getNetwork(), 17721 mCm.getActiveNetworkForUid(TEST_WORK_PROFILE_APP_UID)); 17722 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetworkForUid(TEST_PACKAGE_UID)); 17723 17724 // Remove oem network preference, mProfileDefaultNetworkCallback should receive callback 17725 // with current highest priority network preference (enterprise network) and the others 17726 // should have no callbacks. 17727 final TestOemListenerCallback oemPrefListener = new TestOemListenerCallback(); 17728 mService.setOemNetworkPreference( 17729 new OemNetworkPreferences.Builder().build(), oemPrefListener); 17730 oemPrefListener.expectOnComplete(); 17731 assertNoCallbacks(mDefaultNetworkCallback, mTestPackageDefaultNetworkCallback); 17732 mProfileDefaultNetworkCallback.expectAvailableCallbacksValidated(workAgent); 17733 assertEquals(workAgent.getNetwork(), mCm.getActiveNetworkForUid(TEST_WORK_PROFILE_APP_UID)); 17734 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetworkForUid(TEST_PACKAGE_UID)); 17735 17736 // Remove user profile network preference. 17737 mCm.setProfileNetworkPreference(testHandle, PROFILE_NETWORK_PREFERENCE_DEFAULT, 17738 r -> r.run(), listener); 17739 listener.expectOnComplete(); 17740 assertNoCallbacks(mDefaultNetworkCallback, mTestPackageDefaultNetworkCallback); 17741 mProfileDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellAgent); 17742 assertEquals(mCellAgent.getNetwork(), 17743 mCm.getActiveNetworkForUid(TEST_WORK_PROFILE_APP_UID)); 17744 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetworkForUid(TEST_PACKAGE_UID)); 17745 17746 // Disconnect wifi 17747 mWiFiAgent.disconnect(); 17748 assertNoCallbacks(mProfileDefaultNetworkCallback, mTestPackageDefaultNetworkCallback); 17749 mDefaultNetworkCallback.expect(LOST, mWiFiAgent); 17750 mDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellAgent); 17751 } 17752 17753 @Test 17754 public void testRequestRouteToHostAddress_PackageDoesNotBelongToCaller() { 17755 assertThrows(SecurityException.class, () -> mService.requestRouteToHostAddress( 17756 ConnectivityManager.TYPE_NONE, null /* hostAddress */, "com.not.package.owner", 17757 null /* callingAttributionTag */)); 17758 } 17759 17760 @Test @IgnoreUpTo(SC_V2) 17761 public void testUpdateRateLimit_EnableDisable() throws Exception { 17762 final LinkProperties wifiLp = new LinkProperties(); 17763 wifiLp.setInterfaceName(WIFI_IFNAME); 17764 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, wifiLp); 17765 mWiFiAgent.connect(true); 17766 17767 final LinkProperties cellLp = new LinkProperties(); 17768 cellLp.setInterfaceName(MOBILE_IFNAME); 17769 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp); 17770 mCellAgent.connect(false); 17771 17772 waitForIdle(); 17773 17774 final ArrayTrackRecord<Pair<String, Long>>.ReadHead readHeadWifi = 17775 mDeps.mRateLimitHistory.newReadHead(); 17776 final ArrayTrackRecord<Pair<String, Long>>.ReadHead readHeadCell = 17777 mDeps.mRateLimitHistory.newReadHead(); 17778 17779 // set rate limit to 8MBit/s => 1MB/s 17780 final int rateLimitInBytesPerSec = 1 * 1000 * 1000; 17781 setIngressRateLimit(rateLimitInBytesPerSec); 17782 17783 assertNotNull(readHeadWifi.poll(TIMEOUT_MS, 17784 it -> it.first == wifiLp.getInterfaceName() 17785 && it.second == rateLimitInBytesPerSec)); 17786 assertNotNull(readHeadCell.poll(TIMEOUT_MS, 17787 it -> it.first == cellLp.getInterfaceName() 17788 && it.second == rateLimitInBytesPerSec)); 17789 17790 // disable rate limiting 17791 setIngressRateLimit(-1); 17792 17793 assertNotNull(readHeadWifi.poll(TIMEOUT_MS, 17794 it -> it.first == wifiLp.getInterfaceName() && it.second == -1)); 17795 assertNotNull(readHeadCell.poll(TIMEOUT_MS, 17796 it -> it.first == cellLp.getInterfaceName() && it.second == -1)); 17797 } 17798 17799 @Test @IgnoreUpTo(SC_V2) 17800 public void testUpdateRateLimit_WhenNewNetworkIsAdded() throws Exception { 17801 final LinkProperties wifiLp = new LinkProperties(); 17802 wifiLp.setInterfaceName(WIFI_IFNAME); 17803 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, wifiLp); 17804 mWiFiAgent.connect(true); 17805 17806 waitForIdle(); 17807 17808 final ArrayTrackRecord<Pair<String, Long>>.ReadHead readHead = 17809 mDeps.mRateLimitHistory.newReadHead(); 17810 17811 // set rate limit to 8MBit/s => 1MB/s 17812 final int rateLimitInBytesPerSec = 1 * 1000 * 1000; 17813 setIngressRateLimit(rateLimitInBytesPerSec); 17814 assertNotNull(readHead.poll(TIMEOUT_MS, it -> it.first == wifiLp.getInterfaceName() 17815 && it.second == rateLimitInBytesPerSec)); 17816 17817 final LinkProperties cellLp = new LinkProperties(); 17818 cellLp.setInterfaceName(MOBILE_IFNAME); 17819 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp); 17820 mCellAgent.connect(false); 17821 assertNotNull(readHead.poll(TIMEOUT_MS, it -> it.first == cellLp.getInterfaceName() 17822 && it.second == rateLimitInBytesPerSec)); 17823 } 17824 17825 @Test @IgnoreUpTo(SC_V2) 17826 public void testUpdateRateLimit_OnlyAffectsInternetCapableNetworks() throws Exception { 17827 final LinkProperties wifiLp = new LinkProperties(); 17828 wifiLp.setInterfaceName(WIFI_IFNAME); 17829 17830 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, wifiLp); 17831 mWiFiAgent.connectWithoutInternet(); 17832 17833 waitForIdle(); 17834 17835 setIngressRateLimit(1000); 17836 setIngressRateLimit(-1); 17837 17838 final ArrayTrackRecord<Pair<String, Long>>.ReadHead readHeadWifi = 17839 mDeps.mRateLimitHistory.newReadHead(); 17840 assertNull(readHeadWifi.poll(TIMEOUT_MS, it -> it.first == wifiLp.getInterfaceName())); 17841 } 17842 17843 @Test @IgnoreUpTo(SC_V2) 17844 public void testUpdateRateLimit_DisconnectingResetsRateLimit() 17845 throws Exception { 17846 // Steps: 17847 // - connect network 17848 // - set rate limit 17849 // - disconnect network (interface still exists) 17850 // - disable rate limit 17851 // - connect network 17852 // - ensure network interface is not rate limited 17853 final LinkProperties wifiLp = new LinkProperties(); 17854 wifiLp.setInterfaceName(WIFI_IFNAME); 17855 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, wifiLp); 17856 mWiFiAgent.connect(true); 17857 waitForIdle(); 17858 17859 final ArrayTrackRecord<Pair<String, Long>>.ReadHead readHeadWifi = 17860 mDeps.mRateLimitHistory.newReadHead(); 17861 17862 int rateLimitInBytesPerSec = 1000; 17863 setIngressRateLimit(rateLimitInBytesPerSec); 17864 assertNotNull(readHeadWifi.poll(TIMEOUT_MS, 17865 it -> it.first == wifiLp.getInterfaceName() 17866 && it.second == rateLimitInBytesPerSec)); 17867 17868 mWiFiAgent.disconnect(); 17869 assertNotNull(readHeadWifi.poll(TIMEOUT_MS, 17870 it -> it.first == wifiLp.getInterfaceName() && it.second == -1)); 17871 17872 setIngressRateLimit(-1); 17873 17874 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, wifiLp); 17875 mWiFiAgent.connect(true); 17876 assertNull(readHeadWifi.poll(TIMEOUT_MS, it -> it.first == wifiLp.getInterfaceName())); 17877 } 17878 17879 @Test @IgnoreUpTo(SC_V2) 17880 public void testUpdateRateLimit_UpdateExistingRateLimit() throws Exception { 17881 final LinkProperties wifiLp = new LinkProperties(); 17882 wifiLp.setInterfaceName(WIFI_IFNAME); 17883 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, wifiLp); 17884 mWiFiAgent.connect(true); 17885 waitForIdle(); 17886 17887 final ArrayTrackRecord<Pair<String, Long>>.ReadHead readHeadWifi = 17888 mDeps.mRateLimitHistory.newReadHead(); 17889 17890 // update an active ingress rate limit 17891 setIngressRateLimit(1000); 17892 setIngressRateLimit(2000); 17893 17894 // verify the following order of execution: 17895 // 1. ingress rate limit set to 1000. 17896 // 2. ingress rate limit disabled (triggered by updating active rate limit). 17897 // 3. ingress rate limit set to 2000. 17898 assertNotNull(readHeadWifi.poll(TIMEOUT_MS, 17899 it -> it.first == wifiLp.getInterfaceName() 17900 && it.second == 1000)); 17901 assertNotNull(readHeadWifi.poll(TIMEOUT_MS, 17902 it -> it.first == wifiLp.getInterfaceName() 17903 && it.second == -1)); 17904 assertNotNull(readHeadWifi.poll(TIMEOUT_MS, 17905 it -> it.first == wifiLp.getInterfaceName() 17906 && it.second == 2000)); 17907 } 17908 17909 @Test @IgnoreAfter(SC_V2) 17910 public void testUpdateRateLimit_DoesNothingBeforeT() throws Exception { 17911 final LinkProperties wifiLp = new LinkProperties(); 17912 wifiLp.setInterfaceName(WIFI_IFNAME); 17913 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, wifiLp); 17914 mWiFiAgent.connect(true); 17915 waitForIdle(); 17916 17917 final ArrayTrackRecord<Pair<String, Long>>.ReadHead readHead = 17918 mDeps.mRateLimitHistory.newReadHead(); 17919 17920 setIngressRateLimit(1000); 17921 waitForIdle(); 17922 17923 assertNull(readHead.poll(TEST_CALLBACK_TIMEOUT_MS, it -> true)); 17924 } 17925 17926 @Test 17927 public void testOfferNetwork_ChecksArgumentsOutsideOfHandler() throws Exception { 17928 final TestableNetworkOfferCallback callback = new TestableNetworkOfferCallback( 17929 TIMEOUT_MS /* timeout */, TEST_CALLBACK_TIMEOUT_MS /* noCallbackTimeout */); 17930 final NetworkProvider testProvider = new NetworkProvider(mServiceContext, 17931 mCsHandlerThread.getLooper(), "Test provider"); 17932 final NetworkCapabilities caps = new NetworkCapabilities.Builder() 17933 .addCapability(NET_CAPABILITY_INTERNET) 17934 .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED) 17935 .build(); 17936 17937 final NetworkScore score = new NetworkScore.Builder().build(); 17938 testProvider.registerNetworkOffer(score, caps, r -> r.run(), callback); 17939 testProvider.unregisterNetworkOffer(callback); 17940 17941 assertThrows(NullPointerException.class, 17942 () -> mService.offerNetwork(100, score, caps, null)); 17943 assertThrows(NullPointerException.class, () -> mService.unofferNetwork(null)); 17944 } 17945 17946 public void doTestIgnoreValidationAfterRoam(int resValue, final boolean enabled) 17947 throws Exception { 17948 doReturn(resValue).when(mResources) 17949 .getInteger(R.integer.config_validationFailureAfterRoamIgnoreTimeMillis); 17950 17951 final String bssid1 = "AA:AA:AA:AA:AA:AA"; 17952 final String bssid2 = "BB:BB:BB:BB:BB:BB"; 17953 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 17954 mCellAgent.connect(true); 17955 NetworkCapabilities wifiNc1 = new NetworkCapabilities() 17956 .addCapability(NET_CAPABILITY_INTERNET) 17957 .addCapability(NET_CAPABILITY_NOT_VPN) 17958 .addCapability(NET_CAPABILITY_NOT_RESTRICTED) 17959 .addCapability(NET_CAPABILITY_TRUSTED) 17960 .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED) 17961 .addTransportType(TRANSPORT_WIFI) 17962 .setTransportInfo(new WifiInfo.Builder().setBssid(bssid1).build()); 17963 NetworkCapabilities wifiNc2 = new NetworkCapabilities(wifiNc1) 17964 .setTransportInfo(new WifiInfo.Builder().setBssid(bssid2).build()); 17965 final LinkProperties wifiLp = new LinkProperties(); 17966 wifiLp.setInterfaceName(WIFI_IFNAME); 17967 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, wifiLp, wifiNc1); 17968 mWiFiAgent.connect(true); 17969 17970 // The default network will be switching to Wi-Fi Network. 17971 final TestNetworkCallback wifiNetworkCallback = new TestNetworkCallback(); 17972 final NetworkRequest wifiRequest = new NetworkRequest.Builder() 17973 .addTransportType(TRANSPORT_WIFI).build(); 17974 mCm.requestNetwork(wifiRequest, wifiNetworkCallback); 17975 wifiNetworkCallback.expectAvailableCallbacksValidated(mWiFiAgent); 17976 registerDefaultNetworkCallbacks(); 17977 mDefaultNetworkCallback.expectAvailableCallbacksValidated(mWiFiAgent); 17978 17979 // There is a bug in the current code where ignoring validation after roam will not 17980 // correctly change the default network if the result if the validation is partial or 17981 // captive portal. TODO : fix the bug and reinstate this code. 17982 if (false) { 17983 // Wi-Fi roaming from wifiNc1 to wifiNc2 but the network is now behind a captive portal. 17984 mWiFiAgent.setNetworkCapabilities(wifiNc2, true /* sendToConnectivityService */); 17985 // The only thing changed in this CAPS is the BSSID, which can't be tested for in this 17986 // test because it's redacted. 17987 wifiNetworkCallback.expectCaps(mWiFiAgent); 17988 mDefaultNetworkCallback.expectCaps(mWiFiAgent); 17989 mWiFiAgent.setNetworkPortal(TEST_REDIRECT_URL, false /* privateDnsProbeSent */); 17990 mCm.reportNetworkConnectivity(mWiFiAgent.getNetwork(), false); 17991 // Wi-Fi is now detected to have a portal : cell should become the default network. 17992 mDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellAgent); 17993 wifiNetworkCallback.expectCaps(mWiFiAgent, 17994 c -> !c.hasCapability(NET_CAPABILITY_VALIDATED)); 17995 wifiNetworkCallback.expectCaps(mWiFiAgent, 17996 c -> c.hasCapability(NET_CAPABILITY_CAPTIVE_PORTAL)); 17997 17998 // Wi-Fi becomes valid again. The default network goes back to Wi-Fi. 17999 mWiFiAgent.setNetworkValid(false /* privateDnsProbeSent */); 18000 mCm.reportNetworkConnectivity(mWiFiAgent.getNetwork(), true); 18001 mDefaultNetworkCallback.expectAvailableCallbacksValidated(mWiFiAgent); 18002 wifiNetworkCallback.expectCaps(mWiFiAgent, 18003 c -> !c.hasCapability(NET_CAPABILITY_CAPTIVE_PORTAL)); 18004 18005 // Wi-Fi roaming from wifiNc2 to wifiNc1, and the network now has partial connectivity. 18006 mWiFiAgent.setNetworkCapabilities(wifiNc1, true); 18007 wifiNetworkCallback.expectCaps(mWiFiAgent); 18008 mDefaultNetworkCallback.expectCaps(mWiFiAgent); 18009 mWiFiAgent.setNetworkPartial(); 18010 mCm.reportNetworkConnectivity(mWiFiAgent.getNetwork(), false); 18011 // Wi-Fi now only offers partial connectivity, so in the absence of accepting partial 18012 // connectivity explicitly for this network, it loses default status to cell. 18013 mDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellAgent); 18014 wifiNetworkCallback.expectCaps(mWiFiAgent, 18015 c -> c.hasCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY)); 18016 18017 // Wi-Fi becomes valid again. The default network goes back to Wi-Fi. 18018 mWiFiAgent.setNetworkValid(false /* privateDnsProbeSent */); 18019 mCm.reportNetworkConnectivity(mWiFiAgent.getNetwork(), true); 18020 mDefaultNetworkCallback.expectAvailableCallbacksValidated(mWiFiAgent); 18021 wifiNetworkCallback.expectCaps(mWiFiAgent, 18022 c -> !c.hasCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY)); 18023 } 18024 mCm.unregisterNetworkCallback(wifiNetworkCallback); 18025 18026 // Wi-Fi roams from wifiNc1 to wifiNc2, and now becomes really invalid. If validation 18027 // failures after roam are not ignored, this will cause cell to become the default network. 18028 // If they are ignored, this will not cause a switch until later. 18029 mWiFiAgent.setNetworkCapabilities(wifiNc2, true); 18030 mDefaultNetworkCallback.expectCaps(mWiFiAgent); 18031 mWiFiAgent.setNetworkInvalid(false /* invalidBecauseOfPrivateDns */); 18032 mCm.reportNetworkConnectivity(mWiFiAgent.getNetwork(), false); 18033 18034 if (enabled) { 18035 // Network validation failed, but the result will be ignored. 18036 assertTrue(mCm.getNetworkCapabilities(mWiFiAgent.getNetwork()).hasCapability( 18037 NET_CAPABILITY_VALIDATED)); 18038 mWiFiAgent.setNetworkValid(false); 18039 18040 // Behavior of after config_validationFailureAfterRoamIgnoreTimeMillis 18041 ConditionVariable waitForValidationBlock = new ConditionVariable(); 18042 doReturn(50).when(mResources) 18043 .getInteger(R.integer.config_validationFailureAfterRoamIgnoreTimeMillis); 18044 // Wi-Fi roaming from wifiNc2 to wifiNc1. 18045 mWiFiAgent.setNetworkCapabilities(wifiNc1, true); 18046 mWiFiAgent.setNetworkInvalid(false); 18047 waitForValidationBlock.block(150); 18048 mCm.reportNetworkConnectivity(mWiFiAgent.getNetwork(), false); 18049 mDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellAgent); 18050 } else { 18051 mDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellAgent); 18052 } 18053 18054 // Wi-Fi is still connected and would become the default network if cell were to 18055 // disconnect. This assertion ensures that the switch to cellular was not caused by 18056 // Wi-Fi disconnecting (e.g., because the capability change to wifiNc2 caused it 18057 // to stop satisfying the default request). 18058 mCellAgent.disconnect(); 18059 mDefaultNetworkCallback.expect(LOST, mCellAgent); 18060 mDefaultNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 18061 18062 } 18063 18064 @Test 18065 public void testIgnoreValidationAfterRoamDisabled() throws Exception { 18066 doTestIgnoreValidationAfterRoam(-1, false /* enabled */); 18067 } 18068 18069 @Test 18070 public void testIgnoreValidationAfterRoamEnabled() throws Exception { 18071 final boolean enabled = !mDeps.isAtLeastT(); 18072 doTestIgnoreValidationAfterRoam(5_000, enabled); 18073 } 18074 18075 @Test 18076 public void testShouldIgnoreValidationFailureAfterRoam() { 18077 // Always disabled on T+. 18078 assumeFalse(mDeps.isAtLeastT()); 18079 18080 NetworkAgentInfo nai = fakeWifiNai(new NetworkCapabilities()); 18081 18082 // Enabled, but never roamed. 18083 doReturn(5_000).when(mResources) 18084 .getInteger(R.integer.config_validationFailureAfterRoamIgnoreTimeMillis); 18085 assertEquals(0, nai.lastRoamTime); 18086 assertFalse(mService.shouldIgnoreValidationFailureAfterRoam(nai)); 18087 18088 // Roamed recently. 18089 nai.lastRoamTime = SystemClock.elapsedRealtime() - 500 /* ms */; 18090 assertTrue(mService.shouldIgnoreValidationFailureAfterRoam(nai)); 18091 18092 // Disabled due to invalid setting (maximum is 10 seconds). 18093 doReturn(15_000).when(mResources) 18094 .getInteger(R.integer.config_validationFailureAfterRoamIgnoreTimeMillis); 18095 assertFalse(mService.shouldIgnoreValidationFailureAfterRoam(nai)); 18096 18097 // Disabled. 18098 doReturn(-1).when(mResources) 18099 .getInteger(R.integer.config_validationFailureAfterRoamIgnoreTimeMillis); 18100 assertFalse(mService.shouldIgnoreValidationFailureAfterRoam(nai)); 18101 } 18102 18103 18104 @Test 18105 public void testLegacyTetheringApiGuardWithProperPermission() throws Exception { 18106 final String testIface = "test0"; 18107 mServiceContext.setPermission(ACCESS_NETWORK_STATE, PERMISSION_DENIED); 18108 assertThrows(SecurityException.class, () -> mService.getLastTetherError(testIface)); 18109 assertThrows(SecurityException.class, () -> mService.getTetherableIfaces()); 18110 assertThrows(SecurityException.class, () -> mService.getTetheredIfaces()); 18111 assertThrows(SecurityException.class, () -> mService.getTetheringErroredIfaces()); 18112 assertThrows(SecurityException.class, () -> mService.getTetherableUsbRegexs()); 18113 assertThrows(SecurityException.class, () -> mService.getTetherableWifiRegexs()); 18114 18115 withPermission(ACCESS_NETWORK_STATE, () -> { 18116 mService.getLastTetherError(testIface); 18117 verify(mTetheringManager).getLastTetherError(testIface); 18118 18119 mService.getTetherableIfaces(); 18120 verify(mTetheringManager).getTetherableIfaces(); 18121 18122 mService.getTetheredIfaces(); 18123 verify(mTetheringManager).getTetheredIfaces(); 18124 18125 mService.getTetheringErroredIfaces(); 18126 verify(mTetheringManager).getTetheringErroredIfaces(); 18127 18128 mService.getTetherableUsbRegexs(); 18129 verify(mTetheringManager).getTetherableUsbRegexs(); 18130 18131 mService.getTetherableWifiRegexs(); 18132 verify(mTetheringManager).getTetherableWifiRegexs(); 18133 }); 18134 } 18135 18136 private void verifyMtuSetOnWifiInterface(int mtu) throws Exception { 18137 verify(mMockNetd, times(1)).interfaceSetMtu(WIFI_IFNAME, mtu); 18138 } 18139 18140 private void verifyMtuNeverSetOnWifiInterface() throws Exception { 18141 verify(mMockNetd, never()).interfaceSetMtu(eq(WIFI_IFNAME), anyInt()); 18142 } 18143 18144 private void verifyMtuSetOnWifiInterfaceOnlyUpToT(int mtu) throws Exception { 18145 if (!mService.shouldCreateNetworksImmediately()) { 18146 verify(mMockNetd, times(1)).interfaceSetMtu(WIFI_IFNAME, mtu); 18147 } else { 18148 verify(mMockNetd, never()).interfaceSetMtu(eq(WIFI_IFNAME), anyInt()); 18149 } 18150 } 18151 18152 private void verifyMtuSetOnWifiInterfaceOnlyStartingFromU(int mtu) throws Exception { 18153 if (mService.shouldCreateNetworksImmediately()) { 18154 verify(mMockNetd, times(1)).interfaceSetMtu(WIFI_IFNAME, mtu); 18155 } else { 18156 verify(mMockNetd, never()).interfaceSetMtu(eq(WIFI_IFNAME), anyInt()); 18157 } 18158 } 18159 18160 @Test 18161 public void testSendLinkPropertiesSetInterfaceMtuBeforeConnect() throws Exception { 18162 final int mtu = 1281; 18163 LinkProperties lp = new LinkProperties(); 18164 lp.setInterfaceName(WIFI_IFNAME); 18165 lp.setMtu(mtu); 18166 18167 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 18168 mWiFiAgent.sendLinkProperties(lp); 18169 waitForIdle(); 18170 verifyMtuSetOnWifiInterface(mtu); 18171 reset(mMockNetd); 18172 18173 mWiFiAgent.connect(false /* validated */); 18174 // Before U, the MTU is always (re-)applied when the network connects. 18175 verifyMtuSetOnWifiInterfaceOnlyUpToT(mtu); 18176 } 18177 18178 @Test 18179 public void testSendLinkPropertiesUpdateInterfaceMtuBeforeConnect() throws Exception { 18180 final int mtu = 1327; 18181 LinkProperties lp = new LinkProperties(); 18182 lp.setInterfaceName(WIFI_IFNAME); 18183 lp.setMtu(mtu); 18184 18185 // Registering an agent with an MTU only sets the MTU on U+. 18186 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, lp); 18187 waitForIdle(); 18188 verifyMtuSetOnWifiInterfaceOnlyStartingFromU(mtu); 18189 reset(mMockNetd); 18190 18191 // Future updates with the same MTU don't set the MTU even on T when it's not set initially. 18192 mWiFiAgent.sendLinkProperties(lp); 18193 waitForIdle(); 18194 verifyMtuNeverSetOnWifiInterface(); 18195 18196 // Updating with a different MTU does work. 18197 lp.setMtu(mtu + 1); 18198 mWiFiAgent.sendLinkProperties(lp); 18199 waitForIdle(); 18200 verifyMtuSetOnWifiInterface(mtu + 1); 18201 reset(mMockNetd); 18202 18203 mWiFiAgent.connect(false /* validated */); 18204 // Before U, the MTU is always (re-)applied when the network connects. 18205 verifyMtuSetOnWifiInterfaceOnlyUpToT(mtu + 1); 18206 } 18207 18208 @Test 18209 public void testSendLinkPropertiesUpdateInterfaceMtuAfterConnect() throws Exception { 18210 final int mtu = 1327; 18211 LinkProperties lp = new LinkProperties(); 18212 lp.setInterfaceName(WIFI_IFNAME); 18213 lp.setMtu(mtu); 18214 18215 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 18216 mWiFiAgent.connect(false /* validated */); 18217 verifyMtuNeverSetOnWifiInterface(); 18218 18219 mWiFiAgent.sendLinkProperties(lp); 18220 waitForIdle(); 18221 // The MTU is always (re-)applied when the network connects. 18222 verifyMtuSetOnWifiInterface(mtu); 18223 } 18224 18225 @Test 18226 public void testSendLinkPropertiesSetInterfaceMtu_DifferentMtu() throws Exception { 18227 final int mtu = 1328, mtu2 = 1500; 18228 LinkProperties lp = new LinkProperties(); 18229 lp.setInterfaceName(WIFI_IFNAME); 18230 lp.setMtu(mtu); 18231 18232 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, lp); 18233 mWiFiAgent.connect(false /* validated */); 18234 verifyMtuSetOnWifiInterface(mtu); 18235 reset(mMockNetd); 18236 18237 LinkProperties lp2 = new LinkProperties(lp); 18238 lp2.setMtu(mtu2); 18239 mWiFiAgent.sendLinkProperties(lp2); 18240 waitForIdle(); 18241 verifyMtuSetOnWifiInterface(mtu2); 18242 } 18243 18244 @Test 18245 public void testSendLinkPropertiesSetInterfaceMtu_IdenticalMtuAndIface() throws Exception { 18246 final int mtu = 1329; 18247 LinkProperties lp = new LinkProperties(); 18248 lp.setInterfaceName(WIFI_IFNAME); 18249 lp.setMtu(mtu); 18250 18251 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, lp); 18252 mWiFiAgent.connect(false /* validated */); 18253 verifyMtuSetOnWifiInterface(mtu); 18254 reset(mMockNetd); 18255 18256 mWiFiAgent.sendLinkProperties(new LinkProperties(lp)); 18257 waitForIdle(); 18258 verifyMtuNeverSetOnWifiInterface(); 18259 } 18260 18261 @Test 18262 public void testSendLinkPropertiesSetInterfaceMtu_IdenticalMtuAndNullIface() throws Exception { 18263 final int mtu = 1330; 18264 LinkProperties lp = new LinkProperties(); 18265 lp.setInterfaceName(WIFI_IFNAME); 18266 lp.setMtu(mtu); 18267 18268 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, lp); 18269 mWiFiAgent.connect(false /* validated */); 18270 verifyMtuSetOnWifiInterface(mtu); 18271 reset(mMockNetd); 18272 18273 LinkProperties lp2 = new LinkProperties(lp); 18274 lp2.setInterfaceName(null); 18275 mWiFiAgent.sendLinkProperties(new LinkProperties(lp2)); 18276 waitForIdle(); 18277 verifyMtuNeverSetOnWifiInterface(); 18278 } 18279 18280 @Test 18281 public void testSendLinkPropertiesSetInterfaceMtu_IdenticalMtuDiffIface() throws Exception { 18282 final int mtu = 1331; 18283 LinkProperties lp = new LinkProperties(); 18284 lp.setInterfaceName(WIFI_IFNAME); 18285 lp.setMtu(mtu); 18286 18287 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, lp); 18288 mWiFiAgent.connect(false /* validated */); 18289 verifyMtuSetOnWifiInterface(mtu); 18290 reset(mMockNetd); 18291 18292 final String ifaceName2 = WIFI_IFNAME + "_2"; 18293 LinkProperties lp2 = new LinkProperties(lp); 18294 lp2.setInterfaceName(ifaceName2); 18295 18296 mWiFiAgent.sendLinkProperties(new LinkProperties(lp2)); 18297 waitForIdle(); 18298 verify(mMockNetd, times(1)).interfaceSetMtu(eq(ifaceName2), eq(mtu)); 18299 verifyMtuNeverSetOnWifiInterface(); 18300 } 18301 18302 @Test 18303 public void testCreateDeliveryGroupKeyForConnectivityAction() throws Exception { 18304 final NetworkInfo info = new NetworkInfo(0 /* type */, 2 /* subtype */, 18305 "MOBILE" /* typeName */, "LTE" /* subtypeName */); 18306 assertEquals("0;2;null", createDeliveryGroupKeyForConnectivityAction(info)); 18307 18308 info.setExtraInfo("test_info"); 18309 assertEquals("0;2;test_info", createDeliveryGroupKeyForConnectivityAction(info)); 18310 } 18311 18312 @Test 18313 public void testNetdWakeupAddInterfaceForWifiTransport() throws Exception { 18314 final LinkProperties wifiLp = new LinkProperties(); 18315 wifiLp.setInterfaceName(WIFI_IFNAME); 18316 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, wifiLp); 18317 mWiFiAgent.connect(false /* validated */); 18318 18319 final String expectedPrefix = makeNflogPrefix(WIFI_IFNAME, 18320 mWiFiAgent.getNetwork().getNetworkHandle()); 18321 verify(mMockNetd).wakeupAddInterface(WIFI_IFNAME, expectedPrefix, PACKET_WAKEUP_MARK_MASK, 18322 PACKET_WAKEUP_MARK_MASK); 18323 } 18324 18325 @Test 18326 public void testNetdWakeupAddInterfaceForCellularTransport() throws Exception { 18327 final LinkProperties cellLp = new LinkProperties(); 18328 cellLp.setInterfaceName(MOBILE_IFNAME); 18329 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp); 18330 mCellAgent.connect(false /* validated */); 18331 18332 if (mDeps.isAtLeastU()) { 18333 final String expectedPrefix = makeNflogPrefix(MOBILE_IFNAME, 18334 mCellAgent.getNetwork().getNetworkHandle()); 18335 verify(mMockNetd).wakeupAddInterface(MOBILE_IFNAME, expectedPrefix, 18336 PACKET_WAKEUP_MARK_MASK, PACKET_WAKEUP_MARK_MASK); 18337 } else { 18338 verify(mMockNetd, never()).wakeupAddInterface(eq(MOBILE_IFNAME), anyString(), anyInt(), 18339 anyInt()); 18340 } 18341 } 18342 18343 @Test 18344 public void testNetdWakeupAddInterfaceForEthernetTransport() throws Exception { 18345 final String ethernetIface = "eth42"; 18346 18347 final LinkProperties ethLp = new LinkProperties(); 18348 ethLp.setInterfaceName(ethernetIface); 18349 mEthernetAgent = new TestNetworkAgentWrapper(TRANSPORT_ETHERNET, ethLp); 18350 mEthernetAgent.connect(false /* validated */); 18351 18352 verify(mMockNetd, never()).wakeupAddInterface(eq(ethernetIface), anyString(), anyInt(), 18353 anyInt()); 18354 } 18355 18356 private static final int TEST_FROZEN_UID = 1000; 18357 private static final int TEST_UNFROZEN_UID = 2000; 18358 18359 /** 18360 * Send a UidFrozenStateChanged message to ConnectivityService. Verify that only the frozen UID 18361 * gets passed to socketDestroy(). 18362 */ 18363 @Test 18364 @IgnoreUpTo(Build.VERSION_CODES.TIRAMISU) 18365 public void testFrozenUidSocketDestroy() throws Exception { 18366 ArgumentCaptor<UidFrozenStateChangedCallback> callbackArg = 18367 ArgumentCaptor.forClass(UidFrozenStateChangedCallback.class); 18368 18369 verify(mActivityManager).registerUidFrozenStateChangedCallback(any(), 18370 callbackArg.capture()); 18371 18372 final int[] uids = {TEST_FROZEN_UID, TEST_UNFROZEN_UID}; 18373 final int[] frozenStates = {UID_FROZEN_STATE_FROZEN, UID_FROZEN_STATE_UNFROZEN}; 18374 18375 callbackArg.getValue().onUidFrozenStateChanged(uids, frozenStates); 18376 18377 waitForIdle(); 18378 18379 final Set<Integer> exemptUids = new ArraySet(); 18380 final UidRange frozenUidRange = new UidRange(TEST_FROZEN_UID, TEST_FROZEN_UID); 18381 final Set<UidRange> ranges = Collections.singleton(frozenUidRange); 18382 18383 verify(mDestroySocketsWrapper).destroyLiveTcpSockets(eq(UidRange.toIntRanges(ranges)), 18384 eq(exemptUids)); 18385 } 18386 18387 @Test 18388 public void testDisconnectSuspendedNetworkStopClatd() throws Exception { 18389 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 18390 final NetworkRequest networkRequest = new NetworkRequest.Builder() 18391 .addCapability(NET_CAPABILITY_DUN) 18392 .build(); 18393 mCm.requestNetwork(networkRequest, networkCallback); 18394 18395 final IpPrefix nat64Prefix = new IpPrefix(InetAddress.getByName("64:ff9b::"), 96); 18396 NetworkCapabilities nc = new NetworkCapabilities().addCapability(NET_CAPABILITY_DUN); 18397 final LinkProperties lp = new LinkProperties(); 18398 lp.setInterfaceName(MOBILE_IFNAME); 18399 lp.addLinkAddress(new LinkAddress("2001:db8:1::1/64")); 18400 lp.setNat64Prefix(nat64Prefix); 18401 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, lp, nc); 18402 mCellAgent.connect(true /* validated */, false /* hasInternet */, 18403 false /* privateDnsProbeSent */); 18404 18405 verifyClatdStart(null /* inOrder */, MOBILE_IFNAME, mCellAgent.getNetwork().netId, 18406 nat64Prefix.toString()); 18407 18408 mCellAgent.suspend(); 18409 mCm.unregisterNetworkCallback(networkCallback); 18410 mCellAgent.expectDisconnected(); 18411 waitForIdle(); 18412 18413 verifyClatdStop(null /* inOrder */, MOBILE_IFNAME); 18414 } 18415 } 18416