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_STACK; 31 import static android.Manifest.permission.PACKET_KEEPALIVE_OFFLOAD; 32 import static android.app.PendingIntent.FLAG_IMMUTABLE; 33 import static android.content.Intent.ACTION_PACKAGE_ADDED; 34 import static android.content.Intent.ACTION_PACKAGE_REMOVED; 35 import static android.content.Intent.ACTION_PACKAGE_REPLACED; 36 import static android.content.Intent.ACTION_USER_ADDED; 37 import static android.content.Intent.ACTION_USER_REMOVED; 38 import static android.content.Intent.ACTION_USER_UNLOCKED; 39 import static android.content.pm.PackageInfo.REQUESTED_PERMISSION_GRANTED; 40 import static android.content.pm.PackageManager.FEATURE_ETHERNET; 41 import static android.content.pm.PackageManager.FEATURE_WIFI; 42 import static android.content.pm.PackageManager.FEATURE_WIFI_DIRECT; 43 import static android.content.pm.PackageManager.GET_PERMISSIONS; 44 import static android.content.pm.PackageManager.PERMISSION_DENIED; 45 import static android.content.pm.PackageManager.PERMISSION_GRANTED; 46 import static android.net.ConnectivityManager.ACTION_CAPTIVE_PORTAL_SIGN_IN; 47 import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_DATA_SAVER; 48 import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_MASK; 49 import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_USER_RESTRICTED; 50 import static android.net.ConnectivityManager.BLOCKED_REASON_BATTERY_SAVER; 51 import static android.net.ConnectivityManager.BLOCKED_REASON_NONE; 52 import static android.net.ConnectivityManager.CONNECTIVITY_ACTION; 53 import static android.net.ConnectivityManager.EXTRA_NETWORK_INFO; 54 import static android.net.ConnectivityManager.EXTRA_NETWORK_TYPE; 55 import static android.net.ConnectivityManager.FIREWALL_CHAIN_DOZABLE; 56 import static android.net.ConnectivityManager.FIREWALL_CHAIN_LOCKDOWN_VPN; 57 import static android.net.ConnectivityManager.FIREWALL_CHAIN_LOW_POWER_STANDBY; 58 import static android.net.ConnectivityManager.FIREWALL_CHAIN_OEM_DENY_1; 59 import static android.net.ConnectivityManager.FIREWALL_CHAIN_OEM_DENY_2; 60 import static android.net.ConnectivityManager.FIREWALL_CHAIN_OEM_DENY_3; 61 import static android.net.ConnectivityManager.FIREWALL_CHAIN_POWERSAVE; 62 import static android.net.ConnectivityManager.FIREWALL_CHAIN_RESTRICTED; 63 import static android.net.ConnectivityManager.FIREWALL_CHAIN_STANDBY; 64 import static android.net.ConnectivityManager.FIREWALL_RULE_ALLOW; 65 import static android.net.ConnectivityManager.FIREWALL_RULE_DEFAULT; 66 import static android.net.ConnectivityManager.FIREWALL_RULE_DENY; 67 import static android.net.ConnectivityManager.PROFILE_NETWORK_PREFERENCE_DEFAULT; 68 import static android.net.ConnectivityManager.PROFILE_NETWORK_PREFERENCE_ENTERPRISE; 69 import static android.net.ConnectivityManager.PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK; 70 import static android.net.ConnectivityManager.TYPE_ETHERNET; 71 import static android.net.ConnectivityManager.TYPE_MOBILE; 72 import static android.net.ConnectivityManager.TYPE_MOBILE_FOTA; 73 import static android.net.ConnectivityManager.TYPE_MOBILE_MMS; 74 import static android.net.ConnectivityManager.TYPE_MOBILE_SUPL; 75 import static android.net.ConnectivityManager.TYPE_PROXY; 76 import static android.net.ConnectivityManager.TYPE_VPN; 77 import static android.net.ConnectivityManager.TYPE_WIFI; 78 import static android.net.ConnectivitySettingsManager.PRIVATE_DNS_MODE_OFF; 79 import static android.net.ConnectivitySettingsManager.PRIVATE_DNS_MODE_OPPORTUNISTIC; 80 import static android.net.ConnectivitySettingsManager.PRIVATE_DNS_MODE_PROVIDER_HOSTNAME; 81 import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_DNS; 82 import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_FALLBACK; 83 import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_HTTP; 84 import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_HTTPS; 85 import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_PRIVDNS; 86 import static android.net.INetworkMonitor.NETWORK_VALIDATION_RESULT_PARTIAL; 87 import static android.net.INetworkMonitor.NETWORK_VALIDATION_RESULT_VALID; 88 import static android.net.NetworkCapabilities.NET_CAPABILITY_BIP; 89 import static android.net.NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL; 90 import static android.net.NetworkCapabilities.NET_CAPABILITY_CBS; 91 import static android.net.NetworkCapabilities.NET_CAPABILITY_DUN; 92 import static android.net.NetworkCapabilities.NET_CAPABILITY_EIMS; 93 import static android.net.NetworkCapabilities.NET_CAPABILITY_ENTERPRISE; 94 import static android.net.NetworkCapabilities.NET_CAPABILITY_FOREGROUND; 95 import static android.net.NetworkCapabilities.NET_CAPABILITY_FOTA; 96 import static android.net.NetworkCapabilities.NET_CAPABILITY_IA; 97 import static android.net.NetworkCapabilities.NET_CAPABILITY_IMS; 98 import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET; 99 import static android.net.NetworkCapabilities.NET_CAPABILITY_MMS; 100 import static android.net.NetworkCapabilities.NET_CAPABILITY_MMTEL; 101 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED; 102 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED; 103 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED; 104 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING; 105 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED; 106 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED; 107 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN; 108 import static android.net.NetworkCapabilities.NET_CAPABILITY_OEM_PAID; 109 import static android.net.NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE; 110 import static android.net.NetworkCapabilities.NET_CAPABILITY_PARTIAL_CONNECTIVITY; 111 import static android.net.NetworkCapabilities.NET_CAPABILITY_RCS; 112 import static android.net.NetworkCapabilities.NET_CAPABILITY_SUPL; 113 import static android.net.NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED; 114 import static android.net.NetworkCapabilities.NET_CAPABILITY_TRUSTED; 115 import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED; 116 import static android.net.NetworkCapabilities.NET_CAPABILITY_VSIM; 117 import static android.net.NetworkCapabilities.NET_CAPABILITY_WIFI_P2P; 118 import static android.net.NetworkCapabilities.NET_CAPABILITY_XCAP; 119 import static android.net.NetworkCapabilities.NET_ENTERPRISE_ID_1; 120 import static android.net.NetworkCapabilities.NET_ENTERPRISE_ID_2; 121 import static android.net.NetworkCapabilities.NET_ENTERPRISE_ID_3; 122 import static android.net.NetworkCapabilities.NET_ENTERPRISE_ID_4; 123 import static android.net.NetworkCapabilities.NET_ENTERPRISE_ID_5; 124 import static android.net.NetworkCapabilities.REDACT_FOR_ACCESS_FINE_LOCATION; 125 import static android.net.NetworkCapabilities.REDACT_FOR_LOCAL_MAC_ADDRESS; 126 import static android.net.NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS; 127 import static android.net.NetworkCapabilities.REDACT_NONE; 128 import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; 129 import static android.net.NetworkCapabilities.TRANSPORT_ETHERNET; 130 import static android.net.NetworkCapabilities.TRANSPORT_TEST; 131 import static android.net.NetworkCapabilities.TRANSPORT_VPN; 132 import static android.net.NetworkCapabilities.TRANSPORT_WIFI; 133 import static android.net.NetworkCapabilities.TRANSPORT_WIFI_AWARE; 134 import static android.net.NetworkScore.KEEP_CONNECTED_FOR_HANDOVER; 135 import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID; 136 import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK; 137 import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY; 138 import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY; 139 import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_TEST; 140 import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_TEST_ONLY; 141 import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_UNINITIALIZED; 142 import static android.net.RouteInfo.RTN_UNREACHABLE; 143 import static android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener.PREFIX_OPERATION_ADDED; 144 import static android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener.PREFIX_OPERATION_REMOVED; 145 import static android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener.VALIDATION_RESULT_FAILURE; 146 import static android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener.VALIDATION_RESULT_SUCCESS; 147 import static android.os.Process.INVALID_UID; 148 import static android.system.OsConstants.IPPROTO_TCP; 149 150 import static com.android.server.ConnectivityService.MAX_NETWORK_REQUESTS_PER_SYSTEM_UID; 151 import static com.android.server.ConnectivityService.PREFERENCE_ORDER_MOBILE_DATA_PREFERERRED; 152 import static com.android.server.ConnectivityService.PREFERENCE_ORDER_OEM; 153 import static com.android.server.ConnectivityService.PREFERENCE_ORDER_PROFILE; 154 import static com.android.server.ConnectivityService.PREFERENCE_ORDER_VPN; 155 import static com.android.server.ConnectivityServiceTestUtils.transportToLegacyType; 156 import static com.android.testutils.ConcurrentUtils.await; 157 import static com.android.testutils.ConcurrentUtils.durationOf; 158 import static com.android.testutils.DevSdkIgnoreRule.IgnoreAfter; 159 import static com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo; 160 import static com.android.testutils.DevSdkIgnoreRuleKt.SC_V2; 161 import static com.android.testutils.ExceptionUtils.ignoreExceptions; 162 import static com.android.testutils.HandlerUtils.waitForIdleSerialExecutor; 163 import static com.android.testutils.MiscAsserts.assertContainsAll; 164 import static com.android.testutils.MiscAsserts.assertContainsExactly; 165 import static com.android.testutils.MiscAsserts.assertEmpty; 166 import static com.android.testutils.MiscAsserts.assertLength; 167 import static com.android.testutils.MiscAsserts.assertRunsInAtMost; 168 import static com.android.testutils.MiscAsserts.assertSameElements; 169 import static com.android.testutils.MiscAsserts.assertThrows; 170 import static com.android.testutils.TestPermissionUtil.runAsShell; 171 172 import static org.junit.Assert.assertEquals; 173 import static org.junit.Assert.assertFalse; 174 import static org.junit.Assert.assertNotEquals; 175 import static org.junit.Assert.assertNotNull; 176 import static org.junit.Assert.assertNull; 177 import static org.junit.Assert.assertTrue; 178 import static org.junit.Assert.fail; 179 import static org.junit.Assume.assumeFalse; 180 import static org.junit.Assume.assumeTrue; 181 import static org.mockito.AdditionalMatchers.aryEq; 182 import static org.mockito.ArgumentMatchers.anyBoolean; 183 import static org.mockito.ArgumentMatchers.anyLong; 184 import static org.mockito.ArgumentMatchers.anyString; 185 import static org.mockito.ArgumentMatchers.argThat; 186 import static org.mockito.ArgumentMatchers.eq; 187 import static org.mockito.ArgumentMatchers.isNull; 188 import static org.mockito.Matchers.anyInt; 189 import static org.mockito.Mockito.any; 190 import static org.mockito.Mockito.atLeastOnce; 191 import static org.mockito.Mockito.doAnswer; 192 import static org.mockito.Mockito.doNothing; 193 import static org.mockito.Mockito.doReturn; 194 import static org.mockito.Mockito.doThrow; 195 import static org.mockito.Mockito.inOrder; 196 import static org.mockito.Mockito.mock; 197 import static org.mockito.Mockito.never; 198 import static org.mockito.Mockito.reset; 199 import static org.mockito.Mockito.spy; 200 import static org.mockito.Mockito.timeout; 201 import static org.mockito.Mockito.times; 202 import static org.mockito.Mockito.verify; 203 import static org.mockito.Mockito.verifyNoMoreInteractions; 204 205 import static java.util.Arrays.asList; 206 207 import android.Manifest; 208 import android.annotation.NonNull; 209 import android.annotation.Nullable; 210 import android.app.AlarmManager; 211 import android.app.AppOpsManager; 212 import android.app.NotificationManager; 213 import android.app.PendingIntent; 214 import android.app.admin.DevicePolicyManager; 215 import android.app.usage.NetworkStatsManager; 216 import android.content.BroadcastReceiver; 217 import android.content.ComponentName; 218 import android.content.ContentProvider; 219 import android.content.ContentResolver; 220 import android.content.Context; 221 import android.content.Intent; 222 import android.content.IntentFilter; 223 import android.content.pm.ApplicationInfo; 224 import android.content.pm.PackageInfo; 225 import android.content.pm.PackageManager; 226 import android.content.pm.ResolveInfo; 227 import android.content.pm.ServiceInfo; 228 import android.content.pm.UserInfo; 229 import android.content.res.Resources; 230 import android.location.LocationManager; 231 import android.net.CaptivePortalData; 232 import android.net.ConnectionInfo; 233 import android.net.ConnectivityDiagnosticsManager.DataStallReport; 234 import android.net.ConnectivityManager; 235 import android.net.ConnectivityManager.NetworkCallback; 236 import android.net.ConnectivityManager.PacketKeepalive; 237 import android.net.ConnectivityManager.PacketKeepaliveCallback; 238 import android.net.ConnectivityManager.TooManyRequestsException; 239 import android.net.ConnectivityResources; 240 import android.net.ConnectivitySettingsManager; 241 import android.net.ConnectivityThread; 242 import android.net.DataStallReportParcelable; 243 import android.net.EthernetManager; 244 import android.net.IConnectivityDiagnosticsCallback; 245 import android.net.IDnsResolver; 246 import android.net.INetd; 247 import android.net.INetworkMonitor; 248 import android.net.INetworkMonitorCallbacks; 249 import android.net.IOnCompleteListener; 250 import android.net.IQosCallback; 251 import android.net.InetAddresses; 252 import android.net.InterfaceConfigurationParcel; 253 import android.net.IpPrefix; 254 import android.net.IpSecManager; 255 import android.net.IpSecManager.UdpEncapsulationSocket; 256 import android.net.LinkAddress; 257 import android.net.LinkProperties; 258 import android.net.MatchAllNetworkSpecifier; 259 import android.net.NativeNetworkConfig; 260 import android.net.NativeNetworkType; 261 import android.net.Network; 262 import android.net.NetworkAgent; 263 import android.net.NetworkAgentConfig; 264 import android.net.NetworkCapabilities; 265 import android.net.NetworkFactory; 266 import android.net.NetworkInfo; 267 import android.net.NetworkInfo.DetailedState; 268 import android.net.NetworkPolicyManager; 269 import android.net.NetworkPolicyManager.NetworkPolicyCallback; 270 import android.net.NetworkProvider; 271 import android.net.NetworkRequest; 272 import android.net.NetworkScore; 273 import android.net.NetworkSpecifier; 274 import android.net.NetworkStack; 275 import android.net.NetworkStateSnapshot; 276 import android.net.NetworkTestResultParcelable; 277 import android.net.OemNetworkPreferences; 278 import android.net.PacProxyManager; 279 import android.net.ProfileNetworkPreference; 280 import android.net.Proxy; 281 import android.net.ProxyInfo; 282 import android.net.QosCallbackException; 283 import android.net.QosFilter; 284 import android.net.QosSession; 285 import android.net.ResolverParamsParcel; 286 import android.net.RouteInfo; 287 import android.net.RouteInfoParcel; 288 import android.net.SocketKeepalive; 289 import android.net.TelephonyNetworkSpecifier; 290 import android.net.TetheringManager; 291 import android.net.TransportInfo; 292 import android.net.UidRange; 293 import android.net.UidRangeParcel; 294 import android.net.UnderlyingNetworkInfo; 295 import android.net.Uri; 296 import android.net.VpnManager; 297 import android.net.VpnTransportInfo; 298 import android.net.metrics.IpConnectivityLog; 299 import android.net.netd.aidl.NativeUidRangeConfig; 300 import android.net.networkstack.NetworkStackClientBase; 301 import android.net.resolv.aidl.Nat64PrefixEventParcel; 302 import android.net.resolv.aidl.PrivateDnsValidationEventParcel; 303 import android.net.shared.NetworkMonitorUtils; 304 import android.net.shared.PrivateDnsConfig; 305 import android.net.util.MultinetworkPolicyTracker; 306 import android.net.wifi.WifiInfo; 307 import android.os.BadParcelableException; 308 import android.os.BatteryStatsManager; 309 import android.os.Binder; 310 import android.os.Build; 311 import android.os.Bundle; 312 import android.os.ConditionVariable; 313 import android.os.Handler; 314 import android.os.HandlerThread; 315 import android.os.IBinder; 316 import android.os.INetworkManagementService; 317 import android.os.Looper; 318 import android.os.Messenger; 319 import android.os.Parcel; 320 import android.os.ParcelFileDescriptor; 321 import android.os.Parcelable; 322 import android.os.PersistableBundle; 323 import android.os.Process; 324 import android.os.RemoteException; 325 import android.os.ServiceSpecificException; 326 import android.os.SystemClock; 327 import android.os.SystemConfigManager; 328 import android.os.UserHandle; 329 import android.os.UserManager; 330 import android.provider.Settings; 331 import android.security.Credentials; 332 import android.system.Os; 333 import android.telephony.TelephonyManager; 334 import android.telephony.data.EpsBearerQosSessionAttributes; 335 import android.telephony.data.NrQosSessionAttributes; 336 import android.test.mock.MockContentResolver; 337 import android.text.TextUtils; 338 import android.util.ArraySet; 339 import android.util.Log; 340 import android.util.Pair; 341 import android.util.Range; 342 import android.util.SparseArray; 343 344 import androidx.test.InstrumentationRegistry; 345 import androidx.test.filters.SmallTest; 346 347 import com.android.connectivity.resources.R; 348 import com.android.internal.annotations.GuardedBy; 349 import com.android.internal.app.IBatteryStats; 350 import com.android.internal.net.VpnConfig; 351 import com.android.internal.net.VpnProfile; 352 import com.android.internal.util.WakeupMessage; 353 import com.android.internal.util.test.BroadcastInterceptingContext; 354 import com.android.internal.util.test.FakeSettingsProvider; 355 import com.android.modules.utils.build.SdkLevel; 356 import com.android.net.module.util.ArrayTrackRecord; 357 import com.android.net.module.util.CollectionUtils; 358 import com.android.net.module.util.LocationPermissionChecker; 359 import com.android.networkstack.apishim.NetworkAgentConfigShimImpl; 360 import com.android.networkstack.apishim.api29.ConstantsShim; 361 import com.android.server.ConnectivityService.ConnectivityDiagnosticsCallbackInfo; 362 import com.android.server.ConnectivityService.NetworkRequestInfo; 363 import com.android.server.ConnectivityServiceTest.ConnectivityServiceDependencies.ReportedInterfaces; 364 import com.android.server.connectivity.CarrierPrivilegeAuthenticator; 365 import com.android.server.connectivity.ClatCoordinator; 366 import com.android.server.connectivity.ConnectivityFlags; 367 import com.android.server.connectivity.MockableSystemProperties; 368 import com.android.server.connectivity.Nat464Xlat; 369 import com.android.server.connectivity.NetworkAgentInfo; 370 import com.android.server.connectivity.NetworkNotificationManager.NotificationType; 371 import com.android.server.connectivity.ProxyTracker; 372 import com.android.server.connectivity.QosCallbackTracker; 373 import com.android.server.connectivity.UidRangeUtils; 374 import com.android.server.connectivity.Vpn; 375 import com.android.server.connectivity.VpnProfileStore; 376 import com.android.server.net.NetworkPinner; 377 import com.android.testutils.DevSdkIgnoreRule; 378 import com.android.testutils.DevSdkIgnoreRunner; 379 import com.android.testutils.ExceptionUtils; 380 import com.android.testutils.HandlerUtils; 381 import com.android.testutils.RecorderCallback.CallbackEntry; 382 import com.android.testutils.TestableNetworkCallback; 383 import com.android.testutils.TestableNetworkOfferCallback; 384 385 import org.junit.After; 386 import org.junit.Assert; 387 import org.junit.Before; 388 import org.junit.Ignore; 389 import org.junit.Rule; 390 import org.junit.Test; 391 import org.junit.runner.RunWith; 392 import org.mockito.AdditionalAnswers; 393 import org.mockito.ArgumentCaptor; 394 import org.mockito.InOrder; 395 import org.mockito.Mock; 396 import org.mockito.MockitoAnnotations; 397 import org.mockito.Spy; 398 import org.mockito.stubbing.Answer; 399 400 import java.io.FileDescriptor; 401 import java.io.IOException; 402 import java.io.PrintWriter; 403 import java.io.StringWriter; 404 import java.net.DatagramSocket; 405 import java.net.Inet4Address; 406 import java.net.Inet6Address; 407 import java.net.InetAddress; 408 import java.net.InetSocketAddress; 409 import java.net.Socket; 410 import java.nio.charset.StandardCharsets; 411 import java.util.ArrayList; 412 import java.util.Arrays; 413 import java.util.Collection; 414 import java.util.Collections; 415 import java.util.Comparator; 416 import java.util.HashMap; 417 import java.util.HashSet; 418 import java.util.List; 419 import java.util.Map; 420 import java.util.Objects; 421 import java.util.Set; 422 import java.util.concurrent.CompletableFuture; 423 import java.util.concurrent.CountDownLatch; 424 import java.util.concurrent.Executor; 425 import java.util.concurrent.ExecutorService; 426 import java.util.concurrent.Executors; 427 import java.util.concurrent.LinkedBlockingQueue; 428 import java.util.concurrent.TimeUnit; 429 import java.util.concurrent.TimeoutException; 430 import java.util.concurrent.atomic.AtomicBoolean; 431 import java.util.concurrent.atomic.AtomicReference; 432 import java.util.function.Predicate; 433 import java.util.function.Supplier; 434 import java.util.regex.Matcher; 435 import java.util.regex.Pattern; 436 import java.util.stream.Collectors; 437 438 import kotlin.reflect.KClass; 439 440 /** 441 * Tests for {@link ConnectivityService}. 442 * 443 * Build, install and run with: 444 * runtest frameworks-net -c com.android.server.ConnectivityServiceTest 445 */ 446 @RunWith(DevSdkIgnoreRunner.class) 447 @SmallTest 448 @DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.R) 449 public class ConnectivityServiceTest { 450 private static final String TAG = "ConnectivityServiceTest"; 451 452 @Rule 453 public final DevSdkIgnoreRule ignoreRule = new DevSdkIgnoreRule(); 454 455 private static final int TIMEOUT_MS = 2_000; 456 // Broadcasts can take a long time to be delivered. The test will not wait for that long unless 457 // there is a failure, so use a long timeout. 458 private static final int BROADCAST_TIMEOUT_MS = 30_000; 459 private static final int TEST_LINGER_DELAY_MS = 400; 460 private static final int TEST_NASCENT_DELAY_MS = 300; 461 // Chosen to be less than the linger and nascent timeout. This ensures that we can distinguish 462 // between a LOST callback that arrives immediately and a LOST callback that arrives after 463 // the linger/nascent timeout. For this, our assertions should run fast enough to leave 464 // less than (mService.mLingerDelayMs - TEST_CALLBACK_TIMEOUT_MS) between the time callbacks are 465 // supposedly fired, and the time we call expectCallback. 466 private static final int TEST_CALLBACK_TIMEOUT_MS = 250; 467 // Chosen to be less than TEST_CALLBACK_TIMEOUT_MS. This ensures that requests have time to 468 // complete before callbacks are verified. 469 private static final int TEST_REQUEST_TIMEOUT_MS = 150; 470 471 private static final int UNREASONABLY_LONG_ALARM_WAIT_MS = 1000; 472 473 private static final long TIMESTAMP = 1234L; 474 475 private static final int NET_ID = 110; 476 private static final int OEM_PREF_ANY_NET_ID = -1; 477 // Set a non-zero value to verify the flow to set tcp init rwnd value. 478 private static final int TEST_TCP_INIT_RWND = 60; 479 480 // Used for testing the per-work-profile default network. 481 private static final int TEST_APP_ID = 103; 482 private static final int TEST_WORK_PROFILE_USER_ID = 2; 483 private static final int TEST_WORK_PROFILE_APP_UID = 484 UserHandle.getUid(TEST_WORK_PROFILE_USER_ID, TEST_APP_ID); 485 private static final int TEST_APP_ID_2 = 104; 486 private static final int TEST_WORK_PROFILE_APP_UID_2 = 487 UserHandle.getUid(TEST_WORK_PROFILE_USER_ID, TEST_APP_ID_2); 488 private static final int TEST_APP_ID_3 = 105; 489 private static final int TEST_APP_ID_4 = 106; 490 private static final int TEST_APP_ID_5 = 107; 491 492 private static final String CLAT_PREFIX = "v4-"; 493 private static final String MOBILE_IFNAME = "test_rmnet_data0"; 494 private static final String CLAT_MOBILE_IFNAME = CLAT_PREFIX + MOBILE_IFNAME; 495 private static final String WIFI_IFNAME = "test_wlan0"; 496 private static final String WIFI_WOL_IFNAME = "test_wlan_wol"; 497 private static final String VPN_IFNAME = "tun10042"; 498 private static final String TEST_PACKAGE_NAME = "com.android.test.package"; 499 private static final int TEST_PACKAGE_UID = 123; 500 private static final int TEST_PACKAGE_UID2 = 321; 501 private static final int TEST_PACKAGE_UID3 = 456; 502 private static final String ALWAYS_ON_PACKAGE = "com.android.test.alwaysonvpn"; 503 504 private static final String INTERFACE_NAME = "interface"; 505 506 private static final String TEST_VENUE_URL_NA_PASSPOINT = "https://android.com/"; 507 private static final String TEST_VENUE_URL_NA_OTHER = "https://example.com/"; 508 private static final String TEST_TERMS_AND_CONDITIONS_URL_NA_PASSPOINT = 509 "https://android.com/terms/"; 510 private static final String TEST_TERMS_AND_CONDITIONS_URL_NA_OTHER = 511 "https://example.com/terms/"; 512 private static final String TEST_VENUE_URL_CAPPORT = "https://android.com/capport/"; 513 private static final String TEST_USER_PORTAL_API_URL_CAPPORT = 514 "https://android.com/user/api/capport/"; 515 private static final String TEST_FRIENDLY_NAME = "Network friendly name"; 516 private static final String TEST_REDIRECT_URL = "http://example.com/firstPath"; 517 518 private MockContext mServiceContext; 519 private HandlerThread mCsHandlerThread; 520 private HandlerThread mVMSHandlerThread; 521 private ConnectivityServiceDependencies mDeps; 522 private ConnectivityService mService; 523 private WrappedConnectivityManager mCm; 524 private TestNetworkAgentWrapper mWiFiNetworkAgent; 525 private TestNetworkAgentWrapper mCellNetworkAgent; 526 private TestNetworkAgentWrapper mEthernetNetworkAgent; 527 private MockVpn mMockVpn; 528 private Context mContext; 529 private NetworkPolicyCallback mPolicyCallback; 530 private WrappedMultinetworkPolicyTracker mPolicyTracker; 531 private ProxyTracker mProxyTracker; 532 private HandlerThread mAlarmManagerThread; 533 private TestNetIdManager mNetIdManager; 534 private QosCallbackMockHelper mQosCallbackMockHelper; 535 private QosCallbackTracker mQosCallbackTracker; 536 private VpnManagerService mVpnManagerService; 537 private TestNetworkCallback mDefaultNetworkCallback; 538 private TestNetworkCallback mSystemDefaultNetworkCallback; 539 private TestNetworkCallback mProfileDefaultNetworkCallback; 540 private TestNetworkCallback mTestPackageDefaultNetworkCallback; 541 private TestNetworkCallback mProfileDefaultNetworkCallbackAsAppUid2; 542 private TestNetworkCallback mTestPackageDefaultNetworkCallback2; 543 544 // State variables required to emulate NetworkPolicyManagerService behaviour. 545 private int mBlockedReasons = BLOCKED_REASON_NONE; 546 547 @Mock DeviceIdleInternal mDeviceIdleInternal; 548 @Mock INetworkManagementService mNetworkManagementService; 549 @Mock NetworkStatsManager mStatsManager; 550 @Mock IDnsResolver mMockDnsResolver; 551 @Mock INetd mMockNetd; 552 @Mock NetworkStackClientBase mNetworkStack; 553 @Mock PackageManager mPackageManager; 554 @Mock UserManager mUserManager; 555 @Mock NotificationManager mNotificationManager; 556 @Mock AlarmManager mAlarmManager; 557 @Mock IConnectivityDiagnosticsCallback mConnectivityDiagnosticsCallback; 558 @Mock IBinder mIBinder; 559 @Mock LocationManager mLocationManager; 560 @Mock AppOpsManager mAppOpsManager; 561 @Mock TelephonyManager mTelephonyManager; 562 @Mock EthernetManager mEthernetManager; 563 @Mock NetworkPolicyManager mNetworkPolicyManager; 564 @Mock VpnProfileStore mVpnProfileStore; 565 @Mock SystemConfigManager mSystemConfigManager; 566 @Mock DevicePolicyManager mDevicePolicyManager; 567 @Mock Resources mResources; 568 @Mock ClatCoordinator mClatCoordinator; 569 @Mock PacProxyManager mPacProxyManager; 570 @Mock BpfNetMaps mBpfNetMaps; 571 @Mock CarrierPrivilegeAuthenticator mCarrierPrivilegeAuthenticator; 572 @Mock TetheringManager mTetheringManager; 573 574 // BatteryStatsManager is final and cannot be mocked with regular mockito, so just mock the 575 // underlying binder calls. 576 final BatteryStatsManager mBatteryStatsManager = 577 new BatteryStatsManager(mock(IBatteryStats.class)); 578 579 private ArgumentCaptor<ResolverParamsParcel> mResolverParamsParcelCaptor = 580 ArgumentCaptor.forClass(ResolverParamsParcel.class); 581 582 // This class exists to test bindProcessToNetwork and getBoundNetworkForProcess. These methods 583 // do not go through ConnectivityService but talk to netd directly, so they don't automatically 584 // reflect the state of our test ConnectivityService. 585 private class WrappedConnectivityManager extends ConnectivityManager { 586 private Network mFakeBoundNetwork; 587 bindProcessToNetwork(Network network)588 public synchronized boolean bindProcessToNetwork(Network network) { 589 mFakeBoundNetwork = network; 590 return true; 591 } 592 getBoundNetworkForProcess()593 public synchronized Network getBoundNetworkForProcess() { 594 return mFakeBoundNetwork; 595 } 596 WrappedConnectivityManager(Context context, ConnectivityService service)597 public WrappedConnectivityManager(Context context, ConnectivityService service) { 598 super(context, service); 599 } 600 } 601 602 private class MockContext extends BroadcastInterceptingContext { 603 private final MockContentResolver mContentResolver; 604 605 @Spy private Resources mInternalResources; 606 private final LinkedBlockingQueue<Intent> mStartedActivities = new LinkedBlockingQueue<>(); 607 608 // Map of permission name -> PermissionManager.Permission_{GRANTED|DENIED} constant 609 // For permissions granted across the board, the key is only the permission name. 610 // For permissions only granted to a combination of uid/pid, the key 611 // is "<permission name>,<pid>,<uid>". PID+UID permissons have priority over generic ones. 612 private final HashMap<String, Integer> mMockedPermissions = new HashMap<>(); 613 mockStringResource(int resId)614 private void mockStringResource(int resId) { 615 doAnswer((inv) -> { 616 return "Mock string resource ID=" + inv.getArgument(0); 617 }).when(mInternalResources).getString(resId); 618 } 619 MockContext(Context base, ContentProvider settingsProvider)620 MockContext(Context base, ContentProvider settingsProvider) { 621 super(base); 622 623 mInternalResources = spy(base.getResources()); 624 doReturn(new String[] { 625 "wifi,1,1,1,-1,true", 626 "mobile,0,0,0,-1,true", 627 "mobile_mms,2,0,2,60000,true", 628 "mobile_supl,3,0,2,60000,true", 629 }).when(mInternalResources) 630 .getStringArray(com.android.internal.R.array.networkAttributes); 631 632 final int[] stringResourcesToMock = new int[] { 633 com.android.internal.R.string.config_customVpnAlwaysOnDisconnectedDialogComponent, 634 com.android.internal.R.string.vpn_lockdown_config, 635 com.android.internal.R.string.vpn_lockdown_connected, 636 com.android.internal.R.string.vpn_lockdown_connecting, 637 com.android.internal.R.string.vpn_lockdown_disconnected, 638 com.android.internal.R.string.vpn_lockdown_error, 639 }; 640 for (int resId : stringResourcesToMock) { 641 mockStringResource(resId); 642 } 643 644 mContentResolver = new MockContentResolver(); 645 mContentResolver.addProvider(Settings.AUTHORITY, settingsProvider); 646 } 647 648 @Override startActivityAsUser(Intent intent, UserHandle handle)649 public void startActivityAsUser(Intent intent, UserHandle handle) { 650 mStartedActivities.offer(intent); 651 } 652 expectStartActivityIntent(int timeoutMs)653 public Intent expectStartActivityIntent(int timeoutMs) { 654 Intent intent = null; 655 try { 656 intent = mStartedActivities.poll(timeoutMs, TimeUnit.MILLISECONDS); 657 } catch (InterruptedException e) {} 658 assertNotNull("Did not receive sign-in intent after " + timeoutMs + "ms", intent); 659 return intent; 660 } 661 expectNoStartActivityIntent(int timeoutMs)662 public void expectNoStartActivityIntent(int timeoutMs) { 663 try { 664 assertNull("Received unexpected Intent to start activity", 665 mStartedActivities.poll(timeoutMs, TimeUnit.MILLISECONDS)); 666 } catch (InterruptedException e) {} 667 } 668 669 @Override startService(Intent service)670 public ComponentName startService(Intent service) { 671 final String action = service.getAction(); 672 if (!VpnConfig.SERVICE_INTERFACE.equals(action) 673 && !ConstantsShim.ACTION_VPN_MANAGER_EVENT.equals(action)) { 674 fail("Attempt to start unknown service, action=" + action); 675 } 676 return new ComponentName(service.getPackage(), "com.android.test.Service"); 677 } 678 679 @Override getSystemService(String name)680 public Object getSystemService(String name) { 681 if (Context.CONNECTIVITY_SERVICE.equals(name)) return mCm; 682 if (Context.NOTIFICATION_SERVICE.equals(name)) return mNotificationManager; 683 if (Context.USER_SERVICE.equals(name)) return mUserManager; 684 if (Context.ALARM_SERVICE.equals(name)) return mAlarmManager; 685 if (Context.LOCATION_SERVICE.equals(name)) return mLocationManager; 686 if (Context.APP_OPS_SERVICE.equals(name)) return mAppOpsManager; 687 if (Context.TELEPHONY_SERVICE.equals(name)) return mTelephonyManager; 688 if (Context.ETHERNET_SERVICE.equals(name)) return mEthernetManager; 689 if (Context.NETWORK_POLICY_SERVICE.equals(name)) return mNetworkPolicyManager; 690 if (Context.DEVICE_POLICY_SERVICE.equals(name)) return mDevicePolicyManager; 691 if (Context.SYSTEM_CONFIG_SERVICE.equals(name)) return mSystemConfigManager; 692 if (Context.NETWORK_STATS_SERVICE.equals(name)) return mStatsManager; 693 if (Context.BATTERY_STATS_SERVICE.equals(name)) return mBatteryStatsManager; 694 if (Context.PAC_PROXY_SERVICE.equals(name)) return mPacProxyManager; 695 if (Context.TETHERING_SERVICE.equals(name)) return mTetheringManager; 696 return super.getSystemService(name); 697 } 698 699 final HashMap<UserHandle, UserManager> mUserManagers = new HashMap<>(); 700 @Override createContextAsUser(UserHandle user, int flags)701 public Context createContextAsUser(UserHandle user, int flags) { 702 final Context asUser = mock(Context.class, AdditionalAnswers.delegatesTo(this)); 703 doReturn(user).when(asUser).getUser(); 704 doAnswer((inv) -> { 705 final UserManager um = mUserManagers.computeIfAbsent(user, 706 u -> mock(UserManager.class, AdditionalAnswers.delegatesTo(mUserManager))); 707 return um; 708 }).when(asUser).getSystemService(Context.USER_SERVICE); 709 return asUser; 710 } 711 setWorkProfile(@onNull final UserHandle userHandle, boolean value)712 public void setWorkProfile(@NonNull final UserHandle userHandle, boolean value) { 713 // This relies on all contexts for a given user returning the same UM mock 714 final UserManager umMock = createContextAsUser(userHandle, 0 /* flags */) 715 .getSystemService(UserManager.class); 716 doReturn(value).when(umMock).isManagedProfile(); 717 doReturn(value).when(mUserManager).isManagedProfile(eq(userHandle.getIdentifier())); 718 } 719 setDeviceOwner(@onNull final UserHandle userHandle, String value)720 public void setDeviceOwner(@NonNull final UserHandle userHandle, String value) { 721 // This relies on all contexts for a given user returning the same UM mock 722 final DevicePolicyManager dpmMock = createContextAsUser(userHandle, 0 /* flags */) 723 .getSystemService(DevicePolicyManager.class); 724 doReturn(value).when(dpmMock).getDeviceOwner(); 725 doReturn(value).when(mDevicePolicyManager).getDeviceOwner(); 726 } 727 728 @Override getContentResolver()729 public ContentResolver getContentResolver() { 730 return mContentResolver; 731 } 732 733 @Override getResources()734 public Resources getResources() { 735 return mInternalResources; 736 } 737 738 @Override getPackageManager()739 public PackageManager getPackageManager() { 740 return mPackageManager; 741 } 742 checkMockedPermission(String permission, int pid, int uid, Supplier<Integer> ifAbsent)743 private int checkMockedPermission(String permission, int pid, int uid, 744 Supplier<Integer> ifAbsent) { 745 final Integer granted = mMockedPermissions.get(permission + "," + pid + "," + uid); 746 if (null != granted) { 747 return granted; 748 } 749 final Integer allGranted = mMockedPermissions.get(permission); 750 if (null != allGranted) { 751 return allGranted; 752 } 753 return ifAbsent.get(); 754 } 755 756 @Override checkPermission(String permission, int pid, int uid)757 public int checkPermission(String permission, int pid, int uid) { 758 return checkMockedPermission(permission, pid, uid, 759 () -> super.checkPermission(permission, pid, uid)); 760 } 761 762 @Override checkCallingOrSelfPermission(String permission)763 public int checkCallingOrSelfPermission(String permission) { 764 return checkMockedPermission(permission, Process.myPid(), Process.myUid(), 765 () -> super.checkCallingOrSelfPermission(permission)); 766 } 767 768 @Override enforceCallingOrSelfPermission(String permission, String message)769 public void enforceCallingOrSelfPermission(String permission, String message) { 770 final Integer granted = checkMockedPermission(permission, 771 Process.myPid(), Process.myUid(), 772 () -> { 773 super.enforceCallingOrSelfPermission(permission, message); 774 // enforce will crash if the permission is not granted 775 return PERMISSION_GRANTED; 776 }); 777 778 if (!granted.equals(PERMISSION_GRANTED)) { 779 throw new SecurityException("[Test] permission denied: " + permission); 780 } 781 } 782 783 /** 784 * Mock checks for the specified permission, and have them behave as per {@code granted}. 785 * 786 * This will apply across the board no matter what the checked UID and PID are. 787 * 788 * <p>Passing null reverts to default behavior, which does a real permission check on the 789 * test package. 790 * @param granted One of {@link PackageManager#PERMISSION_GRANTED} or 791 * {@link PackageManager#PERMISSION_DENIED}. 792 */ setPermission(String permission, Integer granted)793 public void setPermission(String permission, Integer granted) { 794 mMockedPermissions.put(permission, granted); 795 } 796 797 /** 798 * Mock checks for the specified permission, and have them behave as per {@code granted}. 799 * 800 * This will only apply to the passed UID and PID. 801 * 802 * <p>Passing null reverts to default behavior, which does a real permission check on the 803 * test package. 804 * @param granted One of {@link PackageManager#PERMISSION_GRANTED} or 805 * {@link PackageManager#PERMISSION_DENIED}. 806 */ setPermission(String permission, int pid, int uid, Integer granted)807 public void setPermission(String permission, int pid, int uid, Integer granted) { 808 final String key = permission + "," + pid + "," + uid; 809 mMockedPermissions.put(key, granted); 810 } 811 812 @Override registerReceiverForAllUsers(@ullable BroadcastReceiver receiver, @NonNull IntentFilter filter, @Nullable String broadcastPermission, @Nullable Handler scheduler)813 public Intent registerReceiverForAllUsers(@Nullable BroadcastReceiver receiver, 814 @NonNull IntentFilter filter, @Nullable String broadcastPermission, 815 @Nullable Handler scheduler) { 816 // TODO: ensure MultinetworkPolicyTracker's BroadcastReceiver is tested; just returning 817 // null should not pass the test 818 return null; 819 } 820 } 821 822 // This was only added in the T SDK, but this test needs to build against the R+S SDKs, too. toSdkSandboxUid(int appUid)823 private static int toSdkSandboxUid(int appUid) { 824 final int firstSdkSandboxUid = 20000; 825 return appUid + (firstSdkSandboxUid - Process.FIRST_APPLICATION_UID); 826 } 827 828 // This function assumes the UID range for user 0 ([1, 99999]) uidRangeParcelsExcludingUids(Integer... excludedUids)829 private static UidRangeParcel[] uidRangeParcelsExcludingUids(Integer... excludedUids) { 830 int start = 1; 831 Arrays.sort(excludedUids); 832 List<UidRangeParcel> parcels = new ArrayList<UidRangeParcel>(); 833 for (int excludedUid : excludedUids) { 834 if (excludedUid == start) { 835 start++; 836 } else { 837 parcels.add(new UidRangeParcel(start, excludedUid - 1)); 838 start = excludedUid + 1; 839 } 840 } 841 if (start <= 99999) { 842 parcels.add(new UidRangeParcel(start, 99999)); 843 } 844 845 return parcels.toArray(new UidRangeParcel[0]); 846 } 847 waitForIdle()848 private void waitForIdle() { 849 HandlerUtils.waitForIdle(mCsHandlerThread, TIMEOUT_MS); 850 waitForIdle(mCellNetworkAgent, TIMEOUT_MS); 851 waitForIdle(mWiFiNetworkAgent, TIMEOUT_MS); 852 waitForIdle(mEthernetNetworkAgent, TIMEOUT_MS); 853 HandlerUtils.waitForIdle(mCsHandlerThread, TIMEOUT_MS); 854 HandlerUtils.waitForIdle(ConnectivityThread.get(), TIMEOUT_MS); 855 } 856 waitForIdle(TestNetworkAgentWrapper agent, long timeoutMs)857 private void waitForIdle(TestNetworkAgentWrapper agent, long timeoutMs) { 858 if (agent == null) { 859 return; 860 } 861 agent.waitForIdle(timeoutMs); 862 } 863 864 @Test testWaitForIdle()865 public void testWaitForIdle() throws Exception { 866 final int attempts = 50; // Causes the test to take about 200ms on bullhead-eng. 867 868 // Tests that waitForIdle returns immediately if the service is already idle. 869 for (int i = 0; i < attempts; i++) { 870 waitForIdle(); 871 } 872 873 // Bring up a network that we can use to send messages to ConnectivityService. 874 ExpectedBroadcast b = expectConnectivityAction(TYPE_WIFI, DetailedState.CONNECTED); 875 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 876 mWiFiNetworkAgent.connect(false); 877 b.expectBroadcast(); 878 Network n = mWiFiNetworkAgent.getNetwork(); 879 assertNotNull(n); 880 881 // Tests that calling waitForIdle waits for messages to be processed. 882 for (int i = 0; i < attempts; i++) { 883 mWiFiNetworkAgent.setSignalStrength(i); 884 waitForIdle(); 885 assertEquals(i, mCm.getNetworkCapabilities(n).getSignalStrength()); 886 } 887 } 888 889 // This test has an inherent race condition in it, and cannot be enabled for continuous testing 890 // or presubmit tests. It is kept for manual runs and documentation purposes. 891 @Ignore verifyThatNotWaitingForIdleCausesRaceConditions()892 public void verifyThatNotWaitingForIdleCausesRaceConditions() throws Exception { 893 // Bring up a network that we can use to send messages to ConnectivityService. 894 ExpectedBroadcast b = expectConnectivityAction(TYPE_WIFI, DetailedState.CONNECTED); 895 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 896 mWiFiNetworkAgent.connect(false); 897 b.expectBroadcast(); 898 Network n = mWiFiNetworkAgent.getNetwork(); 899 assertNotNull(n); 900 901 // Ensure that not calling waitForIdle causes a race condition. 902 final int attempts = 50; // Causes the test to take about 200ms on bullhead-eng. 903 for (int i = 0; i < attempts; i++) { 904 mWiFiNetworkAgent.setSignalStrength(i); 905 if (i != mCm.getNetworkCapabilities(n).getSignalStrength()) { 906 // We hit a race condition, as expected. Pass the test. 907 return; 908 } 909 } 910 911 // No race? There is a bug in this test. 912 fail("expected race condition at least once in " + attempts + " attempts"); 913 } 914 915 private class TestNetworkAgentWrapper extends NetworkAgentWrapper { 916 private static final int VALIDATION_RESULT_INVALID = 0; 917 918 private static final long DATA_STALL_TIMESTAMP = 10L; 919 private static final int DATA_STALL_DETECTION_METHOD = 1; 920 921 private INetworkMonitor mNetworkMonitor; 922 private INetworkMonitorCallbacks mNmCallbacks; 923 private int mNmValidationResult = VALIDATION_RESULT_INVALID; 924 private int mProbesCompleted; 925 private int mProbesSucceeded; 926 private String mNmValidationRedirectUrl = null; 927 private boolean mNmProvNotificationRequested = false; 928 private Runnable mCreatedCallback; 929 private Runnable mUnwantedCallback; 930 private Runnable mDisconnectedCallback; 931 932 private final ConditionVariable mNetworkStatusReceived = new ConditionVariable(); 933 // Contains the redirectUrl from networkStatus(). Before reading, wait for 934 // mNetworkStatusReceived. 935 private String mRedirectUrl; 936 TestNetworkAgentWrapper(int transport)937 TestNetworkAgentWrapper(int transport) throws Exception { 938 this(transport, new LinkProperties(), null /* ncTemplate */, null /* provider */); 939 } 940 TestNetworkAgentWrapper(int transport, LinkProperties linkProperties)941 TestNetworkAgentWrapper(int transport, LinkProperties linkProperties) 942 throws Exception { 943 this(transport, linkProperties, null /* ncTemplate */, null /* provider */); 944 } 945 TestNetworkAgentWrapper(int transport, LinkProperties linkProperties, NetworkCapabilities ncTemplate)946 private TestNetworkAgentWrapper(int transport, LinkProperties linkProperties, 947 NetworkCapabilities ncTemplate) throws Exception { 948 this(transport, linkProperties, ncTemplate, null /* provider */); 949 } 950 TestNetworkAgentWrapper(int transport, LinkProperties linkProperties, NetworkCapabilities ncTemplate, NetworkProvider provider)951 private TestNetworkAgentWrapper(int transport, LinkProperties linkProperties, 952 NetworkCapabilities ncTemplate, NetworkProvider provider) throws Exception { 953 super(transport, linkProperties, ncTemplate, provider, mServiceContext); 954 955 // Waits for the NetworkAgent to be registered, which includes the creation of the 956 // NetworkMonitor. 957 waitForIdle(TIMEOUT_MS); 958 HandlerUtils.waitForIdle(mCsHandlerThread, TIMEOUT_MS); 959 HandlerUtils.waitForIdle(ConnectivityThread.get(), TIMEOUT_MS); 960 } 961 962 class TestInstrumentedNetworkAgent extends InstrumentedNetworkAgent { TestInstrumentedNetworkAgent(NetworkAgentWrapper wrapper, LinkProperties lp, NetworkAgentConfig nac, NetworkProvider provider)963 TestInstrumentedNetworkAgent(NetworkAgentWrapper wrapper, LinkProperties lp, 964 NetworkAgentConfig nac, NetworkProvider provider) { 965 super(wrapper, lp, nac, provider); 966 } 967 968 @Override networkStatus(int status, String redirectUrl)969 public void networkStatus(int status, String redirectUrl) { 970 mRedirectUrl = redirectUrl; 971 mNetworkStatusReceived.open(); 972 } 973 974 @Override onNetworkCreated()975 public void onNetworkCreated() { 976 super.onNetworkCreated(); 977 if (mCreatedCallback != null) mCreatedCallback.run(); 978 } 979 980 @Override onNetworkUnwanted()981 public void onNetworkUnwanted() { 982 super.onNetworkUnwanted(); 983 if (mUnwantedCallback != null) mUnwantedCallback.run(); 984 } 985 986 @Override onNetworkDestroyed()987 public void onNetworkDestroyed() { 988 super.onNetworkDestroyed(); 989 if (mDisconnectedCallback != null) mDisconnectedCallback.run(); 990 } 991 } 992 993 @Override makeNetworkAgent(LinkProperties linkProperties, NetworkAgentConfig nac, NetworkProvider provider)994 protected InstrumentedNetworkAgent makeNetworkAgent(LinkProperties linkProperties, 995 NetworkAgentConfig nac, NetworkProvider provider) throws Exception { 996 mNetworkMonitor = mock(INetworkMonitor.class); 997 998 final Answer validateAnswer = inv -> { 999 new Thread(ignoreExceptions(this::onValidationRequested)).start(); 1000 return null; 1001 }; 1002 1003 doAnswer(validateAnswer).when(mNetworkMonitor).notifyNetworkConnected(any(), any()); 1004 doAnswer(validateAnswer).when(mNetworkMonitor).notifyNetworkConnectedParcel(any()); 1005 doAnswer(validateAnswer).when(mNetworkMonitor).forceReevaluation(anyInt()); 1006 1007 final ArgumentCaptor<Network> nmNetworkCaptor = ArgumentCaptor.forClass(Network.class); 1008 final ArgumentCaptor<INetworkMonitorCallbacks> nmCbCaptor = 1009 ArgumentCaptor.forClass(INetworkMonitorCallbacks.class); 1010 doNothing().when(mNetworkStack).makeNetworkMonitor( 1011 nmNetworkCaptor.capture(), 1012 any() /* name */, 1013 nmCbCaptor.capture()); 1014 1015 final InstrumentedNetworkAgent na = 1016 new TestInstrumentedNetworkAgent(this, linkProperties, nac, provider); 1017 1018 assertEquals(na.getNetwork().netId, nmNetworkCaptor.getValue().netId); 1019 mNmCallbacks = nmCbCaptor.getValue(); 1020 1021 mNmCallbacks.onNetworkMonitorCreated(mNetworkMonitor); 1022 1023 return na; 1024 } 1025 onValidationRequested()1026 private void onValidationRequested() throws Exception { 1027 if (SdkLevel.isAtLeastT()) { 1028 verify(mNetworkMonitor).notifyNetworkConnectedParcel(any()); 1029 } else { 1030 verify(mNetworkMonitor).notifyNetworkConnected(any(), any()); 1031 } 1032 if (mNmProvNotificationRequested 1033 && ((mNmValidationResult & NETWORK_VALIDATION_RESULT_VALID) != 0)) { 1034 mNmCallbacks.hideProvisioningNotification(); 1035 mNmProvNotificationRequested = false; 1036 } 1037 1038 mNmCallbacks.notifyProbeStatusChanged(mProbesCompleted, mProbesSucceeded); 1039 final NetworkTestResultParcelable p = new NetworkTestResultParcelable(); 1040 p.result = mNmValidationResult; 1041 p.probesAttempted = mProbesCompleted; 1042 p.probesSucceeded = mProbesSucceeded; 1043 p.redirectUrl = mNmValidationRedirectUrl; 1044 p.timestampMillis = TIMESTAMP; 1045 mNmCallbacks.notifyNetworkTestedWithExtras(p); 1046 1047 if (mNmValidationRedirectUrl != null) { 1048 mNmCallbacks.showProvisioningNotification( 1049 "test_provisioning_notif_action", TEST_PACKAGE_NAME); 1050 mNmProvNotificationRequested = true; 1051 } 1052 } 1053 1054 /** 1055 * Connect without adding any internet capability. 1056 */ connectWithoutInternet()1057 public void connectWithoutInternet() { 1058 super.connect(); 1059 } 1060 1061 /** 1062 * Transition this NetworkAgent to CONNECTED state with NET_CAPABILITY_INTERNET. 1063 * @param validated Indicate if network should pretend to be validated. 1064 */ connect(boolean validated)1065 public void connect(boolean validated) { 1066 connect(validated, true, false /* isStrictMode */); 1067 } 1068 1069 /** 1070 * Transition this NetworkAgent to CONNECTED state. 1071 * @param validated Indicate if network should pretend to be validated. 1072 * @param hasInternet Indicate if network should pretend to have NET_CAPABILITY_INTERNET. 1073 */ connect(boolean validated, boolean hasInternet, boolean isStrictMode)1074 public void connect(boolean validated, boolean hasInternet, boolean isStrictMode) { 1075 ConnectivityManager.NetworkCallback callback = null; 1076 final ConditionVariable validatedCv = new ConditionVariable(); 1077 if (validated) { 1078 setNetworkValid(isStrictMode); 1079 NetworkRequest request = new NetworkRequest.Builder() 1080 .addTransportType(getNetworkCapabilities().getTransportTypes()[0]) 1081 .clearCapabilities() 1082 .build(); 1083 callback = new ConnectivityManager.NetworkCallback() { 1084 public void onCapabilitiesChanged(Network network, 1085 NetworkCapabilities networkCapabilities) { 1086 if (network.equals(getNetwork()) && 1087 networkCapabilities.hasCapability(NET_CAPABILITY_VALIDATED)) { 1088 validatedCv.open(); 1089 } 1090 } 1091 }; 1092 mCm.registerNetworkCallback(request, callback); 1093 } 1094 if (hasInternet) { 1095 addCapability(NET_CAPABILITY_INTERNET); 1096 } 1097 1098 connectWithoutInternet(); 1099 1100 if (validated) { 1101 // Wait for network to validate. 1102 waitFor(validatedCv); 1103 setNetworkInvalid(isStrictMode); 1104 } 1105 1106 if (callback != null) mCm.unregisterNetworkCallback(callback); 1107 } 1108 connectWithCaptivePortal(String redirectUrl, boolean isStrictMode)1109 public void connectWithCaptivePortal(String redirectUrl, boolean isStrictMode) { 1110 setNetworkPortal(redirectUrl, isStrictMode); 1111 connect(false, true /* hasInternet */, isStrictMode); 1112 } 1113 connectWithPartialConnectivity()1114 public void connectWithPartialConnectivity() { 1115 setNetworkPartial(); 1116 connect(false); 1117 } 1118 connectWithPartialValidConnectivity(boolean isStrictMode)1119 public void connectWithPartialValidConnectivity(boolean isStrictMode) { 1120 setNetworkPartialValid(isStrictMode); 1121 connect(false, true /* hasInternet */, isStrictMode); 1122 } 1123 setNetworkValid(boolean isStrictMode)1124 void setNetworkValid(boolean isStrictMode) { 1125 mNmValidationResult = NETWORK_VALIDATION_RESULT_VALID; 1126 mNmValidationRedirectUrl = null; 1127 int probesSucceeded = NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS; 1128 if (isStrictMode) { 1129 probesSucceeded |= NETWORK_VALIDATION_PROBE_PRIVDNS; 1130 } 1131 // The probesCompleted equals to probesSucceeded for the case of valid network, so put 1132 // the same value into two different parameter of the method. 1133 setProbesStatus(probesSucceeded, probesSucceeded); 1134 } 1135 setNetworkInvalid(boolean isStrictMode)1136 void setNetworkInvalid(boolean isStrictMode) { 1137 mNmValidationResult = VALIDATION_RESULT_INVALID; 1138 mNmValidationRedirectUrl = null; 1139 int probesCompleted = NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS 1140 | NETWORK_VALIDATION_PROBE_HTTP; 1141 int probesSucceeded = 0; 1142 // If the isStrictMode is true, it means the network is invalid when NetworkMonitor 1143 // tried to validate the private DNS but failed. 1144 if (isStrictMode) { 1145 probesCompleted &= ~NETWORK_VALIDATION_PROBE_HTTP; 1146 probesSucceeded = probesCompleted; 1147 probesCompleted |= NETWORK_VALIDATION_PROBE_PRIVDNS; 1148 } 1149 setProbesStatus(probesCompleted, probesSucceeded); 1150 } 1151 setNetworkPortal(String redirectUrl, boolean isStrictMode)1152 void setNetworkPortal(String redirectUrl, boolean isStrictMode) { 1153 setNetworkInvalid(isStrictMode); 1154 mNmValidationRedirectUrl = redirectUrl; 1155 // Suppose the portal is found when NetworkMonitor probes NETWORK_VALIDATION_PROBE_HTTP 1156 // in the beginning, so the NETWORK_VALIDATION_PROBE_HTTPS hasn't probed yet. 1157 int probesCompleted = NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTP; 1158 int probesSucceeded = VALIDATION_RESULT_INVALID; 1159 if (isStrictMode) { 1160 probesCompleted |= NETWORK_VALIDATION_PROBE_PRIVDNS; 1161 } 1162 setProbesStatus(probesCompleted, probesSucceeded); 1163 } 1164 setNetworkPartial()1165 void setNetworkPartial() { 1166 mNmValidationResult = NETWORK_VALIDATION_RESULT_PARTIAL; 1167 mNmValidationRedirectUrl = null; 1168 int probesCompleted = NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS 1169 | NETWORK_VALIDATION_PROBE_FALLBACK; 1170 int probesSucceeded = NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_FALLBACK; 1171 setProbesStatus(probesCompleted, probesSucceeded); 1172 } 1173 setNetworkPartialValid(boolean isStrictMode)1174 void setNetworkPartialValid(boolean isStrictMode) { 1175 setNetworkPartial(); 1176 mNmValidationResult |= NETWORK_VALIDATION_RESULT_VALID; 1177 int probesCompleted = NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS 1178 | NETWORK_VALIDATION_PROBE_HTTP; 1179 int probesSucceeded = NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTP; 1180 // Suppose the partial network cannot pass the private DNS validation as well, so only 1181 // add NETWORK_VALIDATION_PROBE_DNS in probesCompleted but not probesSucceeded. 1182 if (isStrictMode) { 1183 probesCompleted |= NETWORK_VALIDATION_PROBE_PRIVDNS; 1184 } 1185 setProbesStatus(probesCompleted, probesSucceeded); 1186 } 1187 setProbesStatus(int probesCompleted, int probesSucceeded)1188 void setProbesStatus(int probesCompleted, int probesSucceeded) { 1189 mProbesCompleted = probesCompleted; 1190 mProbesSucceeded = probesSucceeded; 1191 } 1192 notifyCapportApiDataChanged(CaptivePortalData data)1193 void notifyCapportApiDataChanged(CaptivePortalData data) { 1194 try { 1195 mNmCallbacks.notifyCaptivePortalDataChanged(data); 1196 } catch (RemoteException e) { 1197 throw new AssertionError("This cannot happen", e); 1198 } 1199 } 1200 waitForRedirectUrl()1201 public String waitForRedirectUrl() { 1202 assertTrue(mNetworkStatusReceived.block(TIMEOUT_MS)); 1203 return mRedirectUrl; 1204 } 1205 expectDisconnected()1206 public void expectDisconnected() { 1207 expectDisconnected(TIMEOUT_MS); 1208 } 1209 expectPreventReconnectReceived()1210 public void expectPreventReconnectReceived() { 1211 expectPreventReconnectReceived(TIMEOUT_MS); 1212 } 1213 notifyDataStallSuspected()1214 void notifyDataStallSuspected() throws Exception { 1215 final DataStallReportParcelable p = new DataStallReportParcelable(); 1216 p.detectionMethod = DATA_STALL_DETECTION_METHOD; 1217 p.timestampMillis = DATA_STALL_TIMESTAMP; 1218 mNmCallbacks.notifyDataStallSuspected(p); 1219 } 1220 setCreatedCallback(Runnable r)1221 public void setCreatedCallback(Runnable r) { 1222 mCreatedCallback = r; 1223 } 1224 setUnwantedCallback(Runnable r)1225 public void setUnwantedCallback(Runnable r) { 1226 mUnwantedCallback = r; 1227 } 1228 setDisconnectedCallback(Runnable r)1229 public void setDisconnectedCallback(Runnable r) { 1230 mDisconnectedCallback = r; 1231 } 1232 } 1233 1234 /** 1235 * A NetworkFactory that allows to wait until any in-flight NetworkRequest add or remove 1236 * operations have been processed and test for them. 1237 */ 1238 private static class MockNetworkFactory extends NetworkFactory { 1239 private final AtomicBoolean mNetworkStarted = new AtomicBoolean(false); 1240 1241 static class RequestEntry { 1242 @NonNull 1243 public final NetworkRequest request; 1244 RequestEntry(@onNull final NetworkRequest request)1245 RequestEntry(@NonNull final NetworkRequest request) { 1246 this.request = request; 1247 } 1248 1249 static final class Add extends RequestEntry { Add(@onNull final NetworkRequest request)1250 Add(@NonNull final NetworkRequest request) { 1251 super(request); 1252 } 1253 } 1254 1255 static final class Remove extends RequestEntry { Remove(@onNull final NetworkRequest request)1256 Remove(@NonNull final NetworkRequest request) { 1257 super(request); 1258 } 1259 } 1260 1261 @Override toString()1262 public String toString() { 1263 return "RequestEntry [ " + getClass().getName() + " : " + request + " ]"; 1264 } 1265 } 1266 1267 // History of received requests adds and removes. 1268 private final ArrayTrackRecord<RequestEntry>.ReadHead mRequestHistory = 1269 new ArrayTrackRecord<RequestEntry>().newReadHead(); 1270 failIfNull(@ullable final T obj, @Nullable final String message)1271 private static <T> T failIfNull(@Nullable final T obj, @Nullable final String message) { 1272 if (null == obj) fail(null != message ? message : "Must not be null"); 1273 return obj; 1274 } 1275 expectRequestAdd()1276 public RequestEntry.Add expectRequestAdd() { 1277 return failIfNull((RequestEntry.Add) mRequestHistory.poll(TIMEOUT_MS, 1278 it -> it instanceof RequestEntry.Add), "Expected request add"); 1279 } 1280 expectRequestAdds(final int count)1281 public void expectRequestAdds(final int count) { 1282 for (int i = count; i > 0; --i) { 1283 expectRequestAdd(); 1284 } 1285 } 1286 expectRequestRemove()1287 public RequestEntry.Remove expectRequestRemove() { 1288 return failIfNull((RequestEntry.Remove) mRequestHistory.poll(TIMEOUT_MS, 1289 it -> it instanceof RequestEntry.Remove), "Expected request remove"); 1290 } 1291 expectRequestRemoves(final int count)1292 public void expectRequestRemoves(final int count) { 1293 for (int i = count; i > 0; --i) { 1294 expectRequestRemove(); 1295 } 1296 } 1297 1298 // Used to collect the networks requests managed by this factory. This is a duplicate of 1299 // the internal information stored in the NetworkFactory (which is private). 1300 private SparseArray<NetworkRequest> mNetworkRequests = new SparseArray<>(); 1301 private final HandlerThread mHandlerSendingRequests; 1302 MockNetworkFactory(Looper looper, Context context, String logTag, NetworkCapabilities filter, HandlerThread threadSendingRequests)1303 public MockNetworkFactory(Looper looper, Context context, String logTag, 1304 NetworkCapabilities filter, HandlerThread threadSendingRequests) { 1305 super(looper, context, logTag, filter); 1306 mHandlerSendingRequests = threadSendingRequests; 1307 } 1308 getMyRequestCount()1309 public int getMyRequestCount() { 1310 return getRequestCount(); 1311 } 1312 startNetwork()1313 protected void startNetwork() { 1314 mNetworkStarted.set(true); 1315 } 1316 stopNetwork()1317 protected void stopNetwork() { 1318 mNetworkStarted.set(false); 1319 } 1320 getMyStartRequested()1321 public boolean getMyStartRequested() { 1322 return mNetworkStarted.get(); 1323 } 1324 1325 1326 @Override needNetworkFor(NetworkRequest request)1327 protected void needNetworkFor(NetworkRequest request) { 1328 mNetworkRequests.put(request.requestId, request); 1329 super.needNetworkFor(request); 1330 mRequestHistory.add(new RequestEntry.Add(request)); 1331 } 1332 1333 @Override releaseNetworkFor(NetworkRequest request)1334 protected void releaseNetworkFor(NetworkRequest request) { 1335 mNetworkRequests.remove(request.requestId); 1336 super.releaseNetworkFor(request); 1337 mRequestHistory.add(new RequestEntry.Remove(request)); 1338 } 1339 assertRequestCountEquals(final int count)1340 public void assertRequestCountEquals(final int count) { 1341 assertEquals(count, getMyRequestCount()); 1342 } 1343 1344 // Trigger releasing the request as unfulfillable triggerUnfulfillable(NetworkRequest r)1345 public void triggerUnfulfillable(NetworkRequest r) { 1346 super.releaseRequestAsUnfulfillableByAnyFactory(r); 1347 } 1348 assertNoRequestChanged()1349 public void assertNoRequestChanged() { 1350 // Make sure there are no remaining requests unaccounted for. 1351 HandlerUtils.waitForIdle(mHandlerSendingRequests, TIMEOUT_MS); 1352 assertNull(mRequestHistory.poll(0, r -> true)); 1353 } 1354 } 1355 uidRangesForUids(int... uids)1356 private Set<UidRange> uidRangesForUids(int... uids) { 1357 final ArraySet<UidRange> ranges = new ArraySet<>(); 1358 for (final int uid : uids) { 1359 ranges.add(new UidRange(uid, uid)); 1360 } 1361 return ranges; 1362 } 1363 uidRangesForUids(Collection<Integer> uids)1364 private Set<UidRange> uidRangesForUids(Collection<Integer> uids) { 1365 return uidRangesForUids(CollectionUtils.toIntArray(uids)); 1366 } 1367 startHandlerThreadAndReturnLooper()1368 private static Looper startHandlerThreadAndReturnLooper() { 1369 final HandlerThread handlerThread = new HandlerThread("MockVpnThread"); 1370 handlerThread.start(); 1371 return handlerThread.getLooper(); 1372 } 1373 1374 private class MockVpn extends Vpn implements TestableNetworkCallback.HasNetwork { 1375 // Careful ! This is different from mNetworkAgent, because MockNetworkAgent does 1376 // not inherit from NetworkAgent. 1377 private TestNetworkAgentWrapper mMockNetworkAgent; 1378 private boolean mAgentRegistered = false; 1379 1380 private int mVpnType = VpnManager.TYPE_VPN_SERVICE; 1381 private UnderlyingNetworkInfo mUnderlyingNetworkInfo; 1382 1383 // These ConditionVariables allow tests to wait for LegacyVpnRunner to be stopped/started. 1384 // TODO: this scheme is ad-hoc and error-prone because it does not fail if, for example, the 1385 // test expects two starts in a row, or even if the production code calls start twice in a 1386 // row. find a better solution. Simply putting a method to create a LegacyVpnRunner into 1387 // Vpn.Dependencies doesn't work because LegacyVpnRunner is not a static class and has 1388 // extensive access into the internals of Vpn. 1389 private ConditionVariable mStartLegacyVpnCv = new ConditionVariable(); 1390 private ConditionVariable mStopVpnRunnerCv = new ConditionVariable(); 1391 MockVpn(int userId)1392 public MockVpn(int userId) { 1393 super(startHandlerThreadAndReturnLooper(), mServiceContext, 1394 new Dependencies() { 1395 @Override 1396 public boolean isCallerSystem() { 1397 return true; 1398 } 1399 1400 @Override 1401 public DeviceIdleInternal getDeviceIdleInternal() { 1402 return mDeviceIdleInternal; 1403 } 1404 }, 1405 mNetworkManagementService, mMockNetd, userId, mVpnProfileStore, 1406 new SystemServices(mServiceContext) { 1407 @Override 1408 public String settingsSecureGetStringForUser(String key, int userId) { 1409 switch (key) { 1410 // Settings keys not marked as @Readable are not readable from 1411 // non-privileged apps, unless marked as testOnly=true 1412 // (atest refuses to install testOnly=true apps), even if mocked 1413 // in the content provider, because 1414 // Settings.Secure.NameValueCache#getStringForUser checks the key 1415 // before querying the mock settings provider. 1416 case Settings.Secure.ALWAYS_ON_VPN_APP: 1417 return null; 1418 default: 1419 return super.settingsSecureGetStringForUser(key, userId); 1420 } 1421 } 1422 }, new Ikev2SessionCreator()); 1423 } 1424 setUids(Set<UidRange> uids)1425 public void setUids(Set<UidRange> uids) { 1426 mNetworkCapabilities.setUids(UidRange.toIntRanges(uids)); 1427 if (mAgentRegistered) { 1428 mMockNetworkAgent.setNetworkCapabilities(mNetworkCapabilities, true); 1429 } 1430 } 1431 setVpnType(int vpnType)1432 public void setVpnType(int vpnType) { 1433 mVpnType = vpnType; 1434 } 1435 1436 @Override getNetwork()1437 public Network getNetwork() { 1438 return (mMockNetworkAgent == null) ? null : mMockNetworkAgent.getNetwork(); 1439 } 1440 getNetworkAgentConfig()1441 public NetworkAgentConfig getNetworkAgentConfig() { 1442 return null == mMockNetworkAgent ? null : mMockNetworkAgent.getNetworkAgentConfig(); 1443 } 1444 1445 @Override getActiveVpnType()1446 public int getActiveVpnType() { 1447 return mVpnType; 1448 } 1449 makeLinkProperties()1450 private LinkProperties makeLinkProperties() { 1451 final LinkProperties lp = new LinkProperties(); 1452 lp.setInterfaceName(VPN_IFNAME); 1453 return lp; 1454 } 1455 registerAgent(boolean isAlwaysMetered, Set<UidRange> uids, LinkProperties lp)1456 private void registerAgent(boolean isAlwaysMetered, Set<UidRange> uids, LinkProperties lp) 1457 throws Exception { 1458 if (mAgentRegistered) throw new IllegalStateException("already registered"); 1459 updateState(NetworkInfo.DetailedState.CONNECTING, "registerAgent"); 1460 mConfig = new VpnConfig(); 1461 mConfig.session = "MySession12345"; 1462 setUids(uids); 1463 if (!isAlwaysMetered) mNetworkCapabilities.addCapability(NET_CAPABILITY_NOT_METERED); 1464 mInterface = VPN_IFNAME; 1465 mNetworkCapabilities.setTransportInfo(new VpnTransportInfo(getActiveVpnType(), 1466 mConfig.session)); 1467 mMockNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_VPN, lp, 1468 mNetworkCapabilities); 1469 mMockNetworkAgent.waitForIdle(TIMEOUT_MS); 1470 1471 verify(mMockNetd, times(1)).networkAddUidRangesParcel( 1472 new NativeUidRangeConfig(mMockVpn.getNetwork().getNetId(), 1473 toUidRangeStableParcels(uids), PREFERENCE_ORDER_VPN)); 1474 verify(mMockNetd, never()).networkRemoveUidRangesParcel(argThat(config -> 1475 mMockVpn.getNetwork().getNetId() == config.netId 1476 && PREFERENCE_ORDER_VPN == config.subPriority)); 1477 mAgentRegistered = true; 1478 verify(mMockNetd).networkCreate(nativeNetworkConfigVpn(getNetwork().netId, 1479 !mMockNetworkAgent.isBypassableVpn(), mVpnType)); 1480 updateState(NetworkInfo.DetailedState.CONNECTED, "registerAgent"); 1481 mNetworkCapabilities.set(mMockNetworkAgent.getNetworkCapabilities()); 1482 mNetworkAgent = mMockNetworkAgent.getNetworkAgent(); 1483 } 1484 registerAgent(Set<UidRange> uids)1485 private void registerAgent(Set<UidRange> uids) throws Exception { 1486 registerAgent(false /* isAlwaysMetered */, uids, makeLinkProperties()); 1487 } 1488 connect(boolean validated, boolean hasInternet, boolean isStrictMode)1489 private void connect(boolean validated, boolean hasInternet, boolean isStrictMode) { 1490 mMockNetworkAgent.connect(validated, hasInternet, isStrictMode); 1491 } 1492 connect(boolean validated)1493 private void connect(boolean validated) { 1494 mMockNetworkAgent.connect(validated); 1495 } 1496 getAgent()1497 private TestNetworkAgentWrapper getAgent() { 1498 return mMockNetworkAgent; 1499 } 1500 setOwnerAndAdminUid(int uid)1501 private void setOwnerAndAdminUid(int uid) throws Exception { 1502 mNetworkCapabilities.setOwnerUid(uid); 1503 mNetworkCapabilities.setAdministratorUids(new int[]{uid}); 1504 } 1505 establish(LinkProperties lp, int uid, Set<UidRange> ranges, boolean validated, boolean hasInternet, boolean isStrictMode)1506 public void establish(LinkProperties lp, int uid, Set<UidRange> ranges, boolean validated, 1507 boolean hasInternet, boolean isStrictMode) throws Exception { 1508 setOwnerAndAdminUid(uid); 1509 registerAgent(false, ranges, lp); 1510 connect(validated, hasInternet, isStrictMode); 1511 waitForIdle(); 1512 } 1513 establish(LinkProperties lp, int uid, Set<UidRange> ranges)1514 public void establish(LinkProperties lp, int uid, Set<UidRange> ranges) throws Exception { 1515 establish(lp, uid, ranges, true, true, false); 1516 } 1517 establishForMyUid(LinkProperties lp)1518 public void establishForMyUid(LinkProperties lp) throws Exception { 1519 final int uid = Process.myUid(); 1520 establish(lp, uid, uidRangesForUids(uid), true, true, false); 1521 } 1522 establishForMyUid(boolean validated, boolean hasInternet, boolean isStrictMode)1523 public void establishForMyUid(boolean validated, boolean hasInternet, boolean isStrictMode) 1524 throws Exception { 1525 final int uid = Process.myUid(); 1526 establish(makeLinkProperties(), uid, uidRangesForUids(uid), validated, hasInternet, 1527 isStrictMode); 1528 } 1529 establishForMyUid()1530 public void establishForMyUid() throws Exception { 1531 establishForMyUid(makeLinkProperties()); 1532 } 1533 sendLinkProperties(LinkProperties lp)1534 public void sendLinkProperties(LinkProperties lp) { 1535 mMockNetworkAgent.sendLinkProperties(lp); 1536 } 1537 disconnect()1538 public void disconnect() { 1539 if (mMockNetworkAgent != null) { 1540 mMockNetworkAgent.disconnect(); 1541 updateState(NetworkInfo.DetailedState.DISCONNECTED, "disconnect"); 1542 } 1543 mAgentRegistered = false; 1544 setUids(null); 1545 // Remove NET_CAPABILITY_INTERNET or MockNetworkAgent will refuse to connect later on. 1546 mNetworkCapabilities.removeCapability(NET_CAPABILITY_INTERNET); 1547 mInterface = null; 1548 } 1549 1550 @Override startLegacyVpnRunner()1551 public void startLegacyVpnRunner() { 1552 mStartLegacyVpnCv.open(); 1553 } 1554 expectStartLegacyVpnRunner()1555 public void expectStartLegacyVpnRunner() { 1556 assertTrue("startLegacyVpnRunner not called after " + TIMEOUT_MS + " ms", 1557 mStartLegacyVpnCv.block(TIMEOUT_MS)); 1558 1559 // startLegacyVpn calls stopVpnRunnerPrivileged, which will open mStopVpnRunnerCv, just 1560 // before calling startLegacyVpnRunner. Restore mStopVpnRunnerCv, so the test can expect 1561 // that the VpnRunner is stopped and immediately restarted by calling 1562 // expectStartLegacyVpnRunner() and expectStopVpnRunnerPrivileged() back-to-back. 1563 mStopVpnRunnerCv = new ConditionVariable(); 1564 } 1565 1566 @Override stopVpnRunnerPrivileged()1567 public void stopVpnRunnerPrivileged() { 1568 if (mVpnRunner != null) { 1569 super.stopVpnRunnerPrivileged(); 1570 disconnect(); 1571 mStartLegacyVpnCv = new ConditionVariable(); 1572 } 1573 mVpnRunner = null; 1574 mStopVpnRunnerCv.open(); 1575 } 1576 expectStopVpnRunnerPrivileged()1577 public void expectStopVpnRunnerPrivileged() { 1578 assertTrue("stopVpnRunnerPrivileged not called after " + TIMEOUT_MS + " ms", 1579 mStopVpnRunnerCv.block(TIMEOUT_MS)); 1580 } 1581 1582 @Override getUnderlyingNetworkInfo()1583 public synchronized UnderlyingNetworkInfo getUnderlyingNetworkInfo() { 1584 if (mUnderlyingNetworkInfo != null) return mUnderlyingNetworkInfo; 1585 1586 return super.getUnderlyingNetworkInfo(); 1587 } 1588 setUnderlyingNetworkInfo( UnderlyingNetworkInfo underlyingNetworkInfo)1589 private synchronized void setUnderlyingNetworkInfo( 1590 UnderlyingNetworkInfo underlyingNetworkInfo) { 1591 mUnderlyingNetworkInfo = underlyingNetworkInfo; 1592 } 1593 } 1594 toUidRangeStableParcels(final @NonNull Set<UidRange> ranges)1595 private UidRangeParcel[] toUidRangeStableParcels(final @NonNull Set<UidRange> ranges) { 1596 return ranges.stream().map( 1597 r -> new UidRangeParcel(r.start, r.stop)).toArray(UidRangeParcel[]::new); 1598 } 1599 intToUidRangeStableParcels(final @NonNull Set<Integer> ranges)1600 private UidRangeParcel[] intToUidRangeStableParcels(final @NonNull Set<Integer> ranges) { 1601 return ranges.stream().map(r -> new UidRangeParcel(r, r)).toArray(UidRangeParcel[]::new); 1602 } 1603 makeVpnManagerService()1604 private VpnManagerService makeVpnManagerService() { 1605 final VpnManagerService.Dependencies deps = new VpnManagerService.Dependencies() { 1606 public int getCallingUid() { 1607 return mDeps.getCallingUid(); 1608 } 1609 1610 public HandlerThread makeHandlerThread() { 1611 return mVMSHandlerThread; 1612 } 1613 1614 @Override 1615 public VpnProfileStore getVpnProfileStore() { 1616 return mVpnProfileStore; 1617 } 1618 1619 public INetd getNetd() { 1620 return mMockNetd; 1621 } 1622 1623 public INetworkManagementService getINetworkManagementService() { 1624 return mNetworkManagementService; 1625 } 1626 }; 1627 return new VpnManagerService(mServiceContext, deps); 1628 } 1629 assertVpnTransportInfo(NetworkCapabilities nc, int type)1630 private void assertVpnTransportInfo(NetworkCapabilities nc, int type) { 1631 assertNotNull(nc); 1632 final TransportInfo ti = nc.getTransportInfo(); 1633 assertTrue("VPN TransportInfo is not a VpnTransportInfo: " + ti, 1634 ti instanceof VpnTransportInfo); 1635 assertEquals(type, ((VpnTransportInfo) ti).getType()); 1636 1637 } 1638 processBroadcast(Intent intent)1639 private void processBroadcast(Intent intent) { 1640 mServiceContext.sendBroadcast(intent); 1641 HandlerUtils.waitForIdle(mVMSHandlerThread, TIMEOUT_MS); 1642 waitForIdle(); 1643 } 1644 mockVpn(int uid)1645 private void mockVpn(int uid) { 1646 synchronized (mVpnManagerService.mVpns) { 1647 int userId = UserHandle.getUserId(uid); 1648 mMockVpn = new MockVpn(userId); 1649 // Every running user always has a Vpn in the mVpns array, even if no VPN is running. 1650 mVpnManagerService.mVpns.put(userId, mMockVpn); 1651 } 1652 } 1653 mockUidNetworkingBlocked()1654 private void mockUidNetworkingBlocked() { 1655 doAnswer(i -> isUidBlocked(mBlockedReasons, i.getArgument(1)) 1656 ).when(mNetworkPolicyManager).isUidNetworkingBlocked(anyInt(), anyBoolean()); 1657 } 1658 isUidBlocked(int blockedReasons, boolean meteredNetwork)1659 private boolean isUidBlocked(int blockedReasons, boolean meteredNetwork) { 1660 final int blockedOnAllNetworksReason = (blockedReasons & ~BLOCKED_METERED_REASON_MASK); 1661 if (blockedOnAllNetworksReason != BLOCKED_REASON_NONE) { 1662 return true; 1663 } 1664 if (meteredNetwork) { 1665 return blockedReasons != BLOCKED_REASON_NONE; 1666 } 1667 return false; 1668 } 1669 setBlockedReasonChanged(int blockedReasons)1670 private void setBlockedReasonChanged(int blockedReasons) { 1671 mBlockedReasons = blockedReasons; 1672 mPolicyCallback.onUidBlockedReasonChanged(Process.myUid(), blockedReasons); 1673 } 1674 getNat464Xlat(NetworkAgentWrapper mna)1675 private Nat464Xlat getNat464Xlat(NetworkAgentWrapper mna) { 1676 return mService.getNetworkAgentInfoForNetwork(mna.getNetwork()).clatd; 1677 } 1678 1679 private class WrappedMultinetworkPolicyTracker extends MultinetworkPolicyTracker { 1680 volatile int mConfigMeteredMultipathPreference; 1681 WrappedMultinetworkPolicyTracker(Context c, Handler h, Runnable r)1682 WrappedMultinetworkPolicyTracker(Context c, Handler h, Runnable r) { 1683 super(c, h, r); 1684 } 1685 1686 @Override getResourcesForActiveSubId()1687 protected Resources getResourcesForActiveSubId() { 1688 return mResources; 1689 } 1690 1691 @Override configMeteredMultipathPreference()1692 public int configMeteredMultipathPreference() { 1693 return mConfigMeteredMultipathPreference; 1694 } 1695 } 1696 1697 /** 1698 * Wait up to TIMEOUT_MS for {@code conditionVariable} to open. 1699 * Fails if TIMEOUT_MS goes by before {@code conditionVariable} opens. 1700 */ waitFor(ConditionVariable conditionVariable)1701 static private void waitFor(ConditionVariable conditionVariable) { 1702 if (conditionVariable.block(TIMEOUT_MS)) { 1703 return; 1704 } 1705 fail("ConditionVariable was blocked for more than " + TIMEOUT_MS + "ms"); 1706 } 1707 doAsUid(final int uid, @NonNull final Supplier<T> what)1708 private <T> T doAsUid(final int uid, @NonNull final Supplier<T> what) { 1709 mDeps.setCallingUid(uid); 1710 try { 1711 return what.get(); 1712 } finally { 1713 mDeps.setCallingUid(null); 1714 } 1715 } 1716 doAsUid(final int uid, @NonNull final Runnable what)1717 private void doAsUid(final int uid, @NonNull final Runnable what) { 1718 doAsUid(uid, () -> { 1719 what.run(); return Void.TYPE; 1720 }); 1721 } 1722 registerNetworkCallbackAsUid(NetworkRequest request, NetworkCallback callback, int uid)1723 private void registerNetworkCallbackAsUid(NetworkRequest request, NetworkCallback callback, 1724 int uid) { 1725 doAsUid(uid, () -> { 1726 mCm.registerNetworkCallback(request, callback); 1727 }); 1728 } 1729 registerDefaultNetworkCallbackAsUid(@onNull final NetworkCallback callback, final int uid)1730 private void registerDefaultNetworkCallbackAsUid(@NonNull final NetworkCallback callback, 1731 final int uid) { 1732 doAsUid(uid, () -> { 1733 mCm.registerDefaultNetworkCallback(callback); 1734 waitForIdle(); 1735 }); 1736 } 1737 1738 private interface ExceptionalRunnable { run()1739 void run() throws Exception; 1740 } 1741 withPermission(String permission, ExceptionalRunnable r)1742 private void withPermission(String permission, ExceptionalRunnable r) throws Exception { 1743 try { 1744 mServiceContext.setPermission(permission, PERMISSION_GRANTED); 1745 r.run(); 1746 } finally { 1747 mServiceContext.setPermission(permission, null); 1748 } 1749 } 1750 withPermission(String permission, int pid, int uid, ExceptionalRunnable r)1751 private void withPermission(String permission, int pid, int uid, ExceptionalRunnable r) 1752 throws Exception { 1753 try { 1754 mServiceContext.setPermission(permission, pid, uid, PERMISSION_GRANTED); 1755 r.run(); 1756 } finally { 1757 mServiceContext.setPermission(permission, pid, uid, null); 1758 } 1759 } 1760 1761 private static final int PRIMARY_USER = 0; 1762 private static final int SECONDARY_USER = 10; 1763 private static final int TERTIARY_USER = 11; 1764 private static final UidRange PRIMARY_UIDRANGE = 1765 UidRange.createForUser(UserHandle.of(PRIMARY_USER)); 1766 private static final int APP1_UID = UserHandle.getUid(PRIMARY_USER, 10100); 1767 private static final int APP2_UID = UserHandle.getUid(PRIMARY_USER, 10101); 1768 private static final int VPN_UID = UserHandle.getUid(PRIMARY_USER, 10043); 1769 private static final UserInfo PRIMARY_USER_INFO = new UserInfo(PRIMARY_USER, "", 1770 UserInfo.FLAG_PRIMARY); 1771 private static final UserHandle PRIMARY_USER_HANDLE = new UserHandle(PRIMARY_USER); 1772 private static final UserHandle SECONDARY_USER_HANDLE = new UserHandle(SECONDARY_USER); 1773 private static final UserHandle TERTIARY_USER_HANDLE = new UserHandle(TERTIARY_USER); 1774 1775 private static final int RESTRICTED_USER = 1; 1776 private static final UserInfo RESTRICTED_USER_INFO = new UserInfo(RESTRICTED_USER, "", 1777 UserInfo.FLAG_RESTRICTED); 1778 static { 1779 RESTRICTED_USER_INFO.restrictedProfileParentId = PRIMARY_USER; 1780 } 1781 1782 @Before setUp()1783 public void setUp() throws Exception { 1784 mNetIdManager = new TestNetIdManager(); 1785 1786 mContext = InstrumentationRegistry.getContext(); 1787 1788 MockitoAnnotations.initMocks(this); 1789 1790 doReturn(asList(PRIMARY_USER_INFO)).when(mUserManager).getAliveUsers(); 1791 doReturn(asList(PRIMARY_USER_HANDLE)).when(mUserManager).getUserHandles(anyBoolean()); 1792 doReturn(PRIMARY_USER_INFO).when(mUserManager).getUserInfo(PRIMARY_USER); 1793 // canHaveRestrictedProfile does not take a userId. It applies to the userId of the context 1794 // it was started from, i.e., PRIMARY_USER. 1795 doReturn(true).when(mUserManager).canHaveRestrictedProfile(); 1796 doReturn(RESTRICTED_USER_INFO).when(mUserManager).getUserInfo(RESTRICTED_USER); 1797 1798 final ApplicationInfo applicationInfo = new ApplicationInfo(); 1799 applicationInfo.targetSdkVersion = Build.VERSION_CODES.Q; 1800 doReturn(applicationInfo).when(mPackageManager) 1801 .getApplicationInfoAsUser(anyString(), anyInt(), any()); 1802 doReturn(applicationInfo.targetSdkVersion).when(mPackageManager) 1803 .getTargetSdkVersion(anyString()); 1804 doReturn(new int[0]).when(mSystemConfigManager).getSystemPermissionUids(anyString()); 1805 1806 // InstrumentationTestRunner prepares a looper, but AndroidJUnitRunner does not. 1807 // http://b/25897652 . 1808 if (Looper.myLooper() == null) { 1809 Looper.prepare(); 1810 } 1811 mockDefaultPackages(); 1812 mockHasSystemFeature(FEATURE_WIFI, true); 1813 mockHasSystemFeature(FEATURE_WIFI_DIRECT, true); 1814 mockHasSystemFeature(FEATURE_ETHERNET, true); 1815 doReturn(true).when(mTelephonyManager).isDataCapable(); 1816 1817 FakeSettingsProvider.clearSettingsProvider(); 1818 mServiceContext = new MockContext(InstrumentationRegistry.getContext(), 1819 new FakeSettingsProvider()); 1820 mServiceContext.setUseRegisteredHandlers(true); 1821 mServiceContext.setPermission(NETWORK_FACTORY, PERMISSION_GRANTED); 1822 mServiceContext.setPermission(NETWORK_STACK, PERMISSION_GRANTED); 1823 mServiceContext.setPermission(CONTROL_OEM_PAID_NETWORK_PREFERENCE, PERMISSION_GRANTED); 1824 mServiceContext.setPermission(PACKET_KEEPALIVE_OFFLOAD, PERMISSION_GRANTED); 1825 mServiceContext.setPermission(CONNECTIVITY_USE_RESTRICTED_NETWORKS, PERMISSION_GRANTED); 1826 1827 mAlarmManagerThread = new HandlerThread("TestAlarmManager"); 1828 mAlarmManagerThread.start(); 1829 initAlarmManager(mAlarmManager, mAlarmManagerThread.getThreadHandler()); 1830 1831 mCsHandlerThread = new HandlerThread("TestConnectivityService"); 1832 mVMSHandlerThread = new HandlerThread("TestVpnManagerService"); 1833 mProxyTracker = new ProxyTracker(mServiceContext, mock(Handler.class), 1834 16 /* EVENT_PROXY_HAS_CHANGED */); 1835 1836 initMockedResources(); 1837 final Context mockResContext = mock(Context.class); 1838 doReturn(mResources).when(mockResContext).getResources(); 1839 ConnectivityResources.setResourcesContextForTest(mockResContext); 1840 mDeps = new ConnectivityServiceDependencies(mockResContext); 1841 1842 mService = new ConnectivityService(mServiceContext, 1843 mMockDnsResolver, 1844 mock(IpConnectivityLog.class), 1845 mMockNetd, 1846 mDeps); 1847 mService.mLingerDelayMs = TEST_LINGER_DELAY_MS; 1848 mService.mNascentDelayMs = TEST_NASCENT_DELAY_MS; 1849 1850 final ArgumentCaptor<NetworkPolicyCallback> policyCallbackCaptor = 1851 ArgumentCaptor.forClass(NetworkPolicyCallback.class); 1852 verify(mNetworkPolicyManager).registerNetworkPolicyCallback(any(), 1853 policyCallbackCaptor.capture()); 1854 mPolicyCallback = policyCallbackCaptor.getValue(); 1855 1856 // Create local CM before sending system ready so that we can answer 1857 // getSystemService() correctly. 1858 mCm = new WrappedConnectivityManager(InstrumentationRegistry.getContext(), mService); 1859 mService.systemReadyInternal(); 1860 mVpnManagerService = makeVpnManagerService(); 1861 mVpnManagerService.systemReady(); 1862 mockVpn(Process.myUid()); 1863 mCm.bindProcessToNetwork(null); 1864 mQosCallbackTracker = mock(QosCallbackTracker.class); 1865 1866 // Ensure that the default setting for Captive Portals is used for most tests 1867 setCaptivePortalMode(ConnectivitySettingsManager.CAPTIVE_PORTAL_MODE_PROMPT); 1868 setAlwaysOnNetworks(false); 1869 setPrivateDnsSettings(PRIVATE_DNS_MODE_OFF, "ignored.example.com"); 1870 } 1871 initMockedResources()1872 private void initMockedResources() { 1873 doReturn(60000).when(mResources).getInteger(R.integer.config_networkTransitionTimeout); 1874 doReturn("").when(mResources).getString(R.string.config_networkCaptivePortalServerUrl); 1875 doReturn(new String[]{ WIFI_WOL_IFNAME }).when(mResources).getStringArray( 1876 R.array.config_wakeonlan_supported_interfaces); 1877 doReturn(new String[] { "0,1", "1,3" }).when(mResources).getStringArray( 1878 R.array.config_networkSupportedKeepaliveCount); 1879 doReturn(new String[0]).when(mResources).getStringArray( 1880 R.array.config_networkNotifySwitches); 1881 doReturn(new int[]{10, 11, 12, 14, 15}).when(mResources).getIntArray( 1882 R.array.config_protectedNetworks); 1883 // We don't test the actual notification value strings, so just return an empty array. 1884 // It doesn't matter what the values are as long as it's not null. 1885 doReturn(new String[0]).when(mResources) 1886 .getStringArray(R.array.network_switch_type_name); 1887 1888 doReturn(R.array.config_networkSupportedKeepaliveCount).when(mResources) 1889 .getIdentifier(eq("config_networkSupportedKeepaliveCount"), eq("array"), any()); 1890 doReturn(R.array.network_switch_type_name).when(mResources) 1891 .getIdentifier(eq("network_switch_type_name"), eq("array"), any()); 1892 doReturn(R.integer.config_networkAvoidBadWifi).when(mResources) 1893 .getIdentifier(eq("config_networkAvoidBadWifi"), eq("integer"), any()); 1894 doReturn(1).when(mResources).getInteger(R.integer.config_networkAvoidBadWifi); 1895 doReturn(true).when(mResources) 1896 .getBoolean(R.bool.config_cellular_radio_timesharing_capable); 1897 } 1898 1899 class ConnectivityServiceDependencies extends ConnectivityService.Dependencies { 1900 final ConnectivityResources mConnRes; 1901 @Mock final MockableSystemProperties mSystemProperties; 1902 ConnectivityServiceDependencies(final Context mockResContext)1903 ConnectivityServiceDependencies(final Context mockResContext) { 1904 mSystemProperties = mock(MockableSystemProperties.class); 1905 doReturn(false).when(mSystemProperties).getBoolean("ro.radio.noril", false); 1906 1907 mConnRes = new ConnectivityResources(mockResContext); 1908 } 1909 1910 @Override getSystemProperties()1911 public MockableSystemProperties getSystemProperties() { 1912 return mSystemProperties; 1913 } 1914 1915 @Override makeHandlerThread()1916 public HandlerThread makeHandlerThread() { 1917 return mCsHandlerThread; 1918 } 1919 1920 @Override getNetworkStack()1921 public NetworkStackClientBase getNetworkStack() { 1922 return mNetworkStack; 1923 } 1924 1925 @Override makeProxyTracker(final Context context, final Handler handler)1926 public ProxyTracker makeProxyTracker(final Context context, final Handler handler) { 1927 return mProxyTracker; 1928 } 1929 1930 @Override makeNetIdManager()1931 public NetIdManager makeNetIdManager() { 1932 return mNetIdManager; 1933 } 1934 1935 @Override queryUserAccess(final int uid, final Network network, final ConnectivityService cs)1936 public boolean queryUserAccess(final int uid, final Network network, 1937 final ConnectivityService cs) { 1938 return true; 1939 } 1940 1941 @Override makeMultinetworkPolicyTracker(final Context c, final Handler h, final Runnable r)1942 public MultinetworkPolicyTracker makeMultinetworkPolicyTracker(final Context c, 1943 final Handler h, final Runnable r) { 1944 if (null != mPolicyTracker) { 1945 throw new IllegalStateException("Multinetwork policy tracker already initialized"); 1946 } 1947 mPolicyTracker = new WrappedMultinetworkPolicyTracker(mServiceContext, h, r); 1948 return mPolicyTracker; 1949 } 1950 1951 @Override getResources(final Context ctx)1952 public ConnectivityResources getResources(final Context ctx) { 1953 return mConnRes; 1954 } 1955 1956 @Override makeLocationPermissionChecker(final Context context)1957 public LocationPermissionChecker makeLocationPermissionChecker(final Context context) { 1958 return new LocationPermissionChecker(context) { 1959 @Override 1960 protected int getCurrentUser() { 1961 return runAsShell(CREATE_USERS, () -> super.getCurrentUser()); 1962 } 1963 }; 1964 } 1965 1966 @Override makeCarrierPrivilegeAuthenticator( @onNull final Context context, @NonNull final TelephonyManager tm)1967 public CarrierPrivilegeAuthenticator makeCarrierPrivilegeAuthenticator( 1968 @NonNull final Context context, @NonNull final TelephonyManager tm) { 1969 return SdkLevel.isAtLeastT() ? mCarrierPrivilegeAuthenticator : null; 1970 } 1971 1972 @Override intentFilterEquals(final PendingIntent a, final PendingIntent b)1973 public boolean intentFilterEquals(final PendingIntent a, final PendingIntent b) { 1974 return runAsShell(GET_INTENT_SENDER_INTENT, () -> a.intentFilterEquals(b)); 1975 } 1976 1977 @GuardedBy("this") 1978 private Integer mCallingUid = null; 1979 1980 @Override getCallingUid()1981 public int getCallingUid() { 1982 synchronized (this) { 1983 if (null != mCallingUid) return mCallingUid; 1984 return super.getCallingUid(); 1985 } 1986 } 1987 1988 // Pass null for the real calling UID setCallingUid(final Integer uid)1989 public void setCallingUid(final Integer uid) { 1990 synchronized (this) { 1991 mCallingUid = uid; 1992 } 1993 } 1994 1995 @GuardedBy("this") 1996 private boolean mCellular464XlatEnabled = true; 1997 1998 @Override getCellular464XlatEnabled()1999 public boolean getCellular464XlatEnabled() { 2000 synchronized (this) { 2001 return mCellular464XlatEnabled; 2002 } 2003 } 2004 setCellular464XlatEnabled(final boolean enabled)2005 public void setCellular464XlatEnabled(final boolean enabled) { 2006 synchronized (this) { 2007 mCellular464XlatEnabled = enabled; 2008 } 2009 } 2010 2011 @GuardedBy("this") 2012 private Integer mConnectionOwnerUid = null; 2013 2014 @Override getConnectionOwnerUid(final int protocol, final InetSocketAddress local, final InetSocketAddress remote)2015 public int getConnectionOwnerUid(final int protocol, final InetSocketAddress local, 2016 final InetSocketAddress remote) { 2017 synchronized (this) { 2018 if (null != mConnectionOwnerUid) return mConnectionOwnerUid; 2019 return super.getConnectionOwnerUid(protocol, local, remote); 2020 } 2021 } 2022 2023 // Pass null to get the production implementation of getConnectionOwnerUid setConnectionOwnerUid(final Integer uid)2024 public void setConnectionOwnerUid(final Integer uid) { 2025 synchronized (this) { 2026 mConnectionOwnerUid = uid; 2027 } 2028 } 2029 2030 final class ReportedInterfaces { 2031 public final Context context; 2032 public final String iface; 2033 public final int[] transportTypes; ReportedInterfaces(final Context c, final String i, final int[] t)2034 ReportedInterfaces(final Context c, final String i, final int[] t) { 2035 context = c; 2036 iface = i; 2037 transportTypes = t; 2038 } 2039 contentEquals(final Context c, final String i, final int[] t)2040 public boolean contentEquals(final Context c, final String i, final int[] t) { 2041 return Objects.equals(context, c) && Objects.equals(iface, i) 2042 && Arrays.equals(transportTypes, t); 2043 } 2044 } 2045 2046 final ArrayTrackRecord<ReportedInterfaces> mReportedInterfaceHistory = 2047 new ArrayTrackRecord<>(); 2048 2049 @Override reportNetworkInterfaceForTransports(final Context context, final String iface, final int[] transportTypes)2050 public void reportNetworkInterfaceForTransports(final Context context, final String iface, 2051 final int[] transportTypes) { 2052 mReportedInterfaceHistory.add(new ReportedInterfaces(context, iface, transportTypes)); 2053 super.reportNetworkInterfaceForTransports(context, iface, transportTypes); 2054 } 2055 2056 @Override isFeatureEnabled(Context context, String name, boolean defaultEnabled)2057 public boolean isFeatureEnabled(Context context, String name, boolean defaultEnabled) { 2058 switch (name) { 2059 case ConnectivityFlags.NO_REMATCH_ALL_REQUESTS_ON_REGISTER: 2060 return true; 2061 default: 2062 return super.isFeatureEnabled(context, name, defaultEnabled); 2063 } 2064 } 2065 2066 @Override getBpfNetMaps(INetd netd)2067 public BpfNetMaps getBpfNetMaps(INetd netd) { 2068 return mBpfNetMaps; 2069 } 2070 2071 @Override getClatCoordinator(INetd netd)2072 public ClatCoordinator getClatCoordinator(INetd netd) { 2073 return mClatCoordinator; 2074 } 2075 2076 final ArrayTrackRecord<Pair<String, Long>> mRateLimitHistory = new ArrayTrackRecord<>(); 2077 final Map<String, Long> mActiveRateLimit = new HashMap<>(); 2078 2079 @Override enableIngressRateLimit(final String iface, final long rateInBytesPerSecond)2080 public void enableIngressRateLimit(final String iface, final long rateInBytesPerSecond) { 2081 mRateLimitHistory.add(new Pair<>(iface, rateInBytesPerSecond)); 2082 // Due to a TC limitation, the rate limit needs to be removed before it can be 2083 // updated. Check that this happened. 2084 assertEquals(-1L, (long) mActiveRateLimit.getOrDefault(iface, -1L)); 2085 mActiveRateLimit.put(iface, rateInBytesPerSecond); 2086 // verify that clsact qdisc has already been created, otherwise attaching a tc police 2087 // filter will fail. 2088 try { 2089 verify(mMockNetd).networkAddInterface(anyInt(), eq(iface)); 2090 } catch (RemoteException e) { 2091 fail(e.getMessage()); 2092 } 2093 } 2094 2095 @Override disableIngressRateLimit(final String iface)2096 public void disableIngressRateLimit(final String iface) { 2097 mRateLimitHistory.add(new Pair<>(iface, -1L)); 2098 assertNotEquals(-1L, (long) mActiveRateLimit.getOrDefault(iface, -1L)); 2099 mActiveRateLimit.put(iface, -1L); 2100 } 2101 } 2102 2103 private static void initAlarmManager(final AlarmManager am, final Handler alarmHandler) { 2104 doAnswer(inv -> { 2105 final long when = inv.getArgument(1); 2106 final WakeupMessage wakeupMsg = inv.getArgument(3); 2107 final Handler handler = inv.getArgument(4); 2108 2109 long delayMs = when - SystemClock.elapsedRealtime(); 2110 if (delayMs < 0) delayMs = 0; 2111 if (delayMs > UNREASONABLY_LONG_ALARM_WAIT_MS) { 2112 fail("Attempting to send msg more than " + UNREASONABLY_LONG_ALARM_WAIT_MS 2113 + "ms into the future: " + delayMs); 2114 } 2115 alarmHandler.postDelayed(() -> handler.post(wakeupMsg::onAlarm), wakeupMsg /* token */, 2116 delayMs); 2117 2118 return null; 2119 }).when(am).setExact(eq(AlarmManager.ELAPSED_REALTIME_WAKEUP), anyLong(), anyString(), 2120 any(WakeupMessage.class), any()); 2121 2122 doAnswer(inv -> { 2123 final WakeupMessage wakeupMsg = inv.getArgument(0); 2124 alarmHandler.removeCallbacksAndMessages(wakeupMsg /* token */); 2125 return null; 2126 }).when(am).cancel(any(WakeupMessage.class)); 2127 } 2128 2129 @After 2130 public void tearDown() throws Exception { 2131 unregisterDefaultNetworkCallbacks(); 2132 maybeTearDownEnterpriseNetwork(); 2133 setAlwaysOnNetworks(false); 2134 if (mCellNetworkAgent != null) { 2135 mCellNetworkAgent.disconnect(); 2136 mCellNetworkAgent = null; 2137 } 2138 if (mWiFiNetworkAgent != null) { 2139 mWiFiNetworkAgent.disconnect(); 2140 mWiFiNetworkAgent = null; 2141 } 2142 if (mEthernetNetworkAgent != null) { 2143 mEthernetNetworkAgent.disconnect(); 2144 mEthernetNetworkAgent = null; 2145 } 2146 2147 if (mQosCallbackMockHelper != null) { 2148 mQosCallbackMockHelper.tearDown(); 2149 mQosCallbackMockHelper = null; 2150 } 2151 mMockVpn.disconnect(); 2152 waitForIdle(); 2153 2154 FakeSettingsProvider.clearSettingsProvider(); 2155 ConnectivityResources.setResourcesContextForTest(null); 2156 2157 mCsHandlerThread.quitSafely(); 2158 mAlarmManagerThread.quitSafely(); 2159 } 2160 2161 private void mockDefaultPackages() throws Exception { 2162 final String myPackageName = mContext.getPackageName(); 2163 final PackageInfo myPackageInfo = mContext.getPackageManager().getPackageInfo( 2164 myPackageName, PackageManager.GET_PERMISSIONS); 2165 doReturn(new String[] {myPackageName}).when(mPackageManager) 2166 .getPackagesForUid(Binder.getCallingUid()); 2167 doReturn(myPackageInfo).when(mPackageManager).getPackageInfoAsUser( 2168 eq(myPackageName), anyInt(), eq(UserHandle.getCallingUserId())); 2169 2170 doReturn(asList(new PackageInfo[] { 2171 buildPackageInfo(/* SYSTEM */ false, APP1_UID), 2172 buildPackageInfo(/* SYSTEM */ false, APP2_UID), 2173 buildPackageInfo(/* SYSTEM */ false, VPN_UID) 2174 })).when(mPackageManager).getInstalledPackagesAsUser(eq(GET_PERMISSIONS), anyInt()); 2175 2176 // Create a fake always-on VPN package. 2177 final int userId = UserHandle.getCallingUserId(); 2178 final ApplicationInfo applicationInfo = new ApplicationInfo(); 2179 applicationInfo.targetSdkVersion = Build.VERSION_CODES.R; // Always-on supported in N+. 2180 doReturn(applicationInfo).when(mPackageManager).getApplicationInfoAsUser( 2181 eq(ALWAYS_ON_PACKAGE), anyInt(), eq(userId)); 2182 2183 // Minimal mocking to keep Vpn#isAlwaysOnPackageSupported happy. 2184 ResolveInfo rInfo = new ResolveInfo(); 2185 rInfo.serviceInfo = new ServiceInfo(); 2186 rInfo.serviceInfo.metaData = new Bundle(); 2187 final List<ResolveInfo> services = asList(new ResolveInfo[]{rInfo}); 2188 doReturn(services).when(mPackageManager).queryIntentServicesAsUser( 2189 any(), eq(PackageManager.GET_META_DATA), eq(userId)); 2190 doReturn(Process.myUid()).when(mPackageManager).getPackageUidAsUser( 2191 TEST_PACKAGE_NAME, userId); 2192 doReturn(VPN_UID).when(mPackageManager).getPackageUidAsUser(ALWAYS_ON_PACKAGE, userId); 2193 } 2194 2195 private void verifyActiveNetwork(int transport) { 2196 // Test getActiveNetworkInfo() 2197 assertNotNull(mCm.getActiveNetworkInfo()); 2198 assertEquals(transportToLegacyType(transport), mCm.getActiveNetworkInfo().getType()); 2199 // Test getActiveNetwork() 2200 assertNotNull(mCm.getActiveNetwork()); 2201 assertEquals(mCm.getActiveNetwork(), mCm.getActiveNetworkForUid(Process.myUid())); 2202 if (!NetworkCapabilities.isValidTransport(transport)) { 2203 throw new IllegalStateException("Unknown transport " + transport); 2204 } 2205 switch (transport) { 2206 case TRANSPORT_WIFI: 2207 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 2208 break; 2209 case TRANSPORT_CELLULAR: 2210 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 2211 break; 2212 case TRANSPORT_ETHERNET: 2213 assertEquals(mEthernetNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 2214 break; 2215 default: 2216 break; 2217 } 2218 // Test getNetworkInfo(Network) 2219 assertNotNull(mCm.getNetworkInfo(mCm.getActiveNetwork())); 2220 assertEquals(transportToLegacyType(transport), 2221 mCm.getNetworkInfo(mCm.getActiveNetwork()).getType()); 2222 assertNotNull(mCm.getActiveNetworkInfoForUid(Process.myUid())); 2223 // Test getNetworkCapabilities(Network) 2224 assertNotNull(mCm.getNetworkCapabilities(mCm.getActiveNetwork())); 2225 assertTrue(mCm.getNetworkCapabilities(mCm.getActiveNetwork()).hasTransport(transport)); 2226 } 2227 2228 private void verifyNoNetwork() { 2229 waitForIdle(); 2230 // Test getActiveNetworkInfo() 2231 assertNull(mCm.getActiveNetworkInfo()); 2232 // Test getActiveNetwork() 2233 assertNull(mCm.getActiveNetwork()); 2234 assertNull(mCm.getActiveNetworkForUid(Process.myUid())); 2235 // Test getAllNetworks() 2236 assertEmpty(mCm.getAllNetworks()); 2237 assertEmpty(mCm.getAllNetworkStateSnapshots()); 2238 } 2239 2240 /** 2241 * Class to simplify expecting broadcasts using BroadcastInterceptingContext. 2242 * Ensures that the receiver is unregistered after the expected broadcast is received. This 2243 * cannot be done in the BroadcastReceiver itself because BroadcastInterceptingContext runs 2244 * the receivers' receive method while iterating over the list of receivers, and unregistering 2245 * the receiver during iteration throws ConcurrentModificationException. 2246 */ 2247 private class ExpectedBroadcast extends CompletableFuture<Intent> { 2248 private final BroadcastReceiver mReceiver; 2249 2250 ExpectedBroadcast(BroadcastReceiver receiver) { 2251 mReceiver = receiver; 2252 } 2253 2254 public Intent expectBroadcast(int timeoutMs) throws Exception { 2255 try { 2256 return get(timeoutMs, TimeUnit.MILLISECONDS); 2257 } catch (TimeoutException e) { 2258 fail("Expected broadcast not received after " + timeoutMs + " ms"); 2259 return null; 2260 } finally { 2261 mServiceContext.unregisterReceiver(mReceiver); 2262 } 2263 } 2264 2265 public Intent expectBroadcast() throws Exception { 2266 return expectBroadcast(BROADCAST_TIMEOUT_MS); 2267 } 2268 2269 public void expectNoBroadcast(int timeoutMs) throws Exception { 2270 waitForIdle(); 2271 try { 2272 final Intent intent = get(timeoutMs, TimeUnit.MILLISECONDS); 2273 fail("Unexpected broadcast: " + intent.getAction() + " " + intent.getExtras()); 2274 } catch (TimeoutException expected) { 2275 } finally { 2276 mServiceContext.unregisterReceiver(mReceiver); 2277 } 2278 } 2279 } 2280 2281 /** Expects that {@code count} CONNECTIVITY_ACTION broadcasts are received. */ 2282 private ExpectedBroadcast registerConnectivityBroadcast(final int count) { 2283 return registerConnectivityBroadcastThat(count, intent -> true); 2284 } 2285 2286 private ExpectedBroadcast registerConnectivityBroadcastThat(final int count, 2287 @NonNull final Predicate<Intent> filter) { 2288 final IntentFilter intentFilter = new IntentFilter(CONNECTIVITY_ACTION); 2289 // AtomicReference allows receiver to access expected even though it is constructed later. 2290 final AtomicReference<ExpectedBroadcast> expectedRef = new AtomicReference<>(); 2291 final BroadcastReceiver receiver = new BroadcastReceiver() { 2292 private int mRemaining = count; 2293 public void onReceive(Context context, Intent intent) { 2294 final int type = intent.getIntExtra(EXTRA_NETWORK_TYPE, -1); 2295 final NetworkInfo ni = intent.getParcelableExtra(EXTRA_NETWORK_INFO); 2296 Log.d(TAG, "Received CONNECTIVITY_ACTION type=" + type + " ni=" + ni); 2297 if (!filter.test(intent)) return; 2298 if (--mRemaining == 0) { 2299 expectedRef.get().complete(intent); 2300 } 2301 } 2302 }; 2303 final ExpectedBroadcast expected = new ExpectedBroadcast(receiver); 2304 expectedRef.set(expected); 2305 mServiceContext.registerReceiver(receiver, intentFilter); 2306 return expected; 2307 } 2308 2309 private ExpectedBroadcast expectProxyChangeAction(ProxyInfo proxy) { 2310 return registerPacProxyBroadcastThat(intent -> { 2311 final ProxyInfo actualProxy = (ProxyInfo) intent.getExtra(Proxy.EXTRA_PROXY_INFO, 2312 ProxyInfo.buildPacProxy(Uri.EMPTY)); 2313 return proxy.equals(actualProxy); 2314 }); 2315 } 2316 2317 private ExpectedBroadcast registerPacProxyBroadcast() { 2318 return registerPacProxyBroadcastThat(intent -> true); 2319 } 2320 2321 private ExpectedBroadcast registerPacProxyBroadcastThat( 2322 @NonNull final Predicate<Intent> filter) { 2323 final IntentFilter intentFilter = new IntentFilter(Proxy.PROXY_CHANGE_ACTION); 2324 // AtomicReference allows receiver to access expected even though it is constructed later. 2325 final AtomicReference<ExpectedBroadcast> expectedRef = new AtomicReference<>(); 2326 final BroadcastReceiver receiver = new BroadcastReceiver() { 2327 public void onReceive(Context context, Intent intent) { 2328 final ProxyInfo proxy = (ProxyInfo) intent.getExtra( 2329 Proxy.EXTRA_PROXY_INFO, ProxyInfo.buildPacProxy(Uri.EMPTY)); 2330 Log.d(TAG, "Receive PROXY_CHANGE_ACTION, proxy = " + proxy); 2331 if (filter.test(intent)) { 2332 expectedRef.get().complete(intent); 2333 } 2334 } 2335 }; 2336 final ExpectedBroadcast expected = new ExpectedBroadcast(receiver); 2337 expectedRef.set(expected); 2338 mServiceContext.registerReceiver(receiver, intentFilter); 2339 return expected; 2340 } 2341 2342 private boolean extraInfoInBroadcastHasExpectedNullness(NetworkInfo ni) { 2343 final DetailedState state = ni.getDetailedState(); 2344 if (state == DetailedState.CONNECTED && ni.getExtraInfo() == null) return false; 2345 // Expect a null extraInfo if the network is CONNECTING, because a CONNECTIVITY_ACTION 2346 // broadcast with a state of CONNECTING only happens due to legacy VPN lockdown, which also 2347 // nulls out extraInfo. 2348 if (state == DetailedState.CONNECTING && ni.getExtraInfo() != null) return false; 2349 // Can't make any assertions about DISCONNECTED broadcasts. When a network actually 2350 // disconnects, disconnectAndDestroyNetwork sets its state to DISCONNECTED and its extraInfo 2351 // to null. But if the DISCONNECTED broadcast is just simulated by LegacyTypeTracker due to 2352 // a network switch, extraInfo will likely be populated. 2353 // This is likely a bug in CS, but likely not one we can fix without impacting apps. 2354 return true; 2355 } 2356 2357 private ExpectedBroadcast expectConnectivityAction(int type, NetworkInfo.DetailedState state) { 2358 return registerConnectivityBroadcastThat(1, intent -> { 2359 final int actualType = intent.getIntExtra(EXTRA_NETWORK_TYPE, -1); 2360 final NetworkInfo ni = intent.getParcelableExtra(EXTRA_NETWORK_INFO); 2361 return type == actualType 2362 && state == ni.getDetailedState() 2363 && extraInfoInBroadcastHasExpectedNullness(ni); 2364 }); 2365 } 2366 2367 @Test 2368 public void testNetworkTypes() { 2369 // Ensure that our mocks for the networkAttributes config variable work as expected. If they 2370 // don't, then tests that depend on CONNECTIVITY_ACTION broadcasts for these network types 2371 // will fail. Failing here is much easier to debug. 2372 assertTrue(mCm.isNetworkSupported(TYPE_WIFI)); 2373 assertTrue(mCm.isNetworkSupported(TYPE_MOBILE)); 2374 assertTrue(mCm.isNetworkSupported(TYPE_MOBILE_MMS)); 2375 assertTrue(mCm.isNetworkSupported(TYPE_MOBILE_FOTA)); 2376 assertFalse(mCm.isNetworkSupported(TYPE_PROXY)); 2377 2378 // Check that TYPE_ETHERNET is supported. Unlike the asserts above, which only validate our 2379 // mocks, this assert exercises the ConnectivityService code path that ensures that 2380 // TYPE_ETHERNET is supported if the ethernet service is running. 2381 assertTrue(mCm.isNetworkSupported(TYPE_ETHERNET)); 2382 } 2383 2384 @Test 2385 public void testNetworkFeature() throws Exception { 2386 // Connect the cell agent and wait for the connected broadcast. 2387 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 2388 mCellNetworkAgent.addCapability(NET_CAPABILITY_SUPL); 2389 ExpectedBroadcast b = expectConnectivityAction(TYPE_MOBILE, DetailedState.CONNECTED); 2390 mCellNetworkAgent.connect(true); 2391 b.expectBroadcast(); 2392 2393 // Build legacy request for SUPL. 2394 final NetworkCapabilities legacyCaps = new NetworkCapabilities(); 2395 legacyCaps.addTransportType(TRANSPORT_CELLULAR); 2396 legacyCaps.addCapability(NET_CAPABILITY_SUPL); 2397 final NetworkRequest legacyRequest = new NetworkRequest(legacyCaps, TYPE_MOBILE_SUPL, 2398 ConnectivityManager.REQUEST_ID_UNSET, NetworkRequest.Type.REQUEST); 2399 2400 // File request, withdraw it and make sure no broadcast is sent 2401 b = registerConnectivityBroadcast(1); 2402 final TestNetworkCallback callback = new TestNetworkCallback(); 2403 mCm.requestNetwork(legacyRequest, callback); 2404 callback.expectCallback(CallbackEntry.AVAILABLE, mCellNetworkAgent); 2405 mCm.unregisterNetworkCallback(callback); 2406 b.expectNoBroadcast(800); // 800ms long enough to at least flake if this is sent 2407 2408 // Disconnect the network and expect mobile disconnected broadcast. 2409 b = expectConnectivityAction(TYPE_MOBILE, DetailedState.DISCONNECTED); 2410 mCellNetworkAgent.disconnect(); 2411 b.expectBroadcast(); 2412 } 2413 2414 @Test 2415 public void testLingering() throws Exception { 2416 verifyNoNetwork(); 2417 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 2418 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 2419 assertNull(mCm.getActiveNetworkInfo()); 2420 assertNull(mCm.getActiveNetwork()); 2421 // Test bringing up validated cellular. 2422 ExpectedBroadcast b = expectConnectivityAction(TYPE_MOBILE, DetailedState.CONNECTED); 2423 mCellNetworkAgent.connect(true); 2424 b.expectBroadcast(); 2425 verifyActiveNetwork(TRANSPORT_CELLULAR); 2426 assertLength(2, mCm.getAllNetworks()); 2427 assertTrue(mCm.getAllNetworks()[0].equals(mCm.getActiveNetwork()) || 2428 mCm.getAllNetworks()[1].equals(mCm.getActiveNetwork())); 2429 assertTrue(mCm.getAllNetworks()[0].equals(mWiFiNetworkAgent.getNetwork()) || 2430 mCm.getAllNetworks()[1].equals(mWiFiNetworkAgent.getNetwork())); 2431 // Test bringing up validated WiFi. 2432 b = registerConnectivityBroadcast(2); 2433 mWiFiNetworkAgent.connect(true); 2434 b.expectBroadcast(); 2435 verifyActiveNetwork(TRANSPORT_WIFI); 2436 assertLength(2, mCm.getAllNetworks()); 2437 assertTrue(mCm.getAllNetworks()[0].equals(mCm.getActiveNetwork()) || 2438 mCm.getAllNetworks()[1].equals(mCm.getActiveNetwork())); 2439 assertTrue(mCm.getAllNetworks()[0].equals(mCellNetworkAgent.getNetwork()) || 2440 mCm.getAllNetworks()[1].equals(mCellNetworkAgent.getNetwork())); 2441 // Test cellular linger timeout. 2442 mCellNetworkAgent.expectDisconnected(); 2443 waitForIdle(); 2444 assertLength(1, mCm.getAllNetworks()); 2445 verifyActiveNetwork(TRANSPORT_WIFI); 2446 assertLength(1, mCm.getAllNetworks()); 2447 assertEquals(mCm.getAllNetworks()[0], mCm.getActiveNetwork()); 2448 // Test WiFi disconnect. 2449 b = registerConnectivityBroadcast(1); 2450 mWiFiNetworkAgent.disconnect(); 2451 b.expectBroadcast(); 2452 verifyNoNetwork(); 2453 } 2454 2455 /** 2456 * Verify a newly created network will be inactive instead of torn down even if no one is 2457 * requesting. 2458 */ 2459 @Test 2460 public void testNewNetworkInactive() throws Exception { 2461 // Create a callback that monitoring the testing network. 2462 final TestNetworkCallback listenCallback = new TestNetworkCallback(); 2463 mCm.registerNetworkCallback(new NetworkRequest.Builder().build(), listenCallback); 2464 2465 // 1. Create a network that is not requested by anyone, and does not satisfy any of the 2466 // default requests. Verify that the network will be inactive instead of torn down. 2467 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 2468 mWiFiNetworkAgent.connectWithoutInternet(); 2469 listenCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 2470 listenCallback.assertNoCallback(); 2471 2472 // Verify that the network will be torn down after nascent expiry. A small period of time 2473 // is added in case of flakiness. 2474 final int nascentTimeoutMs = 2475 mService.mNascentDelayMs + mService.mNascentDelayMs / 4; 2476 listenCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent, nascentTimeoutMs); 2477 2478 // 2. Create a network that is satisfied by a request comes later. 2479 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 2480 mWiFiNetworkAgent.connectWithoutInternet(); 2481 listenCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 2482 final NetworkRequest wifiRequest = new NetworkRequest.Builder() 2483 .addTransportType(TRANSPORT_WIFI).build(); 2484 final TestNetworkCallback wifiCallback = new TestNetworkCallback(); 2485 mCm.requestNetwork(wifiRequest, wifiCallback); 2486 wifiCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 2487 2488 // Verify that the network will be kept since the request is still satisfied. And is able 2489 // to get disconnected as usual if the request is released after the nascent timer expires. 2490 listenCallback.assertNoCallback(nascentTimeoutMs); 2491 mCm.unregisterNetworkCallback(wifiCallback); 2492 listenCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 2493 2494 // 3. Create a network that is satisfied by a request comes later. 2495 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 2496 mWiFiNetworkAgent.connectWithoutInternet(); 2497 listenCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 2498 mCm.requestNetwork(wifiRequest, wifiCallback); 2499 wifiCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 2500 2501 // Verify that the network will still be torn down after the request gets removed. 2502 mCm.unregisterNetworkCallback(wifiCallback); 2503 listenCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 2504 2505 // There is no need to ensure that LOSING is never sent in the common case that the 2506 // network immediately satisfies a request that was already present, because it is already 2507 // verified anywhere whenever {@code TestNetworkCallback#expectAvailable*} is called. 2508 2509 mCm.unregisterNetworkCallback(listenCallback); 2510 } 2511 2512 /** 2513 * Verify a newly created network will be inactive and switch to background if only background 2514 * request is satisfied. 2515 */ 2516 @Test 2517 public void testNewNetworkInactive_bgNetwork() throws Exception { 2518 // Create a callback that monitoring the wifi network. 2519 final TestNetworkCallback wifiListenCallback = new TestNetworkCallback(); 2520 mCm.registerNetworkCallback(new NetworkRequest.Builder() 2521 .addTransportType(TRANSPORT_WIFI).build(), wifiListenCallback); 2522 2523 // Create callbacks that can monitor background and foreground mobile networks. 2524 // This is done by granting using background networks permission before registration. Thus, 2525 // the service will not add {@code NET_CAPABILITY_FOREGROUND} by default. 2526 grantUsingBackgroundNetworksPermissionForUid(Binder.getCallingUid()); 2527 final TestNetworkCallback bgMobileListenCallback = new TestNetworkCallback(); 2528 final TestNetworkCallback fgMobileListenCallback = new TestNetworkCallback(); 2529 mCm.registerNetworkCallback(new NetworkRequest.Builder() 2530 .addTransportType(TRANSPORT_CELLULAR).build(), bgMobileListenCallback); 2531 mCm.registerNetworkCallback(new NetworkRequest.Builder() 2532 .addTransportType(TRANSPORT_CELLULAR) 2533 .addCapability(NET_CAPABILITY_FOREGROUND).build(), fgMobileListenCallback); 2534 2535 // Connect wifi, which satisfies default request. 2536 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 2537 mWiFiNetworkAgent.connect(true); 2538 wifiListenCallback.expectAvailableThenValidatedCallbacks(mWiFiNetworkAgent); 2539 2540 // Connect a cellular network, verify that satisfies only the background callback. 2541 setAlwaysOnNetworks(true); 2542 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 2543 mCellNetworkAgent.connect(true); 2544 bgMobileListenCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 2545 fgMobileListenCallback.assertNoCallback(); 2546 assertFalse(isForegroundNetwork(mCellNetworkAgent)); 2547 2548 mCellNetworkAgent.disconnect(); 2549 bgMobileListenCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 2550 fgMobileListenCallback.assertNoCallback(); 2551 2552 mCm.unregisterNetworkCallback(wifiListenCallback); 2553 mCm.unregisterNetworkCallback(bgMobileListenCallback); 2554 mCm.unregisterNetworkCallback(fgMobileListenCallback); 2555 } 2556 2557 @Test 2558 public void testBinderDeathAfterUnregister() throws Exception { 2559 final NetworkCapabilities caps = new NetworkCapabilities.Builder() 2560 .addTransportType(TRANSPORT_WIFI) 2561 .build(); 2562 final Handler handler = new Handler(ConnectivityThread.getInstanceLooper()); 2563 final Messenger messenger = new Messenger(handler); 2564 final CompletableFuture<Binder.DeathRecipient> deathRecipient = new CompletableFuture<>(); 2565 final Binder binder = new Binder() { 2566 private DeathRecipient mDeathRecipient; 2567 @Override 2568 public void linkToDeath(@NonNull final DeathRecipient recipient, final int flags) { 2569 synchronized (this) { 2570 mDeathRecipient = recipient; 2571 } 2572 super.linkToDeath(recipient, flags); 2573 deathRecipient.complete(recipient); 2574 } 2575 2576 @Override 2577 public boolean unlinkToDeath(@NonNull final DeathRecipient recipient, final int flags) { 2578 synchronized (this) { 2579 if (null == mDeathRecipient) { 2580 throw new IllegalStateException(); 2581 } 2582 mDeathRecipient = null; 2583 } 2584 return super.unlinkToDeath(recipient, flags); 2585 } 2586 }; 2587 final NetworkRequest request = mService.listenForNetwork(caps, messenger, binder, 2588 NetworkCallback.FLAG_NONE, mContext.getOpPackageName(), 2589 mContext.getAttributionTag()); 2590 mService.releaseNetworkRequest(request); 2591 deathRecipient.get().binderDied(); 2592 // Wait for the release message to be processed. 2593 waitForIdle(); 2594 // After waitForIdle(), the message was processed and the service didn't crash. 2595 } 2596 2597 // TODO : migrate to @Parameterized 2598 @Test 2599 public void testValidatedCellularOutscoresUnvalidatedWiFi_CanTimeShare() throws Exception { 2600 // The behavior of this test should be the same whether the radio can time share or not. 2601 doTestValidatedCellularOutscoresUnvalidatedWiFi(true); 2602 } 2603 2604 // TODO : migrate to @Parameterized 2605 @Test 2606 public void testValidatedCellularOutscoresUnvalidatedWiFi_CannotTimeShare() throws Exception { 2607 doTestValidatedCellularOutscoresUnvalidatedWiFi(false); 2608 } 2609 2610 public void doTestValidatedCellularOutscoresUnvalidatedWiFi( 2611 final boolean cellRadioTimesharingCapable) throws Exception { 2612 mService.mCellularRadioTimesharingCapable = cellRadioTimesharingCapable; 2613 // Test bringing up unvalidated WiFi 2614 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 2615 ExpectedBroadcast b = registerConnectivityBroadcast(1); 2616 mWiFiNetworkAgent.connect(false); 2617 b.expectBroadcast(); 2618 verifyActiveNetwork(TRANSPORT_WIFI); 2619 // Test bringing up unvalidated cellular 2620 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 2621 mCellNetworkAgent.connect(false); 2622 waitForIdle(); 2623 verifyActiveNetwork(TRANSPORT_WIFI); 2624 // Test cellular disconnect. 2625 mCellNetworkAgent.disconnect(); 2626 waitForIdle(); 2627 verifyActiveNetwork(TRANSPORT_WIFI); 2628 // Test bringing up validated cellular 2629 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 2630 b = registerConnectivityBroadcast(2); 2631 mCellNetworkAgent.connect(true); 2632 b.expectBroadcast(); 2633 verifyActiveNetwork(TRANSPORT_CELLULAR); 2634 // Test cellular disconnect. 2635 b = registerConnectivityBroadcast(2); 2636 mCellNetworkAgent.disconnect(); 2637 b.expectBroadcast(); 2638 verifyActiveNetwork(TRANSPORT_WIFI); 2639 // Test WiFi disconnect. 2640 b = registerConnectivityBroadcast(1); 2641 mWiFiNetworkAgent.disconnect(); 2642 b.expectBroadcast(); 2643 verifyNoNetwork(); 2644 } 2645 2646 // TODO : migrate to @Parameterized 2647 @Test 2648 public void testUnvalidatedWifiOutscoresUnvalidatedCellular_CanTimeShare() throws Exception { 2649 doTestUnvalidatedWifiOutscoresUnvalidatedCellular(true); 2650 } 2651 2652 // TODO : migrate to @Parameterized 2653 @Test 2654 public void testUnvalidatedWifiOutscoresUnvalidatedCellular_CannotTimeShare() throws Exception { 2655 doTestUnvalidatedWifiOutscoresUnvalidatedCellular(false); 2656 } 2657 2658 public void doTestUnvalidatedWifiOutscoresUnvalidatedCellular( 2659 final boolean cellRadioTimesharingCapable) throws Exception { 2660 mService.mCellularRadioTimesharingCapable = cellRadioTimesharingCapable; 2661 // Test bringing up unvalidated cellular. 2662 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 2663 ExpectedBroadcast b = registerConnectivityBroadcast(1); 2664 mCellNetworkAgent.connect(false); 2665 b.expectBroadcast(); 2666 verifyActiveNetwork(TRANSPORT_CELLULAR); 2667 // Test bringing up unvalidated WiFi. 2668 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 2669 b = registerConnectivityBroadcast(2); 2670 mWiFiNetworkAgent.connect(false); 2671 b.expectBroadcast(); 2672 verifyActiveNetwork(TRANSPORT_WIFI); 2673 // Test WiFi disconnect. 2674 b = registerConnectivityBroadcast(2); 2675 mWiFiNetworkAgent.disconnect(); 2676 b.expectBroadcast(); 2677 verifyActiveNetwork(TRANSPORT_CELLULAR); 2678 // Test cellular disconnect. 2679 b = registerConnectivityBroadcast(1); 2680 mCellNetworkAgent.disconnect(); 2681 b.expectBroadcast(); 2682 verifyNoNetwork(); 2683 } 2684 2685 // TODO : migrate to @Parameterized 2686 @Test 2687 public void testUnlingeringDoesNotValidate_CanTimeShare() throws Exception { 2688 doTestUnlingeringDoesNotValidate(true); 2689 } 2690 2691 // TODO : migrate to @Parameterized 2692 @Test 2693 public void testUnlingeringDoesNotValidate_CannotTimeShare() throws Exception { 2694 doTestUnlingeringDoesNotValidate(false); 2695 } 2696 2697 public void doTestUnlingeringDoesNotValidate( 2698 final boolean cellRadioTimesharingCapable) throws Exception { 2699 mService.mCellularRadioTimesharingCapable = cellRadioTimesharingCapable; 2700 // Test bringing up unvalidated WiFi. 2701 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 2702 ExpectedBroadcast b = registerConnectivityBroadcast(1); 2703 mWiFiNetworkAgent.connect(false); 2704 b.expectBroadcast(); 2705 verifyActiveNetwork(TRANSPORT_WIFI); 2706 assertFalse(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).hasCapability( 2707 NET_CAPABILITY_VALIDATED)); 2708 // Test bringing up validated cellular. 2709 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 2710 b = registerConnectivityBroadcast(2); 2711 mCellNetworkAgent.connect(true); 2712 b.expectBroadcast(); 2713 verifyActiveNetwork(TRANSPORT_CELLULAR); 2714 assertFalse(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).hasCapability( 2715 NET_CAPABILITY_VALIDATED)); 2716 // Test cellular disconnect. 2717 b = registerConnectivityBroadcast(2); 2718 mCellNetworkAgent.disconnect(); 2719 b.expectBroadcast(); 2720 verifyActiveNetwork(TRANSPORT_WIFI); 2721 // Unlingering a network should not cause it to be marked as validated. 2722 assertFalse(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).hasCapability( 2723 NET_CAPABILITY_VALIDATED)); 2724 } 2725 2726 // TODO : migrate to @Parameterized 2727 @Test 2728 public void testRequestMigrationToSameTransport_CanTimeShare() throws Exception { 2729 // Simulate a device where the cell radio is capable of time sharing 2730 mService.mCellularRadioTimesharingCapable = true; 2731 doTestRequestMigrationToSameTransport(TRANSPORT_CELLULAR, true); 2732 doTestRequestMigrationToSameTransport(TRANSPORT_WIFI, true); 2733 doTestRequestMigrationToSameTransport(TRANSPORT_ETHERNET, true); 2734 } 2735 2736 // TODO : migrate to @Parameterized 2737 @Test 2738 public void testRequestMigrationToSameTransport_CannotTimeShare() throws Exception { 2739 // Simulate a device where the cell radio is not capable of time sharing 2740 mService.mCellularRadioTimesharingCapable = false; 2741 doTestRequestMigrationToSameTransport(TRANSPORT_CELLULAR, false); 2742 doTestRequestMigrationToSameTransport(TRANSPORT_WIFI, true); 2743 doTestRequestMigrationToSameTransport(TRANSPORT_ETHERNET, true); 2744 } 2745 2746 public void doTestRequestMigrationToSameTransport(final int transport, 2747 final boolean expectLingering) throws Exception { 2748 // To speed up tests the linger delay is very short by default in tests but this 2749 // test needs to make sure the delay is not incurred so a longer value is safer (it 2750 // reduces the risk that a bug exists but goes undetected). The alarm manager in the test 2751 // throws and crashes CS if this is set to anything more than the below constant though. 2752 mService.mLingerDelayMs = UNREASONABLY_LONG_ALARM_WAIT_MS; 2753 2754 final TestNetworkCallback generalCb = new TestNetworkCallback(); 2755 final TestNetworkCallback defaultCb = new TestNetworkCallback(); 2756 mCm.registerNetworkCallback( 2757 new NetworkRequest.Builder().addTransportType(transport | transport).build(), 2758 generalCb); 2759 mCm.registerDefaultNetworkCallback(defaultCb); 2760 2761 // Bring up net agent 1 2762 final TestNetworkAgentWrapper net1 = new TestNetworkAgentWrapper(transport); 2763 net1.connect(true); 2764 // Make sure the default request is on net 1 2765 generalCb.expectAvailableThenValidatedCallbacks(net1); 2766 defaultCb.expectAvailableThenValidatedCallbacks(net1); 2767 2768 // Bring up net 2 with primary and mms 2769 final TestNetworkAgentWrapper net2 = new TestNetworkAgentWrapper(transport); 2770 net2.addCapability(NET_CAPABILITY_MMS); 2771 net2.setScore(new NetworkScore.Builder().setTransportPrimary(true).build()); 2772 net2.connect(true); 2773 2774 // Make sure the default request goes to net 2 2775 generalCb.expectAvailableCallbacksUnvalidated(net2); 2776 if (expectLingering) { 2777 generalCb.expectCallback(CallbackEntry.LOSING, net1); 2778 } 2779 generalCb.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, net2); 2780 defaultCb.expectAvailableDoubleValidatedCallbacks(net2); 2781 2782 // Make sure cell 1 is unwanted immediately if the radio can't time share, but only 2783 // after some delay if it can. 2784 if (expectLingering) { 2785 net1.assertNotDisconnected(TEST_CALLBACK_TIMEOUT_MS); // always incurs the timeout 2786 generalCb.assertNoCallback(); 2787 // assertNotDisconnected waited for TEST_CALLBACK_TIMEOUT_MS, so waiting for the 2788 // linger period gives TEST_CALLBACK_TIMEOUT_MS time for the event to process. 2789 net1.expectDisconnected(UNREASONABLY_LONG_ALARM_WAIT_MS); 2790 } else { 2791 net1.expectDisconnected(TEST_CALLBACK_TIMEOUT_MS); 2792 } 2793 net1.disconnect(); 2794 generalCb.expectCallback(CallbackEntry.LOST, net1); 2795 2796 // Remove primary from net 2 2797 net2.setScore(new NetworkScore.Builder().build()); 2798 // Request MMS 2799 final TestNetworkCallback mmsCallback = new TestNetworkCallback(); 2800 mCm.requestNetwork(new NetworkRequest.Builder().addCapability(NET_CAPABILITY_MMS).build(), 2801 mmsCallback); 2802 mmsCallback.expectAvailableCallbacksValidated(net2); 2803 2804 // Bring up net 3 with primary but without MMS 2805 final TestNetworkAgentWrapper net3 = new TestNetworkAgentWrapper(transport); 2806 net3.setScore(new NetworkScore.Builder().setTransportPrimary(true).build()); 2807 net3.connect(true); 2808 2809 // Make sure default goes to net 3, but the MMS request doesn't 2810 generalCb.expectAvailableThenValidatedCallbacks(net3); 2811 defaultCb.expectAvailableDoubleValidatedCallbacks(net3); 2812 mmsCallback.assertNoCallback(); 2813 net2.assertNotDisconnected(TEST_CALLBACK_TIMEOUT_MS); // Always incurs the timeout 2814 2815 // Revoke MMS request and make sure net 2 is torn down with the appropriate delay 2816 mCm.unregisterNetworkCallback(mmsCallback); 2817 if (expectLingering) { 2818 // If the radio can time share, the linger delay hasn't elapsed yet, so apps will 2819 // get LOSING. If the radio can't time share, this is a hard loss, since the last 2820 // request keeping up this network has been removed and the network isn't lingering 2821 // for any other request. 2822 generalCb.expectCallback(CallbackEntry.LOSING, net2); 2823 net2.assertNotDisconnected(TEST_CALLBACK_TIMEOUT_MS); 2824 generalCb.assertNoCallback(); 2825 net2.expectDisconnected(UNREASONABLY_LONG_ALARM_WAIT_MS); 2826 } else { 2827 net2.expectDisconnected(TEST_CALLBACK_TIMEOUT_MS); 2828 } 2829 net2.disconnect(); 2830 generalCb.expectCallback(CallbackEntry.LOST, net2); 2831 defaultCb.assertNoCallback(); 2832 2833 net3.disconnect(); 2834 mCm.unregisterNetworkCallback(defaultCb); 2835 mCm.unregisterNetworkCallback(generalCb); 2836 } 2837 2838 // TODO : migrate to @Parameterized 2839 @Test 2840 public void testCellularOutscoresWeakWifi_CanTimeShare() throws Exception { 2841 // The behavior of this test should be the same whether the radio can time share or not. 2842 doTestCellularOutscoresWeakWifi(true); 2843 } 2844 2845 // TODO : migrate to @Parameterized 2846 @Test 2847 public void testCellularOutscoresWeakWifi_CannotTimeShare() throws Exception { 2848 doTestCellularOutscoresWeakWifi(false); 2849 } 2850 2851 public void doTestCellularOutscoresWeakWifi( 2852 final boolean cellRadioTimesharingCapable) throws Exception { 2853 mService.mCellularRadioTimesharingCapable = cellRadioTimesharingCapable; 2854 // Test bringing up validated cellular. 2855 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 2856 ExpectedBroadcast b = registerConnectivityBroadcast(1); 2857 mCellNetworkAgent.connect(true); 2858 b.expectBroadcast(); 2859 verifyActiveNetwork(TRANSPORT_CELLULAR); 2860 // Test bringing up validated WiFi. 2861 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 2862 b = registerConnectivityBroadcast(2); 2863 mWiFiNetworkAgent.connect(true); 2864 b.expectBroadcast(); 2865 verifyActiveNetwork(TRANSPORT_WIFI); 2866 // Test WiFi getting really weak. 2867 b = registerConnectivityBroadcast(2); 2868 mWiFiNetworkAgent.adjustScore(-11); 2869 b.expectBroadcast(); 2870 verifyActiveNetwork(TRANSPORT_CELLULAR); 2871 // Test WiFi restoring signal strength. 2872 b = registerConnectivityBroadcast(2); 2873 mWiFiNetworkAgent.adjustScore(11); 2874 b.expectBroadcast(); 2875 verifyActiveNetwork(TRANSPORT_WIFI); 2876 } 2877 2878 // TODO : migrate to @Parameterized 2879 @Test 2880 public void testReapingNetwork_CanTimeShare() throws Exception { 2881 doTestReapingNetwork(true); 2882 } 2883 2884 // TODO : migrate to @Parameterized 2885 @Test 2886 public void testReapingNetwork_CannotTimeShare() throws Exception { 2887 doTestReapingNetwork(false); 2888 } 2889 2890 public void doTestReapingNetwork( 2891 final boolean cellRadioTimesharingCapable) throws Exception { 2892 mService.mCellularRadioTimesharingCapable = cellRadioTimesharingCapable; 2893 // Test bringing up WiFi without NET_CAPABILITY_INTERNET. 2894 // Expect it to be torn down immediately because it satisfies no requests. 2895 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 2896 mWiFiNetworkAgent.connectWithoutInternet(); 2897 mWiFiNetworkAgent.expectDisconnected(); 2898 // Test bringing up cellular without NET_CAPABILITY_INTERNET. 2899 // Expect it to be torn down immediately because it satisfies no requests. 2900 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 2901 mCellNetworkAgent.connectWithoutInternet(); 2902 mCellNetworkAgent.expectDisconnected(); 2903 // Test bringing up validated WiFi. 2904 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 2905 final ExpectedBroadcast b = expectConnectivityAction(TYPE_WIFI, DetailedState.CONNECTED); 2906 mWiFiNetworkAgent.connect(true); 2907 b.expectBroadcast(); 2908 verifyActiveNetwork(TRANSPORT_WIFI); 2909 // Test bringing up unvalidated cellular. 2910 // Expect it to be torn down because it could never be the highest scoring network 2911 // satisfying the default request even if it validated. 2912 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 2913 mCellNetworkAgent.connect(false); 2914 mCellNetworkAgent.expectDisconnected(); 2915 verifyActiveNetwork(TRANSPORT_WIFI); 2916 mWiFiNetworkAgent.disconnect(); 2917 mWiFiNetworkAgent.expectDisconnected(); 2918 } 2919 2920 // TODO : migrate to @Parameterized 2921 @Test 2922 public void testCellularFallback_CanTimeShare() throws Exception { 2923 doTestCellularFallback(true); 2924 } 2925 2926 // TODO : migrate to @Parameterized 2927 @Test 2928 public void testCellularFallback_CannotTimeShare() throws Exception { 2929 doTestCellularFallback(false); 2930 } 2931 2932 public void doTestCellularFallback( 2933 final boolean cellRadioTimesharingCapable) throws Exception { 2934 mService.mCellularRadioTimesharingCapable = cellRadioTimesharingCapable; 2935 // Test bringing up validated cellular. 2936 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 2937 ExpectedBroadcast b = registerConnectivityBroadcast(1); 2938 mCellNetworkAgent.connect(true); 2939 b.expectBroadcast(); 2940 verifyActiveNetwork(TRANSPORT_CELLULAR); 2941 // Test bringing up validated WiFi. 2942 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 2943 b = registerConnectivityBroadcast(2); 2944 mWiFiNetworkAgent.connect(true); 2945 b.expectBroadcast(); 2946 verifyActiveNetwork(TRANSPORT_WIFI); 2947 // Reevaluate WiFi (it'll instantly fail DNS). 2948 b = registerConnectivityBroadcast(2); 2949 assertTrue(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).hasCapability( 2950 NET_CAPABILITY_VALIDATED)); 2951 mCm.reportBadNetwork(mWiFiNetworkAgent.getNetwork()); 2952 // Should quickly fall back to Cellular. 2953 b.expectBroadcast(); 2954 assertFalse(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).hasCapability( 2955 NET_CAPABILITY_VALIDATED)); 2956 verifyActiveNetwork(TRANSPORT_CELLULAR); 2957 // Reevaluate cellular (it'll instantly fail DNS). 2958 b = registerConnectivityBroadcast(2); 2959 assertTrue(mCm.getNetworkCapabilities(mCellNetworkAgent.getNetwork()).hasCapability( 2960 NET_CAPABILITY_VALIDATED)); 2961 mCm.reportBadNetwork(mCellNetworkAgent.getNetwork()); 2962 // Should quickly fall back to WiFi. 2963 b.expectBroadcast(); 2964 assertFalse(mCm.getNetworkCapabilities(mCellNetworkAgent.getNetwork()).hasCapability( 2965 NET_CAPABILITY_VALIDATED)); 2966 assertFalse(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).hasCapability( 2967 NET_CAPABILITY_VALIDATED)); 2968 verifyActiveNetwork(TRANSPORT_WIFI); 2969 } 2970 2971 // TODO : migrate to @Parameterized 2972 @Test 2973 public void testWiFiFallback_CanTimeShare() throws Exception { 2974 doTestWiFiFallback(true); 2975 } 2976 2977 // TODO : migrate to @Parameterized 2978 @Test 2979 public void testWiFiFallback_CannotTimeShare() throws Exception { 2980 doTestWiFiFallback(false); 2981 } 2982 2983 public void doTestWiFiFallback( 2984 final boolean cellRadioTimesharingCapable) throws Exception { 2985 mService.mCellularRadioTimesharingCapable = cellRadioTimesharingCapable; 2986 // Test bringing up unvalidated WiFi. 2987 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 2988 ExpectedBroadcast b = registerConnectivityBroadcast(1); 2989 mWiFiNetworkAgent.connect(false); 2990 b.expectBroadcast(); 2991 verifyActiveNetwork(TRANSPORT_WIFI); 2992 // Test bringing up validated cellular. 2993 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 2994 b = registerConnectivityBroadcast(2); 2995 mCellNetworkAgent.connect(true); 2996 b.expectBroadcast(); 2997 verifyActiveNetwork(TRANSPORT_CELLULAR); 2998 // Reevaluate cellular (it'll instantly fail DNS). 2999 b = registerConnectivityBroadcast(2); 3000 assertTrue(mCm.getNetworkCapabilities(mCellNetworkAgent.getNetwork()).hasCapability( 3001 NET_CAPABILITY_VALIDATED)); 3002 mCm.reportBadNetwork(mCellNetworkAgent.getNetwork()); 3003 // Should quickly fall back to WiFi. 3004 b.expectBroadcast(); 3005 assertFalse(mCm.getNetworkCapabilities(mCellNetworkAgent.getNetwork()).hasCapability( 3006 NET_CAPABILITY_VALIDATED)); 3007 verifyActiveNetwork(TRANSPORT_WIFI); 3008 } 3009 3010 @Test 3011 public void testRequiresValidation() { 3012 assertTrue(NetworkMonitorUtils.isValidationRequired( 3013 NetworkAgentConfigShimImpl.newInstance(null), 3014 mCm.getDefaultRequest().networkCapabilities)); 3015 } 3016 3017 /** 3018 * Utility NetworkCallback for testing. The caller must explicitly test for all the callbacks 3019 * this class receives, by calling expectCallback() exactly once each time a callback is 3020 * received. assertNoCallback may be called at any time. 3021 */ 3022 private class TestNetworkCallback extends TestableNetworkCallback { 3023 TestNetworkCallback() { 3024 super(TEST_CALLBACK_TIMEOUT_MS); 3025 } 3026 3027 @Override 3028 public void assertNoCallback() { 3029 // TODO: better support this use case in TestableNetworkCallback 3030 waitForIdle(); 3031 assertNoCallback(0 /* timeout */); 3032 } 3033 3034 @Override 3035 public <T extends CallbackEntry> T expectCallback(final KClass<T> type, final HasNetwork n, 3036 final long timeoutMs) { 3037 final T callback = super.expectCallback(type, n, timeoutMs); 3038 if (callback instanceof CallbackEntry.Losing) { 3039 // TODO : move this to the specific test(s) needing this rather than here. 3040 final CallbackEntry.Losing losing = (CallbackEntry.Losing) callback; 3041 final int maxMsToLive = losing.getMaxMsToLive(); 3042 String msg = String.format( 3043 "Invalid linger time value %d, must be between %d and %d", 3044 maxMsToLive, 0, mService.mLingerDelayMs); 3045 assertTrue(msg, 0 <= maxMsToLive && maxMsToLive <= mService.mLingerDelayMs); 3046 } 3047 return callback; 3048 } 3049 } 3050 3051 // Can't be part of TestNetworkCallback because "cannot be declared static; static methods can 3052 // only be declared in a static or top level type". 3053 static void assertNoCallbacks(TestNetworkCallback ... callbacks) { 3054 for (TestNetworkCallback c : callbacks) { 3055 c.assertNoCallback(); 3056 } 3057 } 3058 3059 static void expectOnLost(TestNetworkAgentWrapper network, TestNetworkCallback ... callbacks) { 3060 for (TestNetworkCallback c : callbacks) { 3061 c.expectCallback(CallbackEntry.LOST, network); 3062 } 3063 } 3064 3065 static void expectAvailableCallbacksUnvalidatedWithSpecifier(TestNetworkAgentWrapper network, 3066 NetworkSpecifier specifier, TestNetworkCallback ... callbacks) { 3067 for (TestNetworkCallback c : callbacks) { 3068 c.expectCallback(CallbackEntry.AVAILABLE, network); 3069 c.expectCapabilitiesThat(network, (nc) -> 3070 !nc.hasCapability(NET_CAPABILITY_VALIDATED) 3071 && Objects.equals(specifier, nc.getNetworkSpecifier())); 3072 c.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, network); 3073 c.expectCallback(CallbackEntry.BLOCKED_STATUS, network); 3074 } 3075 } 3076 3077 @Test 3078 public void testStateChangeNetworkCallbacks() throws Exception { 3079 final TestNetworkCallback genericNetworkCallback = new TestNetworkCallback(); 3080 final TestNetworkCallback wifiNetworkCallback = new TestNetworkCallback(); 3081 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback(); 3082 final NetworkRequest genericRequest = new NetworkRequest.Builder() 3083 .clearCapabilities().build(); 3084 final NetworkRequest wifiRequest = new NetworkRequest.Builder() 3085 .addTransportType(TRANSPORT_WIFI).build(); 3086 final NetworkRequest cellRequest = new NetworkRequest.Builder() 3087 .addTransportType(TRANSPORT_CELLULAR).build(); 3088 mCm.registerNetworkCallback(genericRequest, genericNetworkCallback); 3089 mCm.registerNetworkCallback(wifiRequest, wifiNetworkCallback); 3090 mCm.registerNetworkCallback(cellRequest, cellNetworkCallback); 3091 3092 // Test unvalidated networks 3093 ExpectedBroadcast b = registerConnectivityBroadcast(1); 3094 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 3095 mCellNetworkAgent.connect(false); 3096 genericNetworkCallback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent); 3097 cellNetworkCallback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent); 3098 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 3099 b.expectBroadcast(); 3100 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback); 3101 3102 // This should not trigger spurious onAvailable() callbacks, b/21762680. 3103 mCellNetworkAgent.adjustScore(-1); 3104 waitForIdle(); 3105 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback); 3106 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 3107 3108 b = registerConnectivityBroadcast(2); 3109 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3110 mWiFiNetworkAgent.connect(false); 3111 genericNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 3112 wifiNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 3113 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 3114 b.expectBroadcast(); 3115 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback); 3116 3117 b = registerConnectivityBroadcast(2); 3118 mWiFiNetworkAgent.disconnect(); 3119 genericNetworkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 3120 wifiNetworkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 3121 cellNetworkCallback.assertNoCallback(); 3122 b.expectBroadcast(); 3123 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback); 3124 3125 b = registerConnectivityBroadcast(1); 3126 mCellNetworkAgent.disconnect(); 3127 genericNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 3128 cellNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 3129 b.expectBroadcast(); 3130 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback); 3131 3132 // Test validated networks 3133 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 3134 mCellNetworkAgent.connect(true); 3135 genericNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 3136 cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 3137 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 3138 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback); 3139 3140 // This should not trigger spurious onAvailable() callbacks, b/21762680. 3141 mCellNetworkAgent.adjustScore(-1); 3142 waitForIdle(); 3143 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback); 3144 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 3145 3146 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3147 mWiFiNetworkAgent.connect(true); 3148 genericNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 3149 genericNetworkCallback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent); 3150 genericNetworkCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent); 3151 wifiNetworkCallback.expectAvailableThenValidatedCallbacks(mWiFiNetworkAgent); 3152 cellNetworkCallback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent); 3153 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 3154 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback); 3155 3156 mWiFiNetworkAgent.disconnect(); 3157 genericNetworkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 3158 wifiNetworkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 3159 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback); 3160 3161 mCellNetworkAgent.disconnect(); 3162 genericNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 3163 cellNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 3164 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback); 3165 } 3166 3167 private void doNetworkCallbacksSanitizationTest(boolean sanitized) throws Exception { 3168 final TestNetworkCallback callback = new TestNetworkCallback(); 3169 final TestNetworkCallback defaultCallback = new TestNetworkCallback(); 3170 final NetworkRequest wifiRequest = new NetworkRequest.Builder() 3171 .addTransportType(TRANSPORT_WIFI).build(); 3172 mCm.registerNetworkCallback(wifiRequest, callback); 3173 mCm.registerDefaultNetworkCallback(defaultCallback); 3174 3175 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3176 mWiFiNetworkAgent.connect(false); 3177 callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 3178 defaultCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 3179 3180 final LinkProperties newLp = new LinkProperties(); 3181 final Uri capportUrl = Uri.parse("https://capport.example.com/api"); 3182 final CaptivePortalData capportData = new CaptivePortalData.Builder() 3183 .setCaptive(true).build(); 3184 3185 final Uri expectedCapportUrl = sanitized ? null : capportUrl; 3186 newLp.setCaptivePortalApiUrl(capportUrl); 3187 mWiFiNetworkAgent.sendLinkProperties(newLp); 3188 callback.expectLinkPropertiesThat(mWiFiNetworkAgent, lp -> 3189 Objects.equals(expectedCapportUrl, lp.getCaptivePortalApiUrl())); 3190 defaultCallback.expectLinkPropertiesThat(mWiFiNetworkAgent, lp -> 3191 Objects.equals(expectedCapportUrl, lp.getCaptivePortalApiUrl())); 3192 3193 final CaptivePortalData expectedCapportData = sanitized ? null : capportData; 3194 mWiFiNetworkAgent.notifyCapportApiDataChanged(capportData); 3195 callback.expectLinkPropertiesThat(mWiFiNetworkAgent, lp -> 3196 Objects.equals(expectedCapportData, lp.getCaptivePortalData())); 3197 defaultCallback.expectLinkPropertiesThat(mWiFiNetworkAgent, lp -> 3198 Objects.equals(expectedCapportData, lp.getCaptivePortalData())); 3199 3200 final LinkProperties lp = mCm.getLinkProperties(mWiFiNetworkAgent.getNetwork()); 3201 assertEquals(expectedCapportUrl, lp.getCaptivePortalApiUrl()); 3202 assertEquals(expectedCapportData, lp.getCaptivePortalData()); 3203 } 3204 3205 @Test 3206 public void networkCallbacksSanitizationTest_Sanitize() throws Exception { 3207 mServiceContext.setPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, 3208 PERMISSION_DENIED); 3209 mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_DENIED); 3210 doNetworkCallbacksSanitizationTest(true /* sanitized */); 3211 } 3212 3213 @Test 3214 public void networkCallbacksSanitizationTest_NoSanitize_NetworkStack() throws Exception { 3215 mServiceContext.setPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, 3216 PERMISSION_GRANTED); 3217 mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_DENIED); 3218 doNetworkCallbacksSanitizationTest(false /* sanitized */); 3219 } 3220 3221 @Test 3222 public void networkCallbacksSanitizationTest_NoSanitize_Settings() throws Exception { 3223 mServiceContext.setPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, 3224 PERMISSION_DENIED); 3225 mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_GRANTED); 3226 doNetworkCallbacksSanitizationTest(false /* sanitized */); 3227 } 3228 3229 @Test 3230 public void testOwnerUidCannotChange() throws Exception { 3231 final NetworkCapabilities ncTemplate = new NetworkCapabilities(); 3232 final int originalOwnerUid = Process.myUid(); 3233 ncTemplate.setOwnerUid(originalOwnerUid); 3234 3235 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, new LinkProperties(), 3236 ncTemplate); 3237 mWiFiNetworkAgent.connect(false); 3238 waitForIdle(); 3239 3240 // Send ConnectivityService an update to the mWiFiNetworkAgent's capabilities that changes 3241 // the owner UID and an unrelated capability. 3242 NetworkCapabilities agentCapabilities = mWiFiNetworkAgent.getNetworkCapabilities(); 3243 assertEquals(originalOwnerUid, agentCapabilities.getOwnerUid()); 3244 agentCapabilities.setOwnerUid(42); 3245 assertFalse(agentCapabilities.hasCapability(NET_CAPABILITY_NOT_CONGESTED)); 3246 agentCapabilities.addCapability(NET_CAPABILITY_NOT_CONGESTED); 3247 mWiFiNetworkAgent.setNetworkCapabilities(agentCapabilities, true); 3248 waitForIdle(); 3249 3250 // Owner UIDs are not visible without location permission. 3251 setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION, 3252 Manifest.permission.ACCESS_FINE_LOCATION); 3253 3254 // Check that the capability change has been applied but the owner UID is not modified. 3255 NetworkCapabilities nc = mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()); 3256 assertEquals(originalOwnerUid, nc.getOwnerUid()); 3257 assertTrue(nc.hasCapability(NET_CAPABILITY_NOT_CONGESTED)); 3258 } 3259 3260 @Test 3261 public void testMultipleLingering() throws Exception { 3262 // This test would be flaky with the default 120ms timer: that is short enough that 3263 // lingered networks are torn down before assertions can be run. We don't want to mock the 3264 // lingering timer to keep the WakeupMessage logic realistic: this has already proven useful 3265 // in detecting races. 3266 mService.mLingerDelayMs = 300; 3267 3268 NetworkRequest request = new NetworkRequest.Builder() 3269 .clearCapabilities().addCapability(NET_CAPABILITY_NOT_METERED) 3270 .build(); 3271 TestNetworkCallback callback = new TestNetworkCallback(); 3272 mCm.registerNetworkCallback(request, callback); 3273 3274 TestNetworkCallback defaultCallback = new TestNetworkCallback(); 3275 mCm.registerDefaultNetworkCallback(defaultCallback); 3276 3277 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 3278 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3279 mEthernetNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_ETHERNET); 3280 3281 mCellNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED); 3282 mWiFiNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED); 3283 mEthernetNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED); 3284 3285 mCellNetworkAgent.connect(true); 3286 callback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 3287 defaultCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 3288 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 3289 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 3290 3291 mWiFiNetworkAgent.connect(true); 3292 // We get AVAILABLE on wifi when wifi connects and satisfies our unmetered request. 3293 // We then get LOSING when wifi validates and cell is outscored. 3294 callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 3295 // TODO: Investigate sending validated before losing. 3296 callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent); 3297 callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent); 3298 defaultCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent); 3299 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 3300 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 3301 3302 mEthernetNetworkAgent.connect(true); 3303 callback.expectAvailableCallbacksUnvalidated(mEthernetNetworkAgent); 3304 // TODO: Investigate sending validated before losing. 3305 callback.expectCallback(CallbackEntry.LOSING, mWiFiNetworkAgent); 3306 callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mEthernetNetworkAgent); 3307 defaultCallback.expectAvailableDoubleValidatedCallbacks(mEthernetNetworkAgent); 3308 assertEquals(mEthernetNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 3309 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 3310 3311 mEthernetNetworkAgent.disconnect(); 3312 callback.expectCallback(CallbackEntry.LOST, mEthernetNetworkAgent); 3313 defaultCallback.expectCallback(CallbackEntry.LOST, mEthernetNetworkAgent); 3314 defaultCallback.expectAvailableCallbacksValidated(mWiFiNetworkAgent); 3315 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 3316 3317 for (int i = 0; i < 4; i++) { 3318 TestNetworkAgentWrapper oldNetwork, newNetwork; 3319 if (i % 2 == 0) { 3320 mWiFiNetworkAgent.adjustScore(-15); 3321 oldNetwork = mWiFiNetworkAgent; 3322 newNetwork = mCellNetworkAgent; 3323 } else { 3324 mWiFiNetworkAgent.adjustScore(15); 3325 oldNetwork = mCellNetworkAgent; 3326 newNetwork = mWiFiNetworkAgent; 3327 3328 } 3329 callback.expectCallback(CallbackEntry.LOSING, oldNetwork); 3330 // TODO: should we send an AVAILABLE callback to newNetwork, to indicate that it is no 3331 // longer lingering? 3332 defaultCallback.expectAvailableCallbacksValidated(newNetwork); 3333 assertEquals(newNetwork.getNetwork(), mCm.getActiveNetwork()); 3334 } 3335 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 3336 3337 // Verify that if a network no longer satisfies a request, we send LOST and not LOSING, even 3338 // if the network is still up. 3339 mWiFiNetworkAgent.removeCapability(NET_CAPABILITY_NOT_METERED); 3340 // We expect a notification about the capabilities change, and nothing else. 3341 defaultCallback.expectCapabilitiesWithout(NET_CAPABILITY_NOT_METERED, mWiFiNetworkAgent); 3342 defaultCallback.assertNoCallback(); 3343 callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 3344 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 3345 3346 // Wifi no longer satisfies our listen, which is for an unmetered network. 3347 // But because its score is 55, it's still up (and the default network). 3348 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 3349 3350 // Disconnect our test networks. 3351 mWiFiNetworkAgent.disconnect(); 3352 defaultCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 3353 defaultCallback.expectAvailableCallbacksValidated(mCellNetworkAgent); 3354 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 3355 mCellNetworkAgent.disconnect(); 3356 defaultCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 3357 waitForIdle(); 3358 assertEquals(null, mCm.getActiveNetwork()); 3359 3360 mCm.unregisterNetworkCallback(callback); 3361 waitForIdle(); 3362 3363 // Check that a network is only lingered or torn down if it would not satisfy a request even 3364 // if it validated. 3365 request = new NetworkRequest.Builder().clearCapabilities().build(); 3366 callback = new TestNetworkCallback(); 3367 3368 mCm.registerNetworkCallback(request, callback); 3369 3370 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 3371 mCellNetworkAgent.connect(false); // Score: 10 3372 callback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent); 3373 defaultCallback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent); 3374 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 3375 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 3376 3377 // Bring up wifi with a score of 20. 3378 // Cell stays up because it would satisfy the default request if it validated. 3379 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3380 mWiFiNetworkAgent.connect(false); // Score: 20 3381 callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 3382 defaultCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 3383 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 3384 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 3385 3386 mWiFiNetworkAgent.disconnect(); 3387 callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 3388 defaultCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 3389 defaultCallback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent); 3390 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 3391 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 3392 3393 // Bring up wifi, then validate it. Previous versions would immediately tear down cell, but 3394 // it's arguably correct to linger it, since it was the default network before it validated. 3395 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3396 mWiFiNetworkAgent.connect(true); 3397 callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 3398 // TODO: Investigate sending validated before losing. 3399 callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent); 3400 callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent); 3401 defaultCallback.expectAvailableThenValidatedCallbacks(mWiFiNetworkAgent); 3402 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 3403 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 3404 3405 mWiFiNetworkAgent.disconnect(); 3406 callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 3407 defaultCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 3408 defaultCallback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent); 3409 mCellNetworkAgent.disconnect(); 3410 callback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 3411 defaultCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 3412 waitForIdle(); 3413 assertEquals(null, mCm.getActiveNetwork()); 3414 3415 // If a network is lingering, and we add and remove a request from it, resume lingering. 3416 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 3417 mCellNetworkAgent.connect(true); 3418 callback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 3419 defaultCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 3420 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 3421 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3422 mWiFiNetworkAgent.connect(true); 3423 defaultCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent); 3424 callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 3425 // TODO: Investigate sending validated before losing. 3426 callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent); 3427 callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent); 3428 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 3429 3430 NetworkRequest cellRequest = new NetworkRequest.Builder() 3431 .addTransportType(TRANSPORT_CELLULAR).build(); 3432 NetworkCallback noopCallback = new NetworkCallback(); 3433 mCm.requestNetwork(cellRequest, noopCallback); 3434 // TODO: should this cause an AVAILABLE callback, to indicate that the network is no longer 3435 // lingering? 3436 mCm.unregisterNetworkCallback(noopCallback); 3437 callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent); 3438 3439 // Similar to the above: lingering can start even after the lingered request is removed. 3440 // Disconnect wifi and switch to cell. 3441 mWiFiNetworkAgent.disconnect(); 3442 callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 3443 defaultCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 3444 defaultCallback.expectAvailableCallbacksValidated(mCellNetworkAgent); 3445 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 3446 3447 // Cell is now the default network. Pin it with a cell-specific request. 3448 noopCallback = new NetworkCallback(); // Can't reuse NetworkCallbacks. http://b/20701525 3449 mCm.requestNetwork(cellRequest, noopCallback); 3450 3451 // Now connect wifi, and expect it to become the default network. 3452 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3453 mWiFiNetworkAgent.connect(true); 3454 callback.expectAvailableThenValidatedCallbacks(mWiFiNetworkAgent); 3455 defaultCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent); 3456 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 3457 // The default request is lingering on cell, but nothing happens to cell, and we send no 3458 // callbacks for it, because it's kept up by cellRequest. 3459 callback.assertNoCallback(); 3460 // Now unregister cellRequest and expect cell to start lingering. 3461 mCm.unregisterNetworkCallback(noopCallback); 3462 callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent); 3463 3464 // Let linger run its course. 3465 callback.assertNoCallback(); 3466 final int lingerTimeoutMs = mService.mLingerDelayMs + mService.mLingerDelayMs / 4; 3467 callback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent, lingerTimeoutMs); 3468 3469 // Register a TRACK_DEFAULT request and check that it does not affect lingering. 3470 TestNetworkCallback trackDefaultCallback = new TestNetworkCallback(); 3471 mCm.registerDefaultNetworkCallback(trackDefaultCallback); 3472 trackDefaultCallback.expectAvailableCallbacksValidated(mWiFiNetworkAgent); 3473 mEthernetNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_ETHERNET); 3474 mEthernetNetworkAgent.connect(true); 3475 callback.expectAvailableCallbacksUnvalidated(mEthernetNetworkAgent); 3476 callback.expectCallback(CallbackEntry.LOSING, mWiFiNetworkAgent); 3477 callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mEthernetNetworkAgent); 3478 trackDefaultCallback.expectAvailableDoubleValidatedCallbacks(mEthernetNetworkAgent); 3479 defaultCallback.expectAvailableDoubleValidatedCallbacks(mEthernetNetworkAgent); 3480 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 3481 3482 // Let linger run its course. 3483 callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent, lingerTimeoutMs); 3484 3485 // Clean up. 3486 mEthernetNetworkAgent.disconnect(); 3487 callback.expectCallback(CallbackEntry.LOST, mEthernetNetworkAgent); 3488 defaultCallback.expectCallback(CallbackEntry.LOST, mEthernetNetworkAgent); 3489 trackDefaultCallback.expectCallback(CallbackEntry.LOST, mEthernetNetworkAgent); 3490 3491 mCm.unregisterNetworkCallback(callback); 3492 mCm.unregisterNetworkCallback(defaultCallback); 3493 mCm.unregisterNetworkCallback(trackDefaultCallback); 3494 } 3495 3496 private void grantUsingBackgroundNetworksPermissionForUid(final int uid) throws Exception { 3497 grantUsingBackgroundNetworksPermissionForUid(uid, mContext.getPackageName()); 3498 } 3499 3500 private void grantUsingBackgroundNetworksPermissionForUid( 3501 final int uid, final String packageName) throws Exception { 3502 doReturn(buildPackageInfo(true /* hasSystemPermission */, uid)).when(mPackageManager) 3503 .getPackageInfo(eq(packageName), eq(GET_PERMISSIONS)); 3504 mService.mPermissionMonitor.onPackageAdded(packageName, uid); 3505 } 3506 3507 @Test 3508 public void testNetworkGoesIntoBackgroundAfterLinger() throws Exception { 3509 setAlwaysOnNetworks(true); 3510 grantUsingBackgroundNetworksPermissionForUid(Binder.getCallingUid()); 3511 NetworkRequest request = new NetworkRequest.Builder() 3512 .clearCapabilities() 3513 .build(); 3514 TestNetworkCallback callback = new TestNetworkCallback(); 3515 mCm.registerNetworkCallback(request, callback); 3516 3517 TestNetworkCallback defaultCallback = new TestNetworkCallback(); 3518 mCm.registerDefaultNetworkCallback(defaultCallback); 3519 3520 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 3521 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3522 3523 mCellNetworkAgent.connect(true); 3524 callback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 3525 defaultCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 3526 3527 // Wifi comes up and cell lingers. 3528 mWiFiNetworkAgent.connect(true); 3529 defaultCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent); 3530 callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 3531 callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent); 3532 callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent); 3533 3534 // File a request for cellular, then release it. 3535 NetworkRequest cellRequest = new NetworkRequest.Builder() 3536 .addTransportType(TRANSPORT_CELLULAR).build(); 3537 NetworkCallback noopCallback = new NetworkCallback(); 3538 mCm.requestNetwork(cellRequest, noopCallback); 3539 mCm.unregisterNetworkCallback(noopCallback); 3540 callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent); 3541 3542 // Let linger run its course. 3543 callback.assertNoCallback(); 3544 final int lingerTimeoutMs = TEST_LINGER_DELAY_MS + TEST_LINGER_DELAY_MS / 4; 3545 callback.expectCapabilitiesWithout(NET_CAPABILITY_FOREGROUND, mCellNetworkAgent, 3546 lingerTimeoutMs); 3547 3548 // Clean up. 3549 mCm.unregisterNetworkCallback(defaultCallback); 3550 mCm.unregisterNetworkCallback(callback); 3551 } 3552 3553 private NativeNetworkConfig nativeNetworkConfigPhysical(int netId, int permission) { 3554 return new NativeNetworkConfig(netId, NativeNetworkType.PHYSICAL, permission, 3555 /*secure=*/ false, VpnManager.TYPE_VPN_NONE, /*excludeLocalRoutes=*/ false); 3556 } 3557 3558 private NativeNetworkConfig nativeNetworkConfigVpn(int netId, boolean secure, int vpnType) { 3559 return new NativeNetworkConfig(netId, NativeNetworkType.VIRTUAL, INetd.PERMISSION_NONE, 3560 secure, vpnType, /*excludeLocalRoutes=*/ false); 3561 } 3562 3563 @Test 3564 public void testNetworkAgentCallbacks() throws Exception { 3565 // Keeps track of the order of events that happen in this test. 3566 final LinkedBlockingQueue<String> eventOrder = new LinkedBlockingQueue<>(); 3567 3568 final NetworkRequest request = new NetworkRequest.Builder() 3569 .addTransportType(TRANSPORT_WIFI).build(); 3570 final TestNetworkCallback callback = new TestNetworkCallback(); 3571 final AtomicReference<Network> wifiNetwork = new AtomicReference<>(); 3572 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3573 3574 // Expectations for state when various callbacks fire. These expectations run on the handler 3575 // thread and not on the test thread because they need to prevent the handler thread from 3576 // advancing while they examine state. 3577 3578 // 1. When onCreated fires, netd has been told to create the network. 3579 mWiFiNetworkAgent.setCreatedCallback(() -> { 3580 eventOrder.offer("onNetworkCreated"); 3581 wifiNetwork.set(mWiFiNetworkAgent.getNetwork()); 3582 assertNotNull(wifiNetwork.get()); 3583 try { 3584 verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( 3585 wifiNetwork.get().getNetId(), INetd.PERMISSION_NONE)); 3586 } catch (RemoteException impossible) { 3587 fail(); 3588 } 3589 }); 3590 3591 // 2. onNetworkUnwanted isn't precisely ordered with respect to any particular events. Just 3592 // check that it is fired at some point after disconnect. 3593 mWiFiNetworkAgent.setUnwantedCallback(() -> eventOrder.offer("onNetworkUnwanted")); 3594 3595 // 3. While the teardown timer is running, connectivity APIs report the network is gone, but 3596 // netd has not yet been told to destroy it. 3597 final Runnable duringTeardown = () -> { 3598 eventOrder.offer("timePasses"); 3599 assertNull(mCm.getLinkProperties(wifiNetwork.get())); 3600 try { 3601 verify(mMockNetd, never()).networkDestroy(wifiNetwork.get().getNetId()); 3602 } catch (RemoteException impossible) { 3603 fail(); 3604 } 3605 }; 3606 3607 // 4. After onNetworkDisconnected is called, connectivity APIs report the network is gone, 3608 // and netd has been told to destroy it. 3609 mWiFiNetworkAgent.setDisconnectedCallback(() -> { 3610 eventOrder.offer("onNetworkDisconnected"); 3611 assertNull(mCm.getLinkProperties(wifiNetwork.get())); 3612 try { 3613 verify(mMockNetd).networkDestroy(wifiNetwork.get().getNetId()); 3614 } catch (RemoteException impossible) { 3615 fail(); 3616 } 3617 }); 3618 3619 // Connect a network, and file a request for it after it has come up, to ensure the nascent 3620 // timer is cleared and the test does not have to wait for it. Filing the request after the 3621 // network has come up is necessary because ConnectivityService does not appear to clear the 3622 // nascent timer if the first request satisfied by the network was filed before the network 3623 // connected. 3624 // TODO: fix this bug, file the request before connecting, and remove the waitForIdle. 3625 mWiFiNetworkAgent.connectWithoutInternet(); 3626 waitForIdle(); 3627 mCm.requestNetwork(request, callback); 3628 callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 3629 3630 // Set teardown delay and make sure CS has processed it. 3631 mWiFiNetworkAgent.getNetworkAgent().setTeardownDelayMillis(300); 3632 waitForIdle(); 3633 3634 // Post the duringTeardown lambda to the handler so it fires while teardown is in progress. 3635 // The delay must be long enough it will run after the unregisterNetworkCallback has torn 3636 // down the network and started the teardown timer, and short enough that the lambda is 3637 // scheduled to run before the teardown timer. 3638 final Handler h = new Handler(mCsHandlerThread.getLooper()); 3639 h.postDelayed(duringTeardown, 150); 3640 3641 // Disconnect the network and check that events happened in the right order. 3642 mCm.unregisterNetworkCallback(callback); 3643 assertEquals("onNetworkCreated", eventOrder.poll(TIMEOUT_MS, TimeUnit.MILLISECONDS)); 3644 assertEquals("onNetworkUnwanted", eventOrder.poll(TIMEOUT_MS, TimeUnit.MILLISECONDS)); 3645 assertEquals("timePasses", eventOrder.poll(TIMEOUT_MS, TimeUnit.MILLISECONDS)); 3646 assertEquals("onNetworkDisconnected", eventOrder.poll(TIMEOUT_MS, TimeUnit.MILLISECONDS)); 3647 3648 mCm.unregisterNetworkCallback(callback); 3649 } 3650 3651 @Test 3652 public void testExplicitlySelected() throws Exception { 3653 NetworkRequest request = new NetworkRequest.Builder() 3654 .clearCapabilities().addCapability(NET_CAPABILITY_INTERNET) 3655 .build(); 3656 TestNetworkCallback callback = new TestNetworkCallback(); 3657 mCm.registerNetworkCallback(request, callback); 3658 3659 // Bring up validated cell. 3660 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 3661 mCellNetworkAgent.connect(true); 3662 callback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 3663 3664 // Bring up unvalidated wifi with explicitlySelected=true. 3665 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3666 mWiFiNetworkAgent.explicitlySelected(true, false); 3667 mWiFiNetworkAgent.connect(false); 3668 callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 3669 3670 // Cell Remains the default. 3671 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 3672 3673 // Lower wifi's score to below than cell, and check that it doesn't disconnect because 3674 // it's explicitly selected. 3675 mWiFiNetworkAgent.adjustScore(-40); 3676 mWiFiNetworkAgent.adjustScore(40); 3677 callback.assertNoCallback(); 3678 3679 // If the user chooses yes on the "No Internet access, stay connected?" dialog, we switch to 3680 // wifi even though it's unvalidated. 3681 mCm.setAcceptUnvalidated(mWiFiNetworkAgent.getNetwork(), true, false); 3682 callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent); 3683 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 3684 3685 // Disconnect wifi, and then reconnect, again with explicitlySelected=true. 3686 mWiFiNetworkAgent.disconnect(); 3687 callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 3688 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3689 mWiFiNetworkAgent.explicitlySelected(true, false); 3690 mWiFiNetworkAgent.connect(false); 3691 callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 3692 3693 // If the user chooses no on the "No Internet access, stay connected?" dialog, we ask the 3694 // network to disconnect. 3695 mCm.setAcceptUnvalidated(mWiFiNetworkAgent.getNetwork(), false, false); 3696 callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 3697 3698 // Reconnect, again with explicitlySelected=true, but this time validate. 3699 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3700 mWiFiNetworkAgent.explicitlySelected(true, false); 3701 mWiFiNetworkAgent.connect(true); 3702 callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 3703 callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent); 3704 callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent); 3705 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 3706 3707 mEthernetNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_ETHERNET); 3708 mEthernetNetworkAgent.connect(true); 3709 callback.expectAvailableCallbacksUnvalidated(mEthernetNetworkAgent); 3710 callback.expectCallback(CallbackEntry.LOSING, mWiFiNetworkAgent); 3711 callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mEthernetNetworkAgent); 3712 assertEquals(mEthernetNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 3713 callback.assertNoCallback(); 3714 3715 // Disconnect wifi, and then reconnect as if the user had selected "yes, don't ask again" 3716 // (i.e., with explicitlySelected=true and acceptUnvalidated=true). Expect to switch to 3717 // wifi immediately. 3718 mWiFiNetworkAgent.disconnect(); 3719 callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 3720 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3721 mWiFiNetworkAgent.explicitlySelected(true, true); 3722 mWiFiNetworkAgent.connect(false); 3723 callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 3724 callback.expectCallback(CallbackEntry.LOSING, mEthernetNetworkAgent); 3725 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 3726 mEthernetNetworkAgent.disconnect(); 3727 callback.expectCallback(CallbackEntry.LOST, mEthernetNetworkAgent); 3728 3729 // Disconnect and reconnect with explicitlySelected=false and acceptUnvalidated=true. 3730 // Check that the network is not scored specially and that the device prefers cell data. 3731 mWiFiNetworkAgent.disconnect(); 3732 callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 3733 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3734 mWiFiNetworkAgent.explicitlySelected(false, true); 3735 mWiFiNetworkAgent.connect(false); 3736 callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 3737 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 3738 3739 // Clean up. 3740 mWiFiNetworkAgent.disconnect(); 3741 mCellNetworkAgent.disconnect(); 3742 3743 callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 3744 callback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 3745 } 3746 3747 private void tryNetworkFactoryRequests(int capability) throws Exception { 3748 // Verify NOT_RESTRICTED is set appropriately 3749 final NetworkCapabilities nc = new NetworkRequest.Builder().addCapability(capability) 3750 .build().networkCapabilities; 3751 if (capability == NET_CAPABILITY_CBS || capability == NET_CAPABILITY_DUN 3752 || capability == NET_CAPABILITY_EIMS || capability == NET_CAPABILITY_FOTA 3753 || capability == NET_CAPABILITY_IA || capability == NET_CAPABILITY_IMS 3754 || capability == NET_CAPABILITY_RCS || capability == NET_CAPABILITY_XCAP 3755 || capability == NET_CAPABILITY_VSIM || capability == NET_CAPABILITY_BIP 3756 || capability == NET_CAPABILITY_ENTERPRISE || capability == NET_CAPABILITY_MMTEL) { 3757 assertFalse(nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)); 3758 } else { 3759 assertTrue(nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)); 3760 } 3761 3762 NetworkCapabilities filter = new NetworkCapabilities(); 3763 filter.addTransportType(TRANSPORT_CELLULAR); 3764 filter.addCapability(capability); 3765 // Add NOT_VCN_MANAGED capability into filter unconditionally since some requests will add 3766 // NOT_VCN_MANAGED automatically but not for NetworkCapabilities, 3767 // see {@code NetworkCapabilities#deduceNotVcnManagedCapability} for more details. 3768 filter.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED); 3769 final HandlerThread handlerThread = new HandlerThread("testNetworkFactoryRequests"); 3770 handlerThread.start(); 3771 final MockNetworkFactory testFactory = new MockNetworkFactory(handlerThread.getLooper(), 3772 mServiceContext, "testFactory", filter, mCsHandlerThread); 3773 testFactory.setScoreFilter(45); 3774 testFactory.register(); 3775 3776 final NetworkCallback networkCallback; 3777 if (capability != NET_CAPABILITY_INTERNET) { 3778 // If the capability passed in argument is part of the default request, then the 3779 // factory will see the default request. Otherwise the filter will prevent the 3780 // factory from seeing it. In that case, add a request so it can be tested. 3781 assertFalse(testFactory.getMyStartRequested()); 3782 NetworkRequest request = new NetworkRequest.Builder().addCapability(capability).build(); 3783 networkCallback = new NetworkCallback(); 3784 mCm.requestNetwork(request, networkCallback); 3785 } else { 3786 networkCallback = null; 3787 } 3788 testFactory.expectRequestAdd(); 3789 testFactory.assertRequestCountEquals(1); 3790 assertTrue(testFactory.getMyStartRequested()); 3791 3792 // Now bring in a higher scored network. 3793 TestNetworkAgentWrapper testAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 3794 // When testAgent connects, because of its score (50 legacy int / cell transport) 3795 // it will beat or equal the testFactory's offer, so the request will be removed. 3796 // Note the agent as validated only if the capability is INTERNET, as it's the only case 3797 // where it makes sense. 3798 testAgent.connect(NET_CAPABILITY_INTERNET == capability /* validated */); 3799 testAgent.addCapability(capability); 3800 testFactory.expectRequestRemove(); 3801 testFactory.assertRequestCountEquals(0); 3802 assertFalse(testFactory.getMyStartRequested()); 3803 3804 // Add a request and make sure it's not sent to the factory, because the agent 3805 // is satisfying it better. 3806 final NetworkCallback cb = new ConnectivityManager.NetworkCallback(); 3807 mCm.requestNetwork(new NetworkRequest.Builder().addCapability(capability).build(), cb); 3808 expectNoRequestChanged(testFactory); 3809 testFactory.assertRequestCountEquals(0); 3810 assertFalse(testFactory.getMyStartRequested()); 3811 3812 // If using legacy scores, make the test agent weak enough to have the exact same score as 3813 // the factory (50 for cell - 5 adjustment). Make sure the factory doesn't see the request. 3814 // If not using legacy score, this is a no-op and the "same score removes request" behavior 3815 // has already been tested above. 3816 testAgent.adjustScore(-5); 3817 expectNoRequestChanged(testFactory); 3818 assertFalse(testFactory.getMyStartRequested()); 3819 3820 // Make the test agent weak enough that the factory will see the two requests (the one that 3821 // was just sent, and either the default one or the one sent at the top of this test if 3822 // the default won't be seen). 3823 testAgent.setScore(new NetworkScore.Builder().setLegacyInt(2).setExiting(true).build()); 3824 testFactory.expectRequestAdds(2); 3825 testFactory.assertRequestCountEquals(2); 3826 assertTrue(testFactory.getMyStartRequested()); 3827 3828 // Now unregister and make sure the request is removed. 3829 mCm.unregisterNetworkCallback(cb); 3830 testFactory.expectRequestRemove(); 3831 3832 // Bring in a bunch of requests. 3833 assertEquals(1, testFactory.getMyRequestCount()); 3834 ConnectivityManager.NetworkCallback[] networkCallbacks = 3835 new ConnectivityManager.NetworkCallback[10]; 3836 for (int i = 0; i< networkCallbacks.length; i++) { 3837 networkCallbacks[i] = new ConnectivityManager.NetworkCallback(); 3838 NetworkRequest.Builder builder = new NetworkRequest.Builder(); 3839 builder.addCapability(capability); 3840 mCm.requestNetwork(builder.build(), networkCallbacks[i]); 3841 } 3842 testFactory.expectRequestAdds(10); 3843 testFactory.assertRequestCountEquals(11); // +1 for the default/test specific request 3844 assertTrue(testFactory.getMyStartRequested()); 3845 3846 // Remove the requests. 3847 for (int i = 0; i < networkCallbacks.length; i++) { 3848 mCm.unregisterNetworkCallback(networkCallbacks[i]); 3849 } 3850 testFactory.expectRequestRemoves(10); 3851 testFactory.assertRequestCountEquals(1); 3852 assertTrue(testFactory.getMyStartRequested()); 3853 3854 // Adjust the agent score up again. Expect the request to be withdrawn. 3855 testAgent.setScore(new NetworkScore.Builder().setLegacyInt(50).build()); 3856 testFactory.expectRequestRemove(); 3857 testFactory.assertRequestCountEquals(0); 3858 assertFalse(testFactory.getMyStartRequested()); 3859 3860 // Drop the higher scored network. 3861 testAgent.disconnect(); 3862 testFactory.expectRequestAdd(); 3863 testFactory.assertRequestCountEquals(1); 3864 assertEquals(1, testFactory.getMyRequestCount()); 3865 assertTrue(testFactory.getMyStartRequested()); 3866 3867 testFactory.terminate(); 3868 testFactory.assertNoRequestChanged(); 3869 if (networkCallback != null) mCm.unregisterNetworkCallback(networkCallback); 3870 handlerThread.quit(); 3871 } 3872 3873 @Test 3874 public void testNetworkFactoryRequests() throws Exception { 3875 tryNetworkFactoryRequests(NET_CAPABILITY_MMS); 3876 tryNetworkFactoryRequests(NET_CAPABILITY_SUPL); 3877 tryNetworkFactoryRequests(NET_CAPABILITY_DUN); 3878 tryNetworkFactoryRequests(NET_CAPABILITY_FOTA); 3879 tryNetworkFactoryRequests(NET_CAPABILITY_IMS); 3880 tryNetworkFactoryRequests(NET_CAPABILITY_CBS); 3881 tryNetworkFactoryRequests(NET_CAPABILITY_WIFI_P2P); 3882 tryNetworkFactoryRequests(NET_CAPABILITY_IA); 3883 tryNetworkFactoryRequests(NET_CAPABILITY_RCS); 3884 tryNetworkFactoryRequests(NET_CAPABILITY_MMTEL); 3885 tryNetworkFactoryRequests(NET_CAPABILITY_XCAP); 3886 tryNetworkFactoryRequests(NET_CAPABILITY_ENTERPRISE); 3887 tryNetworkFactoryRequests(NET_CAPABILITY_EIMS); 3888 tryNetworkFactoryRequests(NET_CAPABILITY_NOT_METERED); 3889 tryNetworkFactoryRequests(NET_CAPABILITY_INTERNET); 3890 tryNetworkFactoryRequests(NET_CAPABILITY_TRUSTED); 3891 tryNetworkFactoryRequests(NET_CAPABILITY_NOT_VPN); 3892 tryNetworkFactoryRequests(NET_CAPABILITY_VSIM); 3893 tryNetworkFactoryRequests(NET_CAPABILITY_BIP); 3894 // Skipping VALIDATED and CAPTIVE_PORTAL as they're disallowed. 3895 } 3896 3897 @Test 3898 public void testRegisterIgnoringScore() throws Exception { 3899 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3900 mWiFiNetworkAgent.setScore(new NetworkScore.Builder().setLegacyInt(90).build()); 3901 mWiFiNetworkAgent.connect(true /* validated */); 3902 3903 // Make sure the factory sees the default network 3904 final NetworkCapabilities filter = new NetworkCapabilities(); 3905 filter.addTransportType(TRANSPORT_CELLULAR); 3906 filter.addCapability(NET_CAPABILITY_INTERNET); 3907 filter.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED); 3908 final HandlerThread handlerThread = new HandlerThread("testNetworkFactoryRequests"); 3909 handlerThread.start(); 3910 final MockNetworkFactory testFactory = new MockNetworkFactory(handlerThread.getLooper(), 3911 mServiceContext, "testFactory", filter, mCsHandlerThread); 3912 testFactory.register(); 3913 3914 final MockNetworkFactory testFactoryAll = new MockNetworkFactory(handlerThread.getLooper(), 3915 mServiceContext, "testFactoryAll", filter, mCsHandlerThread); 3916 testFactoryAll.registerIgnoringScore(); 3917 3918 // The regular test factory should not see the request, because WiFi is stronger than cell. 3919 expectNoRequestChanged(testFactory); 3920 // With ignoringScore though the request is seen. 3921 testFactoryAll.expectRequestAdd(); 3922 3923 // The legacy int will be ignored anyway, set the only other knob to true 3924 mWiFiNetworkAgent.setScore(new NetworkScore.Builder().setLegacyInt(110) 3925 .setTransportPrimary(true).build()); 3926 3927 expectNoRequestChanged(testFactory); // still not seeing the request 3928 expectNoRequestChanged(testFactoryAll); // still seeing the request 3929 3930 mWiFiNetworkAgent.disconnect(); 3931 } 3932 3933 @Test 3934 public void testNetworkFactoryUnregister() throws Exception { 3935 // Make sure the factory sees the default network 3936 final NetworkCapabilities filter = new NetworkCapabilities(); 3937 filter.addCapability(NET_CAPABILITY_INTERNET); 3938 filter.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED); 3939 3940 final HandlerThread handlerThread = new HandlerThread("testNetworkFactoryRequests"); 3941 handlerThread.start(); 3942 3943 // Checks that calling setScoreFilter on a NetworkFactory immediately before closing it 3944 // does not crash. 3945 for (int i = 0; i < 100; i++) { 3946 final MockNetworkFactory testFactory = new MockNetworkFactory(handlerThread.getLooper(), 3947 mServiceContext, "testFactory", filter, mCsHandlerThread); 3948 // Register the factory and don't be surprised when the default request arrives. 3949 testFactory.register(); 3950 testFactory.expectRequestAdd(); 3951 3952 testFactory.setScoreFilter(42); 3953 testFactory.terminate(); 3954 testFactory.assertNoRequestChanged(); 3955 3956 if (i % 2 == 0) { 3957 try { 3958 testFactory.register(); 3959 fail("Re-registering terminated NetworkFactory should throw"); 3960 } catch (IllegalStateException expected) { 3961 } 3962 } 3963 } 3964 handlerThread.quit(); 3965 } 3966 3967 @Test 3968 public void testNoMutableNetworkRequests() throws Exception { 3969 final PendingIntent pendingIntent = PendingIntent.getBroadcast( 3970 mContext, 0 /* requestCode */, new Intent("a"), FLAG_IMMUTABLE); 3971 final NetworkRequest request1 = new NetworkRequest.Builder() 3972 .addCapability(NET_CAPABILITY_VALIDATED) 3973 .build(); 3974 final NetworkRequest request2 = new NetworkRequest.Builder() 3975 .addCapability(NET_CAPABILITY_CAPTIVE_PORTAL) 3976 .build(); 3977 3978 final Class<IllegalArgumentException> expected = IllegalArgumentException.class; 3979 assertThrows(expected, () -> mCm.requestNetwork(request1, new NetworkCallback())); 3980 assertThrows(expected, () -> mCm.requestNetwork(request1, pendingIntent)); 3981 assertThrows(expected, () -> mCm.requestNetwork(request2, new NetworkCallback())); 3982 assertThrows(expected, () -> mCm.requestNetwork(request2, pendingIntent)); 3983 } 3984 3985 @Test 3986 public void testNoAllowedUidsInNetworkRequests() throws Exception { 3987 final PendingIntent pendingIntent = PendingIntent.getBroadcast( 3988 mContext, 0 /* requestCode */, new Intent("a"), FLAG_IMMUTABLE); 3989 final NetworkRequest r = new NetworkRequest.Builder().build(); 3990 final ArraySet<Integer> allowedUids = new ArraySet<>(); 3991 allowedUids.add(6); 3992 allowedUids.add(9); 3993 r.networkCapabilities.setAllowedUids(allowedUids); 3994 3995 final Handler handler = new Handler(ConnectivityThread.getInstanceLooper()); 3996 final NetworkCallback cb = new NetworkCallback(); 3997 3998 final Class<IllegalArgumentException> expected = IllegalArgumentException.class; 3999 assertThrows(expected, () -> mCm.requestNetwork(r, cb)); 4000 assertThrows(expected, () -> mCm.requestNetwork(r, pendingIntent)); 4001 assertThrows(expected, () -> mCm.registerNetworkCallback(r, cb)); 4002 assertThrows(expected, () -> mCm.registerNetworkCallback(r, cb, handler)); 4003 assertThrows(expected, () -> mCm.registerNetworkCallback(r, pendingIntent)); 4004 assertThrows(expected, () -> mCm.registerBestMatchingNetworkCallback(r, cb, handler)); 4005 4006 // Make sure that resetting the access UIDs to the empty set will allow calling 4007 // requestNetwork and registerNetworkCallback. 4008 r.networkCapabilities.setAllowedUids(Collections.emptySet()); 4009 mCm.requestNetwork(r, cb); 4010 mCm.unregisterNetworkCallback(cb); 4011 mCm.registerNetworkCallback(r, cb); 4012 mCm.unregisterNetworkCallback(cb); 4013 } 4014 4015 @Test 4016 public void testMMSonWiFi() throws Exception { 4017 // Test bringing up cellular without MMS NetworkRequest gets reaped 4018 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 4019 mCellNetworkAgent.addCapability(NET_CAPABILITY_MMS); 4020 mCellNetworkAgent.connectWithoutInternet(); 4021 mCellNetworkAgent.expectDisconnected(); 4022 waitForIdle(); 4023 assertEmpty(mCm.getAllNetworks()); 4024 verifyNoNetwork(); 4025 4026 // Test bringing up validated WiFi. 4027 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4028 final ExpectedBroadcast b = expectConnectivityAction(TYPE_WIFI, DetailedState.CONNECTED); 4029 mWiFiNetworkAgent.connect(true); 4030 b.expectBroadcast(); 4031 verifyActiveNetwork(TRANSPORT_WIFI); 4032 4033 // Register MMS NetworkRequest 4034 NetworkRequest.Builder builder = new NetworkRequest.Builder(); 4035 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_MMS); 4036 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 4037 mCm.requestNetwork(builder.build(), networkCallback); 4038 4039 // Test bringing up unvalidated cellular with MMS 4040 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 4041 mCellNetworkAgent.addCapability(NET_CAPABILITY_MMS); 4042 mCellNetworkAgent.connectWithoutInternet(); 4043 networkCallback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent); 4044 verifyActiveNetwork(TRANSPORT_WIFI); 4045 4046 // Test releasing NetworkRequest disconnects cellular with MMS 4047 mCm.unregisterNetworkCallback(networkCallback); 4048 mCellNetworkAgent.expectDisconnected(); 4049 verifyActiveNetwork(TRANSPORT_WIFI); 4050 } 4051 4052 @Test 4053 public void testMMSonCell() throws Exception { 4054 // Test bringing up cellular without MMS 4055 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 4056 ExpectedBroadcast b = expectConnectivityAction(TYPE_MOBILE, DetailedState.CONNECTED); 4057 mCellNetworkAgent.connect(false); 4058 b.expectBroadcast(); 4059 verifyActiveNetwork(TRANSPORT_CELLULAR); 4060 4061 // Register MMS NetworkRequest 4062 NetworkRequest.Builder builder = new NetworkRequest.Builder(); 4063 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_MMS); 4064 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 4065 mCm.requestNetwork(builder.build(), networkCallback); 4066 4067 // Test bringing up MMS cellular network 4068 TestNetworkAgentWrapper 4069 mmsNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 4070 mmsNetworkAgent.addCapability(NET_CAPABILITY_MMS); 4071 mmsNetworkAgent.connectWithoutInternet(); 4072 networkCallback.expectAvailableCallbacksUnvalidated(mmsNetworkAgent); 4073 verifyActiveNetwork(TRANSPORT_CELLULAR); 4074 4075 // Test releasing MMS NetworkRequest does not disconnect main cellular NetworkAgent 4076 mCm.unregisterNetworkCallback(networkCallback); 4077 mmsNetworkAgent.expectDisconnected(); 4078 verifyActiveNetwork(TRANSPORT_CELLULAR); 4079 } 4080 4081 @Test 4082 public void testPartialConnectivity() throws Exception { 4083 // Register network callback. 4084 NetworkRequest request = new NetworkRequest.Builder() 4085 .clearCapabilities().addCapability(NET_CAPABILITY_INTERNET) 4086 .build(); 4087 TestNetworkCallback callback = new TestNetworkCallback(); 4088 mCm.registerNetworkCallback(request, callback); 4089 4090 // Bring up validated mobile data. 4091 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 4092 mCellNetworkAgent.connect(true); 4093 callback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 4094 4095 // Bring up wifi with partial connectivity. 4096 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4097 mWiFiNetworkAgent.connectWithPartialConnectivity(); 4098 callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 4099 callback.expectCapabilitiesWith(NET_CAPABILITY_PARTIAL_CONNECTIVITY, mWiFiNetworkAgent); 4100 4101 // Mobile data should be the default network. 4102 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 4103 callback.assertNoCallback(); 4104 4105 // With HTTPS probe disabled, NetworkMonitor should pass the network validation with http 4106 // probe. 4107 mWiFiNetworkAgent.setNetworkPartialValid(false /* isStrictMode */); 4108 // If the user chooses yes to use this partial connectivity wifi, switch the default 4109 // network to wifi and check if wifi becomes valid or not. 4110 mCm.setAcceptPartialConnectivity(mWiFiNetworkAgent.getNetwork(), true /* accept */, 4111 false /* always */); 4112 // If user accepts partial connectivity network, 4113 // NetworkMonitor#setAcceptPartialConnectivity() should be called too. 4114 waitForIdle(); 4115 verify(mWiFiNetworkAgent.mNetworkMonitor, times(1)).setAcceptPartialConnectivity(); 4116 4117 // Need a trigger point to let NetworkMonitor tell ConnectivityService that network is 4118 // validated. 4119 mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), true); 4120 callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent); 4121 NetworkCapabilities nc = callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, 4122 mWiFiNetworkAgent); 4123 assertTrue(nc.hasCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY)); 4124 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 4125 4126 // Disconnect and reconnect wifi with partial connectivity again. 4127 mWiFiNetworkAgent.disconnect(); 4128 callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 4129 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4130 mWiFiNetworkAgent.connectWithPartialConnectivity(); 4131 callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 4132 callback.expectCapabilitiesWith(NET_CAPABILITY_PARTIAL_CONNECTIVITY, mWiFiNetworkAgent); 4133 4134 // Mobile data should be the default network. 4135 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 4136 4137 // If the user chooses no, disconnect wifi immediately. 4138 mCm.setAcceptPartialConnectivity(mWiFiNetworkAgent.getNetwork(), false/* accept */, 4139 false /* always */); 4140 callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 4141 4142 // If user accepted partial connectivity before, and device reconnects to that network 4143 // again, but now the network has full connectivity. The network shouldn't contain 4144 // NET_CAPABILITY_PARTIAL_CONNECTIVITY. 4145 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4146 // acceptUnvalidated is also used as setting for accepting partial networks. 4147 mWiFiNetworkAgent.explicitlySelected(true /* explicitlySelected */, 4148 true /* acceptUnvalidated */); 4149 mWiFiNetworkAgent.connect(true); 4150 4151 // If user accepted partial connectivity network before, 4152 // NetworkMonitor#setAcceptPartialConnectivity() will be called in 4153 // ConnectivityService#updateNetworkInfo(). 4154 callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 4155 verify(mWiFiNetworkAgent.mNetworkMonitor, times(1)).setAcceptPartialConnectivity(); 4156 callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent); 4157 nc = callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent); 4158 assertFalse(nc.hasCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY)); 4159 4160 // Wifi should be the default network. 4161 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 4162 mWiFiNetworkAgent.disconnect(); 4163 callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 4164 4165 // The user accepted partial connectivity and selected "don't ask again". Now the user 4166 // reconnects to the partial connectivity network. Switch to wifi as soon as partial 4167 // connectivity is detected. 4168 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4169 mWiFiNetworkAgent.explicitlySelected(true /* explicitlySelected */, 4170 true /* acceptUnvalidated */); 4171 mWiFiNetworkAgent.connectWithPartialConnectivity(); 4172 // If user accepted partial connectivity network before, 4173 // NetworkMonitor#setAcceptPartialConnectivity() will be called in 4174 // ConnectivityService#updateNetworkInfo(). 4175 callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 4176 verify(mWiFiNetworkAgent.mNetworkMonitor, times(1)).setAcceptPartialConnectivity(); 4177 callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent); 4178 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 4179 callback.expectCapabilitiesWith(NET_CAPABILITY_PARTIAL_CONNECTIVITY, mWiFiNetworkAgent); 4180 mWiFiNetworkAgent.setNetworkValid(false /* isStrictMode */); 4181 4182 // Need a trigger point to let NetworkMonitor tell ConnectivityService that network is 4183 // validated. 4184 mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), true); 4185 callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent); 4186 mWiFiNetworkAgent.disconnect(); 4187 callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 4188 4189 // If the user accepted partial connectivity, and the device auto-reconnects to the partial 4190 // connectivity network, it should contain both PARTIAL_CONNECTIVITY and VALIDATED. 4191 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4192 mWiFiNetworkAgent.explicitlySelected(false /* explicitlySelected */, 4193 true /* acceptUnvalidated */); 4194 4195 // NetworkMonitor will immediately (once the HTTPS probe fails...) report the network as 4196 // valid, because ConnectivityService calls setAcceptPartialConnectivity before it calls 4197 // notifyNetworkConnected. 4198 mWiFiNetworkAgent.connectWithPartialValidConnectivity(false /* isStrictMode */); 4199 callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 4200 verify(mWiFiNetworkAgent.mNetworkMonitor, times(1)).setAcceptPartialConnectivity(); 4201 callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent); 4202 callback.expectCapabilitiesWith( 4203 NET_CAPABILITY_PARTIAL_CONNECTIVITY | NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent); 4204 mWiFiNetworkAgent.disconnect(); 4205 callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 4206 } 4207 4208 @Test 4209 public void testCaptivePortalOnPartialConnectivity() throws Exception { 4210 final TestNetworkCallback captivePortalCallback = new TestNetworkCallback(); 4211 final NetworkRequest captivePortalRequest = new NetworkRequest.Builder() 4212 .addCapability(NET_CAPABILITY_CAPTIVE_PORTAL).build(); 4213 mCm.registerNetworkCallback(captivePortalRequest, captivePortalCallback); 4214 4215 final TestNetworkCallback validatedCallback = new TestNetworkCallback(); 4216 final NetworkRequest validatedRequest = new NetworkRequest.Builder() 4217 .addCapability(NET_CAPABILITY_VALIDATED).build(); 4218 mCm.registerNetworkCallback(validatedRequest, validatedCallback); 4219 4220 // Bring up a network with a captive portal. 4221 // Expect onAvailable callback of listen for NET_CAPABILITY_CAPTIVE_PORTAL. 4222 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4223 String redirectUrl = "http://android.com/path"; 4224 mWiFiNetworkAgent.connectWithCaptivePortal(redirectUrl, false /* isStrictMode */); 4225 captivePortalCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 4226 assertEquals(mWiFiNetworkAgent.waitForRedirectUrl(), redirectUrl); 4227 4228 // Check that startCaptivePortalApp sends the expected command to NetworkMonitor. 4229 mCm.startCaptivePortalApp(mWiFiNetworkAgent.getNetwork()); 4230 verify(mWiFiNetworkAgent.mNetworkMonitor, timeout(TIMEOUT_MS).times(1)) 4231 .launchCaptivePortalApp(); 4232 4233 // Report that the captive portal is dismissed with partial connectivity, and check that 4234 // callbacks are fired. 4235 mWiFiNetworkAgent.setNetworkPartial(); 4236 mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), true); 4237 waitForIdle(); 4238 captivePortalCallback.expectCapabilitiesWith(NET_CAPABILITY_PARTIAL_CONNECTIVITY, 4239 mWiFiNetworkAgent); 4240 4241 // Report partial connectivity is accepted. 4242 mWiFiNetworkAgent.setNetworkPartialValid(false /* isStrictMode */); 4243 mCm.setAcceptPartialConnectivity(mWiFiNetworkAgent.getNetwork(), true /* accept */, 4244 false /* always */); 4245 waitForIdle(); 4246 mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), true); 4247 captivePortalCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 4248 validatedCallback.expectAvailableCallbacksValidated(mWiFiNetworkAgent); 4249 NetworkCapabilities nc = 4250 validatedCallback.expectCapabilitiesWith(NET_CAPABILITY_PARTIAL_CONNECTIVITY, 4251 mWiFiNetworkAgent); 4252 4253 mCm.unregisterNetworkCallback(captivePortalCallback); 4254 mCm.unregisterNetworkCallback(validatedCallback); 4255 } 4256 4257 @Test 4258 public void testCaptivePortal() throws Exception { 4259 final TestNetworkCallback captivePortalCallback = new TestNetworkCallback(); 4260 final NetworkRequest captivePortalRequest = new NetworkRequest.Builder() 4261 .addCapability(NET_CAPABILITY_CAPTIVE_PORTAL).build(); 4262 mCm.registerNetworkCallback(captivePortalRequest, captivePortalCallback); 4263 4264 final TestNetworkCallback validatedCallback = new TestNetworkCallback(); 4265 final NetworkRequest validatedRequest = new NetworkRequest.Builder() 4266 .addCapability(NET_CAPABILITY_VALIDATED).build(); 4267 mCm.registerNetworkCallback(validatedRequest, validatedCallback); 4268 4269 // Bring up a network with a captive portal. 4270 // Expect onAvailable callback of listen for NET_CAPABILITY_CAPTIVE_PORTAL. 4271 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4272 String firstRedirectUrl = "http://example.com/firstPath"; 4273 mWiFiNetworkAgent.connectWithCaptivePortal(firstRedirectUrl, false /* isStrictMode */); 4274 captivePortalCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 4275 assertEquals(mWiFiNetworkAgent.waitForRedirectUrl(), firstRedirectUrl); 4276 4277 // Take down network. 4278 // Expect onLost callback. 4279 mWiFiNetworkAgent.disconnect(); 4280 captivePortalCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 4281 4282 // Bring up a network with a captive portal. 4283 // Expect onAvailable callback of listen for NET_CAPABILITY_CAPTIVE_PORTAL. 4284 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4285 String secondRedirectUrl = "http://example.com/secondPath"; 4286 mWiFiNetworkAgent.connectWithCaptivePortal(secondRedirectUrl, false /* isStrictMode */); 4287 captivePortalCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 4288 assertEquals(mWiFiNetworkAgent.waitForRedirectUrl(), secondRedirectUrl); 4289 4290 // Make captive portal disappear then revalidate. 4291 // Expect onLost callback because network no longer provides NET_CAPABILITY_CAPTIVE_PORTAL. 4292 mWiFiNetworkAgent.setNetworkValid(false /* isStrictMode */); 4293 mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), true); 4294 captivePortalCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 4295 4296 // Expect NET_CAPABILITY_VALIDATED onAvailable callback. 4297 validatedCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent); 4298 4299 // Break network connectivity. 4300 // Expect NET_CAPABILITY_VALIDATED onLost callback. 4301 mWiFiNetworkAgent.setNetworkInvalid(false /* isStrictMode */); 4302 mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), false); 4303 validatedCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 4304 } 4305 4306 @Test 4307 public void testCaptivePortalApp() throws Exception { 4308 final TestNetworkCallback captivePortalCallback = new TestNetworkCallback(); 4309 final NetworkRequest captivePortalRequest = new NetworkRequest.Builder() 4310 .addCapability(NET_CAPABILITY_CAPTIVE_PORTAL).build(); 4311 mCm.registerNetworkCallback(captivePortalRequest, captivePortalCallback); 4312 4313 final TestNetworkCallback validatedCallback = new TestNetworkCallback(); 4314 final NetworkRequest validatedRequest = new NetworkRequest.Builder() 4315 .addCapability(NET_CAPABILITY_VALIDATED).build(); 4316 mCm.registerNetworkCallback(validatedRequest, validatedCallback); 4317 4318 // Bring up wifi. 4319 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4320 mWiFiNetworkAgent.connect(true); 4321 validatedCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent); 4322 Network wifiNetwork = mWiFiNetworkAgent.getNetwork(); 4323 4324 // Check that calling startCaptivePortalApp does nothing. 4325 final int fastTimeoutMs = 100; 4326 mCm.startCaptivePortalApp(wifiNetwork); 4327 waitForIdle(); 4328 verify(mWiFiNetworkAgent.mNetworkMonitor, never()).launchCaptivePortalApp(); 4329 mServiceContext.expectNoStartActivityIntent(fastTimeoutMs); 4330 4331 // Turn into a captive portal. 4332 mWiFiNetworkAgent.setNetworkPortal("http://example.com", false /* isStrictMode */); 4333 mCm.reportNetworkConnectivity(wifiNetwork, false); 4334 captivePortalCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 4335 validatedCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 4336 4337 // Check that startCaptivePortalApp sends the expected command to NetworkMonitor. 4338 mCm.startCaptivePortalApp(wifiNetwork); 4339 waitForIdle(); 4340 verify(mWiFiNetworkAgent.mNetworkMonitor).launchCaptivePortalApp(); 4341 4342 // NetworkMonitor uses startCaptivePortal(Network, Bundle) (startCaptivePortalAppInternal) 4343 final Bundle testBundle = new Bundle(); 4344 final String testKey = "testkey"; 4345 final String testValue = "testvalue"; 4346 testBundle.putString(testKey, testValue); 4347 mServiceContext.setPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, 4348 PERMISSION_GRANTED); 4349 mCm.startCaptivePortalApp(wifiNetwork, testBundle); 4350 final Intent signInIntent = mServiceContext.expectStartActivityIntent(TIMEOUT_MS); 4351 assertEquals(ACTION_CAPTIVE_PORTAL_SIGN_IN, signInIntent.getAction()); 4352 assertEquals(testValue, signInIntent.getStringExtra(testKey)); 4353 4354 // Report that the captive portal is dismissed, and check that callbacks are fired 4355 mWiFiNetworkAgent.setNetworkValid(false /* isStrictMode */); 4356 mWiFiNetworkAgent.mNetworkMonitor.forceReevaluation(Process.myUid()); 4357 validatedCallback.expectAvailableCallbacksValidated(mWiFiNetworkAgent); 4358 captivePortalCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 4359 4360 mCm.unregisterNetworkCallback(validatedCallback); 4361 mCm.unregisterNetworkCallback(captivePortalCallback); 4362 } 4363 4364 @Test 4365 public void testAvoidOrIgnoreCaptivePortals() throws Exception { 4366 final TestNetworkCallback captivePortalCallback = new TestNetworkCallback(); 4367 final NetworkRequest captivePortalRequest = new NetworkRequest.Builder() 4368 .addCapability(NET_CAPABILITY_CAPTIVE_PORTAL).build(); 4369 mCm.registerNetworkCallback(captivePortalRequest, captivePortalCallback); 4370 4371 final TestNetworkCallback validatedCallback = new TestNetworkCallback(); 4372 final NetworkRequest validatedRequest = new NetworkRequest.Builder() 4373 .addCapability(NET_CAPABILITY_VALIDATED).build(); 4374 mCm.registerNetworkCallback(validatedRequest, validatedCallback); 4375 4376 setCaptivePortalMode(ConnectivitySettingsManager.CAPTIVE_PORTAL_MODE_AVOID); 4377 // Bring up a network with a captive portal. 4378 // Expect it to fail to connect and not result in any callbacks. 4379 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4380 String firstRedirectUrl = "http://example.com/firstPath"; 4381 4382 mWiFiNetworkAgent.connectWithCaptivePortal(firstRedirectUrl, false /* isStrictMode */); 4383 mWiFiNetworkAgent.expectDisconnected(); 4384 mWiFiNetworkAgent.expectPreventReconnectReceived(); 4385 4386 assertNoCallbacks(captivePortalCallback, validatedCallback); 4387 } 4388 4389 @Test 4390 public void testCaptivePortalApi() throws Exception { 4391 mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_GRANTED); 4392 4393 final TestNetworkCallback captivePortalCallback = new TestNetworkCallback(); 4394 final NetworkRequest captivePortalRequest = new NetworkRequest.Builder() 4395 .addCapability(NET_CAPABILITY_CAPTIVE_PORTAL).build(); 4396 mCm.registerNetworkCallback(captivePortalRequest, captivePortalCallback); 4397 4398 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4399 final String redirectUrl = "http://example.com/firstPath"; 4400 4401 mWiFiNetworkAgent.connectWithCaptivePortal(redirectUrl, false /* isStrictMode */); 4402 captivePortalCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 4403 4404 final CaptivePortalData testData = new CaptivePortalData.Builder() 4405 .setUserPortalUrl(Uri.parse(redirectUrl)) 4406 .setBytesRemaining(12345L) 4407 .build(); 4408 4409 mWiFiNetworkAgent.notifyCapportApiDataChanged(testData); 4410 4411 captivePortalCallback.expectLinkPropertiesThat(mWiFiNetworkAgent, 4412 lp -> testData.equals(lp.getCaptivePortalData())); 4413 4414 final LinkProperties newLps = new LinkProperties(); 4415 newLps.setMtu(1234); 4416 mWiFiNetworkAgent.sendLinkProperties(newLps); 4417 // CaptivePortalData is not lost and unchanged when LPs are received from the NetworkAgent 4418 captivePortalCallback.expectLinkPropertiesThat(mWiFiNetworkAgent, 4419 lp -> testData.equals(lp.getCaptivePortalData()) && lp.getMtu() == 1234); 4420 } 4421 4422 private TestNetworkCallback setupNetworkCallbackAndConnectToWifi() throws Exception { 4423 // Grant NETWORK_SETTINGS permission to be able to receive LinkProperties change callbacks 4424 // with sensitive (captive portal) data 4425 mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_GRANTED); 4426 4427 final TestNetworkCallback captivePortalCallback = new TestNetworkCallback(); 4428 final NetworkRequest captivePortalRequest = new NetworkRequest.Builder() 4429 .addCapability(NET_CAPABILITY_CAPTIVE_PORTAL).build(); 4430 mCm.registerNetworkCallback(captivePortalRequest, captivePortalCallback); 4431 4432 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4433 4434 mWiFiNetworkAgent.connectWithCaptivePortal(TEST_REDIRECT_URL, false /* isStrictMode */); 4435 captivePortalCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 4436 return captivePortalCallback; 4437 } 4438 4439 private class CaptivePortalTestData { 4440 CaptivePortalTestData(CaptivePortalData naPasspointData, CaptivePortalData capportData, 4441 CaptivePortalData naOtherData, CaptivePortalData expectedMergedPasspointData, 4442 CaptivePortalData expectedMergedOtherData) { 4443 mNaPasspointData = naPasspointData; 4444 mCapportData = capportData; 4445 mNaOtherData = naOtherData; 4446 mExpectedMergedPasspointData = expectedMergedPasspointData; 4447 mExpectedMergedOtherData = expectedMergedOtherData; 4448 } 4449 4450 public final CaptivePortalData mNaPasspointData; 4451 public final CaptivePortalData mCapportData; 4452 public final CaptivePortalData mNaOtherData; 4453 public final CaptivePortalData mExpectedMergedPasspointData; 4454 public final CaptivePortalData mExpectedMergedOtherData; 4455 4456 } 4457 4458 private CaptivePortalTestData setupCaptivePortalData() { 4459 final CaptivePortalData capportData = new CaptivePortalData.Builder() 4460 .setUserPortalUrl(Uri.parse(TEST_REDIRECT_URL)) 4461 .setVenueInfoUrl(Uri.parse(TEST_VENUE_URL_CAPPORT)) 4462 .setUserPortalUrl(Uri.parse(TEST_USER_PORTAL_API_URL_CAPPORT)) 4463 .setExpiryTime(1000000L) 4464 .setBytesRemaining(12345L) 4465 .build(); 4466 4467 final CaptivePortalData naPasspointData = new CaptivePortalData.Builder() 4468 .setBytesRemaining(80802L) 4469 .setVenueInfoUrl(Uri.parse(TEST_VENUE_URL_NA_PASSPOINT), 4470 CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT) 4471 .setUserPortalUrl(Uri.parse(TEST_TERMS_AND_CONDITIONS_URL_NA_PASSPOINT), 4472 CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT) 4473 .setVenueFriendlyName(TEST_FRIENDLY_NAME).build(); 4474 4475 final CaptivePortalData naOtherData = new CaptivePortalData.Builder() 4476 .setBytesRemaining(80802L) 4477 .setVenueInfoUrl(Uri.parse(TEST_VENUE_URL_NA_OTHER), 4478 CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_OTHER) 4479 .setUserPortalUrl(Uri.parse(TEST_TERMS_AND_CONDITIONS_URL_NA_OTHER), 4480 CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_OTHER) 4481 .setVenueFriendlyName(TEST_FRIENDLY_NAME).build(); 4482 4483 final CaptivePortalData expectedMergedPasspointData = new CaptivePortalData.Builder() 4484 .setUserPortalUrl(Uri.parse(TEST_REDIRECT_URL)) 4485 .setBytesRemaining(12345L) 4486 .setExpiryTime(1000000L) 4487 .setVenueInfoUrl(Uri.parse(TEST_VENUE_URL_NA_PASSPOINT), 4488 CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT) 4489 .setUserPortalUrl(Uri.parse(TEST_TERMS_AND_CONDITIONS_URL_NA_PASSPOINT), 4490 CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT) 4491 .setVenueFriendlyName(TEST_FRIENDLY_NAME).build(); 4492 4493 final CaptivePortalData expectedMergedOtherData = new CaptivePortalData.Builder() 4494 .setUserPortalUrl(Uri.parse(TEST_REDIRECT_URL)) 4495 .setBytesRemaining(12345L) 4496 .setExpiryTime(1000000L) 4497 .setVenueInfoUrl(Uri.parse(TEST_VENUE_URL_CAPPORT)) 4498 .setUserPortalUrl(Uri.parse(TEST_USER_PORTAL_API_URL_CAPPORT)) 4499 .setVenueFriendlyName(TEST_FRIENDLY_NAME).build(); 4500 return new CaptivePortalTestData(naPasspointData, capportData, naOtherData, 4501 expectedMergedPasspointData, expectedMergedOtherData); 4502 } 4503 4504 @Test 4505 public void testMergeCaptivePortalApiWithFriendlyNameAndVenueUrl() throws Exception { 4506 final TestNetworkCallback captivePortalCallback = setupNetworkCallbackAndConnectToWifi(); 4507 final CaptivePortalTestData captivePortalTestData = setupCaptivePortalData(); 4508 4509 // Baseline capport data 4510 mWiFiNetworkAgent.notifyCapportApiDataChanged(captivePortalTestData.mCapportData); 4511 4512 captivePortalCallback.expectLinkPropertiesThat(mWiFiNetworkAgent, 4513 lp -> captivePortalTestData.mCapportData.equals(lp.getCaptivePortalData())); 4514 4515 // Venue URL, T&C URL and friendly name from Network agent with Passpoint source, confirm 4516 // that API data gets precedence on the bytes remaining. 4517 final LinkProperties linkProperties = new LinkProperties(); 4518 linkProperties.setCaptivePortalData(captivePortalTestData.mNaPasspointData); 4519 mWiFiNetworkAgent.sendLinkProperties(linkProperties); 4520 4521 // Make sure that the capport data is merged 4522 captivePortalCallback.expectLinkPropertiesThat(mWiFiNetworkAgent, 4523 lp -> captivePortalTestData.mExpectedMergedPasspointData 4524 .equals(lp.getCaptivePortalData())); 4525 4526 // Now send this information from non-Passpoint source, confirm that Capport data takes 4527 // precedence 4528 linkProperties.setCaptivePortalData(captivePortalTestData.mNaOtherData); 4529 mWiFiNetworkAgent.sendLinkProperties(linkProperties); 4530 4531 // Make sure that the capport data is merged 4532 captivePortalCallback.expectLinkPropertiesThat(mWiFiNetworkAgent, 4533 lp -> captivePortalTestData.mExpectedMergedOtherData 4534 .equals(lp.getCaptivePortalData())); 4535 4536 // Create a new LP with no Network agent capport data 4537 final LinkProperties newLps = new LinkProperties(); 4538 newLps.setMtu(1234); 4539 mWiFiNetworkAgent.sendLinkProperties(newLps); 4540 // CaptivePortalData is not lost and has the original values when LPs are received from the 4541 // NetworkAgent 4542 captivePortalCallback.expectLinkPropertiesThat(mWiFiNetworkAgent, 4543 lp -> captivePortalTestData.mCapportData.equals(lp.getCaptivePortalData()) 4544 && lp.getMtu() == 1234); 4545 4546 // Now send capport data only from the Network agent 4547 mWiFiNetworkAgent.notifyCapportApiDataChanged(null); 4548 captivePortalCallback.expectLinkPropertiesThat(mWiFiNetworkAgent, 4549 lp -> lp.getCaptivePortalData() == null); 4550 4551 newLps.setCaptivePortalData(captivePortalTestData.mNaPasspointData); 4552 mWiFiNetworkAgent.sendLinkProperties(newLps); 4553 4554 // Make sure that only the network agent capport data is available 4555 captivePortalCallback.expectLinkPropertiesThat(mWiFiNetworkAgent, 4556 lp -> captivePortalTestData.mNaPasspointData.equals(lp.getCaptivePortalData())); 4557 } 4558 4559 @Test 4560 public void testMergeCaptivePortalDataFromNetworkAgentFirstThenCapport() throws Exception { 4561 final TestNetworkCallback captivePortalCallback = setupNetworkCallbackAndConnectToWifi(); 4562 final CaptivePortalTestData captivePortalTestData = setupCaptivePortalData(); 4563 4564 // Venue URL and friendly name from Network agent, confirm that API data gets precedence 4565 // on the bytes remaining. 4566 final LinkProperties linkProperties = new LinkProperties(); 4567 linkProperties.setCaptivePortalData(captivePortalTestData.mNaPasspointData); 4568 mWiFiNetworkAgent.sendLinkProperties(linkProperties); 4569 4570 // Make sure that the data is saved correctly 4571 captivePortalCallback.expectLinkPropertiesThat(mWiFiNetworkAgent, 4572 lp -> captivePortalTestData.mNaPasspointData.equals(lp.getCaptivePortalData())); 4573 4574 // Expected merged data: Network agent data is preferred, and values that are not used by 4575 // it are merged from capport data 4576 mWiFiNetworkAgent.notifyCapportApiDataChanged(captivePortalTestData.mCapportData); 4577 4578 // Make sure that the Capport data is merged correctly 4579 captivePortalCallback.expectLinkPropertiesThat(mWiFiNetworkAgent, 4580 lp -> captivePortalTestData.mExpectedMergedPasspointData.equals( 4581 lp.getCaptivePortalData())); 4582 4583 // Now set the naData to null 4584 linkProperties.setCaptivePortalData(null); 4585 mWiFiNetworkAgent.sendLinkProperties(linkProperties); 4586 4587 // Make sure that the Capport data is retained correctly 4588 captivePortalCallback.expectLinkPropertiesThat(mWiFiNetworkAgent, 4589 lp -> captivePortalTestData.mCapportData.equals(lp.getCaptivePortalData())); 4590 } 4591 4592 @Test 4593 public void testMergeCaptivePortalDataFromNetworkAgentOtherSourceFirstThenCapport() 4594 throws Exception { 4595 final TestNetworkCallback captivePortalCallback = setupNetworkCallbackAndConnectToWifi(); 4596 final CaptivePortalTestData captivePortalTestData = setupCaptivePortalData(); 4597 4598 // Venue URL and friendly name from Network agent, confirm that API data gets precedence 4599 // on the bytes remaining. 4600 final LinkProperties linkProperties = new LinkProperties(); 4601 linkProperties.setCaptivePortalData(captivePortalTestData.mNaOtherData); 4602 mWiFiNetworkAgent.sendLinkProperties(linkProperties); 4603 4604 // Make sure that the data is saved correctly 4605 captivePortalCallback.expectLinkPropertiesThat(mWiFiNetworkAgent, 4606 lp -> captivePortalTestData.mNaOtherData.equals(lp.getCaptivePortalData())); 4607 4608 // Expected merged data: Network agent data is preferred, and values that are not used by 4609 // it are merged from capport data 4610 mWiFiNetworkAgent.notifyCapportApiDataChanged(captivePortalTestData.mCapportData); 4611 4612 // Make sure that the Capport data is merged correctly 4613 captivePortalCallback.expectLinkPropertiesThat(mWiFiNetworkAgent, 4614 lp -> captivePortalTestData.mExpectedMergedOtherData.equals( 4615 lp.getCaptivePortalData())); 4616 } 4617 4618 private NetworkRequest.Builder newWifiRequestBuilder() { 4619 return new NetworkRequest.Builder().addTransportType(TRANSPORT_WIFI); 4620 } 4621 4622 /** 4623 * Verify request matching behavior with network specifiers. 4624 * 4625 * This test does not check updating the specifier on a live network because the specifier is 4626 * immutable and this triggers a WTF in 4627 * {@link ConnectivityService#mixInCapabilities(NetworkAgentInfo, NetworkCapabilities)}. 4628 */ 4629 @Test 4630 public void testNetworkSpecifier() throws Exception { 4631 // A NetworkSpecifier subclass that matches all networks but must not be visible to apps. 4632 class ConfidentialMatchAllNetworkSpecifier extends NetworkSpecifier implements 4633 Parcelable { 4634 @Override 4635 public boolean canBeSatisfiedBy(NetworkSpecifier other) { 4636 return true; 4637 } 4638 4639 @Override 4640 public int describeContents() { 4641 return 0; 4642 } 4643 4644 @Override 4645 public void writeToParcel(Parcel dest, int flags) {} 4646 4647 @Override 4648 public NetworkSpecifier redact() { 4649 return null; 4650 } 4651 } 4652 4653 // A network specifier that matches either another LocalNetworkSpecifier with the same 4654 // string or a ConfidentialMatchAllNetworkSpecifier, and can be passed to apps as is. 4655 class LocalStringNetworkSpecifier extends NetworkSpecifier implements Parcelable { 4656 private String mString; 4657 4658 LocalStringNetworkSpecifier(String string) { 4659 mString = string; 4660 } 4661 4662 @Override 4663 public boolean canBeSatisfiedBy(NetworkSpecifier other) { 4664 if (other instanceof LocalStringNetworkSpecifier) { 4665 return TextUtils.equals(mString, 4666 ((LocalStringNetworkSpecifier) other).mString); 4667 } 4668 if (other instanceof ConfidentialMatchAllNetworkSpecifier) return true; 4669 return false; 4670 } 4671 4672 @Override 4673 public int describeContents() { 4674 return 0; 4675 } 4676 @Override 4677 public void writeToParcel(Parcel dest, int flags) {} 4678 } 4679 4680 4681 NetworkRequest rEmpty1 = newWifiRequestBuilder().build(); 4682 NetworkRequest rEmpty2 = newWifiRequestBuilder().setNetworkSpecifier((String) null).build(); 4683 NetworkRequest rEmpty3 = newWifiRequestBuilder().setNetworkSpecifier("").build(); 4684 NetworkRequest rEmpty4 = newWifiRequestBuilder().setNetworkSpecifier( 4685 (NetworkSpecifier) null).build(); 4686 NetworkRequest rFoo = newWifiRequestBuilder().setNetworkSpecifier( 4687 new LocalStringNetworkSpecifier("foo")).build(); 4688 NetworkRequest rBar = newWifiRequestBuilder().setNetworkSpecifier( 4689 new LocalStringNetworkSpecifier("bar")).build(); 4690 4691 TestNetworkCallback cEmpty1 = new TestNetworkCallback(); 4692 TestNetworkCallback cEmpty2 = new TestNetworkCallback(); 4693 TestNetworkCallback cEmpty3 = new TestNetworkCallback(); 4694 TestNetworkCallback cEmpty4 = new TestNetworkCallback(); 4695 TestNetworkCallback cFoo = new TestNetworkCallback(); 4696 TestNetworkCallback cBar = new TestNetworkCallback(); 4697 TestNetworkCallback[] emptyCallbacks = new TestNetworkCallback[] { 4698 cEmpty1, cEmpty2, cEmpty3, cEmpty4 }; 4699 4700 mCm.registerNetworkCallback(rEmpty1, cEmpty1); 4701 mCm.registerNetworkCallback(rEmpty2, cEmpty2); 4702 mCm.registerNetworkCallback(rEmpty3, cEmpty3); 4703 mCm.registerNetworkCallback(rEmpty4, cEmpty4); 4704 mCm.registerNetworkCallback(rFoo, cFoo); 4705 mCm.registerNetworkCallback(rBar, cBar); 4706 4707 LocalStringNetworkSpecifier nsFoo = new LocalStringNetworkSpecifier("foo"); 4708 LocalStringNetworkSpecifier nsBar = new LocalStringNetworkSpecifier("bar"); 4709 4710 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4711 mWiFiNetworkAgent.connect(false); 4712 expectAvailableCallbacksUnvalidatedWithSpecifier(mWiFiNetworkAgent, null /* specifier */, 4713 cEmpty1, cEmpty2, cEmpty3, cEmpty4); 4714 assertNoCallbacks(cFoo, cBar); 4715 4716 mWiFiNetworkAgent.disconnect(); 4717 expectOnLost(mWiFiNetworkAgent, cEmpty1, cEmpty2, cEmpty3, cEmpty4); 4718 4719 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4720 mWiFiNetworkAgent.setNetworkSpecifier(nsFoo); 4721 mWiFiNetworkAgent.connect(false); 4722 expectAvailableCallbacksUnvalidatedWithSpecifier(mWiFiNetworkAgent, nsFoo, 4723 cEmpty1, cEmpty2, cEmpty3, cEmpty4, cFoo); 4724 cBar.assertNoCallback(); 4725 assertEquals(nsFoo, 4726 mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).getNetworkSpecifier()); 4727 assertNoCallbacks(cEmpty1, cEmpty2, cEmpty3, cEmpty4, cFoo); 4728 4729 mWiFiNetworkAgent.disconnect(); 4730 expectOnLost(mWiFiNetworkAgent, cEmpty1, cEmpty2, cEmpty3, cEmpty4, cFoo); 4731 4732 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4733 mWiFiNetworkAgent.setNetworkSpecifier(nsBar); 4734 mWiFiNetworkAgent.connect(false); 4735 expectAvailableCallbacksUnvalidatedWithSpecifier(mWiFiNetworkAgent, nsBar, 4736 cEmpty1, cEmpty2, cEmpty3, cEmpty4, cBar); 4737 cFoo.assertNoCallback(); 4738 assertEquals(nsBar, 4739 mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).getNetworkSpecifier()); 4740 4741 mWiFiNetworkAgent.disconnect(); 4742 expectOnLost(mWiFiNetworkAgent, cEmpty1, cEmpty2, cEmpty3, cEmpty4, cBar); 4743 cFoo.assertNoCallback(); 4744 4745 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4746 mWiFiNetworkAgent.setNetworkSpecifier(new ConfidentialMatchAllNetworkSpecifier()); 4747 mWiFiNetworkAgent.connect(false); 4748 expectAvailableCallbacksUnvalidatedWithSpecifier(mWiFiNetworkAgent, null /* specifier */, 4749 cEmpty1, cEmpty2, cEmpty3, cEmpty4, cFoo, cBar); 4750 assertNull( 4751 mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).getNetworkSpecifier()); 4752 4753 mWiFiNetworkAgent.disconnect(); 4754 expectOnLost(mWiFiNetworkAgent, cEmpty1, cEmpty2, cEmpty3, cEmpty4, cFoo, cBar); 4755 } 4756 4757 /** 4758 * @return the context's attribution tag 4759 */ 4760 private String getAttributionTag() { 4761 return mContext.getAttributionTag(); 4762 } 4763 4764 @Test 4765 public void testInvalidNetworkSpecifier() { 4766 assertThrows(IllegalArgumentException.class, () -> { 4767 NetworkRequest.Builder builder = new NetworkRequest.Builder(); 4768 builder.setNetworkSpecifier(new MatchAllNetworkSpecifier()); 4769 }); 4770 4771 assertThrows(IllegalArgumentException.class, () -> { 4772 NetworkCapabilities networkCapabilities = new NetworkCapabilities(); 4773 networkCapabilities.addTransportType(TRANSPORT_WIFI) 4774 .setNetworkSpecifier(new MatchAllNetworkSpecifier()); 4775 mService.requestNetwork(Process.INVALID_UID, networkCapabilities, 4776 NetworkRequest.Type.REQUEST.ordinal(), null, 0, null, 4777 ConnectivityManager.TYPE_WIFI, NetworkCallback.FLAG_NONE, 4778 mContext.getPackageName(), getAttributionTag()); 4779 }); 4780 4781 class NonParcelableSpecifier extends NetworkSpecifier { 4782 @Override 4783 public boolean canBeSatisfiedBy(NetworkSpecifier other) { 4784 return false; 4785 } 4786 }; 4787 class ParcelableSpecifier extends NonParcelableSpecifier implements Parcelable { 4788 @Override public int describeContents() { return 0; } 4789 @Override public void writeToParcel(Parcel p, int flags) {} 4790 } 4791 4792 final NetworkRequest.Builder builder = 4793 new NetworkRequest.Builder().addTransportType(TRANSPORT_ETHERNET); 4794 assertThrows(ClassCastException.class, () -> { 4795 builder.setNetworkSpecifier(new NonParcelableSpecifier()); 4796 Parcel parcelW = Parcel.obtain(); 4797 builder.build().writeToParcel(parcelW, 0); 4798 }); 4799 4800 final NetworkRequest nr = 4801 new NetworkRequest.Builder().addTransportType(TRANSPORT_ETHERNET) 4802 .setNetworkSpecifier(new ParcelableSpecifier()) 4803 .build(); 4804 assertNotNull(nr); 4805 4806 assertThrows(BadParcelableException.class, () -> { 4807 Parcel parcelW = Parcel.obtain(); 4808 nr.writeToParcel(parcelW, 0); 4809 byte[] bytes = parcelW.marshall(); 4810 parcelW.recycle(); 4811 4812 Parcel parcelR = Parcel.obtain(); 4813 parcelR.unmarshall(bytes, 0, bytes.length); 4814 parcelR.setDataPosition(0); 4815 NetworkRequest rereadNr = NetworkRequest.CREATOR.createFromParcel(parcelR); 4816 }); 4817 } 4818 4819 @Test 4820 public void testNetworkRequestUidSpoofSecurityException() throws Exception { 4821 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4822 mWiFiNetworkAgent.connect(false); 4823 NetworkRequest networkRequest = newWifiRequestBuilder().build(); 4824 TestNetworkCallback networkCallback = new TestNetworkCallback(); 4825 doThrow(new SecurityException()).when(mAppOpsManager).checkPackage(anyInt(), anyString()); 4826 assertThrows(SecurityException.class, () -> { 4827 mCm.requestNetwork(networkRequest, networkCallback); 4828 }); 4829 } 4830 4831 @Test 4832 public void testInvalidSignalStrength() { 4833 NetworkRequest r = new NetworkRequest.Builder() 4834 .addCapability(NET_CAPABILITY_INTERNET) 4835 .addTransportType(TRANSPORT_WIFI) 4836 .setSignalStrength(-75) 4837 .build(); 4838 // Registering a NetworkCallback with signal strength but w/o NETWORK_SIGNAL_STRENGTH_WAKEUP 4839 // permission should get SecurityException. 4840 assertThrows(SecurityException.class, () -> 4841 mCm.registerNetworkCallback(r, new NetworkCallback())); 4842 4843 assertThrows(SecurityException.class, () -> 4844 mCm.registerNetworkCallback(r, PendingIntent.getService( 4845 mServiceContext, 0 /* requestCode */, new Intent(), FLAG_IMMUTABLE))); 4846 4847 // Requesting a Network with signal strength should get IllegalArgumentException. 4848 assertThrows(IllegalArgumentException.class, () -> 4849 mCm.requestNetwork(r, new NetworkCallback())); 4850 4851 assertThrows(IllegalArgumentException.class, () -> 4852 mCm.requestNetwork(r, PendingIntent.getService( 4853 mServiceContext, 0 /* requestCode */, new Intent(), FLAG_IMMUTABLE))); 4854 } 4855 4856 @Test 4857 public void testRegisterDefaultNetworkCallback() throws Exception { 4858 // NETWORK_SETTINGS is necessary to call registerSystemDefaultNetworkCallback. 4859 mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_GRANTED); 4860 4861 final TestNetworkCallback defaultNetworkCallback = new TestNetworkCallback(); 4862 mCm.registerDefaultNetworkCallback(defaultNetworkCallback); 4863 defaultNetworkCallback.assertNoCallback(); 4864 4865 final Handler handler = new Handler(ConnectivityThread.getInstanceLooper()); 4866 final TestNetworkCallback systemDefaultCallback = new TestNetworkCallback(); 4867 mCm.registerSystemDefaultNetworkCallback(systemDefaultCallback, handler); 4868 systemDefaultCallback.assertNoCallback(); 4869 4870 // Create a TRANSPORT_CELLULAR request to keep the mobile interface up 4871 // whenever Wi-Fi is up. Without this, the mobile network agent is 4872 // reaped before any other activity can take place. 4873 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback(); 4874 final NetworkRequest cellRequest = new NetworkRequest.Builder() 4875 .addTransportType(TRANSPORT_CELLULAR).build(); 4876 mCm.requestNetwork(cellRequest, cellNetworkCallback); 4877 cellNetworkCallback.assertNoCallback(); 4878 4879 // Bring up cell and expect CALLBACK_AVAILABLE. 4880 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 4881 mCellNetworkAgent.connect(true); 4882 cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 4883 defaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 4884 systemDefaultCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 4885 assertEquals(defaultNetworkCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 4886 assertEquals(systemDefaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 4887 4888 // Bring up wifi and expect CALLBACK_AVAILABLE. 4889 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4890 mWiFiNetworkAgent.connect(true); 4891 cellNetworkCallback.assertNoCallback(); 4892 defaultNetworkCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent); 4893 systemDefaultCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent); 4894 assertEquals(defaultNetworkCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 4895 assertEquals(systemDefaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 4896 4897 // Bring down cell. Expect no default network callback, since it wasn't the default. 4898 mCellNetworkAgent.disconnect(); 4899 cellNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 4900 defaultNetworkCallback.assertNoCallback(); 4901 systemDefaultCallback.assertNoCallback(); 4902 assertEquals(defaultNetworkCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 4903 assertEquals(systemDefaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 4904 4905 // Bring up cell. Expect no default network callback, since it won't be the default. 4906 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 4907 mCellNetworkAgent.connect(true); 4908 cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 4909 defaultNetworkCallback.assertNoCallback(); 4910 systemDefaultCallback.assertNoCallback(); 4911 assertEquals(defaultNetworkCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 4912 assertEquals(systemDefaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 4913 4914 // Bring down wifi. Expect the default network callback to notified of LOST wifi 4915 // followed by AVAILABLE cell. 4916 mWiFiNetworkAgent.disconnect(); 4917 cellNetworkCallback.assertNoCallback(); 4918 defaultNetworkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 4919 defaultNetworkCallback.expectAvailableCallbacksValidated(mCellNetworkAgent); 4920 systemDefaultCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 4921 systemDefaultCallback.expectAvailableCallbacksValidated(mCellNetworkAgent); 4922 mCellNetworkAgent.disconnect(); 4923 cellNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 4924 defaultNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 4925 systemDefaultCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 4926 waitForIdle(); 4927 assertEquals(null, mCm.getActiveNetwork()); 4928 4929 mMockVpn.establishForMyUid(); 4930 assertUidRangesUpdatedForMyUid(true); 4931 defaultNetworkCallback.expectAvailableThenValidatedCallbacks(mMockVpn); 4932 systemDefaultCallback.assertNoCallback(); 4933 assertEquals(defaultNetworkCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 4934 assertEquals(null, systemDefaultCallback.getLastAvailableNetwork()); 4935 4936 mMockVpn.disconnect(); 4937 defaultNetworkCallback.expectCallback(CallbackEntry.LOST, mMockVpn); 4938 systemDefaultCallback.assertNoCallback(); 4939 waitForIdle(); 4940 assertEquals(null, mCm.getActiveNetwork()); 4941 } 4942 4943 @Test 4944 public void testAdditionalStateCallbacks() throws Exception { 4945 // File a network request for mobile. 4946 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback(); 4947 final NetworkRequest cellRequest = new NetworkRequest.Builder() 4948 .addTransportType(TRANSPORT_CELLULAR).build(); 4949 mCm.requestNetwork(cellRequest, cellNetworkCallback); 4950 4951 // Bring up the mobile network. 4952 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 4953 mCellNetworkAgent.connect(true); 4954 4955 // We should get onAvailable(), onCapabilitiesChanged(), and 4956 // onLinkPropertiesChanged() in rapid succession. Additionally, we 4957 // should get onCapabilitiesChanged() when the mobile network validates. 4958 cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 4959 cellNetworkCallback.assertNoCallback(); 4960 4961 // Update LinkProperties. 4962 final LinkProperties lp = new LinkProperties(); 4963 lp.setInterfaceName("foonet_data0"); 4964 mCellNetworkAgent.sendLinkProperties(lp); 4965 // We should get onLinkPropertiesChanged(). 4966 cellNetworkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, 4967 mCellNetworkAgent); 4968 cellNetworkCallback.assertNoCallback(); 4969 4970 // Suspend the network. 4971 mCellNetworkAgent.suspend(); 4972 cellNetworkCallback.expectCapabilitiesWithout(NET_CAPABILITY_NOT_SUSPENDED, 4973 mCellNetworkAgent); 4974 cellNetworkCallback.expectCallback(CallbackEntry.SUSPENDED, mCellNetworkAgent); 4975 cellNetworkCallback.assertNoCallback(); 4976 assertEquals(NetworkInfo.State.SUSPENDED, mCm.getActiveNetworkInfo().getState()); 4977 4978 // Register a garden variety default network request. 4979 TestNetworkCallback dfltNetworkCallback = new TestNetworkCallback(); 4980 mCm.registerDefaultNetworkCallback(dfltNetworkCallback); 4981 // We should get onAvailable(), onCapabilitiesChanged(), onLinkPropertiesChanged(), 4982 // as well as onNetworkSuspended() in rapid succession. 4983 dfltNetworkCallback.expectAvailableAndSuspendedCallbacks(mCellNetworkAgent, true); 4984 dfltNetworkCallback.assertNoCallback(); 4985 mCm.unregisterNetworkCallback(dfltNetworkCallback); 4986 4987 mCellNetworkAgent.resume(); 4988 cellNetworkCallback.expectCapabilitiesWith(NET_CAPABILITY_NOT_SUSPENDED, 4989 mCellNetworkAgent); 4990 cellNetworkCallback.expectCallback(CallbackEntry.RESUMED, mCellNetworkAgent); 4991 cellNetworkCallback.assertNoCallback(); 4992 assertEquals(NetworkInfo.State.CONNECTED, mCm.getActiveNetworkInfo().getState()); 4993 4994 dfltNetworkCallback = new TestNetworkCallback(); 4995 mCm.registerDefaultNetworkCallback(dfltNetworkCallback); 4996 // This time onNetworkSuspended should not be called. 4997 dfltNetworkCallback.expectAvailableCallbacksValidated(mCellNetworkAgent); 4998 dfltNetworkCallback.assertNoCallback(); 4999 5000 mCm.unregisterNetworkCallback(dfltNetworkCallback); 5001 mCm.unregisterNetworkCallback(cellNetworkCallback); 5002 } 5003 5004 @Test 5005 public void testRegisterPrivilegedDefaultCallbacksRequireNetworkSettings() throws Exception { 5006 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 5007 mCellNetworkAgent.connect(false /* validated */); 5008 5009 final Handler handler = new Handler(ConnectivityThread.getInstanceLooper()); 5010 final TestNetworkCallback callback = new TestNetworkCallback(); 5011 assertThrows(SecurityException.class, 5012 () -> mCm.registerSystemDefaultNetworkCallback(callback, handler)); 5013 callback.assertNoCallback(); 5014 assertThrows(SecurityException.class, 5015 () -> mCm.registerDefaultNetworkCallbackForUid(APP1_UID, callback, handler)); 5016 callback.assertNoCallback(); 5017 5018 mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_GRANTED); 5019 mCm.registerSystemDefaultNetworkCallback(callback, handler); 5020 callback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent); 5021 mCm.unregisterNetworkCallback(callback); 5022 5023 mCm.registerDefaultNetworkCallbackForUid(APP1_UID, callback, handler); 5024 callback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent); 5025 mCm.unregisterNetworkCallback(callback); 5026 } 5027 5028 @Test 5029 public void testNetworkCallbackWithNullUids() throws Exception { 5030 final NetworkRequest request = new NetworkRequest.Builder() 5031 .removeCapability(NET_CAPABILITY_NOT_VPN) 5032 .build(); 5033 final TestNetworkCallback callback = new TestNetworkCallback(); 5034 mCm.registerNetworkCallback(request, callback); 5035 5036 // Attempt to file a callback for networks applying to another UID. This does not actually 5037 // work, because this code does not currently have permission to do so. The callback behaves 5038 // exactly the same as the one registered just above. 5039 final int otherUid = UserHandle.getUid(RESTRICTED_USER, VPN_UID); 5040 final NetworkRequest otherUidRequest = new NetworkRequest.Builder() 5041 .removeCapability(NET_CAPABILITY_NOT_VPN) 5042 .setUids(UidRange.toIntRanges(uidRangesForUids(otherUid))) 5043 .build(); 5044 final TestNetworkCallback otherUidCallback = new TestNetworkCallback(); 5045 mCm.registerNetworkCallback(otherUidRequest, otherUidCallback); 5046 5047 final NetworkRequest includeOtherUidsRequest = new NetworkRequest.Builder() 5048 .removeCapability(NET_CAPABILITY_NOT_VPN) 5049 .setIncludeOtherUidNetworks(true) 5050 .build(); 5051 final TestNetworkCallback includeOtherUidsCallback = new TestNetworkCallback(); 5052 mCm.registerNetworkCallback(includeOtherUidsRequest, includeOtherUidsCallback); 5053 5054 // Both callbacks see a network with no specifier that applies to their UID. 5055 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 5056 mWiFiNetworkAgent.connect(false /* validated */); 5057 callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 5058 otherUidCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 5059 includeOtherUidsCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 5060 mWiFiNetworkAgent.disconnect(); 5061 callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 5062 otherUidCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 5063 includeOtherUidsCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 5064 5065 // Only the includeOtherUidsCallback sees a VPN that does not apply to its UID. 5066 final UidRange range = UidRange.createForUser(UserHandle.of(RESTRICTED_USER)); 5067 final Set<UidRange> vpnRanges = Collections.singleton(range); 5068 mMockVpn.establish(new LinkProperties(), VPN_UID, vpnRanges); 5069 includeOtherUidsCallback.expectAvailableThenValidatedCallbacks(mMockVpn); 5070 callback.assertNoCallback(); 5071 otherUidCallback.assertNoCallback(); 5072 5073 mMockVpn.disconnect(); 5074 includeOtherUidsCallback.expectCallback(CallbackEntry.LOST, mMockVpn); 5075 callback.assertNoCallback(); 5076 otherUidCallback.assertNoCallback(); 5077 } 5078 5079 private static class RedactableNetworkSpecifier extends NetworkSpecifier { 5080 public static final int ID_INVALID = -1; 5081 5082 public final int networkId; 5083 5084 RedactableNetworkSpecifier(int networkId) { 5085 this.networkId = networkId; 5086 } 5087 5088 @Override 5089 public boolean canBeSatisfiedBy(NetworkSpecifier other) { 5090 return other instanceof RedactableNetworkSpecifier 5091 && this.networkId == ((RedactableNetworkSpecifier) other).networkId; 5092 } 5093 5094 @Override 5095 public NetworkSpecifier redact() { 5096 return new RedactableNetworkSpecifier(ID_INVALID); 5097 } 5098 } 5099 5100 @Test 5101 public void testNetworkCallbackWithNullUidsRedactsSpecifier() throws Exception { 5102 final RedactableNetworkSpecifier specifier = new RedactableNetworkSpecifier(42); 5103 final NetworkRequest request = new NetworkRequest.Builder() 5104 .addCapability(NET_CAPABILITY_INTERNET) 5105 .addTransportType(TRANSPORT_WIFI) 5106 .setNetworkSpecifier(specifier) 5107 .build(); 5108 final TestNetworkCallback callback = new TestNetworkCallback(); 5109 mCm.registerNetworkCallback(request, callback); 5110 5111 // Attempt to file a callback for networks applying to another UID. This does not actually 5112 // work, because this code does not currently have permission to do so. The callback behaves 5113 // exactly the same as the one registered just above. 5114 final int otherUid = UserHandle.getUid(RESTRICTED_USER, VPN_UID); 5115 final NetworkRequest otherUidRequest = new NetworkRequest.Builder() 5116 .addCapability(NET_CAPABILITY_INTERNET) 5117 .addTransportType(TRANSPORT_WIFI) 5118 .setNetworkSpecifier(specifier) 5119 .setUids(UidRange.toIntRanges(uidRangesForUids(otherUid))) 5120 .build(); 5121 final TestNetworkCallback otherUidCallback = new TestNetworkCallback(); 5122 mCm.registerNetworkCallback(otherUidRequest, otherUidCallback); 5123 5124 final NetworkRequest includeOtherUidsRequest = new NetworkRequest.Builder() 5125 .addCapability(NET_CAPABILITY_INTERNET) 5126 .addTransportType(TRANSPORT_WIFI) 5127 .setNetworkSpecifier(specifier) 5128 .setIncludeOtherUidNetworks(true) 5129 .build(); 5130 final TestNetworkCallback includeOtherUidsCallback = new TestNetworkCallback(); 5131 mCm.registerNetworkCallback(includeOtherUidsRequest, callback); 5132 5133 // Only the regular callback sees the network, because callbacks filed with no UID have 5134 // their specifiers redacted. 5135 final LinkProperties emptyLp = new LinkProperties(); 5136 final NetworkCapabilities ncTemplate = new NetworkCapabilities() 5137 .addTransportType(TRANSPORT_WIFI) 5138 .setNetworkSpecifier(specifier); 5139 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, emptyLp, ncTemplate); 5140 mWiFiNetworkAgent.connect(false /* validated */); 5141 callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 5142 otherUidCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 5143 includeOtherUidsCallback.assertNoCallback(); 5144 } 5145 5146 private void setCaptivePortalMode(int mode) { 5147 ContentResolver cr = mServiceContext.getContentResolver(); 5148 Settings.Global.putInt(cr, ConnectivitySettingsManager.CAPTIVE_PORTAL_MODE, mode); 5149 } 5150 5151 private void setAlwaysOnNetworks(boolean enable) { 5152 ContentResolver cr = mServiceContext.getContentResolver(); 5153 Settings.Global.putInt(cr, ConnectivitySettingsManager.MOBILE_DATA_ALWAYS_ON, 5154 enable ? 1 : 0); 5155 mService.updateAlwaysOnNetworks(); 5156 waitForIdle(); 5157 } 5158 5159 private void setPrivateDnsSettings(int mode, String specifier) { 5160 ConnectivitySettingsManager.setPrivateDnsMode(mServiceContext, mode); 5161 ConnectivitySettingsManager.setPrivateDnsHostname(mServiceContext, specifier); 5162 mService.updatePrivateDnsSettings(); 5163 waitForIdle(); 5164 } 5165 5166 private void setIngressRateLimit(int rateLimitInBytesPerSec) { 5167 ConnectivitySettingsManager.setIngressRateLimitInBytesPerSecond(mServiceContext, 5168 rateLimitInBytesPerSec); 5169 mService.updateIngressRateLimit(); 5170 waitForIdle(); 5171 } 5172 5173 private boolean isForegroundNetwork(TestNetworkAgentWrapper network) { 5174 NetworkCapabilities nc = mCm.getNetworkCapabilities(network.getNetwork()); 5175 assertNotNull(nc); 5176 return nc.hasCapability(NET_CAPABILITY_FOREGROUND); 5177 } 5178 5179 @Test 5180 public void testBackgroundNetworks() throws Exception { 5181 // Create a cellular background request. 5182 grantUsingBackgroundNetworksPermissionForUid(Binder.getCallingUid()); 5183 final TestNetworkCallback cellBgCallback = new TestNetworkCallback(); 5184 mCm.requestBackgroundNetwork(new NetworkRequest.Builder() 5185 .addTransportType(TRANSPORT_CELLULAR).build(), 5186 cellBgCallback, mCsHandlerThread.getThreadHandler()); 5187 5188 // Make callbacks for monitoring. 5189 final NetworkRequest request = new NetworkRequest.Builder().build(); 5190 final NetworkRequest fgRequest = new NetworkRequest.Builder() 5191 .addCapability(NET_CAPABILITY_FOREGROUND).build(); 5192 final TestNetworkCallback callback = new TestNetworkCallback(); 5193 final TestNetworkCallback fgCallback = new TestNetworkCallback(); 5194 mCm.registerNetworkCallback(request, callback); 5195 mCm.registerNetworkCallback(fgRequest, fgCallback); 5196 5197 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 5198 mCellNetworkAgent.connect(true); 5199 callback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 5200 fgCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 5201 assertTrue(isForegroundNetwork(mCellNetworkAgent)); 5202 5203 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 5204 mWiFiNetworkAgent.connect(true); 5205 5206 // When wifi connects, cell lingers. 5207 callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 5208 callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent); 5209 callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent); 5210 fgCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 5211 fgCallback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent); 5212 fgCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent); 5213 assertTrue(isForegroundNetwork(mCellNetworkAgent)); 5214 assertTrue(isForegroundNetwork(mWiFiNetworkAgent)); 5215 5216 // When lingering is complete, cell is still there but is now in the background. 5217 waitForIdle(); 5218 int timeoutMs = TEST_LINGER_DELAY_MS + TEST_LINGER_DELAY_MS / 4; 5219 fgCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent, timeoutMs); 5220 // Expect a network capabilities update sans FOREGROUND. 5221 callback.expectCapabilitiesWithout(NET_CAPABILITY_FOREGROUND, mCellNetworkAgent); 5222 assertFalse(isForegroundNetwork(mCellNetworkAgent)); 5223 assertTrue(isForegroundNetwork(mWiFiNetworkAgent)); 5224 5225 // File a cell request and check that cell comes into the foreground. 5226 final NetworkRequest cellRequest = new NetworkRequest.Builder() 5227 .addTransportType(TRANSPORT_CELLULAR).build(); 5228 final TestNetworkCallback cellCallback = new TestNetworkCallback(); 5229 mCm.requestNetwork(cellRequest, cellCallback); 5230 cellCallback.expectAvailableCallbacksValidated(mCellNetworkAgent); 5231 fgCallback.expectAvailableCallbacksValidated(mCellNetworkAgent); 5232 // Expect a network capabilities update with FOREGROUND, because the most recent 5233 // request causes its state to change. 5234 cellCallback.expectCapabilitiesWith(NET_CAPABILITY_FOREGROUND, mCellNetworkAgent); 5235 callback.expectCapabilitiesWith(NET_CAPABILITY_FOREGROUND, mCellNetworkAgent); 5236 assertTrue(isForegroundNetwork(mCellNetworkAgent)); 5237 assertTrue(isForegroundNetwork(mWiFiNetworkAgent)); 5238 5239 // Release the request. The network immediately goes into the background, since it was not 5240 // lingering. 5241 mCm.unregisterNetworkCallback(cellCallback); 5242 fgCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 5243 // Expect a network capabilities update sans FOREGROUND. 5244 callback.expectCapabilitiesWithout(NET_CAPABILITY_FOREGROUND, mCellNetworkAgent); 5245 assertFalse(isForegroundNetwork(mCellNetworkAgent)); 5246 assertTrue(isForegroundNetwork(mWiFiNetworkAgent)); 5247 5248 // Disconnect wifi and check that cell is foreground again. 5249 mWiFiNetworkAgent.disconnect(); 5250 callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 5251 fgCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 5252 fgCallback.expectAvailableCallbacksValidated(mCellNetworkAgent); 5253 assertTrue(isForegroundNetwork(mCellNetworkAgent)); 5254 5255 mCm.unregisterNetworkCallback(callback); 5256 mCm.unregisterNetworkCallback(fgCallback); 5257 mCm.unregisterNetworkCallback(cellBgCallback); 5258 } 5259 5260 @Ignore // This test has instrinsic chances of spurious failures: ignore for continuous testing. 5261 public void benchmarkRequestRegistrationAndCallbackDispatch() throws Exception { 5262 // TODO: turn this unit test into a real benchmarking test. 5263 // Benchmarks connecting and switching performance in the presence of a large number of 5264 // NetworkRequests. 5265 // 1. File NUM_REQUESTS requests. 5266 // 2. Have a network connect. Wait for NUM_REQUESTS onAvailable callbacks to fire. 5267 // 3. Have a new network connect and outscore the previous. Wait for NUM_REQUESTS onLosing 5268 // and NUM_REQUESTS onAvailable callbacks to fire. 5269 // See how long it took. 5270 final int NUM_REQUESTS = 90; 5271 final int REGISTER_TIME_LIMIT_MS = 200; 5272 final int CONNECT_TIME_LIMIT_MS = 60; 5273 final int SWITCH_TIME_LIMIT_MS = 60; 5274 final int UNREGISTER_TIME_LIMIT_MS = 20; 5275 5276 final NetworkRequest request = new NetworkRequest.Builder().clearCapabilities().build(); 5277 final NetworkCallback[] callbacks = new NetworkCallback[NUM_REQUESTS]; 5278 final CountDownLatch availableLatch = new CountDownLatch(NUM_REQUESTS); 5279 final CountDownLatch losingLatch = new CountDownLatch(NUM_REQUESTS); 5280 5281 for (int i = 0; i < NUM_REQUESTS; i++) { 5282 callbacks[i] = new NetworkCallback() { 5283 @Override public void onAvailable(Network n) { availableLatch.countDown(); } 5284 @Override public void onLosing(Network n, int t) { losingLatch.countDown(); } 5285 }; 5286 } 5287 5288 assertRunsInAtMost("Registering callbacks", REGISTER_TIME_LIMIT_MS, () -> { 5289 for (NetworkCallback cb : callbacks) { 5290 mCm.registerNetworkCallback(request, cb); 5291 } 5292 }); 5293 5294 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 5295 // Don't request that the network validate, because otherwise connect() will block until 5296 // the network gets NET_CAPABILITY_VALIDATED, after all the callbacks below have fired, 5297 // and we won't actually measure anything. 5298 mCellNetworkAgent.connect(false); 5299 5300 long onAvailableDispatchingDuration = durationOf(() -> { 5301 await(availableLatch, 10 * CONNECT_TIME_LIMIT_MS); 5302 }); 5303 Log.d(TAG, String.format("Dispatched %d of %d onAvailable callbacks in %dms", 5304 NUM_REQUESTS - availableLatch.getCount(), NUM_REQUESTS, 5305 onAvailableDispatchingDuration)); 5306 assertTrue(String.format("Dispatching %d onAvailable callbacks in %dms, expected %dms", 5307 NUM_REQUESTS, onAvailableDispatchingDuration, CONNECT_TIME_LIMIT_MS), 5308 onAvailableDispatchingDuration <= CONNECT_TIME_LIMIT_MS); 5309 5310 // Give wifi a high enough score that we'll linger cell when wifi comes up. 5311 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 5312 mWiFiNetworkAgent.adjustScore(40); 5313 mWiFiNetworkAgent.connect(false); 5314 5315 long onLostDispatchingDuration = durationOf(() -> { 5316 await(losingLatch, 10 * SWITCH_TIME_LIMIT_MS); 5317 }); 5318 Log.d(TAG, String.format("Dispatched %d of %d onLosing callbacks in %dms", 5319 NUM_REQUESTS - losingLatch.getCount(), NUM_REQUESTS, onLostDispatchingDuration)); 5320 assertTrue(String.format("Dispatching %d onLosing callbacks in %dms, expected %dms", 5321 NUM_REQUESTS, onLostDispatchingDuration, SWITCH_TIME_LIMIT_MS), 5322 onLostDispatchingDuration <= SWITCH_TIME_LIMIT_MS); 5323 5324 assertRunsInAtMost("Unregistering callbacks", UNREGISTER_TIME_LIMIT_MS, () -> { 5325 for (NetworkCallback cb : callbacks) { 5326 mCm.unregisterNetworkCallback(cb); 5327 } 5328 }); 5329 } 5330 5331 @Test 5332 public void testMobileDataAlwaysOn() throws Exception { 5333 grantUsingBackgroundNetworksPermissionForUid(Binder.getCallingUid()); 5334 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback(); 5335 final NetworkRequest cellRequest = new NetworkRequest.Builder() 5336 .addTransportType(TRANSPORT_CELLULAR).build(); 5337 mCm.registerNetworkCallback(cellRequest, cellNetworkCallback); 5338 5339 final HandlerThread handlerThread = new HandlerThread("MobileDataAlwaysOnFactory"); 5340 handlerThread.start(); 5341 NetworkCapabilities filter = new NetworkCapabilities() 5342 .addTransportType(TRANSPORT_CELLULAR) 5343 .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED) 5344 .addCapability(NET_CAPABILITY_INTERNET); 5345 final MockNetworkFactory testFactory = new MockNetworkFactory(handlerThread.getLooper(), 5346 mServiceContext, "testFactory", filter, mCsHandlerThread); 5347 testFactory.setScoreFilter(40); 5348 5349 // Register the factory and expect it to start looking for a network. 5350 testFactory.register(); 5351 5352 try { 5353 // Expect the factory to receive the default network request. 5354 testFactory.expectRequestAdd(); 5355 testFactory.assertRequestCountEquals(1); 5356 assertTrue(testFactory.getMyStartRequested()); 5357 5358 // Bring up wifi. The factory stops looking for a network. 5359 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 5360 // Score 60 - 40 penalty for not validated yet, then 60 when it validates 5361 mWiFiNetworkAgent.connect(true); 5362 // The network connects with a low score, so the offer can still beat it and 5363 // nothing happens. Then the network validates, and the offer with its filter score 5364 // of 40 can no longer beat it and the request is removed. 5365 testFactory.expectRequestRemove(); 5366 testFactory.assertRequestCountEquals(0); 5367 5368 assertFalse(testFactory.getMyStartRequested()); 5369 5370 // Turn on mobile data always on. This request will not match the wifi request, so 5371 // it will be sent to the test factory whose filters allow to see it. 5372 setAlwaysOnNetworks(true); 5373 testFactory.expectRequestAdd(); 5374 testFactory.assertRequestCountEquals(1); 5375 5376 assertTrue(testFactory.getMyStartRequested()); 5377 5378 // Bring up cell data and check that the factory stops looking. 5379 assertLength(1, mCm.getAllNetworks()); 5380 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 5381 mCellNetworkAgent.connect(false); 5382 cellNetworkCallback.expectAvailableCallbacks(mCellNetworkAgent, false, false, false, 5383 TEST_CALLBACK_TIMEOUT_MS); 5384 // When cell connects, it will satisfy the "mobile always on request" right away 5385 // by virtue of being the only network that can satisfy the request. However, its 5386 // score is low (50 - 40 = 10) so the test factory can still hope to beat it. 5387 expectNoRequestChanged(testFactory); 5388 5389 // Next, cell validates. This gives it a score of 50 and the test factory can't 5390 // hope to beat that according to its filters. It will see the message that its 5391 // offer is now unnecessary. 5392 mCellNetworkAgent.setNetworkValid(true); 5393 // Need a trigger point to let NetworkMonitor tell ConnectivityService that network is 5394 // validated – see testPartialConnectivity. 5395 mCm.reportNetworkConnectivity(mCellNetworkAgent.getNetwork(), true); 5396 cellNetworkCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mCellNetworkAgent); 5397 testFactory.expectRequestRemove(); 5398 testFactory.assertRequestCountEquals(0); 5399 // Accordingly, the factory shouldn't be started. 5400 assertFalse(testFactory.getMyStartRequested()); 5401 5402 // Check that cell data stays up. 5403 waitForIdle(); 5404 verifyActiveNetwork(TRANSPORT_WIFI); 5405 assertLength(2, mCm.getAllNetworks()); 5406 5407 // Cell disconnects. There is still the "mobile data always on" request outstanding, 5408 // and the test factory should see it now that it isn't hopelessly outscored. 5409 mCellNetworkAgent.disconnect(); 5410 cellNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 5411 // Wait for the network to be removed from internal structures before 5412 // calling synchronous getter 5413 waitForIdle(); 5414 assertLength(1, mCm.getAllNetworks()); 5415 testFactory.expectRequestAdd(); 5416 testFactory.assertRequestCountEquals(1); 5417 5418 // Reconnect cell validated, see the request disappear again. Then withdraw the 5419 // mobile always on request. This will tear down cell, and there shouldn't be a 5420 // blip where the test factory briefly sees the request or anything. 5421 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 5422 mCellNetworkAgent.connect(true); 5423 cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 5424 waitForIdle(); 5425 assertLength(2, mCm.getAllNetworks()); 5426 testFactory.expectRequestRemove(); 5427 testFactory.assertRequestCountEquals(0); 5428 setAlwaysOnNetworks(false); 5429 expectNoRequestChanged(testFactory); 5430 testFactory.assertRequestCountEquals(0); 5431 assertFalse(testFactory.getMyStartRequested()); 5432 // ... and cell data to be torn down immediately since it is no longer nascent. 5433 cellNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 5434 waitForIdle(); 5435 assertLength(1, mCm.getAllNetworks()); 5436 testFactory.terminate(); 5437 testFactory.assertNoRequestChanged(); 5438 } finally { 5439 mCm.unregisterNetworkCallback(cellNetworkCallback); 5440 handlerThread.quit(); 5441 } 5442 } 5443 5444 @Test 5445 public void testSetAllowBadWifiUntil() throws Exception { 5446 runAsShell(NETWORK_SETTINGS, 5447 () -> mService.setTestAllowBadWifiUntil(System.currentTimeMillis() + 5_000L)); 5448 waitForIdle(); 5449 testAvoidBadWifiConfig_controlledBySettings(); 5450 5451 runAsShell(NETWORK_SETTINGS, 5452 () -> mService.setTestAllowBadWifiUntil(System.currentTimeMillis() - 5_000L)); 5453 waitForIdle(); 5454 testAvoidBadWifiConfig_ignoreSettings(); 5455 } 5456 5457 private void testAvoidBadWifiConfig_controlledBySettings() { 5458 final ContentResolver cr = mServiceContext.getContentResolver(); 5459 final String settingName = ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI; 5460 5461 Settings.Global.putString(cr, settingName, "0"); 5462 mPolicyTracker.reevaluate(); 5463 waitForIdle(); 5464 assertFalse(mService.avoidBadWifi()); 5465 assertFalse(mPolicyTracker.shouldNotifyWifiUnvalidated()); 5466 5467 Settings.Global.putString(cr, settingName, "1"); 5468 mPolicyTracker.reevaluate(); 5469 waitForIdle(); 5470 assertTrue(mService.avoidBadWifi()); 5471 assertFalse(mPolicyTracker.shouldNotifyWifiUnvalidated()); 5472 5473 Settings.Global.putString(cr, settingName, null); 5474 mPolicyTracker.reevaluate(); 5475 waitForIdle(); 5476 assertFalse(mService.avoidBadWifi()); 5477 assertTrue(mPolicyTracker.shouldNotifyWifiUnvalidated()); 5478 } 5479 5480 private void testAvoidBadWifiConfig_ignoreSettings() { 5481 final ContentResolver cr = mServiceContext.getContentResolver(); 5482 final String settingName = ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI; 5483 5484 String[] values = new String[] {null, "0", "1"}; 5485 for (int i = 0; i < values.length; i++) { 5486 Settings.Global.putString(cr, settingName, values[i]); 5487 mPolicyTracker.reevaluate(); 5488 waitForIdle(); 5489 String msg = String.format("config=false, setting=%s", values[i]); 5490 assertTrue(mService.avoidBadWifi()); 5491 assertFalse(msg, mPolicyTracker.shouldNotifyWifiUnvalidated()); 5492 } 5493 } 5494 5495 @Test 5496 public void testAvoidBadWifiSetting() throws Exception { 5497 doReturn(1).when(mResources).getInteger(R.integer.config_networkAvoidBadWifi); 5498 testAvoidBadWifiConfig_ignoreSettings(); 5499 5500 doReturn(0).when(mResources).getInteger(R.integer.config_networkAvoidBadWifi); 5501 testAvoidBadWifiConfig_controlledBySettings(); 5502 } 5503 5504 @Test 5505 public void testOffersAvoidsBadWifi() throws Exception { 5506 // Normal mode : the carrier doesn't restrict moving away from bad wifi. 5507 // This has getAvoidBadWifi return true. 5508 doReturn(1).when(mResources).getInteger(R.integer.config_networkAvoidBadWifi); 5509 // Don't request cell separately for the purposes of this test. 5510 setAlwaysOnNetworks(false); 5511 5512 final NetworkProvider cellProvider = new NetworkProvider(mServiceContext, 5513 mCsHandlerThread.getLooper(), "Cell provider"); 5514 final NetworkProvider wifiProvider = new NetworkProvider(mServiceContext, 5515 mCsHandlerThread.getLooper(), "Wifi provider"); 5516 5517 mCm.registerNetworkProvider(cellProvider); 5518 mCm.registerNetworkProvider(wifiProvider); 5519 5520 final NetworkScore cellScore = new NetworkScore.Builder().build(); 5521 final NetworkScore wifiScore = new NetworkScore.Builder().build(); 5522 final NetworkCapabilities defaultCaps = new NetworkCapabilities.Builder() 5523 .addCapability(NET_CAPABILITY_INTERNET) 5524 .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED) 5525 .build(); 5526 final NetworkCapabilities cellCaps = new NetworkCapabilities.Builder() 5527 .addTransportType(TRANSPORT_CELLULAR) 5528 .addCapability(NET_CAPABILITY_INTERNET) 5529 .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED) 5530 .build(); 5531 final NetworkCapabilities wifiCaps = new NetworkCapabilities.Builder() 5532 .addTransportType(TRANSPORT_WIFI) 5533 .addCapability(NET_CAPABILITY_INTERNET) 5534 .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED) 5535 .build(); 5536 final TestableNetworkOfferCallback cellCallback = new TestableNetworkOfferCallback( 5537 TIMEOUT_MS /* timeout */, TEST_CALLBACK_TIMEOUT_MS /* noCallbackTimeout */); 5538 final TestableNetworkOfferCallback wifiCallback = new TestableNetworkOfferCallback( 5539 TIMEOUT_MS /* timeout */, TEST_CALLBACK_TIMEOUT_MS /* noCallbackTimeout */); 5540 5541 // Offer callbacks will run on the CS handler thread in this test. 5542 cellProvider.registerNetworkOffer(cellScore, cellCaps, r -> r.run(), cellCallback); 5543 wifiProvider.registerNetworkOffer(wifiScore, wifiCaps, r -> r.run(), wifiCallback); 5544 5545 // Both providers see the default request. 5546 cellCallback.expectOnNetworkNeeded(defaultCaps); 5547 wifiCallback.expectOnNetworkNeeded(defaultCaps); 5548 5549 // Listen to cell and wifi to know when agents are finished processing 5550 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback(); 5551 final NetworkRequest cellRequest = new NetworkRequest.Builder() 5552 .addTransportType(TRANSPORT_CELLULAR).build(); 5553 mCm.registerNetworkCallback(cellRequest, cellNetworkCallback); 5554 final TestNetworkCallback wifiNetworkCallback = new TestNetworkCallback(); 5555 final NetworkRequest wifiRequest = new NetworkRequest.Builder() 5556 .addTransportType(TRANSPORT_WIFI).build(); 5557 mCm.registerNetworkCallback(wifiRequest, wifiNetworkCallback); 5558 5559 // Cell connects and validates. 5560 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, 5561 new LinkProperties(), null /* ncTemplate */, cellProvider); 5562 mCellNetworkAgent.connect(true); 5563 cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 5564 cellCallback.assertNoCallback(); 5565 wifiCallback.assertNoCallback(); 5566 5567 // Bring up wifi. At first it's invalidated, so cell is still needed. 5568 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, 5569 new LinkProperties(), null /* ncTemplate */, wifiProvider); 5570 mWiFiNetworkAgent.connect(false); 5571 wifiNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 5572 cellCallback.assertNoCallback(); 5573 wifiCallback.assertNoCallback(); 5574 5575 // Wifi validates. Cell is no longer needed, because it's outscored. 5576 mWiFiNetworkAgent.setNetworkValid(true /* isStrictMode */); 5577 // Have CS reconsider the network (see testPartialConnectivity) 5578 mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), true); 5579 wifiNetworkCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent); 5580 cellCallback.expectOnNetworkUnneeded(defaultCaps); 5581 wifiCallback.assertNoCallback(); 5582 5583 // Wifi is no longer validated. Cell is needed again. 5584 mWiFiNetworkAgent.setNetworkInvalid(true /* isStrictMode */); 5585 mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), false); 5586 wifiNetworkCallback.expectCapabilitiesWithout(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent); 5587 cellCallback.expectOnNetworkNeeded(defaultCaps); 5588 wifiCallback.assertNoCallback(); 5589 5590 // Disconnect wifi and pretend the carrier restricts moving away from bad wifi. 5591 mWiFiNetworkAgent.disconnect(); 5592 wifiNetworkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 5593 // This has getAvoidBadWifi return false. This test doesn't change the value of the 5594 // associated setting. 5595 doReturn(0).when(mResources).getInteger(R.integer.config_networkAvoidBadWifi); 5596 mPolicyTracker.reevaluate(); 5597 waitForIdle(); 5598 5599 // Connect wifi again, cell is needed until wifi validates. 5600 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, 5601 new LinkProperties(), null /* ncTemplate */, wifiProvider); 5602 mWiFiNetworkAgent.connect(false); 5603 wifiNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 5604 cellCallback.assertNoCallback(); 5605 wifiCallback.assertNoCallback(); 5606 mWiFiNetworkAgent.setNetworkValid(true /* isStrictMode */); 5607 mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), true); 5608 wifiNetworkCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent); 5609 cellCallback.expectOnNetworkUnneeded(defaultCaps); 5610 wifiCallback.assertNoCallback(); 5611 5612 // Wifi loses validation. Because the device doesn't avoid bad wifis, cell is 5613 // not needed. 5614 mWiFiNetworkAgent.setNetworkInvalid(true /* isStrictMode */); 5615 mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), false); 5616 wifiNetworkCallback.expectCapabilitiesWithout(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent); 5617 cellCallback.assertNoCallback(); 5618 wifiCallback.assertNoCallback(); 5619 } 5620 5621 @Test 5622 public void testAvoidBadWifi() throws Exception { 5623 final ContentResolver cr = mServiceContext.getContentResolver(); 5624 5625 // Pretend we're on a carrier that restricts switching away from bad wifi. 5626 doReturn(0).when(mResources).getInteger(R.integer.config_networkAvoidBadWifi); 5627 5628 // File a request for cell to ensure it doesn't go down. 5629 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback(); 5630 final NetworkRequest cellRequest = new NetworkRequest.Builder() 5631 .addTransportType(TRANSPORT_CELLULAR).build(); 5632 mCm.requestNetwork(cellRequest, cellNetworkCallback); 5633 5634 TestNetworkCallback defaultCallback = new TestNetworkCallback(); 5635 mCm.registerDefaultNetworkCallback(defaultCallback); 5636 5637 NetworkRequest validatedWifiRequest = new NetworkRequest.Builder() 5638 .addTransportType(TRANSPORT_WIFI) 5639 .addCapability(NET_CAPABILITY_VALIDATED) 5640 .build(); 5641 TestNetworkCallback validatedWifiCallback = new TestNetworkCallback(); 5642 mCm.registerNetworkCallback(validatedWifiRequest, validatedWifiCallback); 5643 5644 Settings.Global.putInt(cr, ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI, 0); 5645 mPolicyTracker.reevaluate(); 5646 5647 // Bring up validated cell. 5648 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 5649 mCellNetworkAgent.connect(true); 5650 cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 5651 defaultCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 5652 Network cellNetwork = mCellNetworkAgent.getNetwork(); 5653 5654 // Bring up validated wifi. 5655 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 5656 mWiFiNetworkAgent.connect(true); 5657 defaultCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent); 5658 validatedWifiCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent); 5659 Network wifiNetwork = mWiFiNetworkAgent.getNetwork(); 5660 5661 // Fail validation on wifi. 5662 mWiFiNetworkAgent.setNetworkInvalid(false /* isStrictMode */); 5663 mCm.reportNetworkConnectivity(wifiNetwork, false); 5664 defaultCallback.expectCapabilitiesWithout(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent); 5665 validatedWifiCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 5666 5667 // Because avoid bad wifi is off, we don't switch to cellular. 5668 defaultCallback.assertNoCallback(); 5669 assertFalse(mCm.getNetworkCapabilities(wifiNetwork).hasCapability( 5670 NET_CAPABILITY_VALIDATED)); 5671 assertTrue(mCm.getNetworkCapabilities(cellNetwork).hasCapability( 5672 NET_CAPABILITY_VALIDATED)); 5673 assertEquals(mCm.getActiveNetwork(), wifiNetwork); 5674 5675 // Simulate switching to a carrier that does not restrict avoiding bad wifi, and expect 5676 // that we switch back to cell. 5677 doReturn(1).when(mResources).getInteger(R.integer.config_networkAvoidBadWifi); 5678 mPolicyTracker.reevaluate(); 5679 defaultCallback.expectAvailableCallbacksValidated(mCellNetworkAgent); 5680 assertEquals(mCm.getActiveNetwork(), cellNetwork); 5681 5682 // Switch back to a restrictive carrier. 5683 doReturn(0).when(mResources).getInteger(R.integer.config_networkAvoidBadWifi); 5684 mPolicyTracker.reevaluate(); 5685 defaultCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 5686 assertEquals(mCm.getActiveNetwork(), wifiNetwork); 5687 5688 // Simulate the user selecting "switch" on the dialog, and check that we switch to cell. 5689 mCm.setAvoidUnvalidated(wifiNetwork); 5690 defaultCallback.expectAvailableCallbacksValidated(mCellNetworkAgent); 5691 assertFalse(mCm.getNetworkCapabilities(wifiNetwork).hasCapability( 5692 NET_CAPABILITY_VALIDATED)); 5693 assertTrue(mCm.getNetworkCapabilities(cellNetwork).hasCapability( 5694 NET_CAPABILITY_VALIDATED)); 5695 assertEquals(mCm.getActiveNetwork(), cellNetwork); 5696 5697 // Disconnect and reconnect wifi to clear the one-time switch above. 5698 mWiFiNetworkAgent.disconnect(); 5699 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 5700 mWiFiNetworkAgent.connect(true); 5701 defaultCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent); 5702 validatedWifiCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent); 5703 wifiNetwork = mWiFiNetworkAgent.getNetwork(); 5704 5705 // Fail validation on wifi and expect the dialog to appear. 5706 mWiFiNetworkAgent.setNetworkInvalid(false /* isStrictMode */); 5707 mCm.reportNetworkConnectivity(wifiNetwork, false); 5708 defaultCallback.expectCapabilitiesWithout(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent); 5709 validatedWifiCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 5710 5711 // Simulate the user selecting "switch" and checking the don't ask again checkbox. 5712 Settings.Global.putInt(cr, ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI, 1); 5713 mPolicyTracker.reevaluate(); 5714 5715 // We now switch to cell. 5716 defaultCallback.expectAvailableCallbacksValidated(mCellNetworkAgent); 5717 assertFalse(mCm.getNetworkCapabilities(wifiNetwork).hasCapability( 5718 NET_CAPABILITY_VALIDATED)); 5719 assertTrue(mCm.getNetworkCapabilities(cellNetwork).hasCapability( 5720 NET_CAPABILITY_VALIDATED)); 5721 assertEquals(mCm.getActiveNetwork(), cellNetwork); 5722 5723 // Simulate the user turning the cellular fallback setting off and then on. 5724 // We switch to wifi and then to cell. 5725 Settings.Global.putString(cr, ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI, null); 5726 mPolicyTracker.reevaluate(); 5727 defaultCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 5728 assertEquals(mCm.getActiveNetwork(), wifiNetwork); 5729 Settings.Global.putInt(cr, ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI, 1); 5730 mPolicyTracker.reevaluate(); 5731 defaultCallback.expectAvailableCallbacksValidated(mCellNetworkAgent); 5732 assertEquals(mCm.getActiveNetwork(), cellNetwork); 5733 5734 // If cell goes down, we switch to wifi. 5735 mCellNetworkAgent.disconnect(); 5736 defaultCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 5737 defaultCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 5738 validatedWifiCallback.assertNoCallback(); 5739 5740 mCm.unregisterNetworkCallback(cellNetworkCallback); 5741 mCm.unregisterNetworkCallback(validatedWifiCallback); 5742 mCm.unregisterNetworkCallback(defaultCallback); 5743 } 5744 5745 @Test 5746 public void testMeteredMultipathPreferenceSetting() throws Exception { 5747 final ContentResolver cr = mServiceContext.getContentResolver(); 5748 final String settingName = ConnectivitySettingsManager.NETWORK_METERED_MULTIPATH_PREFERENCE; 5749 5750 for (int config : asList(0, 3, 2)) { 5751 for (String setting: asList(null, "0", "2", "1")) { 5752 mPolicyTracker.mConfigMeteredMultipathPreference = config; 5753 Settings.Global.putString(cr, settingName, setting); 5754 mPolicyTracker.reevaluate(); 5755 waitForIdle(); 5756 5757 final int expected = (setting != null) ? Integer.parseInt(setting) : config; 5758 String msg = String.format("config=%d, setting=%s", config, setting); 5759 assertEquals(msg, expected, mCm.getMultipathPreference(null)); 5760 } 5761 } 5762 } 5763 5764 /** 5765 * Validate that a satisfied network request does not trigger onUnavailable() once the 5766 * time-out period expires. 5767 */ 5768 @Test 5769 public void testSatisfiedNetworkRequestDoesNotTriggerOnUnavailable() throws Exception { 5770 NetworkRequest nr = new NetworkRequest.Builder().addTransportType( 5771 NetworkCapabilities.TRANSPORT_WIFI).build(); 5772 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 5773 mCm.requestNetwork(nr, networkCallback, TEST_REQUEST_TIMEOUT_MS); 5774 5775 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 5776 mWiFiNetworkAgent.connect(false); 5777 networkCallback.expectAvailableCallbacks(mWiFiNetworkAgent, false, false, false, 5778 TEST_CALLBACK_TIMEOUT_MS); 5779 5780 // pass timeout and validate that UNAVAILABLE is not called 5781 networkCallback.assertNoCallback(); 5782 } 5783 5784 /** 5785 * Validate that a satisfied network request followed by a disconnected (lost) network does 5786 * not trigger onUnavailable() once the time-out period expires. 5787 */ 5788 @Test 5789 public void testSatisfiedThenLostNetworkRequestDoesNotTriggerOnUnavailable() throws Exception { 5790 NetworkRequest nr = new NetworkRequest.Builder().addTransportType( 5791 NetworkCapabilities.TRANSPORT_WIFI).build(); 5792 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 5793 mCm.requestNetwork(nr, networkCallback, TEST_REQUEST_TIMEOUT_MS); 5794 5795 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 5796 mWiFiNetworkAgent.connect(false); 5797 networkCallback.expectAvailableCallbacks(mWiFiNetworkAgent, false, false, false, 5798 TEST_CALLBACK_TIMEOUT_MS); 5799 mWiFiNetworkAgent.disconnect(); 5800 networkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 5801 5802 // Validate that UNAVAILABLE is not called 5803 networkCallback.assertNoCallback(); 5804 } 5805 5806 /** 5807 * Validate that when a time-out is specified for a network request the onUnavailable() 5808 * callback is called when time-out expires. Then validate that if network request is 5809 * (somehow) satisfied - the callback isn't called later. 5810 */ 5811 @Test 5812 public void testTimedoutNetworkRequest() throws Exception { 5813 NetworkRequest nr = new NetworkRequest.Builder().addTransportType( 5814 NetworkCapabilities.TRANSPORT_WIFI).build(); 5815 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 5816 final int timeoutMs = 10; 5817 mCm.requestNetwork(nr, networkCallback, timeoutMs); 5818 5819 // pass timeout and validate that UNAVAILABLE is called 5820 networkCallback.expectCallback(CallbackEntry.UNAVAILABLE, (Network) null); 5821 5822 // create a network satisfying request - validate that request not triggered 5823 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 5824 mWiFiNetworkAgent.connect(false); 5825 networkCallback.assertNoCallback(); 5826 } 5827 5828 /** 5829 * Validate that when a network request is unregistered (cancelled), no posterior event can 5830 * trigger the callback. 5831 */ 5832 @Test 5833 public void testNoCallbackAfterUnregisteredNetworkRequest() throws Exception { 5834 NetworkRequest nr = new NetworkRequest.Builder().addTransportType( 5835 NetworkCapabilities.TRANSPORT_WIFI).build(); 5836 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 5837 final int timeoutMs = 10; 5838 5839 mCm.requestNetwork(nr, networkCallback, timeoutMs); 5840 mCm.unregisterNetworkCallback(networkCallback); 5841 // Regardless of the timeout, unregistering the callback in ConnectivityManager ensures 5842 // that this callback will not be called. 5843 networkCallback.assertNoCallback(); 5844 5845 // create a network satisfying request - validate that request not triggered 5846 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 5847 mWiFiNetworkAgent.connect(false); 5848 networkCallback.assertNoCallback(); 5849 } 5850 5851 @Test 5852 public void testUnfulfillableNetworkRequest() throws Exception { 5853 runUnfulfillableNetworkRequest(false); 5854 } 5855 5856 @Test 5857 public void testUnfulfillableNetworkRequestAfterUnregister() throws Exception { 5858 runUnfulfillableNetworkRequest(true); 5859 } 5860 5861 /** 5862 * Validate the callback flow for a factory releasing a request as unfulfillable. 5863 */ 5864 private void runUnfulfillableNetworkRequest(boolean preUnregister) throws Exception { 5865 NetworkRequest nr = new NetworkRequest.Builder().addTransportType( 5866 NetworkCapabilities.TRANSPORT_WIFI).build(); 5867 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 5868 5869 final HandlerThread handlerThread = new HandlerThread("testUnfulfillableNetworkRequest"); 5870 handlerThread.start(); 5871 NetworkCapabilities filter = new NetworkCapabilities() 5872 .addTransportType(TRANSPORT_WIFI) 5873 .addCapability(NET_CAPABILITY_INTERNET) 5874 .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED); 5875 final MockNetworkFactory testFactory = new MockNetworkFactory(handlerThread.getLooper(), 5876 mServiceContext, "testFactory", filter, mCsHandlerThread); 5877 testFactory.setScoreFilter(40); 5878 5879 // Register the factory and expect it to receive the default request. 5880 testFactory.register(); 5881 testFactory.expectRequestAdd(); 5882 5883 try { 5884 // Now file the test request and expect it. 5885 mCm.requestNetwork(nr, networkCallback); 5886 final NetworkRequest newRequest = testFactory.expectRequestAdd().request; 5887 5888 if (preUnregister) { 5889 mCm.unregisterNetworkCallback(networkCallback); 5890 5891 // The request has been released : the factory should see it removed 5892 // immediately. 5893 testFactory.expectRequestRemove(); 5894 5895 // Simulate the factory releasing the request as unfulfillable: no-op since 5896 // the callback has already been unregistered (but a test that no exceptions are 5897 // thrown). 5898 testFactory.triggerUnfulfillable(newRequest); 5899 } else { 5900 // Simulate the factory releasing the request as unfulfillable and expect 5901 // onUnavailable! 5902 testFactory.triggerUnfulfillable(newRequest); 5903 5904 networkCallback.expectCallback(CallbackEntry.UNAVAILABLE, (Network) null); 5905 5906 // Declaring a request unfulfillable releases it automatically. 5907 testFactory.expectRequestRemove(); 5908 5909 // unregister network callback - a no-op (since already freed by the 5910 // on-unavailable), but should not fail or throw exceptions. 5911 mCm.unregisterNetworkCallback(networkCallback); 5912 5913 // The factory should not see any further removal, as this request has 5914 // already been removed. 5915 } 5916 } finally { 5917 testFactory.terminate(); 5918 handlerThread.quit(); 5919 } 5920 } 5921 5922 /** 5923 * Validate the service throws if request with CBS but without carrier privilege. 5924 */ 5925 @Test 5926 public void testCBSRequestWithoutCarrierPrivilege() throws Exception { 5927 final NetworkRequest nr = new NetworkRequest.Builder().addTransportType( 5928 TRANSPORT_CELLULAR).addCapability(NET_CAPABILITY_CBS).build(); 5929 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 5930 5931 mServiceContext.setPermission(CONNECTIVITY_USE_RESTRICTED_NETWORKS, PERMISSION_DENIED); 5932 // Now file the test request and expect the service throws. 5933 assertThrows(SecurityException.class, () -> mCm.requestNetwork(nr, networkCallback)); 5934 } 5935 5936 private static class TestKeepaliveCallback extends PacketKeepaliveCallback { 5937 5938 public enum CallbackType { ON_STARTED, ON_STOPPED, ON_ERROR } 5939 5940 private class CallbackValue { 5941 public CallbackType callbackType; 5942 public int error; 5943 5944 public CallbackValue(CallbackType type) { 5945 this.callbackType = type; 5946 this.error = PacketKeepalive.SUCCESS; 5947 assertTrue("onError callback must have error", type != CallbackType.ON_ERROR); 5948 } 5949 5950 public CallbackValue(CallbackType type, int error) { 5951 this.callbackType = type; 5952 this.error = error; 5953 assertEquals("error can only be set for onError", type, CallbackType.ON_ERROR); 5954 } 5955 5956 @Override 5957 public boolean equals(Object o) { 5958 return o instanceof CallbackValue && 5959 this.callbackType == ((CallbackValue) o).callbackType && 5960 this.error == ((CallbackValue) o).error; 5961 } 5962 5963 @Override 5964 public String toString() { 5965 return String.format("%s(%s, %d)", getClass().getSimpleName(), callbackType, error); 5966 } 5967 } 5968 5969 private final LinkedBlockingQueue<CallbackValue> mCallbacks = new LinkedBlockingQueue<>(); 5970 5971 @Override 5972 public void onStarted() { 5973 mCallbacks.add(new CallbackValue(CallbackType.ON_STARTED)); 5974 } 5975 5976 @Override 5977 public void onStopped() { 5978 mCallbacks.add(new CallbackValue(CallbackType.ON_STOPPED)); 5979 } 5980 5981 @Override 5982 public void onError(int error) { 5983 mCallbacks.add(new CallbackValue(CallbackType.ON_ERROR, error)); 5984 } 5985 5986 private void expectCallback(CallbackValue callbackValue) throws InterruptedException { 5987 assertEquals(callbackValue, mCallbacks.poll(TIMEOUT_MS, TimeUnit.MILLISECONDS)); 5988 } 5989 5990 public void expectStarted() throws Exception { 5991 expectCallback(new CallbackValue(CallbackType.ON_STARTED)); 5992 } 5993 5994 public void expectStopped() throws Exception { 5995 expectCallback(new CallbackValue(CallbackType.ON_STOPPED)); 5996 } 5997 5998 public void expectError(int error) throws Exception { 5999 expectCallback(new CallbackValue(CallbackType.ON_ERROR, error)); 6000 } 6001 } 6002 6003 private static class TestSocketKeepaliveCallback extends SocketKeepalive.Callback { 6004 6005 public enum CallbackType { ON_STARTED, ON_STOPPED, ON_ERROR }; 6006 6007 private class CallbackValue { 6008 public CallbackType callbackType; 6009 public int error; 6010 6011 CallbackValue(CallbackType type) { 6012 this.callbackType = type; 6013 this.error = SocketKeepalive.SUCCESS; 6014 assertTrue("onError callback must have error", type != CallbackType.ON_ERROR); 6015 } 6016 6017 CallbackValue(CallbackType type, int error) { 6018 this.callbackType = type; 6019 this.error = error; 6020 assertEquals("error can only be set for onError", type, CallbackType.ON_ERROR); 6021 } 6022 6023 @Override 6024 public boolean equals(Object o) { 6025 return o instanceof CallbackValue 6026 && this.callbackType == ((CallbackValue) o).callbackType 6027 && this.error == ((CallbackValue) o).error; 6028 } 6029 6030 @Override 6031 public String toString() { 6032 return String.format("%s(%s, %d)", getClass().getSimpleName(), callbackType, 6033 error); 6034 } 6035 } 6036 6037 private LinkedBlockingQueue<CallbackValue> mCallbacks = new LinkedBlockingQueue<>(); 6038 private final Executor mExecutor; 6039 6040 TestSocketKeepaliveCallback(@NonNull Executor executor) { 6041 mExecutor = executor; 6042 } 6043 6044 @Override 6045 public void onStarted() { 6046 mCallbacks.add(new CallbackValue(CallbackType.ON_STARTED)); 6047 } 6048 6049 @Override 6050 public void onStopped() { 6051 mCallbacks.add(new CallbackValue(CallbackType.ON_STOPPED)); 6052 } 6053 6054 @Override 6055 public void onError(int error) { 6056 mCallbacks.add(new CallbackValue(CallbackType.ON_ERROR, error)); 6057 } 6058 6059 private void expectCallback(CallbackValue callbackValue) throws InterruptedException { 6060 assertEquals(callbackValue, mCallbacks.poll(TIMEOUT_MS, TimeUnit.MILLISECONDS)); 6061 6062 } 6063 6064 public void expectStarted() throws InterruptedException { 6065 expectCallback(new CallbackValue(CallbackType.ON_STARTED)); 6066 } 6067 6068 public void expectStopped() throws InterruptedException { 6069 expectCallback(new CallbackValue(CallbackType.ON_STOPPED)); 6070 } 6071 6072 public void expectError(int error) throws InterruptedException { 6073 expectCallback(new CallbackValue(CallbackType.ON_ERROR, error)); 6074 } 6075 6076 public void assertNoCallback() { 6077 waitForIdleSerialExecutor(mExecutor, TIMEOUT_MS); 6078 CallbackValue cv = mCallbacks.peek(); 6079 assertNull("Unexpected callback: " + cv, cv); 6080 } 6081 } 6082 6083 private Network connectKeepaliveNetwork(LinkProperties lp) throws Exception { 6084 // Ensure the network is disconnected before anything else occurs 6085 if (mWiFiNetworkAgent != null) { 6086 assertNull(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork())); 6087 } 6088 6089 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 6090 ExpectedBroadcast b = expectConnectivityAction(TYPE_WIFI, DetailedState.CONNECTED); 6091 mWiFiNetworkAgent.connect(true); 6092 b.expectBroadcast(); 6093 verifyActiveNetwork(TRANSPORT_WIFI); 6094 mWiFiNetworkAgent.sendLinkProperties(lp); 6095 waitForIdle(); 6096 return mWiFiNetworkAgent.getNetwork(); 6097 } 6098 6099 @Test 6100 public void testPacketKeepalives() throws Exception { 6101 InetAddress myIPv4 = InetAddress.getByName("192.0.2.129"); 6102 InetAddress notMyIPv4 = InetAddress.getByName("192.0.2.35"); 6103 InetAddress myIPv6 = InetAddress.getByName("2001:db8::1"); 6104 InetAddress dstIPv4 = InetAddress.getByName("8.8.8.8"); 6105 InetAddress dstIPv6 = InetAddress.getByName("2001:4860:4860::8888"); 6106 6107 final int validKaInterval = 15; 6108 final int invalidKaInterval = 9; 6109 6110 LinkProperties lp = new LinkProperties(); 6111 lp.setInterfaceName("wlan12"); 6112 lp.addLinkAddress(new LinkAddress(myIPv6, 64)); 6113 lp.addLinkAddress(new LinkAddress(myIPv4, 25)); 6114 lp.addRoute(new RouteInfo(InetAddress.getByName("fe80::1234"))); 6115 lp.addRoute(new RouteInfo(InetAddress.getByName("192.0.2.254"))); 6116 6117 Network notMyNet = new Network(61234); 6118 Network myNet = connectKeepaliveNetwork(lp); 6119 6120 TestKeepaliveCallback callback = new TestKeepaliveCallback(); 6121 PacketKeepalive ka; 6122 6123 // Attempt to start keepalives with invalid parameters and check for errors. 6124 ka = mCm.startNattKeepalive(notMyNet, validKaInterval, callback, myIPv4, 1234, dstIPv4); 6125 callback.expectError(PacketKeepalive.ERROR_INVALID_NETWORK); 6126 6127 ka = mCm.startNattKeepalive(myNet, invalidKaInterval, callback, myIPv4, 1234, dstIPv4); 6128 callback.expectError(PacketKeepalive.ERROR_INVALID_INTERVAL); 6129 6130 ka = mCm.startNattKeepalive(myNet, validKaInterval, callback, myIPv4, 1234, dstIPv6); 6131 callback.expectError(PacketKeepalive.ERROR_INVALID_IP_ADDRESS); 6132 6133 ka = mCm.startNattKeepalive(myNet, validKaInterval, callback, myIPv6, 1234, dstIPv4); 6134 callback.expectError(PacketKeepalive.ERROR_INVALID_IP_ADDRESS); 6135 6136 // NAT-T is only supported for IPv4. 6137 ka = mCm.startNattKeepalive(myNet, validKaInterval, callback, myIPv6, 1234, dstIPv6); 6138 callback.expectError(PacketKeepalive.ERROR_INVALID_IP_ADDRESS); 6139 6140 ka = mCm.startNattKeepalive(myNet, validKaInterval, callback, myIPv4, 123456, dstIPv4); 6141 callback.expectError(PacketKeepalive.ERROR_INVALID_PORT); 6142 6143 ka = mCm.startNattKeepalive(myNet, validKaInterval, callback, myIPv4, 123456, dstIPv4); 6144 callback.expectError(PacketKeepalive.ERROR_INVALID_PORT); 6145 6146 ka = mCm.startNattKeepalive(myNet, validKaInterval, callback, myIPv4, 12345, dstIPv4); 6147 callback.expectError(PacketKeepalive.ERROR_HARDWARE_UNSUPPORTED); 6148 6149 ka = mCm.startNattKeepalive(myNet, validKaInterval, callback, myIPv4, 12345, dstIPv4); 6150 callback.expectError(PacketKeepalive.ERROR_HARDWARE_UNSUPPORTED); 6151 6152 // Check that a started keepalive can be stopped. 6153 mWiFiNetworkAgent.setStartKeepaliveEvent(PacketKeepalive.SUCCESS); 6154 ka = mCm.startNattKeepalive(myNet, validKaInterval, callback, myIPv4, 12345, dstIPv4); 6155 callback.expectStarted(); 6156 mWiFiNetworkAgent.setStopKeepaliveEvent(PacketKeepalive.SUCCESS); 6157 ka.stop(); 6158 callback.expectStopped(); 6159 6160 // Check that deleting the IP address stops the keepalive. 6161 LinkProperties bogusLp = new LinkProperties(lp); 6162 ka = mCm.startNattKeepalive(myNet, validKaInterval, callback, myIPv4, 12345, dstIPv4); 6163 callback.expectStarted(); 6164 bogusLp.removeLinkAddress(new LinkAddress(myIPv4, 25)); 6165 bogusLp.addLinkAddress(new LinkAddress(notMyIPv4, 25)); 6166 mWiFiNetworkAgent.sendLinkProperties(bogusLp); 6167 callback.expectError(PacketKeepalive.ERROR_INVALID_IP_ADDRESS); 6168 mWiFiNetworkAgent.sendLinkProperties(lp); 6169 6170 // Check that a started keepalive is stopped correctly when the network disconnects. 6171 ka = mCm.startNattKeepalive(myNet, validKaInterval, callback, myIPv4, 12345, dstIPv4); 6172 callback.expectStarted(); 6173 mWiFiNetworkAgent.disconnect(); 6174 mWiFiNetworkAgent.expectDisconnected(); 6175 callback.expectError(PacketKeepalive.ERROR_INVALID_NETWORK); 6176 6177 // ... and that stopping it after that has no adverse effects. 6178 waitForIdle(); 6179 final Network myNetAlias = myNet; 6180 assertNull(mCm.getNetworkCapabilities(myNetAlias)); 6181 ka.stop(); 6182 6183 // Reconnect. 6184 myNet = connectKeepaliveNetwork(lp); 6185 mWiFiNetworkAgent.setStartKeepaliveEvent(PacketKeepalive.SUCCESS); 6186 6187 // Check that keepalive slots start from 1 and increment. The first one gets slot 1. 6188 mWiFiNetworkAgent.setExpectedKeepaliveSlot(1); 6189 ka = mCm.startNattKeepalive(myNet, validKaInterval, callback, myIPv4, 12345, dstIPv4); 6190 callback.expectStarted(); 6191 6192 // The second one gets slot 2. 6193 mWiFiNetworkAgent.setExpectedKeepaliveSlot(2); 6194 TestKeepaliveCallback callback2 = new TestKeepaliveCallback(); 6195 PacketKeepalive ka2 = mCm.startNattKeepalive( 6196 myNet, validKaInterval, callback2, myIPv4, 6789, dstIPv4); 6197 callback2.expectStarted(); 6198 6199 // Now stop the first one and create a third. This also gets slot 1. 6200 ka.stop(); 6201 callback.expectStopped(); 6202 6203 mWiFiNetworkAgent.setExpectedKeepaliveSlot(1); 6204 TestKeepaliveCallback callback3 = new TestKeepaliveCallback(); 6205 PacketKeepalive ka3 = mCm.startNattKeepalive( 6206 myNet, validKaInterval, callback3, myIPv4, 9876, dstIPv4); 6207 callback3.expectStarted(); 6208 6209 ka2.stop(); 6210 callback2.expectStopped(); 6211 6212 ka3.stop(); 6213 callback3.expectStopped(); 6214 } 6215 6216 // Helper method to prepare the executor and run test 6217 private void runTestWithSerialExecutors(ExceptionUtils.ThrowingConsumer<Executor> functor) 6218 throws Exception { 6219 final ExecutorService executorSingleThread = Executors.newSingleThreadExecutor(); 6220 final Executor executorInline = (Runnable r) -> r.run(); 6221 functor.accept(executorSingleThread); 6222 executorSingleThread.shutdown(); 6223 functor.accept(executorInline); 6224 } 6225 6226 @Test 6227 public void testNattSocketKeepalives() throws Exception { 6228 runTestWithSerialExecutors(executor -> doTestNattSocketKeepalivesWithExecutor(executor)); 6229 runTestWithSerialExecutors(executor -> doTestNattSocketKeepalivesFdWithExecutor(executor)); 6230 } 6231 6232 private void doTestNattSocketKeepalivesWithExecutor(Executor executor) throws Exception { 6233 // TODO: 1. Move this outside of ConnectivityServiceTest. 6234 // 2. Make test to verify that Nat-T keepalive socket is created by IpSecService. 6235 // 3. Mock ipsec service. 6236 final InetAddress myIPv4 = InetAddress.getByName("192.0.2.129"); 6237 final InetAddress notMyIPv4 = InetAddress.getByName("192.0.2.35"); 6238 final InetAddress myIPv6 = InetAddress.getByName("2001:db8::1"); 6239 final InetAddress dstIPv4 = InetAddress.getByName("8.8.8.8"); 6240 final InetAddress dstIPv6 = InetAddress.getByName("2001:4860:4860::8888"); 6241 6242 final int validKaInterval = 15; 6243 final int invalidKaInterval = 9; 6244 6245 final IpSecManager mIpSec = (IpSecManager) mContext.getSystemService(Context.IPSEC_SERVICE); 6246 final UdpEncapsulationSocket testSocket = mIpSec.openUdpEncapsulationSocket(); 6247 final int srcPort = testSocket.getPort(); 6248 6249 LinkProperties lp = new LinkProperties(); 6250 lp.setInterfaceName("wlan12"); 6251 lp.addLinkAddress(new LinkAddress(myIPv6, 64)); 6252 lp.addLinkAddress(new LinkAddress(myIPv4, 25)); 6253 lp.addRoute(new RouteInfo(InetAddress.getByName("fe80::1234"))); 6254 lp.addRoute(new RouteInfo(InetAddress.getByName("192.0.2.254"))); 6255 6256 Network notMyNet = new Network(61234); 6257 Network myNet = connectKeepaliveNetwork(lp); 6258 6259 TestSocketKeepaliveCallback callback = new TestSocketKeepaliveCallback(executor); 6260 6261 // Attempt to start keepalives with invalid parameters and check for errors. 6262 // Invalid network. 6263 try (SocketKeepalive ka = mCm.createSocketKeepalive( 6264 notMyNet, testSocket, myIPv4, dstIPv4, executor, callback)) { 6265 ka.start(validKaInterval); 6266 callback.expectError(SocketKeepalive.ERROR_INVALID_NETWORK); 6267 } 6268 6269 // Invalid interval. 6270 try (SocketKeepalive ka = mCm.createSocketKeepalive( 6271 myNet, testSocket, myIPv4, dstIPv4, executor, callback)) { 6272 ka.start(invalidKaInterval); 6273 callback.expectError(SocketKeepalive.ERROR_INVALID_INTERVAL); 6274 } 6275 6276 // Invalid destination. 6277 try (SocketKeepalive ka = mCm.createSocketKeepalive( 6278 myNet, testSocket, myIPv4, dstIPv6, executor, callback)) { 6279 ka.start(validKaInterval); 6280 callback.expectError(SocketKeepalive.ERROR_INVALID_IP_ADDRESS); 6281 } 6282 6283 // Invalid source; 6284 try (SocketKeepalive ka = mCm.createSocketKeepalive( 6285 myNet, testSocket, myIPv6, dstIPv4, executor, callback)) { 6286 ka.start(validKaInterval); 6287 callback.expectError(SocketKeepalive.ERROR_INVALID_IP_ADDRESS); 6288 } 6289 6290 // NAT-T is only supported for IPv4. 6291 try (SocketKeepalive ka = mCm.createSocketKeepalive( 6292 myNet, testSocket, myIPv6, dstIPv6, executor, callback)) { 6293 ka.start(validKaInterval); 6294 callback.expectError(SocketKeepalive.ERROR_INVALID_IP_ADDRESS); 6295 } 6296 6297 // Basic check before testing started keepalive. 6298 try (SocketKeepalive ka = mCm.createSocketKeepalive( 6299 myNet, testSocket, myIPv4, dstIPv4, executor, callback)) { 6300 ka.start(validKaInterval); 6301 callback.expectError(SocketKeepalive.ERROR_UNSUPPORTED); 6302 } 6303 6304 // Check that a started keepalive can be stopped. 6305 mWiFiNetworkAgent.setStartKeepaliveEvent(SocketKeepalive.SUCCESS); 6306 try (SocketKeepalive ka = mCm.createSocketKeepalive( 6307 myNet, testSocket, myIPv4, dstIPv4, executor, callback)) { 6308 ka.start(validKaInterval); 6309 callback.expectStarted(); 6310 mWiFiNetworkAgent.setStopKeepaliveEvent(SocketKeepalive.SUCCESS); 6311 ka.stop(); 6312 callback.expectStopped(); 6313 6314 // Check that keepalive could be restarted. 6315 ka.start(validKaInterval); 6316 callback.expectStarted(); 6317 ka.stop(); 6318 callback.expectStopped(); 6319 6320 // Check that keepalive can be restarted without waiting for callback. 6321 ka.start(validKaInterval); 6322 callback.expectStarted(); 6323 ka.stop(); 6324 ka.start(validKaInterval); 6325 callback.expectStopped(); 6326 callback.expectStarted(); 6327 ka.stop(); 6328 callback.expectStopped(); 6329 } 6330 6331 // Check that deleting the IP address stops the keepalive. 6332 LinkProperties bogusLp = new LinkProperties(lp); 6333 try (SocketKeepalive ka = mCm.createSocketKeepalive( 6334 myNet, testSocket, myIPv4, dstIPv4, executor, callback)) { 6335 ka.start(validKaInterval); 6336 callback.expectStarted(); 6337 bogusLp.removeLinkAddress(new LinkAddress(myIPv4, 25)); 6338 bogusLp.addLinkAddress(new LinkAddress(notMyIPv4, 25)); 6339 mWiFiNetworkAgent.sendLinkProperties(bogusLp); 6340 callback.expectError(SocketKeepalive.ERROR_INVALID_IP_ADDRESS); 6341 mWiFiNetworkAgent.sendLinkProperties(lp); 6342 } 6343 6344 // Check that a started keepalive is stopped correctly when the network disconnects. 6345 try (SocketKeepalive ka = mCm.createSocketKeepalive( 6346 myNet, testSocket, myIPv4, dstIPv4, executor, callback)) { 6347 ka.start(validKaInterval); 6348 callback.expectStarted(); 6349 mWiFiNetworkAgent.disconnect(); 6350 mWiFiNetworkAgent.expectDisconnected(); 6351 callback.expectError(SocketKeepalive.ERROR_INVALID_NETWORK); 6352 6353 // ... and that stopping it after that has no adverse effects. 6354 waitForIdle(); 6355 final Network myNetAlias = myNet; 6356 assertNull(mCm.getNetworkCapabilities(myNetAlias)); 6357 ka.stop(); 6358 callback.assertNoCallback(); 6359 } 6360 6361 // Reconnect. 6362 myNet = connectKeepaliveNetwork(lp); 6363 mWiFiNetworkAgent.setStartKeepaliveEvent(SocketKeepalive.SUCCESS); 6364 6365 // Check that a stop followed by network disconnects does not result in crash. 6366 try (SocketKeepalive ka = mCm.createSocketKeepalive( 6367 myNet, testSocket, myIPv4, dstIPv4, executor, callback)) { 6368 ka.start(validKaInterval); 6369 callback.expectStarted(); 6370 // Delay the response of keepalive events in networkAgent long enough to make sure 6371 // the follow-up network disconnection will be processed first. 6372 mWiFiNetworkAgent.setKeepaliveResponseDelay(3 * TIMEOUT_MS); 6373 ka.stop(); 6374 // Call stop() twice shouldn't result in crash, b/182586681. 6375 ka.stop(); 6376 6377 // Make sure the stop has been processed. Wait for executor idle is needed to prevent 6378 // flaky since the actual stop call to the service is delegated to executor thread. 6379 waitForIdleSerialExecutor(executor, TIMEOUT_MS); 6380 waitForIdle(); 6381 6382 mWiFiNetworkAgent.disconnect(); 6383 mWiFiNetworkAgent.expectDisconnected(); 6384 callback.expectStopped(); 6385 callback.assertNoCallback(); 6386 } 6387 6388 // Reconnect. 6389 waitForIdle(); 6390 myNet = connectKeepaliveNetwork(lp); 6391 mWiFiNetworkAgent.setStartKeepaliveEvent(SocketKeepalive.SUCCESS); 6392 6393 // Check that keepalive slots start from 1 and increment. The first one gets slot 1. 6394 mWiFiNetworkAgent.setExpectedKeepaliveSlot(1); 6395 int srcPort2 = 0; 6396 try (SocketKeepalive ka = mCm.createSocketKeepalive( 6397 myNet, testSocket, myIPv4, dstIPv4, executor, callback)) { 6398 ka.start(validKaInterval); 6399 callback.expectStarted(); 6400 6401 // The second one gets slot 2. 6402 mWiFiNetworkAgent.setExpectedKeepaliveSlot(2); 6403 final UdpEncapsulationSocket testSocket2 = mIpSec.openUdpEncapsulationSocket(); 6404 srcPort2 = testSocket2.getPort(); 6405 TestSocketKeepaliveCallback callback2 = new TestSocketKeepaliveCallback(executor); 6406 try (SocketKeepalive ka2 = mCm.createSocketKeepalive( 6407 myNet, testSocket2, myIPv4, dstIPv4, executor, callback2)) { 6408 ka2.start(validKaInterval); 6409 callback2.expectStarted(); 6410 6411 ka.stop(); 6412 callback.expectStopped(); 6413 6414 ka2.stop(); 6415 callback2.expectStopped(); 6416 6417 testSocket.close(); 6418 testSocket2.close(); 6419 } 6420 } 6421 6422 // Check that there is no port leaked after all keepalives and sockets are closed. 6423 // TODO: enable this check after ensuring a valid free port. See b/129512753#comment7. 6424 // assertFalse(isUdpPortInUse(srcPort)); 6425 // assertFalse(isUdpPortInUse(srcPort2)); 6426 6427 mWiFiNetworkAgent.disconnect(); 6428 mWiFiNetworkAgent.expectDisconnected(); 6429 mWiFiNetworkAgent = null; 6430 } 6431 6432 @Test 6433 public void testTcpSocketKeepalives() throws Exception { 6434 runTestWithSerialExecutors(executor -> doTestTcpSocketKeepalivesWithExecutor(executor)); 6435 } 6436 6437 private void doTestTcpSocketKeepalivesWithExecutor(Executor executor) throws Exception { 6438 final int srcPortV4 = 12345; 6439 final int srcPortV6 = 23456; 6440 final InetAddress myIPv4 = InetAddress.getByName("127.0.0.1"); 6441 final InetAddress myIPv6 = InetAddress.getByName("::1"); 6442 6443 final int validKaInterval = 15; 6444 6445 final LinkProperties lp = new LinkProperties(); 6446 lp.setInterfaceName("wlan12"); 6447 lp.addLinkAddress(new LinkAddress(myIPv6, 64)); 6448 lp.addLinkAddress(new LinkAddress(myIPv4, 25)); 6449 lp.addRoute(new RouteInfo(InetAddress.getByName("fe80::1234"))); 6450 lp.addRoute(new RouteInfo(InetAddress.getByName("127.0.0.254"))); 6451 6452 final Network notMyNet = new Network(61234); 6453 final Network myNet = connectKeepaliveNetwork(lp); 6454 6455 final Socket testSocketV4 = new Socket(); 6456 final Socket testSocketV6 = new Socket(); 6457 6458 TestSocketKeepaliveCallback callback = new TestSocketKeepaliveCallback(executor); 6459 6460 // Attempt to start Tcp keepalives with invalid parameters and check for errors. 6461 // Invalid network. 6462 try (SocketKeepalive ka = mCm.createSocketKeepalive( 6463 notMyNet, testSocketV4, executor, callback)) { 6464 ka.start(validKaInterval); 6465 callback.expectError(SocketKeepalive.ERROR_INVALID_NETWORK); 6466 } 6467 6468 // Invalid Socket (socket is not bound with IPv4 address). 6469 try (SocketKeepalive ka = mCm.createSocketKeepalive( 6470 myNet, testSocketV4, executor, callback)) { 6471 ka.start(validKaInterval); 6472 callback.expectError(SocketKeepalive.ERROR_INVALID_SOCKET); 6473 } 6474 6475 // Invalid Socket (socket is not bound with IPv6 address). 6476 try (SocketKeepalive ka = mCm.createSocketKeepalive( 6477 myNet, testSocketV6, executor, callback)) { 6478 ka.start(validKaInterval); 6479 callback.expectError(SocketKeepalive.ERROR_INVALID_SOCKET); 6480 } 6481 6482 // Bind the socket address 6483 testSocketV4.bind(new InetSocketAddress(myIPv4, srcPortV4)); 6484 testSocketV6.bind(new InetSocketAddress(myIPv6, srcPortV6)); 6485 6486 // Invalid Socket (socket is bound with IPv4 address). 6487 try (SocketKeepalive ka = mCm.createSocketKeepalive( 6488 myNet, testSocketV4, executor, callback)) { 6489 ka.start(validKaInterval); 6490 callback.expectError(SocketKeepalive.ERROR_INVALID_SOCKET); 6491 } 6492 6493 // Invalid Socket (socket is bound with IPv6 address). 6494 try (SocketKeepalive ka = mCm.createSocketKeepalive( 6495 myNet, testSocketV6, executor, callback)) { 6496 ka.start(validKaInterval); 6497 callback.expectError(SocketKeepalive.ERROR_INVALID_SOCKET); 6498 } 6499 6500 testSocketV4.close(); 6501 testSocketV6.close(); 6502 6503 mWiFiNetworkAgent.disconnect(); 6504 mWiFiNetworkAgent.expectDisconnected(); 6505 mWiFiNetworkAgent = null; 6506 } 6507 6508 private void doTestNattSocketKeepalivesFdWithExecutor(Executor executor) throws Exception { 6509 final InetAddress myIPv4 = InetAddress.getByName("192.0.2.129"); 6510 final InetAddress anyIPv4 = InetAddress.getByName("0.0.0.0"); 6511 final InetAddress dstIPv4 = InetAddress.getByName("8.8.8.8"); 6512 final int validKaInterval = 15; 6513 6514 // Prepare the target network. 6515 LinkProperties lp = new LinkProperties(); 6516 lp.setInterfaceName("wlan12"); 6517 lp.addLinkAddress(new LinkAddress(myIPv4, 25)); 6518 lp.addRoute(new RouteInfo(InetAddress.getByName("192.0.2.254"))); 6519 Network myNet = connectKeepaliveNetwork(lp); 6520 mWiFiNetworkAgent.setStartKeepaliveEvent(SocketKeepalive.SUCCESS); 6521 mWiFiNetworkAgent.setStopKeepaliveEvent(SocketKeepalive.SUCCESS); 6522 6523 TestSocketKeepaliveCallback callback = new TestSocketKeepaliveCallback(executor); 6524 6525 // Prepare the target file descriptor, keep only one instance. 6526 final IpSecManager mIpSec = (IpSecManager) mContext.getSystemService(Context.IPSEC_SERVICE); 6527 final UdpEncapsulationSocket testSocket = mIpSec.openUdpEncapsulationSocket(); 6528 final int srcPort = testSocket.getPort(); 6529 final ParcelFileDescriptor testPfd = 6530 ParcelFileDescriptor.dup(testSocket.getFileDescriptor()); 6531 testSocket.close(); 6532 assertTrue(isUdpPortInUse(srcPort)); 6533 6534 // Start keepalive and explicit make the variable goes out of scope with try-with-resources 6535 // block. 6536 try (SocketKeepalive ka = mCm.createNattKeepalive( 6537 myNet, testPfd, myIPv4, dstIPv4, executor, callback)) { 6538 ka.start(validKaInterval); 6539 callback.expectStarted(); 6540 ka.stop(); 6541 callback.expectStopped(); 6542 } 6543 6544 // Check that the ParcelFileDescriptor is still valid after keepalive stopped, 6545 // ErrnoException with EBADF will be thrown if the socket is closed when checking local 6546 // address. 6547 assertTrue(isUdpPortInUse(srcPort)); 6548 final InetSocketAddress sa = 6549 (InetSocketAddress) Os.getsockname(testPfd.getFileDescriptor()); 6550 assertEquals(anyIPv4, sa.getAddress()); 6551 6552 testPfd.close(); 6553 // TODO: enable this check after ensuring a valid free port. See b/129512753#comment7. 6554 // assertFalse(isUdpPortInUse(srcPort)); 6555 6556 mWiFiNetworkAgent.disconnect(); 6557 mWiFiNetworkAgent.expectDisconnected(); 6558 mWiFiNetworkAgent = null; 6559 } 6560 6561 private static boolean isUdpPortInUse(int port) { 6562 try (DatagramSocket ignored = new DatagramSocket(port)) { 6563 return false; 6564 } catch (IOException alreadyInUse) { 6565 return true; 6566 } 6567 } 6568 6569 @Test 6570 public void testGetCaptivePortalServerUrl() throws Exception { 6571 String url = mCm.getCaptivePortalServerUrl(); 6572 assertEquals("http://connectivitycheck.gstatic.com/generate_204", url); 6573 } 6574 6575 private static class TestNetworkPinner extends NetworkPinner { 6576 public static boolean awaitPin(int timeoutMs) throws InterruptedException { 6577 synchronized(sLock) { 6578 if (sNetwork == null) { 6579 sLock.wait(timeoutMs); 6580 } 6581 return sNetwork != null; 6582 } 6583 } 6584 6585 public static boolean awaitUnpin(int timeoutMs) throws InterruptedException { 6586 synchronized(sLock) { 6587 if (sNetwork != null) { 6588 sLock.wait(timeoutMs); 6589 } 6590 return sNetwork == null; 6591 } 6592 } 6593 } 6594 6595 private void assertPinnedToWifiWithCellDefault() { 6596 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getBoundNetworkForProcess()); 6597 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 6598 } 6599 6600 private void assertPinnedToWifiWithWifiDefault() { 6601 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getBoundNetworkForProcess()); 6602 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 6603 } 6604 6605 private void assertNotPinnedToWifi() { 6606 assertNull(mCm.getBoundNetworkForProcess()); 6607 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 6608 } 6609 6610 @Test 6611 public void testNetworkPinner() throws Exception { 6612 NetworkRequest wifiRequest = new NetworkRequest.Builder() 6613 .addTransportType(TRANSPORT_WIFI) 6614 .build(); 6615 assertNull(mCm.getBoundNetworkForProcess()); 6616 6617 TestNetworkPinner.pin(mServiceContext, wifiRequest); 6618 assertNull(mCm.getBoundNetworkForProcess()); 6619 6620 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 6621 mCellNetworkAgent.connect(true); 6622 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 6623 mWiFiNetworkAgent.connect(false); 6624 6625 // When wi-fi connects, expect to be pinned. 6626 assertTrue(TestNetworkPinner.awaitPin(100)); 6627 assertPinnedToWifiWithCellDefault(); 6628 6629 // Disconnect and expect the pin to drop. 6630 mWiFiNetworkAgent.disconnect(); 6631 assertTrue(TestNetworkPinner.awaitUnpin(100)); 6632 assertNotPinnedToWifi(); 6633 6634 // Reconnecting does not cause the pin to come back. 6635 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 6636 mWiFiNetworkAgent.connect(false); 6637 assertFalse(TestNetworkPinner.awaitPin(100)); 6638 assertNotPinnedToWifi(); 6639 6640 // Pinning while connected causes the pin to take effect immediately. 6641 TestNetworkPinner.pin(mServiceContext, wifiRequest); 6642 assertTrue(TestNetworkPinner.awaitPin(100)); 6643 assertPinnedToWifiWithCellDefault(); 6644 6645 // Explicitly unpin and expect to use the default network again. 6646 TestNetworkPinner.unpin(); 6647 assertNotPinnedToWifi(); 6648 6649 // Disconnect cell and wifi. 6650 ExpectedBroadcast b = registerConnectivityBroadcast(3); // cell down, wifi up, wifi down. 6651 mCellNetworkAgent.disconnect(); 6652 mWiFiNetworkAgent.disconnect(); 6653 b.expectBroadcast(); 6654 6655 // Pinning takes effect even if the pinned network is the default when the pin is set... 6656 TestNetworkPinner.pin(mServiceContext, wifiRequest); 6657 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 6658 mWiFiNetworkAgent.connect(false); 6659 assertTrue(TestNetworkPinner.awaitPin(100)); 6660 assertPinnedToWifiWithWifiDefault(); 6661 6662 // ... and is maintained even when that network is no longer the default. 6663 b = registerConnectivityBroadcast(1); 6664 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 6665 mCellNetworkAgent.connect(true); 6666 b.expectBroadcast(); 6667 assertPinnedToWifiWithCellDefault(); 6668 } 6669 6670 @Test 6671 public void testNetworkCallbackMaximum() throws Exception { 6672 final int MAX_REQUESTS = 100; 6673 final int CALLBACKS = 87; 6674 final int DIFF_INTENTS = 10; 6675 final int SAME_INTENTS = 10; 6676 final int SYSTEM_ONLY_MAX_REQUESTS = 250; 6677 // Assert 1 (Default request filed before testing) + CALLBACKS + DIFF_INTENTS + 6678 // 1 (same intent) = MAX_REQUESTS - 1, since the capacity is MAX_REQUEST - 1. 6679 assertEquals(MAX_REQUESTS - 1, 1 + CALLBACKS + DIFF_INTENTS + 1); 6680 6681 NetworkRequest networkRequest = new NetworkRequest.Builder().build(); 6682 ArrayList<Object> registered = new ArrayList<>(); 6683 6684 for (int j = 0; j < CALLBACKS; j++) { 6685 final NetworkCallback cb = new NetworkCallback(); 6686 if (j < CALLBACKS / 2) { 6687 mCm.requestNetwork(networkRequest, cb); 6688 } else { 6689 mCm.registerNetworkCallback(networkRequest, cb); 6690 } 6691 registered.add(cb); 6692 } 6693 6694 // Since ConnectivityService will de-duplicate the request with the same intent, 6695 // register multiple times does not really increase multiple requests. 6696 final PendingIntent same_pi = PendingIntent.getBroadcast(mContext, 0 /* requestCode */, 6697 new Intent("same"), FLAG_IMMUTABLE); 6698 for (int j = 0; j < SAME_INTENTS; j++) { 6699 mCm.registerNetworkCallback(networkRequest, same_pi); 6700 // Wait for the requests with the same intent to be de-duplicated. Because 6701 // ConnectivityService side incrementCountOrThrow in binder, decrementCount in handler 6702 // thread, waitForIdle is needed to ensure decrementCount being invoked for same intent 6703 // requests before doing further tests. 6704 waitForIdle(); 6705 } 6706 for (int j = 0; j < SAME_INTENTS; j++) { 6707 mCm.requestNetwork(networkRequest, same_pi); 6708 // Wait for the requests with the same intent to be de-duplicated. 6709 // Refer to the reason above. 6710 waitForIdle(); 6711 } 6712 registered.add(same_pi); 6713 6714 for (int j = 0; j < DIFF_INTENTS; j++) { 6715 if (j < DIFF_INTENTS / 2) { 6716 final PendingIntent pi = PendingIntent.getBroadcast(mContext, 0 /* requestCode */, 6717 new Intent("a" + j), FLAG_IMMUTABLE); 6718 mCm.requestNetwork(networkRequest, pi); 6719 registered.add(pi); 6720 } else { 6721 final PendingIntent pi = PendingIntent.getBroadcast(mContext, 0 /* requestCode */, 6722 new Intent("b" + j), FLAG_IMMUTABLE); 6723 mCm.registerNetworkCallback(networkRequest, pi); 6724 registered.add(pi); 6725 } 6726 } 6727 6728 // Test that the limit is enforced when MAX_REQUESTS simultaneous requests are added. 6729 assertThrows(TooManyRequestsException.class, () -> 6730 mCm.requestNetwork(networkRequest, new NetworkCallback()) 6731 ); 6732 assertThrows(TooManyRequestsException.class, () -> 6733 mCm.registerNetworkCallback(networkRequest, new NetworkCallback()) 6734 ); 6735 assertThrows(TooManyRequestsException.class, () -> 6736 mCm.requestNetwork(networkRequest, 6737 PendingIntent.getBroadcast(mContext, 0 /* requestCode */, 6738 new Intent("c"), FLAG_IMMUTABLE)) 6739 ); 6740 assertThrows(TooManyRequestsException.class, () -> 6741 mCm.registerNetworkCallback(networkRequest, 6742 PendingIntent.getBroadcast(mContext, 0 /* requestCode */, 6743 new Intent("d"), FLAG_IMMUTABLE)) 6744 ); 6745 6746 // The system gets another SYSTEM_ONLY_MAX_REQUESTS slots. 6747 final Handler handler = new Handler(ConnectivityThread.getInstanceLooper()); 6748 withPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, () -> { 6749 ArrayList<NetworkCallback> systemRegistered = new ArrayList<>(); 6750 for (int i = 0; i < SYSTEM_ONLY_MAX_REQUESTS - 1; i++) { 6751 NetworkCallback cb = new NetworkCallback(); 6752 if (i % 2 == 0) { 6753 mCm.registerDefaultNetworkCallbackForUid(1000000 + i, cb, handler); 6754 } else { 6755 mCm.registerNetworkCallback(networkRequest, cb); 6756 } 6757 systemRegistered.add(cb); 6758 } 6759 waitForIdle(); 6760 6761 assertThrows(TooManyRequestsException.class, () -> 6762 mCm.registerDefaultNetworkCallbackForUid(1001042, new NetworkCallback(), 6763 handler)); 6764 assertThrows(TooManyRequestsException.class, () -> 6765 mCm.registerNetworkCallback(networkRequest, new NetworkCallback())); 6766 6767 for (NetworkCallback callback : systemRegistered) { 6768 mCm.unregisterNetworkCallback(callback); 6769 } 6770 waitForIdle(); // Wait for requests to be unregistered before giving up the permission. 6771 }); 6772 6773 for (Object o : registered) { 6774 if (o instanceof NetworkCallback) { 6775 mCm.unregisterNetworkCallback((NetworkCallback) o); 6776 } 6777 if (o instanceof PendingIntent) { 6778 mCm.unregisterNetworkCallback((PendingIntent) o); 6779 } 6780 } 6781 waitForIdle(); 6782 6783 // Test that the limit is not hit when MAX_REQUESTS requests are added and removed. 6784 for (int i = 0; i < MAX_REQUESTS; i++) { 6785 NetworkCallback networkCallback = new NetworkCallback(); 6786 mCm.requestNetwork(networkRequest, networkCallback); 6787 mCm.unregisterNetworkCallback(networkCallback); 6788 } 6789 waitForIdle(); 6790 6791 for (int i = 0; i < MAX_REQUESTS; i++) { 6792 NetworkCallback networkCallback = new NetworkCallback(); 6793 mCm.registerNetworkCallback(networkRequest, networkCallback); 6794 mCm.unregisterNetworkCallback(networkCallback); 6795 } 6796 waitForIdle(); 6797 6798 for (int i = 0; i < MAX_REQUESTS; i++) { 6799 NetworkCallback networkCallback = new NetworkCallback(); 6800 mCm.registerDefaultNetworkCallback(networkCallback); 6801 mCm.unregisterNetworkCallback(networkCallback); 6802 } 6803 waitForIdle(); 6804 6805 for (int i = 0; i < MAX_REQUESTS; i++) { 6806 NetworkCallback networkCallback = new NetworkCallback(); 6807 mCm.registerDefaultNetworkCallback(networkCallback); 6808 mCm.unregisterNetworkCallback(networkCallback); 6809 } 6810 waitForIdle(); 6811 6812 withPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, () -> { 6813 for (int i = 0; i < MAX_REQUESTS; i++) { 6814 NetworkCallback networkCallback = new NetworkCallback(); 6815 mCm.registerDefaultNetworkCallbackForUid(1000000 + i, networkCallback, 6816 new Handler(ConnectivityThread.getInstanceLooper())); 6817 mCm.unregisterNetworkCallback(networkCallback); 6818 } 6819 }); 6820 waitForIdle(); 6821 6822 for (int i = 0; i < MAX_REQUESTS; i++) { 6823 final PendingIntent pendingIntent = PendingIntent.getBroadcast( 6824 mContext, 0 /* requestCode */, new Intent("e" + i), FLAG_IMMUTABLE); 6825 mCm.requestNetwork(networkRequest, pendingIntent); 6826 mCm.unregisterNetworkCallback(pendingIntent); 6827 } 6828 waitForIdle(); 6829 6830 for (int i = 0; i < MAX_REQUESTS; i++) { 6831 final PendingIntent pendingIntent = PendingIntent.getBroadcast( 6832 mContext, 0 /* requestCode */, new Intent("f" + i), FLAG_IMMUTABLE); 6833 mCm.registerNetworkCallback(networkRequest, pendingIntent); 6834 mCm.unregisterNetworkCallback(pendingIntent); 6835 } 6836 } 6837 6838 @Test 6839 public void testNetworkInfoOfTypeNone() throws Exception { 6840 ExpectedBroadcast b = registerConnectivityBroadcast(1); 6841 6842 verifyNoNetwork(); 6843 TestNetworkAgentWrapper wifiAware = new TestNetworkAgentWrapper(TRANSPORT_WIFI_AWARE); 6844 assertNull(mCm.getActiveNetworkInfo()); 6845 6846 Network[] allNetworks = mCm.getAllNetworks(); 6847 assertLength(1, allNetworks); 6848 Network network = allNetworks[0]; 6849 NetworkCapabilities capabilities = mCm.getNetworkCapabilities(network); 6850 assertTrue(capabilities.hasTransport(TRANSPORT_WIFI_AWARE)); 6851 6852 final NetworkRequest request = 6853 new NetworkRequest.Builder().addTransportType(TRANSPORT_WIFI_AWARE).build(); 6854 final TestNetworkCallback callback = new TestNetworkCallback(); 6855 mCm.registerNetworkCallback(request, callback); 6856 6857 // Bring up wifi aware network. 6858 wifiAware.connect(false, false, false /* isStrictMode */); 6859 callback.expectAvailableCallbacksUnvalidated(wifiAware); 6860 6861 assertNull(mCm.getActiveNetworkInfo()); 6862 assertNull(mCm.getActiveNetwork()); 6863 // TODO: getAllNetworkInfo is dirty and returns a non-empty array right from the start 6864 // of this test. Fix it and uncomment the assert below. 6865 //assertEmpty(mCm.getAllNetworkInfo()); 6866 6867 // Disconnect wifi aware network. 6868 wifiAware.disconnect(); 6869 callback.expectCallbackThat(TIMEOUT_MS, (info) -> info instanceof CallbackEntry.Lost); 6870 mCm.unregisterNetworkCallback(callback); 6871 6872 verifyNoNetwork(); 6873 b.expectNoBroadcast(10); 6874 } 6875 6876 @Test 6877 public void testDeprecatedAndUnsupportedOperations() throws Exception { 6878 final int TYPE_NONE = ConnectivityManager.TYPE_NONE; 6879 assertNull(mCm.getNetworkInfo(TYPE_NONE)); 6880 assertNull(mCm.getNetworkForType(TYPE_NONE)); 6881 assertNull(mCm.getLinkProperties(TYPE_NONE)); 6882 assertFalse(mCm.isNetworkSupported(TYPE_NONE)); 6883 6884 assertThrows(IllegalArgumentException.class, 6885 () -> mCm.networkCapabilitiesForType(TYPE_NONE)); 6886 6887 Class<UnsupportedOperationException> unsupported = UnsupportedOperationException.class; 6888 assertThrows(unsupported, () -> mCm.startUsingNetworkFeature(TYPE_WIFI, "")); 6889 assertThrows(unsupported, () -> mCm.stopUsingNetworkFeature(TYPE_WIFI, "")); 6890 // TODO: let test context have configuration application target sdk version 6891 // and test that pre-M requesting for TYPE_NONE sends back APN_REQUEST_FAILED 6892 assertThrows(unsupported, () -> mCm.startUsingNetworkFeature(TYPE_NONE, "")); 6893 assertThrows(unsupported, () -> mCm.stopUsingNetworkFeature(TYPE_NONE, "")); 6894 assertThrows(unsupported, () -> mCm.requestRouteToHostAddress(TYPE_NONE, null)); 6895 } 6896 6897 @Test 6898 public void testLinkPropertiesEnsuresDirectlyConnectedRoutes() throws Exception { 6899 final NetworkRequest networkRequest = new NetworkRequest.Builder() 6900 .addTransportType(TRANSPORT_WIFI).build(); 6901 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 6902 mCm.registerNetworkCallback(networkRequest, networkCallback); 6903 6904 LinkProperties lp = new LinkProperties(); 6905 lp.setInterfaceName(WIFI_IFNAME); 6906 LinkAddress myIpv4Address = new LinkAddress("192.168.12.3/24"); 6907 RouteInfo myIpv4DefaultRoute = new RouteInfo((IpPrefix) null, 6908 InetAddresses.parseNumericAddress("192.168.12.1"), lp.getInterfaceName()); 6909 lp.addLinkAddress(myIpv4Address); 6910 lp.addRoute(myIpv4DefaultRoute); 6911 6912 // Verify direct routes are added when network agent is first registered in 6913 // ConnectivityService. 6914 TestNetworkAgentWrapper networkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, lp); 6915 networkAgent.connect(true); 6916 networkCallback.expectCallback(CallbackEntry.AVAILABLE, networkAgent); 6917 networkCallback.expectCallback(CallbackEntry.NETWORK_CAPS_UPDATED, networkAgent); 6918 CallbackEntry.LinkPropertiesChanged cbi = 6919 networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, 6920 networkAgent); 6921 networkCallback.expectCallback(CallbackEntry.BLOCKED_STATUS, networkAgent); 6922 networkCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, networkAgent); 6923 networkCallback.assertNoCallback(); 6924 checkDirectlyConnectedRoutes(cbi.getLp(), asList(myIpv4Address), 6925 asList(myIpv4DefaultRoute)); 6926 checkDirectlyConnectedRoutes(mCm.getLinkProperties(networkAgent.getNetwork()), 6927 asList(myIpv4Address), asList(myIpv4DefaultRoute)); 6928 6929 // Verify direct routes are added during subsequent link properties updates. 6930 LinkProperties newLp = new LinkProperties(lp); 6931 LinkAddress myIpv6Address1 = new LinkAddress("fe80::cafe/64"); 6932 LinkAddress myIpv6Address2 = new LinkAddress("2001:db8::2/64"); 6933 newLp.addLinkAddress(myIpv6Address1); 6934 newLp.addLinkAddress(myIpv6Address2); 6935 networkAgent.sendLinkProperties(newLp); 6936 cbi = networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, networkAgent); 6937 networkCallback.assertNoCallback(); 6938 checkDirectlyConnectedRoutes(cbi.getLp(), 6939 asList(myIpv4Address, myIpv6Address1, myIpv6Address2), 6940 asList(myIpv4DefaultRoute)); 6941 mCm.unregisterNetworkCallback(networkCallback); 6942 } 6943 6944 private void expectNotifyNetworkStatus(List<Network> defaultNetworks, String defaultIface, 6945 Integer vpnUid, String vpnIfname, List<String> underlyingIfaces) throws Exception { 6946 ArgumentCaptor<List<Network>> defaultNetworksCaptor = ArgumentCaptor.forClass(List.class); 6947 ArgumentCaptor<List<UnderlyingNetworkInfo>> vpnInfosCaptor = 6948 ArgumentCaptor.forClass(List.class); 6949 6950 verify(mStatsManager, atLeastOnce()).notifyNetworkStatus(defaultNetworksCaptor.capture(), 6951 any(List.class), eq(defaultIface), vpnInfosCaptor.capture()); 6952 6953 assertSameElements(defaultNetworks, defaultNetworksCaptor.getValue()); 6954 6955 List<UnderlyingNetworkInfo> infos = vpnInfosCaptor.getValue(); 6956 if (vpnUid != null) { 6957 assertEquals("Should have exactly one VPN:", 1, infos.size()); 6958 UnderlyingNetworkInfo info = infos.get(0); 6959 assertEquals("Unexpected VPN owner:", (int) vpnUid, info.getOwnerUid()); 6960 assertEquals("Unexpected VPN interface:", vpnIfname, info.getInterface()); 6961 assertSameElements(underlyingIfaces, info.getUnderlyingInterfaces()); 6962 } else { 6963 assertEquals(0, infos.size()); 6964 return; 6965 } 6966 } 6967 6968 private void expectNotifyNetworkStatus( 6969 List<Network> defaultNetworks, String defaultIface) throws Exception { 6970 expectNotifyNetworkStatus(defaultNetworks, defaultIface, null, null, List.of()); 6971 } 6972 6973 @Test 6974 public void testStatsIfacesChanged() throws Exception { 6975 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 6976 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 6977 6978 final List<Network> onlyCell = List.of(mCellNetworkAgent.getNetwork()); 6979 final List<Network> onlyWifi = List.of(mWiFiNetworkAgent.getNetwork()); 6980 6981 LinkProperties cellLp = new LinkProperties(); 6982 cellLp.setInterfaceName(MOBILE_IFNAME); 6983 LinkProperties wifiLp = new LinkProperties(); 6984 wifiLp.setInterfaceName(WIFI_IFNAME); 6985 6986 // Simple connection should have updated ifaces 6987 mCellNetworkAgent.connect(false); 6988 mCellNetworkAgent.sendLinkProperties(cellLp); 6989 waitForIdle(); 6990 expectNotifyNetworkStatus(onlyCell, MOBILE_IFNAME); 6991 reset(mStatsManager); 6992 6993 // Default network switch should update ifaces. 6994 mWiFiNetworkAgent.connect(false); 6995 mWiFiNetworkAgent.sendLinkProperties(wifiLp); 6996 waitForIdle(); 6997 assertEquals(wifiLp, mService.getActiveLinkProperties()); 6998 expectNotifyNetworkStatus(onlyWifi, WIFI_IFNAME); 6999 reset(mStatsManager); 7000 7001 // Disconnect should update ifaces. 7002 mWiFiNetworkAgent.disconnect(); 7003 waitForIdle(); 7004 expectNotifyNetworkStatus(onlyCell, MOBILE_IFNAME); 7005 reset(mStatsManager); 7006 7007 // Metered change should update ifaces 7008 mCellNetworkAgent.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED); 7009 waitForIdle(); 7010 expectNotifyNetworkStatus(onlyCell, MOBILE_IFNAME); 7011 reset(mStatsManager); 7012 7013 mCellNetworkAgent.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED); 7014 waitForIdle(); 7015 expectNotifyNetworkStatus(onlyCell, MOBILE_IFNAME); 7016 reset(mStatsManager); 7017 7018 // Temp metered change shouldn't update ifaces 7019 mCellNetworkAgent.addCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED); 7020 waitForIdle(); 7021 verify(mStatsManager, never()).notifyNetworkStatus(eq(onlyCell), 7022 any(List.class), eq(MOBILE_IFNAME), any(List.class)); 7023 reset(mStatsManager); 7024 7025 // Roaming change should update ifaces 7026 mCellNetworkAgent.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING); 7027 waitForIdle(); 7028 expectNotifyNetworkStatus(onlyCell, MOBILE_IFNAME); 7029 reset(mStatsManager); 7030 7031 // Test VPNs. 7032 final LinkProperties lp = new LinkProperties(); 7033 lp.setInterfaceName(VPN_IFNAME); 7034 7035 mMockVpn.establishForMyUid(lp); 7036 assertUidRangesUpdatedForMyUid(true); 7037 7038 final List<Network> cellAndVpn = 7039 List.of(mCellNetworkAgent.getNetwork(), mMockVpn.getNetwork()); 7040 7041 // A VPN with default (null) underlying networks sets the underlying network's interfaces... 7042 expectNotifyNetworkStatus(cellAndVpn, MOBILE_IFNAME, Process.myUid(), VPN_IFNAME, 7043 List.of(MOBILE_IFNAME)); 7044 7045 // ...and updates them as the default network switches. 7046 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 7047 mWiFiNetworkAgent.connect(false); 7048 mWiFiNetworkAgent.sendLinkProperties(wifiLp); 7049 final Network[] onlyNull = new Network[]{null}; 7050 final List<Network> wifiAndVpn = 7051 List.of(mWiFiNetworkAgent.getNetwork(), mMockVpn.getNetwork()); 7052 final List<Network> cellAndWifi = 7053 List.of(mCellNetworkAgent.getNetwork(), mWiFiNetworkAgent.getNetwork()); 7054 final Network[] cellNullAndWifi = 7055 new Network[]{mCellNetworkAgent.getNetwork(), null, mWiFiNetworkAgent.getNetwork()}; 7056 7057 waitForIdle(); 7058 assertEquals(wifiLp, mService.getActiveLinkProperties()); 7059 expectNotifyNetworkStatus(wifiAndVpn, WIFI_IFNAME, Process.myUid(), VPN_IFNAME, 7060 List.of(WIFI_IFNAME)); 7061 reset(mStatsManager); 7062 7063 // A VPN that sets its underlying networks passes the underlying interfaces, and influences 7064 // the default interface sent to NetworkStatsService by virtue of applying to the system 7065 // server UID (or, in this test, to the test's UID). This is the reason for sending 7066 // MOBILE_IFNAME even though the default network is wifi. 7067 // TODO: fix this to pass in the actual default network interface. Whether or not the VPN 7068 // applies to the system server UID should not have any bearing on network stats. 7069 mMockVpn.setUnderlyingNetworks(onlyCell.toArray(new Network[0])); 7070 waitForIdle(); 7071 expectNotifyNetworkStatus(wifiAndVpn, MOBILE_IFNAME, Process.myUid(), VPN_IFNAME, 7072 List.of(MOBILE_IFNAME)); 7073 reset(mStatsManager); 7074 7075 mMockVpn.setUnderlyingNetworks(cellAndWifi.toArray(new Network[0])); 7076 waitForIdle(); 7077 expectNotifyNetworkStatus(wifiAndVpn, MOBILE_IFNAME, Process.myUid(), VPN_IFNAME, 7078 List.of(MOBILE_IFNAME, WIFI_IFNAME)); 7079 reset(mStatsManager); 7080 7081 // Null underlying networks are ignored. 7082 mMockVpn.setUnderlyingNetworks(cellNullAndWifi); 7083 waitForIdle(); 7084 expectNotifyNetworkStatus(wifiAndVpn, MOBILE_IFNAME, Process.myUid(), VPN_IFNAME, 7085 List.of(MOBILE_IFNAME, WIFI_IFNAME)); 7086 reset(mStatsManager); 7087 7088 // If an underlying network disconnects, that interface should no longer be underlying. 7089 // This doesn't actually work because disconnectAndDestroyNetwork only notifies 7090 // NetworkStatsService before the underlying network is actually removed. So the underlying 7091 // network will only be removed if notifyIfacesChangedForNetworkStats is called again. This 7092 // could result in incorrect data usage measurements if the interface used by the 7093 // disconnected network is reused by a system component that does not register an agent for 7094 // it (e.g., tethering). 7095 mCellNetworkAgent.disconnect(); 7096 waitForIdle(); 7097 assertNull(mService.getLinkProperties(mCellNetworkAgent.getNetwork())); 7098 expectNotifyNetworkStatus(wifiAndVpn, MOBILE_IFNAME, Process.myUid(), VPN_IFNAME, 7099 List.of(MOBILE_IFNAME, WIFI_IFNAME)); 7100 7101 // Confirm that we never tell NetworkStatsService that cell is no longer the underlying 7102 // network for the VPN... 7103 verify(mStatsManager, never()).notifyNetworkStatus(any(List.class), 7104 any(List.class), any() /* anyString() doesn't match null */, 7105 argThat(infos -> infos.get(0).getUnderlyingInterfaces().size() == 1 7106 && WIFI_IFNAME.equals(infos.get(0).getUnderlyingInterfaces().get(0)))); 7107 verifyNoMoreInteractions(mStatsManager); 7108 reset(mStatsManager); 7109 7110 // ... but if something else happens that causes notifyIfacesChangedForNetworkStats to be 7111 // called again, it does. For example, connect Ethernet, but with a low score, such that it 7112 // does not become the default network. 7113 mEthernetNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_ETHERNET); 7114 mEthernetNetworkAgent.setScore( 7115 new NetworkScore.Builder().setLegacyInt(30).setExiting(true).build()); 7116 mEthernetNetworkAgent.connect(false); 7117 waitForIdle(); 7118 verify(mStatsManager).notifyNetworkStatus(any(List.class), 7119 any(List.class), any() /* anyString() doesn't match null */, 7120 argThat(vpnInfos -> vpnInfos.get(0).getUnderlyingInterfaces().size() == 1 7121 && WIFI_IFNAME.equals(vpnInfos.get(0).getUnderlyingInterfaces().get(0)))); 7122 mEthernetNetworkAgent.disconnect(); 7123 waitForIdle(); 7124 reset(mStatsManager); 7125 7126 // When a VPN declares no underlying networks (i.e., no connectivity), getAllVpnInfo 7127 // does not return the VPN, so CS does not pass it to NetworkStatsService. This causes 7128 // NetworkStatsFactory#adjustForTunAnd464Xlat not to attempt any VPN data migration, which 7129 // is probably a performance improvement (though it's very unlikely that a VPN would declare 7130 // no underlying networks). 7131 // Also, for the same reason as above, the active interface passed in is null. 7132 mMockVpn.setUnderlyingNetworks(new Network[0]); 7133 waitForIdle(); 7134 expectNotifyNetworkStatus(wifiAndVpn, null); 7135 reset(mStatsManager); 7136 7137 // Specifying only a null underlying network is the same as no networks. 7138 mMockVpn.setUnderlyingNetworks(onlyNull); 7139 waitForIdle(); 7140 expectNotifyNetworkStatus(wifiAndVpn, null); 7141 reset(mStatsManager); 7142 7143 // Specifying networks that are all disconnected is the same as specifying no networks. 7144 mMockVpn.setUnderlyingNetworks(onlyCell.toArray(new Network[0])); 7145 waitForIdle(); 7146 expectNotifyNetworkStatus(wifiAndVpn, null); 7147 reset(mStatsManager); 7148 7149 // Passing in null again means follow the default network again. 7150 mMockVpn.setUnderlyingNetworks(null); 7151 waitForIdle(); 7152 expectNotifyNetworkStatus(wifiAndVpn, WIFI_IFNAME, Process.myUid(), VPN_IFNAME, 7153 List.of(WIFI_IFNAME)); 7154 reset(mStatsManager); 7155 } 7156 7157 @Test 7158 public void testAdminUidsRedacted() throws Exception { 7159 final int[] adminUids = new int[] {Process.myUid() + 1}; 7160 final NetworkCapabilities ncTemplate = new NetworkCapabilities(); 7161 ncTemplate.setAdministratorUids(adminUids); 7162 mCellNetworkAgent = 7163 new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, new LinkProperties(), ncTemplate); 7164 mCellNetworkAgent.connect(false /* validated */); 7165 7166 // Verify case where caller has permission 7167 mServiceContext.setPermission( 7168 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, PERMISSION_GRANTED); 7169 TestNetworkCallback callback = new TestNetworkCallback(); 7170 mCm.registerDefaultNetworkCallback(callback); 7171 callback.expectCallback(CallbackEntry.AVAILABLE, mCellNetworkAgent); 7172 callback.expectCapabilitiesThat( 7173 mCellNetworkAgent, nc -> Arrays.equals(adminUids, nc.getAdministratorUids())); 7174 mCm.unregisterNetworkCallback(callback); 7175 7176 // Verify case where caller does NOT have permission 7177 mServiceContext.setPermission( 7178 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, PERMISSION_DENIED); 7179 mServiceContext.setPermission(NETWORK_STACK, PERMISSION_DENIED); 7180 callback = new TestNetworkCallback(); 7181 mCm.registerDefaultNetworkCallback(callback); 7182 callback.expectCallback(CallbackEntry.AVAILABLE, mCellNetworkAgent); 7183 callback.expectCapabilitiesThat( 7184 mCellNetworkAgent, nc -> nc.getAdministratorUids().length == 0); 7185 } 7186 7187 @Test 7188 public void testNonVpnUnderlyingNetworks() throws Exception { 7189 // Ensure wifi and cellular are not torn down. 7190 for (int transport : new int[]{TRANSPORT_CELLULAR, TRANSPORT_WIFI}) { 7191 final NetworkRequest request = new NetworkRequest.Builder() 7192 .addTransportType(transport) 7193 .removeCapability(NET_CAPABILITY_NOT_VCN_MANAGED) 7194 .build(); 7195 mCm.requestNetwork(request, new NetworkCallback()); 7196 } 7197 7198 // Connect a VCN-managed wifi network. 7199 final LinkProperties wifiLp = new LinkProperties(); 7200 wifiLp.setInterfaceName(WIFI_IFNAME); 7201 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, wifiLp); 7202 mWiFiNetworkAgent.removeCapability(NET_CAPABILITY_NOT_VCN_MANAGED); 7203 mWiFiNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED); 7204 mWiFiNetworkAgent.connect(true /* validated */); 7205 7206 final List<Network> none = List.of(); 7207 expectNotifyNetworkStatus(none, null); // Wifi is not the default network 7208 7209 // Create a virtual network based on the wifi network. 7210 final int ownerUid = 10042; 7211 NetworkCapabilities nc = new NetworkCapabilities.Builder() 7212 .setOwnerUid(ownerUid) 7213 .setAdministratorUids(new int[]{ownerUid}) 7214 .build(); 7215 final String vcnIface = "ipsec42"; 7216 final LinkProperties lp = new LinkProperties(); 7217 lp.setInterfaceName(vcnIface); 7218 final TestNetworkAgentWrapper vcn = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, lp, nc); 7219 vcn.setUnderlyingNetworks(List.of(mWiFiNetworkAgent.getNetwork())); 7220 vcn.connect(false /* validated */); 7221 7222 final TestNetworkCallback callback = new TestNetworkCallback(); 7223 mCm.registerDefaultNetworkCallback(callback); 7224 callback.expectAvailableCallbacksUnvalidated(vcn); 7225 7226 // The underlying wifi network's capabilities are not propagated to the virtual network, 7227 // but NetworkStatsService is informed of the underlying interface. 7228 nc = mCm.getNetworkCapabilities(vcn.getNetwork()); 7229 assertFalse(nc.hasTransport(TRANSPORT_WIFI)); 7230 assertFalse(nc.hasCapability(NET_CAPABILITY_NOT_METERED)); 7231 final List<Network> onlyVcn = List.of(vcn.getNetwork()); 7232 expectNotifyNetworkStatus(onlyVcn, vcnIface, ownerUid, vcnIface, List.of(WIFI_IFNAME)); 7233 7234 // Add NOT_METERED to the underlying network, check that it is not propagated. 7235 mWiFiNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED); 7236 callback.assertNoCallback(); 7237 nc = mCm.getNetworkCapabilities(vcn.getNetwork()); 7238 assertFalse(nc.hasCapability(NET_CAPABILITY_NOT_METERED)); 7239 7240 // Switch underlying networks. 7241 final LinkProperties cellLp = new LinkProperties(); 7242 cellLp.setInterfaceName(MOBILE_IFNAME); 7243 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp); 7244 mCellNetworkAgent.removeCapability(NET_CAPABILITY_NOT_VCN_MANAGED); 7245 mCellNetworkAgent.addCapability(NET_CAPABILITY_NOT_ROAMING); 7246 mCellNetworkAgent.connect(false /* validated */); 7247 vcn.setUnderlyingNetworks(List.of(mCellNetworkAgent.getNetwork())); 7248 7249 // The underlying capability changes do not propagate to the virtual network, but 7250 // NetworkStatsService is informed of the new underlying interface. 7251 callback.assertNoCallback(); 7252 nc = mCm.getNetworkCapabilities(vcn.getNetwork()); 7253 assertFalse(nc.hasTransport(TRANSPORT_WIFI)); 7254 assertFalse(nc.hasCapability(NET_CAPABILITY_NOT_ROAMING)); 7255 expectNotifyNetworkStatus(onlyVcn, vcnIface, ownerUid, vcnIface, List.of(MOBILE_IFNAME)); 7256 } 7257 7258 @Test 7259 public void testBasicDnsConfigurationPushed() throws Exception { 7260 setPrivateDnsSettings(PRIVATE_DNS_MODE_OPPORTUNISTIC, "ignored.example.com"); 7261 7262 // Clear any interactions that occur as a result of CS starting up. 7263 reset(mMockDnsResolver); 7264 7265 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 7266 waitForIdle(); 7267 verify(mMockDnsResolver, never()).setResolverConfiguration(any()); 7268 verifyNoMoreInteractions(mMockDnsResolver); 7269 7270 final LinkProperties cellLp = new LinkProperties(); 7271 cellLp.setInterfaceName(MOBILE_IFNAME); 7272 // Add IPv4 and IPv6 default routes, because DNS-over-TLS code does 7273 // "is-reachable" testing in order to not program netd with unreachable 7274 // nameservers that it might try repeated to validate. 7275 cellLp.addLinkAddress(new LinkAddress("192.0.2.4/24")); 7276 cellLp.addRoute(new RouteInfo((IpPrefix) null, InetAddress.getByName("192.0.2.4"), 7277 MOBILE_IFNAME)); 7278 cellLp.addLinkAddress(new LinkAddress("2001:db8:1::1/64")); 7279 cellLp.addRoute(new RouteInfo((IpPrefix) null, InetAddress.getByName("2001:db8:1::1"), 7280 MOBILE_IFNAME)); 7281 mCellNetworkAgent.sendLinkProperties(cellLp); 7282 mCellNetworkAgent.connect(false); 7283 waitForIdle(); 7284 7285 verify(mMockDnsResolver, times(1)).createNetworkCache( 7286 eq(mCellNetworkAgent.getNetwork().netId)); 7287 // CS tells dnsresolver about the empty DNS config for this network. 7288 verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration(any()); 7289 reset(mMockDnsResolver); 7290 7291 cellLp.addDnsServer(InetAddress.getByName("2001:db8::1")); 7292 mCellNetworkAgent.sendLinkProperties(cellLp); 7293 waitForIdle(); 7294 verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration( 7295 mResolverParamsParcelCaptor.capture()); 7296 ResolverParamsParcel resolvrParams = mResolverParamsParcelCaptor.getValue(); 7297 assertEquals(1, resolvrParams.servers.length); 7298 assertTrue(CollectionUtils.contains(resolvrParams.servers, "2001:db8::1")); 7299 // Opportunistic mode. 7300 assertTrue(CollectionUtils.contains(resolvrParams.tlsServers, "2001:db8::1")); 7301 reset(mMockDnsResolver); 7302 7303 cellLp.addDnsServer(InetAddress.getByName("192.0.2.1")); 7304 mCellNetworkAgent.sendLinkProperties(cellLp); 7305 waitForIdle(); 7306 verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration( 7307 mResolverParamsParcelCaptor.capture()); 7308 resolvrParams = mResolverParamsParcelCaptor.getValue(); 7309 assertEquals(2, resolvrParams.servers.length); 7310 assertTrue(new ArraySet<>(resolvrParams.servers).containsAll( 7311 asList("2001:db8::1", "192.0.2.1"))); 7312 // Opportunistic mode. 7313 assertEquals(2, resolvrParams.tlsServers.length); 7314 assertTrue(new ArraySet<>(resolvrParams.tlsServers).containsAll( 7315 asList("2001:db8::1", "192.0.2.1"))); 7316 reset(mMockDnsResolver); 7317 7318 final String TLS_SPECIFIER = "tls.example.com"; 7319 final String TLS_SERVER6 = "2001:db8:53::53"; 7320 final InetAddress[] TLS_IPS = new InetAddress[]{ InetAddress.getByName(TLS_SERVER6) }; 7321 final String[] TLS_SERVERS = new String[]{ TLS_SERVER6 }; 7322 mCellNetworkAgent.mNmCallbacks.notifyPrivateDnsConfigResolved( 7323 new PrivateDnsConfig(TLS_SPECIFIER, TLS_IPS).toParcel()); 7324 7325 waitForIdle(); 7326 verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration( 7327 mResolverParamsParcelCaptor.capture()); 7328 resolvrParams = mResolverParamsParcelCaptor.getValue(); 7329 assertEquals(2, resolvrParams.servers.length); 7330 assertTrue(new ArraySet<>(resolvrParams.servers).containsAll( 7331 asList("2001:db8::1", "192.0.2.1"))); 7332 reset(mMockDnsResolver); 7333 } 7334 7335 @Test 7336 public void testDnsConfigurationTransTypesPushed() throws Exception { 7337 // Clear any interactions that occur as a result of CS starting up. 7338 reset(mMockDnsResolver); 7339 7340 final NetworkRequest request = new NetworkRequest.Builder() 7341 .clearCapabilities().addCapability(NET_CAPABILITY_INTERNET) 7342 .build(); 7343 final TestNetworkCallback callback = new TestNetworkCallback(); 7344 mCm.registerNetworkCallback(request, callback); 7345 7346 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 7347 mWiFiNetworkAgent.connect(false); 7348 callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 7349 verify(mMockDnsResolver, times(1)).createNetworkCache( 7350 eq(mWiFiNetworkAgent.getNetwork().netId)); 7351 verify(mMockDnsResolver, times(2)).setResolverConfiguration( 7352 mResolverParamsParcelCaptor.capture()); 7353 final ResolverParamsParcel resolverParams = mResolverParamsParcelCaptor.getValue(); 7354 assertContainsExactly(resolverParams.transportTypes, TRANSPORT_WIFI); 7355 reset(mMockDnsResolver); 7356 } 7357 7358 @Test 7359 public void testPrivateDnsNotification() throws Exception { 7360 NetworkRequest request = new NetworkRequest.Builder() 7361 .clearCapabilities().addCapability(NET_CAPABILITY_INTERNET) 7362 .build(); 7363 TestNetworkCallback callback = new TestNetworkCallback(); 7364 mCm.registerNetworkCallback(request, callback); 7365 // Bring up wifi. 7366 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 7367 mWiFiNetworkAgent.connect(false); 7368 callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 7369 // Private DNS resolution failed, checking if the notification will be shown or not. 7370 mWiFiNetworkAgent.setNetworkInvalid(true /* isStrictMode */); 7371 mWiFiNetworkAgent.mNetworkMonitor.forceReevaluation(Process.myUid()); 7372 waitForIdle(); 7373 // If network validation failed, NetworkMonitor will re-evaluate the network. 7374 // ConnectivityService should filter the redundant notification. This part is trying to 7375 // simulate that situation and check if ConnectivityService could filter that case. 7376 mWiFiNetworkAgent.mNetworkMonitor.forceReevaluation(Process.myUid()); 7377 waitForIdle(); 7378 verify(mNotificationManager, timeout(TIMEOUT_MS).times(1)).notify(anyString(), 7379 eq(NotificationType.PRIVATE_DNS_BROKEN.eventId), any()); 7380 // If private DNS resolution successful, the PRIVATE_DNS_BROKEN notification shouldn't be 7381 // shown. 7382 mWiFiNetworkAgent.setNetworkValid(true /* isStrictMode */); 7383 mWiFiNetworkAgent.mNetworkMonitor.forceReevaluation(Process.myUid()); 7384 waitForIdle(); 7385 verify(mNotificationManager, timeout(TIMEOUT_MS).times(1)).cancel(anyString(), 7386 eq(NotificationType.PRIVATE_DNS_BROKEN.eventId)); 7387 // If private DNS resolution failed again, the PRIVATE_DNS_BROKEN notification should be 7388 // shown again. 7389 mWiFiNetworkAgent.setNetworkInvalid(true /* isStrictMode */); 7390 mWiFiNetworkAgent.mNetworkMonitor.forceReevaluation(Process.myUid()); 7391 waitForIdle(); 7392 verify(mNotificationManager, timeout(TIMEOUT_MS).times(2)).notify(anyString(), 7393 eq(NotificationType.PRIVATE_DNS_BROKEN.eventId), any()); 7394 } 7395 7396 @Test 7397 public void testPrivateDnsSettingsChange() throws Exception { 7398 // Clear any interactions that occur as a result of CS starting up. 7399 reset(mMockDnsResolver); 7400 7401 // The default on Android is opportunistic mode ("Automatic"). 7402 setPrivateDnsSettings(PRIVATE_DNS_MODE_OPPORTUNISTIC, "ignored.example.com"); 7403 7404 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback(); 7405 final NetworkRequest cellRequest = new NetworkRequest.Builder() 7406 .addTransportType(TRANSPORT_CELLULAR).build(); 7407 mCm.requestNetwork(cellRequest, cellNetworkCallback); 7408 7409 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 7410 waitForIdle(); 7411 // CS tells netd about the empty DNS config for this network. 7412 verify(mMockDnsResolver, never()).setResolverConfiguration(any()); 7413 verifyNoMoreInteractions(mMockDnsResolver); 7414 7415 final LinkProperties cellLp = new LinkProperties(); 7416 cellLp.setInterfaceName(MOBILE_IFNAME); 7417 // Add IPv4 and IPv6 default routes, because DNS-over-TLS code does 7418 // "is-reachable" testing in order to not program netd with unreachable 7419 // nameservers that it might try repeated to validate. 7420 cellLp.addLinkAddress(new LinkAddress("192.0.2.4/24")); 7421 cellLp.addRoute(new RouteInfo((IpPrefix) null, InetAddress.getByName("192.0.2.4"), 7422 MOBILE_IFNAME)); 7423 cellLp.addLinkAddress(new LinkAddress("2001:db8:1::1/64")); 7424 cellLp.addRoute(new RouteInfo((IpPrefix) null, InetAddress.getByName("2001:db8:1::1"), 7425 MOBILE_IFNAME)); 7426 cellLp.addDnsServer(InetAddress.getByName("2001:db8::1")); 7427 cellLp.addDnsServer(InetAddress.getByName("192.0.2.1")); 7428 7429 mCellNetworkAgent.sendLinkProperties(cellLp); 7430 mCellNetworkAgent.connect(false); 7431 waitForIdle(); 7432 verify(mMockDnsResolver, times(1)).createNetworkCache( 7433 eq(mCellNetworkAgent.getNetwork().netId)); 7434 verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration( 7435 mResolverParamsParcelCaptor.capture()); 7436 ResolverParamsParcel resolvrParams = mResolverParamsParcelCaptor.getValue(); 7437 assertEquals(2, resolvrParams.tlsServers.length); 7438 assertTrue(new ArraySet<>(resolvrParams.tlsServers).containsAll( 7439 asList("2001:db8::1", "192.0.2.1"))); 7440 // Opportunistic mode. 7441 assertEquals(2, resolvrParams.tlsServers.length); 7442 assertTrue(new ArraySet<>(resolvrParams.tlsServers).containsAll( 7443 asList("2001:db8::1", "192.0.2.1"))); 7444 reset(mMockDnsResolver); 7445 cellNetworkCallback.expectCallback(CallbackEntry.AVAILABLE, mCellNetworkAgent); 7446 cellNetworkCallback.expectCallback(CallbackEntry.NETWORK_CAPS_UPDATED, 7447 mCellNetworkAgent); 7448 CallbackEntry.LinkPropertiesChanged cbi = cellNetworkCallback.expectCallback( 7449 CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent); 7450 cellNetworkCallback.expectCallback(CallbackEntry.BLOCKED_STATUS, mCellNetworkAgent); 7451 cellNetworkCallback.assertNoCallback(); 7452 assertFalse(cbi.getLp().isPrivateDnsActive()); 7453 assertNull(cbi.getLp().getPrivateDnsServerName()); 7454 7455 setPrivateDnsSettings(PRIVATE_DNS_MODE_OFF, "ignored.example.com"); 7456 verify(mMockDnsResolver, times(1)).setResolverConfiguration( 7457 mResolverParamsParcelCaptor.capture()); 7458 resolvrParams = mResolverParamsParcelCaptor.getValue(); 7459 assertEquals(2, resolvrParams.servers.length); 7460 assertTrue(new ArraySet<>(resolvrParams.servers).containsAll( 7461 asList("2001:db8::1", "192.0.2.1"))); 7462 reset(mMockDnsResolver); 7463 cellNetworkCallback.assertNoCallback(); 7464 7465 setPrivateDnsSettings(PRIVATE_DNS_MODE_OPPORTUNISTIC, "ignored.example.com"); 7466 verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration( 7467 mResolverParamsParcelCaptor.capture()); 7468 resolvrParams = mResolverParamsParcelCaptor.getValue(); 7469 assertEquals(2, resolvrParams.servers.length); 7470 assertTrue(new ArraySet<>(resolvrParams.servers).containsAll( 7471 asList("2001:db8::1", "192.0.2.1"))); 7472 assertEquals(2, resolvrParams.tlsServers.length); 7473 assertTrue(new ArraySet<>(resolvrParams.tlsServers).containsAll( 7474 asList("2001:db8::1", "192.0.2.1"))); 7475 reset(mMockDnsResolver); 7476 cellNetworkCallback.assertNoCallback(); 7477 7478 setPrivateDnsSettings(PRIVATE_DNS_MODE_PROVIDER_HOSTNAME, "strict.example.com"); 7479 // Can't test dns configuration for strict mode without properly mocking 7480 // out the DNS lookups, but can test that LinkProperties is updated. 7481 cbi = cellNetworkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, 7482 mCellNetworkAgent); 7483 cellNetworkCallback.assertNoCallback(); 7484 assertTrue(cbi.getLp().isPrivateDnsActive()); 7485 assertEquals("strict.example.com", cbi.getLp().getPrivateDnsServerName()); 7486 } 7487 7488 private PrivateDnsValidationEventParcel makePrivateDnsValidationEvent( 7489 final int netId, final String ipAddress, final String hostname, final int validation) { 7490 final PrivateDnsValidationEventParcel event = new PrivateDnsValidationEventParcel(); 7491 event.netId = netId; 7492 event.ipAddress = ipAddress; 7493 event.hostname = hostname; 7494 event.validation = validation; 7495 return event; 7496 } 7497 7498 @Test 7499 public void testLinkPropertiesWithPrivateDnsValidationEvents() throws Exception { 7500 // The default on Android is opportunistic mode ("Automatic"). 7501 setPrivateDnsSettings(PRIVATE_DNS_MODE_OPPORTUNISTIC, "ignored.example.com"); 7502 7503 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback(); 7504 final NetworkRequest cellRequest = new NetworkRequest.Builder() 7505 .addTransportType(TRANSPORT_CELLULAR).build(); 7506 mCm.requestNetwork(cellRequest, cellNetworkCallback); 7507 7508 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 7509 waitForIdle(); 7510 LinkProperties lp = new LinkProperties(); 7511 mCellNetworkAgent.sendLinkProperties(lp); 7512 mCellNetworkAgent.connect(false); 7513 waitForIdle(); 7514 cellNetworkCallback.expectCallback(CallbackEntry.AVAILABLE, mCellNetworkAgent); 7515 cellNetworkCallback.expectCallback(CallbackEntry.NETWORK_CAPS_UPDATED, 7516 mCellNetworkAgent); 7517 CallbackEntry.LinkPropertiesChanged cbi = cellNetworkCallback.expectCallback( 7518 CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent); 7519 cellNetworkCallback.expectCallback(CallbackEntry.BLOCKED_STATUS, mCellNetworkAgent); 7520 cellNetworkCallback.assertNoCallback(); 7521 assertFalse(cbi.getLp().isPrivateDnsActive()); 7522 assertNull(cbi.getLp().getPrivateDnsServerName()); 7523 Set<InetAddress> dnsServers = new HashSet<>(); 7524 checkDnsServers(cbi.getLp(), dnsServers); 7525 7526 // Send a validation event for a server that is not part of the current 7527 // resolver config. The validation event should be ignored. 7528 mService.mResolverUnsolEventCallback.onPrivateDnsValidationEvent( 7529 makePrivateDnsValidationEvent(mCellNetworkAgent.getNetwork().netId, "", 7530 "145.100.185.18", VALIDATION_RESULT_SUCCESS)); 7531 cellNetworkCallback.assertNoCallback(); 7532 7533 // Add a dns server to the LinkProperties. 7534 LinkProperties lp2 = new LinkProperties(lp); 7535 lp2.addDnsServer(InetAddress.getByName("145.100.185.16")); 7536 mCellNetworkAgent.sendLinkProperties(lp2); 7537 cbi = cellNetworkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, 7538 mCellNetworkAgent); 7539 cellNetworkCallback.assertNoCallback(); 7540 assertFalse(cbi.getLp().isPrivateDnsActive()); 7541 assertNull(cbi.getLp().getPrivateDnsServerName()); 7542 dnsServers.add(InetAddress.getByName("145.100.185.16")); 7543 checkDnsServers(cbi.getLp(), dnsServers); 7544 7545 // Send a validation event containing a hostname that is not part of 7546 // the current resolver config. The validation event should be ignored. 7547 mService.mResolverUnsolEventCallback.onPrivateDnsValidationEvent( 7548 makePrivateDnsValidationEvent(mCellNetworkAgent.getNetwork().netId, 7549 "145.100.185.16", "hostname", VALIDATION_RESULT_SUCCESS)); 7550 cellNetworkCallback.assertNoCallback(); 7551 7552 // Send a validation event where validation failed. 7553 mService.mResolverUnsolEventCallback.onPrivateDnsValidationEvent( 7554 makePrivateDnsValidationEvent(mCellNetworkAgent.getNetwork().netId, 7555 "145.100.185.16", "", VALIDATION_RESULT_FAILURE)); 7556 cellNetworkCallback.assertNoCallback(); 7557 7558 // Send a validation event where validation succeeded for a server in 7559 // the current resolver config. A LinkProperties callback with updated 7560 // private dns fields should be sent. 7561 mService.mResolverUnsolEventCallback.onPrivateDnsValidationEvent( 7562 makePrivateDnsValidationEvent(mCellNetworkAgent.getNetwork().netId, 7563 "145.100.185.16", "", VALIDATION_RESULT_SUCCESS)); 7564 cbi = cellNetworkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, 7565 mCellNetworkAgent); 7566 cellNetworkCallback.assertNoCallback(); 7567 assertTrue(cbi.getLp().isPrivateDnsActive()); 7568 assertNull(cbi.getLp().getPrivateDnsServerName()); 7569 checkDnsServers(cbi.getLp(), dnsServers); 7570 7571 // The private dns fields in LinkProperties should be preserved when 7572 // the network agent sends unrelated changes. 7573 LinkProperties lp3 = new LinkProperties(lp2); 7574 lp3.setMtu(1300); 7575 mCellNetworkAgent.sendLinkProperties(lp3); 7576 cbi = cellNetworkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, 7577 mCellNetworkAgent); 7578 cellNetworkCallback.assertNoCallback(); 7579 assertTrue(cbi.getLp().isPrivateDnsActive()); 7580 assertNull(cbi.getLp().getPrivateDnsServerName()); 7581 checkDnsServers(cbi.getLp(), dnsServers); 7582 assertEquals(1300, cbi.getLp().getMtu()); 7583 7584 // Removing the only validated server should affect the private dns 7585 // fields in LinkProperties. 7586 LinkProperties lp4 = new LinkProperties(lp3); 7587 lp4.removeDnsServer(InetAddress.getByName("145.100.185.16")); 7588 mCellNetworkAgent.sendLinkProperties(lp4); 7589 cbi = cellNetworkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, 7590 mCellNetworkAgent); 7591 cellNetworkCallback.assertNoCallback(); 7592 assertFalse(cbi.getLp().isPrivateDnsActive()); 7593 assertNull(cbi.getLp().getPrivateDnsServerName()); 7594 dnsServers.remove(InetAddress.getByName("145.100.185.16")); 7595 checkDnsServers(cbi.getLp(), dnsServers); 7596 assertEquals(1300, cbi.getLp().getMtu()); 7597 } 7598 7599 private void checkDirectlyConnectedRoutes(Object callbackObj, 7600 Collection<LinkAddress> linkAddresses, Collection<RouteInfo> otherRoutes) { 7601 assertTrue(callbackObj instanceof LinkProperties); 7602 LinkProperties lp = (LinkProperties) callbackObj; 7603 7604 Set<RouteInfo> expectedRoutes = new ArraySet<>(); 7605 expectedRoutes.addAll(otherRoutes); 7606 for (LinkAddress address : linkAddresses) { 7607 RouteInfo localRoute = new RouteInfo(address, null, lp.getInterfaceName()); 7608 // Duplicates in linkAddresses are considered failures 7609 assertTrue(expectedRoutes.add(localRoute)); 7610 } 7611 List<RouteInfo> observedRoutes = lp.getRoutes(); 7612 assertEquals(expectedRoutes.size(), observedRoutes.size()); 7613 assertTrue(observedRoutes.containsAll(expectedRoutes)); 7614 } 7615 7616 private static void checkDnsServers(Object callbackObj, Set<InetAddress> dnsServers) { 7617 assertTrue(callbackObj instanceof LinkProperties); 7618 LinkProperties lp = (LinkProperties) callbackObj; 7619 assertEquals(dnsServers.size(), lp.getDnsServers().size()); 7620 assertTrue(lp.getDnsServers().containsAll(dnsServers)); 7621 } 7622 7623 @Test 7624 public void testApplyUnderlyingCapabilities() throws Exception { 7625 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 7626 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 7627 mCellNetworkAgent.connect(false /* validated */); 7628 mWiFiNetworkAgent.connect(false /* validated */); 7629 7630 final NetworkCapabilities cellNc = new NetworkCapabilities() 7631 .addTransportType(TRANSPORT_CELLULAR) 7632 .addCapability(NET_CAPABILITY_INTERNET) 7633 .addCapability(NET_CAPABILITY_NOT_CONGESTED) 7634 .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED) 7635 .setLinkDownstreamBandwidthKbps(10); 7636 final NetworkCapabilities wifiNc = new NetworkCapabilities() 7637 .addTransportType(TRANSPORT_WIFI) 7638 .addCapability(NET_CAPABILITY_INTERNET) 7639 .addCapability(NET_CAPABILITY_NOT_METERED) 7640 .addCapability(NET_CAPABILITY_NOT_ROAMING) 7641 .addCapability(NET_CAPABILITY_NOT_CONGESTED) 7642 .addCapability(NET_CAPABILITY_NOT_SUSPENDED) 7643 .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED) 7644 .setLinkUpstreamBandwidthKbps(20); 7645 mCellNetworkAgent.setNetworkCapabilities(cellNc, true /* sendToConnectivityService */); 7646 mWiFiNetworkAgent.setNetworkCapabilities(wifiNc, true /* sendToConnectivityService */); 7647 waitForIdle(); 7648 7649 final Network mobile = mCellNetworkAgent.getNetwork(); 7650 final Network wifi = mWiFiNetworkAgent.getNetwork(); 7651 7652 final NetworkCapabilities initialCaps = new NetworkCapabilities(); 7653 initialCaps.addTransportType(TRANSPORT_VPN); 7654 initialCaps.addCapability(NET_CAPABILITY_INTERNET); 7655 initialCaps.removeCapability(NET_CAPABILITY_NOT_VPN); 7656 final ArrayList<Network> emptyUnderlyingNetworks = new ArrayList<Network>(); 7657 final ArrayList<Network> underlyingNetworksContainMobile = new ArrayList<Network>(); 7658 underlyingNetworksContainMobile.add(mobile); 7659 final ArrayList<Network> underlyingNetworksContainWifi = new ArrayList<Network>(); 7660 underlyingNetworksContainWifi.add(wifi); 7661 final ArrayList<Network> underlyingNetworksContainMobileAndMobile = 7662 new ArrayList<Network>(); 7663 underlyingNetworksContainMobileAndMobile.add(mobile); 7664 underlyingNetworksContainMobileAndMobile.add(wifi); 7665 7666 final NetworkCapabilities withNoUnderlying = new NetworkCapabilities(); 7667 withNoUnderlying.addCapability(NET_CAPABILITY_INTERNET); 7668 withNoUnderlying.addCapability(NET_CAPABILITY_NOT_CONGESTED); 7669 withNoUnderlying.addCapability(NET_CAPABILITY_NOT_ROAMING); 7670 withNoUnderlying.addCapability(NET_CAPABILITY_NOT_SUSPENDED); 7671 withNoUnderlying.addTransportType(TRANSPORT_VPN); 7672 withNoUnderlying.removeCapability(NET_CAPABILITY_NOT_VPN); 7673 withNoUnderlying.setUnderlyingNetworks(emptyUnderlyingNetworks); 7674 7675 final NetworkCapabilities withMobileUnderlying = new NetworkCapabilities(withNoUnderlying); 7676 withMobileUnderlying.addTransportType(TRANSPORT_CELLULAR); 7677 withMobileUnderlying.removeCapability(NET_CAPABILITY_NOT_ROAMING); 7678 withMobileUnderlying.removeCapability(NET_CAPABILITY_NOT_SUSPENDED); 7679 withMobileUnderlying.setLinkDownstreamBandwidthKbps(10); 7680 withMobileUnderlying.setUnderlyingNetworks(underlyingNetworksContainMobile); 7681 7682 final NetworkCapabilities withWifiUnderlying = new NetworkCapabilities(withNoUnderlying); 7683 withWifiUnderlying.addTransportType(TRANSPORT_WIFI); 7684 withWifiUnderlying.addCapability(NET_CAPABILITY_NOT_METERED); 7685 withWifiUnderlying.setLinkUpstreamBandwidthKbps(20); 7686 withWifiUnderlying.setUnderlyingNetworks(underlyingNetworksContainWifi); 7687 7688 final NetworkCapabilities withWifiAndMobileUnderlying = 7689 new NetworkCapabilities(withNoUnderlying); 7690 withWifiAndMobileUnderlying.addTransportType(TRANSPORT_CELLULAR); 7691 withWifiAndMobileUnderlying.addTransportType(TRANSPORT_WIFI); 7692 withWifiAndMobileUnderlying.removeCapability(NET_CAPABILITY_NOT_METERED); 7693 withWifiAndMobileUnderlying.removeCapability(NET_CAPABILITY_NOT_ROAMING); 7694 withWifiAndMobileUnderlying.setLinkDownstreamBandwidthKbps(10); 7695 withWifiAndMobileUnderlying.setLinkUpstreamBandwidthKbps(20); 7696 withWifiAndMobileUnderlying.setUnderlyingNetworks(underlyingNetworksContainMobileAndMobile); 7697 7698 final NetworkCapabilities initialCapsNotMetered = new NetworkCapabilities(initialCaps); 7699 initialCapsNotMetered.addCapability(NET_CAPABILITY_NOT_METERED); 7700 7701 NetworkCapabilities caps = new NetworkCapabilities(initialCaps); 7702 mService.applyUnderlyingCapabilities(new Network[]{}, initialCapsNotMetered, caps); 7703 assertEquals(withNoUnderlying, caps); 7704 assertEquals(0, new ArrayList<>(caps.getUnderlyingNetworks()).size()); 7705 7706 caps = new NetworkCapabilities(initialCaps); 7707 mService.applyUnderlyingCapabilities(new Network[]{null}, initialCapsNotMetered, caps); 7708 assertEquals(withNoUnderlying, caps); 7709 assertEquals(0, new ArrayList<>(caps.getUnderlyingNetworks()).size()); 7710 7711 caps = new NetworkCapabilities(initialCaps); 7712 mService.applyUnderlyingCapabilities(new Network[]{mobile}, initialCapsNotMetered, caps); 7713 assertEquals(withMobileUnderlying, caps); 7714 assertEquals(1, new ArrayList<>(caps.getUnderlyingNetworks()).size()); 7715 assertEquals(mobile, new ArrayList<>(caps.getUnderlyingNetworks()).get(0)); 7716 7717 caps = new NetworkCapabilities(initialCaps); 7718 mService.applyUnderlyingCapabilities(new Network[]{wifi}, initialCapsNotMetered, caps); 7719 assertEquals(withWifiUnderlying, caps); 7720 assertEquals(1, new ArrayList<>(caps.getUnderlyingNetworks()).size()); 7721 assertEquals(wifi, new ArrayList<>(caps.getUnderlyingNetworks()).get(0)); 7722 7723 withWifiUnderlying.removeCapability(NET_CAPABILITY_NOT_METERED); 7724 caps = new NetworkCapabilities(initialCaps); 7725 mService.applyUnderlyingCapabilities(new Network[]{wifi}, initialCaps, caps); 7726 assertEquals(withWifiUnderlying, caps); 7727 assertEquals(1, new ArrayList<>(caps.getUnderlyingNetworks()).size()); 7728 assertEquals(wifi, new ArrayList<>(caps.getUnderlyingNetworks()).get(0)); 7729 7730 caps = new NetworkCapabilities(initialCaps); 7731 mService.applyUnderlyingCapabilities(new Network[]{mobile, wifi}, initialCaps, caps); 7732 assertEquals(withWifiAndMobileUnderlying, caps); 7733 assertEquals(2, new ArrayList<>(caps.getUnderlyingNetworks()).size()); 7734 assertEquals(mobile, new ArrayList<>(caps.getUnderlyingNetworks()).get(0)); 7735 assertEquals(wifi, new ArrayList<>(caps.getUnderlyingNetworks()).get(1)); 7736 7737 withWifiUnderlying.addCapability(NET_CAPABILITY_NOT_METERED); 7738 caps = new NetworkCapabilities(initialCaps); 7739 mService.applyUnderlyingCapabilities(new Network[]{null, mobile, null, wifi}, 7740 initialCapsNotMetered, caps); 7741 assertEquals(withWifiAndMobileUnderlying, caps); 7742 assertEquals(2, new ArrayList<>(caps.getUnderlyingNetworks()).size()); 7743 assertEquals(mobile, new ArrayList<>(caps.getUnderlyingNetworks()).get(0)); 7744 assertEquals(wifi, new ArrayList<>(caps.getUnderlyingNetworks()).get(1)); 7745 7746 caps = new NetworkCapabilities(initialCaps); 7747 mService.applyUnderlyingCapabilities(new Network[]{null, mobile, null, wifi}, 7748 initialCapsNotMetered, caps); 7749 assertEquals(withWifiAndMobileUnderlying, caps); 7750 assertEquals(2, new ArrayList<>(caps.getUnderlyingNetworks()).size()); 7751 assertEquals(mobile, new ArrayList<>(caps.getUnderlyingNetworks()).get(0)); 7752 assertEquals(wifi, new ArrayList<>(caps.getUnderlyingNetworks()).get(1)); 7753 7754 caps = new NetworkCapabilities(initialCaps); 7755 mService.applyUnderlyingCapabilities(null, initialCapsNotMetered, caps); 7756 assertEquals(withWifiUnderlying, caps); 7757 assertEquals(1, new ArrayList<>(caps.getUnderlyingNetworks()).size()); 7758 assertEquals(wifi, new ArrayList<>(caps.getUnderlyingNetworks()).get(0)); 7759 } 7760 7761 @Test 7762 public void testVpnConnectDisconnectUnderlyingNetwork() throws Exception { 7763 final TestNetworkCallback callback = new TestNetworkCallback(); 7764 final NetworkRequest request = new NetworkRequest.Builder() 7765 .removeCapability(NET_CAPABILITY_NOT_VPN).build(); 7766 7767 runAsShell(NETWORK_SETTINGS, () -> { 7768 mCm.registerNetworkCallback(request, callback); 7769 7770 // Bring up a VPN that specifies an underlying network that does not exist yet. 7771 // Note: it's sort of meaningless for a VPN app to declare a network that doesn't exist 7772 // yet, (and doing so is difficult without using reflection) but it's good to test that 7773 // the code behaves approximately correctly. 7774 mMockVpn.establishForMyUid(false, true, false); 7775 callback.expectAvailableCallbacksUnvalidated(mMockVpn); 7776 assertUidRangesUpdatedForMyUid(true); 7777 final Network wifiNetwork = new Network(mNetIdManager.peekNextNetId()); 7778 mMockVpn.setUnderlyingNetworks(new Network[]{wifiNetwork}); 7779 // onCapabilitiesChanged() should be called because 7780 // NetworkCapabilities#mUnderlyingNetworks is updated. 7781 CallbackEntry ce = callback.expectCallback(CallbackEntry.NETWORK_CAPS_UPDATED, 7782 mMockVpn); 7783 final NetworkCapabilities vpnNc1 = ((CallbackEntry.CapabilitiesChanged) ce).getCaps(); 7784 // Since the wifi network hasn't brought up, 7785 // ConnectivityService#applyUnderlyingCapabilities cannot find it. Update 7786 // NetworkCapabilities#mUnderlyingNetworks to an empty array, and it will be updated to 7787 // the correct underlying networks once the wifi network brings up. But this case 7788 // shouldn't happen in reality since no one could get the network which hasn't brought 7789 // up. For the empty array of underlying networks, it should be happened for 2 cases, 7790 // the first one is that the VPN app declares an empty array for its underlying 7791 // networks, the second one is that the underlying networks are torn down. 7792 // 7793 // It shouldn't be null since the null value means the underlying networks of this 7794 // network should follow the default network. 7795 final ArrayList<Network> underlyingNetwork = new ArrayList<>(); 7796 assertEquals(underlyingNetwork, vpnNc1.getUnderlyingNetworks()); 7797 // Since the wifi network isn't exist, applyUnderlyingCapabilities() 7798 assertTrue(mCm.getNetworkCapabilities(mMockVpn.getNetwork()) 7799 .hasTransport(TRANSPORT_VPN)); 7800 assertFalse(mCm.getNetworkCapabilities(mMockVpn.getNetwork()) 7801 .hasTransport(TRANSPORT_WIFI)); 7802 7803 // Make that underlying network connect, and expect to see its capabilities immediately 7804 // reflected in the VPN's capabilities. 7805 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 7806 assertEquals(wifiNetwork, mWiFiNetworkAgent.getNetwork()); 7807 mWiFiNetworkAgent.connect(false); 7808 // TODO: the callback for the VPN happens before any callbacks are called for the wifi 7809 // network that has just connected. There appear to be two issues here: 7810 // 1. The VPN code will accept an underlying network as soon as getNetworkCapabilities() 7811 // for it returns non-null (which happens very early, during 7812 // handleRegisterNetworkAgent). 7813 // This is not correct because that that point the network is not connected and 7814 // cannot pass any traffic. 7815 // 2. When a network connects, updateNetworkInfo propagates underlying network 7816 // capabilities before rematching networks. 7817 // Given that this scenario can't really happen, this is probably fine for now. 7818 ce = callback.expectCallback(CallbackEntry.NETWORK_CAPS_UPDATED, mMockVpn); 7819 final NetworkCapabilities vpnNc2 = ((CallbackEntry.CapabilitiesChanged) ce).getCaps(); 7820 // The wifi network is brought up, NetworkCapabilities#mUnderlyingNetworks is updated to 7821 // it. 7822 underlyingNetwork.add(wifiNetwork); 7823 assertEquals(underlyingNetwork, vpnNc2.getUnderlyingNetworks()); 7824 callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 7825 assertTrue(mCm.getNetworkCapabilities(mMockVpn.getNetwork()) 7826 .hasTransport(TRANSPORT_VPN)); 7827 assertTrue(mCm.getNetworkCapabilities(mMockVpn.getNetwork()) 7828 .hasTransport(TRANSPORT_WIFI)); 7829 7830 // Disconnect the network, and expect to see the VPN capabilities change accordingly. 7831 mWiFiNetworkAgent.disconnect(); 7832 callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 7833 callback.expectCapabilitiesThat(mMockVpn, (nc) -> 7834 nc.getTransportTypes().length == 1 && nc.hasTransport(TRANSPORT_VPN)); 7835 7836 mMockVpn.disconnect(); 7837 mCm.unregisterNetworkCallback(callback); 7838 }); 7839 } 7840 7841 private void assertGetNetworkInfoOfGetActiveNetworkIsConnected(boolean expectedConnectivity) { 7842 // What Chromium used to do before https://chromium-review.googlesource.com/2605304 7843 assertEquals("Unexpected result for getActiveNetworkInfo(getActiveNetwork())", 7844 expectedConnectivity, mCm.getNetworkInfo(mCm.getActiveNetwork()).isConnected()); 7845 } 7846 7847 @Test 7848 public void testVpnUnderlyingNetworkSuspended() throws Exception { 7849 final TestNetworkCallback callback = new TestNetworkCallback(); 7850 mCm.registerDefaultNetworkCallback(callback); 7851 7852 // Connect a VPN. 7853 mMockVpn.establishForMyUid(false /* validated */, true /* hasInternet */, 7854 false /* isStrictMode */); 7855 callback.expectAvailableCallbacksUnvalidated(mMockVpn); 7856 7857 // Connect cellular data. 7858 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 7859 mCellNetworkAgent.connect(false /* validated */); 7860 callback.expectCapabilitiesThat(mMockVpn, 7861 nc -> nc.hasCapability(NET_CAPABILITY_NOT_SUSPENDED) 7862 && nc.hasTransport(TRANSPORT_CELLULAR)); 7863 callback.assertNoCallback(); 7864 7865 assertTrue(mCm.getNetworkCapabilities(mMockVpn.getNetwork()) 7866 .hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 7867 assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 7868 assertNetworkInfo(TYPE_WIFI, DetailedState.DISCONNECTED); 7869 assertNetworkInfo(TYPE_VPN, DetailedState.CONNECTED); 7870 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 7871 assertGetNetworkInfoOfGetActiveNetworkIsConnected(true); 7872 7873 // Suspend the cellular network and expect the VPN to be suspended. 7874 mCellNetworkAgent.suspend(); 7875 callback.expectCapabilitiesThat(mMockVpn, 7876 nc -> !nc.hasCapability(NET_CAPABILITY_NOT_SUSPENDED) 7877 && nc.hasTransport(TRANSPORT_CELLULAR)); 7878 callback.expectCallback(CallbackEntry.SUSPENDED, mMockVpn); 7879 callback.assertNoCallback(); 7880 7881 assertFalse(mCm.getNetworkCapabilities(mMockVpn.getNetwork()) 7882 .hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 7883 assertNetworkInfo(TYPE_MOBILE, DetailedState.SUSPENDED); 7884 assertNetworkInfo(TYPE_WIFI, DetailedState.DISCONNECTED); 7885 assertNetworkInfo(TYPE_VPN, DetailedState.SUSPENDED); 7886 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.SUSPENDED); 7887 // VPN's main underlying network is suspended, so no connectivity. 7888 assertGetNetworkInfoOfGetActiveNetworkIsConnected(false); 7889 7890 // Switch to another network. The VPN should no longer be suspended. 7891 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 7892 mWiFiNetworkAgent.connect(false /* validated */); 7893 callback.expectCapabilitiesThat(mMockVpn, 7894 nc -> nc.hasCapability(NET_CAPABILITY_NOT_SUSPENDED) 7895 && nc.hasTransport(TRANSPORT_WIFI)); 7896 callback.expectCallback(CallbackEntry.RESUMED, mMockVpn); 7897 callback.assertNoCallback(); 7898 7899 assertTrue(mCm.getNetworkCapabilities(mMockVpn.getNetwork()) 7900 .hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 7901 assertNetworkInfo(TYPE_MOBILE, DetailedState.DISCONNECTED); 7902 assertNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 7903 assertNetworkInfo(TYPE_VPN, DetailedState.CONNECTED); 7904 assertActiveNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 7905 assertGetNetworkInfoOfGetActiveNetworkIsConnected(true); 7906 7907 // Unsuspend cellular and then switch back to it. The VPN remains not suspended. 7908 mCellNetworkAgent.resume(); 7909 callback.assertNoCallback(); 7910 mWiFiNetworkAgent.disconnect(); 7911 callback.expectCapabilitiesThat(mMockVpn, 7912 nc -> nc.hasCapability(NET_CAPABILITY_NOT_SUSPENDED) 7913 && nc.hasTransport(TRANSPORT_CELLULAR)); 7914 // Spurious double callback? 7915 callback.expectCapabilitiesThat(mMockVpn, 7916 nc -> nc.hasCapability(NET_CAPABILITY_NOT_SUSPENDED) 7917 && nc.hasTransport(TRANSPORT_CELLULAR)); 7918 callback.assertNoCallback(); 7919 7920 assertTrue(mCm.getNetworkCapabilities(mMockVpn.getNetwork()) 7921 .hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 7922 assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 7923 assertNetworkInfo(TYPE_WIFI, DetailedState.DISCONNECTED); 7924 assertNetworkInfo(TYPE_VPN, DetailedState.CONNECTED); 7925 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 7926 assertGetNetworkInfoOfGetActiveNetworkIsConnected(true); 7927 7928 // Suspend cellular and expect no connectivity. 7929 mCellNetworkAgent.suspend(); 7930 callback.expectCapabilitiesThat(mMockVpn, 7931 nc -> !nc.hasCapability(NET_CAPABILITY_NOT_SUSPENDED) 7932 && nc.hasTransport(TRANSPORT_CELLULAR)); 7933 callback.expectCallback(CallbackEntry.SUSPENDED, mMockVpn); 7934 callback.assertNoCallback(); 7935 7936 assertFalse(mCm.getNetworkCapabilities(mMockVpn.getNetwork()) 7937 .hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 7938 assertNetworkInfo(TYPE_MOBILE, DetailedState.SUSPENDED); 7939 assertNetworkInfo(TYPE_WIFI, DetailedState.DISCONNECTED); 7940 assertNetworkInfo(TYPE_VPN, DetailedState.SUSPENDED); 7941 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.SUSPENDED); 7942 assertGetNetworkInfoOfGetActiveNetworkIsConnected(false); 7943 7944 // Resume cellular and expect that connectivity comes back. 7945 mCellNetworkAgent.resume(); 7946 callback.expectCapabilitiesThat(mMockVpn, 7947 nc -> nc.hasCapability(NET_CAPABILITY_NOT_SUSPENDED) 7948 && nc.hasTransport(TRANSPORT_CELLULAR)); 7949 callback.expectCallback(CallbackEntry.RESUMED, mMockVpn); 7950 callback.assertNoCallback(); 7951 7952 assertTrue(mCm.getNetworkCapabilities(mMockVpn.getNetwork()) 7953 .hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 7954 assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 7955 assertNetworkInfo(TYPE_WIFI, DetailedState.DISCONNECTED); 7956 assertNetworkInfo(TYPE_VPN, DetailedState.CONNECTED); 7957 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 7958 assertGetNetworkInfoOfGetActiveNetworkIsConnected(true); 7959 } 7960 7961 @Test 7962 public void testVpnNetworkActive() throws Exception { 7963 // NETWORK_SETTINGS is necessary to call registerSystemDefaultNetworkCallback. 7964 mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_GRANTED); 7965 7966 final int uid = Process.myUid(); 7967 7968 final TestNetworkCallback genericNetworkCallback = new TestNetworkCallback(); 7969 final TestNetworkCallback genericNotVpnNetworkCallback = new TestNetworkCallback(); 7970 final TestNetworkCallback wifiNetworkCallback = new TestNetworkCallback(); 7971 final TestNetworkCallback vpnNetworkCallback = new TestNetworkCallback(); 7972 final TestNetworkCallback defaultCallback = new TestNetworkCallback(); 7973 final TestNetworkCallback systemDefaultCallback = new TestNetworkCallback(); 7974 final NetworkRequest genericNotVpnRequest = new NetworkRequest.Builder().build(); 7975 final NetworkRequest genericRequest = new NetworkRequest.Builder() 7976 .removeCapability(NET_CAPABILITY_NOT_VPN).build(); 7977 final NetworkRequest wifiRequest = new NetworkRequest.Builder() 7978 .addTransportType(TRANSPORT_WIFI).build(); 7979 final NetworkRequest vpnNetworkRequest = new NetworkRequest.Builder() 7980 .removeCapability(NET_CAPABILITY_NOT_VPN) 7981 .addTransportType(TRANSPORT_VPN).build(); 7982 mCm.registerNetworkCallback(genericRequest, genericNetworkCallback); 7983 mCm.registerNetworkCallback(genericNotVpnRequest, genericNotVpnNetworkCallback); 7984 mCm.registerNetworkCallback(wifiRequest, wifiNetworkCallback); 7985 mCm.registerNetworkCallback(vpnNetworkRequest, vpnNetworkCallback); 7986 mCm.registerDefaultNetworkCallback(defaultCallback); 7987 mCm.registerSystemDefaultNetworkCallback(systemDefaultCallback, 7988 new Handler(ConnectivityThread.getInstanceLooper())); 7989 defaultCallback.assertNoCallback(); 7990 7991 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 7992 mWiFiNetworkAgent.connect(false); 7993 7994 genericNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 7995 genericNotVpnNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 7996 wifiNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 7997 defaultCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 7998 systemDefaultCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 7999 vpnNetworkCallback.assertNoCallback(); 8000 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 8001 8002 final Set<UidRange> ranges = uidRangesForUids(uid); 8003 mMockVpn.registerAgent(ranges); 8004 mMockVpn.setUnderlyingNetworks(new Network[0]); 8005 8006 // VPN networks do not satisfy the default request and are automatically validated 8007 // by NetworkMonitor 8008 assertFalse(NetworkMonitorUtils.isValidationRequired( 8009 NetworkAgentConfigShimImpl.newInstance(mMockVpn.getNetworkAgentConfig()), 8010 mMockVpn.getAgent().getNetworkCapabilities())); 8011 mMockVpn.getAgent().setNetworkValid(false /* isStrictMode */); 8012 8013 mMockVpn.connect(false); 8014 8015 genericNetworkCallback.expectAvailableThenValidatedCallbacks(mMockVpn); 8016 genericNotVpnNetworkCallback.assertNoCallback(); 8017 wifiNetworkCallback.assertNoCallback(); 8018 vpnNetworkCallback.expectAvailableThenValidatedCallbacks(mMockVpn); 8019 defaultCallback.expectAvailableThenValidatedCallbacks(mMockVpn); 8020 systemDefaultCallback.assertNoCallback(); 8021 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 8022 assertEquals(mWiFiNetworkAgent.getNetwork(), 8023 systemDefaultCallback.getLastAvailableNetwork()); 8024 8025 ranges.clear(); 8026 mMockVpn.setUids(ranges); 8027 8028 genericNetworkCallback.expectCallback(CallbackEntry.LOST, mMockVpn); 8029 genericNotVpnNetworkCallback.assertNoCallback(); 8030 wifiNetworkCallback.assertNoCallback(); 8031 vpnNetworkCallback.expectCallback(CallbackEntry.LOST, mMockVpn); 8032 8033 // TODO : The default network callback should actually get a LOST call here (also see the 8034 // comment below for AVAILABLE). This is because ConnectivityService does not look at UID 8035 // ranges at all when determining whether a network should be rematched. In practice, VPNs 8036 // can't currently update their UIDs without disconnecting, so this does not matter too 8037 // much, but that is the reason the test here has to check for an update to the 8038 // capabilities instead of the expected LOST then AVAILABLE. 8039 defaultCallback.expectCallback(CallbackEntry.NETWORK_CAPS_UPDATED, mMockVpn); 8040 systemDefaultCallback.assertNoCallback(); 8041 8042 ranges.add(new UidRange(uid, uid)); 8043 mMockVpn.setUids(ranges); 8044 8045 genericNetworkCallback.expectAvailableCallbacksValidated(mMockVpn); 8046 genericNotVpnNetworkCallback.assertNoCallback(); 8047 wifiNetworkCallback.assertNoCallback(); 8048 vpnNetworkCallback.expectAvailableCallbacksValidated(mMockVpn); 8049 // TODO : Here like above, AVAILABLE would be correct, but because this can't actually 8050 // happen outside of the test, ConnectivityService does not rematch callbacks. 8051 defaultCallback.expectCallback(CallbackEntry.NETWORK_CAPS_UPDATED, mMockVpn); 8052 systemDefaultCallback.assertNoCallback(); 8053 8054 mWiFiNetworkAgent.disconnect(); 8055 8056 genericNetworkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 8057 genericNotVpnNetworkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 8058 wifiNetworkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 8059 vpnNetworkCallback.assertNoCallback(); 8060 defaultCallback.assertNoCallback(); 8061 systemDefaultCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 8062 8063 mMockVpn.disconnect(); 8064 8065 genericNetworkCallback.expectCallback(CallbackEntry.LOST, mMockVpn); 8066 genericNotVpnNetworkCallback.assertNoCallback(); 8067 wifiNetworkCallback.assertNoCallback(); 8068 vpnNetworkCallback.expectCallback(CallbackEntry.LOST, mMockVpn); 8069 defaultCallback.expectCallback(CallbackEntry.LOST, mMockVpn); 8070 systemDefaultCallback.assertNoCallback(); 8071 assertEquals(null, mCm.getActiveNetwork()); 8072 8073 mCm.unregisterNetworkCallback(genericNetworkCallback); 8074 mCm.unregisterNetworkCallback(wifiNetworkCallback); 8075 mCm.unregisterNetworkCallback(vpnNetworkCallback); 8076 mCm.unregisterNetworkCallback(defaultCallback); 8077 mCm.unregisterNetworkCallback(systemDefaultCallback); 8078 } 8079 8080 @Test 8081 public void testVpnWithoutInternet() throws Exception { 8082 final int uid = Process.myUid(); 8083 8084 final TestNetworkCallback defaultCallback = new TestNetworkCallback(); 8085 mCm.registerDefaultNetworkCallback(defaultCallback); 8086 8087 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 8088 mWiFiNetworkAgent.connect(true); 8089 8090 defaultCallback.expectAvailableThenValidatedCallbacks(mWiFiNetworkAgent); 8091 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 8092 8093 mMockVpn.establishForMyUid(true /* validated */, false /* hasInternet */, 8094 false /* isStrictMode */); 8095 assertUidRangesUpdatedForMyUid(true); 8096 8097 defaultCallback.assertNoCallback(); 8098 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 8099 8100 mMockVpn.disconnect(); 8101 defaultCallback.assertNoCallback(); 8102 8103 mCm.unregisterNetworkCallback(defaultCallback); 8104 } 8105 8106 @Test 8107 public void testVpnWithInternet() throws Exception { 8108 final int uid = Process.myUid(); 8109 8110 final TestNetworkCallback defaultCallback = new TestNetworkCallback(); 8111 mCm.registerDefaultNetworkCallback(defaultCallback); 8112 8113 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 8114 mWiFiNetworkAgent.connect(true); 8115 8116 defaultCallback.expectAvailableThenValidatedCallbacks(mWiFiNetworkAgent); 8117 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 8118 8119 mMockVpn.establishForMyUid(true /* validated */, true /* hasInternet */, 8120 false /* isStrictMode */); 8121 assertUidRangesUpdatedForMyUid(true); 8122 8123 defaultCallback.expectAvailableThenValidatedCallbacks(mMockVpn); 8124 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 8125 8126 mMockVpn.disconnect(); 8127 defaultCallback.expectCallback(CallbackEntry.LOST, mMockVpn); 8128 defaultCallback.expectAvailableCallbacksValidated(mWiFiNetworkAgent); 8129 8130 mCm.unregisterNetworkCallback(defaultCallback); 8131 } 8132 8133 @Test 8134 public void testVpnUnvalidated() throws Exception { 8135 final TestNetworkCallback callback = new TestNetworkCallback(); 8136 mCm.registerDefaultNetworkCallback(callback); 8137 8138 // Bring up Ethernet. 8139 mEthernetNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_ETHERNET); 8140 mEthernetNetworkAgent.connect(true); 8141 callback.expectAvailableThenValidatedCallbacks(mEthernetNetworkAgent); 8142 callback.assertNoCallback(); 8143 8144 // Bring up a VPN that has the INTERNET capability, initially unvalidated. 8145 mMockVpn.establishForMyUid(false /* validated */, true /* hasInternet */, 8146 false /* isStrictMode */); 8147 assertUidRangesUpdatedForMyUid(true); 8148 8149 // Even though the VPN is unvalidated, it becomes the default network for our app. 8150 callback.expectAvailableCallbacksUnvalidated(mMockVpn); 8151 callback.assertNoCallback(); 8152 8153 assertEquals(mMockVpn.getNetwork(), mCm.getActiveNetwork()); 8154 8155 NetworkCapabilities nc = mCm.getNetworkCapabilities(mMockVpn.getNetwork()); 8156 assertFalse(nc.hasCapability(NET_CAPABILITY_VALIDATED)); 8157 assertTrue(nc.hasCapability(NET_CAPABILITY_INTERNET)); 8158 8159 assertFalse(NetworkMonitorUtils.isValidationRequired( 8160 NetworkAgentConfigShimImpl.newInstance(mMockVpn.getNetworkAgentConfig()), 8161 mMockVpn.getAgent().getNetworkCapabilities())); 8162 assertTrue(NetworkMonitorUtils.isPrivateDnsValidationRequired( 8163 mMockVpn.getAgent().getNetworkCapabilities())); 8164 8165 // Pretend that the VPN network validates. 8166 mMockVpn.getAgent().setNetworkValid(false /* isStrictMode */); 8167 mMockVpn.getAgent().mNetworkMonitor.forceReevaluation(Process.myUid()); 8168 // Expect to see the validated capability, but no other changes, because the VPN is already 8169 // the default network for the app. 8170 callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mMockVpn); 8171 callback.assertNoCallback(); 8172 8173 mMockVpn.disconnect(); 8174 callback.expectCallback(CallbackEntry.LOST, mMockVpn); 8175 callback.expectAvailableCallbacksValidated(mEthernetNetworkAgent); 8176 } 8177 8178 @Test 8179 public void testVpnStartsWithUnderlyingCaps() throws Exception { 8180 final int uid = Process.myUid(); 8181 8182 final TestNetworkCallback vpnNetworkCallback = new TestNetworkCallback(); 8183 final NetworkRequest vpnNetworkRequest = new NetworkRequest.Builder() 8184 .removeCapability(NET_CAPABILITY_NOT_VPN) 8185 .addTransportType(TRANSPORT_VPN) 8186 .build(); 8187 mCm.registerNetworkCallback(vpnNetworkRequest, vpnNetworkCallback); 8188 vpnNetworkCallback.assertNoCallback(); 8189 8190 // Connect cell. It will become the default network, and in the absence of setting 8191 // underlying networks explicitly it will become the sole underlying network for the vpn. 8192 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 8193 mCellNetworkAgent.addCapability(NET_CAPABILITY_NOT_SUSPENDED); 8194 mCellNetworkAgent.connect(true); 8195 8196 mMockVpn.establishForMyUid(true /* validated */, false /* hasInternet */, 8197 false /* isStrictMode */); 8198 assertUidRangesUpdatedForMyUid(true); 8199 8200 vpnNetworkCallback.expectAvailableCallbacks(mMockVpn.getNetwork(), 8201 false /* suspended */, false /* validated */, false /* blocked */, TIMEOUT_MS); 8202 vpnNetworkCallback.expectCapabilitiesThat(mMockVpn.getNetwork(), TIMEOUT_MS, 8203 nc -> nc.hasCapability(NET_CAPABILITY_VALIDATED)); 8204 8205 final NetworkCapabilities nc = mCm.getNetworkCapabilities(mMockVpn.getNetwork()); 8206 assertTrue(nc.hasTransport(TRANSPORT_VPN)); 8207 assertTrue(nc.hasTransport(TRANSPORT_CELLULAR)); 8208 assertFalse(nc.hasTransport(TRANSPORT_WIFI)); 8209 assertTrue(nc.hasCapability(NET_CAPABILITY_VALIDATED)); 8210 assertFalse(nc.hasCapability(NET_CAPABILITY_NOT_METERED)); 8211 assertTrue(nc.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 8212 8213 assertVpnTransportInfo(nc, VpnManager.TYPE_VPN_SERVICE); 8214 } 8215 8216 private void assertDefaultNetworkCapabilities(int userId, NetworkAgentWrapper... networks) { 8217 final NetworkCapabilities[] defaultCaps = mService.getDefaultNetworkCapabilitiesForUser( 8218 userId, "com.android.calling.package", "com.test"); 8219 final String defaultCapsString = Arrays.toString(defaultCaps); 8220 assertEquals(defaultCapsString, defaultCaps.length, networks.length); 8221 final Set<NetworkCapabilities> defaultCapsSet = new ArraySet<>(defaultCaps); 8222 for (NetworkAgentWrapper network : networks) { 8223 final NetworkCapabilities nc = mCm.getNetworkCapabilities(network.getNetwork()); 8224 final String msg = "Did not find " + nc + " in " + Arrays.toString(defaultCaps); 8225 assertTrue(msg, defaultCapsSet.contains(nc)); 8226 } 8227 } 8228 8229 @Test 8230 public void testVpnSetUnderlyingNetworks() throws Exception { 8231 final TestNetworkCallback vpnNetworkCallback = new TestNetworkCallback(); 8232 final NetworkRequest vpnNetworkRequest = new NetworkRequest.Builder() 8233 .removeCapability(NET_CAPABILITY_NOT_VPN) 8234 .addTransportType(TRANSPORT_VPN) 8235 .build(); 8236 NetworkCapabilities nc; 8237 mCm.registerNetworkCallback(vpnNetworkRequest, vpnNetworkCallback); 8238 vpnNetworkCallback.assertNoCallback(); 8239 8240 mMockVpn.establishForMyUid(true /* validated */, false /* hasInternet */, 8241 false /* isStrictMode */); 8242 assertUidRangesUpdatedForMyUid(true); 8243 8244 vpnNetworkCallback.expectAvailableThenValidatedCallbacks(mMockVpn); 8245 nc = mCm.getNetworkCapabilities(mMockVpn.getNetwork()); 8246 assertTrue(nc.hasTransport(TRANSPORT_VPN)); 8247 assertFalse(nc.hasTransport(TRANSPORT_CELLULAR)); 8248 assertFalse(nc.hasTransport(TRANSPORT_WIFI)); 8249 // For safety reasons a VPN without underlying networks is considered metered. 8250 assertFalse(nc.hasCapability(NET_CAPABILITY_NOT_METERED)); 8251 // A VPN without underlying networks is not suspended. 8252 assertTrue(nc.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 8253 assertVpnTransportInfo(nc, VpnManager.TYPE_VPN_SERVICE); 8254 8255 final int userId = UserHandle.getUserId(Process.myUid()); 8256 assertDefaultNetworkCapabilities(userId /* no networks */); 8257 8258 // Connect cell and use it as an underlying network. 8259 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 8260 mCellNetworkAgent.addCapability(NET_CAPABILITY_NOT_SUSPENDED); 8261 mCellNetworkAgent.connect(true); 8262 8263 mMockVpn.setUnderlyingNetworks( 8264 new Network[] { mCellNetworkAgent.getNetwork() }); 8265 8266 vpnNetworkCallback.expectCapabilitiesThat(mMockVpn, 8267 (caps) -> caps.hasTransport(TRANSPORT_VPN) 8268 && caps.hasTransport(TRANSPORT_CELLULAR) && !caps.hasTransport(TRANSPORT_WIFI) 8269 && !caps.hasCapability(NET_CAPABILITY_NOT_METERED) 8270 && caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 8271 assertDefaultNetworkCapabilities(userId, mCellNetworkAgent); 8272 8273 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 8274 mWiFiNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED); 8275 mWiFiNetworkAgent.addCapability(NET_CAPABILITY_NOT_SUSPENDED); 8276 mWiFiNetworkAgent.connect(true); 8277 8278 mMockVpn.setUnderlyingNetworks( 8279 new Network[] { mCellNetworkAgent.getNetwork(), mWiFiNetworkAgent.getNetwork() }); 8280 8281 vpnNetworkCallback.expectCapabilitiesThat(mMockVpn, 8282 (caps) -> caps.hasTransport(TRANSPORT_VPN) 8283 && caps.hasTransport(TRANSPORT_CELLULAR) && caps.hasTransport(TRANSPORT_WIFI) 8284 && !caps.hasCapability(NET_CAPABILITY_NOT_METERED) 8285 && caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 8286 assertDefaultNetworkCapabilities(userId, mCellNetworkAgent, mWiFiNetworkAgent); 8287 8288 // Don't disconnect, but note the VPN is not using wifi any more. 8289 mMockVpn.setUnderlyingNetworks( 8290 new Network[] { mCellNetworkAgent.getNetwork() }); 8291 8292 vpnNetworkCallback.expectCapabilitiesThat(mMockVpn, 8293 (caps) -> caps.hasTransport(TRANSPORT_VPN) 8294 && caps.hasTransport(TRANSPORT_CELLULAR) && !caps.hasTransport(TRANSPORT_WIFI) 8295 && !caps.hasCapability(NET_CAPABILITY_NOT_METERED) 8296 && caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 8297 // The return value of getDefaultNetworkCapabilitiesForUser always includes the default 8298 // network (wifi) as well as the underlying networks (cell). 8299 assertDefaultNetworkCapabilities(userId, mCellNetworkAgent, mWiFiNetworkAgent); 8300 8301 // Remove NOT_SUSPENDED from the only network and observe VPN is now suspended. 8302 mCellNetworkAgent.removeCapability(NET_CAPABILITY_NOT_SUSPENDED); 8303 vpnNetworkCallback.expectCapabilitiesThat(mMockVpn, 8304 (caps) -> caps.hasTransport(TRANSPORT_VPN) 8305 && caps.hasTransport(TRANSPORT_CELLULAR) && !caps.hasTransport(TRANSPORT_WIFI) 8306 && !caps.hasCapability(NET_CAPABILITY_NOT_METERED) 8307 && !caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 8308 vpnNetworkCallback.expectCallback(CallbackEntry.SUSPENDED, mMockVpn); 8309 8310 // Add NOT_SUSPENDED again and observe VPN is no longer suspended. 8311 mCellNetworkAgent.addCapability(NET_CAPABILITY_NOT_SUSPENDED); 8312 vpnNetworkCallback.expectCapabilitiesThat(mMockVpn, 8313 (caps) -> caps.hasTransport(TRANSPORT_VPN) 8314 && caps.hasTransport(TRANSPORT_CELLULAR) && !caps.hasTransport(TRANSPORT_WIFI) 8315 && !caps.hasCapability(NET_CAPABILITY_NOT_METERED) 8316 && caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 8317 vpnNetworkCallback.expectCallback(CallbackEntry.RESUMED, mMockVpn); 8318 8319 // Use Wifi but not cell. Note the VPN is now unmetered and not suspended. 8320 mMockVpn.setUnderlyingNetworks( 8321 new Network[] { mWiFiNetworkAgent.getNetwork() }); 8322 8323 vpnNetworkCallback.expectCapabilitiesThat(mMockVpn, 8324 (caps) -> caps.hasTransport(TRANSPORT_VPN) 8325 && !caps.hasTransport(TRANSPORT_CELLULAR) && caps.hasTransport(TRANSPORT_WIFI) 8326 && caps.hasCapability(NET_CAPABILITY_NOT_METERED) 8327 && caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 8328 assertDefaultNetworkCapabilities(userId, mWiFiNetworkAgent); 8329 8330 // Use both again. 8331 mMockVpn.setUnderlyingNetworks( 8332 new Network[] { mCellNetworkAgent.getNetwork(), mWiFiNetworkAgent.getNetwork() }); 8333 8334 vpnNetworkCallback.expectCapabilitiesThat(mMockVpn, 8335 (caps) -> caps.hasTransport(TRANSPORT_VPN) 8336 && caps.hasTransport(TRANSPORT_CELLULAR) && caps.hasTransport(TRANSPORT_WIFI) 8337 && !caps.hasCapability(NET_CAPABILITY_NOT_METERED) 8338 && caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 8339 assertDefaultNetworkCapabilities(userId, mCellNetworkAgent, mWiFiNetworkAgent); 8340 8341 // Cell is suspended again. As WiFi is not, this should not cause a callback. 8342 mCellNetworkAgent.removeCapability(NET_CAPABILITY_NOT_SUSPENDED); 8343 vpnNetworkCallback.assertNoCallback(); 8344 8345 // Stop using WiFi. The VPN is suspended again. 8346 mMockVpn.setUnderlyingNetworks( 8347 new Network[] { mCellNetworkAgent.getNetwork() }); 8348 vpnNetworkCallback.expectCapabilitiesThat(mMockVpn, 8349 (caps) -> caps.hasTransport(TRANSPORT_VPN) 8350 && caps.hasTransport(TRANSPORT_CELLULAR) 8351 && !caps.hasCapability(NET_CAPABILITY_NOT_METERED) 8352 && !caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 8353 vpnNetworkCallback.expectCallback(CallbackEntry.SUSPENDED, mMockVpn); 8354 assertDefaultNetworkCapabilities(userId, mCellNetworkAgent, mWiFiNetworkAgent); 8355 8356 // Use both again. 8357 mMockVpn.setUnderlyingNetworks( 8358 new Network[] { mCellNetworkAgent.getNetwork(), mWiFiNetworkAgent.getNetwork() }); 8359 8360 vpnNetworkCallback.expectCapabilitiesThat(mMockVpn, 8361 (caps) -> caps.hasTransport(TRANSPORT_VPN) 8362 && caps.hasTransport(TRANSPORT_CELLULAR) && caps.hasTransport(TRANSPORT_WIFI) 8363 && !caps.hasCapability(NET_CAPABILITY_NOT_METERED) 8364 && caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 8365 vpnNetworkCallback.expectCallback(CallbackEntry.RESUMED, mMockVpn); 8366 assertDefaultNetworkCapabilities(userId, mCellNetworkAgent, mWiFiNetworkAgent); 8367 8368 // Disconnect cell. Receive update without even removing the dead network from the 8369 // underlying networks – it's dead anyway. Not metered any more. 8370 mCellNetworkAgent.disconnect(); 8371 vpnNetworkCallback.expectCapabilitiesThat(mMockVpn, 8372 (caps) -> caps.hasTransport(TRANSPORT_VPN) 8373 && !caps.hasTransport(TRANSPORT_CELLULAR) && caps.hasTransport(TRANSPORT_WIFI) 8374 && caps.hasCapability(NET_CAPABILITY_NOT_METERED)); 8375 assertDefaultNetworkCapabilities(userId, mWiFiNetworkAgent); 8376 8377 // Disconnect wifi too. No underlying networks means this is now metered. 8378 mWiFiNetworkAgent.disconnect(); 8379 vpnNetworkCallback.expectCapabilitiesThat(mMockVpn, 8380 (caps) -> caps.hasTransport(TRANSPORT_VPN) 8381 && !caps.hasTransport(TRANSPORT_CELLULAR) && !caps.hasTransport(TRANSPORT_WIFI) 8382 && !caps.hasCapability(NET_CAPABILITY_NOT_METERED)); 8383 // When a network disconnects, the callbacks are fired before all state is updated, so for a 8384 // short time, synchronous calls will behave as if the network is still connected. Wait for 8385 // things to settle. 8386 waitForIdle(); 8387 assertDefaultNetworkCapabilities(userId /* no networks */); 8388 8389 mMockVpn.disconnect(); 8390 } 8391 8392 @Test 8393 public void testNullUnderlyingNetworks() throws Exception { 8394 final int uid = Process.myUid(); 8395 8396 final TestNetworkCallback vpnNetworkCallback = new TestNetworkCallback(); 8397 final NetworkRequest vpnNetworkRequest = new NetworkRequest.Builder() 8398 .removeCapability(NET_CAPABILITY_NOT_VPN) 8399 .addTransportType(TRANSPORT_VPN) 8400 .build(); 8401 NetworkCapabilities nc; 8402 mCm.registerNetworkCallback(vpnNetworkRequest, vpnNetworkCallback); 8403 vpnNetworkCallback.assertNoCallback(); 8404 8405 mMockVpn.establishForMyUid(true /* validated */, false /* hasInternet */, 8406 false /* isStrictMode */); 8407 assertUidRangesUpdatedForMyUid(true); 8408 8409 vpnNetworkCallback.expectAvailableThenValidatedCallbacks(mMockVpn); 8410 nc = mCm.getNetworkCapabilities(mMockVpn.getNetwork()); 8411 assertTrue(nc.hasTransport(TRANSPORT_VPN)); 8412 assertFalse(nc.hasTransport(TRANSPORT_CELLULAR)); 8413 assertFalse(nc.hasTransport(TRANSPORT_WIFI)); 8414 // By default, VPN is set to track default network (i.e. its underlying networks is null). 8415 // In case of no default network, VPN is considered metered. 8416 assertFalse(nc.hasCapability(NET_CAPABILITY_NOT_METERED)); 8417 assertVpnTransportInfo(nc, VpnManager.TYPE_VPN_SERVICE); 8418 8419 // Connect to Cell; Cell is the default network. 8420 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 8421 mCellNetworkAgent.connect(true); 8422 8423 vpnNetworkCallback.expectCapabilitiesThat(mMockVpn, 8424 (caps) -> caps.hasTransport(TRANSPORT_VPN) 8425 && caps.hasTransport(TRANSPORT_CELLULAR) && !caps.hasTransport(TRANSPORT_WIFI) 8426 && !caps.hasCapability(NET_CAPABILITY_NOT_METERED)); 8427 8428 // Connect to WiFi; WiFi is the new default. 8429 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 8430 mWiFiNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED); 8431 mWiFiNetworkAgent.connect(true); 8432 8433 vpnNetworkCallback.expectCapabilitiesThat(mMockVpn, 8434 (caps) -> caps.hasTransport(TRANSPORT_VPN) 8435 && !caps.hasTransport(TRANSPORT_CELLULAR) && caps.hasTransport(TRANSPORT_WIFI) 8436 && caps.hasCapability(NET_CAPABILITY_NOT_METERED)); 8437 8438 // Disconnect Cell. The default network did not change, so there shouldn't be any changes in 8439 // the capabilities. 8440 mCellNetworkAgent.disconnect(); 8441 8442 // Disconnect wifi too. Now we have no default network. 8443 mWiFiNetworkAgent.disconnect(); 8444 8445 vpnNetworkCallback.expectCapabilitiesThat(mMockVpn, 8446 (caps) -> caps.hasTransport(TRANSPORT_VPN) 8447 && !caps.hasTransport(TRANSPORT_CELLULAR) && !caps.hasTransport(TRANSPORT_WIFI) 8448 && !caps.hasCapability(NET_CAPABILITY_NOT_METERED)); 8449 8450 mMockVpn.disconnect(); 8451 } 8452 8453 @Test 8454 public void testRestrictedProfileAffectsVpnUidRanges() throws Exception { 8455 // NETWORK_SETTINGS is necessary to see the UID ranges in NetworkCapabilities. 8456 mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_GRANTED); 8457 8458 final NetworkRequest request = new NetworkRequest.Builder() 8459 .removeCapability(NET_CAPABILITY_NOT_VPN) 8460 .build(); 8461 final TestNetworkCallback callback = new TestNetworkCallback(); 8462 mCm.registerNetworkCallback(request, callback); 8463 8464 // Bring up a VPN 8465 mMockVpn.establishForMyUid(); 8466 assertUidRangesUpdatedForMyUid(true); 8467 callback.expectAvailableThenValidatedCallbacks(mMockVpn); 8468 callback.assertNoCallback(); 8469 8470 final int uid = Process.myUid(); 8471 NetworkCapabilities nc = mCm.getNetworkCapabilities(mMockVpn.getNetwork()); 8472 assertNotNull("nc=" + nc, nc.getUids()); 8473 assertEquals(nc.getUids(), UidRange.toIntRanges(uidRangesForUids(uid))); 8474 assertVpnTransportInfo(nc, VpnManager.TYPE_VPN_SERVICE); 8475 8476 // Set an underlying network and expect to see the VPN transports change. 8477 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 8478 mWiFiNetworkAgent.connect(true); 8479 callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 8480 callback.expectCapabilitiesThat(mMockVpn, (caps) 8481 -> caps.hasTransport(TRANSPORT_VPN) 8482 && caps.hasTransport(TRANSPORT_WIFI)); 8483 callback.expectCapabilitiesThat(mWiFiNetworkAgent, (caps) 8484 -> caps.hasCapability(NET_CAPABILITY_VALIDATED)); 8485 8486 doReturn(UserHandle.getUid(RESTRICTED_USER, VPN_UID)).when(mPackageManager) 8487 .getPackageUidAsUser(ALWAYS_ON_PACKAGE, RESTRICTED_USER); 8488 8489 final Intent addedIntent = new Intent(ACTION_USER_ADDED); 8490 addedIntent.putExtra(Intent.EXTRA_USER, UserHandle.of(RESTRICTED_USER)); 8491 addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, RESTRICTED_USER); 8492 8493 // Send a USER_ADDED broadcast for it. 8494 processBroadcast(addedIntent); 8495 8496 // Expect that the VPN UID ranges contain both |uid| and the UID range for the newly-added 8497 // restricted user. 8498 final UidRange rRange = UidRange.createForUser(UserHandle.of(RESTRICTED_USER)); 8499 final Range<Integer> restrictUidRange = new Range<Integer>(rRange.start, rRange.stop); 8500 final Range<Integer> singleUidRange = new Range<Integer>(uid, uid); 8501 callback.expectCapabilitiesThat(mMockVpn, (caps) 8502 -> caps.getUids().size() == 2 8503 && caps.getUids().contains(singleUidRange) 8504 && caps.getUids().contains(restrictUidRange) 8505 && caps.hasTransport(TRANSPORT_VPN) 8506 && caps.hasTransport(TRANSPORT_WIFI)); 8507 8508 // Change the VPN's capabilities somehow (specifically, disconnect wifi). 8509 mWiFiNetworkAgent.disconnect(); 8510 callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 8511 callback.expectCapabilitiesThat(mMockVpn, (caps) 8512 -> caps.getUids().size() == 2 8513 && caps.getUids().contains(singleUidRange) 8514 && caps.getUids().contains(restrictUidRange) 8515 && caps.hasTransport(TRANSPORT_VPN) 8516 && !caps.hasTransport(TRANSPORT_WIFI)); 8517 8518 // Send a USER_REMOVED broadcast and expect to lose the UID range for the restricted user. 8519 final Intent removedIntent = new Intent(ACTION_USER_REMOVED); 8520 removedIntent.putExtra(Intent.EXTRA_USER, UserHandle.of(RESTRICTED_USER)); 8521 removedIntent.putExtra(Intent.EXTRA_USER_HANDLE, RESTRICTED_USER); 8522 processBroadcast(removedIntent); 8523 8524 // Expect that the VPN gains the UID range for the restricted user, and that the capability 8525 // change made just before that (i.e., loss of TRANSPORT_WIFI) is preserved. 8526 callback.expectCapabilitiesThat(mMockVpn, (caps) 8527 -> caps.getUids().size() == 1 8528 && caps.getUids().contains(singleUidRange) 8529 && caps.hasTransport(TRANSPORT_VPN) 8530 && !caps.hasTransport(TRANSPORT_WIFI)); 8531 } 8532 8533 @Test 8534 public void testLockdownVpnWithRestrictedProfiles() throws Exception { 8535 // For ConnectivityService#setAlwaysOnVpnPackage. 8536 mServiceContext.setPermission( 8537 Manifest.permission.CONTROL_ALWAYS_ON_VPN, PERMISSION_GRANTED); 8538 // For call Vpn#setAlwaysOnPackage. 8539 mServiceContext.setPermission( 8540 Manifest.permission.CONTROL_VPN, PERMISSION_GRANTED); 8541 // Necessary to see the UID ranges in NetworkCapabilities. 8542 mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_GRANTED); 8543 8544 final NetworkRequest request = new NetworkRequest.Builder() 8545 .removeCapability(NET_CAPABILITY_NOT_VPN) 8546 .build(); 8547 final TestNetworkCallback callback = new TestNetworkCallback(); 8548 mCm.registerNetworkCallback(request, callback); 8549 8550 final int uid = Process.myUid(); 8551 8552 // Connect wifi and check that UIDs in the main and restricted profiles have network access. 8553 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 8554 mWiFiNetworkAgent.connect(true /* validated */); 8555 final int restrictedUid = UserHandle.getUid(RESTRICTED_USER, 42 /* appId */); 8556 assertNotNull(mCm.getActiveNetworkForUid(uid)); 8557 assertNotNull(mCm.getActiveNetworkForUid(restrictedUid)); 8558 8559 // Enable always-on VPN lockdown. The main user loses network access because no VPN is up. 8560 final ArrayList<String> allowList = new ArrayList<>(); 8561 mVpnManagerService.setAlwaysOnVpnPackage(PRIMARY_USER, ALWAYS_ON_PACKAGE, 8562 true /* lockdown */, allowList); 8563 waitForIdle(); 8564 assertNull(mCm.getActiveNetworkForUid(uid)); 8565 // This is arguably overspecified: a UID that is not running doesn't have an active network. 8566 // But it's useful to check that non-default users do not lose network access, and to prove 8567 // that the loss of connectivity below is indeed due to the restricted profile coming up. 8568 assertNotNull(mCm.getActiveNetworkForUid(restrictedUid)); 8569 8570 // Start the restricted profile, and check that the UID within it loses network access. 8571 doReturn(UserHandle.getUid(RESTRICTED_USER, VPN_UID)).when(mPackageManager) 8572 .getPackageUidAsUser(ALWAYS_ON_PACKAGE, RESTRICTED_USER); 8573 doReturn(asList(PRIMARY_USER_INFO, RESTRICTED_USER_INFO)).when(mUserManager) 8574 .getAliveUsers(); 8575 // TODO: check that VPN app within restricted profile still has access, etc. 8576 final Intent addedIntent = new Intent(ACTION_USER_ADDED); 8577 addedIntent.putExtra(Intent.EXTRA_USER, UserHandle.of(RESTRICTED_USER)); 8578 addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, RESTRICTED_USER); 8579 processBroadcast(addedIntent); 8580 assertNull(mCm.getActiveNetworkForUid(uid)); 8581 assertNull(mCm.getActiveNetworkForUid(restrictedUid)); 8582 8583 // Stop the restricted profile, and check that the UID within it has network access again. 8584 doReturn(asList(PRIMARY_USER_INFO)).when(mUserManager).getAliveUsers(); 8585 8586 // Send a USER_REMOVED broadcast and expect to lose the UID range for the restricted user. 8587 final Intent removedIntent = new Intent(ACTION_USER_REMOVED); 8588 removedIntent.putExtra(Intent.EXTRA_USER, UserHandle.of(RESTRICTED_USER)); 8589 removedIntent.putExtra(Intent.EXTRA_USER_HANDLE, RESTRICTED_USER); 8590 processBroadcast(removedIntent); 8591 assertNull(mCm.getActiveNetworkForUid(uid)); 8592 assertNotNull(mCm.getActiveNetworkForUid(restrictedUid)); 8593 8594 mVpnManagerService.setAlwaysOnVpnPackage(PRIMARY_USER, null, false /* lockdown */, 8595 allowList); 8596 waitForIdle(); 8597 } 8598 8599 @Test 8600 public void testIsActiveNetworkMeteredOverWifi() throws Exception { 8601 // Returns true by default when no network is available. 8602 assertTrue(mCm.isActiveNetworkMetered()); 8603 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 8604 mWiFiNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED); 8605 mWiFiNetworkAgent.connect(true); 8606 waitForIdle(); 8607 8608 assertFalse(mCm.isActiveNetworkMetered()); 8609 } 8610 8611 @Test 8612 public void testIsActiveNetworkMeteredOverCell() throws Exception { 8613 // Returns true by default when no network is available. 8614 assertTrue(mCm.isActiveNetworkMetered()); 8615 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 8616 mCellNetworkAgent.removeCapability(NET_CAPABILITY_NOT_METERED); 8617 mCellNetworkAgent.connect(true); 8618 waitForIdle(); 8619 8620 assertTrue(mCm.isActiveNetworkMetered()); 8621 } 8622 8623 @Test 8624 public void testIsActiveNetworkMeteredOverVpnTrackingPlatformDefault() throws Exception { 8625 // Returns true by default when no network is available. 8626 assertTrue(mCm.isActiveNetworkMetered()); 8627 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 8628 mCellNetworkAgent.removeCapability(NET_CAPABILITY_NOT_METERED); 8629 mCellNetworkAgent.connect(true); 8630 waitForIdle(); 8631 assertTrue(mCm.isActiveNetworkMetered()); 8632 8633 // Connect VPN network. By default it is using current default network (Cell). 8634 mMockVpn.establishForMyUid(); 8635 assertUidRangesUpdatedForMyUid(true); 8636 8637 // Ensure VPN is now the active network. 8638 assertEquals(mMockVpn.getNetwork(), mCm.getActiveNetwork()); 8639 8640 // Expect VPN to be metered. 8641 assertTrue(mCm.isActiveNetworkMetered()); 8642 8643 // Connect WiFi. 8644 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 8645 mWiFiNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED); 8646 mWiFiNetworkAgent.connect(true); 8647 waitForIdle(); 8648 // VPN should still be the active network. 8649 assertEquals(mMockVpn.getNetwork(), mCm.getActiveNetwork()); 8650 8651 // Expect VPN to be unmetered as it should now be using WiFi (new default). 8652 assertFalse(mCm.isActiveNetworkMetered()); 8653 8654 // Disconnecting Cell should not affect VPN's meteredness. 8655 mCellNetworkAgent.disconnect(); 8656 waitForIdle(); 8657 8658 assertFalse(mCm.isActiveNetworkMetered()); 8659 8660 // Disconnect WiFi; Now there is no platform default network. 8661 mWiFiNetworkAgent.disconnect(); 8662 waitForIdle(); 8663 8664 // VPN without any underlying networks is treated as metered. 8665 assertTrue(mCm.isActiveNetworkMetered()); 8666 8667 mMockVpn.disconnect(); 8668 } 8669 8670 @Test 8671 public void testIsActiveNetworkMeteredOverVpnSpecifyingUnderlyingNetworks() throws Exception { 8672 // Returns true by default when no network is available. 8673 assertTrue(mCm.isActiveNetworkMetered()); 8674 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 8675 mCellNetworkAgent.removeCapability(NET_CAPABILITY_NOT_METERED); 8676 mCellNetworkAgent.connect(true); 8677 waitForIdle(); 8678 assertTrue(mCm.isActiveNetworkMetered()); 8679 8680 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 8681 mWiFiNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED); 8682 mWiFiNetworkAgent.connect(true); 8683 waitForIdle(); 8684 assertFalse(mCm.isActiveNetworkMetered()); 8685 8686 // Connect VPN network. 8687 mMockVpn.establishForMyUid(); 8688 assertUidRangesUpdatedForMyUid(true); 8689 8690 // Ensure VPN is now the active network. 8691 assertEquals(mMockVpn.getNetwork(), mCm.getActiveNetwork()); 8692 // VPN is using Cell 8693 mMockVpn.setUnderlyingNetworks( 8694 new Network[] { mCellNetworkAgent.getNetwork() }); 8695 waitForIdle(); 8696 8697 // Expect VPN to be metered. 8698 assertTrue(mCm.isActiveNetworkMetered()); 8699 8700 // VPN is now using WiFi 8701 mMockVpn.setUnderlyingNetworks( 8702 new Network[] { mWiFiNetworkAgent.getNetwork() }); 8703 waitForIdle(); 8704 8705 // Expect VPN to be unmetered 8706 assertFalse(mCm.isActiveNetworkMetered()); 8707 8708 // VPN is using Cell | WiFi. 8709 mMockVpn.setUnderlyingNetworks( 8710 new Network[] { mCellNetworkAgent.getNetwork(), mWiFiNetworkAgent.getNetwork() }); 8711 waitForIdle(); 8712 8713 // Expect VPN to be metered. 8714 assertTrue(mCm.isActiveNetworkMetered()); 8715 8716 // VPN is using WiFi | Cell. 8717 mMockVpn.setUnderlyingNetworks( 8718 new Network[] { mWiFiNetworkAgent.getNetwork(), mCellNetworkAgent.getNetwork() }); 8719 waitForIdle(); 8720 8721 // Order should not matter and VPN should still be metered. 8722 assertTrue(mCm.isActiveNetworkMetered()); 8723 8724 // VPN is not using any underlying networks. 8725 mMockVpn.setUnderlyingNetworks(new Network[0]); 8726 waitForIdle(); 8727 8728 // VPN without underlying networks is treated as metered. 8729 assertTrue(mCm.isActiveNetworkMetered()); 8730 8731 mMockVpn.disconnect(); 8732 } 8733 8734 @Test 8735 public void testIsActiveNetworkMeteredOverAlwaysMeteredVpn() throws Exception { 8736 // Returns true by default when no network is available. 8737 assertTrue(mCm.isActiveNetworkMetered()); 8738 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 8739 mWiFiNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED); 8740 mWiFiNetworkAgent.connect(true); 8741 waitForIdle(); 8742 assertFalse(mCm.isActiveNetworkMetered()); 8743 8744 // Connect VPN network. 8745 mMockVpn.registerAgent(true /* isAlwaysMetered */, uidRangesForUids(Process.myUid()), 8746 new LinkProperties()); 8747 mMockVpn.connect(true); 8748 waitForIdle(); 8749 assertEquals(mMockVpn.getNetwork(), mCm.getActiveNetwork()); 8750 8751 // VPN is tracking current platform default (WiFi). 8752 mMockVpn.setUnderlyingNetworks(null); 8753 waitForIdle(); 8754 8755 // Despite VPN using WiFi (which is unmetered), VPN itself is marked as always metered. 8756 assertTrue(mCm.isActiveNetworkMetered()); 8757 8758 8759 // VPN explicitly declares WiFi as its underlying network. 8760 mMockVpn.setUnderlyingNetworks( 8761 new Network[] { mWiFiNetworkAgent.getNetwork() }); 8762 waitForIdle(); 8763 8764 // Doesn't really matter whether VPN declares its underlying networks explicitly. 8765 assertTrue(mCm.isActiveNetworkMetered()); 8766 8767 // With WiFi lost, VPN is basically without any underlying networks. And in that case it is 8768 // anyways suppose to be metered. 8769 mWiFiNetworkAgent.disconnect(); 8770 waitForIdle(); 8771 8772 assertTrue(mCm.isActiveNetworkMetered()); 8773 8774 mMockVpn.disconnect(); 8775 } 8776 8777 private class DetailedBlockedStatusCallback extends TestNetworkCallback { 8778 public void expectAvailableThenValidatedCallbacks(HasNetwork n, int blockedStatus) { 8779 super.expectAvailableThenValidatedCallbacks(n.getNetwork(), blockedStatus, TIMEOUT_MS); 8780 } 8781 public void expectBlockedStatusCallback(HasNetwork n, int blockedStatus) { 8782 // This doesn't work: 8783 // super.expectBlockedStatusCallback(blockedStatus, n.getNetwork()); 8784 super.expectBlockedStatusCallback(blockedStatus, n.getNetwork(), TIMEOUT_MS); 8785 } 8786 public void onBlockedStatusChanged(Network network, int blockedReasons) { 8787 getHistory().add(new CallbackEntry.BlockedStatusInt(network, blockedReasons)); 8788 } 8789 } 8790 8791 @Test 8792 public void testNetworkBlockedStatus() throws Exception { 8793 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback(); 8794 final NetworkRequest cellRequest = new NetworkRequest.Builder() 8795 .addTransportType(TRANSPORT_CELLULAR) 8796 .build(); 8797 mCm.registerNetworkCallback(cellRequest, cellNetworkCallback); 8798 final DetailedBlockedStatusCallback detailedCallback = new DetailedBlockedStatusCallback(); 8799 mCm.registerNetworkCallback(cellRequest, detailedCallback); 8800 8801 mockUidNetworkingBlocked(); 8802 8803 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 8804 mCellNetworkAgent.connect(true); 8805 cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 8806 detailedCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent, 8807 BLOCKED_REASON_NONE); 8808 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 8809 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 8810 assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 8811 assertExtraInfoFromCmPresent(mCellNetworkAgent); 8812 8813 setBlockedReasonChanged(BLOCKED_REASON_BATTERY_SAVER); 8814 cellNetworkCallback.expectBlockedStatusCallback(true, mCellNetworkAgent); 8815 detailedCallback.expectBlockedStatusCallback(mCellNetworkAgent, 8816 BLOCKED_REASON_BATTERY_SAVER); 8817 assertNull(mCm.getActiveNetwork()); 8818 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); 8819 assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); 8820 assertExtraInfoFromCmBlocked(mCellNetworkAgent); 8821 8822 // If blocked state does not change but blocked reason does, the boolean callback is called. 8823 // TODO: investigate de-duplicating. 8824 setBlockedReasonChanged(BLOCKED_METERED_REASON_USER_RESTRICTED); 8825 cellNetworkCallback.expectBlockedStatusCallback(true, mCellNetworkAgent); 8826 detailedCallback.expectBlockedStatusCallback(mCellNetworkAgent, 8827 BLOCKED_METERED_REASON_USER_RESTRICTED); 8828 8829 setBlockedReasonChanged(BLOCKED_REASON_NONE); 8830 cellNetworkCallback.expectBlockedStatusCallback(false, mCellNetworkAgent); 8831 detailedCallback.expectBlockedStatusCallback(mCellNetworkAgent, BLOCKED_REASON_NONE); 8832 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 8833 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 8834 assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 8835 assertExtraInfoFromCmPresent(mCellNetworkAgent); 8836 8837 setBlockedReasonChanged(BLOCKED_METERED_REASON_DATA_SAVER); 8838 cellNetworkCallback.expectBlockedStatusCallback(true, mCellNetworkAgent); 8839 detailedCallback.expectBlockedStatusCallback(mCellNetworkAgent, 8840 BLOCKED_METERED_REASON_DATA_SAVER); 8841 assertNull(mCm.getActiveNetwork()); 8842 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); 8843 assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); 8844 assertExtraInfoFromCmBlocked(mCellNetworkAgent); 8845 8846 // Restrict the network based on UID rule and NOT_METERED capability change. 8847 mCellNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED); 8848 cellNetworkCallback.expectCapabilitiesWith(NET_CAPABILITY_NOT_METERED, mCellNetworkAgent); 8849 cellNetworkCallback.expectBlockedStatusCallback(false, mCellNetworkAgent); 8850 detailedCallback.expectCapabilitiesWith(NET_CAPABILITY_NOT_METERED, mCellNetworkAgent); 8851 detailedCallback.expectBlockedStatusCallback(mCellNetworkAgent, BLOCKED_REASON_NONE); 8852 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 8853 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 8854 assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 8855 assertExtraInfoFromCmPresent(mCellNetworkAgent); 8856 8857 mCellNetworkAgent.removeCapability(NET_CAPABILITY_NOT_METERED); 8858 cellNetworkCallback.expectCapabilitiesWithout(NET_CAPABILITY_NOT_METERED, 8859 mCellNetworkAgent); 8860 cellNetworkCallback.expectBlockedStatusCallback(true, mCellNetworkAgent); 8861 detailedCallback.expectCapabilitiesWithout(NET_CAPABILITY_NOT_METERED, 8862 mCellNetworkAgent); 8863 detailedCallback.expectBlockedStatusCallback(mCellNetworkAgent, 8864 BLOCKED_METERED_REASON_DATA_SAVER); 8865 assertNull(mCm.getActiveNetwork()); 8866 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); 8867 assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); 8868 assertExtraInfoFromCmBlocked(mCellNetworkAgent); 8869 8870 setBlockedReasonChanged(BLOCKED_REASON_NONE); 8871 cellNetworkCallback.expectBlockedStatusCallback(false, mCellNetworkAgent); 8872 detailedCallback.expectBlockedStatusCallback(mCellNetworkAgent, BLOCKED_REASON_NONE); 8873 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 8874 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 8875 assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 8876 assertExtraInfoFromCmPresent(mCellNetworkAgent); 8877 8878 setBlockedReasonChanged(BLOCKED_REASON_NONE); 8879 cellNetworkCallback.assertNoCallback(); 8880 detailedCallback.assertNoCallback(); 8881 8882 // Restrict background data. Networking is not blocked because the network is unmetered. 8883 setBlockedReasonChanged(BLOCKED_METERED_REASON_DATA_SAVER); 8884 cellNetworkCallback.expectBlockedStatusCallback(true, mCellNetworkAgent); 8885 detailedCallback.expectBlockedStatusCallback(mCellNetworkAgent, 8886 BLOCKED_METERED_REASON_DATA_SAVER); 8887 assertNull(mCm.getActiveNetwork()); 8888 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); 8889 assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); 8890 assertExtraInfoFromCmBlocked(mCellNetworkAgent); 8891 setBlockedReasonChanged(BLOCKED_METERED_REASON_DATA_SAVER); 8892 cellNetworkCallback.assertNoCallback(); 8893 8894 setBlockedReasonChanged(BLOCKED_REASON_NONE); 8895 cellNetworkCallback.expectBlockedStatusCallback(false, mCellNetworkAgent); 8896 detailedCallback.expectBlockedStatusCallback(mCellNetworkAgent, BLOCKED_REASON_NONE); 8897 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 8898 assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 8899 assertExtraInfoFromCmPresent(mCellNetworkAgent); 8900 8901 setBlockedReasonChanged(BLOCKED_REASON_NONE); 8902 cellNetworkCallback.assertNoCallback(); 8903 detailedCallback.assertNoCallback(); 8904 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 8905 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 8906 assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 8907 assertExtraInfoFromCmPresent(mCellNetworkAgent); 8908 8909 mCm.unregisterNetworkCallback(cellNetworkCallback); 8910 } 8911 8912 @Test 8913 public void testNetworkBlockedStatusBeforeAndAfterConnect() throws Exception { 8914 final TestNetworkCallback defaultCallback = new TestNetworkCallback(); 8915 mCm.registerDefaultNetworkCallback(defaultCallback); 8916 mockUidNetworkingBlocked(); 8917 8918 // No Networkcallbacks invoked before any network is active. 8919 setBlockedReasonChanged(BLOCKED_REASON_BATTERY_SAVER); 8920 setBlockedReasonChanged(BLOCKED_REASON_NONE); 8921 setBlockedReasonChanged(BLOCKED_METERED_REASON_DATA_SAVER); 8922 defaultCallback.assertNoCallback(); 8923 8924 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 8925 mCellNetworkAgent.connect(true); 8926 defaultCallback.expectAvailableCallbacksUnvalidatedAndBlocked(mCellNetworkAgent); 8927 defaultCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mCellNetworkAgent); 8928 8929 // Allow to use the network after switching to NOT_METERED network. 8930 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 8931 mWiFiNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED); 8932 mWiFiNetworkAgent.connect(true); 8933 defaultCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent); 8934 8935 // Switch to METERED network. Restrict the use of the network. 8936 mWiFiNetworkAgent.disconnect(); 8937 defaultCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 8938 defaultCallback.expectAvailableCallbacksValidatedAndBlocked(mCellNetworkAgent); 8939 8940 // Network becomes NOT_METERED. 8941 mCellNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED); 8942 defaultCallback.expectCapabilitiesWith(NET_CAPABILITY_NOT_METERED, mCellNetworkAgent); 8943 defaultCallback.expectBlockedStatusCallback(false, mCellNetworkAgent); 8944 8945 // Verify there's no Networkcallbacks invoked after data saver on/off. 8946 setBlockedReasonChanged(BLOCKED_METERED_REASON_DATA_SAVER); 8947 setBlockedReasonChanged(BLOCKED_REASON_NONE); 8948 defaultCallback.assertNoCallback(); 8949 8950 mCellNetworkAgent.disconnect(); 8951 defaultCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 8952 defaultCallback.assertNoCallback(); 8953 8954 mCm.unregisterNetworkCallback(defaultCallback); 8955 } 8956 8957 private void expectNetworkRejectNonSecureVpn(InOrder inOrder, boolean add, 8958 UidRangeParcel... expected) throws Exception { 8959 inOrder.verify(mMockNetd).networkRejectNonSecureVpn(eq(add), aryEq(expected)); 8960 } 8961 8962 private void checkNetworkInfo(NetworkInfo ni, int type, DetailedState state) { 8963 assertNotNull(ni); 8964 assertEquals(type, ni.getType()); 8965 assertEquals(ConnectivityManager.getNetworkTypeName(type), state, ni.getDetailedState()); 8966 if (state == DetailedState.CONNECTED || state == DetailedState.SUSPENDED) { 8967 assertNotNull(ni.getExtraInfo()); 8968 } else { 8969 // Technically speaking, a network that's in CONNECTING state will generally have a 8970 // non-null extraInfo. This doesn't actually happen in this test because it never calls 8971 // a legacy API while a network is connecting. When a network is in CONNECTING state 8972 // because of legacy lockdown VPN, its extraInfo is always null. 8973 assertNull(ni.getExtraInfo()); 8974 } 8975 } 8976 8977 private void assertActiveNetworkInfo(int type, DetailedState state) { 8978 checkNetworkInfo(mCm.getActiveNetworkInfo(), type, state); 8979 } 8980 private void assertNetworkInfo(int type, DetailedState state) { 8981 checkNetworkInfo(mCm.getNetworkInfo(type), type, state); 8982 } 8983 8984 private void assertExtraInfoFromCm(TestNetworkAgentWrapper network, boolean present) { 8985 final NetworkInfo niForNetwork = mCm.getNetworkInfo(network.getNetwork()); 8986 final NetworkInfo niForType = mCm.getNetworkInfo(network.getLegacyType()); 8987 if (present) { 8988 assertEquals(network.getExtraInfo(), niForNetwork.getExtraInfo()); 8989 assertEquals(network.getExtraInfo(), niForType.getExtraInfo()); 8990 } else { 8991 assertNull(niForNetwork.getExtraInfo()); 8992 assertNull(niForType.getExtraInfo()); 8993 } 8994 } 8995 8996 private void assertExtraInfoFromCmBlocked(TestNetworkAgentWrapper network) { 8997 assertExtraInfoFromCm(network, false); 8998 } 8999 9000 private void assertExtraInfoFromCmPresent(TestNetworkAgentWrapper network) { 9001 assertExtraInfoFromCm(network, true); 9002 } 9003 9004 // Checks that each of the |agents| receive a blocked status change callback with the specified 9005 // |blocked| value, in any order. This is needed because when an event affects multiple 9006 // networks, ConnectivityService does not guarantee the order in which callbacks are fired. 9007 private void assertBlockedCallbackInAnyOrder(TestNetworkCallback callback, boolean blocked, 9008 TestNetworkAgentWrapper... agents) { 9009 final List<Network> expectedNetworks = asList(agents).stream() 9010 .map((agent) -> agent.getNetwork()) 9011 .collect(Collectors.toList()); 9012 9013 // Expect exactly one blocked callback for each agent. 9014 for (int i = 0; i < agents.length; i++) { 9015 CallbackEntry e = callback.expectCallbackThat(TIMEOUT_MS, (c) -> 9016 c instanceof CallbackEntry.BlockedStatus 9017 && ((CallbackEntry.BlockedStatus) c).getBlocked() == blocked); 9018 Network network = e.getNetwork(); 9019 assertTrue("Received unexpected blocked callback for network " + network, 9020 expectedNetworks.remove(network)); 9021 } 9022 } 9023 9024 @Test 9025 public void testNetworkBlockedStatusAlwaysOnVpn() throws Exception { 9026 mServiceContext.setPermission( 9027 Manifest.permission.CONTROL_ALWAYS_ON_VPN, PERMISSION_GRANTED); 9028 mServiceContext.setPermission( 9029 Manifest.permission.CONTROL_VPN, PERMISSION_GRANTED); 9030 mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_GRANTED); 9031 9032 final TestNetworkCallback callback = new TestNetworkCallback(); 9033 final NetworkRequest request = new NetworkRequest.Builder() 9034 .removeCapability(NET_CAPABILITY_NOT_VPN) 9035 .build(); 9036 mCm.registerNetworkCallback(request, callback); 9037 9038 final TestNetworkCallback defaultCallback = new TestNetworkCallback(); 9039 mCm.registerDefaultNetworkCallback(defaultCallback); 9040 9041 final TestNetworkCallback vpnUidCallback = new TestNetworkCallback(); 9042 final NetworkRequest vpnUidRequest = new NetworkRequest.Builder().build(); 9043 registerNetworkCallbackAsUid(vpnUidRequest, vpnUidCallback, VPN_UID); 9044 9045 final TestNetworkCallback vpnUidDefaultCallback = new TestNetworkCallback(); 9046 registerDefaultNetworkCallbackAsUid(vpnUidDefaultCallback, VPN_UID); 9047 9048 final TestNetworkCallback vpnDefaultCallbackAsUid = new TestNetworkCallback(); 9049 mCm.registerDefaultNetworkCallbackForUid(VPN_UID, vpnDefaultCallbackAsUid, 9050 new Handler(ConnectivityThread.getInstanceLooper())); 9051 9052 final int uid = Process.myUid(); 9053 final int userId = UserHandle.getUserId(uid); 9054 final ArrayList<String> allowList = new ArrayList<>(); 9055 mVpnManagerService.setAlwaysOnVpnPackage(userId, ALWAYS_ON_PACKAGE, true /* lockdown */, 9056 allowList); 9057 waitForIdle(); 9058 9059 final Set<Integer> excludedUids = new ArraySet<Integer>(); 9060 excludedUids.add(VPN_UID); 9061 if (SdkLevel.isAtLeastT()) { 9062 // On T onwards, the corresponding SDK sandbox UID should also be excluded 9063 excludedUids.add(toSdkSandboxUid(VPN_UID)); 9064 } 9065 final UidRangeParcel[] uidRangeParcels = uidRangeParcelsExcludingUids( 9066 excludedUids.toArray(new Integer[0])); 9067 InOrder inOrder = inOrder(mMockNetd); 9068 expectNetworkRejectNonSecureVpn(inOrder, true, uidRangeParcels); 9069 9070 // Connect a network when lockdown is active, expect to see it blocked. 9071 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 9072 mWiFiNetworkAgent.connect(false /* validated */); 9073 callback.expectAvailableCallbacksUnvalidatedAndBlocked(mWiFiNetworkAgent); 9074 defaultCallback.expectAvailableCallbacksUnvalidatedAndBlocked(mWiFiNetworkAgent); 9075 vpnUidCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 9076 vpnUidDefaultCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 9077 vpnDefaultCallbackAsUid.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 9078 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetworkForUid(VPN_UID)); 9079 assertNull(mCm.getActiveNetwork()); 9080 assertActiveNetworkInfo(TYPE_WIFI, DetailedState.BLOCKED); 9081 // Mobile is BLOCKED even though it's not actually connected. 9082 assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); 9083 assertNetworkInfo(TYPE_WIFI, DetailedState.BLOCKED); 9084 9085 // Disable lockdown, expect to see the network unblocked. 9086 mVpnManagerService.setAlwaysOnVpnPackage(userId, null, false /* lockdown */, allowList); 9087 callback.expectBlockedStatusCallback(false, mWiFiNetworkAgent); 9088 defaultCallback.expectBlockedStatusCallback(false, mWiFiNetworkAgent); 9089 vpnUidCallback.assertNoCallback(); 9090 vpnUidDefaultCallback.assertNoCallback(); 9091 vpnDefaultCallbackAsUid.assertNoCallback(); 9092 expectNetworkRejectNonSecureVpn(inOrder, false, uidRangeParcels); 9093 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetworkForUid(VPN_UID)); 9094 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 9095 assertActiveNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 9096 assertNetworkInfo(TYPE_MOBILE, DetailedState.DISCONNECTED); 9097 assertNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 9098 9099 // Add our UID to the allowlist and re-enable lockdown, expect network is not blocked. 9100 allowList.add(TEST_PACKAGE_NAME); 9101 mVpnManagerService.setAlwaysOnVpnPackage(userId, ALWAYS_ON_PACKAGE, true /* lockdown */, 9102 allowList); 9103 callback.assertNoCallback(); 9104 defaultCallback.assertNoCallback(); 9105 vpnUidCallback.assertNoCallback(); 9106 vpnUidDefaultCallback.assertNoCallback(); 9107 vpnDefaultCallbackAsUid.assertNoCallback(); 9108 9109 excludedUids.add(uid); 9110 if (SdkLevel.isAtLeastT()) { 9111 // On T onwards, the corresponding SDK sandbox UID should also be excluded 9112 excludedUids.add(toSdkSandboxUid(uid)); 9113 } 9114 final UidRangeParcel[] uidRangeParcelsAlsoExcludingUs = uidRangeParcelsExcludingUids( 9115 excludedUids.toArray(new Integer[0])); 9116 expectNetworkRejectNonSecureVpn(inOrder, true, uidRangeParcelsAlsoExcludingUs); 9117 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetworkForUid(VPN_UID)); 9118 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 9119 assertActiveNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 9120 assertNetworkInfo(TYPE_MOBILE, DetailedState.DISCONNECTED); 9121 assertNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 9122 9123 // Connect a new network, expect it to be unblocked. 9124 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 9125 mCellNetworkAgent.connect(false /* validated */); 9126 callback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent); 9127 defaultCallback.assertNoCallback(); 9128 vpnUidCallback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent); 9129 vpnUidDefaultCallback.assertNoCallback(); 9130 vpnDefaultCallbackAsUid.assertNoCallback(); 9131 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetworkForUid(VPN_UID)); 9132 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 9133 assertActiveNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 9134 // Cellular is DISCONNECTED because it's not the default and there are no requests for it. 9135 assertNetworkInfo(TYPE_MOBILE, DetailedState.DISCONNECTED); 9136 assertNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 9137 9138 // Disable lockdown, remove our UID from the allowlist, and re-enable lockdown. 9139 // Everything should now be blocked. 9140 mVpnManagerService.setAlwaysOnVpnPackage(userId, null, false /* lockdown */, allowList); 9141 waitForIdle(); 9142 expectNetworkRejectNonSecureVpn(inOrder, false, uidRangeParcelsAlsoExcludingUs); 9143 allowList.clear(); 9144 mVpnManagerService.setAlwaysOnVpnPackage(userId, ALWAYS_ON_PACKAGE, true /* lockdown */, 9145 allowList); 9146 waitForIdle(); 9147 expectNetworkRejectNonSecureVpn(inOrder, true, uidRangeParcels); 9148 defaultCallback.expectBlockedStatusCallback(true, mWiFiNetworkAgent); 9149 assertBlockedCallbackInAnyOrder(callback, true, mWiFiNetworkAgent, mCellNetworkAgent); 9150 vpnUidCallback.assertNoCallback(); 9151 vpnUidDefaultCallback.assertNoCallback(); 9152 vpnDefaultCallbackAsUid.assertNoCallback(); 9153 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetworkForUid(VPN_UID)); 9154 assertNull(mCm.getActiveNetwork()); 9155 assertActiveNetworkInfo(TYPE_WIFI, DetailedState.BLOCKED); 9156 assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); 9157 assertNetworkInfo(TYPE_WIFI, DetailedState.BLOCKED); 9158 9159 // Disable lockdown. Everything is unblocked. 9160 mVpnManagerService.setAlwaysOnVpnPackage(userId, null, false /* lockdown */, allowList); 9161 defaultCallback.expectBlockedStatusCallback(false, mWiFiNetworkAgent); 9162 assertBlockedCallbackInAnyOrder(callback, false, mWiFiNetworkAgent, mCellNetworkAgent); 9163 vpnUidCallback.assertNoCallback(); 9164 vpnUidDefaultCallback.assertNoCallback(); 9165 vpnDefaultCallbackAsUid.assertNoCallback(); 9166 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetworkForUid(VPN_UID)); 9167 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 9168 assertActiveNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 9169 assertNetworkInfo(TYPE_MOBILE, DetailedState.DISCONNECTED); 9170 assertNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 9171 9172 // Enable and disable an always-on VPN package without lockdown. Expect no changes. 9173 reset(mMockNetd); 9174 mVpnManagerService.setAlwaysOnVpnPackage(userId, ALWAYS_ON_PACKAGE, false /* lockdown */, 9175 allowList); 9176 inOrder.verify(mMockNetd, never()).networkRejectNonSecureVpn(anyBoolean(), any()); 9177 callback.assertNoCallback(); 9178 defaultCallback.assertNoCallback(); 9179 vpnUidCallback.assertNoCallback(); 9180 vpnUidDefaultCallback.assertNoCallback(); 9181 vpnDefaultCallbackAsUid.assertNoCallback(); 9182 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetworkForUid(VPN_UID)); 9183 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 9184 assertActiveNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 9185 assertNetworkInfo(TYPE_MOBILE, DetailedState.DISCONNECTED); 9186 assertNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 9187 9188 mVpnManagerService.setAlwaysOnVpnPackage(userId, null, false /* lockdown */, allowList); 9189 inOrder.verify(mMockNetd, never()).networkRejectNonSecureVpn(anyBoolean(), any()); 9190 callback.assertNoCallback(); 9191 defaultCallback.assertNoCallback(); 9192 vpnUidCallback.assertNoCallback(); 9193 vpnUidDefaultCallback.assertNoCallback(); 9194 vpnDefaultCallbackAsUid.assertNoCallback(); 9195 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetworkForUid(VPN_UID)); 9196 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 9197 assertActiveNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 9198 assertNetworkInfo(TYPE_MOBILE, DetailedState.DISCONNECTED); 9199 assertNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 9200 9201 // Enable lockdown and connect a VPN. The VPN is not blocked. 9202 mVpnManagerService.setAlwaysOnVpnPackage(userId, ALWAYS_ON_PACKAGE, true /* lockdown */, 9203 allowList); 9204 defaultCallback.expectBlockedStatusCallback(true, mWiFiNetworkAgent); 9205 assertBlockedCallbackInAnyOrder(callback, true, mWiFiNetworkAgent, mCellNetworkAgent); 9206 vpnUidCallback.assertNoCallback(); 9207 vpnUidDefaultCallback.assertNoCallback(); 9208 vpnDefaultCallbackAsUid.assertNoCallback(); 9209 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetworkForUid(VPN_UID)); 9210 assertNull(mCm.getActiveNetwork()); 9211 assertActiveNetworkInfo(TYPE_WIFI, DetailedState.BLOCKED); 9212 assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); 9213 assertNetworkInfo(TYPE_WIFI, DetailedState.BLOCKED); 9214 9215 mMockVpn.establishForMyUid(); 9216 assertUidRangesUpdatedForMyUid(true); 9217 defaultCallback.expectAvailableThenValidatedCallbacks(mMockVpn); 9218 vpnUidCallback.assertNoCallback(); // vpnUidCallback has NOT_VPN capability. 9219 vpnUidDefaultCallback.assertNoCallback(); // VPN does not apply to VPN_UID 9220 vpnDefaultCallbackAsUid.assertNoCallback(); 9221 assertEquals(mMockVpn.getNetwork(), mCm.getActiveNetwork()); 9222 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetworkForUid(VPN_UID)); 9223 assertActiveNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 9224 assertNetworkInfo(TYPE_MOBILE, DetailedState.DISCONNECTED); 9225 assertNetworkInfo(TYPE_VPN, DetailedState.CONNECTED); 9226 assertNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 9227 9228 mMockVpn.disconnect(); 9229 defaultCallback.expectCallback(CallbackEntry.LOST, mMockVpn); 9230 defaultCallback.expectAvailableCallbacksUnvalidatedAndBlocked(mWiFiNetworkAgent); 9231 vpnUidCallback.assertNoCallback(); 9232 vpnUidDefaultCallback.assertNoCallback(); 9233 vpnDefaultCallbackAsUid.assertNoCallback(); 9234 assertNull(mCm.getActiveNetwork()); 9235 9236 mCm.unregisterNetworkCallback(callback); 9237 mCm.unregisterNetworkCallback(defaultCallback); 9238 mCm.unregisterNetworkCallback(vpnUidCallback); 9239 mCm.unregisterNetworkCallback(vpnUidDefaultCallback); 9240 mCm.unregisterNetworkCallback(vpnDefaultCallbackAsUid); 9241 } 9242 9243 @Test 9244 public void testVpnExcludesOwnUid() throws Exception { 9245 // required for registerDefaultNetworkCallbackForUid. 9246 mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_GRANTED); 9247 9248 // Connect Wi-Fi. 9249 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 9250 mWiFiNetworkAgent.connect(true /* validated */); 9251 9252 // Connect a VPN that excludes its UID from its UID ranges. 9253 final LinkProperties lp = new LinkProperties(); 9254 lp.setInterfaceName(VPN_IFNAME); 9255 final int myUid = Process.myUid(); 9256 final Set<UidRange> ranges = new ArraySet<>(); 9257 ranges.add(new UidRange(0, myUid - 1)); 9258 ranges.add(new UidRange(myUid + 1, UserHandle.PER_USER_RANGE - 1)); 9259 mMockVpn.setUnderlyingNetworks(new Network[]{mWiFiNetworkAgent.getNetwork()}); 9260 mMockVpn.establish(lp, myUid, ranges); 9261 9262 // Wait for validation before registering callbacks. 9263 waitForIdle(); 9264 9265 final int otherUid = myUid + 1; 9266 final Handler h = new Handler(ConnectivityThread.getInstanceLooper()); 9267 final TestNetworkCallback otherUidCb = new TestNetworkCallback(); 9268 final TestNetworkCallback defaultCb = new TestNetworkCallback(); 9269 final TestNetworkCallback perUidCb = new TestNetworkCallback(); 9270 registerDefaultNetworkCallbackAsUid(otherUidCb, otherUid); 9271 mCm.registerDefaultNetworkCallback(defaultCb, h); 9272 doAsUid(Process.SYSTEM_UID, 9273 () -> mCm.registerDefaultNetworkCallbackForUid(myUid, perUidCb, h)); 9274 9275 otherUidCb.expectAvailableCallbacksValidated(mMockVpn); 9276 // BUG (b/195265065): the default network for the VPN app is actually Wi-Fi, not the VPN. 9277 defaultCb.expectAvailableCallbacksValidated(mMockVpn); 9278 perUidCb.expectAvailableCallbacksValidated(mMockVpn); 9279 // getActiveNetwork is not affected by this bug. 9280 assertEquals(mMockVpn.getNetwork(), mCm.getActiveNetworkForUid(myUid + 1)); 9281 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 9282 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetworkForUid(myUid)); 9283 9284 doAsUid(otherUid, () -> mCm.unregisterNetworkCallback(otherUidCb)); 9285 mCm.unregisterNetworkCallback(defaultCb); 9286 doAsUid(Process.SYSTEM_UID, () -> mCm.unregisterNetworkCallback(perUidCb)); 9287 } 9288 9289 private void setupLegacyLockdownVpn() { 9290 final String profileName = "testVpnProfile"; 9291 final byte[] profileTag = profileName.getBytes(StandardCharsets.UTF_8); 9292 doReturn(profileTag).when(mVpnProfileStore).get(Credentials.LOCKDOWN_VPN); 9293 9294 final VpnProfile profile = new VpnProfile(profileName); 9295 profile.name = "My VPN"; 9296 profile.server = "192.0.2.1"; 9297 profile.dnsServers = "8.8.8.8"; 9298 profile.type = VpnProfile.TYPE_IPSEC_XAUTH_PSK; 9299 final byte[] encodedProfile = profile.encode(); 9300 doReturn(encodedProfile).when(mVpnProfileStore).get(Credentials.VPN + profileName); 9301 } 9302 9303 private void establishLegacyLockdownVpn(Network underlying) throws Exception { 9304 // The legacy lockdown VPN only supports userId 0, and must have an underlying network. 9305 assertNotNull(underlying); 9306 mMockVpn.setVpnType(VpnManager.TYPE_VPN_LEGACY); 9307 // The legacy lockdown VPN only supports userId 0. 9308 final Set<UidRange> ranges = Collections.singleton(PRIMARY_UIDRANGE); 9309 mMockVpn.registerAgent(ranges); 9310 mMockVpn.setUnderlyingNetworks(new Network[]{underlying}); 9311 mMockVpn.connect(true); 9312 } 9313 9314 @Test 9315 public void testLegacyLockdownVpn() throws Exception { 9316 mServiceContext.setPermission( 9317 Manifest.permission.CONTROL_VPN, PERMISSION_GRANTED); 9318 // For LockdownVpnTracker to call registerSystemDefaultNetworkCallback. 9319 mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_GRANTED); 9320 9321 final NetworkRequest request = new NetworkRequest.Builder().clearCapabilities().build(); 9322 final TestNetworkCallback callback = new TestNetworkCallback(); 9323 mCm.registerNetworkCallback(request, callback); 9324 9325 final TestNetworkCallback defaultCallback = new TestNetworkCallback(); 9326 mCm.registerDefaultNetworkCallback(defaultCallback); 9327 9328 final TestNetworkCallback systemDefaultCallback = new TestNetworkCallback(); 9329 mCm.registerSystemDefaultNetworkCallback(systemDefaultCallback, 9330 new Handler(ConnectivityThread.getInstanceLooper())); 9331 9332 // Pretend lockdown VPN was configured. 9333 setupLegacyLockdownVpn(); 9334 9335 // LockdownVpnTracker disables the Vpn teardown code and enables lockdown. 9336 // Check the VPN's state before it does so. 9337 assertTrue(mMockVpn.getEnableTeardown()); 9338 assertFalse(mMockVpn.getLockdown()); 9339 9340 // Send a USER_UNLOCKED broadcast so CS starts LockdownVpnTracker. 9341 final int userId = UserHandle.getUserId(Process.myUid()); 9342 final Intent addedIntent = new Intent(ACTION_USER_UNLOCKED); 9343 addedIntent.putExtra(Intent.EXTRA_USER, UserHandle.of(userId)); 9344 addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 9345 processBroadcast(addedIntent); 9346 9347 // Lockdown VPN disables teardown and enables lockdown. 9348 assertFalse(mMockVpn.getEnableTeardown()); 9349 assertTrue(mMockVpn.getLockdown()); 9350 9351 // Bring up a network. 9352 // Expect nothing to happen because the network does not have an IPv4 default route: legacy 9353 // VPN only supports IPv4. 9354 final LinkProperties cellLp = new LinkProperties(); 9355 cellLp.setInterfaceName("rmnet0"); 9356 cellLp.addLinkAddress(new LinkAddress("2001:db8::1/64")); 9357 cellLp.addRoute(new RouteInfo(new IpPrefix("::/0"), null, "rmnet0")); 9358 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp); 9359 mCellNetworkAgent.connect(false /* validated */); 9360 callback.expectAvailableCallbacksUnvalidatedAndBlocked(mCellNetworkAgent); 9361 defaultCallback.expectAvailableCallbacksUnvalidatedAndBlocked(mCellNetworkAgent); 9362 systemDefaultCallback.expectAvailableCallbacksUnvalidatedAndBlocked(mCellNetworkAgent); 9363 waitForIdle(); 9364 assertNull(mMockVpn.getAgent()); 9365 9366 // Add an IPv4 address. Ideally the VPN should start, but it doesn't because nothing calls 9367 // LockdownVpnTracker#handleStateChangedLocked. This is a bug. 9368 // TODO: consider fixing this. 9369 cellLp.addLinkAddress(new LinkAddress("192.0.2.2/25")); 9370 cellLp.addRoute(new RouteInfo(new IpPrefix("0.0.0.0/0"), null, "rmnet0")); 9371 mCellNetworkAgent.sendLinkProperties(cellLp); 9372 callback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent); 9373 defaultCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent); 9374 systemDefaultCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, 9375 mCellNetworkAgent); 9376 waitForIdle(); 9377 assertNull(mMockVpn.getAgent()); 9378 9379 // Disconnect, then try again with a network that supports IPv4 at connection time. 9380 // Expect lockdown VPN to come up. 9381 ExpectedBroadcast b1 = expectConnectivityAction(TYPE_MOBILE, DetailedState.DISCONNECTED); 9382 mCellNetworkAgent.disconnect(); 9383 callback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 9384 defaultCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 9385 systemDefaultCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 9386 b1.expectBroadcast(); 9387 9388 // When lockdown VPN is active, the NetworkInfo state in CONNECTIVITY_ACTION is overwritten 9389 // with the state of the VPN network. So expect a CONNECTING broadcast. 9390 b1 = expectConnectivityAction(TYPE_MOBILE, DetailedState.CONNECTING); 9391 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp); 9392 mCellNetworkAgent.connect(false /* validated */); 9393 callback.expectAvailableCallbacksUnvalidatedAndBlocked(mCellNetworkAgent); 9394 defaultCallback.expectAvailableCallbacksUnvalidatedAndBlocked(mCellNetworkAgent); 9395 systemDefaultCallback.expectAvailableCallbacksUnvalidatedAndBlocked(mCellNetworkAgent); 9396 b1.expectBroadcast(); 9397 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); 9398 assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); 9399 assertNetworkInfo(TYPE_WIFI, DetailedState.BLOCKED); 9400 assertNetworkInfo(TYPE_VPN, DetailedState.BLOCKED); 9401 assertExtraInfoFromCmBlocked(mCellNetworkAgent); 9402 9403 // TODO: it would be nice if we could simply rely on the production code here, and have 9404 // LockdownVpnTracker start the VPN, have the VPN code register its NetworkAgent with 9405 // ConnectivityService, etc. That would require duplicating a fair bit of code from the 9406 // Vpn tests around how to mock out LegacyVpnRunner. But even if we did that, this does not 9407 // work for at least two reasons: 9408 // 1. In this test, calling registerNetworkAgent does not actually result in an agent being 9409 // registered. This is because nothing calls onNetworkMonitorCreated, which is what 9410 // actually ends up causing handleRegisterNetworkAgent to be called. Code in this test 9411 // that wants to register an agent must use TestNetworkAgentWrapper. 9412 // 2. Even if we exposed Vpn#agentConnect to the test, and made MockVpn#agentConnect call 9413 // the TestNetworkAgentWrapper code, this would deadlock because the 9414 // TestNetworkAgentWrapper code cannot be called on the handler thread since it calls 9415 // waitForIdle(). 9416 mMockVpn.expectStartLegacyVpnRunner(); 9417 b1 = expectConnectivityAction(TYPE_VPN, DetailedState.CONNECTED); 9418 ExpectedBroadcast b2 = expectConnectivityAction(TYPE_MOBILE, DetailedState.CONNECTED); 9419 establishLegacyLockdownVpn(mCellNetworkAgent.getNetwork()); 9420 callback.expectAvailableThenValidatedCallbacks(mMockVpn); 9421 defaultCallback.expectAvailableThenValidatedCallbacks(mMockVpn); 9422 systemDefaultCallback.assertNoCallback(); 9423 NetworkCapabilities vpnNc = mCm.getNetworkCapabilities(mMockVpn.getNetwork()); 9424 b1.expectBroadcast(); 9425 b2.expectBroadcast(); 9426 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 9427 assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 9428 assertNetworkInfo(TYPE_WIFI, DetailedState.DISCONNECTED); 9429 assertNetworkInfo(TYPE_VPN, DetailedState.CONNECTED); 9430 assertExtraInfoFromCmPresent(mCellNetworkAgent); 9431 assertTrue(vpnNc.hasTransport(TRANSPORT_VPN)); 9432 assertTrue(vpnNc.hasTransport(TRANSPORT_CELLULAR)); 9433 assertFalse(vpnNc.hasTransport(TRANSPORT_WIFI)); 9434 assertFalse(vpnNc.hasCapability(NET_CAPABILITY_NOT_METERED)); 9435 assertVpnTransportInfo(vpnNc, VpnManager.TYPE_VPN_LEGACY); 9436 9437 // Switch default network from cell to wifi. Expect VPN to disconnect and reconnect. 9438 final LinkProperties wifiLp = new LinkProperties(); 9439 wifiLp.setInterfaceName("wlan0"); 9440 wifiLp.addLinkAddress(new LinkAddress("192.0.2.163/25")); 9441 wifiLp.addRoute(new RouteInfo(new IpPrefix("0.0.0.0/0"), null, "wlan0")); 9442 final NetworkCapabilities wifiNc = new NetworkCapabilities(); 9443 wifiNc.addTransportType(TRANSPORT_WIFI); 9444 wifiNc.addCapability(NET_CAPABILITY_NOT_METERED); 9445 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, wifiLp, wifiNc); 9446 9447 b1 = expectConnectivityAction(TYPE_MOBILE, DetailedState.DISCONNECTED); 9448 // Wifi is CONNECTING because the VPN isn't up yet. 9449 b2 = expectConnectivityAction(TYPE_WIFI, DetailedState.CONNECTING); 9450 ExpectedBroadcast b3 = expectConnectivityAction(TYPE_VPN, DetailedState.DISCONNECTED); 9451 mWiFiNetworkAgent.connect(false /* validated */); 9452 b1.expectBroadcast(); 9453 b2.expectBroadcast(); 9454 b3.expectBroadcast(); 9455 mMockVpn.expectStopVpnRunnerPrivileged(); 9456 mMockVpn.expectStartLegacyVpnRunner(); 9457 9458 // TODO: why is wifi not blocked? Is it because when this callback is sent, the VPN is still 9459 // connected, so the network is not considered blocked by the lockdown UID ranges? But the 9460 // fact that a VPN is connected should only result in the VPN itself being unblocked, not 9461 // any other network. Bug in isUidBlockedByVpn? 9462 callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 9463 callback.expectCallback(CallbackEntry.LOST, mMockVpn); 9464 defaultCallback.expectCallback(CallbackEntry.LOST, mMockVpn); 9465 defaultCallback.expectAvailableCallbacksUnvalidatedAndBlocked(mWiFiNetworkAgent); 9466 systemDefaultCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 9467 9468 // While the VPN is reconnecting on the new network, everything is blocked. 9469 assertActiveNetworkInfo(TYPE_WIFI, DetailedState.BLOCKED); 9470 assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); 9471 assertNetworkInfo(TYPE_WIFI, DetailedState.BLOCKED); 9472 assertNetworkInfo(TYPE_VPN, DetailedState.BLOCKED); 9473 assertExtraInfoFromCmBlocked(mWiFiNetworkAgent); 9474 9475 // The VPN comes up again on wifi. 9476 b1 = expectConnectivityAction(TYPE_VPN, DetailedState.CONNECTED); 9477 b2 = expectConnectivityAction(TYPE_WIFI, DetailedState.CONNECTED); 9478 establishLegacyLockdownVpn(mWiFiNetworkAgent.getNetwork()); 9479 callback.expectAvailableThenValidatedCallbacks(mMockVpn); 9480 defaultCallback.expectAvailableThenValidatedCallbacks(mMockVpn); 9481 systemDefaultCallback.assertNoCallback(); 9482 b1.expectBroadcast(); 9483 b2.expectBroadcast(); 9484 assertActiveNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 9485 assertNetworkInfo(TYPE_MOBILE, DetailedState.DISCONNECTED); 9486 assertNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 9487 assertNetworkInfo(TYPE_VPN, DetailedState.CONNECTED); 9488 assertExtraInfoFromCmPresent(mWiFiNetworkAgent); 9489 vpnNc = mCm.getNetworkCapabilities(mMockVpn.getNetwork()); 9490 assertTrue(vpnNc.hasTransport(TRANSPORT_VPN)); 9491 assertTrue(vpnNc.hasTransport(TRANSPORT_WIFI)); 9492 assertFalse(vpnNc.hasTransport(TRANSPORT_CELLULAR)); 9493 assertTrue(vpnNc.hasCapability(NET_CAPABILITY_NOT_METERED)); 9494 9495 // Disconnect cell. Nothing much happens since it's not the default network. 9496 mCellNetworkAgent.disconnect(); 9497 callback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 9498 defaultCallback.assertNoCallback(); 9499 systemDefaultCallback.assertNoCallback(); 9500 9501 assertActiveNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 9502 assertNetworkInfo(TYPE_MOBILE, DetailedState.DISCONNECTED); 9503 assertNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 9504 assertNetworkInfo(TYPE_VPN, DetailedState.CONNECTED); 9505 assertExtraInfoFromCmPresent(mWiFiNetworkAgent); 9506 9507 b1 = expectConnectivityAction(TYPE_WIFI, DetailedState.DISCONNECTED); 9508 b2 = expectConnectivityAction(TYPE_VPN, DetailedState.DISCONNECTED); 9509 mWiFiNetworkAgent.disconnect(); 9510 callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 9511 systemDefaultCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 9512 b1.expectBroadcast(); 9513 callback.expectCapabilitiesThat(mMockVpn, nc -> !nc.hasTransport(TRANSPORT_WIFI)); 9514 mMockVpn.expectStopVpnRunnerPrivileged(); 9515 callback.expectCallback(CallbackEntry.LOST, mMockVpn); 9516 b2.expectBroadcast(); 9517 } 9518 9519 @Test 9520 public void testLockdownSetFirewallUidRule() throws Exception { 9521 // For ConnectivityService#setAlwaysOnVpnPackage. 9522 mServiceContext.setPermission( 9523 Manifest.permission.CONTROL_ALWAYS_ON_VPN, PERMISSION_GRANTED); 9524 // Needed to call Vpn#setAlwaysOnPackage. 9525 mServiceContext.setPermission(Manifest.permission.CONTROL_VPN, PERMISSION_GRANTED); 9526 // Needed to call Vpn#isAlwaysOnPackageSupported. 9527 mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_GRANTED); 9528 9529 // Enable Lockdown 9530 final ArrayList<String> allowList = new ArrayList<>(); 9531 mVpnManagerService.setAlwaysOnVpnPackage(PRIMARY_USER, ALWAYS_ON_PACKAGE, 9532 true /* lockdown */, allowList); 9533 waitForIdle(); 9534 9535 // Lockdown rule is set to apps uids 9536 verify(mBpfNetMaps).setUidRule( 9537 eq(FIREWALL_CHAIN_LOCKDOWN_VPN), eq(APP1_UID), eq(FIREWALL_RULE_DENY)); 9538 verify(mBpfNetMaps).setUidRule( 9539 eq(FIREWALL_CHAIN_LOCKDOWN_VPN), eq(APP2_UID), eq(FIREWALL_RULE_DENY)); 9540 9541 reset(mBpfNetMaps); 9542 9543 // Disable lockdown 9544 mVpnManagerService.setAlwaysOnVpnPackage(PRIMARY_USER, null, false /* lockdown */, 9545 allowList); 9546 waitForIdle(); 9547 9548 // Lockdown rule is removed from apps uids 9549 verify(mBpfNetMaps).setUidRule( 9550 eq(FIREWALL_CHAIN_LOCKDOWN_VPN), eq(APP1_UID), eq(FIREWALL_RULE_ALLOW)); 9551 verify(mBpfNetMaps).setUidRule( 9552 eq(FIREWALL_CHAIN_LOCKDOWN_VPN), eq(APP2_UID), eq(FIREWALL_RULE_ALLOW)); 9553 9554 // Interface rules are not changed by Lockdown mode enable/disable 9555 verify(mBpfNetMaps, never()).addUidInterfaceRules(any(), any()); 9556 verify(mBpfNetMaps, never()).removeUidInterfaceRules(any()); 9557 } 9558 9559 private void doTestSetUidFirewallRule(final int chain, final int defaultRule) { 9560 final int uid = 1001; 9561 mCm.setUidFirewallRule(chain, uid, FIREWALL_RULE_ALLOW); 9562 verify(mBpfNetMaps).setUidRule(chain, uid, FIREWALL_RULE_ALLOW); 9563 reset(mBpfNetMaps); 9564 9565 mCm.setUidFirewallRule(chain, uid, FIREWALL_RULE_DENY); 9566 verify(mBpfNetMaps).setUidRule(chain, uid, FIREWALL_RULE_DENY); 9567 reset(mBpfNetMaps); 9568 9569 mCm.setUidFirewallRule(chain, uid, FIREWALL_RULE_DEFAULT); 9570 verify(mBpfNetMaps).setUidRule(chain, uid, defaultRule); 9571 reset(mBpfNetMaps); 9572 } 9573 9574 @Test @IgnoreUpTo(SC_V2) 9575 public void testSetUidFirewallRule() throws Exception { 9576 doTestSetUidFirewallRule(FIREWALL_CHAIN_DOZABLE, FIREWALL_RULE_DENY); 9577 doTestSetUidFirewallRule(FIREWALL_CHAIN_STANDBY, FIREWALL_RULE_ALLOW); 9578 doTestSetUidFirewallRule(FIREWALL_CHAIN_POWERSAVE, FIREWALL_RULE_DENY); 9579 doTestSetUidFirewallRule(FIREWALL_CHAIN_RESTRICTED, FIREWALL_RULE_DENY); 9580 doTestSetUidFirewallRule(FIREWALL_CHAIN_LOW_POWER_STANDBY, FIREWALL_RULE_DENY); 9581 doTestSetUidFirewallRule(FIREWALL_CHAIN_OEM_DENY_1, FIREWALL_RULE_ALLOW); 9582 doTestSetUidFirewallRule(FIREWALL_CHAIN_OEM_DENY_2, FIREWALL_RULE_ALLOW); 9583 doTestSetUidFirewallRule(FIREWALL_CHAIN_OEM_DENY_3, FIREWALL_RULE_ALLOW); 9584 } 9585 9586 @Test @IgnoreUpTo(SC_V2) 9587 public void testSetFirewallChainEnabled() throws Exception { 9588 final List<Integer> firewallChains = Arrays.asList( 9589 FIREWALL_CHAIN_DOZABLE, 9590 FIREWALL_CHAIN_STANDBY, 9591 FIREWALL_CHAIN_POWERSAVE, 9592 FIREWALL_CHAIN_RESTRICTED, 9593 FIREWALL_CHAIN_LOW_POWER_STANDBY, 9594 FIREWALL_CHAIN_OEM_DENY_1, 9595 FIREWALL_CHAIN_OEM_DENY_2, 9596 FIREWALL_CHAIN_OEM_DENY_3); 9597 for (final int chain: firewallChains) { 9598 mCm.setFirewallChainEnabled(chain, true /* enabled */); 9599 verify(mBpfNetMaps).setChildChain(chain, true /* enable */); 9600 reset(mBpfNetMaps); 9601 9602 mCm.setFirewallChainEnabled(chain, false /* enabled */); 9603 verify(mBpfNetMaps).setChildChain(chain, false /* enable */); 9604 reset(mBpfNetMaps); 9605 } 9606 } 9607 9608 private void doTestReplaceFirewallChain(final int chain, final String chainName, 9609 final boolean allowList) { 9610 final int[] uids = new int[] {1001, 1002}; 9611 mCm.replaceFirewallChain(chain, uids); 9612 verify(mBpfNetMaps).replaceUidChain(chainName, allowList, uids); 9613 reset(mBpfNetMaps); 9614 } 9615 9616 @Test @IgnoreUpTo(SC_V2) 9617 public void testReplaceFirewallChain() { 9618 doTestReplaceFirewallChain(FIREWALL_CHAIN_DOZABLE, "fw_dozable", true); 9619 doTestReplaceFirewallChain(FIREWALL_CHAIN_STANDBY, "fw_standby", false); 9620 doTestReplaceFirewallChain(FIREWALL_CHAIN_POWERSAVE, "fw_powersave", true); 9621 doTestReplaceFirewallChain(FIREWALL_CHAIN_RESTRICTED, "fw_restricted", true); 9622 doTestReplaceFirewallChain(FIREWALL_CHAIN_LOW_POWER_STANDBY, "fw_low_power_standby", true); 9623 doTestReplaceFirewallChain(FIREWALL_CHAIN_OEM_DENY_1, "fw_oem_deny_1", false); 9624 doTestReplaceFirewallChain(FIREWALL_CHAIN_OEM_DENY_2, "fw_oem_deny_2", false); 9625 doTestReplaceFirewallChain(FIREWALL_CHAIN_OEM_DENY_3, "fw_oem_deny_3", false); 9626 } 9627 9628 @Test @IgnoreUpTo(SC_V2) 9629 public void testInvalidFirewallChain() throws Exception { 9630 final int uid = 1001; 9631 final Class<IllegalArgumentException> expected = IllegalArgumentException.class; 9632 assertThrows(expected, 9633 () -> mCm.setUidFirewallRule(-1 /* chain */, uid, FIREWALL_RULE_ALLOW)); 9634 assertThrows(expected, 9635 () -> mCm.setUidFirewallRule(100 /* chain */, uid, FIREWALL_RULE_ALLOW)); 9636 assertThrows(expected, () -> mCm.replaceFirewallChain(-1 /* chain */, new int[]{uid})); 9637 assertThrows(expected, () -> mCm.replaceFirewallChain(100 /* chain */, new int[]{uid})); 9638 } 9639 9640 @Test @IgnoreUpTo(SC_V2) 9641 public void testInvalidFirewallRule() throws Exception { 9642 final Class<IllegalArgumentException> expected = IllegalArgumentException.class; 9643 assertThrows(expected, 9644 () -> mCm.setUidFirewallRule(FIREWALL_CHAIN_DOZABLE, 9645 1001 /* uid */, -1 /* rule */)); 9646 assertThrows(expected, 9647 () -> mCm.setUidFirewallRule(FIREWALL_CHAIN_DOZABLE, 9648 1001 /* uid */, 100 /* rule */)); 9649 } 9650 9651 /** 9652 * Test mutable and requestable network capabilities such as 9653 * {@link NetworkCapabilities#NET_CAPABILITY_TRUSTED} and 9654 * {@link NetworkCapabilities#NET_CAPABILITY_NOT_VCN_MANAGED}. Verify that the 9655 * {@code ConnectivityService} re-assign the networks accordingly. 9656 */ 9657 @Test 9658 public final void testLoseMutableAndRequestableCaps() throws Exception { 9659 final int[] testCaps = new int [] { 9660 NET_CAPABILITY_TRUSTED, 9661 NET_CAPABILITY_NOT_VCN_MANAGED 9662 }; 9663 for (final int testCap : testCaps) { 9664 // Create requests with and without the testing capability. 9665 final TestNetworkCallback callbackWithCap = new TestNetworkCallback(); 9666 final TestNetworkCallback callbackWithoutCap = new TestNetworkCallback(); 9667 mCm.requestNetwork(new NetworkRequest.Builder().addCapability(testCap).build(), 9668 callbackWithCap); 9669 mCm.requestNetwork(new NetworkRequest.Builder().removeCapability(testCap).build(), 9670 callbackWithoutCap); 9671 9672 // Setup networks with testing capability and verify the default network changes. 9673 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 9674 mCellNetworkAgent.addCapability(testCap); 9675 mCellNetworkAgent.connect(true); 9676 callbackWithCap.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 9677 callbackWithoutCap.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 9678 verify(mMockNetd).networkSetDefault(eq(mCellNetworkAgent.getNetwork().netId)); 9679 reset(mMockNetd); 9680 9681 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 9682 mWiFiNetworkAgent.addCapability(testCap); 9683 mWiFiNetworkAgent.connect(true); 9684 callbackWithCap.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent); 9685 callbackWithoutCap.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent); 9686 verify(mMockNetd).networkSetDefault(eq(mWiFiNetworkAgent.getNetwork().netId)); 9687 reset(mMockNetd); 9688 9689 // Remove the testing capability on wifi, verify the callback and default network 9690 // changes back to cellular. 9691 mWiFiNetworkAgent.removeCapability(testCap); 9692 callbackWithCap.expectAvailableCallbacksValidated(mCellNetworkAgent); 9693 callbackWithoutCap.expectCapabilitiesWithout(testCap, mWiFiNetworkAgent); 9694 verify(mMockNetd).networkSetDefault(eq(mCellNetworkAgent.getNetwork().netId)); 9695 reset(mMockNetd); 9696 9697 mCellNetworkAgent.removeCapability(testCap); 9698 callbackWithCap.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 9699 callbackWithoutCap.assertNoCallback(); 9700 verify(mMockNetd).networkClearDefault(); 9701 9702 mCm.unregisterNetworkCallback(callbackWithCap); 9703 mCm.unregisterNetworkCallback(callbackWithoutCap); 9704 } 9705 } 9706 9707 @Test 9708 public final void testBatteryStatsNetworkType() throws Exception { 9709 final LinkProperties cellLp = new LinkProperties(); 9710 cellLp.setInterfaceName("cell0"); 9711 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp); 9712 mCellNetworkAgent.connect(true); 9713 waitForIdle(); 9714 final ArrayTrackRecord<ReportedInterfaces>.ReadHead readHead = 9715 mDeps.mReportedInterfaceHistory.newReadHead(); 9716 assertNotNull(readHead.poll(TIMEOUT_MS, ri -> ri.contentEquals(mServiceContext, 9717 cellLp.getInterfaceName(), 9718 new int[] { TRANSPORT_CELLULAR }))); 9719 9720 final LinkProperties wifiLp = new LinkProperties(); 9721 wifiLp.setInterfaceName("wifi0"); 9722 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, wifiLp); 9723 mWiFiNetworkAgent.connect(true); 9724 waitForIdle(); 9725 assertNotNull(readHead.poll(TIMEOUT_MS, ri -> ri.contentEquals(mServiceContext, 9726 wifiLp.getInterfaceName(), 9727 new int[] { TRANSPORT_WIFI }))); 9728 9729 mCellNetworkAgent.disconnect(); 9730 mWiFiNetworkAgent.disconnect(); 9731 9732 cellLp.setInterfaceName("wifi0"); 9733 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp); 9734 mCellNetworkAgent.connect(true); 9735 waitForIdle(); 9736 assertNotNull(readHead.poll(TIMEOUT_MS, ri -> ri.contentEquals(mServiceContext, 9737 cellLp.getInterfaceName(), 9738 new int[] { TRANSPORT_CELLULAR }))); 9739 mCellNetworkAgent.disconnect(); 9740 } 9741 9742 /** 9743 * Make simulated InterfaceConfigParcel for Nat464Xlat to query clat lower layer info. 9744 */ 9745 private InterfaceConfigurationParcel getClatInterfaceConfigParcel(LinkAddress la) { 9746 final InterfaceConfigurationParcel cfg = new InterfaceConfigurationParcel(); 9747 cfg.hwAddr = "11:22:33:44:55:66"; 9748 cfg.ipv4Addr = la.getAddress().getHostAddress(); 9749 cfg.prefixLength = la.getPrefixLength(); 9750 return cfg; 9751 } 9752 9753 /** 9754 * Make expected stack link properties, copied from Nat464Xlat. 9755 */ 9756 private LinkProperties makeClatLinkProperties(LinkAddress la) { 9757 LinkAddress clatAddress = la; 9758 LinkProperties stacked = new LinkProperties(); 9759 stacked.setInterfaceName(CLAT_MOBILE_IFNAME); 9760 RouteInfo ipv4Default = new RouteInfo( 9761 new LinkAddress(Inet4Address.ANY, 0), 9762 clatAddress.getAddress(), CLAT_MOBILE_IFNAME); 9763 stacked.addRoute(ipv4Default); 9764 stacked.addLinkAddress(clatAddress); 9765 return stacked; 9766 } 9767 9768 private Nat64PrefixEventParcel makeNat64PrefixEvent(final int netId, final int prefixOperation, 9769 final String prefixAddress, final int prefixLength) { 9770 final Nat64PrefixEventParcel event = new Nat64PrefixEventParcel(); 9771 event.netId = netId; 9772 event.prefixOperation = prefixOperation; 9773 event.prefixAddress = prefixAddress; 9774 event.prefixLength = prefixLength; 9775 return event; 9776 } 9777 9778 private <T> T verifyWithOrder(@Nullable InOrder inOrder, @NonNull T t) { 9779 if (inOrder != null) { 9780 return inOrder.verify(t); 9781 } else { 9782 return verify(t); 9783 } 9784 } 9785 9786 private <T> T verifyNeverWithOrder(@Nullable InOrder inOrder, @NonNull T t) { 9787 if (inOrder != null) { 9788 return inOrder.verify(t, never()); 9789 } else { 9790 return verify(t, never()); 9791 } 9792 } 9793 9794 private void verifyClatdStart(@Nullable InOrder inOrder, @NonNull String iface, int netId, 9795 @NonNull String nat64Prefix) throws Exception { 9796 if (SdkLevel.isAtLeastT()) { 9797 verifyWithOrder(inOrder, mClatCoordinator) 9798 .clatStart(eq(iface), eq(netId), eq(new IpPrefix(nat64Prefix))); 9799 } else { 9800 verifyWithOrder(inOrder, mMockNetd).clatdStart(eq(iface), eq(nat64Prefix)); 9801 } 9802 } 9803 9804 private void verifyNeverClatdStart(@Nullable InOrder inOrder, @NonNull String iface) 9805 throws Exception { 9806 if (SdkLevel.isAtLeastT()) { 9807 verifyNeverWithOrder(inOrder, mClatCoordinator).clatStart(eq(iface), anyInt(), any()); 9808 } else { 9809 verifyNeverWithOrder(inOrder, mMockNetd).clatdStart(eq(iface), anyString()); 9810 } 9811 } 9812 9813 private void verifyClatdStop(@Nullable InOrder inOrder, @NonNull String iface) 9814 throws Exception { 9815 if (SdkLevel.isAtLeastT()) { 9816 verifyWithOrder(inOrder, mClatCoordinator).clatStop(); 9817 } else { 9818 verifyWithOrder(inOrder, mMockNetd).clatdStop(eq(iface)); 9819 } 9820 } 9821 9822 private void verifyNeverClatdStop(@Nullable InOrder inOrder, @NonNull String iface) 9823 throws Exception { 9824 if (SdkLevel.isAtLeastT()) { 9825 verifyNeverWithOrder(inOrder, mClatCoordinator).clatStop(); 9826 } else { 9827 verifyNeverWithOrder(inOrder, mMockNetd).clatdStop(eq(iface)); 9828 } 9829 } 9830 9831 @Test 9832 public void testStackedLinkProperties() throws Exception { 9833 final LinkAddress myIpv4 = new LinkAddress("1.2.3.4/24"); 9834 final LinkAddress myIpv6 = new LinkAddress("2001:db8:1::1/64"); 9835 final String kNat64PrefixString = "2001:db8:64:64:64:64::"; 9836 final IpPrefix kNat64Prefix = new IpPrefix(InetAddress.getByName(kNat64PrefixString), 96); 9837 final String kOtherNat64PrefixString = "64:ff9b::"; 9838 final IpPrefix kOtherNat64Prefix = new IpPrefix( 9839 InetAddress.getByName(kOtherNat64PrefixString), 96); 9840 final RouteInfo ipv6Default = 9841 new RouteInfo((IpPrefix) null, myIpv6.getAddress(), MOBILE_IFNAME); 9842 final RouteInfo ipv6Subnet = new RouteInfo(myIpv6, null, MOBILE_IFNAME); 9843 final RouteInfo ipv4Subnet = new RouteInfo(myIpv4, null, MOBILE_IFNAME); 9844 final RouteInfo stackedDefault = 9845 new RouteInfo((IpPrefix) null, myIpv4.getAddress(), CLAT_MOBILE_IFNAME); 9846 9847 final NetworkRequest networkRequest = new NetworkRequest.Builder() 9848 .addTransportType(TRANSPORT_CELLULAR) 9849 .addCapability(NET_CAPABILITY_INTERNET) 9850 .build(); 9851 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 9852 mCm.registerNetworkCallback(networkRequest, networkCallback); 9853 9854 // Prepare ipv6 only link properties. 9855 final LinkProperties cellLp = new LinkProperties(); 9856 cellLp.setInterfaceName(MOBILE_IFNAME); 9857 cellLp.addLinkAddress(myIpv6); 9858 cellLp.addRoute(ipv6Default); 9859 cellLp.addRoute(ipv6Subnet); 9860 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp); 9861 reset(mMockDnsResolver); 9862 reset(mMockNetd); 9863 reset(mClatCoordinator); 9864 9865 // Connect with ipv6 link properties. Expect prefix discovery to be started. 9866 mCellNetworkAgent.connect(true); 9867 int cellNetId = mCellNetworkAgent.getNetwork().netId; 9868 waitForIdle(); 9869 9870 verify(mMockNetd, times(1)).networkCreate(nativeNetworkConfigPhysical(cellNetId, 9871 INetd.PERMISSION_NONE)); 9872 assertRoutesAdded(cellNetId, ipv6Subnet, ipv6Default); 9873 verify(mMockDnsResolver, times(1)).createNetworkCache(eq(cellNetId)); 9874 verify(mMockNetd, times(1)).networkAddInterface(cellNetId, MOBILE_IFNAME); 9875 final ArrayTrackRecord<ReportedInterfaces>.ReadHead readHead = 9876 mDeps.mReportedInterfaceHistory.newReadHead(); 9877 assertNotNull(readHead.poll(TIMEOUT_MS, ri -> ri.contentEquals(mServiceContext, 9878 cellLp.getInterfaceName(), 9879 new int[] { TRANSPORT_CELLULAR }))); 9880 9881 networkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 9882 verify(mMockDnsResolver, times(1)).startPrefix64Discovery(cellNetId); 9883 9884 // Switching default network updates TCP buffer sizes. 9885 verifyTcpBufferSizeChange(ConnectivityService.DEFAULT_TCP_BUFFER_SIZES); 9886 // Add an IPv4 address. Expect prefix discovery to be stopped. Netd doesn't tell us that 9887 // the NAT64 prefix was removed because one was never discovered. 9888 cellLp.addLinkAddress(myIpv4); 9889 mCellNetworkAgent.sendLinkProperties(cellLp); 9890 networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent); 9891 assertRoutesAdded(cellNetId, ipv4Subnet); 9892 verify(mMockDnsResolver, times(1)).stopPrefix64Discovery(cellNetId); 9893 verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration(any()); 9894 9895 // Make sure BatteryStats was not told about any v4- interfaces, as none should have 9896 // come online yet. 9897 waitForIdle(); 9898 assertNull(readHead.poll(0 /* timeout */, ri -> mServiceContext.equals(ri.context) 9899 && ri.iface != null && ri.iface.startsWith("v4-"))); 9900 9901 verifyNoMoreInteractions(mMockNetd); 9902 verifyNoMoreInteractions(mClatCoordinator); 9903 verifyNoMoreInteractions(mMockDnsResolver); 9904 reset(mMockNetd); 9905 reset(mClatCoordinator); 9906 reset(mMockDnsResolver); 9907 doReturn(getClatInterfaceConfigParcel(myIpv4)).when(mMockNetd) 9908 .interfaceGetCfg(CLAT_MOBILE_IFNAME); 9909 9910 // Remove IPv4 address. Expect prefix discovery to be started again. 9911 cellLp.removeLinkAddress(myIpv4); 9912 mCellNetworkAgent.sendLinkProperties(cellLp); 9913 networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent); 9914 verify(mMockDnsResolver, times(1)).startPrefix64Discovery(cellNetId); 9915 assertRoutesRemoved(cellNetId, ipv4Subnet); 9916 9917 // When NAT64 prefix discovery succeeds, LinkProperties are updated and clatd is started. 9918 Nat464Xlat clat = getNat464Xlat(mCellNetworkAgent); 9919 assertNull(mCm.getLinkProperties(mCellNetworkAgent.getNetwork()).getNat64Prefix()); 9920 mService.mResolverUnsolEventCallback.onNat64PrefixEvent( 9921 makeNat64PrefixEvent(cellNetId, PREFIX_OPERATION_ADDED, kNat64PrefixString, 96)); 9922 LinkProperties lpBeforeClat = networkCallback.expectCallback( 9923 CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent).getLp(); 9924 assertEquals(0, lpBeforeClat.getStackedLinks().size()); 9925 assertEquals(kNat64Prefix, lpBeforeClat.getNat64Prefix()); 9926 verifyClatdStart(null /* inOrder */, MOBILE_IFNAME, cellNetId, kNat64Prefix.toString()); 9927 9928 // Clat iface comes up. Expect stacked link to be added. 9929 clat.interfaceLinkStateChanged(CLAT_MOBILE_IFNAME, true); 9930 networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent); 9931 List<LinkProperties> stackedLps = mCm.getLinkProperties(mCellNetworkAgent.getNetwork()) 9932 .getStackedLinks(); 9933 assertEquals(makeClatLinkProperties(myIpv4), stackedLps.get(0)); 9934 assertRoutesAdded(cellNetId, stackedDefault); 9935 verify(mMockNetd, times(1)).networkAddInterface(cellNetId, CLAT_MOBILE_IFNAME); 9936 // Change trivial linkproperties and see if stacked link is preserved. 9937 cellLp.addDnsServer(InetAddress.getByName("8.8.8.8")); 9938 mCellNetworkAgent.sendLinkProperties(cellLp); 9939 networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent); 9940 9941 List<LinkProperties> stackedLpsAfterChange = 9942 mCm.getLinkProperties(mCellNetworkAgent.getNetwork()).getStackedLinks(); 9943 assertNotEquals(stackedLpsAfterChange, Collections.EMPTY_LIST); 9944 assertEquals(makeClatLinkProperties(myIpv4), stackedLpsAfterChange.get(0)); 9945 9946 verify(mMockDnsResolver, times(1)).setResolverConfiguration( 9947 mResolverParamsParcelCaptor.capture()); 9948 ResolverParamsParcel resolvrParams = mResolverParamsParcelCaptor.getValue(); 9949 assertEquals(1, resolvrParams.servers.length); 9950 assertTrue(CollectionUtils.contains(resolvrParams.servers, "8.8.8.8")); 9951 9952 for (final LinkProperties stackedLp : stackedLpsAfterChange) { 9953 assertNotNull(readHead.poll(TIMEOUT_MS, ri -> ri.contentEquals(mServiceContext, 9954 stackedLp.getInterfaceName(), 9955 new int[] { TRANSPORT_CELLULAR }))); 9956 } 9957 reset(mMockNetd); 9958 reset(mClatCoordinator); 9959 doReturn(getClatInterfaceConfigParcel(myIpv4)).when(mMockNetd) 9960 .interfaceGetCfg(CLAT_MOBILE_IFNAME); 9961 // Change the NAT64 prefix without first removing it. 9962 // Expect clatd to be stopped and started with the new prefix. 9963 mService.mResolverUnsolEventCallback.onNat64PrefixEvent(makeNat64PrefixEvent( 9964 cellNetId, PREFIX_OPERATION_ADDED, kOtherNat64PrefixString, 96)); 9965 networkCallback.expectLinkPropertiesThat(mCellNetworkAgent, 9966 (lp) -> lp.getStackedLinks().size() == 0); 9967 verifyClatdStop(null /* inOrder */, MOBILE_IFNAME); 9968 assertRoutesRemoved(cellNetId, stackedDefault); 9969 verify(mMockNetd, times(1)).networkRemoveInterface(cellNetId, CLAT_MOBILE_IFNAME); 9970 9971 verifyClatdStart(null /* inOrder */, MOBILE_IFNAME, cellNetId, 9972 kOtherNat64Prefix.toString()); 9973 networkCallback.expectLinkPropertiesThat(mCellNetworkAgent, 9974 (lp) -> lp.getNat64Prefix().equals(kOtherNat64Prefix)); 9975 clat.interfaceLinkStateChanged(CLAT_MOBILE_IFNAME, true); 9976 networkCallback.expectLinkPropertiesThat(mCellNetworkAgent, 9977 (lp) -> lp.getStackedLinks().size() == 1); 9978 assertRoutesAdded(cellNetId, stackedDefault); 9979 verify(mMockNetd, times(1)).networkAddInterface(cellNetId, CLAT_MOBILE_IFNAME); 9980 reset(mMockNetd); 9981 reset(mClatCoordinator); 9982 9983 // Add ipv4 address, expect that clatd and prefix discovery are stopped and stacked 9984 // linkproperties are cleaned up. 9985 cellLp.addLinkAddress(myIpv4); 9986 cellLp.addRoute(ipv4Subnet); 9987 mCellNetworkAgent.sendLinkProperties(cellLp); 9988 networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent); 9989 assertRoutesAdded(cellNetId, ipv4Subnet); 9990 verifyClatdStop(null /* inOrder */, MOBILE_IFNAME); 9991 verify(mMockDnsResolver, times(1)).stopPrefix64Discovery(cellNetId); 9992 9993 // As soon as stop is called, the linkproperties lose the stacked interface. 9994 networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent); 9995 LinkProperties actualLpAfterIpv4 = mCm.getLinkProperties(mCellNetworkAgent.getNetwork()); 9996 LinkProperties expected = new LinkProperties(cellLp); 9997 expected.setNat64Prefix(kOtherNat64Prefix); 9998 assertEquals(expected, actualLpAfterIpv4); 9999 assertEquals(0, actualLpAfterIpv4.getStackedLinks().size()); 10000 assertRoutesRemoved(cellNetId, stackedDefault); 10001 10002 // The interface removed callback happens but has no effect after stop is called. 10003 clat.interfaceRemoved(CLAT_MOBILE_IFNAME); 10004 networkCallback.assertNoCallback(); 10005 verify(mMockNetd, times(1)).networkRemoveInterface(cellNetId, CLAT_MOBILE_IFNAME); 10006 verifyNoMoreInteractions(mMockNetd); 10007 verifyNoMoreInteractions(mClatCoordinator); 10008 verifyNoMoreInteractions(mMockDnsResolver); 10009 reset(mMockNetd); 10010 reset(mClatCoordinator); 10011 reset(mMockDnsResolver); 10012 doReturn(getClatInterfaceConfigParcel(myIpv4)).when(mMockNetd) 10013 .interfaceGetCfg(CLAT_MOBILE_IFNAME); 10014 10015 // Stopping prefix discovery causes netd to tell us that the NAT64 prefix is gone. 10016 mService.mResolverUnsolEventCallback.onNat64PrefixEvent(makeNat64PrefixEvent( 10017 cellNetId, PREFIX_OPERATION_REMOVED, kOtherNat64PrefixString, 96)); 10018 networkCallback.expectLinkPropertiesThat(mCellNetworkAgent, 10019 (lp) -> lp.getNat64Prefix() == null); 10020 10021 // Remove IPv4 address and expect prefix discovery and clatd to be started again. 10022 cellLp.removeLinkAddress(myIpv4); 10023 cellLp.removeRoute(new RouteInfo(myIpv4, null, MOBILE_IFNAME)); 10024 cellLp.removeDnsServer(InetAddress.getByName("8.8.8.8")); 10025 mCellNetworkAgent.sendLinkProperties(cellLp); 10026 networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent); 10027 assertRoutesRemoved(cellNetId, ipv4Subnet); // Directly-connected routes auto-added. 10028 verify(mMockDnsResolver, times(1)).startPrefix64Discovery(cellNetId); 10029 mService.mResolverUnsolEventCallback.onNat64PrefixEvent(makeNat64PrefixEvent( 10030 cellNetId, PREFIX_OPERATION_ADDED, kNat64PrefixString, 96)); 10031 networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent); 10032 verifyClatdStart(null /* inOrder */, MOBILE_IFNAME, cellNetId, kNat64Prefix.toString()); 10033 10034 // Clat iface comes up. Expect stacked link to be added. 10035 clat.interfaceLinkStateChanged(CLAT_MOBILE_IFNAME, true); 10036 networkCallback.expectLinkPropertiesThat(mCellNetworkAgent, 10037 (lp) -> lp.getStackedLinks().size() == 1 && lp.getNat64Prefix() != null); 10038 assertRoutesAdded(cellNetId, stackedDefault); 10039 verify(mMockNetd, times(1)).networkAddInterface(cellNetId, CLAT_MOBILE_IFNAME); 10040 10041 // NAT64 prefix is removed. Expect that clat is stopped. 10042 mService.mResolverUnsolEventCallback.onNat64PrefixEvent(makeNat64PrefixEvent( 10043 cellNetId, PREFIX_OPERATION_REMOVED, kNat64PrefixString, 96)); 10044 networkCallback.expectLinkPropertiesThat(mCellNetworkAgent, 10045 (lp) -> lp.getStackedLinks().size() == 0 && lp.getNat64Prefix() == null); 10046 assertRoutesRemoved(cellNetId, ipv4Subnet, stackedDefault); 10047 10048 // Stop has no effect because clat is already stopped. 10049 verifyClatdStop(null /* inOrder */, MOBILE_IFNAME); 10050 networkCallback.expectLinkPropertiesThat(mCellNetworkAgent, 10051 (lp) -> lp.getStackedLinks().size() == 0); 10052 verify(mMockNetd, times(1)).networkRemoveInterface(cellNetId, CLAT_MOBILE_IFNAME); 10053 verify(mMockNetd, times(1)).interfaceGetCfg(CLAT_MOBILE_IFNAME); 10054 // Clean up. 10055 mCellNetworkAgent.disconnect(); 10056 networkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 10057 networkCallback.assertNoCallback(); 10058 verify(mMockNetd, times(1)).idletimerRemoveInterface(eq(MOBILE_IFNAME), anyInt(), 10059 eq(Integer.toString(TRANSPORT_CELLULAR))); 10060 verify(mMockNetd).networkDestroy(cellNetId); 10061 verifyNoMoreInteractions(mMockNetd); 10062 verifyNoMoreInteractions(mClatCoordinator); 10063 reset(mMockNetd); 10064 reset(mClatCoordinator); 10065 10066 // Test disconnecting a network that is running 464xlat. 10067 10068 // Connect a network with a NAT64 prefix. 10069 doReturn(getClatInterfaceConfigParcel(myIpv4)).when(mMockNetd) 10070 .interfaceGetCfg(CLAT_MOBILE_IFNAME); 10071 cellLp.setNat64Prefix(kNat64Prefix); 10072 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp); 10073 mCellNetworkAgent.connect(false /* validated */); 10074 networkCallback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent); 10075 cellNetId = mCellNetworkAgent.getNetwork().netId; 10076 verify(mMockNetd, times(1)).networkCreate(nativeNetworkConfigPhysical(cellNetId, 10077 INetd.PERMISSION_NONE)); 10078 assertRoutesAdded(cellNetId, ipv6Subnet, ipv6Default); 10079 10080 // Clatd is started and clat iface comes up. Expect stacked link to be added. 10081 verifyClatdStart(null /* inOrder */, MOBILE_IFNAME, cellNetId, kNat64Prefix.toString()); 10082 clat = getNat464Xlat(mCellNetworkAgent); 10083 clat.interfaceLinkStateChanged(CLAT_MOBILE_IFNAME, true /* up */); 10084 networkCallback.expectLinkPropertiesThat(mCellNetworkAgent, 10085 (lp) -> lp.getStackedLinks().size() == 1 10086 && lp.getNat64Prefix().equals(kNat64Prefix)); 10087 verify(mMockNetd).networkAddInterface(cellNetId, CLAT_MOBILE_IFNAME); 10088 // assertRoutesAdded sees all calls since last mMockNetd reset, so expect IPv6 routes again. 10089 assertRoutesAdded(cellNetId, ipv6Subnet, ipv6Default, stackedDefault); 10090 reset(mMockNetd); 10091 reset(mClatCoordinator); 10092 10093 // Disconnect the network. clat is stopped and the network is destroyed. 10094 mCellNetworkAgent.disconnect(); 10095 networkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 10096 networkCallback.assertNoCallback(); 10097 verifyClatdStop(null /* inOrder */, MOBILE_IFNAME); 10098 verify(mMockNetd).idletimerRemoveInterface(eq(MOBILE_IFNAME), anyInt(), 10099 eq(Integer.toString(TRANSPORT_CELLULAR))); 10100 verify(mMockNetd).networkDestroy(cellNetId); 10101 verifyNoMoreInteractions(mMockNetd); 10102 verifyNoMoreInteractions(mClatCoordinator); 10103 10104 mCm.unregisterNetworkCallback(networkCallback); 10105 } 10106 10107 private void expectNat64PrefixChange(TestableNetworkCallback callback, 10108 TestNetworkAgentWrapper agent, IpPrefix prefix) { 10109 callback.expectLinkPropertiesThat(agent, x -> Objects.equals(x.getNat64Prefix(), prefix)); 10110 } 10111 10112 @Test 10113 public void testNat64PrefixMultipleSources() throws Exception { 10114 final String iface = "wlan0"; 10115 final String pref64FromRaStr = "64:ff9b::"; 10116 final String pref64FromDnsStr = "2001:db8:64::"; 10117 final IpPrefix pref64FromRa = new IpPrefix(InetAddress.getByName(pref64FromRaStr), 96); 10118 final IpPrefix pref64FromDns = new IpPrefix(InetAddress.getByName(pref64FromDnsStr), 96); 10119 final IpPrefix newPref64FromRa = new IpPrefix("2001:db8:64:64:64:64::/96"); 10120 10121 final NetworkRequest request = new NetworkRequest.Builder() 10122 .addCapability(NET_CAPABILITY_INTERNET) 10123 .build(); 10124 final TestNetworkCallback callback = new TestNetworkCallback(); 10125 mCm.registerNetworkCallback(request, callback); 10126 10127 final LinkProperties baseLp = new LinkProperties(); 10128 baseLp.setInterfaceName(iface); 10129 baseLp.addLinkAddress(new LinkAddress("2001:db8:1::1/64")); 10130 baseLp.addDnsServer(InetAddress.getByName("2001:4860:4860::6464")); 10131 10132 reset(mMockNetd, mMockDnsResolver); 10133 InOrder inOrder = inOrder(mMockNetd, mMockDnsResolver, mClatCoordinator); 10134 10135 // If a network already has a NAT64 prefix on connect, clatd is started immediately and 10136 // prefix discovery is never started. 10137 LinkProperties lp = new LinkProperties(baseLp); 10138 lp.setNat64Prefix(pref64FromRa); 10139 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, lp); 10140 mWiFiNetworkAgent.connect(false); 10141 final Network network = mWiFiNetworkAgent.getNetwork(); 10142 int netId = network.getNetId(); 10143 callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 10144 verifyClatdStart(inOrder, iface, netId, pref64FromRa.toString()); 10145 inOrder.verify(mMockDnsResolver).setPrefix64(netId, pref64FromRa.toString()); 10146 inOrder.verify(mMockDnsResolver, never()).startPrefix64Discovery(netId); 10147 callback.assertNoCallback(); 10148 assertEquals(pref64FromRa, mCm.getLinkProperties(network).getNat64Prefix()); 10149 10150 // If the RA prefix is withdrawn, clatd is stopped and prefix discovery is started. 10151 lp.setNat64Prefix(null); 10152 mWiFiNetworkAgent.sendLinkProperties(lp); 10153 expectNat64PrefixChange(callback, mWiFiNetworkAgent, null); 10154 verifyClatdStop(inOrder, iface); 10155 inOrder.verify(mMockDnsResolver).setPrefix64(netId, ""); 10156 inOrder.verify(mMockDnsResolver).startPrefix64Discovery(netId); 10157 10158 // If the RA prefix appears while DNS discovery is in progress, discovery is stopped and 10159 // clatd is started with the prefix from the RA. 10160 lp.setNat64Prefix(pref64FromRa); 10161 mWiFiNetworkAgent.sendLinkProperties(lp); 10162 expectNat64PrefixChange(callback, mWiFiNetworkAgent, pref64FromRa); 10163 verifyClatdStart(inOrder, iface, netId, pref64FromRa.toString()); 10164 inOrder.verify(mMockDnsResolver).stopPrefix64Discovery(netId); 10165 inOrder.verify(mMockDnsResolver).setPrefix64(netId, pref64FromRa.toString()); 10166 10167 // Withdraw the RA prefix so we can test the case where an RA prefix appears after DNS 10168 // discovery has succeeded. 10169 lp.setNat64Prefix(null); 10170 mWiFiNetworkAgent.sendLinkProperties(lp); 10171 expectNat64PrefixChange(callback, mWiFiNetworkAgent, null); 10172 verifyClatdStop(inOrder, iface); 10173 inOrder.verify(mMockDnsResolver).setPrefix64(netId, ""); 10174 inOrder.verify(mMockDnsResolver).startPrefix64Discovery(netId); 10175 10176 mService.mResolverUnsolEventCallback.onNat64PrefixEvent( 10177 makeNat64PrefixEvent(netId, PREFIX_OPERATION_ADDED, pref64FromDnsStr, 96)); 10178 expectNat64PrefixChange(callback, mWiFiNetworkAgent, pref64FromDns); 10179 verifyClatdStart(inOrder, iface, netId, pref64FromDns.toString()); 10180 10181 // If an RA advertises the same prefix that was discovered by DNS, nothing happens: prefix 10182 // discovery is not stopped, and there are no callbacks. 10183 lp.setNat64Prefix(pref64FromDns); 10184 mWiFiNetworkAgent.sendLinkProperties(lp); 10185 callback.assertNoCallback(); 10186 verifyNeverClatdStop(inOrder, iface); 10187 verifyNeverClatdStart(inOrder, iface); 10188 inOrder.verify(mMockDnsResolver, never()).stopPrefix64Discovery(netId); 10189 inOrder.verify(mMockDnsResolver, never()).startPrefix64Discovery(netId); 10190 inOrder.verify(mMockDnsResolver, never()).setPrefix64(eq(netId), anyString()); 10191 10192 // If the RA is later withdrawn, nothing happens again. 10193 lp.setNat64Prefix(null); 10194 mWiFiNetworkAgent.sendLinkProperties(lp); 10195 callback.assertNoCallback(); 10196 verifyNeverClatdStop(inOrder, iface); 10197 verifyNeverClatdStart(inOrder, iface); 10198 inOrder.verify(mMockDnsResolver, never()).stopPrefix64Discovery(netId); 10199 inOrder.verify(mMockDnsResolver, never()).startPrefix64Discovery(netId); 10200 inOrder.verify(mMockDnsResolver, never()).setPrefix64(eq(netId), anyString()); 10201 10202 // If the RA prefix changes, clatd is restarted and prefix discovery is stopped. 10203 lp.setNat64Prefix(pref64FromRa); 10204 mWiFiNetworkAgent.sendLinkProperties(lp); 10205 expectNat64PrefixChange(callback, mWiFiNetworkAgent, pref64FromRa); 10206 verifyClatdStop(inOrder, iface); 10207 inOrder.verify(mMockDnsResolver).stopPrefix64Discovery(netId); 10208 10209 // Stopping prefix discovery results in a prefix removed notification. 10210 mService.mResolverUnsolEventCallback.onNat64PrefixEvent( 10211 makeNat64PrefixEvent(netId, PREFIX_OPERATION_REMOVED, pref64FromDnsStr, 96)); 10212 10213 verifyClatdStart(inOrder, iface, netId, pref64FromRa.toString()); 10214 inOrder.verify(mMockDnsResolver).setPrefix64(netId, pref64FromRa.toString()); 10215 inOrder.verify(mMockDnsResolver, never()).startPrefix64Discovery(netId); 10216 10217 // If the RA prefix changes, clatd is restarted and prefix discovery is not started. 10218 lp.setNat64Prefix(newPref64FromRa); 10219 mWiFiNetworkAgent.sendLinkProperties(lp); 10220 expectNat64PrefixChange(callback, mWiFiNetworkAgent, newPref64FromRa); 10221 verifyClatdStop(inOrder, iface); 10222 inOrder.verify(mMockDnsResolver).setPrefix64(netId, ""); 10223 verifyClatdStart(inOrder, iface, netId, newPref64FromRa.toString()); 10224 inOrder.verify(mMockDnsResolver).setPrefix64(netId, newPref64FromRa.toString()); 10225 inOrder.verify(mMockDnsResolver, never()).stopPrefix64Discovery(netId); 10226 inOrder.verify(mMockDnsResolver, never()).startPrefix64Discovery(netId); 10227 10228 // If the RA prefix changes to the same value, nothing happens. 10229 lp.setNat64Prefix(newPref64FromRa); 10230 mWiFiNetworkAgent.sendLinkProperties(lp); 10231 callback.assertNoCallback(); 10232 assertEquals(newPref64FromRa, mCm.getLinkProperties(network).getNat64Prefix()); 10233 verifyNeverClatdStop(inOrder, iface); 10234 verifyNeverClatdStart(inOrder, iface); 10235 inOrder.verify(mMockDnsResolver, never()).stopPrefix64Discovery(netId); 10236 inOrder.verify(mMockDnsResolver, never()).startPrefix64Discovery(netId); 10237 inOrder.verify(mMockDnsResolver, never()).setPrefix64(eq(netId), anyString()); 10238 10239 // The transition between no prefix and DNS prefix is tested in testStackedLinkProperties. 10240 10241 // If the same prefix is learned first by DNS and then by RA, and clat is later stopped, 10242 // (e.g., because the network disconnects) setPrefix64(netid, "") is never called. 10243 lp.setNat64Prefix(null); 10244 mWiFiNetworkAgent.sendLinkProperties(lp); 10245 expectNat64PrefixChange(callback, mWiFiNetworkAgent, null); 10246 verifyClatdStop(inOrder, iface); 10247 inOrder.verify(mMockDnsResolver).setPrefix64(netId, ""); 10248 inOrder.verify(mMockDnsResolver).startPrefix64Discovery(netId); 10249 mService.mResolverUnsolEventCallback.onNat64PrefixEvent( 10250 makeNat64PrefixEvent(netId, PREFIX_OPERATION_ADDED, pref64FromDnsStr, 96)); 10251 expectNat64PrefixChange(callback, mWiFiNetworkAgent, pref64FromDns); 10252 verifyClatdStart(inOrder, iface, netId, pref64FromDns.toString()); 10253 inOrder.verify(mMockDnsResolver, never()).setPrefix64(eq(netId), any()); 10254 10255 lp.setNat64Prefix(pref64FromDns); 10256 mWiFiNetworkAgent.sendLinkProperties(lp); 10257 callback.assertNoCallback(); 10258 verifyNeverClatdStop(inOrder, iface); 10259 verifyNeverClatdStart(inOrder, iface); 10260 inOrder.verify(mMockDnsResolver, never()).stopPrefix64Discovery(netId); 10261 inOrder.verify(mMockDnsResolver, never()).startPrefix64Discovery(netId); 10262 inOrder.verify(mMockDnsResolver, never()).setPrefix64(eq(netId), anyString()); 10263 10264 // When tearing down a network, clat state is only updated after CALLBACK_LOST is fired, but 10265 // before CONNECTIVITY_ACTION is sent. Wait for CONNECTIVITY_ACTION before verifying that 10266 // clat has been stopped, or the test will be flaky. 10267 ExpectedBroadcast b = expectConnectivityAction(TYPE_WIFI, DetailedState.DISCONNECTED); 10268 mWiFiNetworkAgent.disconnect(); 10269 callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 10270 b.expectBroadcast(); 10271 10272 verifyClatdStop(inOrder, iface); 10273 inOrder.verify(mMockDnsResolver).stopPrefix64Discovery(netId); 10274 inOrder.verify(mMockDnsResolver, never()).setPrefix64(eq(netId), anyString()); 10275 10276 mCm.unregisterNetworkCallback(callback); 10277 } 10278 10279 @Test 10280 public void testWith464XlatDisable() throws Exception { 10281 mDeps.setCellular464XlatEnabled(false); 10282 10283 final TestNetworkCallback callback = new TestNetworkCallback(); 10284 final TestNetworkCallback defaultCallback = new TestNetworkCallback(); 10285 final NetworkRequest networkRequest = new NetworkRequest.Builder() 10286 .addCapability(NET_CAPABILITY_INTERNET) 10287 .build(); 10288 mCm.registerNetworkCallback(networkRequest, callback); 10289 mCm.registerDefaultNetworkCallback(defaultCallback); 10290 10291 // Bring up validated cell. 10292 final LinkProperties cellLp = new LinkProperties(); 10293 cellLp.setInterfaceName(MOBILE_IFNAME); 10294 cellLp.addLinkAddress(new LinkAddress("2001:db8:1::1/64")); 10295 cellLp.addRoute(new RouteInfo(new IpPrefix("::/0"), null, MOBILE_IFNAME)); 10296 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 10297 10298 mCellNetworkAgent.sendLinkProperties(cellLp); 10299 mCellNetworkAgent.connect(true); 10300 callback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 10301 defaultCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 10302 final int cellNetId = mCellNetworkAgent.getNetwork().netId; 10303 waitForIdle(); 10304 10305 verify(mMockDnsResolver, never()).startPrefix64Discovery(cellNetId); 10306 Nat464Xlat clat = getNat464Xlat(mCellNetworkAgent); 10307 assertTrue("Nat464Xlat was not IDLE", !clat.isStarted()); 10308 10309 // This cannot happen because prefix discovery cannot succeed if it is never started. 10310 mService.mResolverUnsolEventCallback.onNat64PrefixEvent( 10311 makeNat64PrefixEvent(cellNetId, PREFIX_OPERATION_ADDED, "64:ff9b::", 96)); 10312 10313 // ... but still, check that even if it did, clatd would not be started. 10314 verify(mMockNetd, never()).clatdStart(anyString(), anyString()); 10315 assertTrue("Nat464Xlat was not IDLE", !clat.isStarted()); 10316 } 10317 10318 @Test 10319 public void testDataActivityTracking() throws Exception { 10320 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 10321 final NetworkRequest networkRequest = new NetworkRequest.Builder() 10322 .addCapability(NET_CAPABILITY_INTERNET) 10323 .build(); 10324 mCm.registerNetworkCallback(networkRequest, networkCallback); 10325 10326 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 10327 final LinkProperties cellLp = new LinkProperties(); 10328 cellLp.setInterfaceName(MOBILE_IFNAME); 10329 mCellNetworkAgent.sendLinkProperties(cellLp); 10330 mCellNetworkAgent.connect(true); 10331 networkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 10332 verify(mMockNetd, times(1)).idletimerAddInterface(eq(MOBILE_IFNAME), anyInt(), 10333 eq(Integer.toString(TRANSPORT_CELLULAR))); 10334 10335 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 10336 final LinkProperties wifiLp = new LinkProperties(); 10337 wifiLp.setInterfaceName(WIFI_IFNAME); 10338 mWiFiNetworkAgent.sendLinkProperties(wifiLp); 10339 10340 // Network switch 10341 mWiFiNetworkAgent.connect(true); 10342 networkCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 10343 networkCallback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent); 10344 networkCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent); 10345 verify(mMockNetd, times(1)).idletimerAddInterface(eq(WIFI_IFNAME), anyInt(), 10346 eq(Integer.toString(TRANSPORT_WIFI))); 10347 verify(mMockNetd, times(1)).idletimerRemoveInterface(eq(MOBILE_IFNAME), anyInt(), 10348 eq(Integer.toString(TRANSPORT_CELLULAR))); 10349 10350 // Disconnect wifi and switch back to cell 10351 reset(mMockNetd); 10352 mWiFiNetworkAgent.disconnect(); 10353 networkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 10354 assertNoCallbacks(networkCallback); 10355 verify(mMockNetd, times(1)).idletimerRemoveInterface(eq(WIFI_IFNAME), anyInt(), 10356 eq(Integer.toString(TRANSPORT_WIFI))); 10357 verify(mMockNetd, times(1)).idletimerAddInterface(eq(MOBILE_IFNAME), anyInt(), 10358 eq(Integer.toString(TRANSPORT_CELLULAR))); 10359 10360 // reconnect wifi 10361 reset(mMockNetd); 10362 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 10363 wifiLp.setInterfaceName(WIFI_IFNAME); 10364 mWiFiNetworkAgent.sendLinkProperties(wifiLp); 10365 mWiFiNetworkAgent.connect(true); 10366 networkCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 10367 networkCallback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent); 10368 networkCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent); 10369 verify(mMockNetd, times(1)).idletimerAddInterface(eq(WIFI_IFNAME), anyInt(), 10370 eq(Integer.toString(TRANSPORT_WIFI))); 10371 verify(mMockNetd, times(1)).idletimerRemoveInterface(eq(MOBILE_IFNAME), anyInt(), 10372 eq(Integer.toString(TRANSPORT_CELLULAR))); 10373 10374 // Disconnect cell 10375 reset(mMockNetd); 10376 mCellNetworkAgent.disconnect(); 10377 networkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 10378 // LOST callback is triggered earlier than removing idle timer. Broadcast should also be 10379 // sent as network being switched. Ensure rule removal for cell will not be triggered 10380 // unexpectedly before network being removed. 10381 waitForIdle(); 10382 verify(mMockNetd, times(0)).idletimerRemoveInterface(eq(MOBILE_IFNAME), anyInt(), 10383 eq(Integer.toString(TRANSPORT_CELLULAR))); 10384 verify(mMockNetd, times(1)).networkDestroy(eq(mCellNetworkAgent.getNetwork().netId)); 10385 verify(mMockDnsResolver, times(1)) 10386 .destroyNetworkCache(eq(mCellNetworkAgent.getNetwork().netId)); 10387 10388 // Disconnect wifi 10389 ExpectedBroadcast b = expectConnectivityAction(TYPE_WIFI, DetailedState.DISCONNECTED); 10390 mWiFiNetworkAgent.disconnect(); 10391 b.expectBroadcast(); 10392 verify(mMockNetd, times(1)).idletimerRemoveInterface(eq(WIFI_IFNAME), anyInt(), 10393 eq(Integer.toString(TRANSPORT_WIFI))); 10394 10395 // Clean up 10396 mCm.unregisterNetworkCallback(networkCallback); 10397 } 10398 10399 private void verifyTcpBufferSizeChange(String tcpBufferSizes) throws Exception { 10400 String[] values = tcpBufferSizes.split(","); 10401 String rmemValues = String.join(" ", values[0], values[1], values[2]); 10402 String wmemValues = String.join(" ", values[3], values[4], values[5]); 10403 verify(mMockNetd, atLeastOnce()).setTcpRWmemorySize(rmemValues, wmemValues); 10404 reset(mMockNetd); 10405 } 10406 10407 @Test 10408 public void testTcpBufferReset() throws Exception { 10409 final String testTcpBufferSizes = "1,2,3,4,5,6"; 10410 final NetworkRequest networkRequest = new NetworkRequest.Builder() 10411 .addTransportType(TRANSPORT_CELLULAR) 10412 .addCapability(NET_CAPABILITY_INTERNET) 10413 .build(); 10414 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 10415 mCm.registerNetworkCallback(networkRequest, networkCallback); 10416 10417 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 10418 reset(mMockNetd); 10419 // Switching default network updates TCP buffer sizes. 10420 mCellNetworkAgent.connect(false); 10421 networkCallback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent); 10422 verifyTcpBufferSizeChange(ConnectivityService.DEFAULT_TCP_BUFFER_SIZES); 10423 // Change link Properties should have updated tcp buffer size. 10424 LinkProperties lp = new LinkProperties(); 10425 lp.setTcpBufferSizes(testTcpBufferSizes); 10426 mCellNetworkAgent.sendLinkProperties(lp); 10427 networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent); 10428 verifyTcpBufferSizeChange(testTcpBufferSizes); 10429 // Clean up. 10430 mCellNetworkAgent.disconnect(); 10431 networkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 10432 networkCallback.assertNoCallback(); 10433 mCm.unregisterNetworkCallback(networkCallback); 10434 } 10435 10436 @Test 10437 public void testGetGlobalProxyForNetwork() throws Exception { 10438 final ProxyInfo testProxyInfo = ProxyInfo.buildDirectProxy("test", 8888); 10439 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 10440 final Network wifiNetwork = mWiFiNetworkAgent.getNetwork(); 10441 mProxyTracker.setGlobalProxy(testProxyInfo); 10442 assertEquals(testProxyInfo, mService.getProxyForNetwork(wifiNetwork)); 10443 } 10444 10445 @Test 10446 public void testGetProxyForActiveNetwork() throws Exception { 10447 final ProxyInfo testProxyInfo = ProxyInfo.buildDirectProxy("test", 8888); 10448 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 10449 mWiFiNetworkAgent.connect(true); 10450 waitForIdle(); 10451 assertNull(mService.getProxyForNetwork(null)); 10452 10453 final LinkProperties testLinkProperties = new LinkProperties(); 10454 testLinkProperties.setHttpProxy(testProxyInfo); 10455 10456 mWiFiNetworkAgent.sendLinkProperties(testLinkProperties); 10457 waitForIdle(); 10458 10459 assertEquals(testProxyInfo, mService.getProxyForNetwork(null)); 10460 } 10461 10462 @Test 10463 public void testGetProxyForVPN() throws Exception { 10464 final ProxyInfo testProxyInfo = ProxyInfo.buildDirectProxy("test", 8888); 10465 10466 // Set up a WiFi network with no proxy 10467 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 10468 mWiFiNetworkAgent.connect(true); 10469 waitForIdle(); 10470 assertNull(mService.getProxyForNetwork(null)); 10471 10472 // Connect a VPN network with a proxy. 10473 LinkProperties testLinkProperties = new LinkProperties(); 10474 testLinkProperties.setHttpProxy(testProxyInfo); 10475 mMockVpn.establishForMyUid(testLinkProperties); 10476 assertUidRangesUpdatedForMyUid(true); 10477 10478 // Test that the VPN network returns a proxy, and the WiFi does not. 10479 assertEquals(testProxyInfo, mService.getProxyForNetwork(mMockVpn.getNetwork())); 10480 assertEquals(testProxyInfo, mService.getProxyForNetwork(null)); 10481 assertNull(mService.getProxyForNetwork(mWiFiNetworkAgent.getNetwork())); 10482 10483 // Test that the VPN network returns no proxy when it is set to null. 10484 testLinkProperties.setHttpProxy(null); 10485 mMockVpn.sendLinkProperties(testLinkProperties); 10486 waitForIdle(); 10487 assertNull(mService.getProxyForNetwork(mMockVpn.getNetwork())); 10488 assertNull(mService.getProxyForNetwork(null)); 10489 10490 // Set WiFi proxy and check that the vpn proxy is still null. 10491 testLinkProperties.setHttpProxy(testProxyInfo); 10492 mWiFiNetworkAgent.sendLinkProperties(testLinkProperties); 10493 waitForIdle(); 10494 assertNull(mService.getProxyForNetwork(null)); 10495 10496 // Disconnect from VPN and check that the active network, which is now the WiFi, has the 10497 // correct proxy setting. 10498 mMockVpn.disconnect(); 10499 waitForIdle(); 10500 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 10501 assertEquals(testProxyInfo, mService.getProxyForNetwork(mWiFiNetworkAgent.getNetwork())); 10502 assertEquals(testProxyInfo, mService.getProxyForNetwork(null)); 10503 } 10504 10505 @Test 10506 public void testFullyRoutedVpnResultsInInterfaceFilteringRules() throws Exception { 10507 LinkProperties lp = new LinkProperties(); 10508 lp.setInterfaceName("tun0"); 10509 lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), null)); 10510 lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), RTN_UNREACHABLE)); 10511 // The uid range needs to cover the test app so the network is visible to it. 10512 final Set<UidRange> vpnRange = Collections.singleton(PRIMARY_UIDRANGE); 10513 mMockVpn.establish(lp, VPN_UID, vpnRange); 10514 assertVpnUidRangesUpdated(true, vpnRange, VPN_UID); 10515 10516 // A connected VPN should have interface rules set up. There are two expected invocations, 10517 // one during the VPN initial connection, one during the VPN LinkProperties update. 10518 ArgumentCaptor<int[]> uidCaptor = ArgumentCaptor.forClass(int[].class); 10519 verify(mBpfNetMaps, times(2)).addUidInterfaceRules(eq("tun0"), uidCaptor.capture()); 10520 assertContainsExactly(uidCaptor.getAllValues().get(0), APP1_UID, APP2_UID); 10521 assertContainsExactly(uidCaptor.getAllValues().get(1), APP1_UID, APP2_UID); 10522 assertTrue(mService.mPermissionMonitor.getVpnInterfaceUidRanges("tun0").equals(vpnRange)); 10523 10524 mMockVpn.disconnect(); 10525 waitForIdle(); 10526 10527 // Disconnected VPN should have interface rules removed 10528 verify(mBpfNetMaps).removeUidInterfaceRules(uidCaptor.capture()); 10529 assertContainsExactly(uidCaptor.getValue(), APP1_UID, APP2_UID); 10530 assertNull(mService.mPermissionMonitor.getVpnInterfaceUidRanges("tun0")); 10531 } 10532 10533 @Test 10534 public void testLegacyVpnSetInterfaceFilteringRuleWithWildcard() throws Exception { 10535 LinkProperties lp = new LinkProperties(); 10536 lp.setInterfaceName("tun0"); 10537 lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), null)); 10538 lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), null)); 10539 // The uid range needs to cover the test app so the network is visible to it. 10540 final Set<UidRange> vpnRange = Collections.singleton(PRIMARY_UIDRANGE); 10541 mMockVpn.establish(lp, Process.SYSTEM_UID, vpnRange); 10542 assertVpnUidRangesUpdated(true, vpnRange, Process.SYSTEM_UID); 10543 10544 // A connected Legacy VPN should have interface rules with null interface. 10545 // Null Interface is a wildcard and this accepts traffic from all the interfaces. 10546 // There are two expected invocations, one during the VPN initial connection, 10547 // one during the VPN LinkProperties update. 10548 ArgumentCaptor<int[]> uidCaptor = ArgumentCaptor.forClass(int[].class); 10549 verify(mBpfNetMaps, times(2)).addUidInterfaceRules( 10550 eq(null) /* iface */, uidCaptor.capture()); 10551 assertContainsExactly(uidCaptor.getAllValues().get(0), APP1_UID, APP2_UID, VPN_UID); 10552 assertContainsExactly(uidCaptor.getAllValues().get(1), APP1_UID, APP2_UID, VPN_UID); 10553 assertEquals(mService.mPermissionMonitor.getVpnInterfaceUidRanges(null /* iface */), 10554 vpnRange); 10555 10556 mMockVpn.disconnect(); 10557 waitForIdle(); 10558 10559 // Disconnected VPN should have interface rules removed 10560 verify(mBpfNetMaps).removeUidInterfaceRules(uidCaptor.capture()); 10561 assertContainsExactly(uidCaptor.getValue(), APP1_UID, APP2_UID, VPN_UID); 10562 assertNull(mService.mPermissionMonitor.getVpnInterfaceUidRanges(null /* iface */)); 10563 } 10564 10565 @Test 10566 public void testLocalIpv4OnlyVpnSetInterfaceFilteringRuleWithWildcard() throws Exception { 10567 LinkProperties lp = new LinkProperties(); 10568 lp.setInterfaceName("tun0"); 10569 lp.addRoute(new RouteInfo(new IpPrefix("192.0.2.0/24"), null, "tun0")); 10570 lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), RTN_UNREACHABLE)); 10571 // The uid range needs to cover the test app so the network is visible to it. 10572 final Set<UidRange> vpnRange = Collections.singleton(PRIMARY_UIDRANGE); 10573 mMockVpn.establish(lp, Process.SYSTEM_UID, vpnRange); 10574 assertVpnUidRangesUpdated(true, vpnRange, Process.SYSTEM_UID); 10575 10576 // IPv6 unreachable route should not be misinterpreted as a default route 10577 // A connected VPN should have interface rules with null interface. 10578 // Null Interface is a wildcard and this accepts traffic from all the interfaces. 10579 // There are two expected invocations, one during the VPN initial connection, 10580 // one during the VPN LinkProperties update. 10581 ArgumentCaptor<int[]> uidCaptor = ArgumentCaptor.forClass(int[].class); 10582 verify(mBpfNetMaps, times(2)).addUidInterfaceRules( 10583 eq(null) /* iface */, uidCaptor.capture()); 10584 assertContainsExactly(uidCaptor.getAllValues().get(0), APP1_UID, APP2_UID, VPN_UID); 10585 assertContainsExactly(uidCaptor.getAllValues().get(1), APP1_UID, APP2_UID, VPN_UID); 10586 assertEquals(mService.mPermissionMonitor.getVpnInterfaceUidRanges(null /* iface */), 10587 vpnRange); 10588 10589 mMockVpn.disconnect(); 10590 waitForIdle(); 10591 10592 // Disconnected VPN should have interface rules removed 10593 verify(mBpfNetMaps).removeUidInterfaceRules(uidCaptor.capture()); 10594 assertContainsExactly(uidCaptor.getValue(), APP1_UID, APP2_UID, VPN_UID); 10595 assertNull(mService.mPermissionMonitor.getVpnInterfaceUidRanges(null /* iface */)); 10596 } 10597 10598 @Test 10599 public void testVpnHandoverChangesInterfaceFilteringRule() throws Exception { 10600 LinkProperties lp = new LinkProperties(); 10601 lp.setInterfaceName("tun0"); 10602 lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), null)); 10603 lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), null)); 10604 // The uid range needs to cover the test app so the network is visible to it. 10605 final Set<UidRange> vpnRange = Collections.singleton(PRIMARY_UIDRANGE); 10606 mMockVpn.establish(lp, VPN_UID, vpnRange); 10607 assertVpnUidRangesUpdated(true, vpnRange, VPN_UID); 10608 10609 // Connected VPN should have interface rules set up. There are two expected invocations, 10610 // one during VPN uid update, one during VPN LinkProperties update 10611 ArgumentCaptor<int[]> uidCaptor = ArgumentCaptor.forClass(int[].class); 10612 verify(mBpfNetMaps, times(2)).addUidInterfaceRules(eq("tun0"), uidCaptor.capture()); 10613 assertContainsExactly(uidCaptor.getAllValues().get(0), APP1_UID, APP2_UID); 10614 assertContainsExactly(uidCaptor.getAllValues().get(1), APP1_UID, APP2_UID); 10615 10616 reset(mBpfNetMaps); 10617 InOrder inOrder = inOrder(mBpfNetMaps); 10618 lp.setInterfaceName("tun1"); 10619 mMockVpn.sendLinkProperties(lp); 10620 waitForIdle(); 10621 // VPN handover (switch to a new interface) should result in rules being updated (old rules 10622 // removed first, then new rules added) 10623 inOrder.verify(mBpfNetMaps).removeUidInterfaceRules(uidCaptor.capture()); 10624 assertContainsExactly(uidCaptor.getValue(), APP1_UID, APP2_UID); 10625 inOrder.verify(mBpfNetMaps).addUidInterfaceRules(eq("tun1"), uidCaptor.capture()); 10626 assertContainsExactly(uidCaptor.getValue(), APP1_UID, APP2_UID); 10627 10628 reset(mBpfNetMaps); 10629 lp = new LinkProperties(); 10630 lp.setInterfaceName("tun1"); 10631 lp.addRoute(new RouteInfo(new IpPrefix("192.0.2.0/24"), null, "tun1")); 10632 mMockVpn.sendLinkProperties(lp); 10633 waitForIdle(); 10634 // VPN not routing everything should no longer have interface filtering rules 10635 verify(mBpfNetMaps).removeUidInterfaceRules(uidCaptor.capture()); 10636 assertContainsExactly(uidCaptor.getValue(), APP1_UID, APP2_UID); 10637 10638 reset(mBpfNetMaps); 10639 lp = new LinkProperties(); 10640 lp.setInterfaceName("tun1"); 10641 lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), RTN_UNREACHABLE)); 10642 lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), null)); 10643 mMockVpn.sendLinkProperties(lp); 10644 waitForIdle(); 10645 // Back to routing all IPv6 traffic should have filtering rules 10646 verify(mBpfNetMaps).addUidInterfaceRules(eq("tun1"), uidCaptor.capture()); 10647 assertContainsExactly(uidCaptor.getValue(), APP1_UID, APP2_UID); 10648 } 10649 10650 @Test 10651 public void testStartVpnProfileFromDiffPackage() throws Exception { 10652 final String notMyVpnPkg = "com.not.my.vpn"; 10653 assertThrows( 10654 SecurityException.class, () -> mVpnManagerService.startVpnProfile(notMyVpnPkg)); 10655 } 10656 10657 @Test 10658 public void testStopVpnProfileFromDiffPackage() throws Exception { 10659 final String notMyVpnPkg = "com.not.my.vpn"; 10660 assertThrows(SecurityException.class, () -> mVpnManagerService.stopVpnProfile(notMyVpnPkg)); 10661 } 10662 10663 @Test 10664 public void testUidUpdateChangesInterfaceFilteringRule() throws Exception { 10665 LinkProperties lp = new LinkProperties(); 10666 lp.setInterfaceName("tun0"); 10667 lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), RTN_UNREACHABLE)); 10668 lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), null)); 10669 // The uid range needs to cover the test app so the network is visible to it. 10670 final UidRange vpnRange = PRIMARY_UIDRANGE; 10671 final Set<UidRange> vpnRanges = Collections.singleton(vpnRange); 10672 mMockVpn.establish(lp, VPN_UID, vpnRanges); 10673 assertVpnUidRangesUpdated(true, vpnRanges, VPN_UID); 10674 10675 reset(mBpfNetMaps); 10676 InOrder inOrder = inOrder(mBpfNetMaps); 10677 10678 // Update to new range which is old range minus APP1, i.e. only APP2 10679 final Set<UidRange> newRanges = new HashSet<>(asList( 10680 new UidRange(vpnRange.start, APP1_UID - 1), 10681 new UidRange(APP1_UID + 1, vpnRange.stop))); 10682 mMockVpn.setUids(newRanges); 10683 waitForIdle(); 10684 10685 ArgumentCaptor<int[]> uidCaptor = ArgumentCaptor.forClass(int[].class); 10686 // Verify old rules are removed before new rules are added 10687 inOrder.verify(mBpfNetMaps).removeUidInterfaceRules(uidCaptor.capture()); 10688 assertContainsExactly(uidCaptor.getValue(), APP1_UID, APP2_UID); 10689 inOrder.verify(mBpfNetMaps).addUidInterfaceRules(eq("tun0"), uidCaptor.capture()); 10690 assertContainsExactly(uidCaptor.getValue(), APP2_UID); 10691 } 10692 10693 @Test 10694 public void testLinkPropertiesWithWakeOnLanForActiveNetwork() throws Exception { 10695 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 10696 10697 LinkProperties wifiLp = new LinkProperties(); 10698 wifiLp.setInterfaceName(WIFI_WOL_IFNAME); 10699 wifiLp.setWakeOnLanSupported(false); 10700 10701 // Default network switch should update ifaces. 10702 mWiFiNetworkAgent.connect(false); 10703 mWiFiNetworkAgent.sendLinkProperties(wifiLp); 10704 waitForIdle(); 10705 10706 // ConnectivityService should have changed the WakeOnLanSupported to true 10707 wifiLp.setWakeOnLanSupported(true); 10708 assertEquals(wifiLp, mService.getActiveLinkProperties()); 10709 } 10710 10711 @Test 10712 public void testLegacyExtraInfoSentToNetworkMonitor() throws Exception { 10713 class TestNetworkAgent extends NetworkAgent { 10714 TestNetworkAgent(Context context, Looper looper, NetworkAgentConfig config) { 10715 super(context, looper, "MockAgent", new NetworkCapabilities(), 10716 new LinkProperties(), 40 , config, null /* provider */); 10717 } 10718 } 10719 final NetworkAgent naNoExtraInfo = new TestNetworkAgent( 10720 mServiceContext, mCsHandlerThread.getLooper(), new NetworkAgentConfig()); 10721 naNoExtraInfo.register(); 10722 verify(mNetworkStack).makeNetworkMonitor(any(), isNull(String.class), any()); 10723 naNoExtraInfo.unregister(); 10724 10725 reset(mNetworkStack); 10726 final NetworkAgentConfig config = 10727 new NetworkAgentConfig.Builder().setLegacyExtraInfo("legacyinfo").build(); 10728 final NetworkAgent naExtraInfo = new TestNetworkAgent( 10729 mServiceContext, mCsHandlerThread.getLooper(), config); 10730 naExtraInfo.register(); 10731 verify(mNetworkStack).makeNetworkMonitor(any(), eq("legacyinfo"), any()); 10732 naExtraInfo.unregister(); 10733 } 10734 10735 // To avoid granting location permission bypass. 10736 private void denyAllLocationPrivilegedPermissions() { 10737 mServiceContext.setPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, 10738 PERMISSION_DENIED); 10739 mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_DENIED); 10740 mServiceContext.setPermission(NETWORK_STACK, PERMISSION_DENIED); 10741 mServiceContext.setPermission(Manifest.permission.NETWORK_SETUP_WIZARD, 10742 PERMISSION_DENIED); 10743 } 10744 10745 private void setupLocationPermissions( 10746 int targetSdk, boolean locationToggle, String op, String perm) throws Exception { 10747 denyAllLocationPrivilegedPermissions(); 10748 10749 final ApplicationInfo applicationInfo = new ApplicationInfo(); 10750 applicationInfo.targetSdkVersion = targetSdk; 10751 doReturn(applicationInfo).when(mPackageManager) 10752 .getApplicationInfoAsUser(anyString(), anyInt(), any()); 10753 doReturn(targetSdk).when(mPackageManager).getTargetSdkVersion(any()); 10754 10755 doReturn(locationToggle).when(mLocationManager).isLocationEnabledForUser(any()); 10756 10757 if (op != null) { 10758 doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager).noteOp( 10759 eq(op), eq(Process.myUid()), eq(mContext.getPackageName()), 10760 eq(getAttributionTag()), anyString()); 10761 } 10762 10763 if (perm != null) { 10764 mServiceContext.setPermission(perm, PERMISSION_GRANTED); 10765 } 10766 } 10767 10768 private int getOwnerUidNetCapsPermission(int ownerUid, int callerUid, 10769 boolean includeLocationSensitiveInfo) { 10770 final NetworkCapabilities netCap = new NetworkCapabilities().setOwnerUid(ownerUid); 10771 10772 return mService.createWithLocationInfoSanitizedIfNecessaryWhenParceled( 10773 netCap, includeLocationSensitiveInfo, Process.myUid(), callerUid, 10774 mContext.getPackageName(), getAttributionTag()) 10775 .getOwnerUid(); 10776 } 10777 10778 private void verifyTransportInfoCopyNetCapsPermission( 10779 int callerUid, boolean includeLocationSensitiveInfo, 10780 boolean shouldMakeCopyWithLocationSensitiveFieldsParcelable) { 10781 final TransportInfo transportInfo = mock(TransportInfo.class); 10782 doReturn(REDACT_FOR_ACCESS_FINE_LOCATION).when(transportInfo).getApplicableRedactions(); 10783 final NetworkCapabilities netCap = 10784 new NetworkCapabilities().setTransportInfo(transportInfo); 10785 10786 mService.createWithLocationInfoSanitizedIfNecessaryWhenParceled( 10787 netCap, includeLocationSensitiveInfo, Process.myPid(), callerUid, 10788 mContext.getPackageName(), getAttributionTag()); 10789 if (shouldMakeCopyWithLocationSensitiveFieldsParcelable) { 10790 verify(transportInfo).makeCopy(REDACT_NONE); 10791 } else { 10792 verify(transportInfo).makeCopy(REDACT_FOR_ACCESS_FINE_LOCATION); 10793 } 10794 } 10795 10796 private void verifyOwnerUidAndTransportInfoNetCapsPermission( 10797 boolean shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag, 10798 boolean shouldInclLocationSensitiveOwnerUidWithIncludeFlag, 10799 boolean shouldInclLocationSensitiveTransportInfoWithoutIncludeFlag, 10800 boolean shouldInclLocationSensitiveTransportInfoWithIncludeFlag) { 10801 final int myUid = Process.myUid(); 10802 10803 final int expectedOwnerUidWithoutIncludeFlag = 10804 shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag 10805 ? myUid : INVALID_UID; 10806 assertEquals(expectedOwnerUidWithoutIncludeFlag, getOwnerUidNetCapsPermission( 10807 myUid, myUid, false /* includeLocationSensitiveInfo */)); 10808 10809 final int expectedOwnerUidWithIncludeFlag = 10810 shouldInclLocationSensitiveOwnerUidWithIncludeFlag ? myUid : INVALID_UID; 10811 assertEquals(expectedOwnerUidWithIncludeFlag, getOwnerUidNetCapsPermission( 10812 myUid, myUid, true /* includeLocationSensitiveInfo */)); 10813 10814 verifyTransportInfoCopyNetCapsPermission(myUid, 10815 false, /* includeLocationSensitiveInfo */ 10816 shouldInclLocationSensitiveTransportInfoWithoutIncludeFlag); 10817 10818 verifyTransportInfoCopyNetCapsPermission(myUid, 10819 true, /* includeLocationSensitiveInfo */ 10820 shouldInclLocationSensitiveTransportInfoWithIncludeFlag); 10821 10822 } 10823 10824 private void verifyOwnerUidAndTransportInfoNetCapsPermissionPreS() { 10825 verifyOwnerUidAndTransportInfoNetCapsPermission( 10826 // Ensure that owner uid is included even if the request asks to remove it (which is 10827 // the default) since the app has necessary permissions and targetSdk < S. 10828 true, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */ 10829 true, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */ 10830 // Ensure that location info is removed if the request asks to remove it even if the 10831 // app has necessary permissions. 10832 false, /* shouldInclLocationSensitiveTransportInfoWithoutIncludeFlag */ 10833 true /* shouldInclLocationSensitiveTransportInfoWithIncludeFlag */ 10834 ); 10835 } 10836 10837 @Test 10838 public void testCreateWithLocationInfoSanitizedWithFineLocationAfterQPreS() 10839 throws Exception { 10840 setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION, 10841 Manifest.permission.ACCESS_FINE_LOCATION); 10842 10843 verifyOwnerUidAndTransportInfoNetCapsPermissionPreS(); 10844 } 10845 10846 @Test 10847 public void testCreateWithLocationInfoSanitizedWithFineLocationPreSWithAndWithoutCallbackFlag() 10848 throws Exception { 10849 setupLocationPermissions(Build.VERSION_CODES.R, true, AppOpsManager.OPSTR_FINE_LOCATION, 10850 Manifest.permission.ACCESS_FINE_LOCATION); 10851 10852 verifyOwnerUidAndTransportInfoNetCapsPermissionPreS(); 10853 } 10854 10855 @Test 10856 public void 10857 testCreateWithLocationInfoSanitizedWithFineLocationAfterSWithAndWithoutCallbackFlag() 10858 throws Exception { 10859 setupLocationPermissions(Build.VERSION_CODES.S, true, AppOpsManager.OPSTR_FINE_LOCATION, 10860 Manifest.permission.ACCESS_FINE_LOCATION); 10861 10862 verifyOwnerUidAndTransportInfoNetCapsPermission( 10863 // Ensure that the owner UID is removed if the request asks us to remove it even 10864 // if the app has necessary permissions since targetSdk >= S. 10865 false, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */ 10866 true, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */ 10867 // Ensure that location info is removed if the request asks to remove it even if the 10868 // app has necessary permissions. 10869 false, /* shouldInclLocationSensitiveTransportInfoWithoutIncludeFlag */ 10870 true /* shouldInclLocationSensitiveTransportInfoWithIncludeFlag */ 10871 ); 10872 } 10873 10874 @Test 10875 public void testCreateWithLocationInfoSanitizedWithCoarseLocationPreQ() 10876 throws Exception { 10877 setupLocationPermissions(Build.VERSION_CODES.P, true, AppOpsManager.OPSTR_COARSE_LOCATION, 10878 Manifest.permission.ACCESS_COARSE_LOCATION); 10879 10880 verifyOwnerUidAndTransportInfoNetCapsPermissionPreS(); 10881 } 10882 10883 private void verifyOwnerUidAndTransportInfoNetCapsNotIncluded() { 10884 verifyOwnerUidAndTransportInfoNetCapsPermission( 10885 false, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */ 10886 false, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */ 10887 false, /* shouldInclLocationSensitiveTransportInfoWithoutIncludeFlag */ 10888 false /* shouldInclLocationSensitiveTransportInfoWithIncludeFlag */ 10889 ); 10890 } 10891 10892 @Test 10893 public void testCreateWithLocationInfoSanitizedLocationOff() throws Exception { 10894 // Test that even with fine location permission, and UIDs matching, the UID is sanitized. 10895 setupLocationPermissions(Build.VERSION_CODES.Q, false, AppOpsManager.OPSTR_FINE_LOCATION, 10896 Manifest.permission.ACCESS_FINE_LOCATION); 10897 10898 verifyOwnerUidAndTransportInfoNetCapsNotIncluded(); 10899 } 10900 10901 @Test 10902 public void testCreateWithLocationInfoSanitizedWrongUid() throws Exception { 10903 // Test that even with fine location permission, not being the owner leads to sanitization. 10904 setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION, 10905 Manifest.permission.ACCESS_FINE_LOCATION); 10906 10907 final int myUid = Process.myUid(); 10908 assertEquals(Process.INVALID_UID, 10909 getOwnerUidNetCapsPermission(myUid + 1, myUid, 10910 true /* includeLocationSensitiveInfo */)); 10911 } 10912 10913 @Test 10914 public void testCreateWithLocationInfoSanitizedWithCoarseLocationAfterQ() 10915 throws Exception { 10916 // Test that not having fine location permission leads to sanitization. 10917 setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_COARSE_LOCATION, 10918 Manifest.permission.ACCESS_COARSE_LOCATION); 10919 10920 verifyOwnerUidAndTransportInfoNetCapsNotIncluded(); 10921 } 10922 10923 @Test 10924 public void testCreateWithLocationInfoSanitizedWithCoarseLocationAfterS() 10925 throws Exception { 10926 // Test that not having fine location permission leads to sanitization. 10927 setupLocationPermissions(Build.VERSION_CODES.S, true, AppOpsManager.OPSTR_COARSE_LOCATION, 10928 Manifest.permission.ACCESS_COARSE_LOCATION); 10929 10930 verifyOwnerUidAndTransportInfoNetCapsNotIncluded(); 10931 } 10932 10933 @Test 10934 public void testCreateForCallerWithLocalMacAddressSanitizedWithLocalMacAddressPermission() 10935 throws Exception { 10936 mServiceContext.setPermission(Manifest.permission.LOCAL_MAC_ADDRESS, PERMISSION_GRANTED); 10937 10938 final TransportInfo transportInfo = mock(TransportInfo.class); 10939 doReturn(REDACT_FOR_ACCESS_FINE_LOCATION | REDACT_FOR_LOCAL_MAC_ADDRESS) 10940 .when(transportInfo).getApplicableRedactions(); 10941 final NetworkCapabilities netCap = 10942 new NetworkCapabilities().setTransportInfo(transportInfo); 10943 10944 mService.createWithLocationInfoSanitizedIfNecessaryWhenParceled( 10945 netCap, false /* includeLocationSensitiveInfoInTransportInfo */, 10946 Process.myPid(), Process.myUid(), 10947 mContext.getPackageName(), getAttributionTag()); 10948 // don't redact MAC_ADDRESS fields, only location sensitive fields. 10949 verify(transportInfo).makeCopy(REDACT_FOR_ACCESS_FINE_LOCATION); 10950 } 10951 10952 @Test 10953 public void testCreateForCallerWithLocalMacAddressSanitizedWithoutLocalMacAddressPermission() 10954 throws Exception { 10955 mServiceContext.setPermission(Manifest.permission.LOCAL_MAC_ADDRESS, PERMISSION_DENIED); 10956 10957 final TransportInfo transportInfo = mock(TransportInfo.class); 10958 doReturn(REDACT_FOR_ACCESS_FINE_LOCATION | REDACT_FOR_LOCAL_MAC_ADDRESS) 10959 .when(transportInfo).getApplicableRedactions(); 10960 final NetworkCapabilities netCap = 10961 new NetworkCapabilities().setTransportInfo(transportInfo); 10962 10963 mService.createWithLocationInfoSanitizedIfNecessaryWhenParceled( 10964 netCap, false /* includeLocationSensitiveInfoInTransportInfo */, 10965 Process.myPid(), Process.myUid(), 10966 mContext.getPackageName(), getAttributionTag()); 10967 // redact both MAC_ADDRESS & location sensitive fields. 10968 verify(transportInfo).makeCopy(REDACT_FOR_ACCESS_FINE_LOCATION 10969 | REDACT_FOR_LOCAL_MAC_ADDRESS); 10970 } 10971 10972 @Test 10973 public void testCreateForCallerWithLocalMacAddressSanitizedWithSettingsPermission() 10974 throws Exception { 10975 mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_GRANTED); 10976 10977 final TransportInfo transportInfo = mock(TransportInfo.class); 10978 doReturn(REDACT_FOR_ACCESS_FINE_LOCATION | REDACT_FOR_NETWORK_SETTINGS) 10979 .when(transportInfo).getApplicableRedactions(); 10980 final NetworkCapabilities netCap = 10981 new NetworkCapabilities().setTransportInfo(transportInfo); 10982 10983 mService.createWithLocationInfoSanitizedIfNecessaryWhenParceled( 10984 netCap, false /* includeLocationSensitiveInfoInTransportInfo */, 10985 Process.myPid(), Process.myUid(), 10986 mContext.getPackageName(), getAttributionTag()); 10987 // don't redact NETWORK_SETTINGS fields, only location sensitive fields. 10988 verify(transportInfo).makeCopy(REDACT_FOR_ACCESS_FINE_LOCATION); 10989 } 10990 10991 @Test 10992 public void testCreateForCallerWithLocalMacAddressSanitizedWithoutSettingsPermission() 10993 throws Exception { 10994 mServiceContext.setPermission(Manifest.permission.LOCAL_MAC_ADDRESS, PERMISSION_DENIED); 10995 10996 final TransportInfo transportInfo = mock(TransportInfo.class); 10997 doReturn(REDACT_FOR_ACCESS_FINE_LOCATION | REDACT_FOR_NETWORK_SETTINGS) 10998 .when(transportInfo).getApplicableRedactions(); 10999 final NetworkCapabilities netCap = 11000 new NetworkCapabilities().setTransportInfo(transportInfo); 11001 11002 mService.createWithLocationInfoSanitizedIfNecessaryWhenParceled( 11003 netCap, false /* includeLocationSensitiveInfoInTransportInfo */, 11004 Process.myPid(), Process.myUid(), 11005 mContext.getPackageName(), getAttributionTag()); 11006 // redact both NETWORK_SETTINGS & location sensitive fields. 11007 verify(transportInfo).makeCopy( 11008 REDACT_FOR_ACCESS_FINE_LOCATION | REDACT_FOR_NETWORK_SETTINGS); 11009 } 11010 11011 /** 11012 * Test TransportInfo to verify redaction mechanism. 11013 */ 11014 private static class TestTransportInfo implements TransportInfo { 11015 public final boolean locationRedacted; 11016 public final boolean localMacAddressRedacted; 11017 public final boolean settingsRedacted; 11018 11019 TestTransportInfo() { 11020 locationRedacted = false; 11021 localMacAddressRedacted = false; 11022 settingsRedacted = false; 11023 } 11024 11025 TestTransportInfo(boolean locationRedacted, boolean localMacAddressRedacted, 11026 boolean settingsRedacted) { 11027 this.locationRedacted = locationRedacted; 11028 this.localMacAddressRedacted = 11029 localMacAddressRedacted; 11030 this.settingsRedacted = settingsRedacted; 11031 } 11032 11033 @Override 11034 public TransportInfo makeCopy(@NetworkCapabilities.RedactionType long redactions) { 11035 return new TestTransportInfo( 11036 locationRedacted | (redactions & REDACT_FOR_ACCESS_FINE_LOCATION) != 0, 11037 localMacAddressRedacted | (redactions & REDACT_FOR_LOCAL_MAC_ADDRESS) != 0, 11038 settingsRedacted | (redactions & REDACT_FOR_NETWORK_SETTINGS) != 0 11039 ); 11040 } 11041 11042 @Override 11043 public @NetworkCapabilities.RedactionType long getApplicableRedactions() { 11044 return REDACT_FOR_ACCESS_FINE_LOCATION | REDACT_FOR_LOCAL_MAC_ADDRESS 11045 | REDACT_FOR_NETWORK_SETTINGS; 11046 } 11047 11048 @Override 11049 public boolean equals(Object other) { 11050 if (!(other instanceof TestTransportInfo)) return false; 11051 TestTransportInfo that = (TestTransportInfo) other; 11052 return that.locationRedacted == this.locationRedacted 11053 && that.localMacAddressRedacted == this.localMacAddressRedacted 11054 && that.settingsRedacted == this.settingsRedacted; 11055 } 11056 11057 @Override 11058 public int hashCode() { 11059 return Objects.hash(locationRedacted, localMacAddressRedacted, settingsRedacted); 11060 } 11061 11062 @Override 11063 public String toString() { 11064 return String.format( 11065 "TestTransportInfo{locationRedacted=%s macRedacted=%s settingsRedacted=%s}", 11066 locationRedacted, localMacAddressRedacted, settingsRedacted); 11067 } 11068 } 11069 11070 private TestTransportInfo getTestTransportInfo(NetworkCapabilities nc) { 11071 return (TestTransportInfo) nc.getTransportInfo(); 11072 } 11073 11074 private TestTransportInfo getTestTransportInfo(TestNetworkAgentWrapper n) { 11075 final NetworkCapabilities nc = mCm.getNetworkCapabilities(n.getNetwork()); 11076 assertNotNull(nc); 11077 return getTestTransportInfo(nc); 11078 } 11079 11080 11081 private void verifyNetworkCallbackLocationDataInclusionUsingTransportInfoAndOwnerUidInNetCaps( 11082 @NonNull TestNetworkCallback wifiNetworkCallback, int actualOwnerUid, 11083 @NonNull TransportInfo actualTransportInfo, int expectedOwnerUid, 11084 @NonNull TransportInfo expectedTransportInfo) throws Exception { 11085 doReturn(Build.VERSION_CODES.S).when(mPackageManager).getTargetSdkVersion(anyString()); 11086 final NetworkCapabilities ncTemplate = 11087 new NetworkCapabilities() 11088 .addTransportType(TRANSPORT_WIFI) 11089 .setOwnerUid(actualOwnerUid); 11090 11091 final NetworkRequest wifiRequest = new NetworkRequest.Builder() 11092 .addTransportType(TRANSPORT_WIFI).build(); 11093 mCm.registerNetworkCallback(wifiRequest, wifiNetworkCallback); 11094 11095 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, new LinkProperties(), 11096 ncTemplate); 11097 mWiFiNetworkAgent.connect(false); 11098 11099 wifiNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 11100 11101 // Send network capabilities update with TransportInfo to trigger capabilities changed 11102 // callback. 11103 mWiFiNetworkAgent.setNetworkCapabilities( 11104 ncTemplate.setTransportInfo(actualTransportInfo), true); 11105 11106 wifiNetworkCallback.expectCapabilitiesThat(mWiFiNetworkAgent, 11107 nc -> Objects.equals(expectedOwnerUid, nc.getOwnerUid()) 11108 && Objects.equals(expectedTransportInfo, nc.getTransportInfo())); 11109 } 11110 11111 @Test 11112 public void testVerifyLocationDataIsNotIncludedWhenInclFlagNotSet() throws Exception { 11113 final TestNetworkCallback wifiNetworkCallack = new TestNetworkCallback(); 11114 final int ownerUid = Process.myUid(); 11115 final TransportInfo transportInfo = new TestTransportInfo(); 11116 // Even though the test uid holds privileged permissions, mask location fields since 11117 // the callback did not explicitly opt-in to get location data. 11118 final TransportInfo sanitizedTransportInfo = new TestTransportInfo( 11119 true, /* locationRedacted */ 11120 true, /* localMacAddressRedacted */ 11121 true /* settingsRedacted */ 11122 ); 11123 // Should not expect location data since the callback does not set the flag for including 11124 // location data. 11125 verifyNetworkCallbackLocationDataInclusionUsingTransportInfoAndOwnerUidInNetCaps( 11126 wifiNetworkCallack, ownerUid, transportInfo, INVALID_UID, sanitizedTransportInfo); 11127 } 11128 11129 @Test 11130 public void testTransportInfoRedactionInSynchronousCalls() throws Exception { 11131 final NetworkCapabilities ncTemplate = new NetworkCapabilities() 11132 .addTransportType(TRANSPORT_WIFI) 11133 .setTransportInfo(new TestTransportInfo()); 11134 11135 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, new LinkProperties(), 11136 ncTemplate); 11137 mWiFiNetworkAgent.connect(true /* validated; waits for callback */); 11138 11139 // NETWORK_SETTINGS redaction is controlled by the NETWORK_SETTINGS permission 11140 assertTrue(getTestTransportInfo(mWiFiNetworkAgent).settingsRedacted); 11141 withPermission(NETWORK_SETTINGS, () -> { 11142 assertFalse(getTestTransportInfo(mWiFiNetworkAgent).settingsRedacted); 11143 }); 11144 assertTrue(getTestTransportInfo(mWiFiNetworkAgent).settingsRedacted); 11145 11146 // LOCAL_MAC_ADDRESS redaction is controlled by the LOCAL_MAC_ADDRESS permission 11147 assertTrue(getTestTransportInfo(mWiFiNetworkAgent).localMacAddressRedacted); 11148 withPermission(LOCAL_MAC_ADDRESS, () -> { 11149 assertFalse(getTestTransportInfo(mWiFiNetworkAgent).localMacAddressRedacted); 11150 }); 11151 assertTrue(getTestTransportInfo(mWiFiNetworkAgent).localMacAddressRedacted); 11152 11153 // Synchronous getNetworkCapabilities calls never return unredacted location-sensitive 11154 // information. 11155 assertTrue(getTestTransportInfo(mWiFiNetworkAgent).locationRedacted); 11156 setupLocationPermissions(Build.VERSION_CODES.S, true, AppOpsManager.OPSTR_FINE_LOCATION, 11157 Manifest.permission.ACCESS_FINE_LOCATION); 11158 assertTrue(getTestTransportInfo(mWiFiNetworkAgent).locationRedacted); 11159 denyAllLocationPrivilegedPermissions(); 11160 assertTrue(getTestTransportInfo(mWiFiNetworkAgent).locationRedacted); 11161 } 11162 11163 private void setupConnectionOwnerUid(int vpnOwnerUid, @VpnManager.VpnType int vpnType) 11164 throws Exception { 11165 final Set<UidRange> vpnRange = Collections.singleton(PRIMARY_UIDRANGE); 11166 mMockVpn.setVpnType(vpnType); 11167 mMockVpn.establish(new LinkProperties(), vpnOwnerUid, vpnRange); 11168 assertVpnUidRangesUpdated(true, vpnRange, vpnOwnerUid); 11169 11170 final UnderlyingNetworkInfo underlyingNetworkInfo = 11171 new UnderlyingNetworkInfo(vpnOwnerUid, VPN_IFNAME, new ArrayList<>()); 11172 mMockVpn.setUnderlyingNetworkInfo(underlyingNetworkInfo); 11173 mDeps.setConnectionOwnerUid(42); 11174 } 11175 11176 private void setupConnectionOwnerUidAsVpnApp(int vpnOwnerUid, @VpnManager.VpnType int vpnType) 11177 throws Exception { 11178 setupConnectionOwnerUid(vpnOwnerUid, vpnType); 11179 11180 // Test as VPN app 11181 mServiceContext.setPermission(NETWORK_STACK, PERMISSION_DENIED); 11182 mServiceContext.setPermission( 11183 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, PERMISSION_DENIED); 11184 } 11185 11186 private ConnectionInfo getTestConnectionInfo() throws Exception { 11187 return new ConnectionInfo( 11188 IPPROTO_TCP, 11189 new InetSocketAddress(InetAddresses.parseNumericAddress("1.2.3.4"), 1234), 11190 new InetSocketAddress(InetAddresses.parseNumericAddress("2.3.4.5"), 2345)); 11191 } 11192 11193 @Test 11194 public void testGetConnectionOwnerUidPlatformVpn() throws Exception { 11195 final int myUid = Process.myUid(); 11196 setupConnectionOwnerUidAsVpnApp(myUid, VpnManager.TYPE_VPN_PLATFORM); 11197 11198 assertEquals(INVALID_UID, mService.getConnectionOwnerUid(getTestConnectionInfo())); 11199 } 11200 11201 @Test 11202 public void testGetConnectionOwnerUidVpnServiceWrongUser() throws Exception { 11203 final int myUid = Process.myUid(); 11204 setupConnectionOwnerUidAsVpnApp(myUid + 1, VpnManager.TYPE_VPN_SERVICE); 11205 11206 assertEquals(INVALID_UID, mService.getConnectionOwnerUid(getTestConnectionInfo())); 11207 } 11208 11209 @Test 11210 public void testGetConnectionOwnerUidVpnServiceDoesNotThrow() throws Exception { 11211 final int myUid = Process.myUid(); 11212 setupConnectionOwnerUidAsVpnApp(myUid, VpnManager.TYPE_VPN_SERVICE); 11213 11214 assertEquals(42, mService.getConnectionOwnerUid(getTestConnectionInfo())); 11215 } 11216 11217 @Test 11218 public void testGetConnectionOwnerUidVpnServiceNetworkStackDoesNotThrow() throws Exception { 11219 final int myUid = Process.myUid(); 11220 setupConnectionOwnerUid(myUid, VpnManager.TYPE_VPN_SERVICE); 11221 mServiceContext.setPermission(NETWORK_STACK, PERMISSION_GRANTED); 11222 11223 assertEquals(42, mService.getConnectionOwnerUid(getTestConnectionInfo())); 11224 } 11225 11226 @Test 11227 public void testGetConnectionOwnerUidVpnServiceMainlineNetworkStackDoesNotThrow() 11228 throws Exception { 11229 final int myUid = Process.myUid(); 11230 setupConnectionOwnerUid(myUid, VpnManager.TYPE_VPN_SERVICE); 11231 mServiceContext.setPermission( 11232 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, PERMISSION_GRANTED); 11233 11234 assertEquals(42, mService.getConnectionOwnerUid(getTestConnectionInfo())); 11235 } 11236 11237 private static PackageInfo buildPackageInfo(boolean hasSystemPermission, int uid) { 11238 final PackageInfo packageInfo = new PackageInfo(); 11239 if (hasSystemPermission) { 11240 packageInfo.requestedPermissions = new String[] { 11241 CHANGE_NETWORK_STATE, CONNECTIVITY_USE_RESTRICTED_NETWORKS }; 11242 packageInfo.requestedPermissionsFlags = new int[] { 11243 REQUESTED_PERMISSION_GRANTED, REQUESTED_PERMISSION_GRANTED }; 11244 } else { 11245 packageInfo.requestedPermissions = new String[0]; 11246 } 11247 packageInfo.applicationInfo = new ApplicationInfo(); 11248 packageInfo.applicationInfo.privateFlags = 0; 11249 packageInfo.applicationInfo.uid = UserHandle.getUid(UserHandle.USER_SYSTEM, 11250 UserHandle.getAppId(uid)); 11251 return packageInfo; 11252 } 11253 11254 @Test 11255 public void testRegisterConnectivityDiagnosticsCallbackInvalidRequest() throws Exception { 11256 final NetworkRequest request = 11257 new NetworkRequest( 11258 new NetworkCapabilities(), TYPE_ETHERNET, 0, NetworkRequest.Type.NONE); 11259 try { 11260 mService.registerConnectivityDiagnosticsCallback( 11261 mConnectivityDiagnosticsCallback, request, mContext.getPackageName()); 11262 fail("registerConnectivityDiagnosticsCallback should throw on invalid NetworkRequest"); 11263 } catch (IllegalArgumentException expected) { 11264 } 11265 } 11266 11267 private void assertRouteInfoParcelMatches(RouteInfo route, RouteInfoParcel parcel) { 11268 assertEquals(route.getDestination().toString(), parcel.destination); 11269 assertEquals(route.getInterface(), parcel.ifName); 11270 assertEquals(route.getMtu(), parcel.mtu); 11271 11272 switch (route.getType()) { 11273 case RouteInfo.RTN_UNICAST: 11274 if (route.hasGateway()) { 11275 assertEquals(route.getGateway().getHostAddress(), parcel.nextHop); 11276 } else { 11277 assertEquals(INetd.NEXTHOP_NONE, parcel.nextHop); 11278 } 11279 break; 11280 case RouteInfo.RTN_UNREACHABLE: 11281 assertEquals(INetd.NEXTHOP_UNREACHABLE, parcel.nextHop); 11282 break; 11283 case RouteInfo.RTN_THROW: 11284 assertEquals(INetd.NEXTHOP_THROW, parcel.nextHop); 11285 break; 11286 default: 11287 assertEquals(INetd.NEXTHOP_NONE, parcel.nextHop); 11288 break; 11289 } 11290 } 11291 11292 private void assertRoutesAdded(int netId, RouteInfo... routes) throws Exception { 11293 // TODO: add @JavaDerive(equals=true) to RouteInfoParcel, use eq() directly, and delete 11294 // assertRouteInfoParcelMatches above. 11295 ArgumentCaptor<RouteInfoParcel> captor = ArgumentCaptor.forClass(RouteInfoParcel.class); 11296 verify(mMockNetd, times(routes.length)).networkAddRouteParcel(eq(netId), captor.capture()); 11297 for (int i = 0; i < routes.length; i++) { 11298 assertRouteInfoParcelMatches(routes[i], captor.getAllValues().get(i)); 11299 } 11300 } 11301 11302 private void assertRoutesRemoved(int netId, RouteInfo... routes) throws Exception { 11303 ArgumentCaptor<RouteInfoParcel> captor = ArgumentCaptor.forClass(RouteInfoParcel.class); 11304 verify(mMockNetd, times(routes.length)).networkRemoveRouteParcel(eq(netId), 11305 captor.capture()); 11306 for (int i = 0; i < routes.length; i++) { 11307 assertRouteInfoParcelMatches(routes[i], captor.getAllValues().get(i)); 11308 } 11309 } 11310 11311 @Test 11312 public void testRegisterUnregisterConnectivityDiagnosticsCallback() throws Exception { 11313 final NetworkRequest wifiRequest = 11314 new NetworkRequest.Builder().addTransportType(TRANSPORT_WIFI).build(); 11315 doReturn(mIBinder).when(mConnectivityDiagnosticsCallback).asBinder(); 11316 11317 mService.registerConnectivityDiagnosticsCallback( 11318 mConnectivityDiagnosticsCallback, wifiRequest, mContext.getPackageName()); 11319 11320 // Block until all other events are done processing. 11321 HandlerUtils.waitForIdle(mCsHandlerThread, TIMEOUT_MS); 11322 11323 verify(mIBinder).linkToDeath(any(ConnectivityDiagnosticsCallbackInfo.class), anyInt()); 11324 verify(mConnectivityDiagnosticsCallback).asBinder(); 11325 assertTrue(mService.mConnectivityDiagnosticsCallbacks.containsKey(mIBinder)); 11326 11327 mService.unregisterConnectivityDiagnosticsCallback(mConnectivityDiagnosticsCallback); 11328 verify(mIBinder, timeout(TIMEOUT_MS)) 11329 .unlinkToDeath(any(ConnectivityDiagnosticsCallbackInfo.class), anyInt()); 11330 assertFalse(mService.mConnectivityDiagnosticsCallbacks.containsKey(mIBinder)); 11331 verify(mConnectivityDiagnosticsCallback, atLeastOnce()).asBinder(); 11332 } 11333 11334 @Test 11335 public void testRegisterDuplicateConnectivityDiagnosticsCallback() throws Exception { 11336 final NetworkRequest wifiRequest = 11337 new NetworkRequest.Builder().addTransportType(TRANSPORT_WIFI).build(); 11338 doReturn(mIBinder).when(mConnectivityDiagnosticsCallback).asBinder(); 11339 11340 mService.registerConnectivityDiagnosticsCallback( 11341 mConnectivityDiagnosticsCallback, wifiRequest, mContext.getPackageName()); 11342 11343 // Block until all other events are done processing. 11344 HandlerUtils.waitForIdle(mCsHandlerThread, TIMEOUT_MS); 11345 11346 verify(mIBinder).linkToDeath(any(ConnectivityDiagnosticsCallbackInfo.class), anyInt()); 11347 verify(mConnectivityDiagnosticsCallback).asBinder(); 11348 assertTrue(mService.mConnectivityDiagnosticsCallbacks.containsKey(mIBinder)); 11349 11350 // Register the same callback again 11351 mService.registerConnectivityDiagnosticsCallback( 11352 mConnectivityDiagnosticsCallback, wifiRequest, mContext.getPackageName()); 11353 11354 // Block until all other events are done processing. 11355 HandlerUtils.waitForIdle(mCsHandlerThread, TIMEOUT_MS); 11356 11357 assertTrue(mService.mConnectivityDiagnosticsCallbacks.containsKey(mIBinder)); 11358 } 11359 11360 @Test(expected = NullPointerException.class) 11361 public void testRegisterConnectivityDiagnosticsCallbackNullCallback() { 11362 mService.registerConnectivityDiagnosticsCallback( 11363 null /* callback */, 11364 new NetworkRequest.Builder().build(), 11365 mContext.getPackageName()); 11366 } 11367 11368 @Test(expected = NullPointerException.class) 11369 public void testRegisterConnectivityDiagnosticsCallbackNullNetworkRequest() { 11370 mService.registerConnectivityDiagnosticsCallback( 11371 mConnectivityDiagnosticsCallback, 11372 null /* request */, 11373 mContext.getPackageName()); 11374 } 11375 11376 @Test(expected = NullPointerException.class) 11377 public void testRegisterConnectivityDiagnosticsCallbackNullPackageName() { 11378 mService.registerConnectivityDiagnosticsCallback( 11379 mConnectivityDiagnosticsCallback, 11380 new NetworkRequest.Builder().build(), 11381 null /* callingPackageName */); 11382 } 11383 11384 @Test(expected = NullPointerException.class) 11385 public void testUnregisterConnectivityDiagnosticsCallbackNullPackageName() { 11386 mService.unregisterConnectivityDiagnosticsCallback(null /* callback */); 11387 } 11388 11389 public NetworkAgentInfo fakeMobileNai(NetworkCapabilities nc) { 11390 final NetworkCapabilities cellNc = new NetworkCapabilities.Builder(nc) 11391 .addTransportType(TRANSPORT_CELLULAR).build(); 11392 final NetworkInfo info = new NetworkInfo(TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_LTE, 11393 ConnectivityManager.getNetworkTypeName(TYPE_MOBILE), 11394 TelephonyManager.getNetworkTypeName(TelephonyManager.NETWORK_TYPE_LTE)); 11395 return fakeNai(cellNc, info); 11396 } 11397 11398 private NetworkAgentInfo fakeWifiNai(NetworkCapabilities nc) { 11399 final NetworkCapabilities wifiNc = new NetworkCapabilities.Builder(nc) 11400 .addTransportType(TRANSPORT_WIFI).build(); 11401 final NetworkInfo info = new NetworkInfo(TYPE_WIFI, 0 /* subtype */, 11402 ConnectivityManager.getNetworkTypeName(TYPE_WIFI), "" /* subtypeName */); 11403 return fakeNai(wifiNc, info); 11404 } 11405 11406 private NetworkAgentInfo fakeVpnNai(NetworkCapabilities nc) { 11407 final NetworkCapabilities vpnNc = new NetworkCapabilities.Builder(nc) 11408 .addTransportType(TRANSPORT_VPN).build(); 11409 final NetworkInfo info = new NetworkInfo(TYPE_VPN, 0 /* subtype */, 11410 ConnectivityManager.getNetworkTypeName(TYPE_VPN), "" /* subtypeName */); 11411 return fakeNai(vpnNc, info); 11412 } 11413 11414 private NetworkAgentInfo fakeNai(NetworkCapabilities nc, NetworkInfo networkInfo) { 11415 return new NetworkAgentInfo(null, new Network(NET_ID), networkInfo, new LinkProperties(), 11416 nc, new NetworkScore.Builder().setLegacyInt(0).build(), 11417 mServiceContext, null, new NetworkAgentConfig(), mService, null, null, 0, 11418 INVALID_UID, TEST_LINGER_DELAY_MS, mQosCallbackTracker, 11419 new ConnectivityService.Dependencies()); 11420 } 11421 11422 @Test 11423 public void testCheckConnectivityDiagnosticsPermissionsNetworkStack() throws Exception { 11424 final NetworkAgentInfo naiWithoutUid = fakeMobileNai(new NetworkCapabilities()); 11425 11426 mServiceContext.setPermission(NETWORK_STACK, PERMISSION_GRANTED); 11427 assertTrue( 11428 "NetworkStack permission not applied", 11429 mService.checkConnectivityDiagnosticsPermissions( 11430 Process.myPid(), Process.myUid(), naiWithoutUid, 11431 mContext.getOpPackageName())); 11432 } 11433 11434 @Test 11435 public void testCheckConnectivityDiagnosticsPermissionsWrongUidPackageName() throws Exception { 11436 final int wrongUid = Process.myUid() + 1; 11437 11438 final NetworkCapabilities nc = new NetworkCapabilities(); 11439 nc.setAdministratorUids(new int[] {wrongUid}); 11440 final NetworkAgentInfo naiWithUid = fakeWifiNai(nc); 11441 11442 mServiceContext.setPermission(NETWORK_STACK, PERMISSION_DENIED); 11443 11444 assertFalse( 11445 "Mismatched uid/package name should not pass the location permission check", 11446 mService.checkConnectivityDiagnosticsPermissions( 11447 Process.myPid() + 1, wrongUid, naiWithUid, mContext.getOpPackageName())); 11448 } 11449 11450 private void verifyConnectivityDiagnosticsPermissionsWithNetworkAgentInfo( 11451 NetworkAgentInfo info, boolean expectPermission) { 11452 mServiceContext.setPermission(NETWORK_STACK, PERMISSION_DENIED); 11453 11454 assertEquals( 11455 "Unexpected ConnDiags permission", 11456 expectPermission, 11457 mService.checkConnectivityDiagnosticsPermissions( 11458 Process.myPid(), Process.myUid(), info, mContext.getOpPackageName())); 11459 } 11460 11461 @Test 11462 public void testCheckConnectivityDiagnosticsPermissionsCellularNoLocationPermission() 11463 throws Exception { 11464 final NetworkCapabilities nc = new NetworkCapabilities(); 11465 nc.setAdministratorUids(new int[] {Process.myUid()}); 11466 final NetworkAgentInfo naiWithUid = fakeMobileNai(nc); 11467 11468 verifyConnectivityDiagnosticsPermissionsWithNetworkAgentInfo(naiWithUid, 11469 true /* expectPermission */); 11470 } 11471 11472 @Test 11473 public void testCheckConnectivityDiagnosticsPermissionsWifiNoLocationPermission() 11474 throws Exception { 11475 final NetworkCapabilities nc = new NetworkCapabilities(); 11476 nc.setAdministratorUids(new int[] {Process.myUid()}); 11477 final NetworkAgentInfo naiWithUid = fakeWifiNai(nc); 11478 11479 verifyConnectivityDiagnosticsPermissionsWithNetworkAgentInfo(naiWithUid, 11480 false /* expectPermission */); 11481 } 11482 11483 @Test 11484 public void testCheckConnectivityDiagnosticsPermissionsActiveVpn() throws Exception { 11485 final NetworkAgentInfo naiWithoutUid = fakeMobileNai(new NetworkCapabilities()); 11486 11487 mMockVpn.establishForMyUid(); 11488 assertUidRangesUpdatedForMyUid(true); 11489 11490 // Wait for networks to connect and broadcasts to be sent before removing permissions. 11491 waitForIdle(); 11492 setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION, 11493 Manifest.permission.ACCESS_FINE_LOCATION); 11494 11495 assertTrue(mMockVpn.setUnderlyingNetworks(new Network[] {naiWithoutUid.network})); 11496 waitForIdle(); 11497 assertTrue( 11498 "Active VPN permission not applied", 11499 mService.checkConnectivityDiagnosticsPermissions( 11500 Process.myPid(), Process.myUid(), naiWithoutUid, 11501 mContext.getOpPackageName())); 11502 11503 assertTrue(mMockVpn.setUnderlyingNetworks(null)); 11504 waitForIdle(); 11505 assertFalse( 11506 "VPN shouldn't receive callback on non-underlying network", 11507 mService.checkConnectivityDiagnosticsPermissions( 11508 Process.myPid(), Process.myUid(), naiWithoutUid, 11509 mContext.getOpPackageName())); 11510 } 11511 11512 @Test 11513 public void testCheckConnectivityDiagnosticsPermissionsNetworkAdministrator() throws Exception { 11514 final NetworkCapabilities nc = new NetworkCapabilities(); 11515 nc.setAdministratorUids(new int[] {Process.myUid()}); 11516 final NetworkAgentInfo naiWithUid = fakeMobileNai(nc); 11517 11518 setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION, 11519 Manifest.permission.ACCESS_FINE_LOCATION); 11520 mServiceContext.setPermission(NETWORK_STACK, PERMISSION_DENIED); 11521 11522 assertTrue( 11523 "NetworkCapabilities administrator uid permission not applied", 11524 mService.checkConnectivityDiagnosticsPermissions( 11525 Process.myPid(), Process.myUid(), naiWithUid, mContext.getOpPackageName())); 11526 } 11527 11528 @Test 11529 public void testCheckConnectivityDiagnosticsPermissionsFails() throws Exception { 11530 final NetworkCapabilities nc = new NetworkCapabilities(); 11531 nc.setOwnerUid(Process.myUid()); 11532 nc.setAdministratorUids(new int[] {Process.myUid()}); 11533 final NetworkAgentInfo naiWithUid = fakeMobileNai(nc); 11534 11535 setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION, 11536 Manifest.permission.ACCESS_FINE_LOCATION); 11537 mServiceContext.setPermission(NETWORK_STACK, PERMISSION_DENIED); 11538 11539 // Use wrong pid and uid 11540 assertFalse( 11541 "Permissions allowed when they shouldn't be granted", 11542 mService.checkConnectivityDiagnosticsPermissions( 11543 Process.myPid() + 1, Process.myUid() + 1, naiWithUid, 11544 mContext.getOpPackageName())); 11545 } 11546 11547 @Test 11548 public void testUnderlyingNetworksWillBeSetInNetworkAgentInfoConstructor() throws Exception { 11549 assumeTrue(SdkLevel.isAtLeastT()); 11550 final Network network1 = new Network(100); 11551 final Network network2 = new Network(101); 11552 final List<Network> underlyingNetworks = new ArrayList<>(); 11553 final NetworkCapabilities ncWithEmptyUnderlyingNetworks = new NetworkCapabilities.Builder() 11554 .setUnderlyingNetworks(underlyingNetworks) 11555 .build(); 11556 final NetworkAgentInfo vpnNaiWithEmptyUnderlyingNetworks = 11557 fakeVpnNai(ncWithEmptyUnderlyingNetworks); 11558 assertEquals(underlyingNetworks, 11559 Arrays.asList(vpnNaiWithEmptyUnderlyingNetworks.declaredUnderlyingNetworks)); 11560 11561 underlyingNetworks.add(network1); 11562 underlyingNetworks.add(network2); 11563 final NetworkCapabilities ncWithUnderlyingNetworks = new NetworkCapabilities.Builder() 11564 .setUnderlyingNetworks(underlyingNetworks) 11565 .build(); 11566 final NetworkAgentInfo vpnNaiWithUnderlyingNetwokrs = fakeVpnNai(ncWithUnderlyingNetworks); 11567 assertEquals(underlyingNetworks, 11568 Arrays.asList(vpnNaiWithUnderlyingNetwokrs.declaredUnderlyingNetworks)); 11569 11570 final NetworkCapabilities ncWithoutUnderlyingNetworks = new NetworkCapabilities.Builder() 11571 .build(); 11572 final NetworkAgentInfo vpnNaiWithoutUnderlyingNetwokrs = 11573 fakeVpnNai(ncWithoutUnderlyingNetworks); 11574 assertNull(vpnNaiWithoutUnderlyingNetwokrs.declaredUnderlyingNetworks); 11575 } 11576 11577 @Test 11578 public void testRegisterConnectivityDiagnosticsCallbackCallsOnConnectivityReport() 11579 throws Exception { 11580 // Set up the Network, which leads to a ConnectivityReport being cached for the network. 11581 final TestNetworkCallback callback = new TestNetworkCallback(); 11582 mCm.registerDefaultNetworkCallback(callback); 11583 final LinkProperties linkProperties = new LinkProperties(); 11584 linkProperties.setInterfaceName(INTERFACE_NAME); 11585 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, linkProperties); 11586 mCellNetworkAgent.connect(true); 11587 callback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 11588 callback.assertNoCallback(); 11589 11590 final NetworkRequest request = new NetworkRequest.Builder().build(); 11591 doReturn(mIBinder).when(mConnectivityDiagnosticsCallback).asBinder(); 11592 11593 mServiceContext.setPermission(NETWORK_STACK, PERMISSION_GRANTED); 11594 11595 mService.registerConnectivityDiagnosticsCallback( 11596 mConnectivityDiagnosticsCallback, request, mContext.getPackageName()); 11597 11598 verify(mConnectivityDiagnosticsCallback, timeout(TIMEOUT_MS)) 11599 .onConnectivityReportAvailable(argThat(report -> { 11600 return INTERFACE_NAME.equals(report.getLinkProperties().getInterfaceName()) 11601 && report.getNetworkCapabilities().hasTransport(TRANSPORT_CELLULAR); 11602 })); 11603 } 11604 11605 private void setUpConnectivityDiagnosticsCallback() throws Exception { 11606 final NetworkRequest request = new NetworkRequest.Builder().build(); 11607 doReturn(mIBinder).when(mConnectivityDiagnosticsCallback).asBinder(); 11608 11609 mServiceContext.setPermission(NETWORK_STACK, PERMISSION_GRANTED); 11610 11611 mService.registerConnectivityDiagnosticsCallback( 11612 mConnectivityDiagnosticsCallback, request, mContext.getPackageName()); 11613 11614 // Block until all other events are done processing. 11615 HandlerUtils.waitForIdle(mCsHandlerThread, TIMEOUT_MS); 11616 11617 // Connect the cell agent verify that it notifies TestNetworkCallback that it is available 11618 final TestNetworkCallback callback = new TestNetworkCallback(); 11619 mCm.registerDefaultNetworkCallback(callback); 11620 11621 final NetworkCapabilities ncTemplate = new NetworkCapabilities() 11622 .addTransportType(TRANSPORT_CELLULAR) 11623 .setTransportInfo(new TestTransportInfo()); 11624 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, new LinkProperties(), 11625 ncTemplate); 11626 mCellNetworkAgent.connect(true); 11627 callback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 11628 callback.assertNoCallback(); 11629 11630 // Make sure a report is sent and that the caps are suitably redacted. 11631 verify(mConnectivityDiagnosticsCallback, timeout(TIMEOUT_MS)) 11632 .onConnectivityReportAvailable(argThat(report -> 11633 areConnDiagCapsRedacted(report.getNetworkCapabilities()))); 11634 reset(mConnectivityDiagnosticsCallback); 11635 } 11636 11637 private boolean areConnDiagCapsRedacted(NetworkCapabilities nc) { 11638 TestTransportInfo ti = getTestTransportInfo(nc); 11639 return nc.getUids() == null 11640 && nc.getAdministratorUids().length == 0 11641 && nc.getOwnerUid() == Process.INVALID_UID 11642 && ti.locationRedacted 11643 && ti.localMacAddressRedacted 11644 && ti.settingsRedacted; 11645 } 11646 11647 @Test 11648 public void testConnectivityDiagnosticsCallbackOnDataStallSuspected() throws Exception { 11649 setUpConnectivityDiagnosticsCallback(); 11650 11651 // Trigger notifyDataStallSuspected() on the INetworkMonitorCallbacks instance in the 11652 // cellular network agent 11653 mCellNetworkAgent.notifyDataStallSuspected(); 11654 11655 // Verify onDataStallSuspected fired 11656 verify(mConnectivityDiagnosticsCallback, timeout(TIMEOUT_MS)).onDataStallSuspected( 11657 argThat(report -> areConnDiagCapsRedacted(report.getNetworkCapabilities()))); 11658 } 11659 11660 @Test 11661 public void testConnectivityDiagnosticsCallbackOnConnectivityReported() throws Exception { 11662 setUpConnectivityDiagnosticsCallback(); 11663 11664 final Network n = mCellNetworkAgent.getNetwork(); 11665 final boolean hasConnectivity = true; 11666 mService.reportNetworkConnectivity(n, hasConnectivity); 11667 11668 // Verify onNetworkConnectivityReported fired 11669 verify(mConnectivityDiagnosticsCallback, timeout(TIMEOUT_MS)) 11670 .onNetworkConnectivityReported(eq(n), eq(hasConnectivity)); 11671 verify(mConnectivityDiagnosticsCallback, timeout(TIMEOUT_MS)) 11672 .onConnectivityReportAvailable( 11673 argThat(report -> 11674 areConnDiagCapsRedacted(report.getNetworkCapabilities()))); 11675 11676 final boolean noConnectivity = false; 11677 mService.reportNetworkConnectivity(n, noConnectivity); 11678 11679 // Wait for onNetworkConnectivityReported to fire 11680 verify(mConnectivityDiagnosticsCallback, timeout(TIMEOUT_MS)) 11681 .onNetworkConnectivityReported(eq(n), eq(noConnectivity)); 11682 11683 // Also expect a ConnectivityReport after NetworkMonitor asynchronously re-validates 11684 verify(mConnectivityDiagnosticsCallback, timeout(TIMEOUT_MS).times(2)) 11685 .onConnectivityReportAvailable( 11686 argThat(report -> 11687 areConnDiagCapsRedacted(report.getNetworkCapabilities()))); 11688 } 11689 11690 @Test 11691 public void testConnectivityDiagnosticsCallbackOnConnectivityReportedSeparateUid() 11692 throws Exception { 11693 setUpConnectivityDiagnosticsCallback(); 11694 11695 // report known Connectivity from a different uid. Verify that network is not re-validated 11696 // and this callback is not notified. 11697 final Network n = mCellNetworkAgent.getNetwork(); 11698 final boolean hasConnectivity = true; 11699 doAsUid(Process.myUid() + 1, () -> mService.reportNetworkConnectivity(n, hasConnectivity)); 11700 11701 // Block until all other events are done processing. 11702 HandlerUtils.waitForIdle(mCsHandlerThread, TIMEOUT_MS); 11703 11704 // Verify onNetworkConnectivityReported did not fire 11705 verify(mConnectivityDiagnosticsCallback, never()) 11706 .onNetworkConnectivityReported(any(), anyBoolean()); 11707 verify(mConnectivityDiagnosticsCallback, never()) 11708 .onConnectivityReportAvailable(any()); 11709 11710 // report different Connectivity from a different uid. Verify that network is re-validated 11711 // and that this callback is notified. 11712 final boolean noConnectivity = false; 11713 doAsUid(Process.myUid() + 1, () -> mService.reportNetworkConnectivity(n, noConnectivity)); 11714 11715 // Wait for onNetworkConnectivityReported to fire 11716 verify(mConnectivityDiagnosticsCallback, timeout(TIMEOUT_MS)) 11717 .onNetworkConnectivityReported(eq(n), eq(noConnectivity)); 11718 11719 // Also expect a ConnectivityReport after NetworkMonitor asynchronously re-validates 11720 verify(mConnectivityDiagnosticsCallback, timeout(TIMEOUT_MS)) 11721 .onConnectivityReportAvailable( 11722 argThat(report -> 11723 areConnDiagCapsRedacted(report.getNetworkCapabilities()))); 11724 } 11725 11726 @Test(expected = NullPointerException.class) 11727 public void testSimulateDataStallNullNetwork() { 11728 mService.simulateDataStall( 11729 DataStallReport.DETECTION_METHOD_DNS_EVENTS, 11730 0L /* timestampMillis */, 11731 null /* network */, 11732 new PersistableBundle()); 11733 } 11734 11735 @Test(expected = NullPointerException.class) 11736 public void testSimulateDataStallNullPersistableBundle() { 11737 mService.simulateDataStall( 11738 DataStallReport.DETECTION_METHOD_DNS_EVENTS, 11739 0L /* timestampMillis */, 11740 mock(Network.class), 11741 null /* extras */); 11742 } 11743 11744 @Test 11745 public void testRouteAddDeleteUpdate() throws Exception { 11746 final NetworkRequest request = new NetworkRequest.Builder().build(); 11747 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 11748 mCm.registerNetworkCallback(request, networkCallback); 11749 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 11750 reset(mMockNetd); 11751 mCellNetworkAgent.connect(false); 11752 networkCallback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent); 11753 final int netId = mCellNetworkAgent.getNetwork().netId; 11754 11755 final String iface = "rmnet_data0"; 11756 final InetAddress gateway = InetAddress.getByName("fe80::5678"); 11757 RouteInfo direct = RouteInfo.makeHostRoute(gateway, iface); 11758 RouteInfo rio1 = new RouteInfo(new IpPrefix("2001:db8:1::/48"), gateway, iface); 11759 RouteInfo rio2 = new RouteInfo(new IpPrefix("2001:db8:2::/48"), gateway, iface); 11760 RouteInfo defaultRoute = new RouteInfo((IpPrefix) null, gateway, iface); 11761 RouteInfo defaultWithMtu = new RouteInfo(null, gateway, iface, RouteInfo.RTN_UNICAST, 11762 1280 /* mtu */); 11763 11764 // Send LinkProperties and check that we ask netd to add routes. 11765 LinkProperties lp = new LinkProperties(); 11766 lp.setInterfaceName(iface); 11767 lp.addRoute(direct); 11768 lp.addRoute(rio1); 11769 lp.addRoute(defaultRoute); 11770 mCellNetworkAgent.sendLinkProperties(lp); 11771 networkCallback.expectLinkPropertiesThat(mCellNetworkAgent, x -> x.getRoutes().size() == 3); 11772 11773 assertRoutesAdded(netId, direct, rio1, defaultRoute); 11774 reset(mMockNetd); 11775 11776 // Send updated LinkProperties and check that we ask netd to add, remove, update routes. 11777 assertTrue(lp.getRoutes().contains(defaultRoute)); 11778 lp.removeRoute(rio1); 11779 lp.addRoute(rio2); 11780 lp.addRoute(defaultWithMtu); 11781 // Ensure adding the same route with a different MTU replaces the previous route. 11782 assertFalse(lp.getRoutes().contains(defaultRoute)); 11783 assertTrue(lp.getRoutes().contains(defaultWithMtu)); 11784 11785 mCellNetworkAgent.sendLinkProperties(lp); 11786 networkCallback.expectLinkPropertiesThat(mCellNetworkAgent, 11787 x -> x.getRoutes().contains(rio2)); 11788 11789 assertRoutesRemoved(netId, rio1); 11790 assertRoutesAdded(netId, rio2); 11791 11792 ArgumentCaptor<RouteInfoParcel> captor = ArgumentCaptor.forClass(RouteInfoParcel.class); 11793 verify(mMockNetd).networkUpdateRouteParcel(eq(netId), captor.capture()); 11794 assertRouteInfoParcelMatches(defaultWithMtu, captor.getValue()); 11795 11796 11797 mCm.unregisterNetworkCallback(networkCallback); 11798 } 11799 11800 @Test 11801 public void testDumpDoesNotCrash() { 11802 mServiceContext.setPermission(DUMP, PERMISSION_GRANTED); 11803 // Filing a couple requests prior to testing the dump. 11804 final TestNetworkCallback genericNetworkCallback = new TestNetworkCallback(); 11805 final TestNetworkCallback wifiNetworkCallback = new TestNetworkCallback(); 11806 final NetworkRequest genericRequest = new NetworkRequest.Builder() 11807 .clearCapabilities().build(); 11808 final NetworkRequest wifiRequest = new NetworkRequest.Builder() 11809 .addTransportType(TRANSPORT_WIFI).build(); 11810 mCm.registerNetworkCallback(genericRequest, genericNetworkCallback); 11811 mCm.registerNetworkCallback(wifiRequest, wifiNetworkCallback); 11812 final StringWriter stringWriter = new StringWriter(); 11813 11814 mService.dump(new FileDescriptor(), new PrintWriter(stringWriter), new String[0]); 11815 11816 assertFalse(stringWriter.toString().isEmpty()); 11817 } 11818 11819 @Test 11820 public void testRequestsSortedByIdSortsCorrectly() { 11821 final TestNetworkCallback genericNetworkCallback = new TestNetworkCallback(); 11822 final TestNetworkCallback wifiNetworkCallback = new TestNetworkCallback(); 11823 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback(); 11824 final NetworkRequest genericRequest = new NetworkRequest.Builder() 11825 .clearCapabilities().build(); 11826 final NetworkRequest wifiRequest = new NetworkRequest.Builder() 11827 .addTransportType(TRANSPORT_WIFI).build(); 11828 final NetworkRequest cellRequest = new NetworkRequest.Builder() 11829 .addTransportType(TRANSPORT_CELLULAR).build(); 11830 mCm.registerNetworkCallback(genericRequest, genericNetworkCallback); 11831 mCm.registerNetworkCallback(wifiRequest, wifiNetworkCallback); 11832 mCm.registerNetworkCallback(cellRequest, cellNetworkCallback); 11833 waitForIdle(); 11834 11835 final NetworkRequestInfo[] nriOutput = mService.requestsSortedById(); 11836 11837 assertTrue(nriOutput.length > 1); 11838 for (int i = 0; i < nriOutput.length - 1; i++) { 11839 final boolean isRequestIdInOrder = 11840 nriOutput[i].mRequests.get(0).requestId 11841 < nriOutput[i + 1].mRequests.get(0).requestId; 11842 assertTrue(isRequestIdInOrder); 11843 } 11844 } 11845 11846 private void assertUidRangesUpdatedForMyUid(boolean add) throws Exception { 11847 final int uid = Process.myUid(); 11848 assertVpnUidRangesUpdated(add, uidRangesForUids(uid), uid); 11849 } 11850 11851 private void assertVpnUidRangesUpdated(boolean add, Set<UidRange> vpnRanges, int exemptUid) 11852 throws Exception { 11853 InOrder inOrder = inOrder(mMockNetd); 11854 ArgumentCaptor<int[]> exemptUidCaptor = ArgumentCaptor.forClass(int[].class); 11855 11856 inOrder.verify(mMockNetd, times(1)).socketDestroy(eq(toUidRangeStableParcels(vpnRanges)), 11857 exemptUidCaptor.capture()); 11858 assertContainsExactly(exemptUidCaptor.getValue(), Process.VPN_UID, exemptUid); 11859 11860 if (add) { 11861 inOrder.verify(mMockNetd, times(1)).networkAddUidRangesParcel( 11862 new NativeUidRangeConfig(mMockVpn.getNetwork().getNetId(), 11863 toUidRangeStableParcels(vpnRanges), PREFERENCE_ORDER_VPN)); 11864 } else { 11865 inOrder.verify(mMockNetd, times(1)).networkRemoveUidRangesParcel( 11866 new NativeUidRangeConfig(mMockVpn.getNetwork().getNetId(), 11867 toUidRangeStableParcels(vpnRanges), PREFERENCE_ORDER_VPN)); 11868 } 11869 11870 inOrder.verify(mMockNetd, times(1)).socketDestroy(eq(toUidRangeStableParcels(vpnRanges)), 11871 exemptUidCaptor.capture()); 11872 assertContainsExactly(exemptUidCaptor.getValue(), Process.VPN_UID, exemptUid); 11873 } 11874 11875 @Test 11876 public void testVpnUidRangesUpdate() throws Exception { 11877 // Set up a WiFi network without proxy. 11878 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 11879 mWiFiNetworkAgent.connect(true); 11880 assertNull(mService.getProxyForNetwork(null)); 11881 assertNull(mCm.getDefaultProxy()); 11882 11883 final ExpectedBroadcast b1 = registerPacProxyBroadcast(); 11884 final LinkProperties lp = new LinkProperties(); 11885 lp.setInterfaceName("tun0"); 11886 lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), null)); 11887 lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), null)); 11888 final UidRange vpnRange = PRIMARY_UIDRANGE; 11889 final Set<UidRange> vpnRanges = Collections.singleton(vpnRange); 11890 mMockVpn.establish(lp, VPN_UID, vpnRanges); 11891 assertVpnUidRangesUpdated(true, vpnRanges, VPN_UID); 11892 // VPN is connected but proxy is not set, so there is no need to send proxy broadcast. 11893 b1.expectNoBroadcast(500); 11894 11895 // Update to new range which is old range minus APP1, i.e. only APP2 11896 final ExpectedBroadcast b2 = registerPacProxyBroadcast(); 11897 final Set<UidRange> newRanges = new HashSet<>(asList( 11898 new UidRange(vpnRange.start, APP1_UID - 1), 11899 new UidRange(APP1_UID + 1, vpnRange.stop))); 11900 mMockVpn.setUids(newRanges); 11901 waitForIdle(); 11902 11903 assertVpnUidRangesUpdated(true, newRanges, VPN_UID); 11904 assertVpnUidRangesUpdated(false, vpnRanges, VPN_UID); 11905 11906 // Uid has changed but proxy is not set, so there is no need to send proxy broadcast. 11907 b2.expectNoBroadcast(500); 11908 11909 final ProxyInfo testProxyInfo = ProxyInfo.buildDirectProxy("test", 8888); 11910 final ExpectedBroadcast b3 = registerPacProxyBroadcast(); 11911 lp.setHttpProxy(testProxyInfo); 11912 mMockVpn.sendLinkProperties(lp); 11913 waitForIdle(); 11914 // Proxy is set, so send a proxy broadcast. 11915 b3.expectBroadcast(); 11916 11917 final ExpectedBroadcast b4 = registerPacProxyBroadcast(); 11918 mMockVpn.setUids(vpnRanges); 11919 waitForIdle(); 11920 // Uid has changed and proxy is already set, so send a proxy broadcast. 11921 b4.expectBroadcast(); 11922 11923 final ExpectedBroadcast b5 = registerPacProxyBroadcast(); 11924 // Proxy is removed, send a proxy broadcast. 11925 lp.setHttpProxy(null); 11926 mMockVpn.sendLinkProperties(lp); 11927 waitForIdle(); 11928 b5.expectBroadcast(); 11929 11930 // Proxy is added in WiFi(default network), setDefaultProxy will be called. 11931 final LinkProperties wifiLp = mCm.getLinkProperties(mWiFiNetworkAgent.getNetwork()); 11932 assertNotNull(wifiLp); 11933 final ExpectedBroadcast b6 = expectProxyChangeAction(testProxyInfo); 11934 wifiLp.setHttpProxy(testProxyInfo); 11935 mWiFiNetworkAgent.sendLinkProperties(wifiLp); 11936 waitForIdle(); 11937 b6.expectBroadcast(); 11938 } 11939 11940 @Test 11941 public void testProxyBroadcastWillBeSentWhenVpnHasProxyAndConnects() throws Exception { 11942 // Set up a WiFi network without proxy. 11943 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 11944 mWiFiNetworkAgent.connect(true); 11945 assertNull(mService.getProxyForNetwork(null)); 11946 assertNull(mCm.getDefaultProxy()); 11947 11948 final LinkProperties lp = new LinkProperties(); 11949 lp.setInterfaceName("tun0"); 11950 lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), null)); 11951 lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), null)); 11952 final ProxyInfo testProxyInfo = ProxyInfo.buildDirectProxy("test", 8888); 11953 lp.setHttpProxy(testProxyInfo); 11954 final UidRange vpnRange = PRIMARY_UIDRANGE; 11955 final Set<UidRange> vpnRanges = Collections.singleton(vpnRange); 11956 final ExpectedBroadcast b1 = registerPacProxyBroadcast(); 11957 mMockVpn.setOwnerAndAdminUid(VPN_UID); 11958 mMockVpn.registerAgent(false, vpnRanges, lp); 11959 // In any case, the proxy broadcast won't be sent before VPN goes into CONNECTED state. 11960 // Otherwise, the app that calls ConnectivityManager#getDefaultProxy() when it receives the 11961 // proxy broadcast will get null. 11962 b1.expectNoBroadcast(500); 11963 11964 final ExpectedBroadcast b2 = registerPacProxyBroadcast(); 11965 mMockVpn.connect(true /* validated */, true /* hasInternet */, false /* isStrictMode */); 11966 waitForIdle(); 11967 assertVpnUidRangesUpdated(true, vpnRanges, VPN_UID); 11968 // Vpn is connected with proxy, so the proxy broadcast will be sent to inform the apps to 11969 // update their proxy data. 11970 b2.expectBroadcast(); 11971 } 11972 11973 @Test 11974 public void testProxyBroadcastWillBeSentWhenTheProxyOfNonDefaultNetworkHasChanged() 11975 throws Exception { 11976 // Set up a CELLULAR network without proxy. 11977 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 11978 mCellNetworkAgent.connect(true); 11979 assertNull(mService.getProxyForNetwork(null)); 11980 assertNull(mCm.getDefaultProxy()); 11981 // CELLULAR network should be the default network. 11982 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 11983 11984 // Set up a WiFi network without proxy. 11985 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 11986 mWiFiNetworkAgent.connect(true); 11987 assertNull(mService.getProxyForNetwork(null)); 11988 assertNull(mCm.getDefaultProxy()); 11989 // WiFi network should be the default network. 11990 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 11991 // CELLULAR network is not the default network. 11992 assertNotEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 11993 11994 // CELLULAR network is not the system default network, but it might be a per-app default 11995 // network. The proxy broadcast should be sent once its proxy has changed. 11996 final LinkProperties cellularLp = new LinkProperties(); 11997 cellularLp.setInterfaceName(MOBILE_IFNAME); 11998 final ProxyInfo testProxyInfo = ProxyInfo.buildDirectProxy("test", 8888); 11999 final ExpectedBroadcast b = registerPacProxyBroadcast(); 12000 cellularLp.setHttpProxy(testProxyInfo); 12001 mCellNetworkAgent.sendLinkProperties(cellularLp); 12002 b.expectBroadcast(); 12003 } 12004 12005 @Test 12006 public void testInvalidRequestTypes() { 12007 final int[] invalidReqTypeInts = new int[]{-1, NetworkRequest.Type.NONE.ordinal(), 12008 NetworkRequest.Type.LISTEN.ordinal(), NetworkRequest.Type.values().length}; 12009 final NetworkCapabilities nc = new NetworkCapabilities().addTransportType(TRANSPORT_WIFI); 12010 12011 for (int reqTypeInt : invalidReqTypeInts) { 12012 assertThrows("Expect throws for invalid request type " + reqTypeInt, 12013 IllegalArgumentException.class, 12014 () -> mService.requestNetwork(Process.INVALID_UID, nc, reqTypeInt, null, 0, 12015 null, ConnectivityManager.TYPE_NONE, NetworkCallback.FLAG_NONE, 12016 mContext.getPackageName(), getAttributionTag()) 12017 ); 12018 } 12019 } 12020 12021 @Test 12022 public void testKeepConnected() throws Exception { 12023 setAlwaysOnNetworks(false); 12024 registerDefaultNetworkCallbacks(); 12025 final TestNetworkCallback allNetworksCb = new TestNetworkCallback(); 12026 final NetworkRequest allNetworksRequest = new NetworkRequest.Builder().clearCapabilities() 12027 .build(); 12028 mCm.registerNetworkCallback(allNetworksRequest, allNetworksCb); 12029 12030 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 12031 mCellNetworkAgent.connect(true /* validated */); 12032 12033 mDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 12034 allNetworksCb.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 12035 12036 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 12037 mWiFiNetworkAgent.connect(true /* validated */); 12038 12039 mDefaultNetworkCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent); 12040 // While the default callback doesn't see the network before it's validated, the listen 12041 // sees the network come up and validate later 12042 allNetworksCb.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 12043 allNetworksCb.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent); 12044 allNetworksCb.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent); 12045 allNetworksCb.expectCallback(CallbackEntry.LOST, mCellNetworkAgent, 12046 TEST_LINGER_DELAY_MS * 2); 12047 12048 // The cell network has disconnected (see LOST above) because it was outscored and 12049 // had no requests (see setAlwaysOnNetworks(false) above) 12050 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 12051 final NetworkScore score = new NetworkScore.Builder().setLegacyInt(30).build(); 12052 mCellNetworkAgent.setScore(score); 12053 mCellNetworkAgent.connect(false /* validated */); 12054 12055 // The cell network gets torn down right away. 12056 allNetworksCb.expectAvailableCallbacksUnvalidated(mCellNetworkAgent); 12057 allNetworksCb.expectCallback(CallbackEntry.LOST, mCellNetworkAgent, 12058 TEST_NASCENT_DELAY_MS * 2); 12059 allNetworksCb.assertNoCallback(); 12060 12061 // Now create a cell network with KEEP_CONNECTED_FOR_HANDOVER and make sure it's 12062 // not disconnected immediately when outscored. 12063 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 12064 final NetworkScore scoreKeepup = new NetworkScore.Builder().setLegacyInt(30) 12065 .setKeepConnectedReason(KEEP_CONNECTED_FOR_HANDOVER).build(); 12066 mCellNetworkAgent.setScore(scoreKeepup); 12067 mCellNetworkAgent.connect(true /* validated */); 12068 12069 allNetworksCb.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 12070 mDefaultNetworkCallback.assertNoCallback(); 12071 12072 mWiFiNetworkAgent.disconnect(); 12073 12074 allNetworksCb.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 12075 mDefaultNetworkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 12076 mDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellNetworkAgent); 12077 12078 // Reconnect a WiFi network and make sure the cell network is still not torn down. 12079 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 12080 mWiFiNetworkAgent.connect(true /* validated */); 12081 12082 allNetworksCb.expectAvailableThenValidatedCallbacks(mWiFiNetworkAgent); 12083 mDefaultNetworkCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent); 12084 12085 // Now remove the reason to keep connected and make sure the network lingers and is 12086 // torn down. 12087 mCellNetworkAgent.setScore(new NetworkScore.Builder().setLegacyInt(30).build()); 12088 allNetworksCb.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent, 12089 TEST_NASCENT_DELAY_MS * 2); 12090 allNetworksCb.expectCallback(CallbackEntry.LOST, mCellNetworkAgent, 12091 TEST_LINGER_DELAY_MS * 2); 12092 mDefaultNetworkCallback.assertNoCallback(); 12093 12094 mCm.unregisterNetworkCallback(allNetworksCb); 12095 // mDefaultNetworkCallback will be unregistered by tearDown() 12096 } 12097 12098 private class QosCallbackMockHelper { 12099 @NonNull public final QosFilter mFilter; 12100 @NonNull public final IQosCallback mCallback; 12101 @NonNull public final TestNetworkAgentWrapper mAgentWrapper; 12102 @NonNull private final List<IQosCallback> mCallbacks = new ArrayList(); 12103 12104 QosCallbackMockHelper() throws Exception { 12105 Log.d(TAG, "QosCallbackMockHelper: "); 12106 mFilter = mock(QosFilter.class); 12107 12108 // Ensure the network is disconnected before anything else occurs 12109 assertNull(mCellNetworkAgent); 12110 12111 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 12112 mCellNetworkAgent.connect(true); 12113 12114 verifyActiveNetwork(TRANSPORT_CELLULAR); 12115 waitForIdle(); 12116 final Network network = mCellNetworkAgent.getNetwork(); 12117 12118 final Pair<IQosCallback, IBinder> pair = createQosCallback(); 12119 mCallback = pair.first; 12120 12121 doReturn(network).when(mFilter).getNetwork(); 12122 doReturn(QosCallbackException.EX_TYPE_FILTER_NONE).when(mFilter).validate(); 12123 mAgentWrapper = mCellNetworkAgent; 12124 } 12125 12126 void registerQosCallback(@NonNull final QosFilter filter, 12127 @NonNull final IQosCallback callback) { 12128 mCallbacks.add(callback); 12129 final NetworkAgentInfo nai = 12130 mService.getNetworkAgentInfoForNetwork(filter.getNetwork()); 12131 mService.registerQosCallbackInternal(filter, callback, nai); 12132 } 12133 12134 void tearDown() { 12135 for (int i = 0; i < mCallbacks.size(); i++) { 12136 mService.unregisterQosCallback(mCallbacks.get(i)); 12137 } 12138 } 12139 } 12140 12141 private Pair<IQosCallback, IBinder> createQosCallback() { 12142 final IQosCallback callback = mock(IQosCallback.class); 12143 final IBinder binder = mock(Binder.class); 12144 doReturn(binder).when(callback).asBinder(); 12145 doReturn(true).when(binder).isBinderAlive(); 12146 return new Pair<>(callback, binder); 12147 } 12148 12149 12150 @Test 12151 public void testQosCallbackRegistration() throws Exception { 12152 mQosCallbackMockHelper = new QosCallbackMockHelper(); 12153 final NetworkAgentWrapper wrapper = mQosCallbackMockHelper.mAgentWrapper; 12154 12155 doReturn(QosCallbackException.EX_TYPE_FILTER_NONE) 12156 .when(mQosCallbackMockHelper.mFilter).validate(); 12157 mQosCallbackMockHelper.registerQosCallback( 12158 mQosCallbackMockHelper.mFilter, mQosCallbackMockHelper.mCallback); 12159 12160 final NetworkAgentWrapper.CallbackType.OnQosCallbackRegister cbRegister1 = 12161 (NetworkAgentWrapper.CallbackType.OnQosCallbackRegister) 12162 wrapper.getCallbackHistory().poll(1000, x -> true); 12163 assertNotNull(cbRegister1); 12164 12165 final int registerCallbackId = cbRegister1.mQosCallbackId; 12166 mService.unregisterQosCallback(mQosCallbackMockHelper.mCallback); 12167 final NetworkAgentWrapper.CallbackType.OnQosCallbackUnregister cbUnregister; 12168 cbUnregister = (NetworkAgentWrapper.CallbackType.OnQosCallbackUnregister) 12169 wrapper.getCallbackHistory().poll(1000, x -> true); 12170 assertNotNull(cbUnregister); 12171 assertEquals(registerCallbackId, cbUnregister.mQosCallbackId); 12172 assertNull(wrapper.getCallbackHistory().poll(200, x -> true)); 12173 } 12174 12175 @Test 12176 public void testQosCallbackNoRegistrationOnValidationError() throws Exception { 12177 mQosCallbackMockHelper = new QosCallbackMockHelper(); 12178 12179 doReturn(QosCallbackException.EX_TYPE_FILTER_NETWORK_RELEASED) 12180 .when(mQosCallbackMockHelper.mFilter).validate(); 12181 mQosCallbackMockHelper.registerQosCallback( 12182 mQosCallbackMockHelper.mFilter, mQosCallbackMockHelper.mCallback); 12183 waitForIdle(); 12184 verify(mQosCallbackMockHelper.mCallback) 12185 .onError(eq(QosCallbackException.EX_TYPE_FILTER_NETWORK_RELEASED)); 12186 } 12187 12188 @Test 12189 public void testQosCallbackAvailableAndLost() throws Exception { 12190 mQosCallbackMockHelper = new QosCallbackMockHelper(); 12191 final int sessionId = 10; 12192 final int qosCallbackId = 1; 12193 12194 doReturn(QosCallbackException.EX_TYPE_FILTER_NONE) 12195 .when(mQosCallbackMockHelper.mFilter).validate(); 12196 mQosCallbackMockHelper.registerQosCallback( 12197 mQosCallbackMockHelper.mFilter, mQosCallbackMockHelper.mCallback); 12198 waitForIdle(); 12199 12200 final EpsBearerQosSessionAttributes attributes = new EpsBearerQosSessionAttributes( 12201 1, 2, 3, 4, 5, new ArrayList<>()); 12202 mQosCallbackMockHelper.mAgentWrapper.getNetworkAgent() 12203 .sendQosSessionAvailable(qosCallbackId, sessionId, attributes); 12204 waitForIdle(); 12205 12206 verify(mQosCallbackMockHelper.mCallback).onQosEpsBearerSessionAvailable(argThat(session -> 12207 session.getSessionId() == sessionId 12208 && session.getSessionType() == QosSession.TYPE_EPS_BEARER), eq(attributes)); 12209 12210 mQosCallbackMockHelper.mAgentWrapper.getNetworkAgent() 12211 .sendQosSessionLost(qosCallbackId, sessionId, QosSession.TYPE_EPS_BEARER); 12212 waitForIdle(); 12213 verify(mQosCallbackMockHelper.mCallback).onQosSessionLost(argThat(session -> 12214 session.getSessionId() == sessionId 12215 && session.getSessionType() == QosSession.TYPE_EPS_BEARER)); 12216 } 12217 12218 @Test 12219 public void testNrQosCallbackAvailableAndLost() throws Exception { 12220 mQosCallbackMockHelper = new QosCallbackMockHelper(); 12221 final int sessionId = 10; 12222 final int qosCallbackId = 1; 12223 12224 doReturn(QosCallbackException.EX_TYPE_FILTER_NONE) 12225 .when(mQosCallbackMockHelper.mFilter).validate(); 12226 mQosCallbackMockHelper.registerQosCallback( 12227 mQosCallbackMockHelper.mFilter, mQosCallbackMockHelper.mCallback); 12228 waitForIdle(); 12229 12230 final NrQosSessionAttributes attributes = new NrQosSessionAttributes( 12231 1, 2, 3, 4, 5, 6, 7, new ArrayList<>()); 12232 mQosCallbackMockHelper.mAgentWrapper.getNetworkAgent() 12233 .sendQosSessionAvailable(qosCallbackId, sessionId, attributes); 12234 waitForIdle(); 12235 12236 verify(mQosCallbackMockHelper.mCallback).onNrQosSessionAvailable(argThat(session -> 12237 session.getSessionId() == sessionId 12238 && session.getSessionType() == QosSession.TYPE_NR_BEARER), eq(attributes)); 12239 12240 mQosCallbackMockHelper.mAgentWrapper.getNetworkAgent() 12241 .sendQosSessionLost(qosCallbackId, sessionId, QosSession.TYPE_NR_BEARER); 12242 waitForIdle(); 12243 verify(mQosCallbackMockHelper.mCallback).onQosSessionLost(argThat(session -> 12244 session.getSessionId() == sessionId 12245 && session.getSessionType() == QosSession.TYPE_NR_BEARER)); 12246 } 12247 12248 @Test 12249 public void testQosCallbackTooManyRequests() throws Exception { 12250 mQosCallbackMockHelper = new QosCallbackMockHelper(); 12251 12252 doReturn(QosCallbackException.EX_TYPE_FILTER_NONE) 12253 .when(mQosCallbackMockHelper.mFilter).validate(); 12254 for (int i = 0; i < 100; i++) { 12255 final Pair<IQosCallback, IBinder> pair = createQosCallback(); 12256 12257 try { 12258 mQosCallbackMockHelper.registerQosCallback( 12259 mQosCallbackMockHelper.mFilter, pair.first); 12260 } catch (ServiceSpecificException e) { 12261 assertEquals(e.errorCode, ConnectivityManager.Errors.TOO_MANY_REQUESTS); 12262 if (i < 50) { 12263 fail("TOO_MANY_REQUESTS thrown too early, the count is " + i); 12264 } 12265 12266 // As long as there is at least 50 requests, it is safe to assume it works. 12267 // Note: The count isn't being tested precisely against 100 because the counter 12268 // is shared with request network. 12269 return; 12270 } 12271 } 12272 fail("TOO_MANY_REQUESTS never thrown"); 12273 } 12274 12275 private void mockGetApplicationInfo(@NonNull final String packageName, final int uid) { 12276 mockGetApplicationInfo(packageName, uid, PRIMARY_USER_HANDLE); 12277 } 12278 12279 private void mockGetApplicationInfo(@NonNull final String packageName, final int uid, 12280 @NonNull final UserHandle user) { 12281 final ApplicationInfo applicationInfo = new ApplicationInfo(); 12282 applicationInfo.uid = uid; 12283 try { 12284 doReturn(applicationInfo).when(mPackageManager).getApplicationInfoAsUser( 12285 eq(packageName), anyInt(), eq(user)); 12286 } catch (Exception e) { 12287 fail(e.getMessage()); 12288 } 12289 } 12290 12291 private void mockGetApplicationInfoThrowsNameNotFound(@NonNull final String packageName, 12292 @NonNull final UserHandle user) 12293 throws Exception { 12294 doThrow(new PackageManager.NameNotFoundException(packageName)).when( 12295 mPackageManager).getApplicationInfoAsUser(eq(packageName), anyInt(), eq(user)); 12296 } 12297 12298 private void mockHasSystemFeature(@NonNull final String featureName, final boolean hasFeature) { 12299 doReturn(hasFeature).when(mPackageManager).hasSystemFeature(eq(featureName)); 12300 } 12301 12302 private Range<Integer> getNriFirstUidRange(@NonNull final NetworkRequestInfo nri) { 12303 return nri.mRequests.get(0).networkCapabilities.getUids().iterator().next(); 12304 } 12305 12306 private OemNetworkPreferences createDefaultOemNetworkPreferences( 12307 @OemNetworkPreferences.OemNetworkPreference final int preference) { 12308 // Arrange PackageManager mocks 12309 mockGetApplicationInfo(TEST_PACKAGE_NAME, TEST_PACKAGE_UID); 12310 12311 // Build OemNetworkPreferences object 12312 return new OemNetworkPreferences.Builder() 12313 .addNetworkPreference(TEST_PACKAGE_NAME, preference) 12314 .build(); 12315 } 12316 12317 @Test 12318 public void testOemNetworkRequestFactoryPreferenceUninitializedThrowsError() { 12319 @OemNetworkPreferences.OemNetworkPreference final int prefToTest = 12320 OEM_NETWORK_PREFERENCE_UNINITIALIZED; 12321 12322 // Act on OemNetworkRequestFactory.createNrisFromOemNetworkPreferences() 12323 assertThrows(IllegalArgumentException.class, 12324 () -> mService.new OemNetworkRequestFactory() 12325 .createNrisFromOemNetworkPreferences( 12326 createDefaultOemNetworkPreferences(prefToTest))); 12327 } 12328 12329 @Test 12330 public void testOemNetworkRequestFactoryPreferenceOemPaid() 12331 throws Exception { 12332 // Expectations 12333 final int expectedNumOfNris = 1; 12334 final int expectedNumOfRequests = 3; 12335 12336 @OemNetworkPreferences.OemNetworkPreference final int prefToTest = 12337 OEM_NETWORK_PREFERENCE_OEM_PAID; 12338 12339 // Act on OemNetworkRequestFactory.createNrisFromOemNetworkPreferences() 12340 final ArraySet<NetworkRequestInfo> nris = 12341 mService.new OemNetworkRequestFactory() 12342 .createNrisFromOemNetworkPreferences( 12343 createDefaultOemNetworkPreferences(prefToTest)); 12344 final NetworkRequestInfo nri = nris.iterator().next(); 12345 assertEquals(PREFERENCE_ORDER_OEM, nri.mPreferenceOrder); 12346 final List<NetworkRequest> mRequests = nri.mRequests; 12347 assertEquals(expectedNumOfNris, nris.size()); 12348 assertEquals(expectedNumOfRequests, mRequests.size()); 12349 assertTrue(mRequests.get(0).isListen()); 12350 assertTrue(mRequests.get(0).hasCapability(NET_CAPABILITY_NOT_METERED)); 12351 assertTrue(mRequests.get(0).hasCapability(NET_CAPABILITY_VALIDATED)); 12352 assertTrue(mRequests.get(1).isRequest()); 12353 assertTrue(mRequests.get(1).hasCapability(NET_CAPABILITY_OEM_PAID)); 12354 assertEquals(NetworkRequest.Type.TRACK_DEFAULT, mRequests.get(2).type); 12355 assertTrue(mService.getDefaultRequest().networkCapabilities.equalsNetCapabilities( 12356 mRequests.get(2).networkCapabilities)); 12357 } 12358 12359 @Test 12360 public void testOemNetworkRequestFactoryPreferenceOemPaidNoFallback() 12361 throws Exception { 12362 // Expectations 12363 final int expectedNumOfNris = 1; 12364 final int expectedNumOfRequests = 2; 12365 12366 @OemNetworkPreferences.OemNetworkPreference final int prefToTest = 12367 OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK; 12368 12369 // Act on OemNetworkRequestFactory.createNrisFromOemNetworkPreferences() 12370 final ArraySet<NetworkRequestInfo> nris = 12371 mService.new OemNetworkRequestFactory() 12372 .createNrisFromOemNetworkPreferences( 12373 createDefaultOemNetworkPreferences(prefToTest)); 12374 final NetworkRequestInfo nri = nris.iterator().next(); 12375 assertEquals(PREFERENCE_ORDER_OEM, nri.mPreferenceOrder); 12376 final List<NetworkRequest> mRequests = nri.mRequests; 12377 assertEquals(expectedNumOfNris, nris.size()); 12378 assertEquals(expectedNumOfRequests, mRequests.size()); 12379 assertTrue(mRequests.get(0).isListen()); 12380 assertTrue(mRequests.get(0).hasCapability(NET_CAPABILITY_NOT_METERED)); 12381 assertTrue(mRequests.get(0).hasCapability(NET_CAPABILITY_VALIDATED)); 12382 assertTrue(mRequests.get(1).isRequest()); 12383 assertTrue(mRequests.get(1).hasCapability(NET_CAPABILITY_OEM_PAID)); 12384 } 12385 12386 @Test 12387 public void testOemNetworkRequestFactoryPreferenceOemPaidOnly() 12388 throws Exception { 12389 // Expectations 12390 final int expectedNumOfNris = 1; 12391 final int expectedNumOfRequests = 1; 12392 12393 @OemNetworkPreferences.OemNetworkPreference final int prefToTest = 12394 OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY; 12395 12396 // Act on OemNetworkRequestFactory.createNrisFromOemNetworkPreferences() 12397 final ArraySet<NetworkRequestInfo> nris = 12398 mService.new OemNetworkRequestFactory() 12399 .createNrisFromOemNetworkPreferences( 12400 createDefaultOemNetworkPreferences(prefToTest)); 12401 final NetworkRequestInfo nri = nris.iterator().next(); 12402 assertEquals(PREFERENCE_ORDER_OEM, nri.mPreferenceOrder); 12403 final List<NetworkRequest> mRequests = nri.mRequests; 12404 assertEquals(expectedNumOfNris, nris.size()); 12405 assertEquals(expectedNumOfRequests, mRequests.size()); 12406 assertTrue(mRequests.get(0).isRequest()); 12407 assertTrue(mRequests.get(0).hasCapability(NET_CAPABILITY_OEM_PAID)); 12408 } 12409 12410 @Test 12411 public void testOemNetworkRequestFactoryPreferenceOemPrivateOnly() 12412 throws Exception { 12413 // Expectations 12414 final int expectedNumOfNris = 1; 12415 final int expectedNumOfRequests = 1; 12416 12417 @OemNetworkPreferences.OemNetworkPreference final int prefToTest = 12418 OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY; 12419 12420 // Act on OemNetworkRequestFactory.createNrisFromOemNetworkPreferences() 12421 final ArraySet<NetworkRequestInfo> nris = 12422 mService.new OemNetworkRequestFactory() 12423 .createNrisFromOemNetworkPreferences( 12424 createDefaultOemNetworkPreferences(prefToTest)); 12425 final NetworkRequestInfo nri = nris.iterator().next(); 12426 assertEquals(PREFERENCE_ORDER_OEM, nri.mPreferenceOrder); 12427 final List<NetworkRequest> mRequests = nri.mRequests; 12428 assertEquals(expectedNumOfNris, nris.size()); 12429 assertEquals(expectedNumOfRequests, mRequests.size()); 12430 assertTrue(mRequests.get(0).isRequest()); 12431 assertTrue(mRequests.get(0).hasCapability(NET_CAPABILITY_OEM_PRIVATE)); 12432 assertFalse(mRequests.get(0).hasCapability(NET_CAPABILITY_OEM_PAID)); 12433 } 12434 12435 @Test 12436 public void testOemNetworkRequestFactoryCreatesCorrectNumOfNris() 12437 throws Exception { 12438 // Expectations 12439 final int expectedNumOfNris = 2; 12440 12441 // Arrange PackageManager mocks 12442 final String testPackageName2 = "com.google.apps.dialer"; 12443 mockGetApplicationInfo(TEST_PACKAGE_NAME, TEST_PACKAGE_UID); 12444 mockGetApplicationInfo(testPackageName2, TEST_PACKAGE_UID); 12445 12446 // Build OemNetworkPreferences object 12447 final int testOemPref = OEM_NETWORK_PREFERENCE_OEM_PAID; 12448 final int testOemPref2 = OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK; 12449 final OemNetworkPreferences pref = new OemNetworkPreferences.Builder() 12450 .addNetworkPreference(TEST_PACKAGE_NAME, testOemPref) 12451 .addNetworkPreference(testPackageName2, testOemPref2) 12452 .build(); 12453 12454 // Act on OemNetworkRequestFactory.createNrisFromOemNetworkPreferences() 12455 final ArraySet<NetworkRequestInfo> nris = 12456 mService.new OemNetworkRequestFactory().createNrisFromOemNetworkPreferences(pref); 12457 12458 assertNotNull(nris); 12459 assertEquals(expectedNumOfNris, nris.size()); 12460 } 12461 12462 @Test 12463 public void testOemNetworkRequestFactoryMultiplePrefsCorrectlySetsUids() 12464 throws Exception { 12465 // Arrange PackageManager mocks 12466 final String testPackageName2 = "com.google.apps.dialer"; 12467 final int testPackageNameUid2 = 456; 12468 mockGetApplicationInfo(TEST_PACKAGE_NAME, TEST_PACKAGE_UID); 12469 mockGetApplicationInfo(testPackageName2, testPackageNameUid2); 12470 12471 // Build OemNetworkPreferences object 12472 final int testOemPref = OEM_NETWORK_PREFERENCE_OEM_PAID; 12473 final int testOemPref2 = OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK; 12474 final OemNetworkPreferences pref = new OemNetworkPreferences.Builder() 12475 .addNetworkPreference(TEST_PACKAGE_NAME, testOemPref) 12476 .addNetworkPreference(testPackageName2, testOemPref2) 12477 .build(); 12478 12479 // Act on OemNetworkRequestFactory.createNrisFromOemNetworkPreferences() 12480 final List<NetworkRequestInfo> nris = 12481 new ArrayList<>( 12482 mService.new OemNetworkRequestFactory().createNrisFromOemNetworkPreferences( 12483 pref)); 12484 12485 // Sort by uid to access nris by index 12486 nris.sort(Comparator.comparingInt(nri -> getNriFirstUidRange(nri).getLower())); 12487 assertEquals(TEST_PACKAGE_UID, (int) getNriFirstUidRange(nris.get(0)).getLower()); 12488 assertEquals(TEST_PACKAGE_UID, (int) getNriFirstUidRange(nris.get(0)).getUpper()); 12489 assertEquals(testPackageNameUid2, (int) getNriFirstUidRange(nris.get(1)).getLower()); 12490 assertEquals(testPackageNameUid2, (int) getNriFirstUidRange(nris.get(1)).getUpper()); 12491 } 12492 12493 @Test 12494 public void testOemNetworkRequestFactoryMultipleUsersSetsUids() 12495 throws Exception { 12496 // Arrange users 12497 final int secondUserTestPackageUid = UserHandle.getUid(SECONDARY_USER, TEST_PACKAGE_UID); 12498 final int thirdUserTestPackageUid = UserHandle.getUid(TERTIARY_USER, TEST_PACKAGE_UID); 12499 doReturn(asList(PRIMARY_USER_HANDLE, SECONDARY_USER_HANDLE, TERTIARY_USER_HANDLE)) 12500 .when(mUserManager).getUserHandles(anyBoolean()); 12501 12502 // Arrange PackageManager mocks testing for users who have and don't have a package. 12503 mockGetApplicationInfoThrowsNameNotFound(TEST_PACKAGE_NAME, PRIMARY_USER_HANDLE); 12504 mockGetApplicationInfo(TEST_PACKAGE_NAME, secondUserTestPackageUid, SECONDARY_USER_HANDLE); 12505 mockGetApplicationInfo(TEST_PACKAGE_NAME, thirdUserTestPackageUid, TERTIARY_USER_HANDLE); 12506 12507 // Build OemNetworkPreferences object 12508 final int testOemPref = OEM_NETWORK_PREFERENCE_OEM_PAID; 12509 final OemNetworkPreferences pref = new OemNetworkPreferences.Builder() 12510 .addNetworkPreference(TEST_PACKAGE_NAME, testOemPref) 12511 .build(); 12512 12513 // Act on OemNetworkRequestFactory.createNrisFromOemNetworkPreferences() 12514 final List<NetworkRequestInfo> nris = 12515 new ArrayList<>( 12516 mService.new OemNetworkRequestFactory().createNrisFromOemNetworkPreferences( 12517 pref)); 12518 12519 // UIDs for users with installed packages should be present. 12520 // Three users exist, but only two have the test package installed. 12521 final int expectedUidSize = 2; 12522 final List<Range<Integer>> uids = 12523 new ArrayList<>(nris.get(0).mRequests.get(0).networkCapabilities.getUids()); 12524 assertEquals(expectedUidSize, uids.size()); 12525 12526 // Sort by uid to access nris by index 12527 uids.sort(Comparator.comparingInt(uid -> uid.getLower())); 12528 assertEquals(secondUserTestPackageUid, (int) uids.get(0).getLower()); 12529 assertEquals(secondUserTestPackageUid, (int) uids.get(0).getUpper()); 12530 assertEquals(thirdUserTestPackageUid, (int) uids.get(1).getLower()); 12531 assertEquals(thirdUserTestPackageUid, (int) uids.get(1).getUpper()); 12532 } 12533 12534 @Test 12535 public void testOemNetworkRequestFactoryAddsPackagesToCorrectPreference() 12536 throws Exception { 12537 // Expectations 12538 final int expectedNumOfNris = 1; 12539 final int expectedNumOfAppUids = 2; 12540 12541 // Arrange PackageManager mocks 12542 final String testPackageName2 = "com.google.apps.dialer"; 12543 final int testPackageNameUid2 = 456; 12544 mockGetApplicationInfo(TEST_PACKAGE_NAME, TEST_PACKAGE_UID); 12545 mockGetApplicationInfo(testPackageName2, testPackageNameUid2); 12546 12547 // Build OemNetworkPreferences object 12548 final int testOemPref = OEM_NETWORK_PREFERENCE_OEM_PAID; 12549 final OemNetworkPreferences pref = new OemNetworkPreferences.Builder() 12550 .addNetworkPreference(TEST_PACKAGE_NAME, testOemPref) 12551 .addNetworkPreference(testPackageName2, testOemPref) 12552 .build(); 12553 12554 // Act on OemNetworkRequestFactory.createNrisFromOemNetworkPreferences() 12555 final ArraySet<NetworkRequestInfo> nris = 12556 mService.new OemNetworkRequestFactory().createNrisFromOemNetworkPreferences(pref); 12557 12558 assertEquals(expectedNumOfNris, nris.size()); 12559 assertEquals(expectedNumOfAppUids, 12560 nris.iterator().next().mRequests.get(0).networkCapabilities.getUids().size()); 12561 } 12562 12563 @Test 12564 public void testSetOemNetworkPreferenceNullListenerAndPrefParamThrowsNpe() { 12565 mockHasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, true); 12566 12567 // Act on ConnectivityService.setOemNetworkPreference() 12568 assertThrows(NullPointerException.class, 12569 () -> mService.setOemNetworkPreference( 12570 null, 12571 null)); 12572 } 12573 12574 @Test 12575 public void testSetOemNetworkPreferenceFailsForNonAutomotive() 12576 throws Exception { 12577 mockHasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, false); 12578 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 12579 OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY; 12580 12581 // Act on ConnectivityService.setOemNetworkPreference() 12582 assertThrows(UnsupportedOperationException.class, 12583 () -> mService.setOemNetworkPreference( 12584 createDefaultOemNetworkPreferences(networkPref), 12585 null)); 12586 } 12587 12588 @Test 12589 public void testSetOemNetworkPreferenceFailsForTestRequestWithoutPermission() { 12590 // Calling setOemNetworkPreference() with a test pref requires the permission 12591 // MANAGE_TEST_NETWORKS. 12592 mockHasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, false); 12593 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 12594 OEM_NETWORK_PREFERENCE_TEST; 12595 12596 // Act on ConnectivityService.setOemNetworkPreference() 12597 assertThrows(SecurityException.class, 12598 () -> mService.setOemNetworkPreference( 12599 createDefaultOemNetworkPreferences(networkPref), 12600 null)); 12601 } 12602 12603 @Test 12604 public void testSetOemNetworkPreferenceFailsForInvalidTestRequest() { 12605 assertSetOemNetworkPreferenceFailsForInvalidTestRequest(OEM_NETWORK_PREFERENCE_TEST); 12606 } 12607 12608 @Test 12609 public void testSetOemNetworkPreferenceFailsForInvalidTestOnlyRequest() { 12610 assertSetOemNetworkPreferenceFailsForInvalidTestRequest(OEM_NETWORK_PREFERENCE_TEST_ONLY); 12611 } 12612 12613 private void assertSetOemNetworkPreferenceFailsForInvalidTestRequest( 12614 @OemNetworkPreferences.OemNetworkPreference final int oemNetworkPreferenceForTest) { 12615 mockHasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, true); 12616 final String secondPackage = "does.not.matter"; 12617 12618 // A valid test request would only have a single mapping. 12619 final OemNetworkPreferences pref = new OemNetworkPreferences.Builder() 12620 .addNetworkPreference(TEST_PACKAGE_NAME, oemNetworkPreferenceForTest) 12621 .addNetworkPreference(secondPackage, oemNetworkPreferenceForTest) 12622 .build(); 12623 12624 // Act on ConnectivityService.setOemNetworkPreference() 12625 assertThrows(IllegalArgumentException.class, 12626 () -> mService.setOemNetworkPreference(pref, null)); 12627 } 12628 12629 private void setOemNetworkPreferenceAgentConnected(final int transportType, 12630 final boolean connectAgent) throws Exception { 12631 switch(transportType) { 12632 // Corresponds to a metered cellular network. Will be used for the default network. 12633 case TRANSPORT_CELLULAR: 12634 if (!connectAgent) { 12635 mCellNetworkAgent.disconnect(); 12636 break; 12637 } 12638 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 12639 mCellNetworkAgent.removeCapability(NET_CAPABILITY_NOT_METERED); 12640 mCellNetworkAgent.connect(true); 12641 break; 12642 // Corresponds to a restricted ethernet network with OEM_PAID/OEM_PRIVATE. 12643 case TRANSPORT_ETHERNET: 12644 if (!connectAgent) { 12645 stopOemManagedNetwork(); 12646 break; 12647 } 12648 startOemManagedNetwork(true); 12649 break; 12650 // Corresponds to unmetered Wi-Fi. 12651 case TRANSPORT_WIFI: 12652 if (!connectAgent) { 12653 mWiFiNetworkAgent.disconnect(); 12654 break; 12655 } 12656 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 12657 mWiFiNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED); 12658 mWiFiNetworkAgent.connect(true); 12659 break; 12660 default: 12661 throw new AssertionError("Unsupported transport type passed in."); 12662 12663 } 12664 waitForIdle(); 12665 } 12666 12667 private void startOemManagedNetwork(final boolean isOemPaid) throws Exception { 12668 mEthernetNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_ETHERNET); 12669 mEthernetNetworkAgent.addCapability( 12670 isOemPaid ? NET_CAPABILITY_OEM_PAID : NET_CAPABILITY_OEM_PRIVATE); 12671 mEthernetNetworkAgent.removeCapability(NET_CAPABILITY_NOT_RESTRICTED); 12672 mEthernetNetworkAgent.connect(true); 12673 } 12674 12675 private void stopOemManagedNetwork() { 12676 mEthernetNetworkAgent.disconnect(); 12677 waitForIdle(); 12678 } 12679 12680 private void verifyMultipleDefaultNetworksTracksCorrectly( 12681 final int expectedOemRequestsSize, 12682 @NonNull final Network expectedDefaultNetwork, 12683 @NonNull final Network expectedPerAppNetwork) { 12684 // The current test setup assumes two tracked default network requests; one for the default 12685 // network and the other for the OEM network preference being tested. This will be validated 12686 // each time to confirm it doesn't change under test. 12687 final int expectedDefaultNetworkRequestsSize = 2; 12688 assertEquals(expectedDefaultNetworkRequestsSize, mService.mDefaultNetworkRequests.size()); 12689 for (final NetworkRequestInfo defaultRequest : mService.mDefaultNetworkRequests) { 12690 final Network defaultNetwork = defaultRequest.getSatisfier() == null 12691 ? null : defaultRequest.getSatisfier().network(); 12692 // If this is the default request. 12693 if (defaultRequest == mService.mDefaultRequest) { 12694 assertEquals( 12695 expectedDefaultNetwork, 12696 defaultNetwork); 12697 // Make sure this value doesn't change. 12698 assertEquals(1, defaultRequest.mRequests.size()); 12699 continue; 12700 } 12701 assertEquals(expectedPerAppNetwork, defaultNetwork); 12702 assertEquals(expectedOemRequestsSize, defaultRequest.mRequests.size()); 12703 } 12704 verifyMultipleDefaultCallbacks(expectedDefaultNetwork, expectedPerAppNetwork); 12705 } 12706 12707 /** 12708 * Verify default callbacks for 'available' fire as expected. This will only run if 12709 * registerDefaultNetworkCallbacks() was executed prior and will only be different if the 12710 * setOemNetworkPreference() per-app API was used for the current process. 12711 * @param expectedSystemDefault the expected network for the system default. 12712 * @param expectedPerAppDefault the expected network for the current process's default. 12713 */ 12714 private void verifyMultipleDefaultCallbacks( 12715 @NonNull final Network expectedSystemDefault, 12716 @NonNull final Network expectedPerAppDefault) { 12717 if (null != mSystemDefaultNetworkCallback && null != expectedSystemDefault 12718 && mService.mNoServiceNetwork.network() != expectedSystemDefault) { 12719 // getLastAvailableNetwork() is used as this method can be called successively with 12720 // the same network to validate therefore expectAvailableThenValidatedCallbacks 12721 // can't be used. 12722 assertEquals(mSystemDefaultNetworkCallback.getLastAvailableNetwork(), 12723 expectedSystemDefault); 12724 } 12725 if (null != mDefaultNetworkCallback && null != expectedPerAppDefault 12726 && mService.mNoServiceNetwork.network() != expectedPerAppDefault) { 12727 assertEquals(mDefaultNetworkCallback.getLastAvailableNetwork(), 12728 expectedPerAppDefault); 12729 } 12730 } 12731 12732 private void registerDefaultNetworkCallbacks() { 12733 if (mSystemDefaultNetworkCallback != null || mDefaultNetworkCallback != null 12734 || mProfileDefaultNetworkCallback != null 12735 || mProfileDefaultNetworkCallbackAsAppUid2 != null 12736 || mTestPackageDefaultNetworkCallback2 != null 12737 || mTestPackageDefaultNetworkCallback != null) { 12738 throw new IllegalStateException("Default network callbacks already registered"); 12739 } 12740 12741 // Using Manifest.permission.NETWORK_SETTINGS for registerSystemDefaultNetworkCallback() 12742 mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_GRANTED); 12743 mSystemDefaultNetworkCallback = new TestNetworkCallback(); 12744 mDefaultNetworkCallback = new TestNetworkCallback(); 12745 mProfileDefaultNetworkCallback = new TestNetworkCallback(); 12746 mTestPackageDefaultNetworkCallback = new TestNetworkCallback(); 12747 mProfileDefaultNetworkCallbackAsAppUid2 = new TestNetworkCallback(); 12748 mTestPackageDefaultNetworkCallback2 = new TestNetworkCallback(); 12749 mCm.registerSystemDefaultNetworkCallback(mSystemDefaultNetworkCallback, 12750 new Handler(ConnectivityThread.getInstanceLooper())); 12751 mCm.registerDefaultNetworkCallback(mDefaultNetworkCallback); 12752 registerDefaultNetworkCallbackAsUid(mProfileDefaultNetworkCallback, 12753 TEST_WORK_PROFILE_APP_UID); 12754 registerDefaultNetworkCallbackAsUid(mTestPackageDefaultNetworkCallback, TEST_PACKAGE_UID); 12755 registerDefaultNetworkCallbackAsUid(mProfileDefaultNetworkCallbackAsAppUid2, 12756 TEST_WORK_PROFILE_APP_UID_2); 12757 registerDefaultNetworkCallbackAsUid(mTestPackageDefaultNetworkCallback2, 12758 TEST_PACKAGE_UID2); 12759 // TODO: test using ConnectivityManager#registerDefaultNetworkCallbackAsUid as well. 12760 mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_DENIED); 12761 } 12762 12763 private void unregisterDefaultNetworkCallbacks() { 12764 if (null != mDefaultNetworkCallback) { 12765 mCm.unregisterNetworkCallback(mDefaultNetworkCallback); 12766 } 12767 if (null != mSystemDefaultNetworkCallback) { 12768 mCm.unregisterNetworkCallback(mSystemDefaultNetworkCallback); 12769 } 12770 if (null != mProfileDefaultNetworkCallback) { 12771 mCm.unregisterNetworkCallback(mProfileDefaultNetworkCallback); 12772 } 12773 if (null != mTestPackageDefaultNetworkCallback) { 12774 mCm.unregisterNetworkCallback(mTestPackageDefaultNetworkCallback); 12775 } 12776 if (null != mProfileDefaultNetworkCallbackAsAppUid2) { 12777 mCm.unregisterNetworkCallback(mProfileDefaultNetworkCallbackAsAppUid2); 12778 } 12779 if (null != mTestPackageDefaultNetworkCallback2) { 12780 mCm.unregisterNetworkCallback(mTestPackageDefaultNetworkCallback2); 12781 } 12782 } 12783 12784 private void setupMultipleDefaultNetworksForOemNetworkPreferenceNotCurrentUidTest( 12785 @OemNetworkPreferences.OemNetworkPreference final int networkPrefToSetup) 12786 throws Exception { 12787 final int testPackageNameUid = TEST_PACKAGE_UID; 12788 final String testPackageName = "per.app.defaults.package"; 12789 setupMultipleDefaultNetworksForOemNetworkPreferenceTest( 12790 networkPrefToSetup, testPackageNameUid, testPackageName); 12791 } 12792 12793 private void setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest( 12794 @OemNetworkPreferences.OemNetworkPreference final int networkPrefToSetup) 12795 throws Exception { 12796 final int testPackageNameUid = Process.myUid(); 12797 final String testPackageName = "per.app.defaults.package"; 12798 setupMultipleDefaultNetworksForOemNetworkPreferenceTest( 12799 networkPrefToSetup, testPackageNameUid, testPackageName); 12800 } 12801 12802 private void setupMultipleDefaultNetworksForOemNetworkPreferenceTest( 12803 @OemNetworkPreferences.OemNetworkPreference final int networkPrefToSetup, 12804 final int testPackageUid, @NonNull final String testPackageName) throws Exception { 12805 // Only the default request should be included at start. 12806 assertEquals(1, mService.mDefaultNetworkRequests.size()); 12807 12808 final UidRangeParcel[] uidRanges = 12809 toUidRangeStableParcels(uidRangesForUids(testPackageUid)); 12810 setupSetOemNetworkPreferenceForPreferenceTest( 12811 networkPrefToSetup, uidRanges, testPackageName); 12812 } 12813 12814 private void setupSetOemNetworkPreferenceForPreferenceTest( 12815 @OemNetworkPreferences.OemNetworkPreference final int networkPrefToSetup, 12816 @NonNull final UidRangeParcel[] uidRanges, 12817 @NonNull final String testPackageName) throws Exception { 12818 setupSetOemNetworkPreferenceForPreferenceTest(networkPrefToSetup, uidRanges, 12819 testPackageName, PRIMARY_USER_HANDLE, true /* hasAutomotiveFeature */); 12820 } 12821 12822 private void setupSetOemNetworkPreferenceForPreferenceTest( 12823 @OemNetworkPreferences.OemNetworkPreference final int networkPrefToSetup, 12824 @NonNull final UidRangeParcel[] uidRanges, 12825 @NonNull final String testPackageName, 12826 @NonNull final UserHandle user) throws Exception { 12827 setupSetOemNetworkPreferenceForPreferenceTest(networkPrefToSetup, uidRanges, 12828 testPackageName, user, true /* hasAutomotiveFeature */); 12829 } 12830 12831 private void setupSetOemNetworkPreferenceForPreferenceTest( 12832 @OemNetworkPreferences.OemNetworkPreference final int networkPrefToSetup, 12833 @NonNull final UidRangeParcel[] uidRanges, 12834 @NonNull final String testPackageName, 12835 @NonNull final UserHandle user, 12836 final boolean hasAutomotiveFeature) throws Exception { 12837 mockHasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, hasAutomotiveFeature); 12838 12839 // These tests work off a single UID therefore using 'start' is valid. 12840 mockGetApplicationInfo(testPackageName, uidRanges[0].start, user); 12841 12842 setOemNetworkPreference(networkPrefToSetup, testPackageName); 12843 } 12844 12845 private void setOemNetworkPreference(final int networkPrefToSetup, 12846 @NonNull final String... testPackageNames) 12847 throws Exception { 12848 mockHasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, true); 12849 12850 // Build OemNetworkPreferences object 12851 final OemNetworkPreferences.Builder builder = new OemNetworkPreferences.Builder(); 12852 for (final String packageName : testPackageNames) { 12853 builder.addNetworkPreference(packageName, networkPrefToSetup); 12854 } 12855 final OemNetworkPreferences pref = builder.build(); 12856 12857 // Act on ConnectivityService.setOemNetworkPreference() 12858 final TestOemListenerCallback oemPrefListener = new TestOemListenerCallback(); 12859 mService.setOemNetworkPreference(pref, oemPrefListener); 12860 12861 // Verify call returned successfully 12862 oemPrefListener.expectOnComplete(); 12863 } 12864 12865 private static class TestOemListenerCallback implements IOnCompleteListener { 12866 final CompletableFuture<Object> mDone = new CompletableFuture<>(); 12867 12868 @Override 12869 public void onComplete() { 12870 mDone.complete(new Object()); 12871 } 12872 12873 void expectOnComplete() { 12874 try { 12875 mDone.get(TIMEOUT_MS, TimeUnit.MILLISECONDS); 12876 } catch (TimeoutException e) { 12877 fail("Expected onComplete() not received after " + TIMEOUT_MS + " ms"); 12878 } catch (Exception e) { 12879 fail(e.getMessage()); 12880 } 12881 } 12882 12883 @Override 12884 public IBinder asBinder() { 12885 return null; 12886 } 12887 } 12888 12889 @Test 12890 public void testMultiDefaultGetActiveNetworkIsCorrect() throws Exception { 12891 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 12892 OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY; 12893 final int expectedOemPrefRequestSize = 1; 12894 registerDefaultNetworkCallbacks(); 12895 12896 // Setup the test process to use networkPref for their default network. 12897 setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest(networkPref); 12898 12899 // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID. 12900 // The active network for the default should be null at this point as this is a retricted 12901 // network. 12902 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true); 12903 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 12904 null, 12905 mEthernetNetworkAgent.getNetwork()); 12906 12907 // Verify that the active network is correct 12908 verifyActiveNetwork(TRANSPORT_ETHERNET); 12909 // default NCs will be unregistered in tearDown 12910 } 12911 12912 @Test 12913 public void testMultiDefaultIsActiveNetworkMeteredIsCorrect() throws Exception { 12914 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 12915 OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY; 12916 final int expectedOemPrefRequestSize = 1; 12917 registerDefaultNetworkCallbacks(); 12918 12919 // Setup the test process to use networkPref for their default network. 12920 setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest(networkPref); 12921 12922 // Returns true by default when no network is available. 12923 assertTrue(mCm.isActiveNetworkMetered()); 12924 12925 // Connect to an unmetered restricted network that will only be available to the OEM pref. 12926 mEthernetNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_ETHERNET); 12927 mEthernetNetworkAgent.addCapability(NET_CAPABILITY_OEM_PAID); 12928 mEthernetNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED); 12929 mEthernetNetworkAgent.removeCapability(NET_CAPABILITY_NOT_RESTRICTED); 12930 mEthernetNetworkAgent.connect(true); 12931 waitForIdle(); 12932 12933 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 12934 null, 12935 mEthernetNetworkAgent.getNetwork()); 12936 12937 assertFalse(mCm.isActiveNetworkMetered()); 12938 // default NCs will be unregistered in tearDown 12939 } 12940 12941 @Test 12942 public void testPerAppDefaultRegisterDefaultNetworkCallback() throws Exception { 12943 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 12944 OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY; 12945 final int expectedOemPrefRequestSize = 1; 12946 final TestNetworkCallback defaultNetworkCallback = new TestNetworkCallback(); 12947 12948 // Register the default network callback before the pref is already set. This means that 12949 // the policy will be applied to the callback on setOemNetworkPreference(). 12950 mCm.registerDefaultNetworkCallback(defaultNetworkCallback); 12951 defaultNetworkCallback.assertNoCallback(); 12952 12953 final TestNetworkCallback otherUidDefaultCallback = new TestNetworkCallback(); 12954 withPermission(NETWORK_SETTINGS, () -> 12955 mCm.registerDefaultNetworkCallbackForUid(TEST_PACKAGE_UID, otherUidDefaultCallback, 12956 new Handler(ConnectivityThread.getInstanceLooper()))); 12957 12958 // Setup the test process to use networkPref for their default network. 12959 setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest(networkPref); 12960 12961 // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID. 12962 // The active nai for the default is null at this point as this is a restricted network. 12963 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true); 12964 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 12965 null, 12966 mEthernetNetworkAgent.getNetwork()); 12967 12968 // At this point with a restricted network used, the available callback should trigger. 12969 defaultNetworkCallback.expectAvailableThenValidatedCallbacks(mEthernetNetworkAgent); 12970 assertEquals(defaultNetworkCallback.getLastAvailableNetwork(), 12971 mEthernetNetworkAgent.getNetwork()); 12972 otherUidDefaultCallback.assertNoCallback(); 12973 12974 // Now bring down the default network which should trigger a LOST callback. 12975 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, false); 12976 12977 // At this point, with no network is available, the lost callback should trigger 12978 defaultNetworkCallback.expectCallback(CallbackEntry.LOST, mEthernetNetworkAgent); 12979 otherUidDefaultCallback.assertNoCallback(); 12980 12981 // Confirm we can unregister without issues. 12982 mCm.unregisterNetworkCallback(defaultNetworkCallback); 12983 mCm.unregisterNetworkCallback(otherUidDefaultCallback); 12984 } 12985 12986 @Test 12987 public void testPerAppDefaultRegisterDefaultNetworkCallbackAfterPrefSet() throws Exception { 12988 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 12989 OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY; 12990 final int expectedOemPrefRequestSize = 1; 12991 final TestNetworkCallback defaultNetworkCallback = new TestNetworkCallback(); 12992 12993 // Setup the test process to use networkPref for their default network. 12994 setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest(networkPref); 12995 12996 // Register the default network callback after the pref is already set. This means that 12997 // the policy will be applied to the callback on requestNetwork(). 12998 mCm.registerDefaultNetworkCallback(defaultNetworkCallback); 12999 defaultNetworkCallback.assertNoCallback(); 13000 13001 final TestNetworkCallback otherUidDefaultCallback = new TestNetworkCallback(); 13002 withPermission(NETWORK_SETTINGS, () -> 13003 mCm.registerDefaultNetworkCallbackForUid(TEST_PACKAGE_UID, otherUidDefaultCallback, 13004 new Handler(ConnectivityThread.getInstanceLooper()))); 13005 13006 // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID. 13007 // The active nai for the default is null at this point as this is a restricted network. 13008 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true); 13009 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 13010 null, 13011 mEthernetNetworkAgent.getNetwork()); 13012 13013 // At this point with a restricted network used, the available callback should trigger 13014 defaultNetworkCallback.expectAvailableThenValidatedCallbacks(mEthernetNetworkAgent); 13015 assertEquals(defaultNetworkCallback.getLastAvailableNetwork(), 13016 mEthernetNetworkAgent.getNetwork()); 13017 otherUidDefaultCallback.assertNoCallback(); 13018 13019 // Now bring down the default network which should trigger a LOST callback. 13020 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, false); 13021 otherUidDefaultCallback.assertNoCallback(); 13022 13023 // At this point, with no network is available, the lost callback should trigger 13024 defaultNetworkCallback.expectCallback(CallbackEntry.LOST, mEthernetNetworkAgent); 13025 otherUidDefaultCallback.assertNoCallback(); 13026 13027 // Confirm we can unregister without issues. 13028 mCm.unregisterNetworkCallback(defaultNetworkCallback); 13029 mCm.unregisterNetworkCallback(otherUidDefaultCallback); 13030 } 13031 13032 @Test 13033 public void testPerAppDefaultRegisterDefaultNetworkCallbackDoesNotFire() throws Exception { 13034 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 13035 OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY; 13036 final int expectedOemPrefRequestSize = 1; 13037 final TestNetworkCallback defaultNetworkCallback = new TestNetworkCallback(); 13038 final int userId = UserHandle.getUserId(Process.myUid()); 13039 13040 mCm.registerDefaultNetworkCallback(defaultNetworkCallback); 13041 defaultNetworkCallback.assertNoCallback(); 13042 13043 final TestNetworkCallback otherUidDefaultCallback = new TestNetworkCallback(); 13044 withPermission(NETWORK_SETTINGS, () -> 13045 mCm.registerDefaultNetworkCallbackForUid(TEST_PACKAGE_UID, otherUidDefaultCallback, 13046 new Handler(ConnectivityThread.getInstanceLooper()))); 13047 13048 // Setup a process different than the test process to use the default network. This means 13049 // that the defaultNetworkCallback won't be tracked by the per-app policy. 13050 setupMultipleDefaultNetworksForOemNetworkPreferenceNotCurrentUidTest(networkPref); 13051 13052 // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID. 13053 // The active nai for the default is null at this point as this is a restricted network. 13054 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true); 13055 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 13056 null, 13057 mEthernetNetworkAgent.getNetwork()); 13058 13059 // As this callback does not have access to the OEM_PAID network, it will not fire. 13060 defaultNetworkCallback.assertNoCallback(); 13061 assertDefaultNetworkCapabilities(userId /* no networks */); 13062 13063 // The other UID does have access, and gets a callback. 13064 otherUidDefaultCallback.expectAvailableThenValidatedCallbacks(mEthernetNetworkAgent); 13065 13066 // Bring up unrestricted cellular. This should now satisfy the default network. 13067 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); 13068 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 13069 mCellNetworkAgent.getNetwork(), 13070 mEthernetNetworkAgent.getNetwork()); 13071 13072 // At this point with an unrestricted network used, the available callback should trigger 13073 // The other UID is unaffected and remains on the paid network. 13074 defaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 13075 assertEquals(defaultNetworkCallback.getLastAvailableNetwork(), 13076 mCellNetworkAgent.getNetwork()); 13077 assertDefaultNetworkCapabilities(userId, mCellNetworkAgent); 13078 otherUidDefaultCallback.assertNoCallback(); 13079 13080 // Now bring down the per-app network. 13081 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, false); 13082 13083 // Since the callback didn't use the per-app network, only the other UID gets a callback. 13084 // Because the preference specifies no fallback, it does not switch to cellular. 13085 defaultNetworkCallback.assertNoCallback(); 13086 otherUidDefaultCallback.expectCallback(CallbackEntry.LOST, mEthernetNetworkAgent); 13087 13088 // Now bring down the default network. 13089 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, false); 13090 13091 // As this callback was tracking the default, this should now trigger. 13092 defaultNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 13093 otherUidDefaultCallback.assertNoCallback(); 13094 13095 // Confirm we can unregister without issues. 13096 mCm.unregisterNetworkCallback(defaultNetworkCallback); 13097 mCm.unregisterNetworkCallback(otherUidDefaultCallback); 13098 } 13099 13100 /** 13101 * This method assumes that the same uidRanges input will be used to verify that dependencies 13102 * are called as expected. 13103 */ 13104 private void verifySetOemNetworkPreferenceForPreference( 13105 @NonNull final UidRangeParcel[] uidRanges, 13106 final int addUidRangesNetId, 13107 final int addUidRangesTimes, 13108 final int removeUidRangesNetId, 13109 final int removeUidRangesTimes, 13110 final boolean shouldDestroyNetwork) throws RemoteException { 13111 verifySetOemNetworkPreferenceForPreference(uidRanges, uidRanges, 13112 addUidRangesNetId, addUidRangesTimes, removeUidRangesNetId, removeUidRangesTimes, 13113 shouldDestroyNetwork); 13114 } 13115 13116 private void verifySetOemNetworkPreferenceForPreference( 13117 @NonNull final UidRangeParcel[] addedUidRanges, 13118 @NonNull final UidRangeParcel[] removedUidRanges, 13119 final int addUidRangesNetId, 13120 final int addUidRangesTimes, 13121 final int removeUidRangesNetId, 13122 final int removeUidRangesTimes, 13123 final boolean shouldDestroyNetwork) throws RemoteException { 13124 final boolean useAnyIdForAdd = OEM_PREF_ANY_NET_ID == addUidRangesNetId; 13125 final boolean useAnyIdForRemove = OEM_PREF_ANY_NET_ID == removeUidRangesNetId; 13126 13127 // Validate that add/remove uid range (with oem priority) to/from netd. 13128 verify(mMockNetd, times(addUidRangesTimes)).networkAddUidRangesParcel(argThat(config -> 13129 (useAnyIdForAdd ? true : addUidRangesNetId == config.netId) 13130 && Arrays.equals(addedUidRanges, config.uidRanges) 13131 && PREFERENCE_ORDER_OEM == config.subPriority)); 13132 verify(mMockNetd, times(removeUidRangesTimes)).networkRemoveUidRangesParcel( 13133 argThat(config -> (useAnyIdForRemove ? true : removeUidRangesNetId == config.netId) 13134 && Arrays.equals(removedUidRanges, config.uidRanges) 13135 && PREFERENCE_ORDER_OEM == config.subPriority)); 13136 if (shouldDestroyNetwork) { 13137 verify(mMockNetd, times(1)) 13138 .networkDestroy((useAnyIdForRemove ? anyInt() : eq(removeUidRangesNetId))); 13139 } 13140 reset(mMockNetd); 13141 } 13142 13143 /** 13144 * Test the tracked default requests allows test requests without standard setup. 13145 */ 13146 @Test 13147 public void testSetOemNetworkPreferenceAllowsValidTestRequestWithoutChecks() throws Exception { 13148 @OemNetworkPreferences.OemNetworkPreference int networkPref = 13149 OEM_NETWORK_PREFERENCE_TEST; 13150 validateSetOemNetworkPreferenceAllowsValidTestPrefRequest(networkPref); 13151 } 13152 13153 /** 13154 * Test the tracked default requests allows test only requests without standard setup. 13155 */ 13156 @Test 13157 public void testSetOemNetworkPreferenceAllowsValidTestOnlyRequestWithoutChecks() 13158 throws Exception { 13159 @OemNetworkPreferences.OemNetworkPreference int networkPref = 13160 OEM_NETWORK_PREFERENCE_TEST_ONLY; 13161 validateSetOemNetworkPreferenceAllowsValidTestPrefRequest(networkPref); 13162 } 13163 13164 private void validateSetOemNetworkPreferenceAllowsValidTestPrefRequest(int networkPref) 13165 throws Exception { 13166 // The caller must have the MANAGE_TEST_NETWORKS permission. 13167 final int testPackageUid = 123; 13168 final String validTestPackageName = "does.not.matter"; 13169 final UidRangeParcel[] uidRanges = 13170 toUidRangeStableParcels(uidRangesForUids(testPackageUid)); 13171 mServiceContext.setPermission( 13172 Manifest.permission.MANAGE_TEST_NETWORKS, PERMISSION_GRANTED); 13173 13174 // Put the system into a state in which setOemNetworkPreference() would normally fail. This 13175 // will confirm that a valid test request can bypass these checks. 13176 mockHasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, false); 13177 mServiceContext.setPermission( 13178 Manifest.permission.CONTROL_OEM_PAID_NETWORK_PREFERENCE, PERMISSION_DENIED); 13179 13180 // Validate the starting requests only includes the system default request. 13181 assertEquals(1, mService.mDefaultNetworkRequests.size()); 13182 13183 // Add an OEM default network request to track. 13184 setupSetOemNetworkPreferenceForPreferenceTest( 13185 networkPref, uidRanges, validTestPackageName, PRIMARY_USER_HANDLE, 13186 false /* hasAutomotiveFeature */); 13187 13188 // Two requests should now exist; the system default and the test request. 13189 assertEquals(2, mService.mDefaultNetworkRequests.size()); 13190 } 13191 13192 /** 13193 * Test the tracked default requests clear previous OEM requests on setOemNetworkPreference(). 13194 */ 13195 @Test 13196 public void testSetOemNetworkPreferenceClearPreviousOemValues() throws Exception { 13197 @OemNetworkPreferences.OemNetworkPreference int networkPref = 13198 OEM_NETWORK_PREFERENCE_OEM_PAID; 13199 final int testPackageUid = 123; 13200 final String testPackageName = "com.google.apps.contacts"; 13201 final UidRangeParcel[] uidRanges = 13202 toUidRangeStableParcels(uidRangesForUids(testPackageUid)); 13203 13204 // Validate the starting requests only includes the system default request. 13205 assertEquals(1, mService.mDefaultNetworkRequests.size()); 13206 13207 // Add an OEM default network request to track. 13208 setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges, testPackageName); 13209 13210 // Two requests should exist, one for the fallback and one for the pref. 13211 assertEquals(2, mService.mDefaultNetworkRequests.size()); 13212 13213 networkPref = OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY; 13214 setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges, testPackageName); 13215 13216 // Two requests should still exist validating the previous per-app request was replaced. 13217 assertEquals(2, mService.mDefaultNetworkRequests.size()); 13218 } 13219 13220 /** 13221 * Test network priority for preference OEM_NETWORK_PREFERENCE_OEM_PAID in the following order: 13222 * NET_CAPABILITY_NOT_METERED -> NET_CAPABILITY_OEM_PAID -> fallback 13223 */ 13224 @Test 13225 public void testMultilayerForPreferenceOemPaidEvaluatesCorrectly() 13226 throws Exception { 13227 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 13228 OEM_NETWORK_PREFERENCE_OEM_PAID; 13229 13230 // Arrange PackageManager mocks 13231 final UidRangeParcel[] uidRanges = 13232 toUidRangeStableParcels(uidRangesForUids(TEST_PACKAGE_UID)); 13233 setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges, TEST_PACKAGE_NAME); 13234 13235 // Verify the starting state. No networks should be connected. 13236 verifySetOemNetworkPreferenceForPreference(uidRanges, 13237 OEM_PREF_ANY_NET_ID, 0 /* times */, 13238 OEM_PREF_ANY_NET_ID, 0 /* times */, 13239 false /* shouldDestroyNetwork */); 13240 13241 // Test lowest to highest priority requests. 13242 // Bring up metered cellular. This will satisfy the fallback network. 13243 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); 13244 verifySetOemNetworkPreferenceForPreference(uidRanges, 13245 mCellNetworkAgent.getNetwork().netId, 1 /* times */, 13246 OEM_PREF_ANY_NET_ID, 0 /* times */, 13247 false /* shouldDestroyNetwork */); 13248 13249 // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID. 13250 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true); 13251 verifySetOemNetworkPreferenceForPreference(uidRanges, 13252 mEthernetNetworkAgent.getNetwork().netId, 1 /* times */, 13253 mCellNetworkAgent.getNetwork().netId, 1 /* times */, 13254 false /* shouldDestroyNetwork */); 13255 13256 // Bring up unmetered Wi-Fi. This will satisfy NET_CAPABILITY_NOT_METERED. 13257 setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, true); 13258 verifySetOemNetworkPreferenceForPreference(uidRanges, 13259 mWiFiNetworkAgent.getNetwork().netId, 1 /* times */, 13260 mEthernetNetworkAgent.getNetwork().netId, 1 /* times */, 13261 false /* shouldDestroyNetwork */); 13262 13263 // Disconnecting OEM_PAID should have no effect as it is lower in priority then unmetered. 13264 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, false); 13265 // netd should not be called as default networks haven't changed. 13266 verifySetOemNetworkPreferenceForPreference(uidRanges, 13267 OEM_PREF_ANY_NET_ID, 0 /* times */, 13268 OEM_PREF_ANY_NET_ID, 0 /* times */, 13269 false /* shouldDestroyNetwork */); 13270 13271 // Disconnecting unmetered should put PANS on lowest priority fallback request. 13272 setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, false); 13273 verifySetOemNetworkPreferenceForPreference(uidRanges, 13274 mCellNetworkAgent.getNetwork().netId, 1 /* times */, 13275 mWiFiNetworkAgent.getNetwork().netId, 0 /* times */, 13276 true /* shouldDestroyNetwork */); 13277 13278 // Disconnecting the fallback network should result in no connectivity. 13279 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, false); 13280 verifySetOemNetworkPreferenceForPreference(uidRanges, 13281 OEM_PREF_ANY_NET_ID, 0 /* times */, 13282 mCellNetworkAgent.getNetwork().netId, 0 /* times */, 13283 true /* shouldDestroyNetwork */); 13284 } 13285 13286 /** 13287 * Test network priority for OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK in the following order: 13288 * NET_CAPABILITY_NOT_METERED -> NET_CAPABILITY_OEM_PAID 13289 */ 13290 @Test 13291 public void testMultilayerForPreferenceOemPaidNoFallbackEvaluatesCorrectly() 13292 throws Exception { 13293 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 13294 OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK; 13295 13296 // Arrange PackageManager mocks 13297 final UidRangeParcel[] uidRanges = 13298 toUidRangeStableParcels(uidRangesForUids(TEST_PACKAGE_UID)); 13299 setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges, TEST_PACKAGE_NAME); 13300 13301 // Verify the starting state. This preference doesn't support using the fallback network 13302 // therefore should be on the disconnected network as it has no networks to connect to. 13303 verifySetOemNetworkPreferenceForPreference(uidRanges, 13304 mService.mNoServiceNetwork.network.getNetId(), 1 /* times */, 13305 OEM_PREF_ANY_NET_ID, 0 /* times */, 13306 false /* shouldDestroyNetwork */); 13307 13308 // Test lowest to highest priority requests. 13309 // Bring up metered cellular. This will satisfy the fallback network. 13310 // This preference should not use this network as it doesn't support fallback usage. 13311 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); 13312 verifySetOemNetworkPreferenceForPreference(uidRanges, 13313 OEM_PREF_ANY_NET_ID, 0 /* times */, 13314 OEM_PREF_ANY_NET_ID, 0 /* times */, 13315 false /* shouldDestroyNetwork */); 13316 13317 // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID. 13318 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true); 13319 verifySetOemNetworkPreferenceForPreference(uidRanges, 13320 mEthernetNetworkAgent.getNetwork().netId, 1 /* times */, 13321 mService.mNoServiceNetwork.network.getNetId(), 1 /* times */, 13322 false /* shouldDestroyNetwork */); 13323 13324 // Bring up unmetered Wi-Fi. This will satisfy NET_CAPABILITY_NOT_METERED. 13325 setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, true); 13326 verifySetOemNetworkPreferenceForPreference(uidRanges, 13327 mWiFiNetworkAgent.getNetwork().netId, 1 /* times */, 13328 mEthernetNetworkAgent.getNetwork().netId, 1 /* times */, 13329 false /* shouldDestroyNetwork */); 13330 13331 // Disconnecting unmetered should put PANS on OEM_PAID. 13332 setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, false); 13333 verifySetOemNetworkPreferenceForPreference(uidRanges, 13334 mEthernetNetworkAgent.getNetwork().netId, 1 /* times */, 13335 mWiFiNetworkAgent.getNetwork().netId, 0 /* times */, 13336 true /* shouldDestroyNetwork */); 13337 13338 // Disconnecting OEM_PAID should result in no connectivity. 13339 // OEM_PAID_NO_FALLBACK not supporting a fallback now uses the disconnected network. 13340 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, false); 13341 verifySetOemNetworkPreferenceForPreference(uidRanges, 13342 mService.mNoServiceNetwork.network.getNetId(), 1 /* times */, 13343 mEthernetNetworkAgent.getNetwork().netId, 0 /* times */, 13344 true /* shouldDestroyNetwork */); 13345 } 13346 13347 /** 13348 * Test network priority for OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY in the following order: 13349 * NET_CAPABILITY_OEM_PAID 13350 * This preference should only apply to OEM_PAID networks. 13351 */ 13352 @Test 13353 public void testMultilayerForPreferenceOemPaidOnlyEvaluatesCorrectly() 13354 throws Exception { 13355 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 13356 OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY; 13357 13358 // Arrange PackageManager mocks 13359 final UidRangeParcel[] uidRanges = 13360 toUidRangeStableParcels(uidRangesForUids(TEST_PACKAGE_UID)); 13361 setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges, TEST_PACKAGE_NAME); 13362 13363 // Verify the starting state. This preference doesn't support using the fallback network 13364 // therefore should be on the disconnected network as it has no networks to connect to. 13365 verifySetOemNetworkPreferenceForPreference(uidRanges, 13366 mService.mNoServiceNetwork.network.getNetId(), 1 /* times */, 13367 OEM_PREF_ANY_NET_ID, 0 /* times */, 13368 false /* shouldDestroyNetwork */); 13369 13370 // Bring up metered cellular. This should not apply to this preference. 13371 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); 13372 verifySetOemNetworkPreferenceForPreference(uidRanges, 13373 OEM_PREF_ANY_NET_ID, 0 /* times */, 13374 OEM_PREF_ANY_NET_ID, 0 /* times */, 13375 false /* shouldDestroyNetwork */); 13376 13377 // Bring up unmetered Wi-Fi. This should not apply to this preference. 13378 setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, true); 13379 verifySetOemNetworkPreferenceForPreference(uidRanges, 13380 OEM_PREF_ANY_NET_ID, 0 /* times */, 13381 OEM_PREF_ANY_NET_ID, 0 /* times */, 13382 false /* shouldDestroyNetwork */); 13383 13384 // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID. 13385 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true); 13386 verifySetOemNetworkPreferenceForPreference(uidRanges, 13387 mEthernetNetworkAgent.getNetwork().netId, 1 /* times */, 13388 mService.mNoServiceNetwork.network.getNetId(), 1 /* times */, 13389 false /* shouldDestroyNetwork */); 13390 13391 // Disconnecting OEM_PAID should result in no connectivity. 13392 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, false); 13393 verifySetOemNetworkPreferenceForPreference(uidRanges, 13394 mService.mNoServiceNetwork.network.getNetId(), 1 /* times */, 13395 mEthernetNetworkAgent.getNetwork().netId, 0 /* times */, 13396 true /* shouldDestroyNetwork */); 13397 } 13398 13399 /** 13400 * Test network priority for OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY in the following order: 13401 * NET_CAPABILITY_OEM_PRIVATE 13402 * This preference should only apply to OEM_PRIVATE networks. 13403 */ 13404 @Test 13405 public void testMultilayerForPreferenceOemPrivateOnlyEvaluatesCorrectly() 13406 throws Exception { 13407 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 13408 OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY; 13409 13410 // Arrange PackageManager mocks 13411 final UidRangeParcel[] uidRanges = 13412 toUidRangeStableParcels(uidRangesForUids(TEST_PACKAGE_UID)); 13413 setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges, TEST_PACKAGE_NAME); 13414 13415 // Verify the starting state. This preference doesn't support using the fallback network 13416 // therefore should be on the disconnected network as it has no networks to connect to. 13417 verifySetOemNetworkPreferenceForPreference(uidRanges, 13418 mService.mNoServiceNetwork.network.getNetId(), 1 /* times */, 13419 OEM_PREF_ANY_NET_ID, 0 /* times */, 13420 false /* shouldDestroyNetwork */); 13421 13422 // Bring up metered cellular. This should not apply to this preference. 13423 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); 13424 verifySetOemNetworkPreferenceForPreference(uidRanges, 13425 OEM_PREF_ANY_NET_ID, 0 /* times */, 13426 OEM_PREF_ANY_NET_ID, 0 /* times */, 13427 false /* shouldDestroyNetwork */); 13428 13429 // Bring up unmetered Wi-Fi. This should not apply to this preference. 13430 setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, true); 13431 verifySetOemNetworkPreferenceForPreference(uidRanges, 13432 OEM_PREF_ANY_NET_ID, 0 /* times */, 13433 OEM_PREF_ANY_NET_ID, 0 /* times */, 13434 false /* shouldDestroyNetwork */); 13435 13436 // Bring up ethernet with OEM_PRIVATE. This will satisfy NET_CAPABILITY_OEM_PRIVATE. 13437 startOemManagedNetwork(false); 13438 verifySetOemNetworkPreferenceForPreference(uidRanges, 13439 mEthernetNetworkAgent.getNetwork().netId, 1 /* times */, 13440 mService.mNoServiceNetwork.network.getNetId(), 1 /* times */, 13441 false /* shouldDestroyNetwork */); 13442 13443 // Disconnecting OEM_PRIVATE should result in no connectivity. 13444 stopOemManagedNetwork(); 13445 verifySetOemNetworkPreferenceForPreference(uidRanges, 13446 mService.mNoServiceNetwork.network.getNetId(), 1 /* times */, 13447 mEthernetNetworkAgent.getNetwork().netId, 0 /* times */, 13448 true /* shouldDestroyNetwork */); 13449 } 13450 13451 @Test 13452 public void testMultilayerForMultipleUsersEvaluatesCorrectly() 13453 throws Exception { 13454 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 13455 OEM_NETWORK_PREFERENCE_OEM_PAID; 13456 13457 // Arrange users 13458 final int secondUser = 10; 13459 final UserHandle secondUserHandle = new UserHandle(secondUser); 13460 doReturn(asList(PRIMARY_USER_HANDLE, secondUserHandle)).when(mUserManager) 13461 .getUserHandles(anyBoolean()); 13462 13463 // Arrange PackageManager mocks 13464 final int secondUserTestPackageUid = UserHandle.getUid(secondUser, TEST_PACKAGE_UID); 13465 final UidRangeParcel[] uidRanges = 13466 toUidRangeStableParcels( 13467 uidRangesForUids(TEST_PACKAGE_UID, secondUserTestPackageUid)); 13468 mockGetApplicationInfo(TEST_PACKAGE_NAME, secondUserTestPackageUid, secondUserHandle); 13469 setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges, TEST_PACKAGE_NAME); 13470 13471 // Verify the starting state. No networks should be connected. 13472 verifySetOemNetworkPreferenceForPreference(uidRanges, 13473 OEM_PREF_ANY_NET_ID, 0 /* times */, 13474 OEM_PREF_ANY_NET_ID, 0 /* times */, 13475 false /* shouldDestroyNetwork */); 13476 13477 // Test that we correctly add the expected values for multiple users. 13478 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); 13479 verifySetOemNetworkPreferenceForPreference(uidRanges, 13480 mCellNetworkAgent.getNetwork().netId, 1 /* times */, 13481 OEM_PREF_ANY_NET_ID, 0 /* times */, 13482 false /* shouldDestroyNetwork */); 13483 13484 // Test that we correctly remove the expected values for multiple users. 13485 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, false); 13486 verifySetOemNetworkPreferenceForPreference(uidRanges, 13487 OEM_PREF_ANY_NET_ID, 0 /* times */, 13488 mCellNetworkAgent.getNetwork().netId, 0 /* times */, 13489 true /* shouldDestroyNetwork */); 13490 } 13491 13492 @Test 13493 public void testMultilayerForBroadcastedUsersEvaluatesCorrectly() 13494 throws Exception { 13495 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 13496 OEM_NETWORK_PREFERENCE_OEM_PAID; 13497 13498 // Arrange users 13499 final int secondUser = 10; 13500 final UserHandle secondUserHandle = new UserHandle(secondUser); 13501 doReturn(asList(PRIMARY_USER_HANDLE)).when(mUserManager).getUserHandles(anyBoolean()); 13502 13503 // Arrange PackageManager mocks 13504 final int secondUserTestPackageUid = UserHandle.getUid(secondUser, TEST_PACKAGE_UID); 13505 final UidRangeParcel[] uidRangesSingleUser = 13506 toUidRangeStableParcels(uidRangesForUids(TEST_PACKAGE_UID)); 13507 final UidRangeParcel[] uidRangesBothUsers = 13508 toUidRangeStableParcels( 13509 uidRangesForUids(TEST_PACKAGE_UID, secondUserTestPackageUid)); 13510 mockGetApplicationInfo(TEST_PACKAGE_NAME, secondUserTestPackageUid, secondUserHandle); 13511 setupSetOemNetworkPreferenceForPreferenceTest( 13512 networkPref, uidRangesSingleUser, TEST_PACKAGE_NAME); 13513 13514 // Verify the starting state. No networks should be connected. 13515 verifySetOemNetworkPreferenceForPreference(uidRangesSingleUser, 13516 OEM_PREF_ANY_NET_ID, 0 /* times */, 13517 OEM_PREF_ANY_NET_ID, 0 /* times */, 13518 false /* shouldDestroyNetwork */); 13519 13520 // Test that we correctly add the expected values for multiple users. 13521 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); 13522 verifySetOemNetworkPreferenceForPreference(uidRangesSingleUser, 13523 mCellNetworkAgent.getNetwork().netId, 1 /* times */, 13524 OEM_PREF_ANY_NET_ID, 0 /* times */, 13525 false /* shouldDestroyNetwork */); 13526 13527 // Send a broadcast indicating a user was added. 13528 doReturn(asList(PRIMARY_USER_HANDLE, secondUserHandle)).when(mUserManager) 13529 .getUserHandles(anyBoolean()); 13530 final Intent addedIntent = new Intent(ACTION_USER_ADDED); 13531 addedIntent.putExtra(Intent.EXTRA_USER, UserHandle.of(secondUser)); 13532 processBroadcast(addedIntent); 13533 13534 // Test that we correctly add values for all users and remove for the single user. 13535 verifySetOemNetworkPreferenceForPreference(uidRangesBothUsers, uidRangesSingleUser, 13536 mCellNetworkAgent.getNetwork().netId, 1 /* times */, 13537 mCellNetworkAgent.getNetwork().netId, 1 /* times */, 13538 false /* shouldDestroyNetwork */); 13539 13540 // Send a broadcast indicating a user was removed. 13541 doReturn(asList(PRIMARY_USER_HANDLE)).when(mUserManager).getUserHandles(anyBoolean()); 13542 final Intent removedIntent = new Intent(ACTION_USER_REMOVED); 13543 removedIntent.putExtra(Intent.EXTRA_USER, UserHandle.of(secondUser)); 13544 processBroadcast(removedIntent); 13545 13546 // Test that we correctly add values for the single user and remove for the all users. 13547 verifySetOemNetworkPreferenceForPreference(uidRangesSingleUser, uidRangesBothUsers, 13548 mCellNetworkAgent.getNetwork().netId, 1 /* times */, 13549 mCellNetworkAgent.getNetwork().netId, 1 /* times */, 13550 false /* shouldDestroyNetwork */); 13551 } 13552 13553 @Test 13554 public void testMultilayerForPackageChangesEvaluatesCorrectly() 13555 throws Exception { 13556 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 13557 OEM_NETWORK_PREFERENCE_OEM_PAID; 13558 final String packageScheme = "package:"; 13559 13560 // Arrange PackageManager mocks 13561 final String packageToInstall = "package.to.install"; 13562 final int packageToInstallUid = 81387; 13563 final UidRangeParcel[] uidRangesSinglePackage = 13564 toUidRangeStableParcels(uidRangesForUids(TEST_PACKAGE_UID)); 13565 mockGetApplicationInfo(TEST_PACKAGE_NAME, TEST_PACKAGE_UID); 13566 mockGetApplicationInfoThrowsNameNotFound(packageToInstall, PRIMARY_USER_HANDLE); 13567 setOemNetworkPreference(networkPref, TEST_PACKAGE_NAME, packageToInstall); 13568 grantUsingBackgroundNetworksPermissionForUid(Binder.getCallingUid(), packageToInstall); 13569 13570 // Verify the starting state. No networks should be connected. 13571 verifySetOemNetworkPreferenceForPreference(uidRangesSinglePackage, 13572 OEM_PREF_ANY_NET_ID, 0 /* times */, 13573 OEM_PREF_ANY_NET_ID, 0 /* times */, 13574 false /* shouldDestroyNetwork */); 13575 13576 // Test that we correctly add the expected values for installed packages. 13577 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); 13578 verifySetOemNetworkPreferenceForPreference(uidRangesSinglePackage, 13579 mCellNetworkAgent.getNetwork().netId, 1 /* times */, 13580 OEM_PREF_ANY_NET_ID, 0 /* times */, 13581 false /* shouldDestroyNetwork */); 13582 13583 // Set the system to recognize the package to be installed 13584 mockGetApplicationInfo(packageToInstall, packageToInstallUid); 13585 final UidRangeParcel[] uidRangesAllPackages = 13586 toUidRangeStableParcels(uidRangesForUids(TEST_PACKAGE_UID, packageToInstallUid)); 13587 13588 // Send a broadcast indicating a package was installed. 13589 final Intent addedIntent = new Intent(ACTION_PACKAGE_ADDED); 13590 addedIntent.setData(Uri.parse(packageScheme + packageToInstall)); 13591 processBroadcast(addedIntent); 13592 13593 // Test the single package is removed and the combined packages are added. 13594 verifySetOemNetworkPreferenceForPreference(uidRangesAllPackages, uidRangesSinglePackage, 13595 mCellNetworkAgent.getNetwork().netId, 1 /* times */, 13596 mCellNetworkAgent.getNetwork().netId, 1 /* times */, 13597 false /* shouldDestroyNetwork */); 13598 13599 // Set the system to no longer recognize the package to be installed 13600 mockGetApplicationInfoThrowsNameNotFound(packageToInstall, PRIMARY_USER_HANDLE); 13601 13602 // Send a broadcast indicating a package was removed. 13603 final Intent removedIntent = new Intent(ACTION_PACKAGE_REMOVED); 13604 removedIntent.setData(Uri.parse(packageScheme + packageToInstall)); 13605 processBroadcast(removedIntent); 13606 13607 // Test the combined packages are removed and the single package is added. 13608 verifySetOemNetworkPreferenceForPreference(uidRangesSinglePackage, uidRangesAllPackages, 13609 mCellNetworkAgent.getNetwork().netId, 1 /* times */, 13610 mCellNetworkAgent.getNetwork().netId, 1 /* times */, 13611 false /* shouldDestroyNetwork */); 13612 13613 // Set the system to change the installed package's uid 13614 final int replacedTestPackageUid = TEST_PACKAGE_UID + 1; 13615 mockGetApplicationInfo(TEST_PACKAGE_NAME, replacedTestPackageUid); 13616 final UidRangeParcel[] uidRangesReplacedPackage = 13617 toUidRangeStableParcels(uidRangesForUids(replacedTestPackageUid)); 13618 13619 // Send a broadcast indicating a package was replaced. 13620 final Intent replacedIntent = new Intent(ACTION_PACKAGE_REPLACED); 13621 replacedIntent.setData(Uri.parse(packageScheme + TEST_PACKAGE_NAME)); 13622 processBroadcast(replacedIntent); 13623 13624 // Test the original uid is removed and is replaced with the new uid. 13625 verifySetOemNetworkPreferenceForPreference(uidRangesReplacedPackage, uidRangesSinglePackage, 13626 mCellNetworkAgent.getNetwork().netId, 1 /* times */, 13627 mCellNetworkAgent.getNetwork().netId, 1 /* times */, 13628 false /* shouldDestroyNetwork */); 13629 } 13630 13631 /** 13632 * Test network priority for preference OEM_NETWORK_PREFERENCE_OEM_PAID in the following order: 13633 * NET_CAPABILITY_NOT_METERED -> NET_CAPABILITY_OEM_PAID -> fallback 13634 */ 13635 @Test 13636 public void testMultipleDefaultNetworksTracksOemNetworkPreferenceOemPaidCorrectly() 13637 throws Exception { 13638 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 13639 OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID; 13640 setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest(networkPref); 13641 final int expectedDefaultRequestSize = 2; 13642 final int expectedOemPrefRequestSize = 3; 13643 registerDefaultNetworkCallbacks(); 13644 13645 // The fallback as well as the OEM preference should now be tracked. 13646 assertEquals(expectedDefaultRequestSize, mService.mDefaultNetworkRequests.size()); 13647 13648 // Test lowest to highest priority requests. 13649 // Bring up metered cellular. This will satisfy the fallback network. 13650 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); 13651 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 13652 mCellNetworkAgent.getNetwork(), 13653 mCellNetworkAgent.getNetwork()); 13654 13655 // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID. 13656 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true); 13657 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 13658 mCellNetworkAgent.getNetwork(), 13659 mEthernetNetworkAgent.getNetwork()); 13660 13661 // Bring up unmetered Wi-Fi. This will satisfy NET_CAPABILITY_NOT_METERED. 13662 setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, true); 13663 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 13664 mWiFiNetworkAgent.getNetwork(), 13665 mWiFiNetworkAgent.getNetwork()); 13666 13667 // Disconnecting unmetered Wi-Fi will put the pref on OEM_PAID and fallback on cellular. 13668 setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, false); 13669 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 13670 mCellNetworkAgent.getNetwork(), 13671 mEthernetNetworkAgent.getNetwork()); 13672 13673 // Disconnecting cellular should keep OEM network on OEM_PAID and fallback will be null. 13674 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, false); 13675 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 13676 null, 13677 mEthernetNetworkAgent.getNetwork()); 13678 13679 // Disconnecting OEM_PAID will put both on null as it is the last network. 13680 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, false); 13681 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 13682 null, 13683 null); 13684 13685 // default callbacks will be unregistered in tearDown 13686 } 13687 13688 @Test 13689 public void testNetworkFactoryRequestsWithMultilayerRequest() 13690 throws Exception { 13691 // First use OEM_PAID preference to create a multi-layer request : 1. listen for 13692 // unmetered, 2. request network with cap OEM_PAID, 3, request the default network for 13693 // fallback. 13694 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 13695 OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID; 13696 setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest(networkPref); 13697 13698 final HandlerThread handlerThread = new HandlerThread("MockFactory"); 13699 handlerThread.start(); 13700 NetworkCapabilities internetFilter = new NetworkCapabilities() 13701 .addCapability(NET_CAPABILITY_INTERNET) 13702 .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED); 13703 final MockNetworkFactory internetFactory = new MockNetworkFactory(handlerThread.getLooper(), 13704 mServiceContext, "internetFactory", internetFilter, mCsHandlerThread); 13705 internetFactory.setScoreFilter(40); 13706 internetFactory.register(); 13707 // Default internet request only. The unmetered request is never sent to factories (it's a 13708 // LISTEN, not requestable). The 3rd (fallback) request in OEM_PAID NRI is TRACK_DEFAULT 13709 // which is also not sent to factories. Finally, the OEM_PAID request doesn't match the 13710 // internetFactory filter. 13711 internetFactory.expectRequestAdds(1); 13712 internetFactory.assertRequestCountEquals(1); 13713 13714 NetworkCapabilities oemPaidFilter = new NetworkCapabilities() 13715 .addCapability(NET_CAPABILITY_INTERNET) 13716 .addCapability(NET_CAPABILITY_OEM_PAID) 13717 .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED) 13718 .removeCapability(NET_CAPABILITY_NOT_RESTRICTED); 13719 final MockNetworkFactory oemPaidFactory = new MockNetworkFactory(handlerThread.getLooper(), 13720 mServiceContext, "oemPaidFactory", oemPaidFilter, mCsHandlerThread); 13721 oemPaidFactory.setScoreFilter(40); 13722 oemPaidFactory.register(); 13723 oemPaidFactory.expectRequestAdd(); // Because nobody satisfies the request 13724 13725 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 13726 mCellNetworkAgent.connect(true); 13727 13728 // A network connected that satisfies the default internet request. For the OEM_PAID 13729 // preference, this is not as good as an OEM_PAID network, so even if the score of 13730 // the network is better than the factory announced, it still should try to bring up 13731 // the network. 13732 expectNoRequestChanged(oemPaidFactory); 13733 oemPaidFactory.assertRequestCountEquals(1); 13734 // The internet factory however is outscored, and should lose its requests. 13735 internetFactory.expectRequestRemove(); 13736 internetFactory.assertRequestCountEquals(0); 13737 13738 final NetworkCapabilities oemPaidNc = new NetworkCapabilities(); 13739 oemPaidNc.addCapability(NET_CAPABILITY_OEM_PAID); 13740 oemPaidNc.removeCapability(NET_CAPABILITY_NOT_RESTRICTED); 13741 final TestNetworkAgentWrapper oemPaidAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, 13742 new LinkProperties(), oemPaidNc); 13743 oemPaidAgent.connect(true); 13744 13745 // The oemPaidAgent has score 50/cell transport, so it beats what the oemPaidFactory can 13746 // provide, therefore it loses the request. 13747 oemPaidFactory.expectRequestRemove(); 13748 oemPaidFactory.assertRequestCountEquals(0); 13749 expectNoRequestChanged(internetFactory); 13750 internetFactory.assertRequestCountEquals(0); 13751 13752 oemPaidAgent.setScore(new NetworkScore.Builder().setLegacyInt(20).setExiting(true).build()); 13753 // Now the that the agent is weak, the oemPaidFactory can beat the existing network for the 13754 // OEM_PAID request. The internet factory however can't beat a network that has OEM_PAID 13755 // for the preference request, so it doesn't see the request. 13756 oemPaidFactory.expectRequestAdd(); 13757 oemPaidFactory.assertRequestCountEquals(1); 13758 expectNoRequestChanged(internetFactory); 13759 internetFactory.assertRequestCountEquals(0); 13760 13761 mCellNetworkAgent.disconnect(); 13762 // The network satisfying the default internet request has disconnected, so the 13763 // internetFactory sees the default request again. However there is a network with OEM_PAID 13764 // connected, so the 2nd OEM_PAID req is already satisfied, so the oemPaidFactory doesn't 13765 // care about networks that don't have OEM_PAID. 13766 expectNoRequestChanged(oemPaidFactory); 13767 oemPaidFactory.assertRequestCountEquals(1); 13768 internetFactory.expectRequestAdd(); 13769 internetFactory.assertRequestCountEquals(1); 13770 13771 // Cell connects again, still with score 50. Back to the previous state. 13772 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 13773 mCellNetworkAgent.connect(true); 13774 expectNoRequestChanged(oemPaidFactory); 13775 oemPaidFactory.assertRequestCountEquals(1); 13776 internetFactory.expectRequestRemove(); 13777 internetFactory.assertRequestCountEquals(0); 13778 13779 // Create a request that holds the upcoming wifi network. 13780 final TestNetworkCallback wifiCallback = new TestNetworkCallback(); 13781 mCm.requestNetwork(new NetworkRequest.Builder().addTransportType(TRANSPORT_WIFI).build(), 13782 wifiCallback); 13783 13784 // Now WiFi connects and it's unmetered, but it's weaker than cell. 13785 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 13786 mWiFiNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED); 13787 mWiFiNetworkAgent.setScore(new NetworkScore.Builder().setLegacyInt(30).setExiting(true) 13788 .build()); // Not the best Internet network, but unmetered 13789 mWiFiNetworkAgent.connect(true); 13790 13791 // The OEM_PAID preference prefers an unmetered network to an OEM_PAID network, so 13792 // the oemPaidFactory can't beat wifi no matter how high its score. 13793 oemPaidFactory.expectRequestRemove(); 13794 expectNoRequestChanged(internetFactory); 13795 13796 mCellNetworkAgent.disconnect(); 13797 // Now that the best internet network (cell, with its 50 score compared to 30 for WiFi 13798 // at this point), the default internet request is satisfied by a network worse than 13799 // the internetFactory announced, so it gets the request. However, there is still an 13800 // unmetered network, so the oemPaidNetworkFactory still can't beat this. 13801 expectNoRequestChanged(oemPaidFactory); 13802 internetFactory.expectRequestAdd(); 13803 mCm.unregisterNetworkCallback(wifiCallback); 13804 } 13805 13806 /** 13807 * Test network priority for OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK in the following order: 13808 * NET_CAPABILITY_NOT_METERED -> NET_CAPABILITY_OEM_PAID 13809 */ 13810 @Test 13811 public void testMultipleDefaultNetworksTracksOemNetworkPreferenceOemPaidNoFallbackCorrectly() 13812 throws Exception { 13813 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 13814 OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK; 13815 setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest(networkPref); 13816 final int expectedDefaultRequestSize = 2; 13817 final int expectedOemPrefRequestSize = 2; 13818 registerDefaultNetworkCallbacks(); 13819 13820 // The fallback as well as the OEM preference should now be tracked. 13821 assertEquals(expectedDefaultRequestSize, mService.mDefaultNetworkRequests.size()); 13822 13823 // Test lowest to highest priority requests. 13824 // Bring up metered cellular. This will satisfy the fallback network but not the pref. 13825 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); 13826 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 13827 mCellNetworkAgent.getNetwork(), 13828 mService.mNoServiceNetwork.network()); 13829 13830 // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID. 13831 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true); 13832 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 13833 mCellNetworkAgent.getNetwork(), 13834 mEthernetNetworkAgent.getNetwork()); 13835 13836 // Bring up unmetered Wi-Fi. This will satisfy NET_CAPABILITY_NOT_METERED. 13837 setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, true); 13838 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 13839 mWiFiNetworkAgent.getNetwork(), 13840 mWiFiNetworkAgent.getNetwork()); 13841 13842 // Disconnecting unmetered Wi-Fi will put the OEM pref on OEM_PAID and fallback on cellular. 13843 setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, false); 13844 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 13845 mCellNetworkAgent.getNetwork(), 13846 mEthernetNetworkAgent.getNetwork()); 13847 13848 // Disconnecting cellular should keep OEM network on OEM_PAID and fallback will be null. 13849 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, false); 13850 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 13851 null, 13852 mEthernetNetworkAgent.getNetwork()); 13853 13854 // Disconnecting OEM_PAID puts the fallback on null and the pref on the disconnected net. 13855 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, false); 13856 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 13857 null, 13858 mService.mNoServiceNetwork.network()); 13859 13860 // default callbacks will be unregistered in tearDown 13861 } 13862 13863 /** 13864 * Test network priority for OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY in the following order: 13865 * NET_CAPABILITY_OEM_PAID 13866 * This preference should only apply to OEM_PAID networks. 13867 */ 13868 @Test 13869 public void testMultipleDefaultNetworksTracksOemNetworkPreferenceOemPaidOnlyCorrectly() 13870 throws Exception { 13871 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 13872 OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY; 13873 setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest(networkPref); 13874 final int expectedDefaultRequestSize = 2; 13875 final int expectedOemPrefRequestSize = 1; 13876 registerDefaultNetworkCallbacks(); 13877 13878 // The fallback as well as the OEM preference should now be tracked. 13879 assertEquals(expectedDefaultRequestSize, mService.mDefaultNetworkRequests.size()); 13880 13881 // Test lowest to highest priority requests. 13882 // Bring up metered cellular. This will satisfy the fallback network. 13883 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); 13884 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 13885 mCellNetworkAgent.getNetwork(), 13886 mService.mNoServiceNetwork.network()); 13887 13888 // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID. 13889 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true); 13890 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 13891 mCellNetworkAgent.getNetwork(), 13892 mEthernetNetworkAgent.getNetwork()); 13893 13894 // Bring up unmetered Wi-Fi. The OEM network shouldn't change, the fallback will take Wi-Fi. 13895 setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, true); 13896 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 13897 mWiFiNetworkAgent.getNetwork(), 13898 mEthernetNetworkAgent.getNetwork()); 13899 13900 // Disconnecting unmetered Wi-Fi shouldn't change the OEM network with fallback on cellular. 13901 setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, false); 13902 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 13903 mCellNetworkAgent.getNetwork(), 13904 mEthernetNetworkAgent.getNetwork()); 13905 13906 // Disconnecting OEM_PAID will keep the fallback on cellular and nothing for OEM_PAID. 13907 // OEM_PAID_ONLY not supporting a fallback now uses the disconnected network. 13908 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, false); 13909 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 13910 mCellNetworkAgent.getNetwork(), 13911 mService.mNoServiceNetwork.network()); 13912 13913 // Disconnecting cellular will put the fallback on null and the pref on disconnected. 13914 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, false); 13915 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 13916 null, 13917 mService.mNoServiceNetwork.network()); 13918 13919 // default callbacks will be unregistered in tearDown 13920 } 13921 13922 /** 13923 * Test network priority for OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY in the following order: 13924 * NET_CAPABILITY_OEM_PRIVATE 13925 * This preference should only apply to OEM_PRIVATE networks. 13926 */ 13927 @Test 13928 public void testMultipleDefaultNetworksTracksOemNetworkPreferenceOemPrivateOnlyCorrectly() 13929 throws Exception { 13930 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 13931 OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY; 13932 setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest(networkPref); 13933 final int expectedDefaultRequestSize = 2; 13934 final int expectedOemPrefRequestSize = 1; 13935 registerDefaultNetworkCallbacks(); 13936 13937 // The fallback as well as the OEM preference should now be tracked. 13938 assertEquals(expectedDefaultRequestSize, mService.mDefaultNetworkRequests.size()); 13939 13940 // Test lowest to highest priority requests. 13941 // Bring up metered cellular. This will satisfy the fallback network. 13942 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); 13943 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 13944 mCellNetworkAgent.getNetwork(), 13945 mService.mNoServiceNetwork.network()); 13946 13947 // Bring up ethernet with OEM_PRIVATE. This will satisfy NET_CAPABILITY_OEM_PRIVATE. 13948 startOemManagedNetwork(false); 13949 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 13950 mCellNetworkAgent.getNetwork(), 13951 mEthernetNetworkAgent.getNetwork()); 13952 13953 // Bring up unmetered Wi-Fi. The OEM network shouldn't change, the fallback will take Wi-Fi. 13954 setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, true); 13955 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 13956 mWiFiNetworkAgent.getNetwork(), 13957 mEthernetNetworkAgent.getNetwork()); 13958 13959 // Disconnecting unmetered Wi-Fi shouldn't change the OEM network with fallback on cellular. 13960 setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, false); 13961 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 13962 mCellNetworkAgent.getNetwork(), 13963 mEthernetNetworkAgent.getNetwork()); 13964 13965 // Disconnecting OEM_PRIVATE will keep the fallback on cellular. 13966 // OEM_PRIVATE_ONLY not supporting a fallback now uses to the disconnected network. 13967 stopOemManagedNetwork(); 13968 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 13969 mCellNetworkAgent.getNetwork(), 13970 mService.mNoServiceNetwork.network()); 13971 13972 // Disconnecting cellular will put the fallback on null and pref on disconnected. 13973 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, false); 13974 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 13975 null, 13976 mService.mNoServiceNetwork.network()); 13977 13978 // default callbacks will be unregistered in tearDown 13979 } 13980 13981 @Test 13982 public void testCapabilityWithOemNetworkPreference() throws Exception { 13983 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 13984 OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY; 13985 setupMultipleDefaultNetworksForOemNetworkPreferenceNotCurrentUidTest(networkPref); 13986 registerDefaultNetworkCallbacks(); 13987 13988 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); 13989 13990 mSystemDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 13991 mDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 13992 13993 mCellNetworkAgent.addCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED); 13994 mSystemDefaultNetworkCallback.expectCapabilitiesThat(mCellNetworkAgent, nc -> 13995 nc.hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED)); 13996 mDefaultNetworkCallback.expectCapabilitiesThat(mCellNetworkAgent, nc -> 13997 nc.hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED)); 13998 13999 // default callbacks will be unregistered in tearDown 14000 } 14001 14002 @Test 14003 public void testSetOemNetworkPreferenceLogsRequest() throws Exception { 14004 mServiceContext.setPermission(DUMP, PERMISSION_GRANTED); 14005 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 14006 OEM_NETWORK_PREFERENCE_OEM_PAID; 14007 final StringWriter stringWriter = new StringWriter(); 14008 final String logIdentifier = "UPDATE INITIATED: OemNetworkPreferences"; 14009 final Pattern pattern = Pattern.compile(logIdentifier); 14010 14011 final int expectedNumLogs = 2; 14012 final UidRangeParcel[] uidRanges = 14013 toUidRangeStableParcels(uidRangesForUids(TEST_PACKAGE_UID)); 14014 14015 // Call twice to generate two logs. 14016 setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges, TEST_PACKAGE_NAME); 14017 setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges, TEST_PACKAGE_NAME); 14018 mService.dump(new FileDescriptor(), new PrintWriter(stringWriter), new String[0]); 14019 14020 final String dumpOutput = stringWriter.toString(); 14021 final Matcher matcher = pattern.matcher(dumpOutput); 14022 int count = 0; 14023 while (matcher.find()) { 14024 count++; 14025 } 14026 assertEquals(expectedNumLogs, count); 14027 } 14028 14029 @Test 14030 public void testGetAllNetworkStateSnapshots() throws Exception { 14031 verifyNoNetwork(); 14032 14033 // Setup test cellular network with specified LinkProperties and NetworkCapabilities, 14034 // verify the content of the snapshot matches. 14035 final LinkProperties cellLp = new LinkProperties(); 14036 final LinkAddress myIpv4Addr = new LinkAddress(InetAddress.getByName("192.0.2.129"), 25); 14037 final LinkAddress myIpv6Addr = new LinkAddress(InetAddress.getByName("2001:db8::1"), 64); 14038 cellLp.setInterfaceName("test01"); 14039 cellLp.addLinkAddress(myIpv4Addr); 14040 cellLp.addLinkAddress(myIpv6Addr); 14041 cellLp.addRoute(new RouteInfo(InetAddress.getByName("fe80::1234"))); 14042 cellLp.addRoute(new RouteInfo(InetAddress.getByName("192.0.2.254"))); 14043 cellLp.addRoute(new RouteInfo(myIpv4Addr, null)); 14044 cellLp.addRoute(new RouteInfo(myIpv6Addr, null)); 14045 final NetworkCapabilities cellNcTemplate = new NetworkCapabilities.Builder() 14046 .addTransportType(TRANSPORT_CELLULAR).addCapability(NET_CAPABILITY_MMS).build(); 14047 14048 final TestNetworkCallback cellCb = new TestNetworkCallback(); 14049 mCm.requestNetwork(new NetworkRequest.Builder().addCapability(NET_CAPABILITY_MMS).build(), 14050 cellCb); 14051 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp, cellNcTemplate); 14052 mCellNetworkAgent.connect(true); 14053 cellCb.expectAvailableCallbacksUnvalidated(mCellNetworkAgent); 14054 List<NetworkStateSnapshot> snapshots = mCm.getAllNetworkStateSnapshots(); 14055 assertLength(1, snapshots); 14056 14057 // Compose the expected cellular snapshot for verification. 14058 final NetworkCapabilities cellNc = 14059 mCm.getNetworkCapabilities(mCellNetworkAgent.getNetwork()); 14060 final NetworkStateSnapshot cellSnapshot = new NetworkStateSnapshot( 14061 mCellNetworkAgent.getNetwork(), cellNc, cellLp, 14062 null, ConnectivityManager.TYPE_MOBILE); 14063 assertEquals(cellSnapshot, snapshots.get(0)); 14064 14065 // Connect wifi and verify the snapshots. 14066 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 14067 mWiFiNetworkAgent.connect(true); 14068 waitForIdle(); 14069 // Compose the expected wifi snapshot for verification. 14070 final NetworkCapabilities wifiNc = 14071 mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()); 14072 final NetworkStateSnapshot wifiSnapshot = new NetworkStateSnapshot( 14073 mWiFiNetworkAgent.getNetwork(), wifiNc, new LinkProperties(), null, 14074 ConnectivityManager.TYPE_WIFI); 14075 14076 snapshots = mCm.getAllNetworkStateSnapshots(); 14077 assertLength(2, snapshots); 14078 assertContainsAll(snapshots, cellSnapshot, wifiSnapshot); 14079 14080 // Set cellular as suspended, verify the snapshots will contain suspended networks. 14081 mCellNetworkAgent.suspend(); 14082 waitForIdle(); 14083 final NetworkCapabilities cellSuspendedNc = 14084 mCm.getNetworkCapabilities(mCellNetworkAgent.getNetwork()); 14085 assertFalse(cellSuspendedNc.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 14086 final NetworkStateSnapshot cellSuspendedSnapshot = new NetworkStateSnapshot( 14087 mCellNetworkAgent.getNetwork(), cellSuspendedNc, cellLp, 14088 null, ConnectivityManager.TYPE_MOBILE); 14089 snapshots = mCm.getAllNetworkStateSnapshots(); 14090 assertLength(2, snapshots); 14091 assertContainsAll(snapshots, cellSuspendedSnapshot, wifiSnapshot); 14092 14093 // Disconnect wifi, verify the snapshots contain only cellular. 14094 mWiFiNetworkAgent.disconnect(); 14095 waitForIdle(); 14096 snapshots = mCm.getAllNetworkStateSnapshots(); 14097 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 14098 assertLength(1, snapshots); 14099 assertEquals(cellSuspendedSnapshot, snapshots.get(0)); 14100 14101 mCellNetworkAgent.resume(); 14102 waitForIdle(); 14103 snapshots = mCm.getAllNetworkStateSnapshots(); 14104 assertLength(1, snapshots); 14105 assertEquals(cellSnapshot, snapshots.get(0)); 14106 14107 mCellNetworkAgent.disconnect(); 14108 waitForIdle(); 14109 verifyNoNetwork(); 14110 mCm.unregisterNetworkCallback(cellCb); 14111 } 14112 14113 // Cannot be part of MockNetworkFactory since it requires method of the test. 14114 private void expectNoRequestChanged(@NonNull MockNetworkFactory factory) { 14115 waitForIdle(); 14116 factory.assertNoRequestChanged(); 14117 } 14118 14119 @Test 14120 public void testRegisterBestMatchingNetworkCallback_noIssueToFactory() throws Exception { 14121 // Prepare mock mms factory. 14122 final HandlerThread handlerThread = new HandlerThread("MockCellularFactory"); 14123 handlerThread.start(); 14124 NetworkCapabilities filter = new NetworkCapabilities() 14125 .addTransportType(TRANSPORT_CELLULAR) 14126 .addCapability(NET_CAPABILITY_MMS); 14127 final MockNetworkFactory testFactory = new MockNetworkFactory(handlerThread.getLooper(), 14128 mServiceContext, "testFactory", filter, mCsHandlerThread); 14129 testFactory.setScoreFilter(40); 14130 14131 try { 14132 // Register the factory. It doesn't see the default request because its filter does 14133 // not include INTERNET. 14134 testFactory.register(); 14135 expectNoRequestChanged(testFactory); 14136 testFactory.assertRequestCountEquals(0); 14137 // The factory won't try to start the network since the default request doesn't 14138 // match the filter (no INTERNET capability). 14139 assertFalse(testFactory.getMyStartRequested()); 14140 14141 // Register callback for listening best matching network. Verify that the request won't 14142 // be sent to factory. 14143 final TestNetworkCallback bestMatchingCb = new TestNetworkCallback(); 14144 mCm.registerBestMatchingNetworkCallback( 14145 new NetworkRequest.Builder().addCapability(NET_CAPABILITY_MMS).build(), 14146 bestMatchingCb, mCsHandlerThread.getThreadHandler()); 14147 bestMatchingCb.assertNoCallback(); 14148 expectNoRequestChanged(testFactory); 14149 testFactory.assertRequestCountEquals(0); 14150 assertFalse(testFactory.getMyStartRequested()); 14151 14152 // Fire a normal mms request, verify the factory will only see the request. 14153 final TestNetworkCallback mmsNetworkCallback = new TestNetworkCallback(); 14154 final NetworkRequest mmsRequest = new NetworkRequest.Builder() 14155 .addCapability(NET_CAPABILITY_MMS).build(); 14156 mCm.requestNetwork(mmsRequest, mmsNetworkCallback); 14157 testFactory.expectRequestAdd(); 14158 testFactory.assertRequestCountEquals(1); 14159 assertTrue(testFactory.getMyStartRequested()); 14160 14161 // Unregister best matching callback, verify factory see no change. 14162 mCm.unregisterNetworkCallback(bestMatchingCb); 14163 expectNoRequestChanged(testFactory); 14164 testFactory.assertRequestCountEquals(1); 14165 assertTrue(testFactory.getMyStartRequested()); 14166 } finally { 14167 testFactory.terminate(); 14168 } 14169 } 14170 14171 @Test 14172 public void testRegisterBestMatchingNetworkCallback_trackBestNetwork() throws Exception { 14173 final TestNetworkCallback bestMatchingCb = new TestNetworkCallback(); 14174 mCm.registerBestMatchingNetworkCallback( 14175 new NetworkRequest.Builder().addCapability(NET_CAPABILITY_TRUSTED).build(), 14176 bestMatchingCb, mCsHandlerThread.getThreadHandler()); 14177 14178 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 14179 mCellNetworkAgent.connect(true); 14180 bestMatchingCb.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 14181 14182 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 14183 mWiFiNetworkAgent.connect(true); 14184 bestMatchingCb.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent); 14185 14186 // Change something on cellular to trigger capabilities changed, since the callback 14187 // only cares about the best network, verify it received nothing from cellular. 14188 mCellNetworkAgent.addCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED); 14189 bestMatchingCb.assertNoCallback(); 14190 14191 // Make cellular the best network again, verify the callback now tracks cellular. 14192 mWiFiNetworkAgent.adjustScore(-50); 14193 bestMatchingCb.expectAvailableCallbacksValidated(mCellNetworkAgent); 14194 14195 // Make cellular temporary non-trusted, which will not satisfying the request. 14196 // Verify the callback switch from/to the other network accordingly. 14197 mCellNetworkAgent.removeCapability(NET_CAPABILITY_TRUSTED); 14198 bestMatchingCb.expectAvailableCallbacksValidated(mWiFiNetworkAgent); 14199 mCellNetworkAgent.addCapability(NET_CAPABILITY_TRUSTED); 14200 bestMatchingCb.expectAvailableDoubleValidatedCallbacks(mCellNetworkAgent); 14201 14202 // Verify the callback doesn't care about wifi disconnect. 14203 mWiFiNetworkAgent.disconnect(); 14204 bestMatchingCb.assertNoCallback(); 14205 mCellNetworkAgent.disconnect(); 14206 bestMatchingCb.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 14207 } 14208 14209 private UidRangeParcel[] uidRangeFor(final UserHandle handle) { 14210 final UidRange range = UidRange.createForUser(handle); 14211 return new UidRangeParcel[] { new UidRangeParcel(range.start, range.stop) }; 14212 } 14213 14214 private UidRangeParcel[] uidRangeFor(final UserHandle handle, 14215 ProfileNetworkPreference profileNetworkPreference) { 14216 final Set<UidRange> uidRangeSet; 14217 UidRange range = UidRange.createForUser(handle); 14218 if (profileNetworkPreference.getIncludedUids().length != 0) { 14219 uidRangeSet = UidRangeUtils.convertArrayToUidRange( 14220 profileNetworkPreference.getIncludedUids()); 14221 14222 } else if (profileNetworkPreference.getExcludedUids().length != 0) { 14223 uidRangeSet = UidRangeUtils.removeRangeSetFromUidRange( 14224 range, UidRangeUtils.convertArrayToUidRange( 14225 profileNetworkPreference.getExcludedUids())); 14226 } else { 14227 uidRangeSet = new ArraySet<>(); 14228 uidRangeSet.add(range); 14229 } 14230 UidRangeParcel[] uidRangeParcels = new UidRangeParcel[uidRangeSet.size()]; 14231 int i = 0; 14232 for (UidRange range1 : uidRangeSet) { 14233 uidRangeParcels[i] = new UidRangeParcel(range1.start, range1.stop); 14234 i++; 14235 } 14236 return uidRangeParcels; 14237 } 14238 14239 private static class TestOnCompleteListener implements Runnable { 14240 final class OnComplete {} 14241 final ArrayTrackRecord<OnComplete>.ReadHead mHistory = 14242 new ArrayTrackRecord<OnComplete>().newReadHead(); 14243 14244 @Override 14245 public void run() { 14246 mHistory.add(new OnComplete()); 14247 } 14248 14249 public void expectOnComplete() { 14250 assertNotNull(mHistory.poll(TIMEOUT_MS, it -> true)); 14251 } 14252 } 14253 14254 private TestNetworkAgentWrapper makeEnterpriseNetworkAgent() throws Exception { 14255 final NetworkCapabilities workNc = new NetworkCapabilities(); 14256 workNc.addCapability(NET_CAPABILITY_ENTERPRISE); 14257 workNc.removeCapability(NET_CAPABILITY_NOT_RESTRICTED); 14258 return new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, new LinkProperties(), workNc); 14259 } 14260 14261 private TestNetworkAgentWrapper makeEnterpriseNetworkAgent(int enterpriseId) throws Exception { 14262 final NetworkCapabilities workNc = new NetworkCapabilities(); 14263 workNc.addCapability(NET_CAPABILITY_ENTERPRISE); 14264 workNc.removeCapability(NET_CAPABILITY_NOT_RESTRICTED); 14265 workNc.addEnterpriseId(enterpriseId); 14266 return new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, new LinkProperties(), workNc); 14267 } 14268 14269 private TestNetworkCallback mEnterpriseCallback; 14270 private UserHandle setupEnterpriseNetwork() { 14271 final UserHandle userHandle = UserHandle.of(TEST_WORK_PROFILE_USER_ID); 14272 mServiceContext.setWorkProfile(userHandle, true); 14273 14274 // File a request to avoid the enterprise network being disconnected as soon as the default 14275 // request goes away – it would make impossible to test that networkRemoveUidRanges 14276 // is called, as the network would disconnect first for lack of a request. 14277 mEnterpriseCallback = new TestNetworkCallback(); 14278 final NetworkRequest keepUpRequest = new NetworkRequest.Builder() 14279 .addCapability(NET_CAPABILITY_ENTERPRISE) 14280 .build(); 14281 mCm.requestNetwork(keepUpRequest, mEnterpriseCallback); 14282 return userHandle; 14283 } 14284 14285 private void maybeTearDownEnterpriseNetwork() { 14286 if (null != mEnterpriseCallback) { 14287 mCm.unregisterNetworkCallback(mEnterpriseCallback); 14288 } 14289 } 14290 14291 /** 14292 * Make sure per profile network preferences behave as expected for a given 14293 * profile network preference. 14294 */ 14295 public void testPreferenceForUserNetworkUpDownForGivenPreference( 14296 ProfileNetworkPreference profileNetworkPreference, 14297 boolean connectWorkProfileAgentAhead, 14298 UserHandle testHandle, 14299 TestNetworkCallback profileDefaultNetworkCallback, 14300 TestNetworkCallback disAllowProfileDefaultNetworkCallback) throws Exception { 14301 final InOrder inOrder = inOrder(mMockNetd); 14302 14303 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 14304 mCellNetworkAgent.connect(true); 14305 14306 mSystemDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 14307 mDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 14308 profileDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 14309 if (disAllowProfileDefaultNetworkCallback != null) { 14310 disAllowProfileDefaultNetworkCallback.expectAvailableThenValidatedCallbacks( 14311 mCellNetworkAgent); 14312 } 14313 inOrder.verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( 14314 mCellNetworkAgent.getNetwork().netId, INetd.PERMISSION_NONE)); 14315 14316 final TestNetworkAgentWrapper workAgent = 14317 makeEnterpriseNetworkAgent(profileNetworkPreference.getPreferenceEnterpriseId()); 14318 if (connectWorkProfileAgentAhead) { 14319 workAgent.connect(false); 14320 } 14321 14322 final TestOnCompleteListener listener = new TestOnCompleteListener(); 14323 mCm.setProfileNetworkPreferences(testHandle, List.of(profileNetworkPreference), 14324 r -> r.run(), listener); 14325 listener.expectOnComplete(); 14326 boolean allowFallback = true; 14327 if (profileNetworkPreference.getPreference() 14328 == PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK) { 14329 allowFallback = false; 14330 } 14331 if (allowFallback && !connectWorkProfileAgentAhead) { 14332 // Setting a network preference for this user will create a new set of routing rules for 14333 // the UID range that corresponds to this user, inorder to define the default network 14334 // for these apps separately. This is true because the multi-layer request relevant to 14335 // this UID range contains a TRACK_DEFAULT, so the range will be moved through 14336 // UID-specific rules to the correct network – in this case the system default network. 14337 // The case where the default network for the profile happens to be the same as the 14338 // system default is not handled specially, the rules are always active as long as 14339 // a preference is set. 14340 inOrder.verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 14341 mCellNetworkAgent.getNetwork().netId, 14342 uidRangeFor(testHandle, profileNetworkPreference), 14343 PREFERENCE_ORDER_PROFILE)); 14344 } 14345 14346 // The enterprise network is not ready yet. 14347 assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback); 14348 if (allowFallback && !connectWorkProfileAgentAhead) { 14349 assertNoCallbacks(profileDefaultNetworkCallback); 14350 } else if (!connectWorkProfileAgentAhead) { 14351 profileDefaultNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 14352 if (disAllowProfileDefaultNetworkCallback != null) { 14353 assertNoCallbacks(disAllowProfileDefaultNetworkCallback); 14354 } 14355 } 14356 14357 if (!connectWorkProfileAgentAhead) { 14358 workAgent.connect(false); 14359 } 14360 14361 profileDefaultNetworkCallback.expectAvailableCallbacksUnvalidated(workAgent); 14362 if (disAllowProfileDefaultNetworkCallback != null) { 14363 disAllowProfileDefaultNetworkCallback.assertNoCallback(); 14364 } 14365 mSystemDefaultNetworkCallback.assertNoCallback(); 14366 mDefaultNetworkCallback.assertNoCallback(); 14367 inOrder.verify(mMockNetd).networkCreate( 14368 nativeNetworkConfigPhysical(workAgent.getNetwork().netId, INetd.PERMISSION_SYSTEM)); 14369 inOrder.verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 14370 workAgent.getNetwork().netId, 14371 uidRangeFor(testHandle, profileNetworkPreference), 14372 PREFERENCE_ORDER_PROFILE)); 14373 14374 if (allowFallback && !connectWorkProfileAgentAhead) { 14375 inOrder.verify(mMockNetd).networkRemoveUidRangesParcel(new NativeUidRangeConfig( 14376 mCellNetworkAgent.getNetwork().netId, 14377 uidRangeFor(testHandle, profileNetworkPreference), 14378 PREFERENCE_ORDER_PROFILE)); 14379 } 14380 14381 // Make sure changes to the work agent send callbacks to the app in the work profile, but 14382 // not to the other apps. 14383 workAgent.setNetworkValid(true /* isStrictMode */); 14384 workAgent.mNetworkMonitor.forceReevaluation(Process.myUid()); 14385 profileDefaultNetworkCallback.expectCapabilitiesThat(workAgent, 14386 nc -> nc.hasCapability(NET_CAPABILITY_VALIDATED) 14387 && nc.hasCapability(NET_CAPABILITY_ENTERPRISE) 14388 && nc.hasEnterpriseId( 14389 profileNetworkPreference.getPreferenceEnterpriseId()) 14390 && nc.getEnterpriseIds().length == 1); 14391 if (disAllowProfileDefaultNetworkCallback != null) { 14392 assertNoCallbacks(disAllowProfileDefaultNetworkCallback); 14393 } 14394 assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback); 14395 14396 workAgent.addCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED); 14397 profileDefaultNetworkCallback.expectCapabilitiesThat(workAgent, nc -> 14398 nc.hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED)); 14399 if (disAllowProfileDefaultNetworkCallback != null) { 14400 assertNoCallbacks(disAllowProfileDefaultNetworkCallback); 14401 } 14402 assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback); 14403 14404 // Conversely, change a capability on the system-wide default network and make sure 14405 // that only the apps outside of the work profile receive the callbacks. 14406 mCellNetworkAgent.addCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED); 14407 mSystemDefaultNetworkCallback.expectCapabilitiesThat(mCellNetworkAgent, nc -> 14408 nc.hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED)); 14409 mDefaultNetworkCallback.expectCapabilitiesThat(mCellNetworkAgent, nc -> 14410 nc.hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED)); 14411 if (disAllowProfileDefaultNetworkCallback != null) { 14412 disAllowProfileDefaultNetworkCallback.expectCapabilitiesThat(mCellNetworkAgent, nc -> 14413 nc.hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED)); 14414 } 14415 profileDefaultNetworkCallback.assertNoCallback(); 14416 14417 // Disconnect and reconnect the system-wide default network and make sure that the 14418 // apps on this network see the appropriate callbacks, and the app on the work profile 14419 // doesn't because it continues to use the enterprise network. 14420 mCellNetworkAgent.disconnect(); 14421 mSystemDefaultNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 14422 mDefaultNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 14423 if (disAllowProfileDefaultNetworkCallback != null) { 14424 disAllowProfileDefaultNetworkCallback.expectCallback( 14425 CallbackEntry.LOST, mCellNetworkAgent); 14426 } 14427 profileDefaultNetworkCallback.assertNoCallback(); 14428 inOrder.verify(mMockNetd).networkDestroy(mCellNetworkAgent.getNetwork().netId); 14429 14430 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 14431 mCellNetworkAgent.connect(true); 14432 mSystemDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 14433 mDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 14434 if (disAllowProfileDefaultNetworkCallback != null) { 14435 disAllowProfileDefaultNetworkCallback.expectAvailableThenValidatedCallbacks( 14436 mCellNetworkAgent); 14437 14438 } 14439 profileDefaultNetworkCallback.assertNoCallback(); 14440 inOrder.verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( 14441 mCellNetworkAgent.getNetwork().netId, INetd.PERMISSION_NONE)); 14442 14443 // When the agent disconnects, test that the app on the work profile falls back to the 14444 // default network. 14445 workAgent.disconnect(); 14446 profileDefaultNetworkCallback.expectCallback(CallbackEntry.LOST, workAgent); 14447 if (allowFallback) { 14448 profileDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellNetworkAgent); 14449 if (disAllowProfileDefaultNetworkCallback != null) { 14450 assertNoCallbacks(disAllowProfileDefaultNetworkCallback); 14451 } 14452 } 14453 assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback); 14454 if (allowFallback) { 14455 inOrder.verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 14456 mCellNetworkAgent.getNetwork().netId, 14457 uidRangeFor(testHandle, profileNetworkPreference), 14458 PREFERENCE_ORDER_PROFILE)); 14459 } 14460 inOrder.verify(mMockNetd).networkDestroy(workAgent.getNetwork().netId); 14461 14462 mCellNetworkAgent.disconnect(); 14463 mSystemDefaultNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 14464 mDefaultNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 14465 if (disAllowProfileDefaultNetworkCallback != null) { 14466 disAllowProfileDefaultNetworkCallback.expectCallback( 14467 CallbackEntry.LOST, mCellNetworkAgent); 14468 } 14469 if (allowFallback) { 14470 profileDefaultNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 14471 } 14472 14473 // Waiting for the handler to be idle before checking for networkDestroy is necessary 14474 // here because ConnectivityService calls onLost before the network is fully torn down. 14475 waitForIdle(); 14476 inOrder.verify(mMockNetd).networkDestroy(mCellNetworkAgent.getNetwork().netId); 14477 14478 // If the control comes here, callbacks seem to behave correctly in the presence of 14479 // a default network when the enterprise network goes up and down. Now, make sure they 14480 // also behave correctly in the absence of a system-wide default network. 14481 final TestNetworkAgentWrapper workAgent2 = 14482 makeEnterpriseNetworkAgent(profileNetworkPreference.getPreferenceEnterpriseId()); 14483 workAgent2.connect(false); 14484 14485 profileDefaultNetworkCallback.expectAvailableCallbacksUnvalidated(workAgent2); 14486 if (disAllowProfileDefaultNetworkCallback != null) { 14487 assertNoCallbacks(disAllowProfileDefaultNetworkCallback); 14488 } 14489 assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback); 14490 inOrder.verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( 14491 workAgent2.getNetwork().netId, INetd.PERMISSION_SYSTEM)); 14492 inOrder.verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 14493 workAgent2.getNetwork().netId, 14494 uidRangeFor(testHandle, profileNetworkPreference), PREFERENCE_ORDER_PROFILE)); 14495 14496 workAgent2.setNetworkValid(true /* isStrictMode */); 14497 workAgent2.mNetworkMonitor.forceReevaluation(Process.myUid()); 14498 profileDefaultNetworkCallback.expectCapabilitiesThat(workAgent2, 14499 nc -> nc.hasCapability(NET_CAPABILITY_ENTERPRISE) 14500 && !nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED) 14501 && nc.hasEnterpriseId( 14502 profileNetworkPreference.getPreferenceEnterpriseId()) 14503 && nc.getEnterpriseIds().length == 1); 14504 if (disAllowProfileDefaultNetworkCallback != null) { 14505 assertNoCallbacks(disAllowProfileDefaultNetworkCallback); 14506 } 14507 assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback); 14508 inOrder.verify(mMockNetd, never()).networkAddUidRangesParcel(any()); 14509 14510 // When the agent disconnects, test that the app on the work profile fall back to the 14511 // default network. 14512 workAgent2.disconnect(); 14513 profileDefaultNetworkCallback.expectCallback(CallbackEntry.LOST, workAgent2); 14514 if (disAllowProfileDefaultNetworkCallback != null) { 14515 assertNoCallbacks(disAllowProfileDefaultNetworkCallback); 14516 } 14517 assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback); 14518 inOrder.verify(mMockNetd).networkDestroy(workAgent2.getNetwork().netId); 14519 14520 assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback, 14521 profileDefaultNetworkCallback); 14522 14523 // Callbacks will be unregistered by tearDown() 14524 } 14525 14526 /** 14527 * Make sure per-profile networking preference behaves as expected when the enterprise network 14528 * goes up and down while the preference is active. Make sure they behave as expected whether 14529 * there is a general default network or not. 14530 */ 14531 @Test 14532 public void testPreferenceForUserNetworkUpDown() throws Exception { 14533 final UserHandle testHandle = setupEnterpriseNetwork(); 14534 registerDefaultNetworkCallbacks(); 14535 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder = 14536 new ProfileNetworkPreference.Builder(); 14537 profileNetworkPreferenceBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE); 14538 profileNetworkPreferenceBuilder.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1); 14539 testPreferenceForUserNetworkUpDownForGivenPreference( 14540 profileNetworkPreferenceBuilder.build(), false, 14541 testHandle, mProfileDefaultNetworkCallback, null); 14542 } 14543 14544 /** 14545 * Make sure per-profile networking preference behaves as expected when the enterprise network 14546 * goes up and down while the preference is active. Make sure they behave as expected whether 14547 * there is a general default network or not when configured to not fallback to default network. 14548 */ 14549 @Test 14550 public void testPreferenceForUserNetworkUpDownWithNoFallback() throws Exception { 14551 final UserHandle testHandle = setupEnterpriseNetwork(); 14552 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder = 14553 new ProfileNetworkPreference.Builder(); 14554 profileNetworkPreferenceBuilder.setPreference( 14555 PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK); 14556 profileNetworkPreferenceBuilder.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1); 14557 registerDefaultNetworkCallbacks(); 14558 testPreferenceForUserNetworkUpDownForGivenPreference( 14559 profileNetworkPreferenceBuilder.build(), false, 14560 testHandle, mProfileDefaultNetworkCallback, null); 14561 } 14562 14563 /** 14564 * Make sure per-profile networking preference behaves as expected when the enterprise network 14565 * goes up and down while the preference is active. Make sure they behave as expected whether 14566 * there is a general default network or not when configured to not fallback to default network 14567 * along with already connected enterprise work agent 14568 */ 14569 @Test 14570 public void testPreferenceForUserNetworkUpDownWithNoFallbackWithAlreadyConnectedWorkAgent() 14571 throws Exception { 14572 final UserHandle testHandle = setupEnterpriseNetwork(); 14573 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder = 14574 new ProfileNetworkPreference.Builder(); 14575 profileNetworkPreferenceBuilder.setPreference( 14576 PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK); 14577 profileNetworkPreferenceBuilder.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1); 14578 registerDefaultNetworkCallbacks(); 14579 testPreferenceForUserNetworkUpDownForGivenPreference( 14580 profileNetworkPreferenceBuilder.build(), true, testHandle, 14581 mProfileDefaultNetworkCallback, null); 14582 } 14583 14584 /** 14585 * Make sure per-profile networking preference for specific uid of test handle 14586 * behaves as expected 14587 */ 14588 @Test 14589 public void testPreferenceForDefaultUidOfTestHandle() throws Exception { 14590 final UserHandle testHandle = setupEnterpriseNetwork(); 14591 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder = 14592 new ProfileNetworkPreference.Builder(); 14593 profileNetworkPreferenceBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE); 14594 profileNetworkPreferenceBuilder.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1); 14595 profileNetworkPreferenceBuilder.setIncludedUids( 14596 new int[]{testHandle.getUid(TEST_WORK_PROFILE_APP_UID)}); 14597 registerDefaultNetworkCallbacks(); 14598 testPreferenceForUserNetworkUpDownForGivenPreference( 14599 profileNetworkPreferenceBuilder.build(), false, testHandle, 14600 mProfileDefaultNetworkCallback, null); 14601 } 14602 14603 /** 14604 * Make sure per-profile networking preference for specific uid of test handle 14605 * behaves as expected 14606 */ 14607 @Test 14608 public void testPreferenceForSpecificUidOfOnlyOneApp() throws Exception { 14609 final UserHandle testHandle = setupEnterpriseNetwork(); 14610 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder = 14611 new ProfileNetworkPreference.Builder(); 14612 profileNetworkPreferenceBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE); 14613 profileNetworkPreferenceBuilder.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1); 14614 profileNetworkPreferenceBuilder.setIncludedUids( 14615 new int[]{testHandle.getUid(TEST_WORK_PROFILE_APP_UID_2)}); 14616 registerDefaultNetworkCallbacks(); 14617 testPreferenceForUserNetworkUpDownForGivenPreference( 14618 profileNetworkPreferenceBuilder.build(), false, 14619 testHandle, mProfileDefaultNetworkCallbackAsAppUid2, null); 14620 } 14621 14622 /** 14623 * Make sure per-profile networking preference for specific uid of test handle 14624 * behaves as expected 14625 */ 14626 @Test 14627 public void testPreferenceForDisallowSpecificUidOfApp() throws Exception { 14628 final UserHandle testHandle = setupEnterpriseNetwork(); 14629 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder = 14630 new ProfileNetworkPreference.Builder(); 14631 profileNetworkPreferenceBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE); 14632 profileNetworkPreferenceBuilder.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1); 14633 profileNetworkPreferenceBuilder.setExcludedUids( 14634 new int[]{testHandle.getUid(TEST_WORK_PROFILE_APP_UID_2)}); 14635 registerDefaultNetworkCallbacks(); 14636 testPreferenceForUserNetworkUpDownForGivenPreference( 14637 profileNetworkPreferenceBuilder.build(), false, 14638 testHandle, mProfileDefaultNetworkCallback, 14639 mProfileDefaultNetworkCallbackAsAppUid2); 14640 } 14641 14642 /** 14643 * Make sure per-profile networking preference for specific uid of test handle 14644 * invalid uid inputs 14645 */ 14646 @Test 14647 public void testPreferenceForInvalidUids() throws Exception { 14648 final UserHandle testHandle = setupEnterpriseNetwork(); 14649 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder = 14650 new ProfileNetworkPreference.Builder(); 14651 profileNetworkPreferenceBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE); 14652 profileNetworkPreferenceBuilder.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1); 14653 profileNetworkPreferenceBuilder.setExcludedUids( 14654 new int[]{testHandle.getUid(0) - 1}); 14655 final TestOnCompleteListener listener = new TestOnCompleteListener(); 14656 Assert.assertThrows(IllegalArgumentException.class, () -> mCm.setProfileNetworkPreferences( 14657 testHandle, List.of(profileNetworkPreferenceBuilder.build()), 14658 r -> r.run(), listener)); 14659 14660 profileNetworkPreferenceBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE); 14661 profileNetworkPreferenceBuilder.setIncludedUids( 14662 new int[]{testHandle.getUid(0) - 1}); 14663 Assert.assertThrows(IllegalArgumentException.class, 14664 () -> mCm.setProfileNetworkPreferences( 14665 testHandle, List.of(profileNetworkPreferenceBuilder.build()), 14666 r -> r.run(), listener)); 14667 14668 14669 profileNetworkPreferenceBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE); 14670 profileNetworkPreferenceBuilder.setIncludedUids( 14671 new int[]{testHandle.getUid(0) - 1}); 14672 profileNetworkPreferenceBuilder.setExcludedUids( 14673 new int[]{testHandle.getUid(TEST_WORK_PROFILE_APP_UID_2)}); 14674 Assert.assertThrows(IllegalArgumentException.class, 14675 () -> mCm.setProfileNetworkPreferences( 14676 testHandle, List.of(profileNetworkPreferenceBuilder.build()), 14677 r -> r.run(), listener)); 14678 14679 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder2 = 14680 new ProfileNetworkPreference.Builder(); 14681 profileNetworkPreferenceBuilder2.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE); 14682 profileNetworkPreferenceBuilder2.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1); 14683 profileNetworkPreferenceBuilder2.setIncludedUids( 14684 new int[]{testHandle.getUid(TEST_WORK_PROFILE_APP_UID_2)}); 14685 profileNetworkPreferenceBuilder.setIncludedUids( 14686 new int[]{testHandle.getUid(TEST_WORK_PROFILE_APP_UID_2)}); 14687 Assert.assertThrows(IllegalArgumentException.class, 14688 () -> mCm.setProfileNetworkPreferences( 14689 testHandle, List.of(profileNetworkPreferenceBuilder.build(), 14690 profileNetworkPreferenceBuilder2.build()), 14691 r -> r.run(), listener)); 14692 14693 profileNetworkPreferenceBuilder2.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE); 14694 profileNetworkPreferenceBuilder2.setExcludedUids( 14695 new int[]{testHandle.getUid(TEST_WORK_PROFILE_APP_UID_2)}); 14696 profileNetworkPreferenceBuilder.setExcludedUids( 14697 new int[]{testHandle.getUid(TEST_WORK_PROFILE_APP_UID_2)}); 14698 Assert.assertThrows(IllegalArgumentException.class, 14699 () -> mCm.setProfileNetworkPreferences( 14700 testHandle, List.of(profileNetworkPreferenceBuilder.build(), 14701 profileNetworkPreferenceBuilder2.build()), 14702 r -> r.run(), listener)); 14703 14704 profileNetworkPreferenceBuilder2.setPreference( 14705 PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK); 14706 profileNetworkPreferenceBuilder2.setExcludedUids( 14707 new int[]{testHandle.getUid(TEST_WORK_PROFILE_APP_UID_2)}); 14708 profileNetworkPreferenceBuilder.setExcludedUids( 14709 new int[]{testHandle.getUid(TEST_WORK_PROFILE_APP_UID_2)}); 14710 Assert.assertThrows(IllegalArgumentException.class, 14711 () -> mCm.setProfileNetworkPreferences( 14712 testHandle, List.of(profileNetworkPreferenceBuilder.build(), 14713 profileNetworkPreferenceBuilder2.build()), 14714 r -> r.run(), listener)); 14715 } 14716 14717 /** 14718 * Make sure per-profile networking preference behaves as expected when the enterprise network 14719 * goes up and down while the preference is active. Make sure they behave as expected whether 14720 * there is a general default network or not when configured to fallback to default network 14721 * along with already connected enterprise work agent 14722 */ 14723 @Test 14724 public void testPreferenceForUserNetworkUpDownWithFallbackWithAlreadyConnectedWorkAgent() 14725 throws Exception { 14726 final UserHandle testHandle = setupEnterpriseNetwork(); 14727 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder = 14728 new ProfileNetworkPreference.Builder(); 14729 profileNetworkPreferenceBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE); 14730 profileNetworkPreferenceBuilder.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1); 14731 registerDefaultNetworkCallbacks(); 14732 testPreferenceForUserNetworkUpDownForGivenPreference( 14733 profileNetworkPreferenceBuilder.build(), true, 14734 testHandle, mProfileDefaultNetworkCallback, 14735 null); 14736 } 14737 14738 /** 14739 * Make sure per-profile networking preference behaves as expected when the enterprise network 14740 * goes up and down while the preference is active for a given enterprise identifier 14741 */ 14742 @Test 14743 public void testPreferenceForUserNetworkUpDownWithDefaultEnterpriseId() 14744 throws Exception { 14745 final UserHandle testHandle = setupEnterpriseNetwork(); 14746 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder = 14747 new ProfileNetworkPreference.Builder(); 14748 profileNetworkPreferenceBuilder.setPreference( 14749 PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK); 14750 profileNetworkPreferenceBuilder.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1); 14751 registerDefaultNetworkCallbacks(); 14752 testPreferenceForUserNetworkUpDownForGivenPreference( 14753 profileNetworkPreferenceBuilder.build(), true, 14754 testHandle, mProfileDefaultNetworkCallback, 14755 null); 14756 } 14757 14758 /** 14759 * Make sure per-profile networking preference behaves as expected when the enterprise network 14760 * goes up and down while the preference is active for a given enterprise identifier 14761 */ 14762 @Test 14763 public void testPreferenceForUserNetworkUpDownWithId2() 14764 throws Exception { 14765 final UserHandle testHandle = setupEnterpriseNetwork(); 14766 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder = 14767 new ProfileNetworkPreference.Builder(); 14768 profileNetworkPreferenceBuilder.setPreference( 14769 PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK); 14770 profileNetworkPreferenceBuilder.setPreferenceEnterpriseId( 14771 NET_ENTERPRISE_ID_2); 14772 registerDefaultNetworkCallbacks(); 14773 testPreferenceForUserNetworkUpDownForGivenPreference( 14774 profileNetworkPreferenceBuilder.build(), true, 14775 testHandle, mProfileDefaultNetworkCallback, null); 14776 } 14777 14778 /** 14779 * Make sure per-profile networking preference behaves as expected when the enterprise network 14780 * goes up and down while the preference is active for a given enterprise identifier 14781 */ 14782 @Test 14783 public void testPreferenceForUserNetworkUpDownWithInvalidId() 14784 throws Exception { 14785 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder = 14786 new ProfileNetworkPreference.Builder(); 14787 profileNetworkPreferenceBuilder.setPreference( 14788 PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK); 14789 profileNetworkPreferenceBuilder.setPreferenceEnterpriseId(0); 14790 registerDefaultNetworkCallbacks(); 14791 assertThrows("Should not be able to set invalid enterprise id", 14792 IllegalStateException.class, () -> profileNetworkPreferenceBuilder.build()); 14793 } 14794 14795 /** 14796 * Make sure per-profile networking preference throws exception when default preference 14797 * is set along with enterprise preference. 14798 */ 14799 @Test 14800 public void testPreferenceWithInvalidPreferenceDefaultAndEnterpriseTogether() 14801 throws Exception { 14802 final UserHandle testHandle = setupEnterpriseNetwork(); 14803 mServiceContext.setWorkProfile(testHandle, true); 14804 14805 final int testWorkProfileAppUid1 = 14806 UserHandle.getUid(testHandle.getIdentifier(), TEST_APP_ID); 14807 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder1 = 14808 new ProfileNetworkPreference.Builder(); 14809 profileNetworkPreferenceBuilder1.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE); 14810 profileNetworkPreferenceBuilder1.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1); 14811 profileNetworkPreferenceBuilder1.setIncludedUids(new int[]{testWorkProfileAppUid1}); 14812 14813 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder2 = 14814 new ProfileNetworkPreference.Builder(); 14815 profileNetworkPreferenceBuilder2.setPreference(PROFILE_NETWORK_PREFERENCE_DEFAULT); 14816 final TestOnCompleteListener listener = new TestOnCompleteListener(); 14817 Assert.assertThrows(IllegalArgumentException.class, 14818 () -> mCm.setProfileNetworkPreferences( 14819 testHandle, List.of(profileNetworkPreferenceBuilder1.build(), 14820 profileNetworkPreferenceBuilder2.build()), 14821 r -> r.run(), listener)); 14822 Assert.assertThrows(IllegalArgumentException.class, 14823 () -> mCm.setProfileNetworkPreferences( 14824 testHandle, List.of(profileNetworkPreferenceBuilder2.build(), 14825 profileNetworkPreferenceBuilder1.build()), 14826 r -> r.run(), listener)); 14827 } 14828 14829 /** 14830 * Make sure per profile network preferences behave as expected when two slices with 14831 * two different apps within same user profile is configured 14832 * Make sure per profile network preferences overrides with latest preference when 14833 * same user preference is set twice 14834 */ 14835 @Test 14836 public void testSetPreferenceWithOverridingPreference() 14837 throws Exception { 14838 final InOrder inOrder = inOrder(mMockNetd); 14839 final UserHandle testHandle = setupEnterpriseNetwork(); 14840 mServiceContext.setWorkProfile(testHandle, true); 14841 registerDefaultNetworkCallbacks(); 14842 14843 final TestNetworkCallback appCb1 = new TestNetworkCallback(); 14844 final TestNetworkCallback appCb2 = new TestNetworkCallback(); 14845 final TestNetworkCallback appCb3 = new TestNetworkCallback(); 14846 14847 final int testWorkProfileAppUid1 = 14848 UserHandle.getUid(testHandle.getIdentifier(), TEST_APP_ID); 14849 final int testWorkProfileAppUid2 = 14850 UserHandle.getUid(testHandle.getIdentifier(), TEST_APP_ID_2); 14851 final int testWorkProfileAppUid3 = 14852 UserHandle.getUid(testHandle.getIdentifier(), TEST_APP_ID_3); 14853 14854 registerDefaultNetworkCallbackAsUid(appCb1, testWorkProfileAppUid1); 14855 registerDefaultNetworkCallbackAsUid(appCb2, testWorkProfileAppUid2); 14856 registerDefaultNetworkCallbackAsUid(appCb3, testWorkProfileAppUid3); 14857 14858 // Connect both a regular cell agent and an enterprise network first. 14859 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 14860 mCellNetworkAgent.connect(true); 14861 14862 final TestNetworkAgentWrapper workAgent1 = makeEnterpriseNetworkAgent(NET_ENTERPRISE_ID_1); 14863 final TestNetworkAgentWrapper workAgent2 = makeEnterpriseNetworkAgent(NET_ENTERPRISE_ID_2); 14864 workAgent1.connect(true); 14865 workAgent2.connect(true); 14866 14867 mSystemDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 14868 mDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 14869 14870 appCb1.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 14871 appCb2.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 14872 appCb3.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 14873 14874 verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( 14875 mCellNetworkAgent.getNetwork().netId, INetd.PERMISSION_NONE)); 14876 verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( 14877 workAgent1.getNetwork().netId, INetd.PERMISSION_SYSTEM)); 14878 verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( 14879 workAgent2.getNetwork().netId, INetd.PERMISSION_SYSTEM)); 14880 14881 final TestOnCompleteListener listener = new TestOnCompleteListener(); 14882 14883 // Set preferences for testHandle to map testWorkProfileAppUid1 to 14884 // NET_ENTERPRISE_ID_1 and testWorkProfileAppUid2 to NET_ENTERPRISE_ID_2. 14885 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder1 = 14886 new ProfileNetworkPreference.Builder(); 14887 profileNetworkPreferenceBuilder1.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE); 14888 profileNetworkPreferenceBuilder1.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1); 14889 profileNetworkPreferenceBuilder1.setIncludedUids(new int[]{testWorkProfileAppUid1}); 14890 14891 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder2 = 14892 new ProfileNetworkPreference.Builder(); 14893 profileNetworkPreferenceBuilder2.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE); 14894 profileNetworkPreferenceBuilder2.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_2); 14895 profileNetworkPreferenceBuilder2.setIncludedUids(new int[]{testWorkProfileAppUid2}); 14896 14897 mCm.setProfileNetworkPreferences(testHandle, 14898 List.of(profileNetworkPreferenceBuilder1.build(), 14899 profileNetworkPreferenceBuilder2.build()), 14900 r -> r.run(), listener); 14901 listener.expectOnComplete(); 14902 verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 14903 workAgent2.getNetwork().netId, 14904 uidRangeFor(testHandle, profileNetworkPreferenceBuilder2.build()), 14905 PREFERENCE_ORDER_PROFILE)); 14906 verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 14907 workAgent1.getNetwork().netId, 14908 uidRangeFor(testHandle, profileNetworkPreferenceBuilder1.build()), 14909 PREFERENCE_ORDER_PROFILE)); 14910 14911 assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback); 14912 appCb1.expectAvailableCallbacksValidated(workAgent1); 14913 appCb2.expectAvailableCallbacksValidated(workAgent2); 14914 14915 // Set preferences for testHandle to map testWorkProfileAppUid3 to 14916 // to NET_ENTERPRISE_ID_1. 14917 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder3 = 14918 new ProfileNetworkPreference.Builder(); 14919 profileNetworkPreferenceBuilder3.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE); 14920 profileNetworkPreferenceBuilder3.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1); 14921 profileNetworkPreferenceBuilder3.setIncludedUids(new int[]{testWorkProfileAppUid3}); 14922 14923 mCm.setProfileNetworkPreferences(testHandle, 14924 List.of(profileNetworkPreferenceBuilder3.build()), 14925 r -> r.run(), listener); 14926 listener.expectOnComplete(); 14927 verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 14928 workAgent1.getNetwork().netId, 14929 uidRangeFor(testHandle, profileNetworkPreferenceBuilder3.build()), 14930 PREFERENCE_ORDER_PROFILE)); 14931 verify(mMockNetd).networkRemoveUidRangesParcel(new NativeUidRangeConfig( 14932 workAgent2.getNetwork().netId, 14933 uidRangeFor(testHandle, profileNetworkPreferenceBuilder2.build()), 14934 PREFERENCE_ORDER_PROFILE)); 14935 verify(mMockNetd).networkRemoveUidRangesParcel(new NativeUidRangeConfig( 14936 workAgent1.getNetwork().netId, 14937 uidRangeFor(testHandle, profileNetworkPreferenceBuilder1.build()), 14938 PREFERENCE_ORDER_PROFILE)); 14939 14940 assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback); 14941 appCb3.expectAvailableCallbacksValidated(workAgent1); 14942 appCb2.expectAvailableCallbacksValidated(mCellNetworkAgent); 14943 appCb1.expectAvailableCallbacksValidated(mCellNetworkAgent); 14944 14945 // Set the preferences for testHandle to default. 14946 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder = 14947 new ProfileNetworkPreference.Builder(); 14948 profileNetworkPreferenceBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_DEFAULT); 14949 14950 mCm.setProfileNetworkPreferences(testHandle, 14951 List.of(profileNetworkPreferenceBuilder.build()), 14952 r -> r.run(), listener); 14953 listener.expectOnComplete(); 14954 verify(mMockNetd).networkRemoveUidRangesParcel(new NativeUidRangeConfig( 14955 workAgent1.getNetwork().netId, 14956 uidRangeFor(testHandle, profileNetworkPreferenceBuilder3.build()), 14957 PREFERENCE_ORDER_PROFILE)); 14958 14959 assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback, appCb1, appCb2); 14960 appCb3.expectAvailableCallbacksValidated(mCellNetworkAgent); 14961 workAgent2.disconnect(); 14962 mCellNetworkAgent.disconnect(); 14963 14964 mCm.unregisterNetworkCallback(appCb1); 14965 mCm.unregisterNetworkCallback(appCb2); 14966 mCm.unregisterNetworkCallback(appCb3); 14967 // Other callbacks will be unregistered by tearDown() 14968 } 14969 14970 /** 14971 * Make sure per profile network preferences behave as expected when multiple slices with 14972 * multiple different apps within same user profile is configured. 14973 */ 14974 @Test 14975 public void testSetPreferenceWithMultiplePreferences() 14976 throws Exception { 14977 final InOrder inOrder = inOrder(mMockNetd); 14978 14979 final UserHandle testHandle = setupEnterpriseNetwork(); 14980 mServiceContext.setWorkProfile(testHandle, true); 14981 registerDefaultNetworkCallbacks(); 14982 14983 final TestNetworkCallback appCb1 = new TestNetworkCallback(); 14984 final TestNetworkCallback appCb2 = new TestNetworkCallback(); 14985 final TestNetworkCallback appCb3 = new TestNetworkCallback(); 14986 final TestNetworkCallback appCb4 = new TestNetworkCallback(); 14987 final TestNetworkCallback appCb5 = new TestNetworkCallback(); 14988 14989 final int testWorkProfileAppUid1 = 14990 UserHandle.getUid(testHandle.getIdentifier(), TEST_APP_ID); 14991 final int testWorkProfileAppUid2 = 14992 UserHandle.getUid(testHandle.getIdentifier(), TEST_APP_ID_2); 14993 final int testWorkProfileAppUid3 = 14994 UserHandle.getUid(testHandle.getIdentifier(), TEST_APP_ID_3); 14995 final int testWorkProfileAppUid4 = 14996 UserHandle.getUid(testHandle.getIdentifier(), TEST_APP_ID_4); 14997 final int testWorkProfileAppUid5 = 14998 UserHandle.getUid(testHandle.getIdentifier(), TEST_APP_ID_5); 14999 15000 registerDefaultNetworkCallbackAsUid(appCb1, testWorkProfileAppUid1); 15001 registerDefaultNetworkCallbackAsUid(appCb2, testWorkProfileAppUid2); 15002 registerDefaultNetworkCallbackAsUid(appCb3, testWorkProfileAppUid3); 15003 registerDefaultNetworkCallbackAsUid(appCb4, testWorkProfileAppUid4); 15004 registerDefaultNetworkCallbackAsUid(appCb5, testWorkProfileAppUid5); 15005 15006 // Connect both a regular cell agent and an enterprise network first. 15007 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 15008 mCellNetworkAgent.connect(true); 15009 15010 final TestNetworkAgentWrapper workAgent1 = makeEnterpriseNetworkAgent(NET_ENTERPRISE_ID_1); 15011 final TestNetworkAgentWrapper workAgent2 = makeEnterpriseNetworkAgent(NET_ENTERPRISE_ID_2); 15012 final TestNetworkAgentWrapper workAgent3 = makeEnterpriseNetworkAgent(NET_ENTERPRISE_ID_3); 15013 final TestNetworkAgentWrapper workAgent4 = makeEnterpriseNetworkAgent(NET_ENTERPRISE_ID_4); 15014 final TestNetworkAgentWrapper workAgent5 = makeEnterpriseNetworkAgent(NET_ENTERPRISE_ID_5); 15015 15016 workAgent1.connect(true); 15017 workAgent2.connect(true); 15018 workAgent3.connect(true); 15019 workAgent4.connect(true); 15020 workAgent5.connect(true); 15021 15022 mSystemDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 15023 mDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 15024 appCb1.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 15025 appCb2.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 15026 appCb3.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 15027 appCb4.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 15028 appCb5.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 15029 15030 verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( 15031 mCellNetworkAgent.getNetwork().netId, INetd.PERMISSION_NONE)); 15032 verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( 15033 workAgent1.getNetwork().netId, INetd.PERMISSION_SYSTEM)); 15034 verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( 15035 workAgent2.getNetwork().netId, INetd.PERMISSION_SYSTEM)); 15036 verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( 15037 workAgent3.getNetwork().netId, INetd.PERMISSION_SYSTEM)); 15038 verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( 15039 workAgent4.getNetwork().netId, INetd.PERMISSION_SYSTEM)); 15040 verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( 15041 workAgent5.getNetwork().netId, INetd.PERMISSION_SYSTEM)); 15042 15043 final TestOnCompleteListener listener = new TestOnCompleteListener(); 15044 15045 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder1 = 15046 new ProfileNetworkPreference.Builder(); 15047 profileNetworkPreferenceBuilder1.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE); 15048 profileNetworkPreferenceBuilder1.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1); 15049 profileNetworkPreferenceBuilder1.setIncludedUids(new int[]{testWorkProfileAppUid1}); 15050 15051 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder2 = 15052 new ProfileNetworkPreference.Builder(); 15053 profileNetworkPreferenceBuilder2.setPreference( 15054 PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK); 15055 profileNetworkPreferenceBuilder2.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_2); 15056 profileNetworkPreferenceBuilder2.setIncludedUids(new int[]{testWorkProfileAppUid2}); 15057 15058 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder3 = 15059 new ProfileNetworkPreference.Builder(); 15060 profileNetworkPreferenceBuilder3.setPreference( 15061 PROFILE_NETWORK_PREFERENCE_ENTERPRISE); 15062 profileNetworkPreferenceBuilder3.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_3); 15063 profileNetworkPreferenceBuilder3.setIncludedUids(new int[]{testWorkProfileAppUid3}); 15064 15065 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder4 = 15066 new ProfileNetworkPreference.Builder(); 15067 profileNetworkPreferenceBuilder4.setPreference( 15068 PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK); 15069 profileNetworkPreferenceBuilder4.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_4); 15070 profileNetworkPreferenceBuilder4.setIncludedUids(new int[]{testWorkProfileAppUid4}); 15071 15072 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder5 = 15073 new ProfileNetworkPreference.Builder(); 15074 profileNetworkPreferenceBuilder5.setPreference( 15075 PROFILE_NETWORK_PREFERENCE_ENTERPRISE); 15076 profileNetworkPreferenceBuilder5.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_5); 15077 profileNetworkPreferenceBuilder5.setIncludedUids(new int[]{testWorkProfileAppUid5}); 15078 15079 mCm.setProfileNetworkPreferences(testHandle, 15080 List.of(profileNetworkPreferenceBuilder1.build(), 15081 profileNetworkPreferenceBuilder2.build(), 15082 profileNetworkPreferenceBuilder3.build(), 15083 profileNetworkPreferenceBuilder4.build(), 15084 profileNetworkPreferenceBuilder5.build()), 15085 r -> r.run(), listener); 15086 15087 listener.expectOnComplete(); 15088 15089 verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 15090 workAgent1.getNetwork().netId, 15091 uidRangeFor(testHandle, profileNetworkPreferenceBuilder1.build()), 15092 PREFERENCE_ORDER_PROFILE)); 15093 verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 15094 workAgent2.getNetwork().netId, 15095 uidRangeFor(testHandle, profileNetworkPreferenceBuilder2.build()), 15096 PREFERENCE_ORDER_PROFILE)); 15097 verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 15098 workAgent3.getNetwork().netId, 15099 uidRangeFor(testHandle, profileNetworkPreferenceBuilder3.build()), 15100 PREFERENCE_ORDER_PROFILE)); 15101 verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 15102 workAgent4.getNetwork().netId, 15103 uidRangeFor(testHandle, profileNetworkPreferenceBuilder4.build()), 15104 PREFERENCE_ORDER_PROFILE)); 15105 verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 15106 workAgent5.getNetwork().netId, 15107 uidRangeFor(testHandle, profileNetworkPreferenceBuilder5.build()), 15108 PREFERENCE_ORDER_PROFILE)); 15109 15110 assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback); 15111 appCb1.expectAvailableCallbacksValidated(workAgent1); 15112 appCb2.expectAvailableCallbacksValidated(workAgent2); 15113 appCb3.expectAvailableCallbacksValidated(workAgent3); 15114 appCb4.expectAvailableCallbacksValidated(workAgent4); 15115 appCb5.expectAvailableCallbacksValidated(workAgent5); 15116 15117 workAgent1.disconnect(); 15118 workAgent2.disconnect(); 15119 workAgent3.disconnect(); 15120 workAgent4.disconnect(); 15121 workAgent5.disconnect(); 15122 15123 appCb1.expectCallback(CallbackEntry.LOST, workAgent1); 15124 appCb2.expectCallback(CallbackEntry.LOST, workAgent2); 15125 appCb3.expectCallback(CallbackEntry.LOST, workAgent3); 15126 appCb4.expectCallback(CallbackEntry.LOST, workAgent4); 15127 appCb5.expectCallback(CallbackEntry.LOST, workAgent5); 15128 15129 appCb1.expectAvailableCallbacksValidated(mCellNetworkAgent); 15130 appCb2.assertNoCallback(); 15131 appCb3.expectAvailableCallbacksValidated(mCellNetworkAgent); 15132 appCb4.assertNoCallback(); 15133 appCb5.expectAvailableCallbacksValidated(mCellNetworkAgent); 15134 15135 verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 15136 mCellNetworkAgent.getNetwork().netId, 15137 uidRangeFor(testHandle, profileNetworkPreferenceBuilder1.build()), 15138 PREFERENCE_ORDER_PROFILE)); 15139 verify(mMockNetd, never()).networkAddUidRangesParcel(new NativeUidRangeConfig( 15140 mCellNetworkAgent.getNetwork().netId, 15141 uidRangeFor(testHandle, profileNetworkPreferenceBuilder2.build()), 15142 PREFERENCE_ORDER_PROFILE)); 15143 verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 15144 mCellNetworkAgent.getNetwork().netId, 15145 uidRangeFor(testHandle, profileNetworkPreferenceBuilder3.build()), 15146 PREFERENCE_ORDER_PROFILE)); 15147 verify(mMockNetd, never()).networkAddUidRangesParcel(new NativeUidRangeConfig( 15148 mCellNetworkAgent.getNetwork().netId, 15149 uidRangeFor(testHandle, profileNetworkPreferenceBuilder4.build()), 15150 PREFERENCE_ORDER_PROFILE)); 15151 verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 15152 mCellNetworkAgent.getNetwork().netId, 15153 uidRangeFor(testHandle, profileNetworkPreferenceBuilder5.build()), 15154 PREFERENCE_ORDER_PROFILE)); 15155 15156 mSystemDefaultNetworkCallback.assertNoCallback(); 15157 mDefaultNetworkCallback.assertNoCallback(); 15158 15159 // Set the preferences for testHandle to default. 15160 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder = 15161 new ProfileNetworkPreference.Builder(); 15162 profileNetworkPreferenceBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_DEFAULT); 15163 15164 mCm.setProfileNetworkPreferences(testHandle, 15165 List.of(profileNetworkPreferenceBuilder.build()), 15166 r -> r.run(), listener); 15167 listener.expectOnComplete(); 15168 assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback, appCb1, appCb3, 15169 appCb5); 15170 appCb2.expectAvailableCallbacksValidated(mCellNetworkAgent); 15171 appCb4.expectAvailableCallbacksValidated(mCellNetworkAgent); 15172 mCellNetworkAgent.disconnect(); 15173 15174 mCm.unregisterNetworkCallback(appCb1); 15175 mCm.unregisterNetworkCallback(appCb2); 15176 mCm.unregisterNetworkCallback(appCb3); 15177 mCm.unregisterNetworkCallback(appCb4); 15178 mCm.unregisterNetworkCallback(appCb5); 15179 // Other callbacks will be unregistered by tearDown() 15180 } 15181 15182 /** 15183 * Test that, in a given networking context, calling setPreferenceForUser to set per-profile 15184 * defaults on then off works as expected. 15185 */ 15186 @Test 15187 public void testSetPreferenceForUserOnOff() throws Exception { 15188 final InOrder inOrder = inOrder(mMockNetd); 15189 final UserHandle testHandle = setupEnterpriseNetwork(); 15190 15191 // Connect both a regular cell agent and an enterprise network first. 15192 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 15193 mCellNetworkAgent.connect(true); 15194 15195 final TestNetworkAgentWrapper workAgent = makeEnterpriseNetworkAgent(); 15196 workAgent.connect(true); 15197 15198 final TestOnCompleteListener listener = new TestOnCompleteListener(); 15199 mCm.setProfileNetworkPreference(testHandle, PROFILE_NETWORK_PREFERENCE_ENTERPRISE, 15200 r -> r.run(), listener); 15201 listener.expectOnComplete(); 15202 inOrder.verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( 15203 mCellNetworkAgent.getNetwork().netId, INetd.PERMISSION_NONE)); 15204 inOrder.verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 15205 workAgent.getNetwork().netId, uidRangeFor(testHandle), PREFERENCE_ORDER_PROFILE)); 15206 15207 registerDefaultNetworkCallbacks(); 15208 15209 mSystemDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellNetworkAgent); 15210 mDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellNetworkAgent); 15211 mProfileDefaultNetworkCallback.expectAvailableCallbacksValidated(workAgent); 15212 15213 mCm.setProfileNetworkPreference(testHandle, PROFILE_NETWORK_PREFERENCE_DEFAULT, 15214 r -> r.run(), listener); 15215 listener.expectOnComplete(); 15216 15217 mProfileDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellNetworkAgent); 15218 assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback); 15219 inOrder.verify(mMockNetd).networkRemoveUidRangesParcel(new NativeUidRangeConfig( 15220 workAgent.getNetwork().netId, uidRangeFor(testHandle), PREFERENCE_ORDER_PROFILE)); 15221 15222 workAgent.disconnect(); 15223 mCellNetworkAgent.disconnect(); 15224 15225 // Callbacks will be unregistered by tearDown() 15226 } 15227 15228 /** 15229 * Test per-profile default networks for two different profiles concurrently. 15230 */ 15231 @Test 15232 public void testSetPreferenceForTwoProfiles() throws Exception { 15233 final InOrder inOrder = inOrder(mMockNetd); 15234 final UserHandle testHandle2 = setupEnterpriseNetwork(); 15235 final UserHandle testHandle4 = UserHandle.of(TEST_WORK_PROFILE_USER_ID + 2); 15236 mServiceContext.setWorkProfile(testHandle4, true); 15237 registerDefaultNetworkCallbacks(); 15238 15239 final TestNetworkCallback app4Cb = new TestNetworkCallback(); 15240 final int testWorkProfileAppUid4 = 15241 UserHandle.getUid(testHandle4.getIdentifier(), TEST_APP_ID); 15242 registerDefaultNetworkCallbackAsUid(app4Cb, testWorkProfileAppUid4); 15243 15244 // Connect both a regular cell agent and an enterprise network first. 15245 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 15246 mCellNetworkAgent.connect(true); 15247 15248 final TestNetworkAgentWrapper workAgent = makeEnterpriseNetworkAgent(); 15249 workAgent.connect(true); 15250 15251 mSystemDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 15252 mDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 15253 mProfileDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 15254 app4Cb.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 15255 inOrder.verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( 15256 mCellNetworkAgent.getNetwork().netId, INetd.PERMISSION_NONE)); 15257 inOrder.verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( 15258 workAgent.getNetwork().netId, INetd.PERMISSION_SYSTEM)); 15259 15260 final TestOnCompleteListener listener = new TestOnCompleteListener(); 15261 mCm.setProfileNetworkPreference(testHandle2, PROFILE_NETWORK_PREFERENCE_ENTERPRISE, 15262 r -> r.run(), listener); 15263 listener.expectOnComplete(); 15264 inOrder.verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 15265 workAgent.getNetwork().netId, uidRangeFor(testHandle2), PREFERENCE_ORDER_PROFILE)); 15266 15267 mProfileDefaultNetworkCallback.expectAvailableCallbacksValidated(workAgent); 15268 assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback, 15269 app4Cb); 15270 15271 mCm.setProfileNetworkPreference(testHandle4, PROFILE_NETWORK_PREFERENCE_ENTERPRISE, 15272 r -> r.run(), listener); 15273 listener.expectOnComplete(); 15274 inOrder.verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 15275 workAgent.getNetwork().netId, uidRangeFor(testHandle4), PREFERENCE_ORDER_PROFILE)); 15276 15277 app4Cb.expectAvailableCallbacksValidated(workAgent); 15278 assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback, 15279 mProfileDefaultNetworkCallback); 15280 15281 mCm.setProfileNetworkPreference(testHandle2, PROFILE_NETWORK_PREFERENCE_DEFAULT, 15282 r -> r.run(), listener); 15283 listener.expectOnComplete(); 15284 inOrder.verify(mMockNetd).networkRemoveUidRangesParcel(new NativeUidRangeConfig( 15285 workAgent.getNetwork().netId, uidRangeFor(testHandle2), PREFERENCE_ORDER_PROFILE)); 15286 15287 mProfileDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellNetworkAgent); 15288 assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback, 15289 app4Cb); 15290 15291 workAgent.disconnect(); 15292 mCellNetworkAgent.disconnect(); 15293 15294 mCm.unregisterNetworkCallback(app4Cb); 15295 // Other callbacks will be unregistered by tearDown() 15296 } 15297 15298 @Test 15299 public void testProfilePreferenceRemovedUponUserRemoved() throws Exception { 15300 final InOrder inOrder = inOrder(mMockNetd); 15301 final UserHandle testHandle = setupEnterpriseNetwork(); 15302 15303 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 15304 mCellNetworkAgent.connect(true); 15305 15306 final TestOnCompleteListener listener = new TestOnCompleteListener(); 15307 mCm.setProfileNetworkPreference(testHandle, PROFILE_NETWORK_PREFERENCE_ENTERPRISE, 15308 r -> r.run(), listener); 15309 listener.expectOnComplete(); 15310 inOrder.verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( 15311 mCellNetworkAgent.getNetwork().netId, INetd.PERMISSION_NONE)); 15312 inOrder.verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 15313 mCellNetworkAgent.getNetwork().netId, uidRangeFor(testHandle), 15314 PREFERENCE_ORDER_PROFILE)); 15315 15316 final Intent removedIntent = new Intent(ACTION_USER_REMOVED); 15317 removedIntent.putExtra(Intent.EXTRA_USER, testHandle); 15318 processBroadcast(removedIntent); 15319 15320 inOrder.verify(mMockNetd).networkRemoveUidRangesParcel(new NativeUidRangeConfig( 15321 mCellNetworkAgent.getNetwork().netId, uidRangeFor(testHandle), 15322 PREFERENCE_ORDER_PROFILE)); 15323 } 15324 15325 /** 15326 * Make sure wrong preferences for per-profile default networking are rejected. 15327 */ 15328 @Test 15329 public void testProfileNetworkPrefWrongPreference() throws Exception { 15330 final UserHandle testHandle = UserHandle.of(TEST_WORK_PROFILE_USER_ID); 15331 mServiceContext.setWorkProfile(testHandle, true); 15332 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder = 15333 new ProfileNetworkPreference.Builder(); 15334 profileNetworkPreferenceBuilder.setPreference( 15335 PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK + 1); 15336 profileNetworkPreferenceBuilder.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1); 15337 assertThrows("Should not be able to set an illegal preference", 15338 IllegalArgumentException.class, 15339 () -> mCm.setProfileNetworkPreferences(testHandle, 15340 List.of(profileNetworkPreferenceBuilder.build()), 15341 null, null)); 15342 } 15343 15344 /** 15345 * Make sure requests for per-profile default networking for a non-work profile are 15346 * rejected 15347 */ 15348 @Test 15349 public void testProfileNetworkPrefWrongProfile() throws Exception { 15350 final UserHandle testHandle = UserHandle.of(TEST_WORK_PROFILE_USER_ID); 15351 mServiceContext.setWorkProfile(testHandle, false); 15352 mServiceContext.setDeviceOwner(testHandle, null); 15353 assertThrows("Should not be able to set a user pref for a non-work profile " 15354 + "and non device owner", 15355 IllegalArgumentException.class , () -> 15356 mCm.setProfileNetworkPreference(testHandle, 15357 PROFILE_NETWORK_PREFERENCE_ENTERPRISE, null, null)); 15358 } 15359 15360 /** 15361 * Make sure requests for per-profile default networking for a device owner is 15362 * accepted on T and not accepted on S 15363 */ 15364 @Test 15365 public void testProfileNetworkDeviceOwner() throws Exception { 15366 final UserHandle testHandle = UserHandle.of(TEST_WORK_PROFILE_USER_ID); 15367 mServiceContext.setWorkProfile(testHandle, false); 15368 mServiceContext.setDeviceOwner(testHandle, "deviceOwnerPackage"); 15369 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder = 15370 new ProfileNetworkPreference.Builder(); 15371 profileNetworkPreferenceBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE); 15372 profileNetworkPreferenceBuilder.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1); 15373 final TestOnCompleteListener listener = new TestOnCompleteListener(); 15374 if (SdkLevel.isAtLeastT()) { 15375 mCm.setProfileNetworkPreferences(testHandle, 15376 List.of(profileNetworkPreferenceBuilder.build()), 15377 r -> r.run(), listener); 15378 } else { 15379 // S should not allow setting preference on device owner 15380 assertThrows("Should not be able to set a user pref for a non-work profile on S", 15381 IllegalArgumentException.class , () -> 15382 mCm.setProfileNetworkPreferences(testHandle, 15383 List.of(profileNetworkPreferenceBuilder.build()), 15384 r -> r.run(), listener)); 15385 } 15386 } 15387 15388 @Test 15389 public void testSubIdsClearedWithoutNetworkFactoryPermission() throws Exception { 15390 mServiceContext.setPermission(NETWORK_FACTORY, PERMISSION_DENIED); 15391 final NetworkCapabilities nc = new NetworkCapabilities(); 15392 nc.setSubscriptionIds(Collections.singleton(Process.myUid())); 15393 15394 final NetworkCapabilities result = 15395 mService.networkCapabilitiesRestrictedForCallerPermissions( 15396 nc, Process.myPid(), Process.myUid()); 15397 assertTrue(result.getSubscriptionIds().isEmpty()); 15398 } 15399 15400 @Test 15401 public void testSubIdsExistWithNetworkFactoryPermission() throws Exception { 15402 mServiceContext.setPermission(NETWORK_FACTORY, PERMISSION_GRANTED); 15403 15404 final Set<Integer> subIds = Collections.singleton(Process.myUid()); 15405 final NetworkCapabilities nc = new NetworkCapabilities(); 15406 nc.setSubscriptionIds(subIds); 15407 15408 final NetworkCapabilities result = 15409 mService.networkCapabilitiesRestrictedForCallerPermissions( 15410 nc, Process.myPid(), Process.myUid()); 15411 assertEquals(subIds, result.getSubscriptionIds()); 15412 } 15413 15414 private NetworkRequest getRequestWithSubIds() { 15415 return new NetworkRequest.Builder() 15416 .setSubscriptionIds(Collections.singleton(Process.myUid())) 15417 .build(); 15418 } 15419 15420 @Test 15421 public void testNetworkRequestWithSubIdsWithNetworkFactoryPermission() throws Exception { 15422 mServiceContext.setPermission(NETWORK_FACTORY, PERMISSION_GRANTED); 15423 final PendingIntent pendingIntent = PendingIntent.getBroadcast( 15424 mContext, 0 /* requestCode */, new Intent("a"), FLAG_IMMUTABLE); 15425 final NetworkCallback networkCallback1 = new NetworkCallback(); 15426 final NetworkCallback networkCallback2 = new NetworkCallback(); 15427 15428 mCm.requestNetwork(getRequestWithSubIds(), networkCallback1); 15429 mCm.requestNetwork(getRequestWithSubIds(), pendingIntent); 15430 mCm.registerNetworkCallback(getRequestWithSubIds(), networkCallback2); 15431 15432 mCm.unregisterNetworkCallback(networkCallback1); 15433 mCm.releaseNetworkRequest(pendingIntent); 15434 mCm.unregisterNetworkCallback(networkCallback2); 15435 } 15436 15437 @Test 15438 public void testNetworkRequestWithSubIdsWithoutNetworkFactoryPermission() throws Exception { 15439 mServiceContext.setPermission(NETWORK_FACTORY, PERMISSION_DENIED); 15440 final PendingIntent pendingIntent = PendingIntent.getBroadcast( 15441 mContext, 0 /* requestCode */, new Intent("a"), FLAG_IMMUTABLE); 15442 15443 final Class<SecurityException> expected = SecurityException.class; 15444 assertThrows( 15445 expected, () -> mCm.requestNetwork(getRequestWithSubIds(), new NetworkCallback())); 15446 assertThrows(expected, () -> mCm.requestNetwork(getRequestWithSubIds(), pendingIntent)); 15447 assertThrows( 15448 expected, 15449 () -> mCm.registerNetworkCallback(getRequestWithSubIds(), new NetworkCallback())); 15450 } 15451 15452 @Test 15453 public void testAllowedUids() throws Exception { 15454 final int preferenceOrder = 15455 ConnectivityService.PREFERENCE_ORDER_IRRELEVANT_BECAUSE_NOT_DEFAULT; 15456 mServiceContext.setPermission(NETWORK_FACTORY, PERMISSION_GRANTED); 15457 mServiceContext.setPermission(MANAGE_TEST_NETWORKS, PERMISSION_GRANTED); 15458 final TestNetworkCallback cb = new TestNetworkCallback(); 15459 mCm.requestNetwork(new NetworkRequest.Builder() 15460 .clearCapabilities() 15461 .addTransportType(TRANSPORT_TEST) 15462 .build(), 15463 cb); 15464 15465 final ArraySet<Integer> uids = new ArraySet<>(); 15466 uids.add(200); 15467 final NetworkCapabilities nc = new NetworkCapabilities.Builder() 15468 .addTransportType(TRANSPORT_TEST) 15469 .removeCapability(NET_CAPABILITY_NOT_RESTRICTED) 15470 .setAllowedUids(uids) 15471 .build(); 15472 final TestNetworkAgentWrapper agent = new TestNetworkAgentWrapper(TRANSPORT_TEST, 15473 new LinkProperties(), nc); 15474 agent.connect(true); 15475 cb.expectAvailableThenValidatedCallbacks(agent); 15476 15477 final InOrder inOrder = inOrder(mMockNetd); 15478 final NativeUidRangeConfig uids200Parcel = new NativeUidRangeConfig( 15479 agent.getNetwork().getNetId(), 15480 intToUidRangeStableParcels(uids), 15481 preferenceOrder); 15482 if (SdkLevel.isAtLeastT()) { 15483 inOrder.verify(mMockNetd, times(1)).networkAddUidRangesParcel(uids200Parcel); 15484 } 15485 15486 uids.add(300); 15487 uids.add(400); 15488 nc.setAllowedUids(uids); 15489 agent.setNetworkCapabilities(nc, true /* sendToConnectivityService */); 15490 if (SdkLevel.isAtLeastT()) { 15491 cb.expectCapabilitiesThat(agent, caps -> caps.getAllowedUids().equals(uids)); 15492 } else { 15493 cb.assertNoCallback(); 15494 } 15495 15496 uids.remove(200); 15497 final NativeUidRangeConfig uids300400Parcel = new NativeUidRangeConfig( 15498 agent.getNetwork().getNetId(), 15499 intToUidRangeStableParcels(uids), 15500 preferenceOrder); 15501 if (SdkLevel.isAtLeastT()) { 15502 inOrder.verify(mMockNetd, times(1)).networkAddUidRangesParcel(uids300400Parcel); 15503 } 15504 15505 nc.setAllowedUids(uids); 15506 agent.setNetworkCapabilities(nc, true /* sendToConnectivityService */); 15507 if (SdkLevel.isAtLeastT()) { 15508 cb.expectCapabilitiesThat(agent, caps -> caps.getAllowedUids().equals(uids)); 15509 inOrder.verify(mMockNetd, times(1)).networkRemoveUidRangesParcel(uids200Parcel); 15510 } else { 15511 cb.assertNoCallback(); 15512 } 15513 15514 uids.clear(); 15515 uids.add(600); 15516 nc.setAllowedUids(uids); 15517 agent.setNetworkCapabilities(nc, true /* sendToConnectivityService */); 15518 if (SdkLevel.isAtLeastT()) { 15519 cb.expectCapabilitiesThat(agent, caps -> caps.getAllowedUids().equals(uids)); 15520 } else { 15521 cb.assertNoCallback(); 15522 } 15523 final NativeUidRangeConfig uids600Parcel = new NativeUidRangeConfig( 15524 agent.getNetwork().getNetId(), 15525 intToUidRangeStableParcels(uids), 15526 preferenceOrder); 15527 if (SdkLevel.isAtLeastT()) { 15528 inOrder.verify(mMockNetd, times(1)).networkAddUidRangesParcel(uids600Parcel); 15529 inOrder.verify(mMockNetd, times(1)).networkRemoveUidRangesParcel(uids300400Parcel); 15530 } 15531 15532 uids.clear(); 15533 nc.setAllowedUids(uids); 15534 agent.setNetworkCapabilities(nc, true /* sendToConnectivityService */); 15535 if (SdkLevel.isAtLeastT()) { 15536 cb.expectCapabilitiesThat(agent, caps -> caps.getAllowedUids().isEmpty()); 15537 inOrder.verify(mMockNetd, times(1)).networkRemoveUidRangesParcel(uids600Parcel); 15538 } else { 15539 cb.assertNoCallback(); 15540 verify(mMockNetd, never()).networkAddUidRangesParcel(any()); 15541 verify(mMockNetd, never()).networkRemoveUidRangesParcel(any()); 15542 } 15543 15544 } 15545 15546 @Test 15547 public void testAutomotiveEthernetAllowedUids() throws Exception { 15548 mServiceContext.setPermission(NETWORK_FACTORY, PERMISSION_GRANTED); 15549 mServiceContext.setPermission(MANAGE_TEST_NETWORKS, PERMISSION_GRANTED); 15550 15551 // In this test the automotive feature will be enabled. 15552 mockHasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, true); 15553 15554 // Simulate a restricted ethernet network. 15555 final NetworkCapabilities.Builder agentNetCaps = new NetworkCapabilities.Builder() 15556 .addTransportType(TRANSPORT_ETHERNET) 15557 .addCapability(NET_CAPABILITY_INTERNET) 15558 .addCapability(NET_CAPABILITY_NOT_SUSPENDED) 15559 .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED) 15560 .removeCapability(NET_CAPABILITY_NOT_RESTRICTED); 15561 15562 mEthernetNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_ETHERNET, 15563 new LinkProperties(), agentNetCaps.build()); 15564 validateAllowedUids(mEthernetNetworkAgent, TRANSPORT_ETHERNET, agentNetCaps, true); 15565 } 15566 15567 @Test 15568 public void testCbsAllowedUids() throws Exception { 15569 mServiceContext.setPermission(NETWORK_FACTORY, PERMISSION_GRANTED); 15570 mServiceContext.setPermission(MANAGE_TEST_NETWORKS, PERMISSION_GRANTED); 15571 15572 // In this test TEST_PACKAGE_UID will be the UID of the carrier service UID. 15573 doReturn(true).when(mCarrierPrivilegeAuthenticator) 15574 .hasCarrierPrivilegeForNetworkCapabilities(eq(TEST_PACKAGE_UID), any()); 15575 15576 // Simulate a restricted telephony network. The telephony factory is entitled to set 15577 // the access UID to the service package on any of its restricted networks. 15578 final NetworkCapabilities.Builder agentNetCaps = new NetworkCapabilities.Builder() 15579 .addTransportType(TRANSPORT_CELLULAR) 15580 .addCapability(NET_CAPABILITY_INTERNET) 15581 .addCapability(NET_CAPABILITY_NOT_SUSPENDED) 15582 .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED) 15583 .removeCapability(NET_CAPABILITY_NOT_RESTRICTED) 15584 .setNetworkSpecifier(new TelephonyNetworkSpecifier(1 /* subid */)); 15585 15586 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, 15587 new LinkProperties(), agentNetCaps.build()); 15588 validateAllowedUids(mCellNetworkAgent, TRANSPORT_CELLULAR, agentNetCaps, false); 15589 } 15590 15591 private void validateAllowedUids(final TestNetworkAgentWrapper testAgent, 15592 @NetworkCapabilities.Transport final int transportUnderTest, 15593 final NetworkCapabilities.Builder ncb, final boolean forAutomotive) throws Exception { 15594 final ArraySet<Integer> serviceUidSet = new ArraySet<>(); 15595 serviceUidSet.add(TEST_PACKAGE_UID); 15596 final ArraySet<Integer> nonServiceUidSet = new ArraySet<>(); 15597 nonServiceUidSet.add(TEST_PACKAGE_UID2); 15598 final ArraySet<Integer> serviceUidSetPlus = new ArraySet<>(); 15599 serviceUidSetPlus.add(TEST_PACKAGE_UID); 15600 serviceUidSetPlus.add(TEST_PACKAGE_UID2); 15601 15602 final TestNetworkCallback cb = new TestNetworkCallback(); 15603 15604 /* Test setting UIDs */ 15605 // Cell gets to set the service UID as access UID 15606 mCm.requestNetwork(new NetworkRequest.Builder() 15607 .addTransportType(transportUnderTest) 15608 .removeCapability(NET_CAPABILITY_NOT_RESTRICTED) 15609 .build(), cb); 15610 testAgent.connect(true); 15611 cb.expectAvailableThenValidatedCallbacks(testAgent); 15612 ncb.setAllowedUids(serviceUidSet); 15613 testAgent.setNetworkCapabilities(ncb.build(), true /* sendToCS */); 15614 if (SdkLevel.isAtLeastT()) { 15615 cb.expectCapabilitiesThat(testAgent, 15616 caps -> caps.getAllowedUids().equals(serviceUidSet)); 15617 } else { 15618 // S must ignore access UIDs. 15619 cb.assertNoCallback(TEST_CALLBACK_TIMEOUT_MS); 15620 } 15621 15622 /* Test setting UIDs is rejected when expected */ 15623 if (forAutomotive) { 15624 mockHasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, false); 15625 } 15626 15627 // ...but not to some other UID. Rejection sets UIDs to the empty set 15628 ncb.setAllowedUids(nonServiceUidSet); 15629 testAgent.setNetworkCapabilities(ncb.build(), true /* sendToCS */); 15630 if (SdkLevel.isAtLeastT()) { 15631 cb.expectCapabilitiesThat(testAgent, 15632 caps -> caps.getAllowedUids().isEmpty()); 15633 } else { 15634 // S must ignore access UIDs. 15635 cb.assertNoCallback(TEST_CALLBACK_TIMEOUT_MS); 15636 } 15637 15638 // ...and also not to multiple UIDs even including the service UID 15639 ncb.setAllowedUids(serviceUidSetPlus); 15640 testAgent.setNetworkCapabilities(ncb.build(), true /* sendToCS */); 15641 cb.assertNoCallback(TEST_CALLBACK_TIMEOUT_MS); 15642 15643 testAgent.disconnect(); 15644 cb.expectCallback(CallbackEntry.LOST, testAgent); 15645 mCm.unregisterNetworkCallback(cb); 15646 15647 // Must be unset before touching the transports, because remove and add transport types 15648 // check the specifier on the builder immediately, contradicting normal builder semantics 15649 // TODO : fix the builder 15650 ncb.setNetworkSpecifier(null); 15651 ncb.removeTransportType(transportUnderTest); 15652 ncb.addTransportType(TRANSPORT_WIFI); 15653 // Wifi does not get to set access UID, even to the correct UID 15654 mCm.requestNetwork(new NetworkRequest.Builder() 15655 .addTransportType(TRANSPORT_WIFI) 15656 .removeCapability(NET_CAPABILITY_NOT_RESTRICTED) 15657 .build(), cb); 15658 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, 15659 new LinkProperties(), ncb.build()); 15660 mWiFiNetworkAgent.connect(true); 15661 cb.expectAvailableThenValidatedCallbacks(mWiFiNetworkAgent); 15662 ncb.setAllowedUids(serviceUidSet); 15663 mWiFiNetworkAgent.setNetworkCapabilities(ncb.build(), true /* sendToCS */); 15664 cb.assertNoCallback(TEST_CALLBACK_TIMEOUT_MS); 15665 mCm.unregisterNetworkCallback(cb); 15666 } 15667 15668 /** 15669 * Validate request counts are counted accurately on setProfileNetworkPreference on set/replace. 15670 */ 15671 @Test 15672 public void testProfileNetworkPrefCountsRequestsCorrectlyOnSet() throws Exception { 15673 final UserHandle testHandle = setupEnterpriseNetwork(); 15674 final TestOnCompleteListener listener = new TestOnCompleteListener(); 15675 // Leave one request available so the profile preference can be set. 15676 testRequestCountLimits(1 /* countToLeaveAvailable */, () -> { 15677 withPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, 15678 Process.myPid(), Process.myUid(), () -> { 15679 // Set initially to test the limit prior to having existing requests. 15680 mCm.setProfileNetworkPreference(testHandle, 15681 PROFILE_NETWORK_PREFERENCE_ENTERPRISE, 15682 Runnable::run, listener); 15683 }); 15684 listener.expectOnComplete(); 15685 15686 // Simulate filing requests as some app on the work profile 15687 final int otherAppUid = UserHandle.getUid(TEST_WORK_PROFILE_USER_ID, 15688 UserHandle.getAppId(Process.myUid() + 1)); 15689 final int remainingCount = ConnectivityService.MAX_NETWORK_REQUESTS_PER_UID 15690 - mService.mNetworkRequestCounter.mUidToNetworkRequestCount.get(otherAppUid) 15691 - 1; 15692 final NetworkCallback[] callbacks = new NetworkCallback[remainingCount]; 15693 doAsUid(otherAppUid, () -> { 15694 for (int i = 0; i < remainingCount; ++i) { 15695 callbacks[i] = new TestableNetworkCallback(); 15696 mCm.registerDefaultNetworkCallback(callbacks[i]); 15697 } 15698 }); 15699 15700 withPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, 15701 Process.myPid(), Process.myUid(), () -> { 15702 // re-set so as to test the limit as part of replacing existing requests. 15703 mCm.setProfileNetworkPreference(testHandle, 15704 PROFILE_NETWORK_PREFERENCE_ENTERPRISE, Runnable::run, listener); 15705 }); 15706 listener.expectOnComplete(); 15707 15708 doAsUid(otherAppUid, () -> { 15709 for (final NetworkCallback callback : callbacks) { 15710 mCm.unregisterNetworkCallback(callback); 15711 } 15712 }); 15713 }); 15714 } 15715 15716 /** 15717 * Validate request counts are counted accurately on setOemNetworkPreference on set/replace. 15718 */ 15719 @Test 15720 public void testSetOemNetworkPreferenceCountsRequestsCorrectlyOnSet() throws Exception { 15721 mockHasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, true); 15722 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 15723 OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY; 15724 // Leave one request available so the OEM preference can be set. 15725 testRequestCountLimits(1 /* countToLeaveAvailable */, () -> 15726 withPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, () -> { 15727 // Set initially to test the limit prior to having existing requests. 15728 final TestOemListenerCallback listener = new TestOemListenerCallback(); 15729 mService.setOemNetworkPreference( 15730 createDefaultOemNetworkPreferences(networkPref), listener); 15731 listener.expectOnComplete(); 15732 15733 // re-set so as to test the limit as part of replacing existing requests. 15734 mService.setOemNetworkPreference( 15735 createDefaultOemNetworkPreferences(networkPref), listener); 15736 listener.expectOnComplete(); 15737 })); 15738 } 15739 15740 private void testRequestCountLimits(final int countToLeaveAvailable, 15741 @NonNull final ExceptionalRunnable r) throws Exception { 15742 final ArraySet<TestNetworkCallback> callbacks = new ArraySet<>(); 15743 try { 15744 final int requestCount = mService.mSystemNetworkRequestCounter 15745 .mUidToNetworkRequestCount.get(Process.myUid()); 15746 // The limit is hit when total requests = limit - 1, and exceeded with a crash when 15747 // total requests >= limit. 15748 final int countToFile = 15749 MAX_NETWORK_REQUESTS_PER_SYSTEM_UID - requestCount - countToLeaveAvailable; 15750 // Need permission so registerDefaultNetworkCallback uses mSystemNetworkRequestCounter 15751 withPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, () -> { 15752 for (int i = 1; i < countToFile; i++) { 15753 final TestNetworkCallback cb = new TestNetworkCallback(); 15754 mCm.registerDefaultNetworkCallback(cb); 15755 callbacks.add(cb); 15756 } 15757 assertEquals(MAX_NETWORK_REQUESTS_PER_SYSTEM_UID - 1 - countToLeaveAvailable, 15758 mService.mSystemNetworkRequestCounter 15759 .mUidToNetworkRequestCount.get(Process.myUid())); 15760 }); 15761 // Code to run to check if it triggers a max request count limit error. 15762 r.run(); 15763 } finally { 15764 for (final TestNetworkCallback cb : callbacks) { 15765 mCm.unregisterNetworkCallback(cb); 15766 } 15767 } 15768 } 15769 15770 private void assertCreateNrisFromMobileDataPreferredUids(Set<Integer> uids) { 15771 final Set<NetworkRequestInfo> nris = 15772 mService.createNrisFromMobileDataPreferredUids(uids); 15773 final NetworkRequestInfo nri = nris.iterator().next(); 15774 // Verify that one NRI is created with multilayer requests. Because one NRI can contain 15775 // multiple uid ranges, so it only need create one NRI here. 15776 assertEquals(1, nris.size()); 15777 assertTrue(nri.isMultilayerRequest()); 15778 assertEquals(nri.getUids(), uidRangesForUids(uids)); 15779 assertEquals(PREFERENCE_ORDER_MOBILE_DATA_PREFERERRED, nri.mPreferenceOrder); 15780 } 15781 15782 /** 15783 * Test createNrisFromMobileDataPreferredUids returns correct NetworkRequestInfo. 15784 */ 15785 @Test 15786 public void testCreateNrisFromMobileDataPreferredUids() { 15787 // Verify that empty uid set should not create any NRI for it. 15788 final Set<NetworkRequestInfo> nrisNoUid = 15789 mService.createNrisFromMobileDataPreferredUids(new ArraySet<>()); 15790 assertEquals(0, nrisNoUid.size()); 15791 15792 final int uid1 = PRIMARY_USER_HANDLE.getUid(TEST_PACKAGE_UID); 15793 final int uid2 = PRIMARY_USER_HANDLE.getUid(TEST_PACKAGE_UID2); 15794 final int uid3 = SECONDARY_USER_HANDLE.getUid(TEST_PACKAGE_UID); 15795 assertCreateNrisFromMobileDataPreferredUids(Set.of(uid1)); 15796 assertCreateNrisFromMobileDataPreferredUids(Set.of(uid1, uid3)); 15797 assertCreateNrisFromMobileDataPreferredUids(Set.of(uid1, uid2)); 15798 } 15799 15800 private void setAndUpdateMobileDataPreferredUids(Set<Integer> uids) { 15801 ConnectivitySettingsManager.setMobileDataPreferredUids(mServiceContext, uids); 15802 mService.updateMobileDataPreferredUids(); 15803 waitForIdle(); 15804 } 15805 15806 /** 15807 * Test that MOBILE_DATA_PREFERRED_UIDS changes will send correct net id and uid ranges to netd. 15808 */ 15809 @Test 15810 public void testMobileDataPreferredUidsChanged() throws Exception { 15811 final InOrder inorder = inOrder(mMockNetd); 15812 registerDefaultNetworkCallbacks(); 15813 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 15814 mCellNetworkAgent.connect(true); 15815 mDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 15816 mTestPackageDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 15817 15818 final int cellNetId = mCellNetworkAgent.getNetwork().netId; 15819 inorder.verify(mMockNetd, times(1)).networkCreate(nativeNetworkConfigPhysical( 15820 cellNetId, INetd.PERMISSION_NONE)); 15821 15822 // Initial mobile data preferred uids status. 15823 setAndUpdateMobileDataPreferredUids(Set.of()); 15824 inorder.verify(mMockNetd, never()).networkAddUidRangesParcel(any()); 15825 inorder.verify(mMockNetd, never()).networkRemoveUidRangesParcel(any()); 15826 15827 // Set MOBILE_DATA_PREFERRED_UIDS setting and verify that net id and uid ranges send to netd 15828 final Set<Integer> uids1 = Set.of(PRIMARY_USER_HANDLE.getUid(TEST_PACKAGE_UID)); 15829 final UidRangeParcel[] uidRanges1 = toUidRangeStableParcels(uidRangesForUids(uids1)); 15830 final NativeUidRangeConfig config1 = new NativeUidRangeConfig(cellNetId, uidRanges1, 15831 PREFERENCE_ORDER_MOBILE_DATA_PREFERERRED); 15832 setAndUpdateMobileDataPreferredUids(uids1); 15833 inorder.verify(mMockNetd, times(1)).networkAddUidRangesParcel(config1); 15834 inorder.verify(mMockNetd, never()).networkRemoveUidRangesParcel(any()); 15835 15836 // Set MOBILE_DATA_PREFERRED_UIDS setting again and verify that old rules are removed and 15837 // new rules are added. 15838 final Set<Integer> uids2 = Set.of(PRIMARY_USER_HANDLE.getUid(TEST_PACKAGE_UID), 15839 PRIMARY_USER_HANDLE.getUid(TEST_PACKAGE_UID2), 15840 SECONDARY_USER_HANDLE.getUid(TEST_PACKAGE_UID)); 15841 final UidRangeParcel[] uidRanges2 = toUidRangeStableParcels(uidRangesForUids(uids2)); 15842 final NativeUidRangeConfig config2 = new NativeUidRangeConfig(cellNetId, uidRanges2, 15843 PREFERENCE_ORDER_MOBILE_DATA_PREFERERRED); 15844 setAndUpdateMobileDataPreferredUids(uids2); 15845 inorder.verify(mMockNetd, times(1)).networkRemoveUidRangesParcel(config1); 15846 inorder.verify(mMockNetd, times(1)).networkAddUidRangesParcel(config2); 15847 15848 // Clear MOBILE_DATA_PREFERRED_UIDS setting again and verify that old rules are removed and 15849 // new rules are not added. 15850 setAndUpdateMobileDataPreferredUids(Set.of()); 15851 inorder.verify(mMockNetd, times(1)).networkRemoveUidRangesParcel(config2); 15852 inorder.verify(mMockNetd, never()).networkAddUidRangesParcel(any()); 15853 } 15854 15855 /** 15856 * Make sure mobile data preferred uids feature behaves as expected when the mobile network 15857 * goes up and down while the uids is set. Make sure they behave as expected whether 15858 * there is a general default network or not. 15859 */ 15860 @Test 15861 public void testMobileDataPreferenceForMobileNetworkUpDown() throws Exception { 15862 final InOrder inorder = inOrder(mMockNetd); 15863 // File a request for cell to ensure it doesn't go down. 15864 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback(); 15865 final NetworkRequest cellRequest = new NetworkRequest.Builder() 15866 .addTransportType(TRANSPORT_CELLULAR).build(); 15867 mCm.requestNetwork(cellRequest, cellNetworkCallback); 15868 cellNetworkCallback.assertNoCallback(); 15869 15870 registerDefaultNetworkCallbacks(); 15871 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 15872 mWiFiNetworkAgent.connect(true); 15873 mDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mWiFiNetworkAgent); 15874 mTestPackageDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mWiFiNetworkAgent); 15875 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetworkForUid(TEST_PACKAGE_UID)); 15876 15877 final int wifiNetId = mWiFiNetworkAgent.getNetwork().netId; 15878 inorder.verify(mMockNetd, times(1)).networkCreate(nativeNetworkConfigPhysical( 15879 wifiNetId, INetd.PERMISSION_NONE)); 15880 15881 // Initial mobile data preferred uids status. 15882 setAndUpdateMobileDataPreferredUids(Set.of()); 15883 inorder.verify(mMockNetd, never()).networkAddUidRangesParcel(any()); 15884 inorder.verify(mMockNetd, never()).networkRemoveUidRangesParcel(any()); 15885 15886 // Set MOBILE_DATA_PREFERRED_UIDS setting and verify that wifi net id and uid ranges send to 15887 // netd. 15888 final Set<Integer> uids = Set.of(PRIMARY_USER_HANDLE.getUid(TEST_PACKAGE_UID)); 15889 final UidRangeParcel[] uidRanges = toUidRangeStableParcels(uidRangesForUids(uids)); 15890 final NativeUidRangeConfig wifiConfig = new NativeUidRangeConfig(wifiNetId, uidRanges, 15891 PREFERENCE_ORDER_MOBILE_DATA_PREFERERRED); 15892 setAndUpdateMobileDataPreferredUids(uids); 15893 inorder.verify(mMockNetd, times(1)).networkAddUidRangesParcel(wifiConfig); 15894 inorder.verify(mMockNetd, never()).networkRemoveUidRangesParcel(any()); 15895 15896 // Cellular network connected. mTestPackageDefaultNetworkCallback should receive 15897 // callback with cellular network and net id and uid ranges should be updated to netd. 15898 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 15899 mCellNetworkAgent.connect(true); 15900 cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 15901 mDefaultNetworkCallback.assertNoCallback(); 15902 mTestPackageDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 15903 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetworkForUid(TEST_PACKAGE_UID)); 15904 15905 final int cellNetId = mCellNetworkAgent.getNetwork().netId; 15906 final NativeUidRangeConfig cellConfig = new NativeUidRangeConfig(cellNetId, uidRanges, 15907 PREFERENCE_ORDER_MOBILE_DATA_PREFERERRED); 15908 inorder.verify(mMockNetd, times(1)).networkCreate(nativeNetworkConfigPhysical( 15909 cellNetId, INetd.PERMISSION_NONE)); 15910 inorder.verify(mMockNetd, times(1)).networkAddUidRangesParcel(cellConfig); 15911 inorder.verify(mMockNetd, times(1)).networkRemoveUidRangesParcel(wifiConfig); 15912 15913 // Cellular network disconnected. mTestPackageDefaultNetworkCallback should receive 15914 // callback with wifi network from fallback request. 15915 mCellNetworkAgent.disconnect(); 15916 mDefaultNetworkCallback.assertNoCallback(); 15917 cellNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 15918 mTestPackageDefaultNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 15919 mTestPackageDefaultNetworkCallback.expectAvailableCallbacksValidated(mWiFiNetworkAgent); 15920 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetworkForUid(TEST_PACKAGE_UID)); 15921 inorder.verify(mMockNetd, times(1)).networkAddUidRangesParcel(wifiConfig); 15922 inorder.verify(mMockNetd, never()).networkRemoveUidRangesParcel(any()); 15923 inorder.verify(mMockNetd).networkDestroy(cellNetId); 15924 15925 // Cellular network comes back. mTestPackageDefaultNetworkCallback should receive 15926 // callback with cellular network. 15927 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 15928 mCellNetworkAgent.connect(true); 15929 cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 15930 mDefaultNetworkCallback.assertNoCallback(); 15931 mTestPackageDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 15932 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetworkForUid(TEST_PACKAGE_UID)); 15933 15934 final int cellNetId2 = mCellNetworkAgent.getNetwork().netId; 15935 final NativeUidRangeConfig cellConfig2 = new NativeUidRangeConfig(cellNetId2, uidRanges, 15936 PREFERENCE_ORDER_MOBILE_DATA_PREFERERRED); 15937 inorder.verify(mMockNetd, times(1)).networkCreate(nativeNetworkConfigPhysical( 15938 cellNetId2, INetd.PERMISSION_NONE)); 15939 inorder.verify(mMockNetd, times(1)).networkAddUidRangesParcel(cellConfig2); 15940 inorder.verify(mMockNetd, times(1)).networkRemoveUidRangesParcel(wifiConfig); 15941 15942 // Wifi network disconnected. mTestPackageDefaultNetworkCallback should not receive 15943 // any callback. 15944 mWiFiNetworkAgent.disconnect(); 15945 mDefaultNetworkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 15946 mDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellNetworkAgent); 15947 mTestPackageDefaultNetworkCallback.assertNoCallback(); 15948 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetworkForUid(TEST_PACKAGE_UID)); 15949 waitForIdle(); 15950 inorder.verify(mMockNetd, never()).networkAddUidRangesParcel(any()); 15951 inorder.verify(mMockNetd, never()).networkRemoveUidRangesParcel(any()); 15952 inorder.verify(mMockNetd).networkDestroy(wifiNetId); 15953 15954 mCm.unregisterNetworkCallback(cellNetworkCallback); 15955 } 15956 15957 @Test 15958 public void testMultilayerRequestsOfSetMobileDataPreferredUids() throws Exception { 15959 // First set mobile data preferred uid to create a multi-layer requests: 1. request for 15960 // cellular, 2. track the default network for fallback. 15961 setAndUpdateMobileDataPreferredUids( 15962 Set.of(PRIMARY_USER_HANDLE.getUid(TEST_PACKAGE_UID))); 15963 15964 final HandlerThread handlerThread = new HandlerThread("MockFactory"); 15965 handlerThread.start(); 15966 final NetworkCapabilities cellFilter = new NetworkCapabilities() 15967 .addTransportType(TRANSPORT_CELLULAR) 15968 .addCapability(NET_CAPABILITY_INTERNET) 15969 .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED); 15970 final MockNetworkFactory cellFactory = new MockNetworkFactory(handlerThread.getLooper(), 15971 mServiceContext, "cellFactory", cellFilter, mCsHandlerThread); 15972 cellFactory.setScoreFilter(40); 15973 15974 try { 15975 cellFactory.register(); 15976 // Default internet request and the mobile data preferred request. 15977 cellFactory.expectRequestAdds(2); 15978 cellFactory.assertRequestCountEquals(2); 15979 15980 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 15981 mWiFiNetworkAgent.connect(true); 15982 15983 // The cellFactory however is outscored, and should lose default internet request. 15984 // But it should still see mobile data preferred request. 15985 cellFactory.expectRequestRemove(); 15986 cellFactory.assertRequestCountEquals(1); 15987 15988 mWiFiNetworkAgent.disconnect(); 15989 // The network satisfying the default internet request has disconnected, so the 15990 // cellFactory sees the default internet requests again. 15991 cellFactory.expectRequestAdd(); 15992 cellFactory.assertRequestCountEquals(2); 15993 } finally { 15994 cellFactory.terminate(); 15995 handlerThread.quitSafely(); 15996 } 15997 } 15998 15999 /** 16000 * Validate request counts are counted accurately on MOBILE_DATA_PREFERRED_UIDS change 16001 * on set/replace. 16002 */ 16003 @Test 16004 public void testMobileDataPreferredUidsChangedCountsRequestsCorrectlyOnSet() throws Exception { 16005 ConnectivitySettingsManager.setMobileDataPreferredUids(mServiceContext, 16006 Set.of(PRIMARY_USER_HANDLE.getUid(TEST_PACKAGE_UID))); 16007 // Leave one request available so MDO preference set up above can be set. 16008 testRequestCountLimits(1 /* countToLeaveAvailable */, () -> 16009 withPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, 16010 Process.myPid(), Process.myUid(), () -> { 16011 // Set initially to test the limit prior to having existing requests. 16012 mService.updateMobileDataPreferredUids(); 16013 waitForIdle(); 16014 16015 // re-set so as to test the limit as part of replacing existing requests 16016 mService.updateMobileDataPreferredUids(); 16017 waitForIdle(); 16018 })); 16019 } 16020 16021 @Test 16022 public void testAllNetworkPreferencesCanCoexist() 16023 throws Exception { 16024 final InOrder inorder = inOrder(mMockNetd); 16025 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 16026 OEM_NETWORK_PREFERENCE_OEM_PAID; 16027 final UserHandle testHandle = setupEnterpriseNetwork(); 16028 16029 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); 16030 final int cellNetId = mCellNetworkAgent.getNetwork().netId; 16031 inorder.verify(mMockNetd, times(1)).networkCreate(nativeNetworkConfigPhysical( 16032 cellNetId, INetd.PERMISSION_NONE)); 16033 16034 // Set oem network preference 16035 final int[] uids1 = new int[] { PRIMARY_USER_HANDLE.getUid(TEST_PACKAGE_UID) }; 16036 final UidRangeParcel[] uidRanges1 = toUidRangeStableParcels(uidRangesForUids(uids1)); 16037 final NativeUidRangeConfig config1 = new NativeUidRangeConfig(cellNetId, uidRanges1, 16038 PREFERENCE_ORDER_OEM); 16039 setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges1, TEST_PACKAGE_NAME); 16040 inorder.verify(mMockNetd, times(1)).networkAddUidRangesParcel(config1); 16041 inorder.verify(mMockNetd, never()).networkRemoveUidRangesParcel(any()); 16042 16043 // Set user profile network preference 16044 final TestNetworkAgentWrapper workAgent = makeEnterpriseNetworkAgent(); 16045 workAgent.connect(true); 16046 16047 final TestOnCompleteListener listener = new TestOnCompleteListener(); 16048 mCm.setProfileNetworkPreference(testHandle, PROFILE_NETWORK_PREFERENCE_ENTERPRISE, 16049 r -> r.run(), listener); 16050 listener.expectOnComplete(); 16051 final NativeUidRangeConfig config2 = new NativeUidRangeConfig(workAgent.getNetwork().netId, 16052 uidRangeFor(testHandle), PREFERENCE_ORDER_PROFILE); 16053 inorder.verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( 16054 workAgent.getNetwork().netId, INetd.PERMISSION_SYSTEM)); 16055 inorder.verify(mMockNetd, never()).networkRemoveUidRangesParcel(any()); 16056 inorder.verify(mMockNetd).networkAddUidRangesParcel(config2); 16057 16058 // Set MOBILE_DATA_PREFERRED_UIDS setting 16059 final Set<Integer> uids2 = Set.of(PRIMARY_USER_HANDLE.getUid(TEST_PACKAGE_UID2)); 16060 final UidRangeParcel[] uidRanges2 = toUidRangeStableParcels(uidRangesForUids(uids2)); 16061 final NativeUidRangeConfig config3 = new NativeUidRangeConfig(cellNetId, uidRanges2, 16062 PREFERENCE_ORDER_MOBILE_DATA_PREFERERRED); 16063 setAndUpdateMobileDataPreferredUids(uids2); 16064 inorder.verify(mMockNetd, never()).networkRemoveUidRangesParcel(any()); 16065 inorder.verify(mMockNetd, times(1)).networkAddUidRangesParcel(config3); 16066 16067 // Set oem network preference again with different uid. 16068 final Set<Integer> uids3 = Set.of(PRIMARY_USER_HANDLE.getUid(TEST_PACKAGE_UID3)); 16069 final UidRangeParcel[] uidRanges3 = toUidRangeStableParcels(uidRangesForUids(uids3)); 16070 final NativeUidRangeConfig config4 = new NativeUidRangeConfig(cellNetId, uidRanges3, 16071 PREFERENCE_ORDER_OEM); 16072 setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges3, "com.android.test"); 16073 inorder.verify(mMockNetd, times(1)).networkRemoveUidRangesParcel(config1); 16074 inorder.verify(mMockNetd, times(1)).networkAddUidRangesParcel(config4); 16075 16076 // Remove user profile network preference 16077 mCm.setProfileNetworkPreference(testHandle, PROFILE_NETWORK_PREFERENCE_DEFAULT, 16078 r -> r.run(), listener); 16079 listener.expectOnComplete(); 16080 inorder.verify(mMockNetd, times(1)).networkRemoveUidRangesParcel(config2); 16081 inorder.verify(mMockNetd, never()).networkAddUidRangesParcel(any()); 16082 16083 // Set MOBILE_DATA_PREFERRED_UIDS setting again with same uid as oem network preference. 16084 final NativeUidRangeConfig config6 = new NativeUidRangeConfig(cellNetId, uidRanges3, 16085 PREFERENCE_ORDER_MOBILE_DATA_PREFERERRED); 16086 setAndUpdateMobileDataPreferredUids(uids3); 16087 inorder.verify(mMockNetd, times(1)).networkRemoveUidRangesParcel(config3); 16088 inorder.verify(mMockNetd, times(1)).networkAddUidRangesParcel(config6); 16089 } 16090 16091 @Test 16092 public void testNetworkCallbackAndActiveNetworkForUid_AllNetworkPreferencesEnabled() 16093 throws Exception { 16094 // File a request for cell to ensure it doesn't go down. 16095 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback(); 16096 final NetworkRequest cellRequest = new NetworkRequest.Builder() 16097 .addTransportType(TRANSPORT_CELLULAR).build(); 16098 mCm.requestNetwork(cellRequest, cellNetworkCallback); 16099 cellNetworkCallback.assertNoCallback(); 16100 16101 // Register callbacks and have wifi network as default network. 16102 registerDefaultNetworkCallbacks(); 16103 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 16104 mWiFiNetworkAgent.connect(true); 16105 mDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mWiFiNetworkAgent); 16106 mProfileDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mWiFiNetworkAgent); 16107 mTestPackageDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mWiFiNetworkAgent); 16108 assertEquals(mWiFiNetworkAgent.getNetwork(), 16109 mCm.getActiveNetworkForUid(TEST_WORK_PROFILE_APP_UID)); 16110 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetworkForUid(TEST_PACKAGE_UID)); 16111 16112 // Set MOBILE_DATA_PREFERRED_UIDS setting with TEST_WORK_PROFILE_APP_UID and 16113 // TEST_PACKAGE_UID. Both mProfileDefaultNetworkCallback and 16114 // mTestPackageDefaultNetworkCallback should receive callback with cell network. 16115 setAndUpdateMobileDataPreferredUids(Set.of(TEST_WORK_PROFILE_APP_UID, TEST_PACKAGE_UID)); 16116 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 16117 mCellNetworkAgent.connect(true); 16118 cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 16119 mDefaultNetworkCallback.assertNoCallback(); 16120 mProfileDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 16121 mTestPackageDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 16122 assertEquals(mCellNetworkAgent.getNetwork(), 16123 mCm.getActiveNetworkForUid(TEST_WORK_PROFILE_APP_UID)); 16124 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetworkForUid(TEST_PACKAGE_UID)); 16125 16126 // Set user profile network preference with test profile. mProfileDefaultNetworkCallback 16127 // should receive callback with higher priority network preference (enterprise network). 16128 // The others should have no callbacks. 16129 final UserHandle testHandle = setupEnterpriseNetwork(); 16130 final TestNetworkAgentWrapper workAgent = makeEnterpriseNetworkAgent(); 16131 workAgent.connect(true); 16132 final TestOnCompleteListener listener = new TestOnCompleteListener(); 16133 mCm.setProfileNetworkPreference(testHandle, PROFILE_NETWORK_PREFERENCE_ENTERPRISE, 16134 r -> r.run(), listener); 16135 listener.expectOnComplete(); 16136 assertNoCallbacks(mDefaultNetworkCallback, mTestPackageDefaultNetworkCallback); 16137 mProfileDefaultNetworkCallback.expectAvailableCallbacksValidated(workAgent); 16138 assertEquals(workAgent.getNetwork(), mCm.getActiveNetworkForUid(TEST_WORK_PROFILE_APP_UID)); 16139 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetworkForUid(TEST_PACKAGE_UID)); 16140 16141 // Set oem network preference with TEST_PACKAGE_UID. mTestPackageDefaultNetworkCallback 16142 // should receive callback with higher priority network preference (current default network) 16143 // and the others should have no callbacks. 16144 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 16145 OEM_NETWORK_PREFERENCE_OEM_PAID; 16146 final int[] uids1 = new int[] { TEST_PACKAGE_UID }; 16147 final UidRangeParcel[] uidRanges1 = toUidRangeStableParcels(uidRangesForUids(uids1)); 16148 setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges1, TEST_PACKAGE_NAME); 16149 assertNoCallbacks(mDefaultNetworkCallback, mProfileDefaultNetworkCallback); 16150 mTestPackageDefaultNetworkCallback.expectAvailableCallbacksValidated(mWiFiNetworkAgent); 16151 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetworkForUid(TEST_PACKAGE_UID)); 16152 assertEquals(workAgent.getNetwork(), mCm.getActiveNetworkForUid(TEST_WORK_PROFILE_APP_UID)); 16153 16154 // Set oem network preference with TEST_WORK_PROFILE_APP_UID. Both 16155 // mProfileDefaultNetworkCallback and mTestPackageDefaultNetworkCallback should receive 16156 // callback. 16157 final int[] uids2 = new int[] { TEST_WORK_PROFILE_APP_UID }; 16158 final UidRangeParcel[] uidRanges2 = toUidRangeStableParcels(uidRangesForUids(uids2)); 16159 doReturn(Arrays.asList(testHandle)).when(mUserManager).getUserHandles(anyBoolean()); 16160 setupSetOemNetworkPreferenceForPreferenceTest( 16161 networkPref, uidRanges2, "com.android.test", testHandle); 16162 mDefaultNetworkCallback.assertNoCallback(); 16163 mProfileDefaultNetworkCallback.expectAvailableCallbacksValidated(mWiFiNetworkAgent); 16164 mTestPackageDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellNetworkAgent); 16165 assertEquals(mWiFiNetworkAgent.getNetwork(), 16166 mCm.getActiveNetworkForUid(TEST_WORK_PROFILE_APP_UID)); 16167 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetworkForUid(TEST_PACKAGE_UID)); 16168 16169 // Remove oem network preference, mProfileDefaultNetworkCallback should receive callback 16170 // with current highest priority network preference (enterprise network) and the others 16171 // should have no callbacks. 16172 final TestOemListenerCallback oemPrefListener = new TestOemListenerCallback(); 16173 mService.setOemNetworkPreference( 16174 new OemNetworkPreferences.Builder().build(), oemPrefListener); 16175 oemPrefListener.expectOnComplete(); 16176 assertNoCallbacks(mDefaultNetworkCallback, mTestPackageDefaultNetworkCallback); 16177 mProfileDefaultNetworkCallback.expectAvailableCallbacksValidated(workAgent); 16178 assertEquals(workAgent.getNetwork(), mCm.getActiveNetworkForUid(TEST_WORK_PROFILE_APP_UID)); 16179 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetworkForUid(TEST_PACKAGE_UID)); 16180 16181 // Remove user profile network preference. 16182 mCm.setProfileNetworkPreference(testHandle, PROFILE_NETWORK_PREFERENCE_DEFAULT, 16183 r -> r.run(), listener); 16184 listener.expectOnComplete(); 16185 assertNoCallbacks(mDefaultNetworkCallback, mTestPackageDefaultNetworkCallback); 16186 mProfileDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellNetworkAgent); 16187 assertEquals(mCellNetworkAgent.getNetwork(), 16188 mCm.getActiveNetworkForUid(TEST_WORK_PROFILE_APP_UID)); 16189 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetworkForUid(TEST_PACKAGE_UID)); 16190 16191 // Disconnect wifi 16192 mWiFiNetworkAgent.disconnect(); 16193 assertNoCallbacks(mProfileDefaultNetworkCallback, mTestPackageDefaultNetworkCallback); 16194 mDefaultNetworkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 16195 mDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellNetworkAgent); 16196 } 16197 16198 @Test 16199 public void testRequestRouteToHostAddress_PackageDoesNotBelongToCaller() { 16200 assertThrows(SecurityException.class, () -> mService.requestRouteToHostAddress( 16201 ConnectivityManager.TYPE_NONE, null /* hostAddress */, "com.not.package.owner", 16202 null /* callingAttributionTag */)); 16203 } 16204 16205 @Test @IgnoreUpTo(SC_V2) 16206 public void testUpdateRateLimit_EnableDisable() throws Exception { 16207 final LinkProperties wifiLp = new LinkProperties(); 16208 wifiLp.setInterfaceName(WIFI_IFNAME); 16209 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, wifiLp); 16210 mWiFiNetworkAgent.connect(true); 16211 16212 final LinkProperties cellLp = new LinkProperties(); 16213 cellLp.setInterfaceName(MOBILE_IFNAME); 16214 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp); 16215 mCellNetworkAgent.connect(false); 16216 16217 waitForIdle(); 16218 16219 final ArrayTrackRecord<Pair<String, Long>>.ReadHead readHeadWifi = 16220 mDeps.mRateLimitHistory.newReadHead(); 16221 final ArrayTrackRecord<Pair<String, Long>>.ReadHead readHeadCell = 16222 mDeps.mRateLimitHistory.newReadHead(); 16223 16224 // set rate limit to 8MBit/s => 1MB/s 16225 final int rateLimitInBytesPerSec = 1 * 1000 * 1000; 16226 setIngressRateLimit(rateLimitInBytesPerSec); 16227 16228 assertNotNull(readHeadWifi.poll(TIMEOUT_MS, 16229 it -> it.first == wifiLp.getInterfaceName() 16230 && it.second == rateLimitInBytesPerSec)); 16231 assertNotNull(readHeadCell.poll(TIMEOUT_MS, 16232 it -> it.first == cellLp.getInterfaceName() 16233 && it.second == rateLimitInBytesPerSec)); 16234 16235 // disable rate limiting 16236 setIngressRateLimit(-1); 16237 16238 assertNotNull(readHeadWifi.poll(TIMEOUT_MS, 16239 it -> it.first == wifiLp.getInterfaceName() && it.second == -1)); 16240 assertNotNull(readHeadCell.poll(TIMEOUT_MS, 16241 it -> it.first == cellLp.getInterfaceName() && it.second == -1)); 16242 } 16243 16244 @Test @IgnoreUpTo(SC_V2) 16245 public void testUpdateRateLimit_WhenNewNetworkIsAdded() throws Exception { 16246 final LinkProperties wifiLp = new LinkProperties(); 16247 wifiLp.setInterfaceName(WIFI_IFNAME); 16248 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, wifiLp); 16249 mWiFiNetworkAgent.connect(true); 16250 16251 waitForIdle(); 16252 16253 final ArrayTrackRecord<Pair<String, Long>>.ReadHead readHead = 16254 mDeps.mRateLimitHistory.newReadHead(); 16255 16256 // set rate limit to 8MBit/s => 1MB/s 16257 final int rateLimitInBytesPerSec = 1 * 1000 * 1000; 16258 setIngressRateLimit(rateLimitInBytesPerSec); 16259 assertNotNull(readHead.poll(TIMEOUT_MS, it -> it.first == wifiLp.getInterfaceName() 16260 && it.second == rateLimitInBytesPerSec)); 16261 16262 final LinkProperties cellLp = new LinkProperties(); 16263 cellLp.setInterfaceName(MOBILE_IFNAME); 16264 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp); 16265 mCellNetworkAgent.connect(false); 16266 assertNotNull(readHead.poll(TIMEOUT_MS, it -> it.first == cellLp.getInterfaceName() 16267 && it.second == rateLimitInBytesPerSec)); 16268 } 16269 16270 @Test @IgnoreUpTo(SC_V2) 16271 public void testUpdateRateLimit_OnlyAffectsInternetCapableNetworks() throws Exception { 16272 final LinkProperties wifiLp = new LinkProperties(); 16273 wifiLp.setInterfaceName(WIFI_IFNAME); 16274 16275 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, wifiLp); 16276 mWiFiNetworkAgent.connectWithoutInternet(); 16277 16278 waitForIdle(); 16279 16280 setIngressRateLimit(1000); 16281 setIngressRateLimit(-1); 16282 16283 final ArrayTrackRecord<Pair<String, Long>>.ReadHead readHeadWifi = 16284 mDeps.mRateLimitHistory.newReadHead(); 16285 assertNull(readHeadWifi.poll(TIMEOUT_MS, it -> it.first == wifiLp.getInterfaceName())); 16286 } 16287 16288 @Test @IgnoreUpTo(SC_V2) 16289 public void testUpdateRateLimit_DisconnectingResetsRateLimit() 16290 throws Exception { 16291 // Steps: 16292 // - connect network 16293 // - set rate limit 16294 // - disconnect network (interface still exists) 16295 // - disable rate limit 16296 // - connect network 16297 // - ensure network interface is not rate limited 16298 final LinkProperties wifiLp = new LinkProperties(); 16299 wifiLp.setInterfaceName(WIFI_IFNAME); 16300 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, wifiLp); 16301 mWiFiNetworkAgent.connect(true); 16302 waitForIdle(); 16303 16304 final ArrayTrackRecord<Pair<String, Long>>.ReadHead readHeadWifi = 16305 mDeps.mRateLimitHistory.newReadHead(); 16306 16307 int rateLimitInBytesPerSec = 1000; 16308 setIngressRateLimit(rateLimitInBytesPerSec); 16309 assertNotNull(readHeadWifi.poll(TIMEOUT_MS, 16310 it -> it.first == wifiLp.getInterfaceName() 16311 && it.second == rateLimitInBytesPerSec)); 16312 16313 mWiFiNetworkAgent.disconnect(); 16314 assertNotNull(readHeadWifi.poll(TIMEOUT_MS, 16315 it -> it.first == wifiLp.getInterfaceName() && it.second == -1)); 16316 16317 setIngressRateLimit(-1); 16318 16319 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, wifiLp); 16320 mWiFiNetworkAgent.connect(true); 16321 assertNull(readHeadWifi.poll(TIMEOUT_MS, it -> it.first == wifiLp.getInterfaceName())); 16322 } 16323 16324 @Test @IgnoreUpTo(SC_V2) 16325 public void testUpdateRateLimit_UpdateExistingRateLimit() throws Exception { 16326 final LinkProperties wifiLp = new LinkProperties(); 16327 wifiLp.setInterfaceName(WIFI_IFNAME); 16328 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, wifiLp); 16329 mWiFiNetworkAgent.connect(true); 16330 waitForIdle(); 16331 16332 final ArrayTrackRecord<Pair<String, Long>>.ReadHead readHeadWifi = 16333 mDeps.mRateLimitHistory.newReadHead(); 16334 16335 // update an active ingress rate limit 16336 setIngressRateLimit(1000); 16337 setIngressRateLimit(2000); 16338 16339 // verify the following order of execution: 16340 // 1. ingress rate limit set to 1000. 16341 // 2. ingress rate limit disabled (triggered by updating active rate limit). 16342 // 3. ingress rate limit set to 2000. 16343 assertNotNull(readHeadWifi.poll(TIMEOUT_MS, 16344 it -> it.first == wifiLp.getInterfaceName() 16345 && it.second == 1000)); 16346 assertNotNull(readHeadWifi.poll(TIMEOUT_MS, 16347 it -> it.first == wifiLp.getInterfaceName() 16348 && it.second == -1)); 16349 assertNotNull(readHeadWifi.poll(TIMEOUT_MS, 16350 it -> it.first == wifiLp.getInterfaceName() 16351 && it.second == 2000)); 16352 } 16353 16354 @Test @IgnoreAfter(SC_V2) 16355 public void testUpdateRateLimit_DoesNothingBeforeT() throws Exception { 16356 final LinkProperties wifiLp = new LinkProperties(); 16357 wifiLp.setInterfaceName(WIFI_IFNAME); 16358 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, wifiLp); 16359 mWiFiNetworkAgent.connect(true); 16360 waitForIdle(); 16361 16362 final ArrayTrackRecord<Pair<String, Long>>.ReadHead readHead = 16363 mDeps.mRateLimitHistory.newReadHead(); 16364 16365 setIngressRateLimit(1000); 16366 waitForIdle(); 16367 16368 assertNull(readHead.poll(TEST_CALLBACK_TIMEOUT_MS, it -> true)); 16369 } 16370 16371 @Test 16372 public void testIgnoreValidationAfterRoamDisabled() throws Exception { 16373 assumeFalse(SdkLevel.isAtLeastT()); 16374 // testIgnoreValidationAfterRoam off 16375 doReturn(-1).when(mResources) 16376 .getInteger(R.integer.config_validationFailureAfterRoamIgnoreTimeMillis); 16377 16378 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 16379 mCellNetworkAgent.connect(true); 16380 NetworkCapabilities wifiNc1 = new NetworkCapabilities() 16381 .addTransportType(TRANSPORT_WIFI) 16382 .setTransportInfo(new WifiInfo.Builder().setBssid("AA:AA:AA:AA:AA:AA").build()); 16383 NetworkCapabilities wifiNc2 = new NetworkCapabilities() 16384 .addTransportType(TRANSPORT_WIFI) 16385 .setTransportInfo(new WifiInfo.Builder().setBssid("BB:BB:BB:BB:BB:BB").build()); 16386 final LinkProperties wifiLp = new LinkProperties(); 16387 wifiLp.setInterfaceName(WIFI_IFNAME); 16388 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, wifiLp, wifiNc1); 16389 mWiFiNetworkAgent.connect(true); 16390 16391 // The default network will be switching to Wi-Fi Network. 16392 final TestNetworkCallback wifiNetworkCallback = new TestNetworkCallback(); 16393 final NetworkRequest wifiRequest = new NetworkRequest.Builder() 16394 .addTransportType(TRANSPORT_WIFI).build(); 16395 mCm.registerNetworkCallback(wifiRequest, wifiNetworkCallback); 16396 wifiNetworkCallback.expectAvailableCallbacksValidated(mWiFiNetworkAgent); 16397 registerDefaultNetworkCallbacks(); 16398 mDefaultNetworkCallback.expectAvailableCallbacksValidated(mWiFiNetworkAgent); 16399 16400 // Wi-Fi roaming from wifiNc1 to wifiNc2. 16401 mWiFiNetworkAgent.setNetworkCapabilities(wifiNc2, true); 16402 mWiFiNetworkAgent.setNetworkInvalid(false); 16403 mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), false); 16404 mDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellNetworkAgent); 16405 } 16406 16407 @Test 16408 public void testIgnoreValidationAfterRoamEnabled() throws Exception { 16409 assumeFalse(SdkLevel.isAtLeastT()); 16410 // testIgnoreValidationAfterRoam on 16411 doReturn(5000).when(mResources) 16412 .getInteger(R.integer.config_validationFailureAfterRoamIgnoreTimeMillis); 16413 16414 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 16415 mCellNetworkAgent.connect(true); 16416 NetworkCapabilities wifiNc1 = new NetworkCapabilities() 16417 .addTransportType(TRANSPORT_WIFI) 16418 .setTransportInfo(new WifiInfo.Builder().setBssid("AA:AA:AA:AA:AA:AA").build()); 16419 NetworkCapabilities wifiNc2 = new NetworkCapabilities() 16420 .addTransportType(TRANSPORT_WIFI) 16421 .setTransportInfo(new WifiInfo.Builder().setBssid("BB:BB:BB:BB:BB:BB").build()); 16422 final LinkProperties wifiLp = new LinkProperties(); 16423 wifiLp.setInterfaceName(WIFI_IFNAME); 16424 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, wifiLp, wifiNc1); 16425 mWiFiNetworkAgent.connect(true); 16426 16427 // The default network will be switching to Wi-Fi Network. 16428 final TestNetworkCallback wifiNetworkCallback = new TestNetworkCallback(); 16429 final NetworkRequest wifiRequest = new NetworkRequest.Builder() 16430 .addTransportType(TRANSPORT_WIFI).build(); 16431 mCm.registerNetworkCallback(wifiRequest, wifiNetworkCallback); 16432 wifiNetworkCallback.expectAvailableCallbacksValidated(mWiFiNetworkAgent); 16433 registerDefaultNetworkCallbacks(); 16434 mDefaultNetworkCallback.expectAvailableCallbacksValidated(mWiFiNetworkAgent); 16435 16436 // Wi-Fi roaming from wifiNc1 to wifiNc2. 16437 mWiFiNetworkAgent.setNetworkCapabilities(wifiNc2, true); 16438 mWiFiNetworkAgent.setNetworkInvalid(false); 16439 mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), false); 16440 16441 // Network validation failed, but the result will be ignored. 16442 assertTrue(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).hasCapability( 16443 NET_CAPABILITY_VALIDATED)); 16444 mWiFiNetworkAgent.setNetworkValid(false); 16445 16446 // Behavior of after config_validationFailureAfterRoamIgnoreTimeMillis 16447 ConditionVariable waitForValidationBlock = new ConditionVariable(); 16448 doReturn(50).when(mResources) 16449 .getInteger(R.integer.config_validationFailureAfterRoamIgnoreTimeMillis); 16450 // Wi-Fi roaming from wifiNc2 to wifiNc1. 16451 mWiFiNetworkAgent.setNetworkCapabilities(wifiNc1, true); 16452 mWiFiNetworkAgent.setNetworkInvalid(false); 16453 waitForValidationBlock.block(150); 16454 mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), false); 16455 mDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellNetworkAgent); 16456 } 16457 16458 @Test 16459 public void testLegacyTetheringApiGuardWithProperPermission() throws Exception { 16460 final String testIface = "test0"; 16461 mServiceContext.setPermission(ACCESS_NETWORK_STATE, PERMISSION_DENIED); 16462 assertThrows(SecurityException.class, () -> mService.getLastTetherError(testIface)); 16463 assertThrows(SecurityException.class, () -> mService.getTetherableIfaces()); 16464 assertThrows(SecurityException.class, () -> mService.getTetheredIfaces()); 16465 assertThrows(SecurityException.class, () -> mService.getTetheringErroredIfaces()); 16466 assertThrows(SecurityException.class, () -> mService.getTetherableUsbRegexs()); 16467 assertThrows(SecurityException.class, () -> mService.getTetherableWifiRegexs()); 16468 16469 withPermission(ACCESS_NETWORK_STATE, () -> { 16470 mService.getLastTetherError(testIface); 16471 verify(mTetheringManager).getLastTetherError(testIface); 16472 16473 mService.getTetherableIfaces(); 16474 verify(mTetheringManager).getTetherableIfaces(); 16475 16476 mService.getTetheredIfaces(); 16477 verify(mTetheringManager).getTetheredIfaces(); 16478 16479 mService.getTetheringErroredIfaces(); 16480 verify(mTetheringManager).getTetheringErroredIfaces(); 16481 16482 mService.getTetherableUsbRegexs(); 16483 verify(mTetheringManager).getTetherableUsbRegexs(); 16484 16485 mService.getTetherableWifiRegexs(); 16486 verify(mTetheringManager).getTetherableWifiRegexs(); 16487 }); 16488 } 16489 } 16490