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.CHANGE_NETWORK_STATE; 20 import static android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS; 21 import static android.Manifest.permission.CONTROL_OEM_PAID_NETWORK_PREFERENCE; 22 import static android.Manifest.permission.CREATE_USERS; 23 import static android.Manifest.permission.DUMP; 24 import static android.Manifest.permission.GET_INTENT_SENDER_INTENT; 25 import static android.Manifest.permission.LOCAL_MAC_ADDRESS; 26 import static android.Manifest.permission.NETWORK_FACTORY; 27 import static android.Manifest.permission.NETWORK_SETTINGS; 28 import static android.Manifest.permission.NETWORK_STACK; 29 import static android.Manifest.permission.PACKET_KEEPALIVE_OFFLOAD; 30 import static android.app.PendingIntent.FLAG_IMMUTABLE; 31 import static android.content.Intent.ACTION_PACKAGE_ADDED; 32 import static android.content.Intent.ACTION_PACKAGE_REMOVED; 33 import static android.content.Intent.ACTION_PACKAGE_REPLACED; 34 import static android.content.Intent.ACTION_USER_ADDED; 35 import static android.content.Intent.ACTION_USER_REMOVED; 36 import static android.content.Intent.ACTION_USER_UNLOCKED; 37 import static android.content.pm.PackageInfo.REQUESTED_PERMISSION_GRANTED; 38 import static android.content.pm.PackageManager.FEATURE_WIFI; 39 import static android.content.pm.PackageManager.FEATURE_WIFI_DIRECT; 40 import static android.content.pm.PackageManager.GET_PERMISSIONS; 41 import static android.content.pm.PackageManager.MATCH_ANY_USER; 42 import static android.content.pm.PackageManager.PERMISSION_DENIED; 43 import static android.content.pm.PackageManager.PERMISSION_GRANTED; 44 import static android.net.ConnectivityManager.ACTION_CAPTIVE_PORTAL_SIGN_IN; 45 import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_DATA_SAVER; 46 import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_MASK; 47 import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_USER_RESTRICTED; 48 import static android.net.ConnectivityManager.BLOCKED_REASON_BATTERY_SAVER; 49 import static android.net.ConnectivityManager.BLOCKED_REASON_NONE; 50 import static android.net.ConnectivityManager.CONNECTIVITY_ACTION; 51 import static android.net.ConnectivityManager.EXTRA_NETWORK_INFO; 52 import static android.net.ConnectivityManager.EXTRA_NETWORK_TYPE; 53 import static android.net.ConnectivityManager.PROFILE_NETWORK_PREFERENCE_DEFAULT; 54 import static android.net.ConnectivityManager.PROFILE_NETWORK_PREFERENCE_ENTERPRISE; 55 import static android.net.ConnectivityManager.TYPE_ETHERNET; 56 import static android.net.ConnectivityManager.TYPE_MOBILE; 57 import static android.net.ConnectivityManager.TYPE_MOBILE_FOTA; 58 import static android.net.ConnectivityManager.TYPE_MOBILE_MMS; 59 import static android.net.ConnectivityManager.TYPE_MOBILE_SUPL; 60 import static android.net.ConnectivityManager.TYPE_PROXY; 61 import static android.net.ConnectivityManager.TYPE_VPN; 62 import static android.net.ConnectivityManager.TYPE_WIFI; 63 import static android.net.ConnectivitySettingsManager.PRIVATE_DNS_MODE_OFF; 64 import static android.net.ConnectivitySettingsManager.PRIVATE_DNS_MODE_OPPORTUNISTIC; 65 import static android.net.ConnectivitySettingsManager.PRIVATE_DNS_MODE_PROVIDER_HOSTNAME; 66 import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_DNS; 67 import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_FALLBACK; 68 import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_HTTP; 69 import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_HTTPS; 70 import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_PRIVDNS; 71 import static android.net.INetworkMonitor.NETWORK_VALIDATION_RESULT_PARTIAL; 72 import static android.net.INetworkMonitor.NETWORK_VALIDATION_RESULT_VALID; 73 import static android.net.NetworkCapabilities.NET_CAPABILITY_BIP; 74 import static android.net.NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL; 75 import static android.net.NetworkCapabilities.NET_CAPABILITY_CBS; 76 import static android.net.NetworkCapabilities.NET_CAPABILITY_DUN; 77 import static android.net.NetworkCapabilities.NET_CAPABILITY_EIMS; 78 import static android.net.NetworkCapabilities.NET_CAPABILITY_ENTERPRISE; 79 import static android.net.NetworkCapabilities.NET_CAPABILITY_FOREGROUND; 80 import static android.net.NetworkCapabilities.NET_CAPABILITY_FOTA; 81 import static android.net.NetworkCapabilities.NET_CAPABILITY_IA; 82 import static android.net.NetworkCapabilities.NET_CAPABILITY_IMS; 83 import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET; 84 import static android.net.NetworkCapabilities.NET_CAPABILITY_MMS; 85 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED; 86 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED; 87 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED; 88 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING; 89 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED; 90 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED; 91 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN; 92 import static android.net.NetworkCapabilities.NET_CAPABILITY_OEM_PAID; 93 import static android.net.NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE; 94 import static android.net.NetworkCapabilities.NET_CAPABILITY_PARTIAL_CONNECTIVITY; 95 import static android.net.NetworkCapabilities.NET_CAPABILITY_RCS; 96 import static android.net.NetworkCapabilities.NET_CAPABILITY_SUPL; 97 import static android.net.NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED; 98 import static android.net.NetworkCapabilities.NET_CAPABILITY_TRUSTED; 99 import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED; 100 import static android.net.NetworkCapabilities.NET_CAPABILITY_VSIM; 101 import static android.net.NetworkCapabilities.NET_CAPABILITY_WIFI_P2P; 102 import static android.net.NetworkCapabilities.NET_CAPABILITY_XCAP; 103 import static android.net.NetworkCapabilities.REDACT_FOR_ACCESS_FINE_LOCATION; 104 import static android.net.NetworkCapabilities.REDACT_FOR_LOCAL_MAC_ADDRESS; 105 import static android.net.NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS; 106 import static android.net.NetworkCapabilities.REDACT_NONE; 107 import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; 108 import static android.net.NetworkCapabilities.TRANSPORT_ETHERNET; 109 import static android.net.NetworkCapabilities.TRANSPORT_VPN; 110 import static android.net.NetworkCapabilities.TRANSPORT_WIFI; 111 import static android.net.NetworkCapabilities.TRANSPORT_WIFI_AWARE; 112 import static android.net.NetworkScore.KEEP_CONNECTED_FOR_HANDOVER; 113 import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID; 114 import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK; 115 import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY; 116 import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY; 117 import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_TEST; 118 import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_TEST_ONLY; 119 import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_UNINITIALIZED; 120 import static android.net.RouteInfo.RTN_UNREACHABLE; 121 import static android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener.PREFIX_OPERATION_ADDED; 122 import static android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener.PREFIX_OPERATION_REMOVED; 123 import static android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener.VALIDATION_RESULT_FAILURE; 124 import static android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener.VALIDATION_RESULT_SUCCESS; 125 import static android.os.Process.INVALID_UID; 126 import static android.system.OsConstants.IPPROTO_TCP; 127 128 import static com.android.server.ConnectivityService.MAX_NETWORK_REQUESTS_PER_SYSTEM_UID; 129 import static com.android.server.ConnectivityService.PREFERENCE_PRIORITY_MOBILE_DATA_PREFERERRED; 130 import static com.android.server.ConnectivityService.PREFERENCE_PRIORITY_OEM; 131 import static com.android.server.ConnectivityService.PREFERENCE_PRIORITY_PROFILE; 132 import static com.android.server.ConnectivityService.PREFERENCE_PRIORITY_VPN; 133 import static com.android.server.ConnectivityServiceTestUtils.transportToLegacyType; 134 import static com.android.testutils.ConcurrentUtils.await; 135 import static com.android.testutils.ConcurrentUtils.durationOf; 136 import static com.android.testutils.ExceptionUtils.ignoreExceptions; 137 import static com.android.testutils.HandlerUtils.waitForIdleSerialExecutor; 138 import static com.android.testutils.MiscAsserts.assertContainsAll; 139 import static com.android.testutils.MiscAsserts.assertContainsExactly; 140 import static com.android.testutils.MiscAsserts.assertEmpty; 141 import static com.android.testutils.MiscAsserts.assertLength; 142 import static com.android.testutils.MiscAsserts.assertRunsInAtMost; 143 import static com.android.testutils.MiscAsserts.assertSameElements; 144 import static com.android.testutils.MiscAsserts.assertThrows; 145 import static com.android.testutils.TestPermissionUtil.runAsShell; 146 147 import static org.junit.Assert.assertEquals; 148 import static org.junit.Assert.assertFalse; 149 import static org.junit.Assert.assertNotEquals; 150 import static org.junit.Assert.assertNotNull; 151 import static org.junit.Assert.assertNull; 152 import static org.junit.Assert.assertTrue; 153 import static org.junit.Assert.fail; 154 import static org.mockito.AdditionalMatchers.aryEq; 155 import static org.mockito.ArgumentMatchers.anyBoolean; 156 import static org.mockito.ArgumentMatchers.anyLong; 157 import static org.mockito.ArgumentMatchers.anyString; 158 import static org.mockito.ArgumentMatchers.argThat; 159 import static org.mockito.ArgumentMatchers.eq; 160 import static org.mockito.ArgumentMatchers.isNull; 161 import static org.mockito.ArgumentMatchers.startsWith; 162 import static org.mockito.Matchers.anyInt; 163 import static org.mockito.Mockito.any; 164 import static org.mockito.Mockito.atLeastOnce; 165 import static org.mockito.Mockito.doAnswer; 166 import static org.mockito.Mockito.doNothing; 167 import static org.mockito.Mockito.doReturn; 168 import static org.mockito.Mockito.doThrow; 169 import static org.mockito.Mockito.inOrder; 170 import static org.mockito.Mockito.mock; 171 import static org.mockito.Mockito.never; 172 import static org.mockito.Mockito.reset; 173 import static org.mockito.Mockito.spy; 174 import static org.mockito.Mockito.timeout; 175 import static org.mockito.Mockito.times; 176 import static org.mockito.Mockito.verify; 177 import static org.mockito.Mockito.verifyNoMoreInteractions; 178 import static org.mockito.Mockito.when; 179 180 import android.Manifest; 181 import android.annotation.NonNull; 182 import android.annotation.Nullable; 183 import android.app.AlarmManager; 184 import android.app.AppOpsManager; 185 import android.app.NotificationManager; 186 import android.app.PendingIntent; 187 import android.app.usage.NetworkStatsManager; 188 import android.content.BroadcastReceiver; 189 import android.content.ComponentName; 190 import android.content.ContentProvider; 191 import android.content.ContentResolver; 192 import android.content.Context; 193 import android.content.Intent; 194 import android.content.IntentFilter; 195 import android.content.pm.ApplicationInfo; 196 import android.content.pm.PackageInfo; 197 import android.content.pm.PackageManager; 198 import android.content.pm.ResolveInfo; 199 import android.content.pm.ServiceInfo; 200 import android.content.pm.UserInfo; 201 import android.content.res.Resources; 202 import android.location.LocationManager; 203 import android.net.CaptivePortalData; 204 import android.net.ConnectionInfo; 205 import android.net.ConnectivityManager; 206 import android.net.ConnectivityManager.NetworkCallback; 207 import android.net.ConnectivityManager.PacketKeepalive; 208 import android.net.ConnectivityManager.PacketKeepaliveCallback; 209 import android.net.ConnectivityManager.TooManyRequestsException; 210 import android.net.ConnectivityResources; 211 import android.net.ConnectivitySettingsManager; 212 import android.net.ConnectivityThread; 213 import android.net.DataStallReportParcelable; 214 import android.net.EthernetManager; 215 import android.net.IConnectivityDiagnosticsCallback; 216 import android.net.IDnsResolver; 217 import android.net.INetd; 218 import android.net.INetworkMonitor; 219 import android.net.INetworkMonitorCallbacks; 220 import android.net.IOnCompleteListener; 221 import android.net.IQosCallback; 222 import android.net.InetAddresses; 223 import android.net.InterfaceConfigurationParcel; 224 import android.net.IpPrefix; 225 import android.net.IpSecManager; 226 import android.net.IpSecManager.UdpEncapsulationSocket; 227 import android.net.LinkAddress; 228 import android.net.LinkProperties; 229 import android.net.MatchAllNetworkSpecifier; 230 import android.net.NativeNetworkConfig; 231 import android.net.NativeNetworkType; 232 import android.net.Network; 233 import android.net.NetworkAgent; 234 import android.net.NetworkAgentConfig; 235 import android.net.NetworkCapabilities; 236 import android.net.NetworkFactory; 237 import android.net.NetworkInfo; 238 import android.net.NetworkInfo.DetailedState; 239 import android.net.NetworkPolicyManager; 240 import android.net.NetworkPolicyManager.NetworkPolicyCallback; 241 import android.net.NetworkRequest; 242 import android.net.NetworkScore; 243 import android.net.NetworkSpecifier; 244 import android.net.NetworkStack; 245 import android.net.NetworkStateSnapshot; 246 import android.net.NetworkTestResultParcelable; 247 import android.net.OemNetworkPreferences; 248 import android.net.ProxyInfo; 249 import android.net.QosCallbackException; 250 import android.net.QosFilter; 251 import android.net.QosSession; 252 import android.net.ResolverParamsParcel; 253 import android.net.RouteInfo; 254 import android.net.RouteInfoParcel; 255 import android.net.SocketKeepalive; 256 import android.net.TransportInfo; 257 import android.net.UidRange; 258 import android.net.UidRangeParcel; 259 import android.net.UnderlyingNetworkInfo; 260 import android.net.Uri; 261 import android.net.VpnManager; 262 import android.net.VpnTransportInfo; 263 import android.net.metrics.IpConnectivityLog; 264 import android.net.netd.aidl.NativeUidRangeConfig; 265 import android.net.networkstack.NetworkStackClientBase; 266 import android.net.resolv.aidl.Nat64PrefixEventParcel; 267 import android.net.resolv.aidl.PrivateDnsValidationEventParcel; 268 import android.net.shared.NetworkMonitorUtils; 269 import android.net.shared.PrivateDnsConfig; 270 import android.net.util.MultinetworkPolicyTracker; 271 import android.os.BadParcelableException; 272 import android.os.BatteryStatsManager; 273 import android.os.Binder; 274 import android.os.Build; 275 import android.os.Bundle; 276 import android.os.ConditionVariable; 277 import android.os.Handler; 278 import android.os.HandlerThread; 279 import android.os.IBinder; 280 import android.os.INetworkManagementService; 281 import android.os.Looper; 282 import android.os.Messenger; 283 import android.os.Parcel; 284 import android.os.ParcelFileDescriptor; 285 import android.os.Parcelable; 286 import android.os.Process; 287 import android.os.RemoteException; 288 import android.os.ServiceSpecificException; 289 import android.os.SystemClock; 290 import android.os.SystemConfigManager; 291 import android.os.UserHandle; 292 import android.os.UserManager; 293 import android.provider.Settings; 294 import android.security.Credentials; 295 import android.system.Os; 296 import android.telephony.TelephonyManager; 297 import android.telephony.data.EpsBearerQosSessionAttributes; 298 import android.telephony.data.NrQosSessionAttributes; 299 import android.test.mock.MockContentResolver; 300 import android.text.TextUtils; 301 import android.util.ArraySet; 302 import android.util.Log; 303 import android.util.Pair; 304 import android.util.Range; 305 import android.util.SparseArray; 306 307 import androidx.test.InstrumentationRegistry; 308 import androidx.test.filters.SmallTest; 309 310 import com.android.connectivity.resources.R; 311 import com.android.internal.app.IBatteryStats; 312 import com.android.internal.net.VpnConfig; 313 import com.android.internal.net.VpnProfile; 314 import com.android.internal.util.ArrayUtils; 315 import com.android.internal.util.WakeupMessage; 316 import com.android.internal.util.test.BroadcastInterceptingContext; 317 import com.android.internal.util.test.FakeSettingsProvider; 318 import com.android.net.module.util.ArrayTrackRecord; 319 import com.android.net.module.util.CollectionUtils; 320 import com.android.net.module.util.LocationPermissionChecker; 321 import com.android.server.ConnectivityService.ConnectivityDiagnosticsCallbackInfo; 322 import com.android.server.ConnectivityService.NetworkRequestInfo; 323 import com.android.server.connectivity.MockableSystemProperties; 324 import com.android.server.connectivity.Nat464Xlat; 325 import com.android.server.connectivity.NetworkAgentInfo; 326 import com.android.server.connectivity.NetworkNotificationManager.NotificationType; 327 import com.android.server.connectivity.ProxyTracker; 328 import com.android.server.connectivity.QosCallbackTracker; 329 import com.android.server.connectivity.Vpn; 330 import com.android.server.connectivity.VpnProfileStore; 331 import com.android.server.net.NetworkPinner; 332 import com.android.testutils.DevSdkIgnoreRule; 333 import com.android.testutils.DevSdkIgnoreRunner; 334 import com.android.testutils.ExceptionUtils; 335 import com.android.testutils.HandlerUtils; 336 import com.android.testutils.RecorderCallback.CallbackEntry; 337 import com.android.testutils.TestableNetworkCallback; 338 339 import org.junit.After; 340 import org.junit.Before; 341 import org.junit.Ignore; 342 import org.junit.Test; 343 import org.junit.runner.RunWith; 344 import org.mockito.AdditionalAnswers; 345 import org.mockito.ArgumentCaptor; 346 import org.mockito.InOrder; 347 import org.mockito.Mock; 348 import org.mockito.MockitoAnnotations; 349 import org.mockito.Spy; 350 import org.mockito.stubbing.Answer; 351 352 import java.io.FileDescriptor; 353 import java.io.IOException; 354 import java.io.PrintWriter; 355 import java.io.StringWriter; 356 import java.net.DatagramSocket; 357 import java.net.Inet4Address; 358 import java.net.Inet6Address; 359 import java.net.InetAddress; 360 import java.net.InetSocketAddress; 361 import java.net.Socket; 362 import java.nio.charset.StandardCharsets; 363 import java.util.ArrayList; 364 import java.util.Arrays; 365 import java.util.Collection; 366 import java.util.Collections; 367 import java.util.Comparator; 368 import java.util.HashMap; 369 import java.util.HashSet; 370 import java.util.List; 371 import java.util.Objects; 372 import java.util.Set; 373 import java.util.concurrent.CompletableFuture; 374 import java.util.concurrent.CountDownLatch; 375 import java.util.concurrent.Executor; 376 import java.util.concurrent.ExecutorService; 377 import java.util.concurrent.Executors; 378 import java.util.concurrent.LinkedBlockingQueue; 379 import java.util.concurrent.TimeUnit; 380 import java.util.concurrent.TimeoutException; 381 import java.util.concurrent.atomic.AtomicBoolean; 382 import java.util.concurrent.atomic.AtomicReference; 383 import java.util.function.Predicate; 384 import java.util.function.Supplier; 385 import java.util.regex.Matcher; 386 import java.util.regex.Pattern; 387 import java.util.stream.Collectors; 388 389 import kotlin.reflect.KClass; 390 391 /** 392 * Tests for {@link ConnectivityService}. 393 * 394 * Build, install and run with: 395 * runtest frameworks-net -c com.android.server.ConnectivityServiceTest 396 */ 397 @RunWith(DevSdkIgnoreRunner.class) 398 @SmallTest 399 @DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.R) 400 public class ConnectivityServiceTest { 401 private static final String TAG = "ConnectivityServiceTest"; 402 403 private static final int TIMEOUT_MS = 2_000; 404 // Broadcasts can take a long time to be delivered. The test will not wait for that long unless 405 // there is a failure, so use a long timeout. 406 private static final int BROADCAST_TIMEOUT_MS = 30_000; 407 private static final int TEST_LINGER_DELAY_MS = 400; 408 private static final int TEST_NASCENT_DELAY_MS = 300; 409 // Chosen to be less than the linger and nascent timeout. This ensures that we can distinguish 410 // between a LOST callback that arrives immediately and a LOST callback that arrives after 411 // the linger/nascent timeout. For this, our assertions should run fast enough to leave 412 // less than (mService.mLingerDelayMs - TEST_CALLBACK_TIMEOUT_MS) between the time callbacks are 413 // supposedly fired, and the time we call expectCallback. 414 private static final int TEST_CALLBACK_TIMEOUT_MS = 250; 415 // Chosen to be less than TEST_CALLBACK_TIMEOUT_MS. This ensures that requests have time to 416 // complete before callbacks are verified. 417 private static final int TEST_REQUEST_TIMEOUT_MS = 150; 418 419 private static final int UNREASONABLY_LONG_ALARM_WAIT_MS = 1000; 420 421 private static final long TIMESTAMP = 1234L; 422 423 private static final int NET_ID = 110; 424 private static final int OEM_PREF_ANY_NET_ID = -1; 425 // Set a non-zero value to verify the flow to set tcp init rwnd value. 426 private static final int TEST_TCP_INIT_RWND = 60; 427 428 // Used for testing the per-work-profile default network. 429 private static final int TEST_APP_ID = 103; 430 private static final int TEST_WORK_PROFILE_USER_ID = 2; 431 private static final int TEST_WORK_PROFILE_APP_UID = 432 UserHandle.getUid(TEST_WORK_PROFILE_USER_ID, TEST_APP_ID); 433 private static final String CLAT_PREFIX = "v4-"; 434 private static final String MOBILE_IFNAME = "test_rmnet_data0"; 435 private static final String CLAT_MOBILE_IFNAME = CLAT_PREFIX + MOBILE_IFNAME; 436 private static final String WIFI_IFNAME = "test_wlan0"; 437 private static final String WIFI_WOL_IFNAME = "test_wlan_wol"; 438 private static final String VPN_IFNAME = "tun10042"; 439 private static final String TEST_PACKAGE_NAME = "com.android.test.package"; 440 private static final int TEST_PACKAGE_UID = 123; 441 private static final int TEST_PACKAGE_UID2 = 321; 442 private static final int TEST_PACKAGE_UID3 = 456; 443 private static final String ALWAYS_ON_PACKAGE = "com.android.test.alwaysonvpn"; 444 445 private static final String INTERFACE_NAME = "interface"; 446 447 private static final String TEST_VENUE_URL_NA_PASSPOINT = "https://android.com/"; 448 private static final String TEST_VENUE_URL_NA_OTHER = "https://example.com/"; 449 private static final String TEST_TERMS_AND_CONDITIONS_URL_NA_PASSPOINT = 450 "https://android.com/terms/"; 451 private static final String TEST_TERMS_AND_CONDITIONS_URL_NA_OTHER = 452 "https://example.com/terms/"; 453 private static final String TEST_VENUE_URL_CAPPORT = "https://android.com/capport/"; 454 private static final String TEST_USER_PORTAL_API_URL_CAPPORT = 455 "https://android.com/user/api/capport/"; 456 private static final String TEST_FRIENDLY_NAME = "Network friendly name"; 457 private static final String TEST_REDIRECT_URL = "http://example.com/firstPath"; 458 459 private MockContext mServiceContext; 460 private HandlerThread mCsHandlerThread; 461 private HandlerThread mVMSHandlerThread; 462 private ConnectivityService.Dependencies mDeps; 463 private ConnectivityService mService; 464 private WrappedConnectivityManager mCm; 465 private TestNetworkAgentWrapper mWiFiNetworkAgent; 466 private TestNetworkAgentWrapper mCellNetworkAgent; 467 private TestNetworkAgentWrapper mEthernetNetworkAgent; 468 private MockVpn mMockVpn; 469 private Context mContext; 470 private NetworkPolicyCallback mPolicyCallback; 471 private WrappedMultinetworkPolicyTracker mPolicyTracker; 472 private HandlerThread mAlarmManagerThread; 473 private TestNetIdManager mNetIdManager; 474 private QosCallbackMockHelper mQosCallbackMockHelper; 475 private QosCallbackTracker mQosCallbackTracker; 476 private VpnManagerService mVpnManagerService; 477 private TestNetworkCallback mDefaultNetworkCallback; 478 private TestNetworkCallback mSystemDefaultNetworkCallback; 479 private TestNetworkCallback mProfileDefaultNetworkCallback; 480 private TestNetworkCallback mTestPackageDefaultNetworkCallback; 481 482 // State variables required to emulate NetworkPolicyManagerService behaviour. 483 private int mBlockedReasons = BLOCKED_REASON_NONE; 484 485 @Mock DeviceIdleInternal mDeviceIdleInternal; 486 @Mock INetworkManagementService mNetworkManagementService; 487 @Mock NetworkStatsManager mStatsManager; 488 @Mock IDnsResolver mMockDnsResolver; 489 @Mock INetd mMockNetd; 490 @Mock NetworkStackClientBase mNetworkStack; 491 @Mock PackageManager mPackageManager; 492 @Mock UserManager mUserManager; 493 @Mock NotificationManager mNotificationManager; 494 @Mock AlarmManager mAlarmManager; 495 @Mock IConnectivityDiagnosticsCallback mConnectivityDiagnosticsCallback; 496 @Mock IBinder mIBinder; 497 @Mock LocationManager mLocationManager; 498 @Mock AppOpsManager mAppOpsManager; 499 @Mock TelephonyManager mTelephonyManager; 500 @Mock MockableSystemProperties mSystemProperties; 501 @Mock EthernetManager mEthernetManager; 502 @Mock NetworkPolicyManager mNetworkPolicyManager; 503 @Mock VpnProfileStore mVpnProfileStore; 504 @Mock SystemConfigManager mSystemConfigManager; 505 @Mock Resources mResources; 506 @Mock ProxyTracker mProxyTracker; 507 508 // BatteryStatsManager is final and cannot be mocked with regular mockito, so just mock the 509 // underlying binder calls. 510 final BatteryStatsManager mBatteryStatsManager = 511 new BatteryStatsManager(mock(IBatteryStats.class)); 512 513 private ArgumentCaptor<ResolverParamsParcel> mResolverParamsParcelCaptor = 514 ArgumentCaptor.forClass(ResolverParamsParcel.class); 515 516 // This class exists to test bindProcessToNetwork and getBoundNetworkForProcess. These methods 517 // do not go through ConnectivityService but talk to netd directly, so they don't automatically 518 // reflect the state of our test ConnectivityService. 519 private class WrappedConnectivityManager extends ConnectivityManager { 520 private Network mFakeBoundNetwork; 521 522 public synchronized boolean bindProcessToNetwork(Network network) { 523 mFakeBoundNetwork = network; 524 return true; 525 } 526 527 public synchronized Network getBoundNetworkForProcess() { 528 return mFakeBoundNetwork; 529 } 530 531 public WrappedConnectivityManager(Context context, ConnectivityService service) { 532 super(context, service); 533 } 534 } 535 536 private class MockContext extends BroadcastInterceptingContext { 537 private final MockContentResolver mContentResolver; 538 539 @Spy private Resources mInternalResources; 540 private final LinkedBlockingQueue<Intent> mStartedActivities = new LinkedBlockingQueue<>(); 541 542 // Map of permission name -> PermissionManager.Permission_{GRANTED|DENIED} constant 543 // For permissions granted across the board, the key is only the permission name. 544 // For permissions only granted to a combination of uid/pid, the key 545 // is "<permission name>,<pid>,<uid>". PID+UID permissons have priority over generic ones. 546 private final HashMap<String, Integer> mMockedPermissions = new HashMap<>(); 547 548 MockContext(Context base, ContentProvider settingsProvider) { 549 super(base); 550 551 mInternalResources = spy(base.getResources()); 552 when(mInternalResources.getStringArray(com.android.internal.R.array.networkAttributes)) 553 .thenReturn(new String[] { 554 "wifi,1,1,1,-1,true", 555 "mobile,0,0,0,-1,true", 556 "mobile_mms,2,0,2,60000,true", 557 "mobile_supl,3,0,2,60000,true", 558 }); 559 560 mContentResolver = new MockContentResolver(); 561 mContentResolver.addProvider(Settings.AUTHORITY, settingsProvider); 562 } 563 564 @Override 565 public void startActivityAsUser(Intent intent, UserHandle handle) { 566 mStartedActivities.offer(intent); 567 } 568 569 public Intent expectStartActivityIntent(int timeoutMs) { 570 Intent intent = null; 571 try { 572 intent = mStartedActivities.poll(timeoutMs, TimeUnit.MILLISECONDS); 573 } catch (InterruptedException e) {} 574 assertNotNull("Did not receive sign-in intent after " + timeoutMs + "ms", intent); 575 return intent; 576 } 577 578 public void expectNoStartActivityIntent(int timeoutMs) { 579 try { 580 assertNull("Received unexpected Intent to start activity", 581 mStartedActivities.poll(timeoutMs, TimeUnit.MILLISECONDS)); 582 } catch (InterruptedException e) {} 583 } 584 585 @Override 586 public ComponentName startService(Intent service) { 587 final String action = service.getAction(); 588 if (!VpnConfig.SERVICE_INTERFACE.equals(action)) { 589 fail("Attempt to start unknown service, action=" + action); 590 } 591 return new ComponentName(service.getPackage(), "com.android.test.Service"); 592 } 593 594 @Override 595 public Object getSystemService(String name) { 596 if (Context.CONNECTIVITY_SERVICE.equals(name)) return mCm; 597 if (Context.NOTIFICATION_SERVICE.equals(name)) return mNotificationManager; 598 if (Context.USER_SERVICE.equals(name)) return mUserManager; 599 if (Context.ALARM_SERVICE.equals(name)) return mAlarmManager; 600 if (Context.LOCATION_SERVICE.equals(name)) return mLocationManager; 601 if (Context.APP_OPS_SERVICE.equals(name)) return mAppOpsManager; 602 if (Context.TELEPHONY_SERVICE.equals(name)) return mTelephonyManager; 603 if (Context.ETHERNET_SERVICE.equals(name)) return mEthernetManager; 604 if (Context.NETWORK_POLICY_SERVICE.equals(name)) return mNetworkPolicyManager; 605 if (Context.SYSTEM_CONFIG_SERVICE.equals(name)) return mSystemConfigManager; 606 if (Context.NETWORK_STATS_SERVICE.equals(name)) return mStatsManager; 607 if (Context.BATTERY_STATS_SERVICE.equals(name)) return mBatteryStatsManager; 608 return super.getSystemService(name); 609 } 610 611 final HashMap<UserHandle, UserManager> mUserManagers = new HashMap<>(); 612 @Override 613 public Context createContextAsUser(UserHandle user, int flags) { 614 final Context asUser = mock(Context.class, AdditionalAnswers.delegatesTo(this)); 615 doReturn(user).when(asUser).getUser(); 616 doAnswer((inv) -> { 617 final UserManager um = mUserManagers.computeIfAbsent(user, 618 u -> mock(UserManager.class, AdditionalAnswers.delegatesTo(mUserManager))); 619 return um; 620 }).when(asUser).getSystemService(Context.USER_SERVICE); 621 return asUser; 622 } 623 624 public void setWorkProfile(@NonNull final UserHandle userHandle, boolean value) { 625 // This relies on all contexts for a given user returning the same UM mock 626 final UserManager umMock = createContextAsUser(userHandle, 0 /* flags */) 627 .getSystemService(UserManager.class); 628 doReturn(value).when(umMock).isManagedProfile(); 629 doReturn(value).when(mUserManager).isManagedProfile(eq(userHandle.getIdentifier())); 630 } 631 632 @Override 633 public ContentResolver getContentResolver() { 634 return mContentResolver; 635 } 636 637 @Override 638 public Resources getResources() { 639 return mInternalResources; 640 } 641 642 @Override 643 public PackageManager getPackageManager() { 644 return mPackageManager; 645 } 646 647 private int checkMockedPermission(String permission, int pid, int uid, 648 Supplier<Integer> ifAbsent) { 649 final Integer granted = mMockedPermissions.get(permission + "," + pid + "," + uid); 650 if (null != granted) { 651 return granted; 652 } 653 final Integer allGranted = mMockedPermissions.get(permission); 654 if (null != allGranted) { 655 return allGranted; 656 } 657 return ifAbsent.get(); 658 } 659 660 @Override 661 public int checkPermission(String permission, int pid, int uid) { 662 return checkMockedPermission(permission, pid, uid, 663 () -> super.checkPermission(permission, pid, uid)); 664 } 665 666 @Override 667 public int checkCallingOrSelfPermission(String permission) { 668 return checkMockedPermission(permission, Process.myPid(), Process.myUid(), 669 () -> super.checkCallingOrSelfPermission(permission)); 670 } 671 672 @Override 673 public void enforceCallingOrSelfPermission(String permission, String message) { 674 final Integer granted = checkMockedPermission(permission, 675 Process.myPid(), Process.myUid(), 676 () -> { 677 super.enforceCallingOrSelfPermission(permission, message); 678 // enforce will crash if the permission is not granted 679 return PERMISSION_GRANTED; 680 }); 681 682 if (!granted.equals(PERMISSION_GRANTED)) { 683 throw new SecurityException("[Test] permission denied: " + permission); 684 } 685 } 686 687 /** 688 * Mock checks for the specified permission, and have them behave as per {@code granted}. 689 * 690 * This will apply across the board no matter what the checked UID and PID are. 691 * 692 * <p>Passing null reverts to default behavior, which does a real permission check on the 693 * test package. 694 * @param granted One of {@link PackageManager#PERMISSION_GRANTED} or 695 * {@link PackageManager#PERMISSION_DENIED}. 696 */ 697 public void setPermission(String permission, Integer granted) { 698 mMockedPermissions.put(permission, granted); 699 } 700 701 /** 702 * Mock checks for the specified permission, and have them behave as per {@code granted}. 703 * 704 * This will only apply to the passed UID and PID. 705 * 706 * <p>Passing null reverts to default behavior, which does a real permission check on the 707 * test package. 708 * @param granted One of {@link PackageManager#PERMISSION_GRANTED} or 709 * {@link PackageManager#PERMISSION_DENIED}. 710 */ 711 public void setPermission(String permission, int pid, int uid, Integer granted) { 712 final String key = permission + "," + pid + "," + uid; 713 mMockedPermissions.put(key, granted); 714 } 715 716 @Override 717 public Intent registerReceiverForAllUsers(@Nullable BroadcastReceiver receiver, 718 @NonNull IntentFilter filter, @Nullable String broadcastPermission, 719 @Nullable Handler scheduler) { 720 // TODO: ensure MultinetworkPolicyTracker's BroadcastReceiver is tested; just returning 721 // null should not pass the test 722 return null; 723 } 724 } 725 726 private void waitForIdle() { 727 HandlerUtils.waitForIdle(mCsHandlerThread, TIMEOUT_MS); 728 waitForIdle(mCellNetworkAgent, TIMEOUT_MS); 729 waitForIdle(mWiFiNetworkAgent, TIMEOUT_MS); 730 waitForIdle(mEthernetNetworkAgent, TIMEOUT_MS); 731 HandlerUtils.waitForIdle(mCsHandlerThread, TIMEOUT_MS); 732 HandlerUtils.waitForIdle(ConnectivityThread.get(), TIMEOUT_MS); 733 } 734 735 private void waitForIdle(TestNetworkAgentWrapper agent, long timeoutMs) { 736 if (agent == null) { 737 return; 738 } 739 agent.waitForIdle(timeoutMs); 740 } 741 742 @Test 743 public void testWaitForIdle() throws Exception { 744 final int attempts = 50; // Causes the test to take about 200ms on bullhead-eng. 745 746 // Tests that waitForIdle returns immediately if the service is already idle. 747 for (int i = 0; i < attempts; i++) { 748 waitForIdle(); 749 } 750 751 // Bring up a network that we can use to send messages to ConnectivityService. 752 ExpectedBroadcast b = expectConnectivityAction(TYPE_WIFI, DetailedState.CONNECTED); 753 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 754 mWiFiNetworkAgent.connect(false); 755 b.expectBroadcast(); 756 Network n = mWiFiNetworkAgent.getNetwork(); 757 assertNotNull(n); 758 759 // Tests that calling waitForIdle waits for messages to be processed. 760 for (int i = 0; i < attempts; i++) { 761 mWiFiNetworkAgent.setSignalStrength(i); 762 waitForIdle(); 763 assertEquals(i, mCm.getNetworkCapabilities(n).getSignalStrength()); 764 } 765 } 766 767 // This test has an inherent race condition in it, and cannot be enabled for continuous testing 768 // or presubmit tests. It is kept for manual runs and documentation purposes. 769 @Ignore 770 public void verifyThatNotWaitingForIdleCausesRaceConditions() throws Exception { 771 // Bring up a network that we can use to send messages to ConnectivityService. 772 ExpectedBroadcast b = expectConnectivityAction(TYPE_WIFI, DetailedState.CONNECTED); 773 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 774 mWiFiNetworkAgent.connect(false); 775 b.expectBroadcast(); 776 Network n = mWiFiNetworkAgent.getNetwork(); 777 assertNotNull(n); 778 779 // Ensure that not calling waitForIdle causes a race condition. 780 final int attempts = 50; // Causes the test to take about 200ms on bullhead-eng. 781 for (int i = 0; i < attempts; i++) { 782 mWiFiNetworkAgent.setSignalStrength(i); 783 if (i != mCm.getNetworkCapabilities(n).getSignalStrength()) { 784 // We hit a race condition, as expected. Pass the test. 785 return; 786 } 787 } 788 789 // No race? There is a bug in this test. 790 fail("expected race condition at least once in " + attempts + " attempts"); 791 } 792 793 private class TestNetworkAgentWrapper extends NetworkAgentWrapper { 794 private static final int VALIDATION_RESULT_INVALID = 0; 795 796 private static final long DATA_STALL_TIMESTAMP = 10L; 797 private static final int DATA_STALL_DETECTION_METHOD = 1; 798 799 private INetworkMonitor mNetworkMonitor; 800 private INetworkMonitorCallbacks mNmCallbacks; 801 private int mNmValidationResult = VALIDATION_RESULT_INVALID; 802 private int mProbesCompleted; 803 private int mProbesSucceeded; 804 private String mNmValidationRedirectUrl = null; 805 private boolean mNmProvNotificationRequested = false; 806 private Runnable mCreatedCallback; 807 private Runnable mUnwantedCallback; 808 private Runnable mDisconnectedCallback; 809 810 private final ConditionVariable mNetworkStatusReceived = new ConditionVariable(); 811 // Contains the redirectUrl from networkStatus(). Before reading, wait for 812 // mNetworkStatusReceived. 813 private String mRedirectUrl; 814 815 TestNetworkAgentWrapper(int transport) throws Exception { 816 this(transport, new LinkProperties(), null); 817 } 818 819 TestNetworkAgentWrapper(int transport, LinkProperties linkProperties) 820 throws Exception { 821 this(transport, linkProperties, null); 822 } 823 824 private TestNetworkAgentWrapper(int transport, LinkProperties linkProperties, 825 NetworkCapabilities ncTemplate) throws Exception { 826 super(transport, linkProperties, ncTemplate, mServiceContext); 827 828 // Waits for the NetworkAgent to be registered, which includes the creation of the 829 // NetworkMonitor. 830 waitForIdle(TIMEOUT_MS); 831 HandlerUtils.waitForIdle(mCsHandlerThread, TIMEOUT_MS); 832 HandlerUtils.waitForIdle(ConnectivityThread.get(), TIMEOUT_MS); 833 } 834 835 @Override 836 protected InstrumentedNetworkAgent makeNetworkAgent(LinkProperties linkProperties, 837 NetworkAgentConfig nac) throws Exception { 838 mNetworkMonitor = mock(INetworkMonitor.class); 839 840 final Answer validateAnswer = inv -> { 841 new Thread(ignoreExceptions(this::onValidationRequested)).start(); 842 return null; 843 }; 844 845 doAnswer(validateAnswer).when(mNetworkMonitor).notifyNetworkConnected(any(), any()); 846 doAnswer(validateAnswer).when(mNetworkMonitor).forceReevaluation(anyInt()); 847 848 final ArgumentCaptor<Network> nmNetworkCaptor = ArgumentCaptor.forClass(Network.class); 849 final ArgumentCaptor<INetworkMonitorCallbacks> nmCbCaptor = 850 ArgumentCaptor.forClass(INetworkMonitorCallbacks.class); 851 doNothing().when(mNetworkStack).makeNetworkMonitor( 852 nmNetworkCaptor.capture(), 853 any() /* name */, 854 nmCbCaptor.capture()); 855 856 final InstrumentedNetworkAgent na = 857 new InstrumentedNetworkAgent(this, linkProperties, nac) { 858 @Override 859 public void networkStatus(int status, String redirectUrl) { 860 mRedirectUrl = redirectUrl; 861 mNetworkStatusReceived.open(); 862 } 863 864 @Override 865 public void onNetworkCreated() { 866 super.onNetworkCreated(); 867 if (mCreatedCallback != null) mCreatedCallback.run(); 868 } 869 870 @Override 871 public void onNetworkUnwanted() { 872 super.onNetworkUnwanted(); 873 if (mUnwantedCallback != null) mUnwantedCallback.run(); 874 } 875 876 @Override 877 public void onNetworkDestroyed() { 878 super.onNetworkDestroyed(); 879 if (mDisconnectedCallback != null) mDisconnectedCallback.run(); 880 } 881 }; 882 883 assertEquals(na.getNetwork().netId, nmNetworkCaptor.getValue().netId); 884 mNmCallbacks = nmCbCaptor.getValue(); 885 886 mNmCallbacks.onNetworkMonitorCreated(mNetworkMonitor); 887 888 return na; 889 } 890 891 private void onValidationRequested() throws Exception { 892 if (mNmProvNotificationRequested 893 && ((mNmValidationResult & NETWORK_VALIDATION_RESULT_VALID) != 0)) { 894 mNmCallbacks.hideProvisioningNotification(); 895 mNmProvNotificationRequested = false; 896 } 897 898 mNmCallbacks.notifyProbeStatusChanged(mProbesCompleted, mProbesSucceeded); 899 final NetworkTestResultParcelable p = new NetworkTestResultParcelable(); 900 p.result = mNmValidationResult; 901 p.probesAttempted = mProbesCompleted; 902 p.probesSucceeded = mProbesSucceeded; 903 p.redirectUrl = mNmValidationRedirectUrl; 904 p.timestampMillis = TIMESTAMP; 905 mNmCallbacks.notifyNetworkTestedWithExtras(p); 906 907 if (mNmValidationRedirectUrl != null) { 908 mNmCallbacks.showProvisioningNotification( 909 "test_provisioning_notif_action", TEST_PACKAGE_NAME); 910 mNmProvNotificationRequested = true; 911 } 912 } 913 914 /** 915 * Connect without adding any internet capability. 916 */ 917 public void connectWithoutInternet() { 918 super.connect(); 919 } 920 921 /** 922 * Transition this NetworkAgent to CONNECTED state with NET_CAPABILITY_INTERNET. 923 * @param validated Indicate if network should pretend to be validated. 924 */ 925 public void connect(boolean validated) { 926 connect(validated, true, false /* isStrictMode */); 927 } 928 929 /** 930 * Transition this NetworkAgent to CONNECTED state. 931 * @param validated Indicate if network should pretend to be validated. 932 * @param hasInternet Indicate if network should pretend to have NET_CAPABILITY_INTERNET. 933 */ 934 public void connect(boolean validated, boolean hasInternet, boolean isStrictMode) { 935 assertFalse(getNetworkCapabilities().hasCapability(NET_CAPABILITY_INTERNET)); 936 937 ConnectivityManager.NetworkCallback callback = null; 938 final ConditionVariable validatedCv = new ConditionVariable(); 939 if (validated) { 940 setNetworkValid(isStrictMode); 941 NetworkRequest request = new NetworkRequest.Builder() 942 .addTransportType(getNetworkCapabilities().getTransportTypes()[0]) 943 .clearCapabilities() 944 .build(); 945 callback = new ConnectivityManager.NetworkCallback() { 946 public void onCapabilitiesChanged(Network network, 947 NetworkCapabilities networkCapabilities) { 948 if (network.equals(getNetwork()) && 949 networkCapabilities.hasCapability(NET_CAPABILITY_VALIDATED)) { 950 validatedCv.open(); 951 } 952 } 953 }; 954 mCm.registerNetworkCallback(request, callback); 955 } 956 if (hasInternet) { 957 addCapability(NET_CAPABILITY_INTERNET); 958 } 959 960 connectWithoutInternet(); 961 962 if (validated) { 963 // Wait for network to validate. 964 waitFor(validatedCv); 965 setNetworkInvalid(isStrictMode); 966 } 967 968 if (callback != null) mCm.unregisterNetworkCallback(callback); 969 } 970 971 public void connectWithCaptivePortal(String redirectUrl, boolean isStrictMode) { 972 setNetworkPortal(redirectUrl, isStrictMode); 973 connect(false, true /* hasInternet */, isStrictMode); 974 } 975 976 public void connectWithPartialConnectivity() { 977 setNetworkPartial(); 978 connect(false); 979 } 980 981 public void connectWithPartialValidConnectivity(boolean isStrictMode) { 982 setNetworkPartialValid(isStrictMode); 983 connect(false, true /* hasInternet */, isStrictMode); 984 } 985 986 void setNetworkValid(boolean isStrictMode) { 987 mNmValidationResult = NETWORK_VALIDATION_RESULT_VALID; 988 mNmValidationRedirectUrl = null; 989 int probesSucceeded = NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS; 990 if (isStrictMode) { 991 probesSucceeded |= NETWORK_VALIDATION_PROBE_PRIVDNS; 992 } 993 // The probesCompleted equals to probesSucceeded for the case of valid network, so put 994 // the same value into two different parameter of the method. 995 setProbesStatus(probesSucceeded, probesSucceeded); 996 } 997 998 void setNetworkInvalid(boolean isStrictMode) { 999 mNmValidationResult = VALIDATION_RESULT_INVALID; 1000 mNmValidationRedirectUrl = null; 1001 int probesCompleted = NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS 1002 | NETWORK_VALIDATION_PROBE_HTTP; 1003 int probesSucceeded = 0; 1004 // If the isStrictMode is true, it means the network is invalid when NetworkMonitor 1005 // tried to validate the private DNS but failed. 1006 if (isStrictMode) { 1007 probesCompleted &= ~NETWORK_VALIDATION_PROBE_HTTP; 1008 probesSucceeded = probesCompleted; 1009 probesCompleted |= NETWORK_VALIDATION_PROBE_PRIVDNS; 1010 } 1011 setProbesStatus(probesCompleted, probesSucceeded); 1012 } 1013 1014 void setNetworkPortal(String redirectUrl, boolean isStrictMode) { 1015 setNetworkInvalid(isStrictMode); 1016 mNmValidationRedirectUrl = redirectUrl; 1017 // Suppose the portal is found when NetworkMonitor probes NETWORK_VALIDATION_PROBE_HTTP 1018 // in the beginning, so the NETWORK_VALIDATION_PROBE_HTTPS hasn't probed yet. 1019 int probesCompleted = NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTP; 1020 int probesSucceeded = VALIDATION_RESULT_INVALID; 1021 if (isStrictMode) { 1022 probesCompleted |= NETWORK_VALIDATION_PROBE_PRIVDNS; 1023 } 1024 setProbesStatus(probesCompleted, probesSucceeded); 1025 } 1026 1027 void setNetworkPartial() { 1028 mNmValidationResult = NETWORK_VALIDATION_RESULT_PARTIAL; 1029 mNmValidationRedirectUrl = null; 1030 int probesCompleted = NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS 1031 | NETWORK_VALIDATION_PROBE_FALLBACK; 1032 int probesSucceeded = NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_FALLBACK; 1033 setProbesStatus(probesCompleted, probesSucceeded); 1034 } 1035 1036 void setNetworkPartialValid(boolean isStrictMode) { 1037 setNetworkPartial(); 1038 mNmValidationResult |= NETWORK_VALIDATION_RESULT_VALID; 1039 int probesCompleted = NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS 1040 | NETWORK_VALIDATION_PROBE_HTTP; 1041 int probesSucceeded = NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTP; 1042 // Suppose the partial network cannot pass the private DNS validation as well, so only 1043 // add NETWORK_VALIDATION_PROBE_DNS in probesCompleted but not probesSucceeded. 1044 if (isStrictMode) { 1045 probesCompleted |= NETWORK_VALIDATION_PROBE_PRIVDNS; 1046 } 1047 setProbesStatus(probesCompleted, probesSucceeded); 1048 } 1049 1050 void setProbesStatus(int probesCompleted, int probesSucceeded) { 1051 mProbesCompleted = probesCompleted; 1052 mProbesSucceeded = probesSucceeded; 1053 } 1054 1055 void notifyCapportApiDataChanged(CaptivePortalData data) { 1056 try { 1057 mNmCallbacks.notifyCaptivePortalDataChanged(data); 1058 } catch (RemoteException e) { 1059 throw new AssertionError("This cannot happen", e); 1060 } 1061 } 1062 1063 public String waitForRedirectUrl() { 1064 assertTrue(mNetworkStatusReceived.block(TIMEOUT_MS)); 1065 return mRedirectUrl; 1066 } 1067 1068 public void expectDisconnected() { 1069 expectDisconnected(TIMEOUT_MS); 1070 } 1071 1072 public void expectPreventReconnectReceived() { 1073 expectPreventReconnectReceived(TIMEOUT_MS); 1074 } 1075 1076 void notifyDataStallSuspected() throws Exception { 1077 final DataStallReportParcelable p = new DataStallReportParcelable(); 1078 p.detectionMethod = DATA_STALL_DETECTION_METHOD; 1079 p.timestampMillis = DATA_STALL_TIMESTAMP; 1080 mNmCallbacks.notifyDataStallSuspected(p); 1081 } 1082 1083 public void setCreatedCallback(Runnable r) { 1084 mCreatedCallback = r; 1085 } 1086 1087 public void setUnwantedCallback(Runnable r) { 1088 mUnwantedCallback = r; 1089 } 1090 1091 public void setDisconnectedCallback(Runnable r) { 1092 mDisconnectedCallback = r; 1093 } 1094 } 1095 1096 /** 1097 * A NetworkFactory that allows to wait until any in-flight NetworkRequest add or remove 1098 * operations have been processed and test for them. 1099 */ 1100 private static class MockNetworkFactory extends NetworkFactory { 1101 private final AtomicBoolean mNetworkStarted = new AtomicBoolean(false); 1102 1103 static class RequestEntry { 1104 @NonNull 1105 public final NetworkRequest request; 1106 1107 RequestEntry(@NonNull final NetworkRequest request) { 1108 this.request = request; 1109 } 1110 1111 static final class Add extends RequestEntry { 1112 Add(@NonNull final NetworkRequest request) { 1113 super(request); 1114 } 1115 } 1116 1117 static final class Remove extends RequestEntry { 1118 Remove(@NonNull final NetworkRequest request) { 1119 super(request); 1120 } 1121 } 1122 1123 @Override 1124 public String toString() { 1125 return "RequestEntry [ " + getClass().getName() + " : " + request + " ]"; 1126 } 1127 } 1128 1129 // History of received requests adds and removes. 1130 private final ArrayTrackRecord<RequestEntry>.ReadHead mRequestHistory = 1131 new ArrayTrackRecord<RequestEntry>().newReadHead(); 1132 1133 private static <T> T failIfNull(@Nullable final T obj, @Nullable final String message) { 1134 if (null == obj) fail(null != message ? message : "Must not be null"); 1135 return obj; 1136 } 1137 1138 public RequestEntry.Add expectRequestAdd() { 1139 return failIfNull((RequestEntry.Add) mRequestHistory.poll(TIMEOUT_MS, 1140 it -> it instanceof RequestEntry.Add), "Expected request add"); 1141 } 1142 1143 public void expectRequestAdds(final int count) { 1144 for (int i = count; i > 0; --i) { 1145 expectRequestAdd(); 1146 } 1147 } 1148 1149 public RequestEntry.Remove expectRequestRemove() { 1150 return failIfNull((RequestEntry.Remove) mRequestHistory.poll(TIMEOUT_MS, 1151 it -> it instanceof RequestEntry.Remove), "Expected request remove"); 1152 } 1153 1154 public void expectRequestRemoves(final int count) { 1155 for (int i = count; i > 0; --i) { 1156 expectRequestRemove(); 1157 } 1158 } 1159 1160 // Used to collect the networks requests managed by this factory. This is a duplicate of 1161 // the internal information stored in the NetworkFactory (which is private). 1162 private SparseArray<NetworkRequest> mNetworkRequests = new SparseArray<>(); 1163 private final HandlerThread mHandlerSendingRequests; 1164 1165 public MockNetworkFactory(Looper looper, Context context, String logTag, 1166 NetworkCapabilities filter, HandlerThread threadSendingRequests) { 1167 super(looper, context, logTag, filter); 1168 mHandlerSendingRequests = threadSendingRequests; 1169 } 1170 1171 public int getMyRequestCount() { 1172 return getRequestCount(); 1173 } 1174 1175 protected void startNetwork() { 1176 mNetworkStarted.set(true); 1177 } 1178 1179 protected void stopNetwork() { 1180 mNetworkStarted.set(false); 1181 } 1182 1183 public boolean getMyStartRequested() { 1184 return mNetworkStarted.get(); 1185 } 1186 1187 1188 @Override 1189 protected void needNetworkFor(NetworkRequest request) { 1190 mNetworkRequests.put(request.requestId, request); 1191 super.needNetworkFor(request); 1192 mRequestHistory.add(new RequestEntry.Add(request)); 1193 } 1194 1195 @Override 1196 protected void releaseNetworkFor(NetworkRequest request) { 1197 mNetworkRequests.remove(request.requestId); 1198 super.releaseNetworkFor(request); 1199 mRequestHistory.add(new RequestEntry.Remove(request)); 1200 } 1201 1202 public void assertRequestCountEquals(final int count) { 1203 assertEquals(count, getMyRequestCount()); 1204 } 1205 1206 @Override 1207 public void terminate() { 1208 super.terminate(); 1209 // Make sure there are no remaining requests unaccounted for. 1210 HandlerUtils.waitForIdle(mHandlerSendingRequests, TIMEOUT_MS); 1211 assertNull(mRequestHistory.poll(0, r -> true)); 1212 } 1213 1214 // Trigger releasing the request as unfulfillable 1215 public void triggerUnfulfillable(NetworkRequest r) { 1216 super.releaseRequestAsUnfulfillableByAnyFactory(r); 1217 } 1218 1219 public void assertNoRequestChanged() { 1220 assertNull(mRequestHistory.poll(0, r -> true)); 1221 } 1222 } 1223 1224 private Set<UidRange> uidRangesForUids(int... uids) { 1225 final ArraySet<UidRange> ranges = new ArraySet<>(); 1226 for (final int uid : uids) { 1227 ranges.add(new UidRange(uid, uid)); 1228 } 1229 return ranges; 1230 } 1231 1232 private Set<UidRange> uidRangesForUids(Collection<Integer> uids) { 1233 return uidRangesForUids(CollectionUtils.toIntArray(uids)); 1234 } 1235 1236 private static Looper startHandlerThreadAndReturnLooper() { 1237 final HandlerThread handlerThread = new HandlerThread("MockVpnThread"); 1238 handlerThread.start(); 1239 return handlerThread.getLooper(); 1240 } 1241 1242 private class MockVpn extends Vpn implements TestableNetworkCallback.HasNetwork { 1243 // Careful ! This is different from mNetworkAgent, because MockNetworkAgent does 1244 // not inherit from NetworkAgent. 1245 private TestNetworkAgentWrapper mMockNetworkAgent; 1246 private boolean mAgentRegistered = false; 1247 1248 private int mVpnType = VpnManager.TYPE_VPN_SERVICE; 1249 private UnderlyingNetworkInfo mUnderlyingNetworkInfo; 1250 1251 // These ConditionVariables allow tests to wait for LegacyVpnRunner to be stopped/started. 1252 // TODO: this scheme is ad-hoc and error-prone because it does not fail if, for example, the 1253 // test expects two starts in a row, or even if the production code calls start twice in a 1254 // row. find a better solution. Simply putting a method to create a LegacyVpnRunner into 1255 // Vpn.Dependencies doesn't work because LegacyVpnRunner is not a static class and has 1256 // extensive access into the internals of Vpn. 1257 private ConditionVariable mStartLegacyVpnCv = new ConditionVariable(); 1258 private ConditionVariable mStopVpnRunnerCv = new ConditionVariable(); 1259 1260 public MockVpn(int userId) { 1261 super(startHandlerThreadAndReturnLooper(), mServiceContext, 1262 new Dependencies() { 1263 @Override 1264 public boolean isCallerSystem() { 1265 return true; 1266 } 1267 1268 @Override 1269 public DeviceIdleInternal getDeviceIdleInternal() { 1270 return mDeviceIdleInternal; 1271 } 1272 }, 1273 mNetworkManagementService, mMockNetd, userId, mVpnProfileStore, 1274 new SystemServices(mServiceContext) { 1275 @Override 1276 public String settingsSecureGetStringForUser(String key, int userId) { 1277 switch (key) { 1278 // Settings keys not marked as @Readable are not readable from 1279 // non-privileged apps, unless marked as testOnly=true 1280 // (atest refuses to install testOnly=true apps), even if mocked 1281 // in the content provider, because 1282 // Settings.Secure.NameValueCache#getStringForUser checks the key 1283 // before querying the mock settings provider. 1284 case Settings.Secure.ALWAYS_ON_VPN_APP: 1285 return null; 1286 default: 1287 return super.settingsSecureGetStringForUser(key, userId); 1288 } 1289 } 1290 }, new Ikev2SessionCreator()); 1291 } 1292 1293 public void setUids(Set<UidRange> uids) { 1294 mNetworkCapabilities.setUids(UidRange.toIntRanges(uids)); 1295 if (mAgentRegistered) { 1296 mMockNetworkAgent.setNetworkCapabilities(mNetworkCapabilities, true); 1297 } 1298 } 1299 1300 public void setVpnType(int vpnType) { 1301 mVpnType = vpnType; 1302 } 1303 1304 @Override 1305 public Network getNetwork() { 1306 return (mMockNetworkAgent == null) ? null : mMockNetworkAgent.getNetwork(); 1307 } 1308 1309 @Override 1310 public int getActiveVpnType() { 1311 return mVpnType; 1312 } 1313 1314 private LinkProperties makeLinkProperties() { 1315 final LinkProperties lp = new LinkProperties(); 1316 lp.setInterfaceName(VPN_IFNAME); 1317 return lp; 1318 } 1319 1320 private void registerAgent(boolean isAlwaysMetered, Set<UidRange> uids, LinkProperties lp) 1321 throws Exception { 1322 if (mAgentRegistered) throw new IllegalStateException("already registered"); 1323 updateState(NetworkInfo.DetailedState.CONNECTING, "registerAgent"); 1324 mConfig = new VpnConfig(); 1325 mConfig.session = "MySession12345"; 1326 setUids(uids); 1327 if (!isAlwaysMetered) mNetworkCapabilities.addCapability(NET_CAPABILITY_NOT_METERED); 1328 mInterface = VPN_IFNAME; 1329 mNetworkCapabilities.setTransportInfo(new VpnTransportInfo(getActiveVpnType(), 1330 mConfig.session)); 1331 mMockNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_VPN, lp, 1332 mNetworkCapabilities); 1333 mMockNetworkAgent.waitForIdle(TIMEOUT_MS); 1334 1335 verify(mMockNetd, times(1)).networkAddUidRangesParcel( 1336 new NativeUidRangeConfig(mMockVpn.getNetwork().getNetId(), 1337 toUidRangeStableParcels(uids), PREFERENCE_PRIORITY_VPN)); 1338 verify(mMockNetd, never()).networkRemoveUidRangesParcel(argThat(config -> 1339 mMockVpn.getNetwork().getNetId() == config.netId 1340 && PREFERENCE_PRIORITY_VPN == config.subPriority)); 1341 mAgentRegistered = true; 1342 verify(mMockNetd).networkCreate(nativeNetworkConfigVpn(getNetwork().netId, 1343 !mMockNetworkAgent.isBypassableVpn(), mVpnType)); 1344 updateState(NetworkInfo.DetailedState.CONNECTED, "registerAgent"); 1345 mNetworkCapabilities.set(mMockNetworkAgent.getNetworkCapabilities()); 1346 mNetworkAgent = mMockNetworkAgent.getNetworkAgent(); 1347 } 1348 1349 private void registerAgent(Set<UidRange> uids) throws Exception { 1350 registerAgent(false /* isAlwaysMetered */, uids, makeLinkProperties()); 1351 } 1352 1353 private void connect(boolean validated, boolean hasInternet, boolean isStrictMode) { 1354 mMockNetworkAgent.connect(validated, hasInternet, isStrictMode); 1355 } 1356 1357 private void connect(boolean validated) { 1358 mMockNetworkAgent.connect(validated); 1359 } 1360 1361 private TestNetworkAgentWrapper getAgent() { 1362 return mMockNetworkAgent; 1363 } 1364 1365 private void setOwnerAndAdminUid(int uid) throws Exception { 1366 mNetworkCapabilities.setOwnerUid(uid); 1367 mNetworkCapabilities.setAdministratorUids(new int[]{uid}); 1368 } 1369 1370 public void establish(LinkProperties lp, int uid, Set<UidRange> ranges, boolean validated, 1371 boolean hasInternet, boolean isStrictMode) throws Exception { 1372 setOwnerAndAdminUid(uid); 1373 registerAgent(false, ranges, lp); 1374 connect(validated, hasInternet, isStrictMode); 1375 waitForIdle(); 1376 } 1377 1378 public void establish(LinkProperties lp, int uid, Set<UidRange> ranges) throws Exception { 1379 establish(lp, uid, ranges, true, true, false); 1380 } 1381 1382 public void establishForMyUid(LinkProperties lp) throws Exception { 1383 final int uid = Process.myUid(); 1384 establish(lp, uid, uidRangesForUids(uid), true, true, false); 1385 } 1386 1387 public void establishForMyUid(boolean validated, boolean hasInternet, boolean isStrictMode) 1388 throws Exception { 1389 final int uid = Process.myUid(); 1390 establish(makeLinkProperties(), uid, uidRangesForUids(uid), validated, hasInternet, 1391 isStrictMode); 1392 } 1393 1394 public void establishForMyUid() throws Exception { 1395 establishForMyUid(makeLinkProperties()); 1396 } 1397 1398 public void sendLinkProperties(LinkProperties lp) { 1399 mMockNetworkAgent.sendLinkProperties(lp); 1400 } 1401 1402 public void disconnect() { 1403 if (mMockNetworkAgent != null) { 1404 mMockNetworkAgent.disconnect(); 1405 updateState(NetworkInfo.DetailedState.DISCONNECTED, "disconnect"); 1406 } 1407 mAgentRegistered = false; 1408 setUids(null); 1409 // Remove NET_CAPABILITY_INTERNET or MockNetworkAgent will refuse to connect later on. 1410 mNetworkCapabilities.removeCapability(NET_CAPABILITY_INTERNET); 1411 mInterface = null; 1412 } 1413 1414 @Override 1415 public void startLegacyVpnRunner() { 1416 mStartLegacyVpnCv.open(); 1417 } 1418 1419 public void expectStartLegacyVpnRunner() { 1420 assertTrue("startLegacyVpnRunner not called after " + TIMEOUT_MS + " ms", 1421 mStartLegacyVpnCv.block(TIMEOUT_MS)); 1422 1423 // startLegacyVpn calls stopVpnRunnerPrivileged, which will open mStopVpnRunnerCv, just 1424 // before calling startLegacyVpnRunner. Restore mStopVpnRunnerCv, so the test can expect 1425 // that the VpnRunner is stopped and immediately restarted by calling 1426 // expectStartLegacyVpnRunner() and expectStopVpnRunnerPrivileged() back-to-back. 1427 mStopVpnRunnerCv = new ConditionVariable(); 1428 } 1429 1430 @Override 1431 public void stopVpnRunnerPrivileged() { 1432 if (mVpnRunner != null) { 1433 super.stopVpnRunnerPrivileged(); 1434 disconnect(); 1435 mStartLegacyVpnCv = new ConditionVariable(); 1436 } 1437 mVpnRunner = null; 1438 mStopVpnRunnerCv.open(); 1439 } 1440 1441 public void expectStopVpnRunnerPrivileged() { 1442 assertTrue("stopVpnRunnerPrivileged not called after " + TIMEOUT_MS + " ms", 1443 mStopVpnRunnerCv.block(TIMEOUT_MS)); 1444 } 1445 1446 @Override 1447 public synchronized UnderlyingNetworkInfo getUnderlyingNetworkInfo() { 1448 if (mUnderlyingNetworkInfo != null) return mUnderlyingNetworkInfo; 1449 1450 return super.getUnderlyingNetworkInfo(); 1451 } 1452 1453 private synchronized void setUnderlyingNetworkInfo( 1454 UnderlyingNetworkInfo underlyingNetworkInfo) { 1455 mUnderlyingNetworkInfo = underlyingNetworkInfo; 1456 } 1457 } 1458 1459 private UidRangeParcel[] toUidRangeStableParcels(final @NonNull Set<UidRange> ranges) { 1460 return ranges.stream().map( 1461 r -> new UidRangeParcel(r.start, r.stop)).toArray(UidRangeParcel[]::new); 1462 } 1463 1464 private VpnManagerService makeVpnManagerService() { 1465 final VpnManagerService.Dependencies deps = new VpnManagerService.Dependencies() { 1466 public int getCallingUid() { 1467 return mDeps.getCallingUid(); 1468 } 1469 1470 public HandlerThread makeHandlerThread() { 1471 return mVMSHandlerThread; 1472 } 1473 1474 @Override 1475 public VpnProfileStore getVpnProfileStore() { 1476 return mVpnProfileStore; 1477 } 1478 1479 public INetd getNetd() { 1480 return mMockNetd; 1481 } 1482 1483 public INetworkManagementService getINetworkManagementService() { 1484 return mNetworkManagementService; 1485 } 1486 }; 1487 return new VpnManagerService(mServiceContext, deps); 1488 } 1489 1490 private void assertVpnTransportInfo(NetworkCapabilities nc, int type) { 1491 assertNotNull(nc); 1492 final TransportInfo ti = nc.getTransportInfo(); 1493 assertTrue("VPN TransportInfo is not a VpnTransportInfo: " + ti, 1494 ti instanceof VpnTransportInfo); 1495 assertEquals(type, ((VpnTransportInfo) ti).getType()); 1496 1497 } 1498 1499 private void processBroadcast(Intent intent) { 1500 mServiceContext.sendBroadcast(intent); 1501 HandlerUtils.waitForIdle(mVMSHandlerThread, TIMEOUT_MS); 1502 waitForIdle(); 1503 } 1504 1505 private void mockVpn(int uid) { 1506 synchronized (mVpnManagerService.mVpns) { 1507 int userId = UserHandle.getUserId(uid); 1508 mMockVpn = new MockVpn(userId); 1509 // Every running user always has a Vpn in the mVpns array, even if no VPN is running. 1510 mVpnManagerService.mVpns.put(userId, mMockVpn); 1511 } 1512 } 1513 1514 private void mockUidNetworkingBlocked() { 1515 doAnswer(i -> isUidBlocked(mBlockedReasons, i.getArgument(1)) 1516 ).when(mNetworkPolicyManager).isUidNetworkingBlocked(anyInt(), anyBoolean()); 1517 } 1518 1519 private boolean isUidBlocked(int blockedReasons, boolean meteredNetwork) { 1520 final int blockedOnAllNetworksReason = (blockedReasons & ~BLOCKED_METERED_REASON_MASK); 1521 if (blockedOnAllNetworksReason != BLOCKED_REASON_NONE) { 1522 return true; 1523 } 1524 if (meteredNetwork) { 1525 return blockedReasons != BLOCKED_REASON_NONE; 1526 } 1527 return false; 1528 } 1529 1530 private void setBlockedReasonChanged(int blockedReasons) { 1531 mBlockedReasons = blockedReasons; 1532 mPolicyCallback.onUidBlockedReasonChanged(Process.myUid(), blockedReasons); 1533 } 1534 1535 private Nat464Xlat getNat464Xlat(NetworkAgentWrapper mna) { 1536 return mService.getNetworkAgentInfoForNetwork(mna.getNetwork()).clatd; 1537 } 1538 1539 private class WrappedMultinetworkPolicyTracker extends MultinetworkPolicyTracker { 1540 volatile int mConfigMeteredMultipathPreference; 1541 1542 WrappedMultinetworkPolicyTracker(Context c, Handler h, Runnable r) { 1543 super(c, h, r); 1544 } 1545 1546 @Override 1547 protected Resources getResourcesForActiveSubId() { 1548 return mResources; 1549 } 1550 1551 @Override 1552 public int configMeteredMultipathPreference() { 1553 return mConfigMeteredMultipathPreference; 1554 } 1555 } 1556 1557 /** 1558 * Wait up to TIMEOUT_MS for {@code conditionVariable} to open. 1559 * Fails if TIMEOUT_MS goes by before {@code conditionVariable} opens. 1560 */ 1561 static private void waitFor(ConditionVariable conditionVariable) { 1562 if (conditionVariable.block(TIMEOUT_MS)) { 1563 return; 1564 } 1565 fail("ConditionVariable was blocked for more than " + TIMEOUT_MS + "ms"); 1566 } 1567 1568 private <T> T doAsUid(final int uid, @NonNull final Supplier<T> what) { 1569 when(mDeps.getCallingUid()).thenReturn(uid); 1570 try { 1571 return what.get(); 1572 } finally { 1573 returnRealCallingUid(); 1574 } 1575 } 1576 1577 private void doAsUid(final int uid, @NonNull final Runnable what) { 1578 doAsUid(uid, () -> { 1579 what.run(); return Void.TYPE; 1580 }); 1581 } 1582 1583 private void registerNetworkCallbackAsUid(NetworkRequest request, NetworkCallback callback, 1584 int uid) { 1585 doAsUid(uid, () -> { 1586 mCm.registerNetworkCallback(request, callback); 1587 }); 1588 } 1589 1590 private void registerDefaultNetworkCallbackAsUid(@NonNull final NetworkCallback callback, 1591 final int uid) { 1592 doAsUid(uid, () -> { 1593 mCm.registerDefaultNetworkCallback(callback); 1594 waitForIdle(); 1595 }); 1596 } 1597 1598 private interface ExceptionalRunnable { 1599 void run() throws Exception; 1600 } 1601 1602 private void withPermission(String permission, ExceptionalRunnable r) throws Exception { 1603 try { 1604 mServiceContext.setPermission(permission, PERMISSION_GRANTED); 1605 r.run(); 1606 } finally { 1607 mServiceContext.setPermission(permission, null); 1608 } 1609 } 1610 1611 private void withPermission(String permission, int pid, int uid, ExceptionalRunnable r) 1612 throws Exception { 1613 try { 1614 mServiceContext.setPermission(permission, pid, uid, PERMISSION_GRANTED); 1615 r.run(); 1616 } finally { 1617 mServiceContext.setPermission(permission, pid, uid, null); 1618 } 1619 } 1620 1621 private static final int PRIMARY_USER = 0; 1622 private static final int SECONDARY_USER = 10; 1623 private static final int TERTIARY_USER = 11; 1624 private static final UidRange PRIMARY_UIDRANGE = 1625 UidRange.createForUser(UserHandle.of(PRIMARY_USER)); 1626 private static final int APP1_UID = UserHandle.getUid(PRIMARY_USER, 10100); 1627 private static final int APP2_UID = UserHandle.getUid(PRIMARY_USER, 10101); 1628 private static final int VPN_UID = UserHandle.getUid(PRIMARY_USER, 10043); 1629 private static final UserInfo PRIMARY_USER_INFO = new UserInfo(PRIMARY_USER, "", 1630 UserInfo.FLAG_PRIMARY); 1631 private static final UserHandle PRIMARY_USER_HANDLE = new UserHandle(PRIMARY_USER); 1632 private static final UserHandle SECONDARY_USER_HANDLE = new UserHandle(SECONDARY_USER); 1633 private static final UserHandle TERTIARY_USER_HANDLE = new UserHandle(TERTIARY_USER); 1634 1635 private static final int RESTRICTED_USER = 1; 1636 private static final UserInfo RESTRICTED_USER_INFO = new UserInfo(RESTRICTED_USER, "", 1637 UserInfo.FLAG_RESTRICTED); 1638 static { 1639 RESTRICTED_USER_INFO.restrictedProfileParentId = PRIMARY_USER; 1640 } 1641 1642 @Before 1643 public void setUp() throws Exception { 1644 mNetIdManager = new TestNetIdManager(); 1645 1646 mContext = InstrumentationRegistry.getContext(); 1647 1648 MockitoAnnotations.initMocks(this); 1649 1650 when(mUserManager.getAliveUsers()).thenReturn(Arrays.asList(PRIMARY_USER_INFO)); 1651 when(mUserManager.getUserHandles(anyBoolean())).thenReturn( 1652 Arrays.asList(PRIMARY_USER_HANDLE)); 1653 when(mUserManager.getUserInfo(PRIMARY_USER)).thenReturn(PRIMARY_USER_INFO); 1654 // canHaveRestrictedProfile does not take a userId. It applies to the userId of the context 1655 // it was started from, i.e., PRIMARY_USER. 1656 when(mUserManager.canHaveRestrictedProfile()).thenReturn(true); 1657 when(mUserManager.getUserInfo(RESTRICTED_USER)).thenReturn(RESTRICTED_USER_INFO); 1658 1659 final ApplicationInfo applicationInfo = new ApplicationInfo(); 1660 applicationInfo.targetSdkVersion = Build.VERSION_CODES.Q; 1661 when(mPackageManager.getApplicationInfoAsUser(anyString(), anyInt(), any())) 1662 .thenReturn(applicationInfo); 1663 when(mPackageManager.getTargetSdkVersion(anyString())) 1664 .thenReturn(applicationInfo.targetSdkVersion); 1665 when(mSystemConfigManager.getSystemPermissionUids(anyString())).thenReturn(new int[0]); 1666 1667 // InstrumentationTestRunner prepares a looper, but AndroidJUnitRunner does not. 1668 // http://b/25897652 . 1669 if (Looper.myLooper() == null) { 1670 Looper.prepare(); 1671 } 1672 mockDefaultPackages(); 1673 mockHasSystemFeature(FEATURE_WIFI, true); 1674 mockHasSystemFeature(FEATURE_WIFI_DIRECT, true); 1675 doReturn(true).when(mTelephonyManager).isDataCapable(); 1676 1677 FakeSettingsProvider.clearSettingsProvider(); 1678 mServiceContext = new MockContext(InstrumentationRegistry.getContext(), 1679 new FakeSettingsProvider()); 1680 mServiceContext.setUseRegisteredHandlers(true); 1681 mServiceContext.setPermission(NETWORK_FACTORY, PERMISSION_GRANTED); 1682 mServiceContext.setPermission(NETWORK_STACK, PERMISSION_GRANTED); 1683 mServiceContext.setPermission(CONTROL_OEM_PAID_NETWORK_PREFERENCE, PERMISSION_GRANTED); 1684 mServiceContext.setPermission(PACKET_KEEPALIVE_OFFLOAD, PERMISSION_GRANTED); 1685 mServiceContext.setPermission(CONNECTIVITY_USE_RESTRICTED_NETWORKS, PERMISSION_GRANTED); 1686 1687 mAlarmManagerThread = new HandlerThread("TestAlarmManager"); 1688 mAlarmManagerThread.start(); 1689 initAlarmManager(mAlarmManager, mAlarmManagerThread.getThreadHandler()); 1690 1691 mCsHandlerThread = new HandlerThread("TestConnectivityService"); 1692 mVMSHandlerThread = new HandlerThread("TestVpnManagerService"); 1693 mDeps = makeDependencies(); 1694 returnRealCallingUid(); 1695 mService = new ConnectivityService(mServiceContext, 1696 mMockDnsResolver, 1697 mock(IpConnectivityLog.class), 1698 mMockNetd, 1699 mDeps); 1700 mService.mLingerDelayMs = TEST_LINGER_DELAY_MS; 1701 mService.mNascentDelayMs = TEST_NASCENT_DELAY_MS; 1702 verify(mDeps).makeMultinetworkPolicyTracker(any(), any(), any()); 1703 1704 final ArgumentCaptor<NetworkPolicyCallback> policyCallbackCaptor = 1705 ArgumentCaptor.forClass(NetworkPolicyCallback.class); 1706 verify(mNetworkPolicyManager).registerNetworkPolicyCallback(any(), 1707 policyCallbackCaptor.capture()); 1708 mPolicyCallback = policyCallbackCaptor.getValue(); 1709 1710 // Create local CM before sending system ready so that we can answer 1711 // getSystemService() correctly. 1712 mCm = new WrappedConnectivityManager(InstrumentationRegistry.getContext(), mService); 1713 mService.systemReadyInternal(); 1714 mVpnManagerService = makeVpnManagerService(); 1715 mVpnManagerService.systemReady(); 1716 mockVpn(Process.myUid()); 1717 mCm.bindProcessToNetwork(null); 1718 mQosCallbackTracker = mock(QosCallbackTracker.class); 1719 1720 // Ensure that the default setting for Captive Portals is used for most tests 1721 setCaptivePortalMode(ConnectivitySettingsManager.CAPTIVE_PORTAL_MODE_PROMPT); 1722 setAlwaysOnNetworks(false); 1723 setPrivateDnsSettings(PRIVATE_DNS_MODE_OFF, "ignored.example.com"); 1724 } 1725 1726 private void returnRealCallingUid() { 1727 doAnswer((invocationOnMock) -> Binder.getCallingUid()).when(mDeps).getCallingUid(); 1728 } 1729 1730 private ConnectivityService.Dependencies makeDependencies() { 1731 doReturn(false).when(mSystemProperties).getBoolean("ro.radio.noril", false); 1732 final ConnectivityService.Dependencies deps = mock(ConnectivityService.Dependencies.class); 1733 doReturn(mCsHandlerThread).when(deps).makeHandlerThread(); 1734 doReturn(mNetIdManager).when(deps).makeNetIdManager(); 1735 doReturn(mNetworkStack).when(deps).getNetworkStack(); 1736 doReturn(mSystemProperties).when(deps).getSystemProperties(); 1737 doReturn(mProxyTracker).when(deps).makeProxyTracker(any(), any()); 1738 doReturn(true).when(deps).queryUserAccess(anyInt(), any(), any()); 1739 doAnswer(inv -> { 1740 mPolicyTracker = new WrappedMultinetworkPolicyTracker( 1741 inv.getArgument(0), inv.getArgument(1), inv.getArgument(2)); 1742 return mPolicyTracker; 1743 }).when(deps).makeMultinetworkPolicyTracker(any(), any(), any()); 1744 doReturn(true).when(deps).getCellular464XlatEnabled(); 1745 doAnswer(inv -> 1746 new LocationPermissionChecker(inv.getArgument(0)) { 1747 @Override 1748 protected int getCurrentUser() { 1749 return runAsShell(CREATE_USERS, () -> super.getCurrentUser()); 1750 } 1751 }).when(deps).makeLocationPermissionChecker(any()); 1752 1753 doReturn(60000).when(mResources).getInteger(R.integer.config_networkTransitionTimeout); 1754 doReturn("").when(mResources).getString(R.string.config_networkCaptivePortalServerUrl); 1755 doReturn(new String[]{ WIFI_WOL_IFNAME }).when(mResources).getStringArray( 1756 R.array.config_wakeonlan_supported_interfaces); 1757 doReturn(new String[] { "0,1", "1,3" }).when(mResources).getStringArray( 1758 R.array.config_networkSupportedKeepaliveCount); 1759 doReturn(new String[0]).when(mResources).getStringArray( 1760 R.array.config_networkNotifySwitches); 1761 doReturn(new int[]{10, 11, 12, 14, 15}).when(mResources).getIntArray( 1762 R.array.config_protectedNetworks); 1763 // We don't test the actual notification value strings, so just return an empty array. 1764 // It doesn't matter what the values are as long as it's not null. 1765 doReturn(new String[0]).when(mResources).getStringArray(R.array.network_switch_type_name); 1766 1767 doReturn(R.array.config_networkSupportedKeepaliveCount).when(mResources) 1768 .getIdentifier(eq("config_networkSupportedKeepaliveCount"), eq("array"), any()); 1769 doReturn(R.array.network_switch_type_name).when(mResources) 1770 .getIdentifier(eq("network_switch_type_name"), eq("array"), any()); 1771 doReturn(R.integer.config_networkAvoidBadWifi).when(mResources) 1772 .getIdentifier(eq("config_networkAvoidBadWifi"), eq("integer"), any()); 1773 doReturn(1).when(mResources).getInteger(R.integer.config_networkAvoidBadWifi); 1774 1775 final ConnectivityResources connRes = mock(ConnectivityResources.class); 1776 doReturn(mResources).when(connRes).get(); 1777 doReturn(connRes).when(deps).getResources(any()); 1778 1779 final Context mockResContext = mock(Context.class); 1780 doReturn(mResources).when(mockResContext).getResources(); 1781 ConnectivityResources.setResourcesContextForTest(mockResContext); 1782 1783 doAnswer(inv -> { 1784 final PendingIntent a = inv.getArgument(0); 1785 final PendingIntent b = inv.getArgument(1); 1786 return runAsShell(GET_INTENT_SENDER_INTENT, () -> a.intentFilterEquals(b)); 1787 }).when(deps).intentFilterEquals(any(), any()); 1788 1789 return deps; 1790 } 1791 1792 private static void initAlarmManager(final AlarmManager am, final Handler alarmHandler) { 1793 doAnswer(inv -> { 1794 final long when = inv.getArgument(1); 1795 final WakeupMessage wakeupMsg = inv.getArgument(3); 1796 final Handler handler = inv.getArgument(4); 1797 1798 long delayMs = when - SystemClock.elapsedRealtime(); 1799 if (delayMs < 0) delayMs = 0; 1800 if (delayMs > UNREASONABLY_LONG_ALARM_WAIT_MS) { 1801 fail("Attempting to send msg more than " + UNREASONABLY_LONG_ALARM_WAIT_MS 1802 + "ms into the future: " + delayMs); 1803 } 1804 alarmHandler.postDelayed(() -> handler.post(wakeupMsg::onAlarm), wakeupMsg /* token */, 1805 delayMs); 1806 1807 return null; 1808 }).when(am).setExact(eq(AlarmManager.ELAPSED_REALTIME_WAKEUP), anyLong(), anyString(), 1809 any(WakeupMessage.class), any()); 1810 1811 doAnswer(inv -> { 1812 final WakeupMessage wakeupMsg = inv.getArgument(0); 1813 alarmHandler.removeCallbacksAndMessages(wakeupMsg /* token */); 1814 return null; 1815 }).when(am).cancel(any(WakeupMessage.class)); 1816 } 1817 1818 @After 1819 public void tearDown() throws Exception { 1820 unregisterDefaultNetworkCallbacks(); 1821 maybeTearDownEnterpriseNetwork(); 1822 setAlwaysOnNetworks(false); 1823 if (mCellNetworkAgent != null) { 1824 mCellNetworkAgent.disconnect(); 1825 mCellNetworkAgent = null; 1826 } 1827 if (mWiFiNetworkAgent != null) { 1828 mWiFiNetworkAgent.disconnect(); 1829 mWiFiNetworkAgent = null; 1830 } 1831 if (mEthernetNetworkAgent != null) { 1832 mEthernetNetworkAgent.disconnect(); 1833 mEthernetNetworkAgent = null; 1834 } 1835 1836 if (mQosCallbackMockHelper != null) { 1837 mQosCallbackMockHelper.tearDown(); 1838 mQosCallbackMockHelper = null; 1839 } 1840 mMockVpn.disconnect(); 1841 waitForIdle(); 1842 1843 FakeSettingsProvider.clearSettingsProvider(); 1844 ConnectivityResources.setResourcesContextForTest(null); 1845 1846 mCsHandlerThread.quitSafely(); 1847 mAlarmManagerThread.quitSafely(); 1848 } 1849 1850 private void mockDefaultPackages() throws Exception { 1851 final String myPackageName = mContext.getPackageName(); 1852 final PackageInfo myPackageInfo = mContext.getPackageManager().getPackageInfo( 1853 myPackageName, PackageManager.GET_PERMISSIONS); 1854 when(mPackageManager.getPackagesForUid(Binder.getCallingUid())).thenReturn( 1855 new String[] {myPackageName}); 1856 when(mPackageManager.getPackageInfoAsUser(eq(myPackageName), anyInt(), 1857 eq(UserHandle.getCallingUserId()))).thenReturn(myPackageInfo); 1858 1859 when(mPackageManager.getInstalledPackages(eq(GET_PERMISSIONS | MATCH_ANY_USER))).thenReturn( 1860 Arrays.asList(new PackageInfo[] { 1861 buildPackageInfo(/* SYSTEM */ false, APP1_UID), 1862 buildPackageInfo(/* SYSTEM */ false, APP2_UID), 1863 buildPackageInfo(/* SYSTEM */ false, VPN_UID) 1864 })); 1865 1866 // Create a fake always-on VPN package. 1867 final int userId = UserHandle.getCallingUserId(); 1868 final ApplicationInfo applicationInfo = new ApplicationInfo(); 1869 applicationInfo.targetSdkVersion = Build.VERSION_CODES.R; // Always-on supported in N+. 1870 when(mPackageManager.getApplicationInfoAsUser(eq(ALWAYS_ON_PACKAGE), anyInt(), 1871 eq(userId))).thenReturn(applicationInfo); 1872 1873 // Minimal mocking to keep Vpn#isAlwaysOnPackageSupported happy. 1874 ResolveInfo rInfo = new ResolveInfo(); 1875 rInfo.serviceInfo = new ServiceInfo(); 1876 rInfo.serviceInfo.metaData = new Bundle(); 1877 final List<ResolveInfo> services = Arrays.asList(new ResolveInfo[]{rInfo}); 1878 when(mPackageManager.queryIntentServicesAsUser(any(), eq(PackageManager.GET_META_DATA), 1879 eq(userId))).thenReturn(services); 1880 when(mPackageManager.getPackageUidAsUser(TEST_PACKAGE_NAME, userId)) 1881 .thenReturn(Process.myUid()); 1882 when(mPackageManager.getPackageUidAsUser(ALWAYS_ON_PACKAGE, userId)) 1883 .thenReturn(VPN_UID); 1884 } 1885 1886 private void verifyActiveNetwork(int transport) { 1887 // Test getActiveNetworkInfo() 1888 assertNotNull(mCm.getActiveNetworkInfo()); 1889 assertEquals(transportToLegacyType(transport), mCm.getActiveNetworkInfo().getType()); 1890 // Test getActiveNetwork() 1891 assertNotNull(mCm.getActiveNetwork()); 1892 assertEquals(mCm.getActiveNetwork(), mCm.getActiveNetworkForUid(Process.myUid())); 1893 if (!NetworkCapabilities.isValidTransport(transport)) { 1894 throw new IllegalStateException("Unknown transport " + transport); 1895 } 1896 switch (transport) { 1897 case TRANSPORT_WIFI: 1898 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 1899 break; 1900 case TRANSPORT_CELLULAR: 1901 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 1902 break; 1903 case TRANSPORT_ETHERNET: 1904 assertEquals(mEthernetNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 1905 break; 1906 default: 1907 break; 1908 } 1909 // Test getNetworkInfo(Network) 1910 assertNotNull(mCm.getNetworkInfo(mCm.getActiveNetwork())); 1911 assertEquals(transportToLegacyType(transport), 1912 mCm.getNetworkInfo(mCm.getActiveNetwork()).getType()); 1913 assertNotNull(mCm.getActiveNetworkInfoForUid(Process.myUid())); 1914 // Test getNetworkCapabilities(Network) 1915 assertNotNull(mCm.getNetworkCapabilities(mCm.getActiveNetwork())); 1916 assertTrue(mCm.getNetworkCapabilities(mCm.getActiveNetwork()).hasTransport(transport)); 1917 } 1918 1919 private void verifyNoNetwork() { 1920 waitForIdle(); 1921 // Test getActiveNetworkInfo() 1922 assertNull(mCm.getActiveNetworkInfo()); 1923 // Test getActiveNetwork() 1924 assertNull(mCm.getActiveNetwork()); 1925 assertNull(mCm.getActiveNetworkForUid(Process.myUid())); 1926 // Test getAllNetworks() 1927 assertEmpty(mCm.getAllNetworks()); 1928 assertEmpty(mCm.getAllNetworkStateSnapshots()); 1929 } 1930 1931 /** 1932 * Class to simplify expecting broadcasts using BroadcastInterceptingContext. 1933 * Ensures that the receiver is unregistered after the expected broadcast is received. This 1934 * cannot be done in the BroadcastReceiver itself because BroadcastInterceptingContext runs 1935 * the receivers' receive method while iterating over the list of receivers, and unregistering 1936 * the receiver during iteration throws ConcurrentModificationException. 1937 */ 1938 private class ExpectedBroadcast extends CompletableFuture<Intent> { 1939 private final BroadcastReceiver mReceiver; 1940 1941 ExpectedBroadcast(BroadcastReceiver receiver) { 1942 mReceiver = receiver; 1943 } 1944 1945 public Intent expectBroadcast(int timeoutMs) throws Exception { 1946 try { 1947 return get(timeoutMs, TimeUnit.MILLISECONDS); 1948 } catch (TimeoutException e) { 1949 fail("Expected broadcast not received after " + timeoutMs + " ms"); 1950 return null; 1951 } finally { 1952 mServiceContext.unregisterReceiver(mReceiver); 1953 } 1954 } 1955 1956 public Intent expectBroadcast() throws Exception { 1957 return expectBroadcast(BROADCAST_TIMEOUT_MS); 1958 } 1959 1960 public void expectNoBroadcast(int timeoutMs) throws Exception { 1961 waitForIdle(); 1962 try { 1963 final Intent intent = get(timeoutMs, TimeUnit.MILLISECONDS); 1964 fail("Unexpected broadcast: " + intent.getAction() + " " + intent.getExtras()); 1965 } catch (TimeoutException expected) { 1966 } finally { 1967 mServiceContext.unregisterReceiver(mReceiver); 1968 } 1969 } 1970 } 1971 1972 /** Expects that {@code count} CONNECTIVITY_ACTION broadcasts are received. */ 1973 private ExpectedBroadcast registerConnectivityBroadcast(final int count) { 1974 return registerConnectivityBroadcastThat(count, intent -> true); 1975 } 1976 1977 private ExpectedBroadcast registerConnectivityBroadcastThat(final int count, 1978 @NonNull final Predicate<Intent> filter) { 1979 final IntentFilter intentFilter = new IntentFilter(CONNECTIVITY_ACTION); 1980 // AtomicReference allows receiver to access expected even though it is constructed later. 1981 final AtomicReference<ExpectedBroadcast> expectedRef = new AtomicReference<>(); 1982 final BroadcastReceiver receiver = new BroadcastReceiver() { 1983 private int mRemaining = count; 1984 public void onReceive(Context context, Intent intent) { 1985 final int type = intent.getIntExtra(EXTRA_NETWORK_TYPE, -1); 1986 final NetworkInfo ni = intent.getParcelableExtra(EXTRA_NETWORK_INFO); 1987 Log.d(TAG, "Received CONNECTIVITY_ACTION type=" + type + " ni=" + ni); 1988 if (!filter.test(intent)) return; 1989 if (--mRemaining == 0) { 1990 expectedRef.get().complete(intent); 1991 } 1992 } 1993 }; 1994 final ExpectedBroadcast expected = new ExpectedBroadcast(receiver); 1995 expectedRef.set(expected); 1996 mServiceContext.registerReceiver(receiver, intentFilter); 1997 return expected; 1998 } 1999 2000 private boolean extraInfoInBroadcastHasExpectedNullness(NetworkInfo ni) { 2001 final DetailedState state = ni.getDetailedState(); 2002 if (state == DetailedState.CONNECTED && ni.getExtraInfo() == null) return false; 2003 // Expect a null extraInfo if the network is CONNECTING, because a CONNECTIVITY_ACTION 2004 // broadcast with a state of CONNECTING only happens due to legacy VPN lockdown, which also 2005 // nulls out extraInfo. 2006 if (state == DetailedState.CONNECTING && ni.getExtraInfo() != null) return false; 2007 // Can't make any assertions about DISCONNECTED broadcasts. When a network actually 2008 // disconnects, disconnectAndDestroyNetwork sets its state to DISCONNECTED and its extraInfo 2009 // to null. But if the DISCONNECTED broadcast is just simulated by LegacyTypeTracker due to 2010 // a network switch, extraInfo will likely be populated. 2011 // This is likely a bug in CS, but likely not one we can fix without impacting apps. 2012 return true; 2013 } 2014 2015 private ExpectedBroadcast expectConnectivityAction(int type, NetworkInfo.DetailedState state) { 2016 return registerConnectivityBroadcastThat(1, intent -> { 2017 final int actualType = intent.getIntExtra(EXTRA_NETWORK_TYPE, -1); 2018 final NetworkInfo ni = intent.getParcelableExtra(EXTRA_NETWORK_INFO); 2019 return type == actualType 2020 && state == ni.getDetailedState() 2021 && extraInfoInBroadcastHasExpectedNullness(ni); 2022 }); 2023 } 2024 2025 @Test 2026 public void testNetworkTypes() { 2027 // Ensure that our mocks for the networkAttributes config variable work as expected. If they 2028 // don't, then tests that depend on CONNECTIVITY_ACTION broadcasts for these network types 2029 // will fail. Failing here is much easier to debug. 2030 assertTrue(mCm.isNetworkSupported(TYPE_WIFI)); 2031 assertTrue(mCm.isNetworkSupported(TYPE_MOBILE)); 2032 assertTrue(mCm.isNetworkSupported(TYPE_MOBILE_MMS)); 2033 assertTrue(mCm.isNetworkSupported(TYPE_MOBILE_FOTA)); 2034 assertFalse(mCm.isNetworkSupported(TYPE_PROXY)); 2035 2036 // Check that TYPE_ETHERNET is supported. Unlike the asserts above, which only validate our 2037 // mocks, this assert exercises the ConnectivityService code path that ensures that 2038 // TYPE_ETHERNET is supported if the ethernet service is running. 2039 assertTrue(mCm.isNetworkSupported(TYPE_ETHERNET)); 2040 } 2041 2042 @Test 2043 public void testNetworkFeature() throws Exception { 2044 // Connect the cell agent and wait for the connected broadcast. 2045 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 2046 mCellNetworkAgent.addCapability(NET_CAPABILITY_SUPL); 2047 ExpectedBroadcast b = expectConnectivityAction(TYPE_MOBILE, DetailedState.CONNECTED); 2048 mCellNetworkAgent.connect(true); 2049 b.expectBroadcast(); 2050 2051 // Build legacy request for SUPL. 2052 final NetworkCapabilities legacyCaps = new NetworkCapabilities(); 2053 legacyCaps.addTransportType(TRANSPORT_CELLULAR); 2054 legacyCaps.addCapability(NET_CAPABILITY_SUPL); 2055 final NetworkRequest legacyRequest = new NetworkRequest(legacyCaps, TYPE_MOBILE_SUPL, 2056 ConnectivityManager.REQUEST_ID_UNSET, NetworkRequest.Type.REQUEST); 2057 2058 // File request, withdraw it and make sure no broadcast is sent 2059 b = registerConnectivityBroadcast(1); 2060 final TestNetworkCallback callback = new TestNetworkCallback(); 2061 mCm.requestNetwork(legacyRequest, callback); 2062 callback.expectCallback(CallbackEntry.AVAILABLE, mCellNetworkAgent); 2063 mCm.unregisterNetworkCallback(callback); 2064 b.expectNoBroadcast(800); // 800ms long enough to at least flake if this is sent 2065 2066 // Disconnect the network and expect mobile disconnected broadcast. 2067 b = expectConnectivityAction(TYPE_MOBILE, DetailedState.DISCONNECTED); 2068 mCellNetworkAgent.disconnect(); 2069 b.expectBroadcast(); 2070 } 2071 2072 @Test 2073 public void testLingering() throws Exception { 2074 verifyNoNetwork(); 2075 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 2076 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 2077 assertNull(mCm.getActiveNetworkInfo()); 2078 assertNull(mCm.getActiveNetwork()); 2079 // Test bringing up validated cellular. 2080 ExpectedBroadcast b = expectConnectivityAction(TYPE_MOBILE, DetailedState.CONNECTED); 2081 mCellNetworkAgent.connect(true); 2082 b.expectBroadcast(); 2083 verifyActiveNetwork(TRANSPORT_CELLULAR); 2084 assertLength(2, mCm.getAllNetworks()); 2085 assertTrue(mCm.getAllNetworks()[0].equals(mCm.getActiveNetwork()) || 2086 mCm.getAllNetworks()[1].equals(mCm.getActiveNetwork())); 2087 assertTrue(mCm.getAllNetworks()[0].equals(mWiFiNetworkAgent.getNetwork()) || 2088 mCm.getAllNetworks()[1].equals(mWiFiNetworkAgent.getNetwork())); 2089 // Test bringing up validated WiFi. 2090 b = registerConnectivityBroadcast(2); 2091 mWiFiNetworkAgent.connect(true); 2092 b.expectBroadcast(); 2093 verifyActiveNetwork(TRANSPORT_WIFI); 2094 assertLength(2, mCm.getAllNetworks()); 2095 assertTrue(mCm.getAllNetworks()[0].equals(mCm.getActiveNetwork()) || 2096 mCm.getAllNetworks()[1].equals(mCm.getActiveNetwork())); 2097 assertTrue(mCm.getAllNetworks()[0].equals(mCellNetworkAgent.getNetwork()) || 2098 mCm.getAllNetworks()[1].equals(mCellNetworkAgent.getNetwork())); 2099 // Test cellular linger timeout. 2100 mCellNetworkAgent.expectDisconnected(); 2101 waitForIdle(); 2102 assertLength(1, mCm.getAllNetworks()); 2103 verifyActiveNetwork(TRANSPORT_WIFI); 2104 assertLength(1, mCm.getAllNetworks()); 2105 assertEquals(mCm.getAllNetworks()[0], mCm.getActiveNetwork()); 2106 // Test WiFi disconnect. 2107 b = registerConnectivityBroadcast(1); 2108 mWiFiNetworkAgent.disconnect(); 2109 b.expectBroadcast(); 2110 verifyNoNetwork(); 2111 } 2112 2113 /** 2114 * Verify a newly created network will be inactive instead of torn down even if no one is 2115 * requesting. 2116 */ 2117 @Test 2118 public void testNewNetworkInactive() throws Exception { 2119 // Create a callback that monitoring the testing network. 2120 final TestNetworkCallback listenCallback = new TestNetworkCallback(); 2121 mCm.registerNetworkCallback(new NetworkRequest.Builder().build(), listenCallback); 2122 2123 // 1. Create a network that is not requested by anyone, and does not satisfy any of the 2124 // default requests. Verify that the network will be inactive instead of torn down. 2125 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 2126 mWiFiNetworkAgent.connectWithoutInternet(); 2127 listenCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 2128 listenCallback.assertNoCallback(); 2129 2130 // Verify that the network will be torn down after nascent expiry. A small period of time 2131 // is added in case of flakiness. 2132 final int nascentTimeoutMs = 2133 mService.mNascentDelayMs + mService.mNascentDelayMs / 4; 2134 listenCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent, nascentTimeoutMs); 2135 2136 // 2. Create a network that is satisfied by a request comes later. 2137 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 2138 mWiFiNetworkAgent.connectWithoutInternet(); 2139 listenCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 2140 final NetworkRequest wifiRequest = new NetworkRequest.Builder() 2141 .addTransportType(TRANSPORT_WIFI).build(); 2142 final TestNetworkCallback wifiCallback = new TestNetworkCallback(); 2143 mCm.requestNetwork(wifiRequest, wifiCallback); 2144 wifiCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 2145 2146 // Verify that the network will be kept since the request is still satisfied. And is able 2147 // to get disconnected as usual if the request is released after the nascent timer expires. 2148 listenCallback.assertNoCallback(nascentTimeoutMs); 2149 mCm.unregisterNetworkCallback(wifiCallback); 2150 listenCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 2151 2152 // 3. Create a network that is satisfied by a request comes later. 2153 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 2154 mWiFiNetworkAgent.connectWithoutInternet(); 2155 listenCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 2156 mCm.requestNetwork(wifiRequest, wifiCallback); 2157 wifiCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 2158 2159 // Verify that the network will still be torn down after the request gets removed. 2160 mCm.unregisterNetworkCallback(wifiCallback); 2161 listenCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 2162 2163 // There is no need to ensure that LOSING is never sent in the common case that the 2164 // network immediately satisfies a request that was already present, because it is already 2165 // verified anywhere whenever {@code TestNetworkCallback#expectAvailable*} is called. 2166 2167 mCm.unregisterNetworkCallback(listenCallback); 2168 } 2169 2170 /** 2171 * Verify a newly created network will be inactive and switch to background if only background 2172 * request is satisfied. 2173 */ 2174 @Test 2175 public void testNewNetworkInactive_bgNetwork() throws Exception { 2176 // Create a callback that monitoring the wifi network. 2177 final TestNetworkCallback wifiListenCallback = new TestNetworkCallback(); 2178 mCm.registerNetworkCallback(new NetworkRequest.Builder() 2179 .addTransportType(TRANSPORT_WIFI).build(), wifiListenCallback); 2180 2181 // Create callbacks that can monitor background and foreground mobile networks. 2182 // This is done by granting using background networks permission before registration. Thus, 2183 // the service will not add {@code NET_CAPABILITY_FOREGROUND} by default. 2184 grantUsingBackgroundNetworksPermissionForUid(Binder.getCallingUid()); 2185 final TestNetworkCallback bgMobileListenCallback = new TestNetworkCallback(); 2186 final TestNetworkCallback fgMobileListenCallback = new TestNetworkCallback(); 2187 mCm.registerNetworkCallback(new NetworkRequest.Builder() 2188 .addTransportType(TRANSPORT_CELLULAR).build(), bgMobileListenCallback); 2189 mCm.registerNetworkCallback(new NetworkRequest.Builder() 2190 .addTransportType(TRANSPORT_CELLULAR) 2191 .addCapability(NET_CAPABILITY_FOREGROUND).build(), fgMobileListenCallback); 2192 2193 // Connect wifi, which satisfies default request. 2194 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 2195 mWiFiNetworkAgent.connect(true); 2196 wifiListenCallback.expectAvailableThenValidatedCallbacks(mWiFiNetworkAgent); 2197 2198 // Connect a cellular network, verify that satisfies only the background callback. 2199 setAlwaysOnNetworks(true); 2200 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 2201 mCellNetworkAgent.connect(true); 2202 bgMobileListenCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 2203 fgMobileListenCallback.assertNoCallback(); 2204 assertFalse(isForegroundNetwork(mCellNetworkAgent)); 2205 2206 mCellNetworkAgent.disconnect(); 2207 bgMobileListenCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 2208 fgMobileListenCallback.assertNoCallback(); 2209 2210 mCm.unregisterNetworkCallback(wifiListenCallback); 2211 mCm.unregisterNetworkCallback(bgMobileListenCallback); 2212 mCm.unregisterNetworkCallback(fgMobileListenCallback); 2213 } 2214 2215 @Test 2216 public void testBinderDeathAfterUnregister() throws Exception { 2217 final NetworkCapabilities caps = new NetworkCapabilities.Builder() 2218 .addTransportType(TRANSPORT_WIFI) 2219 .build(); 2220 final Handler handler = new Handler(ConnectivityThread.getInstanceLooper()); 2221 final Messenger messenger = new Messenger(handler); 2222 final CompletableFuture<Binder.DeathRecipient> deathRecipient = new CompletableFuture<>(); 2223 final Binder binder = new Binder() { 2224 private DeathRecipient mDeathRecipient; 2225 @Override 2226 public void linkToDeath(@NonNull final DeathRecipient recipient, final int flags) { 2227 synchronized (this) { 2228 mDeathRecipient = recipient; 2229 } 2230 super.linkToDeath(recipient, flags); 2231 deathRecipient.complete(recipient); 2232 } 2233 2234 @Override 2235 public boolean unlinkToDeath(@NonNull final DeathRecipient recipient, final int flags) { 2236 synchronized (this) { 2237 if (null == mDeathRecipient) { 2238 throw new IllegalStateException(); 2239 } 2240 mDeathRecipient = null; 2241 } 2242 return super.unlinkToDeath(recipient, flags); 2243 } 2244 }; 2245 final NetworkRequest request = mService.listenForNetwork(caps, messenger, binder, 2246 NetworkCallback.FLAG_NONE, mContext.getOpPackageName(), 2247 mContext.getAttributionTag()); 2248 mService.releaseNetworkRequest(request); 2249 deathRecipient.get().binderDied(); 2250 // Wait for the release message to be processed. 2251 waitForIdle(); 2252 } 2253 2254 @Test 2255 public void testValidatedCellularOutscoresUnvalidatedWiFi() throws Exception { 2256 // Test bringing up unvalidated WiFi 2257 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 2258 ExpectedBroadcast b = registerConnectivityBroadcast(1); 2259 mWiFiNetworkAgent.connect(false); 2260 b.expectBroadcast(); 2261 verifyActiveNetwork(TRANSPORT_WIFI); 2262 // Test bringing up unvalidated cellular 2263 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 2264 mCellNetworkAgent.connect(false); 2265 waitForIdle(); 2266 verifyActiveNetwork(TRANSPORT_WIFI); 2267 // Test cellular disconnect. 2268 mCellNetworkAgent.disconnect(); 2269 waitForIdle(); 2270 verifyActiveNetwork(TRANSPORT_WIFI); 2271 // Test bringing up validated cellular 2272 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 2273 b = registerConnectivityBroadcast(2); 2274 mCellNetworkAgent.connect(true); 2275 b.expectBroadcast(); 2276 verifyActiveNetwork(TRANSPORT_CELLULAR); 2277 // Test cellular disconnect. 2278 b = registerConnectivityBroadcast(2); 2279 mCellNetworkAgent.disconnect(); 2280 b.expectBroadcast(); 2281 verifyActiveNetwork(TRANSPORT_WIFI); 2282 // Test WiFi disconnect. 2283 b = registerConnectivityBroadcast(1); 2284 mWiFiNetworkAgent.disconnect(); 2285 b.expectBroadcast(); 2286 verifyNoNetwork(); 2287 } 2288 2289 @Test 2290 public void testUnvalidatedWifiOutscoresUnvalidatedCellular() throws Exception { 2291 // Test bringing up unvalidated cellular. 2292 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 2293 ExpectedBroadcast b = registerConnectivityBroadcast(1); 2294 mCellNetworkAgent.connect(false); 2295 b.expectBroadcast(); 2296 verifyActiveNetwork(TRANSPORT_CELLULAR); 2297 // Test bringing up unvalidated WiFi. 2298 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 2299 b = registerConnectivityBroadcast(2); 2300 mWiFiNetworkAgent.connect(false); 2301 b.expectBroadcast(); 2302 verifyActiveNetwork(TRANSPORT_WIFI); 2303 // Test WiFi disconnect. 2304 b = registerConnectivityBroadcast(2); 2305 mWiFiNetworkAgent.disconnect(); 2306 b.expectBroadcast(); 2307 verifyActiveNetwork(TRANSPORT_CELLULAR); 2308 // Test cellular disconnect. 2309 b = registerConnectivityBroadcast(1); 2310 mCellNetworkAgent.disconnect(); 2311 b.expectBroadcast(); 2312 verifyNoNetwork(); 2313 } 2314 2315 @Test 2316 public void testUnlingeringDoesNotValidate() throws Exception { 2317 // Test bringing up unvalidated WiFi. 2318 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 2319 ExpectedBroadcast b = registerConnectivityBroadcast(1); 2320 mWiFiNetworkAgent.connect(false); 2321 b.expectBroadcast(); 2322 verifyActiveNetwork(TRANSPORT_WIFI); 2323 assertFalse(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).hasCapability( 2324 NET_CAPABILITY_VALIDATED)); 2325 // Test bringing up validated cellular. 2326 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 2327 b = registerConnectivityBroadcast(2); 2328 mCellNetworkAgent.connect(true); 2329 b.expectBroadcast(); 2330 verifyActiveNetwork(TRANSPORT_CELLULAR); 2331 assertFalse(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).hasCapability( 2332 NET_CAPABILITY_VALIDATED)); 2333 // Test cellular disconnect. 2334 b = registerConnectivityBroadcast(2); 2335 mCellNetworkAgent.disconnect(); 2336 b.expectBroadcast(); 2337 verifyActiveNetwork(TRANSPORT_WIFI); 2338 // Unlingering a network should not cause it to be marked as validated. 2339 assertFalse(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).hasCapability( 2340 NET_CAPABILITY_VALIDATED)); 2341 } 2342 2343 @Test 2344 public void testCellularOutscoresWeakWifi() throws Exception { 2345 // Test bringing up validated cellular. 2346 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 2347 ExpectedBroadcast b = registerConnectivityBroadcast(1); 2348 mCellNetworkAgent.connect(true); 2349 b.expectBroadcast(); 2350 verifyActiveNetwork(TRANSPORT_CELLULAR); 2351 // Test bringing up validated WiFi. 2352 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 2353 b = registerConnectivityBroadcast(2); 2354 mWiFiNetworkAgent.connect(true); 2355 b.expectBroadcast(); 2356 verifyActiveNetwork(TRANSPORT_WIFI); 2357 // Test WiFi getting really weak. 2358 b = registerConnectivityBroadcast(2); 2359 mWiFiNetworkAgent.adjustScore(-11); 2360 b.expectBroadcast(); 2361 verifyActiveNetwork(TRANSPORT_CELLULAR); 2362 // Test WiFi restoring signal strength. 2363 b = registerConnectivityBroadcast(2); 2364 mWiFiNetworkAgent.adjustScore(11); 2365 b.expectBroadcast(); 2366 verifyActiveNetwork(TRANSPORT_WIFI); 2367 } 2368 2369 @Test 2370 public void testReapingNetwork() throws Exception { 2371 // Test bringing up WiFi without NET_CAPABILITY_INTERNET. 2372 // Expect it to be torn down immediately because it satisfies no requests. 2373 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 2374 mWiFiNetworkAgent.connectWithoutInternet(); 2375 mWiFiNetworkAgent.expectDisconnected(); 2376 // Test bringing up cellular without NET_CAPABILITY_INTERNET. 2377 // Expect it to be torn down immediately because it satisfies no requests. 2378 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 2379 mCellNetworkAgent.connectWithoutInternet(); 2380 mCellNetworkAgent.expectDisconnected(); 2381 // Test bringing up validated WiFi. 2382 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 2383 final ExpectedBroadcast b = expectConnectivityAction(TYPE_WIFI, DetailedState.CONNECTED); 2384 mWiFiNetworkAgent.connect(true); 2385 b.expectBroadcast(); 2386 verifyActiveNetwork(TRANSPORT_WIFI); 2387 // Test bringing up unvalidated cellular. 2388 // Expect it to be torn down because it could never be the highest scoring network 2389 // satisfying the default request even if it validated. 2390 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 2391 mCellNetworkAgent.connect(false); 2392 mCellNetworkAgent.expectDisconnected(); 2393 verifyActiveNetwork(TRANSPORT_WIFI); 2394 mWiFiNetworkAgent.disconnect(); 2395 mWiFiNetworkAgent.expectDisconnected(); 2396 } 2397 2398 @Test 2399 public void testCellularFallback() throws Exception { 2400 // Test bringing up validated cellular. 2401 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 2402 ExpectedBroadcast b = registerConnectivityBroadcast(1); 2403 mCellNetworkAgent.connect(true); 2404 b.expectBroadcast(); 2405 verifyActiveNetwork(TRANSPORT_CELLULAR); 2406 // Test bringing up validated WiFi. 2407 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 2408 b = registerConnectivityBroadcast(2); 2409 mWiFiNetworkAgent.connect(true); 2410 b.expectBroadcast(); 2411 verifyActiveNetwork(TRANSPORT_WIFI); 2412 // Reevaluate WiFi (it'll instantly fail DNS). 2413 b = registerConnectivityBroadcast(2); 2414 assertTrue(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).hasCapability( 2415 NET_CAPABILITY_VALIDATED)); 2416 mCm.reportBadNetwork(mWiFiNetworkAgent.getNetwork()); 2417 // Should quickly fall back to Cellular. 2418 b.expectBroadcast(); 2419 assertFalse(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).hasCapability( 2420 NET_CAPABILITY_VALIDATED)); 2421 verifyActiveNetwork(TRANSPORT_CELLULAR); 2422 // Reevaluate cellular (it'll instantly fail DNS). 2423 b = registerConnectivityBroadcast(2); 2424 assertTrue(mCm.getNetworkCapabilities(mCellNetworkAgent.getNetwork()).hasCapability( 2425 NET_CAPABILITY_VALIDATED)); 2426 mCm.reportBadNetwork(mCellNetworkAgent.getNetwork()); 2427 // Should quickly fall back to WiFi. 2428 b.expectBroadcast(); 2429 assertFalse(mCm.getNetworkCapabilities(mCellNetworkAgent.getNetwork()).hasCapability( 2430 NET_CAPABILITY_VALIDATED)); 2431 assertFalse(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).hasCapability( 2432 NET_CAPABILITY_VALIDATED)); 2433 verifyActiveNetwork(TRANSPORT_WIFI); 2434 } 2435 2436 @Test 2437 public void testWiFiFallback() throws Exception { 2438 // Test bringing up unvalidated WiFi. 2439 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 2440 ExpectedBroadcast b = registerConnectivityBroadcast(1); 2441 mWiFiNetworkAgent.connect(false); 2442 b.expectBroadcast(); 2443 verifyActiveNetwork(TRANSPORT_WIFI); 2444 // Test bringing up validated cellular. 2445 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 2446 b = registerConnectivityBroadcast(2); 2447 mCellNetworkAgent.connect(true); 2448 b.expectBroadcast(); 2449 verifyActiveNetwork(TRANSPORT_CELLULAR); 2450 // Reevaluate cellular (it'll instantly fail DNS). 2451 b = registerConnectivityBroadcast(2); 2452 assertTrue(mCm.getNetworkCapabilities(mCellNetworkAgent.getNetwork()).hasCapability( 2453 NET_CAPABILITY_VALIDATED)); 2454 mCm.reportBadNetwork(mCellNetworkAgent.getNetwork()); 2455 // Should quickly fall back to WiFi. 2456 b.expectBroadcast(); 2457 assertFalse(mCm.getNetworkCapabilities(mCellNetworkAgent.getNetwork()).hasCapability( 2458 NET_CAPABILITY_VALIDATED)); 2459 verifyActiveNetwork(TRANSPORT_WIFI); 2460 } 2461 2462 @Test 2463 public void testRequiresValidation() { 2464 assertTrue(NetworkMonitorUtils.isValidationRequired( 2465 mCm.getDefaultRequest().networkCapabilities)); 2466 } 2467 2468 /** 2469 * Utility NetworkCallback for testing. The caller must explicitly test for all the callbacks 2470 * this class receives, by calling expectCallback() exactly once each time a callback is 2471 * received. assertNoCallback may be called at any time. 2472 */ 2473 private class TestNetworkCallback extends TestableNetworkCallback { 2474 TestNetworkCallback() { 2475 super(TEST_CALLBACK_TIMEOUT_MS); 2476 } 2477 2478 @Override 2479 public void assertNoCallback() { 2480 // TODO: better support this use case in TestableNetworkCallback 2481 waitForIdle(); 2482 assertNoCallback(0 /* timeout */); 2483 } 2484 2485 @Override 2486 public <T extends CallbackEntry> T expectCallback(final KClass<T> type, final HasNetwork n, 2487 final long timeoutMs) { 2488 final T callback = super.expectCallback(type, n, timeoutMs); 2489 if (callback instanceof CallbackEntry.Losing) { 2490 // TODO : move this to the specific test(s) needing this rather than here. 2491 final CallbackEntry.Losing losing = (CallbackEntry.Losing) callback; 2492 final int maxMsToLive = losing.getMaxMsToLive(); 2493 String msg = String.format( 2494 "Invalid linger time value %d, must be between %d and %d", 2495 maxMsToLive, 0, mService.mLingerDelayMs); 2496 assertTrue(msg, 0 <= maxMsToLive && maxMsToLive <= mService.mLingerDelayMs); 2497 } 2498 return callback; 2499 } 2500 } 2501 2502 // Can't be part of TestNetworkCallback because "cannot be declared static; static methods can 2503 // only be declared in a static or top level type". 2504 static void assertNoCallbacks(TestNetworkCallback ... callbacks) { 2505 for (TestNetworkCallback c : callbacks) { 2506 c.assertNoCallback(); 2507 } 2508 } 2509 2510 static void expectOnLost(TestNetworkAgentWrapper network, TestNetworkCallback ... callbacks) { 2511 for (TestNetworkCallback c : callbacks) { 2512 c.expectCallback(CallbackEntry.LOST, network); 2513 } 2514 } 2515 2516 static void expectAvailableCallbacksUnvalidatedWithSpecifier(TestNetworkAgentWrapper network, 2517 NetworkSpecifier specifier, TestNetworkCallback ... callbacks) { 2518 for (TestNetworkCallback c : callbacks) { 2519 c.expectCallback(CallbackEntry.AVAILABLE, network); 2520 c.expectCapabilitiesThat(network, (nc) -> 2521 !nc.hasCapability(NET_CAPABILITY_VALIDATED) 2522 && Objects.equals(specifier, nc.getNetworkSpecifier())); 2523 c.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, network); 2524 c.expectCallback(CallbackEntry.BLOCKED_STATUS, network); 2525 } 2526 } 2527 2528 @Test 2529 public void testStateChangeNetworkCallbacks() throws Exception { 2530 final TestNetworkCallback genericNetworkCallback = new TestNetworkCallback(); 2531 final TestNetworkCallback wifiNetworkCallback = new TestNetworkCallback(); 2532 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback(); 2533 final NetworkRequest genericRequest = new NetworkRequest.Builder() 2534 .clearCapabilities().build(); 2535 final NetworkRequest wifiRequest = new NetworkRequest.Builder() 2536 .addTransportType(TRANSPORT_WIFI).build(); 2537 final NetworkRequest cellRequest = new NetworkRequest.Builder() 2538 .addTransportType(TRANSPORT_CELLULAR).build(); 2539 mCm.registerNetworkCallback(genericRequest, genericNetworkCallback); 2540 mCm.registerNetworkCallback(wifiRequest, wifiNetworkCallback); 2541 mCm.registerNetworkCallback(cellRequest, cellNetworkCallback); 2542 2543 // Test unvalidated networks 2544 ExpectedBroadcast b = registerConnectivityBroadcast(1); 2545 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 2546 mCellNetworkAgent.connect(false); 2547 genericNetworkCallback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent); 2548 cellNetworkCallback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent); 2549 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 2550 b.expectBroadcast(); 2551 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback); 2552 2553 // This should not trigger spurious onAvailable() callbacks, b/21762680. 2554 mCellNetworkAgent.adjustScore(-1); 2555 waitForIdle(); 2556 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback); 2557 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 2558 2559 b = registerConnectivityBroadcast(2); 2560 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 2561 mWiFiNetworkAgent.connect(false); 2562 genericNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 2563 wifiNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 2564 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 2565 b.expectBroadcast(); 2566 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback); 2567 2568 b = registerConnectivityBroadcast(2); 2569 mWiFiNetworkAgent.disconnect(); 2570 genericNetworkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 2571 wifiNetworkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 2572 cellNetworkCallback.assertNoCallback(); 2573 b.expectBroadcast(); 2574 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback); 2575 2576 b = registerConnectivityBroadcast(1); 2577 mCellNetworkAgent.disconnect(); 2578 genericNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 2579 cellNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 2580 b.expectBroadcast(); 2581 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback); 2582 2583 // Test validated networks 2584 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 2585 mCellNetworkAgent.connect(true); 2586 genericNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 2587 cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 2588 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 2589 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback); 2590 2591 // This should not trigger spurious onAvailable() callbacks, b/21762680. 2592 mCellNetworkAgent.adjustScore(-1); 2593 waitForIdle(); 2594 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback); 2595 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 2596 2597 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 2598 mWiFiNetworkAgent.connect(true); 2599 genericNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 2600 genericNetworkCallback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent); 2601 genericNetworkCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent); 2602 wifiNetworkCallback.expectAvailableThenValidatedCallbacks(mWiFiNetworkAgent); 2603 cellNetworkCallback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent); 2604 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 2605 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback); 2606 2607 mWiFiNetworkAgent.disconnect(); 2608 genericNetworkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 2609 wifiNetworkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 2610 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback); 2611 2612 mCellNetworkAgent.disconnect(); 2613 genericNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 2614 cellNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 2615 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback); 2616 } 2617 2618 private void doNetworkCallbacksSanitizationTest(boolean sanitized) throws Exception { 2619 final TestNetworkCallback callback = new TestNetworkCallback(); 2620 final TestNetworkCallback defaultCallback = new TestNetworkCallback(); 2621 final NetworkRequest wifiRequest = new NetworkRequest.Builder() 2622 .addTransportType(TRANSPORT_WIFI).build(); 2623 mCm.registerNetworkCallback(wifiRequest, callback); 2624 mCm.registerDefaultNetworkCallback(defaultCallback); 2625 2626 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 2627 mWiFiNetworkAgent.connect(false); 2628 callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 2629 defaultCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 2630 2631 final LinkProperties newLp = new LinkProperties(); 2632 final Uri capportUrl = Uri.parse("https://capport.example.com/api"); 2633 final CaptivePortalData capportData = new CaptivePortalData.Builder() 2634 .setCaptive(true).build(); 2635 2636 final Uri expectedCapportUrl = sanitized ? null : capportUrl; 2637 newLp.setCaptivePortalApiUrl(capportUrl); 2638 mWiFiNetworkAgent.sendLinkProperties(newLp); 2639 callback.expectLinkPropertiesThat(mWiFiNetworkAgent, lp -> 2640 Objects.equals(expectedCapportUrl, lp.getCaptivePortalApiUrl())); 2641 defaultCallback.expectLinkPropertiesThat(mWiFiNetworkAgent, lp -> 2642 Objects.equals(expectedCapportUrl, lp.getCaptivePortalApiUrl())); 2643 2644 final CaptivePortalData expectedCapportData = sanitized ? null : capportData; 2645 mWiFiNetworkAgent.notifyCapportApiDataChanged(capportData); 2646 callback.expectLinkPropertiesThat(mWiFiNetworkAgent, lp -> 2647 Objects.equals(expectedCapportData, lp.getCaptivePortalData())); 2648 defaultCallback.expectLinkPropertiesThat(mWiFiNetworkAgent, lp -> 2649 Objects.equals(expectedCapportData, lp.getCaptivePortalData())); 2650 2651 final LinkProperties lp = mCm.getLinkProperties(mWiFiNetworkAgent.getNetwork()); 2652 assertEquals(expectedCapportUrl, lp.getCaptivePortalApiUrl()); 2653 assertEquals(expectedCapportData, lp.getCaptivePortalData()); 2654 } 2655 2656 @Test 2657 public void networkCallbacksSanitizationTest_Sanitize() throws Exception { 2658 mServiceContext.setPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, 2659 PERMISSION_DENIED); 2660 mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_DENIED); 2661 doNetworkCallbacksSanitizationTest(true /* sanitized */); 2662 } 2663 2664 @Test 2665 public void networkCallbacksSanitizationTest_NoSanitize_NetworkStack() throws Exception { 2666 mServiceContext.setPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, 2667 PERMISSION_GRANTED); 2668 mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_DENIED); 2669 doNetworkCallbacksSanitizationTest(false /* sanitized */); 2670 } 2671 2672 @Test 2673 public void networkCallbacksSanitizationTest_NoSanitize_Settings() throws Exception { 2674 mServiceContext.setPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, 2675 PERMISSION_DENIED); 2676 mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_GRANTED); 2677 doNetworkCallbacksSanitizationTest(false /* sanitized */); 2678 } 2679 2680 @Test 2681 public void testOwnerUidCannotChange() throws Exception { 2682 final NetworkCapabilities ncTemplate = new NetworkCapabilities(); 2683 final int originalOwnerUid = Process.myUid(); 2684 ncTemplate.setOwnerUid(originalOwnerUid); 2685 2686 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, new LinkProperties(), 2687 ncTemplate); 2688 mWiFiNetworkAgent.connect(false); 2689 waitForIdle(); 2690 2691 // Send ConnectivityService an update to the mWiFiNetworkAgent's capabilities that changes 2692 // the owner UID and an unrelated capability. 2693 NetworkCapabilities agentCapabilities = mWiFiNetworkAgent.getNetworkCapabilities(); 2694 assertEquals(originalOwnerUid, agentCapabilities.getOwnerUid()); 2695 agentCapabilities.setOwnerUid(42); 2696 assertFalse(agentCapabilities.hasCapability(NET_CAPABILITY_NOT_CONGESTED)); 2697 agentCapabilities.addCapability(NET_CAPABILITY_NOT_CONGESTED); 2698 mWiFiNetworkAgent.setNetworkCapabilities(agentCapabilities, true); 2699 waitForIdle(); 2700 2701 // Owner UIDs are not visible without location permission. 2702 setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION, 2703 Manifest.permission.ACCESS_FINE_LOCATION); 2704 2705 // Check that the capability change has been applied but the owner UID is not modified. 2706 NetworkCapabilities nc = mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()); 2707 assertEquals(originalOwnerUid, nc.getOwnerUid()); 2708 assertTrue(nc.hasCapability(NET_CAPABILITY_NOT_CONGESTED)); 2709 } 2710 2711 @Test 2712 public void testMultipleLingering() throws Exception { 2713 // This test would be flaky with the default 120ms timer: that is short enough that 2714 // lingered networks are torn down before assertions can be run. We don't want to mock the 2715 // lingering timer to keep the WakeupMessage logic realistic: this has already proven useful 2716 // in detecting races. 2717 mService.mLingerDelayMs = 300; 2718 2719 NetworkRequest request = new NetworkRequest.Builder() 2720 .clearCapabilities().addCapability(NET_CAPABILITY_NOT_METERED) 2721 .build(); 2722 TestNetworkCallback callback = new TestNetworkCallback(); 2723 mCm.registerNetworkCallback(request, callback); 2724 2725 TestNetworkCallback defaultCallback = new TestNetworkCallback(); 2726 mCm.registerDefaultNetworkCallback(defaultCallback); 2727 2728 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 2729 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 2730 mEthernetNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_ETHERNET); 2731 2732 mCellNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED); 2733 mWiFiNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED); 2734 mEthernetNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED); 2735 2736 mCellNetworkAgent.connect(true); 2737 callback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 2738 defaultCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 2739 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 2740 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 2741 2742 mWiFiNetworkAgent.connect(true); 2743 // We get AVAILABLE on wifi when wifi connects and satisfies our unmetered request. 2744 // We then get LOSING when wifi validates and cell is outscored. 2745 callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 2746 // TODO: Investigate sending validated before losing. 2747 callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent); 2748 callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent); 2749 defaultCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent); 2750 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 2751 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 2752 2753 mEthernetNetworkAgent.connect(true); 2754 callback.expectAvailableCallbacksUnvalidated(mEthernetNetworkAgent); 2755 // TODO: Investigate sending validated before losing. 2756 callback.expectCallback(CallbackEntry.LOSING, mWiFiNetworkAgent); 2757 callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mEthernetNetworkAgent); 2758 defaultCallback.expectAvailableDoubleValidatedCallbacks(mEthernetNetworkAgent); 2759 assertEquals(mEthernetNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 2760 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 2761 2762 mEthernetNetworkAgent.disconnect(); 2763 callback.expectCallback(CallbackEntry.LOST, mEthernetNetworkAgent); 2764 defaultCallback.expectCallback(CallbackEntry.LOST, mEthernetNetworkAgent); 2765 defaultCallback.expectAvailableCallbacksValidated(mWiFiNetworkAgent); 2766 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 2767 2768 for (int i = 0; i < 4; i++) { 2769 TestNetworkAgentWrapper oldNetwork, newNetwork; 2770 if (i % 2 == 0) { 2771 mWiFiNetworkAgent.adjustScore(-15); 2772 oldNetwork = mWiFiNetworkAgent; 2773 newNetwork = mCellNetworkAgent; 2774 } else { 2775 mWiFiNetworkAgent.adjustScore(15); 2776 oldNetwork = mCellNetworkAgent; 2777 newNetwork = mWiFiNetworkAgent; 2778 2779 } 2780 callback.expectCallback(CallbackEntry.LOSING, oldNetwork); 2781 // TODO: should we send an AVAILABLE callback to newNetwork, to indicate that it is no 2782 // longer lingering? 2783 defaultCallback.expectAvailableCallbacksValidated(newNetwork); 2784 assertEquals(newNetwork.getNetwork(), mCm.getActiveNetwork()); 2785 } 2786 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 2787 2788 // Verify that if a network no longer satisfies a request, we send LOST and not LOSING, even 2789 // if the network is still up. 2790 mWiFiNetworkAgent.removeCapability(NET_CAPABILITY_NOT_METERED); 2791 // We expect a notification about the capabilities change, and nothing else. 2792 defaultCallback.expectCapabilitiesWithout(NET_CAPABILITY_NOT_METERED, mWiFiNetworkAgent); 2793 defaultCallback.assertNoCallback(); 2794 callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 2795 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 2796 2797 // Wifi no longer satisfies our listen, which is for an unmetered network. 2798 // But because its score is 55, it's still up (and the default network). 2799 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 2800 2801 // Disconnect our test networks. 2802 mWiFiNetworkAgent.disconnect(); 2803 defaultCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 2804 defaultCallback.expectAvailableCallbacksValidated(mCellNetworkAgent); 2805 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 2806 mCellNetworkAgent.disconnect(); 2807 defaultCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 2808 waitForIdle(); 2809 assertEquals(null, mCm.getActiveNetwork()); 2810 2811 mCm.unregisterNetworkCallback(callback); 2812 waitForIdle(); 2813 2814 // Check that a network is only lingered or torn down if it would not satisfy a request even 2815 // if it validated. 2816 request = new NetworkRequest.Builder().clearCapabilities().build(); 2817 callback = new TestNetworkCallback(); 2818 2819 mCm.registerNetworkCallback(request, callback); 2820 2821 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 2822 mCellNetworkAgent.connect(false); // Score: 10 2823 callback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent); 2824 defaultCallback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent); 2825 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 2826 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 2827 2828 // Bring up wifi with a score of 20. 2829 // Cell stays up because it would satisfy the default request if it validated. 2830 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 2831 mWiFiNetworkAgent.connect(false); // Score: 20 2832 callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 2833 defaultCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 2834 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 2835 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 2836 2837 mWiFiNetworkAgent.disconnect(); 2838 callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 2839 defaultCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 2840 defaultCallback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent); 2841 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 2842 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 2843 2844 // Bring up wifi, then validate it. Previous versions would immediately tear down cell, but 2845 // it's arguably correct to linger it, since it was the default network before it validated. 2846 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 2847 mWiFiNetworkAgent.connect(true); 2848 callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 2849 // TODO: Investigate sending validated before losing. 2850 callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent); 2851 callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent); 2852 defaultCallback.expectAvailableThenValidatedCallbacks(mWiFiNetworkAgent); 2853 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 2854 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 2855 2856 mWiFiNetworkAgent.disconnect(); 2857 callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 2858 defaultCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 2859 defaultCallback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent); 2860 mCellNetworkAgent.disconnect(); 2861 callback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 2862 defaultCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 2863 waitForIdle(); 2864 assertEquals(null, mCm.getActiveNetwork()); 2865 2866 // If a network is lingering, and we add and remove a request from it, resume lingering. 2867 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 2868 mCellNetworkAgent.connect(true); 2869 callback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 2870 defaultCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 2871 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 2872 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 2873 mWiFiNetworkAgent.connect(true); 2874 defaultCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent); 2875 callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 2876 // TODO: Investigate sending validated before losing. 2877 callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent); 2878 callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent); 2879 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 2880 2881 NetworkRequest cellRequest = new NetworkRequest.Builder() 2882 .addTransportType(TRANSPORT_CELLULAR).build(); 2883 NetworkCallback noopCallback = new NetworkCallback(); 2884 mCm.requestNetwork(cellRequest, noopCallback); 2885 // TODO: should this cause an AVAILABLE callback, to indicate that the network is no longer 2886 // lingering? 2887 mCm.unregisterNetworkCallback(noopCallback); 2888 callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent); 2889 2890 // Similar to the above: lingering can start even after the lingered request is removed. 2891 // Disconnect wifi and switch to cell. 2892 mWiFiNetworkAgent.disconnect(); 2893 callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 2894 defaultCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 2895 defaultCallback.expectAvailableCallbacksValidated(mCellNetworkAgent); 2896 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 2897 2898 // Cell is now the default network. Pin it with a cell-specific request. 2899 noopCallback = new NetworkCallback(); // Can't reuse NetworkCallbacks. http://b/20701525 2900 mCm.requestNetwork(cellRequest, noopCallback); 2901 2902 // Now connect wifi, and expect it to become the default network. 2903 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 2904 mWiFiNetworkAgent.connect(true); 2905 callback.expectAvailableThenValidatedCallbacks(mWiFiNetworkAgent); 2906 defaultCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent); 2907 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 2908 // The default request is lingering on cell, but nothing happens to cell, and we send no 2909 // callbacks for it, because it's kept up by cellRequest. 2910 callback.assertNoCallback(); 2911 // Now unregister cellRequest and expect cell to start lingering. 2912 mCm.unregisterNetworkCallback(noopCallback); 2913 callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent); 2914 2915 // Let linger run its course. 2916 callback.assertNoCallback(); 2917 final int lingerTimeoutMs = mService.mLingerDelayMs + mService.mLingerDelayMs / 4; 2918 callback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent, lingerTimeoutMs); 2919 2920 // Register a TRACK_DEFAULT request and check that it does not affect lingering. 2921 TestNetworkCallback trackDefaultCallback = new TestNetworkCallback(); 2922 mCm.registerDefaultNetworkCallback(trackDefaultCallback); 2923 trackDefaultCallback.expectAvailableCallbacksValidated(mWiFiNetworkAgent); 2924 mEthernetNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_ETHERNET); 2925 mEthernetNetworkAgent.connect(true); 2926 callback.expectAvailableCallbacksUnvalidated(mEthernetNetworkAgent); 2927 callback.expectCallback(CallbackEntry.LOSING, mWiFiNetworkAgent); 2928 callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mEthernetNetworkAgent); 2929 trackDefaultCallback.expectAvailableDoubleValidatedCallbacks(mEthernetNetworkAgent); 2930 defaultCallback.expectAvailableDoubleValidatedCallbacks(mEthernetNetworkAgent); 2931 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 2932 2933 // Let linger run its course. 2934 callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent, lingerTimeoutMs); 2935 2936 // Clean up. 2937 mEthernetNetworkAgent.disconnect(); 2938 callback.expectCallback(CallbackEntry.LOST, mEthernetNetworkAgent); 2939 defaultCallback.expectCallback(CallbackEntry.LOST, mEthernetNetworkAgent); 2940 trackDefaultCallback.expectCallback(CallbackEntry.LOST, mEthernetNetworkAgent); 2941 2942 mCm.unregisterNetworkCallback(callback); 2943 mCm.unregisterNetworkCallback(defaultCallback); 2944 mCm.unregisterNetworkCallback(trackDefaultCallback); 2945 } 2946 2947 private void grantUsingBackgroundNetworksPermissionForUid(final int uid) throws Exception { 2948 grantUsingBackgroundNetworksPermissionForUid(uid, mContext.getPackageName()); 2949 } 2950 2951 private void grantUsingBackgroundNetworksPermissionForUid( 2952 final int uid, final String packageName) throws Exception { 2953 when(mPackageManager.getPackageInfo( 2954 eq(packageName), eq(GET_PERMISSIONS | MATCH_ANY_USER))) 2955 .thenReturn(buildPackageInfo(true /* hasSystemPermission */, uid)); 2956 mService.mPermissionMonitor.onPackageAdded(packageName, uid); 2957 } 2958 2959 @Test 2960 public void testNetworkGoesIntoBackgroundAfterLinger() throws Exception { 2961 setAlwaysOnNetworks(true); 2962 grantUsingBackgroundNetworksPermissionForUid(Binder.getCallingUid()); 2963 NetworkRequest request = new NetworkRequest.Builder() 2964 .clearCapabilities() 2965 .build(); 2966 TestNetworkCallback callback = new TestNetworkCallback(); 2967 mCm.registerNetworkCallback(request, callback); 2968 2969 TestNetworkCallback defaultCallback = new TestNetworkCallback(); 2970 mCm.registerDefaultNetworkCallback(defaultCallback); 2971 2972 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 2973 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 2974 2975 mCellNetworkAgent.connect(true); 2976 callback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 2977 defaultCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 2978 2979 // Wifi comes up and cell lingers. 2980 mWiFiNetworkAgent.connect(true); 2981 defaultCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent); 2982 callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 2983 callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent); 2984 callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent); 2985 2986 // File a request for cellular, then release it. 2987 NetworkRequest cellRequest = new NetworkRequest.Builder() 2988 .addTransportType(TRANSPORT_CELLULAR).build(); 2989 NetworkCallback noopCallback = new NetworkCallback(); 2990 mCm.requestNetwork(cellRequest, noopCallback); 2991 mCm.unregisterNetworkCallback(noopCallback); 2992 callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent); 2993 2994 // Let linger run its course. 2995 callback.assertNoCallback(); 2996 final int lingerTimeoutMs = TEST_LINGER_DELAY_MS + TEST_LINGER_DELAY_MS / 4; 2997 callback.expectCapabilitiesWithout(NET_CAPABILITY_FOREGROUND, mCellNetworkAgent, 2998 lingerTimeoutMs); 2999 3000 // Clean up. 3001 mCm.unregisterNetworkCallback(defaultCallback); 3002 mCm.unregisterNetworkCallback(callback); 3003 } 3004 3005 private NativeNetworkConfig nativeNetworkConfigPhysical(int netId, int permission) { 3006 return new NativeNetworkConfig(netId, NativeNetworkType.PHYSICAL, permission, 3007 /*secure=*/ false, VpnManager.TYPE_VPN_NONE); 3008 } 3009 3010 private NativeNetworkConfig nativeNetworkConfigVpn(int netId, boolean secure, int vpnType) { 3011 return new NativeNetworkConfig(netId, NativeNetworkType.VIRTUAL, INetd.PERMISSION_NONE, 3012 secure, vpnType); 3013 } 3014 3015 @Test 3016 public void testNetworkAgentCallbacks() throws Exception { 3017 // Keeps track of the order of events that happen in this test. 3018 final LinkedBlockingQueue<String> eventOrder = new LinkedBlockingQueue<>(); 3019 3020 final NetworkRequest request = new NetworkRequest.Builder() 3021 .addTransportType(TRANSPORT_WIFI).build(); 3022 final TestNetworkCallback callback = new TestNetworkCallback(); 3023 final AtomicReference<Network> wifiNetwork = new AtomicReference<>(); 3024 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3025 3026 // Expectations for state when various callbacks fire. These expectations run on the handler 3027 // thread and not on the test thread because they need to prevent the handler thread from 3028 // advancing while they examine state. 3029 3030 // 1. When onCreated fires, netd has been told to create the network. 3031 mWiFiNetworkAgent.setCreatedCallback(() -> { 3032 eventOrder.offer("onNetworkCreated"); 3033 wifiNetwork.set(mWiFiNetworkAgent.getNetwork()); 3034 assertNotNull(wifiNetwork.get()); 3035 try { 3036 verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( 3037 wifiNetwork.get().getNetId(), INetd.PERMISSION_NONE)); 3038 } catch (RemoteException impossible) { 3039 fail(); 3040 } 3041 }); 3042 3043 // 2. onNetworkUnwanted isn't precisely ordered with respect to any particular events. Just 3044 // check that it is fired at some point after disconnect. 3045 mWiFiNetworkAgent.setUnwantedCallback(() -> eventOrder.offer("onNetworkUnwanted")); 3046 3047 // 3. While the teardown timer is running, connectivity APIs report the network is gone, but 3048 // netd has not yet been told to destroy it. 3049 final Runnable duringTeardown = () -> { 3050 eventOrder.offer("timePasses"); 3051 assertNull(mCm.getLinkProperties(wifiNetwork.get())); 3052 try { 3053 verify(mMockNetd, never()).networkDestroy(wifiNetwork.get().getNetId()); 3054 } catch (RemoteException impossible) { 3055 fail(); 3056 } 3057 }; 3058 3059 // 4. After onNetworkDisconnected is called, connectivity APIs report the network is gone, 3060 // and netd has been told to destroy it. 3061 mWiFiNetworkAgent.setDisconnectedCallback(() -> { 3062 eventOrder.offer("onNetworkDisconnected"); 3063 assertNull(mCm.getLinkProperties(wifiNetwork.get())); 3064 try { 3065 verify(mMockNetd).networkDestroy(wifiNetwork.get().getNetId()); 3066 } catch (RemoteException impossible) { 3067 fail(); 3068 } 3069 }); 3070 3071 // Connect a network, and file a request for it after it has come up, to ensure the nascent 3072 // timer is cleared and the test does not have to wait for it. Filing the request after the 3073 // network has come up is necessary because ConnectivityService does not appear to clear the 3074 // nascent timer if the first request satisfied by the network was filed before the network 3075 // connected. 3076 // TODO: fix this bug, file the request before connecting, and remove the waitForIdle. 3077 mWiFiNetworkAgent.connectWithoutInternet(); 3078 waitForIdle(); 3079 mCm.requestNetwork(request, callback); 3080 callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 3081 3082 // Set teardown delay and make sure CS has processed it. 3083 mWiFiNetworkAgent.getNetworkAgent().setTeardownDelayMillis(300); 3084 waitForIdle(); 3085 3086 // Post the duringTeardown lambda to the handler so it fires while teardown is in progress. 3087 // The delay must be long enough it will run after the unregisterNetworkCallback has torn 3088 // down the network and started the teardown timer, and short enough that the lambda is 3089 // scheduled to run before the teardown timer. 3090 final Handler h = new Handler(mCsHandlerThread.getLooper()); 3091 h.postDelayed(duringTeardown, 150); 3092 3093 // Disconnect the network and check that events happened in the right order. 3094 mCm.unregisterNetworkCallback(callback); 3095 assertEquals("onNetworkCreated", eventOrder.poll(TIMEOUT_MS, TimeUnit.MILLISECONDS)); 3096 assertEquals("onNetworkUnwanted", eventOrder.poll(TIMEOUT_MS, TimeUnit.MILLISECONDS)); 3097 assertEquals("timePasses", eventOrder.poll(TIMEOUT_MS, TimeUnit.MILLISECONDS)); 3098 assertEquals("onNetworkDisconnected", eventOrder.poll(TIMEOUT_MS, TimeUnit.MILLISECONDS)); 3099 3100 mCm.unregisterNetworkCallback(callback); 3101 } 3102 3103 @Test 3104 public void testExplicitlySelected() throws Exception { 3105 NetworkRequest request = new NetworkRequest.Builder() 3106 .clearCapabilities().addCapability(NET_CAPABILITY_INTERNET) 3107 .build(); 3108 TestNetworkCallback callback = new TestNetworkCallback(); 3109 mCm.registerNetworkCallback(request, callback); 3110 3111 // Bring up validated cell. 3112 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 3113 mCellNetworkAgent.connect(true); 3114 callback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 3115 3116 // Bring up unvalidated wifi with explicitlySelected=true. 3117 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3118 mWiFiNetworkAgent.explicitlySelected(true, false); 3119 mWiFiNetworkAgent.connect(false); 3120 callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 3121 3122 // Cell Remains the default. 3123 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 3124 3125 // Lower wifi's score to below than cell, and check that it doesn't disconnect because 3126 // it's explicitly selected. 3127 mWiFiNetworkAgent.adjustScore(-40); 3128 mWiFiNetworkAgent.adjustScore(40); 3129 callback.assertNoCallback(); 3130 3131 // If the user chooses yes on the "No Internet access, stay connected?" dialog, we switch to 3132 // wifi even though it's unvalidated. 3133 mCm.setAcceptUnvalidated(mWiFiNetworkAgent.getNetwork(), true, false); 3134 callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent); 3135 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 3136 3137 // Disconnect wifi, and then reconnect, again with explicitlySelected=true. 3138 mWiFiNetworkAgent.disconnect(); 3139 callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 3140 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3141 mWiFiNetworkAgent.explicitlySelected(true, false); 3142 mWiFiNetworkAgent.connect(false); 3143 callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 3144 3145 // If the user chooses no on the "No Internet access, stay connected?" dialog, we ask the 3146 // network to disconnect. 3147 mCm.setAcceptUnvalidated(mWiFiNetworkAgent.getNetwork(), false, false); 3148 callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 3149 3150 // Reconnect, again with explicitlySelected=true, but this time validate. 3151 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3152 mWiFiNetworkAgent.explicitlySelected(true, false); 3153 mWiFiNetworkAgent.connect(true); 3154 callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 3155 callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent); 3156 callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent); 3157 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 3158 3159 mEthernetNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_ETHERNET); 3160 mEthernetNetworkAgent.connect(true); 3161 callback.expectAvailableCallbacksUnvalidated(mEthernetNetworkAgent); 3162 callback.expectCallback(CallbackEntry.LOSING, mWiFiNetworkAgent); 3163 callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mEthernetNetworkAgent); 3164 assertEquals(mEthernetNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 3165 callback.assertNoCallback(); 3166 3167 // Disconnect wifi, and then reconnect as if the user had selected "yes, don't ask again" 3168 // (i.e., with explicitlySelected=true and acceptUnvalidated=true). Expect to switch to 3169 // wifi immediately. 3170 mWiFiNetworkAgent.disconnect(); 3171 callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 3172 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3173 mWiFiNetworkAgent.explicitlySelected(true, true); 3174 mWiFiNetworkAgent.connect(false); 3175 callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 3176 callback.expectCallback(CallbackEntry.LOSING, mEthernetNetworkAgent); 3177 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 3178 mEthernetNetworkAgent.disconnect(); 3179 callback.expectCallback(CallbackEntry.LOST, mEthernetNetworkAgent); 3180 3181 // Disconnect and reconnect with explicitlySelected=false and acceptUnvalidated=true. 3182 // Check that the network is not scored specially and that the device prefers cell data. 3183 mWiFiNetworkAgent.disconnect(); 3184 callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 3185 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3186 mWiFiNetworkAgent.explicitlySelected(false, true); 3187 mWiFiNetworkAgent.connect(false); 3188 callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 3189 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 3190 3191 // Clean up. 3192 mWiFiNetworkAgent.disconnect(); 3193 mCellNetworkAgent.disconnect(); 3194 3195 callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 3196 callback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 3197 } 3198 3199 private void tryNetworkFactoryRequests(int capability) throws Exception { 3200 // Verify NOT_RESTRICTED is set appropriately 3201 final NetworkCapabilities nc = new NetworkRequest.Builder().addCapability(capability) 3202 .build().networkCapabilities; 3203 if (capability == NET_CAPABILITY_CBS || capability == NET_CAPABILITY_DUN 3204 || capability == NET_CAPABILITY_EIMS || capability == NET_CAPABILITY_FOTA 3205 || capability == NET_CAPABILITY_IA || capability == NET_CAPABILITY_IMS 3206 || capability == NET_CAPABILITY_RCS || capability == NET_CAPABILITY_XCAP 3207 || capability == NET_CAPABILITY_VSIM || capability == NET_CAPABILITY_BIP 3208 || capability == NET_CAPABILITY_ENTERPRISE) { 3209 assertFalse(nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)); 3210 } else { 3211 assertTrue(nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)); 3212 } 3213 3214 NetworkCapabilities filter = new NetworkCapabilities(); 3215 filter.addTransportType(TRANSPORT_CELLULAR); 3216 filter.addCapability(capability); 3217 // Add NOT_VCN_MANAGED capability into filter unconditionally since some requests will add 3218 // NOT_VCN_MANAGED automatically but not for NetworkCapabilities, 3219 // see {@code NetworkCapabilities#deduceNotVcnManagedCapability} for more details. 3220 filter.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED); 3221 final HandlerThread handlerThread = new HandlerThread("testNetworkFactoryRequests"); 3222 handlerThread.start(); 3223 final MockNetworkFactory testFactory = new MockNetworkFactory(handlerThread.getLooper(), 3224 mServiceContext, "testFactory", filter, mCsHandlerThread); 3225 testFactory.setScoreFilter(45); 3226 testFactory.register(); 3227 3228 final NetworkCallback networkCallback; 3229 if (capability != NET_CAPABILITY_INTERNET) { 3230 // If the capability passed in argument is part of the default request, then the 3231 // factory will see the default request. Otherwise the filter will prevent the 3232 // factory from seeing it. In that case, add a request so it can be tested. 3233 assertFalse(testFactory.getMyStartRequested()); 3234 NetworkRequest request = new NetworkRequest.Builder().addCapability(capability).build(); 3235 networkCallback = new NetworkCallback(); 3236 mCm.requestNetwork(request, networkCallback); 3237 } else { 3238 networkCallback = null; 3239 } 3240 testFactory.expectRequestAdd(); 3241 testFactory.assertRequestCountEquals(1); 3242 assertTrue(testFactory.getMyStartRequested()); 3243 3244 // Now bring in a higher scored network. 3245 TestNetworkAgentWrapper testAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 3246 // When testAgent connects, because of its score (50 legacy int / cell transport) 3247 // it will beat or equal the testFactory's offer, so the request will be removed. 3248 // Note the agent as validated only if the capability is INTERNET, as it's the only case 3249 // where it makes sense. 3250 testAgent.connect(NET_CAPABILITY_INTERNET == capability /* validated */); 3251 testAgent.addCapability(capability); 3252 testFactory.expectRequestRemove(); 3253 testFactory.assertRequestCountEquals(0); 3254 assertFalse(testFactory.getMyStartRequested()); 3255 3256 // Add a request and make sure it's not sent to the factory, because the agent 3257 // is satisfying it better. 3258 final NetworkCallback cb = new ConnectivityManager.NetworkCallback(); 3259 mCm.requestNetwork(new NetworkRequest.Builder().addCapability(capability).build(), cb); 3260 expectNoRequestChanged(testFactory); 3261 testFactory.assertRequestCountEquals(0); 3262 assertFalse(testFactory.getMyStartRequested()); 3263 3264 // If using legacy scores, make the test agent weak enough to have the exact same score as 3265 // the factory (50 for cell - 5 adjustment). Make sure the factory doesn't see the request. 3266 // If not using legacy score, this is a no-op and the "same score removes request" behavior 3267 // has already been tested above. 3268 testAgent.adjustScore(-5); 3269 expectNoRequestChanged(testFactory); 3270 assertFalse(testFactory.getMyStartRequested()); 3271 3272 // Make the test agent weak enough that the factory will see the two requests (the one that 3273 // was just sent, and either the default one or the one sent at the top of this test if 3274 // the default won't be seen). 3275 testAgent.setScore(new NetworkScore.Builder().setLegacyInt(2).setExiting(true).build()); 3276 testFactory.expectRequestAdds(2); 3277 testFactory.assertRequestCountEquals(2); 3278 assertTrue(testFactory.getMyStartRequested()); 3279 3280 // Now unregister and make sure the request is removed. 3281 mCm.unregisterNetworkCallback(cb); 3282 testFactory.expectRequestRemove(); 3283 3284 // Bring in a bunch of requests. 3285 assertEquals(1, testFactory.getMyRequestCount()); 3286 ConnectivityManager.NetworkCallback[] networkCallbacks = 3287 new ConnectivityManager.NetworkCallback[10]; 3288 for (int i = 0; i< networkCallbacks.length; i++) { 3289 networkCallbacks[i] = new ConnectivityManager.NetworkCallback(); 3290 NetworkRequest.Builder builder = new NetworkRequest.Builder(); 3291 builder.addCapability(capability); 3292 mCm.requestNetwork(builder.build(), networkCallbacks[i]); 3293 } 3294 testFactory.expectRequestAdds(10); 3295 testFactory.assertRequestCountEquals(11); // +1 for the default/test specific request 3296 assertTrue(testFactory.getMyStartRequested()); 3297 3298 // Remove the requests. 3299 for (int i = 0; i < networkCallbacks.length; i++) { 3300 mCm.unregisterNetworkCallback(networkCallbacks[i]); 3301 } 3302 testFactory.expectRequestRemoves(10); 3303 testFactory.assertRequestCountEquals(1); 3304 assertTrue(testFactory.getMyStartRequested()); 3305 3306 // Adjust the agent score up again. Expect the request to be withdrawn. 3307 testAgent.setScore(new NetworkScore.Builder().setLegacyInt(50).build()); 3308 testFactory.expectRequestRemove(); 3309 testFactory.assertRequestCountEquals(0); 3310 assertFalse(testFactory.getMyStartRequested()); 3311 3312 // Drop the higher scored network. 3313 testAgent.disconnect(); 3314 testFactory.expectRequestAdd(); 3315 testFactory.assertRequestCountEquals(1); 3316 assertEquals(1, testFactory.getMyRequestCount()); 3317 assertTrue(testFactory.getMyStartRequested()); 3318 3319 testFactory.terminate(); 3320 if (networkCallback != null) mCm.unregisterNetworkCallback(networkCallback); 3321 handlerThread.quit(); 3322 } 3323 3324 @Test 3325 public void testNetworkFactoryRequests() throws Exception { 3326 tryNetworkFactoryRequests(NET_CAPABILITY_MMS); 3327 tryNetworkFactoryRequests(NET_CAPABILITY_SUPL); 3328 tryNetworkFactoryRequests(NET_CAPABILITY_DUN); 3329 tryNetworkFactoryRequests(NET_CAPABILITY_FOTA); 3330 tryNetworkFactoryRequests(NET_CAPABILITY_IMS); 3331 tryNetworkFactoryRequests(NET_CAPABILITY_CBS); 3332 tryNetworkFactoryRequests(NET_CAPABILITY_WIFI_P2P); 3333 tryNetworkFactoryRequests(NET_CAPABILITY_IA); 3334 tryNetworkFactoryRequests(NET_CAPABILITY_RCS); 3335 tryNetworkFactoryRequests(NET_CAPABILITY_XCAP); 3336 tryNetworkFactoryRequests(NET_CAPABILITY_ENTERPRISE); 3337 tryNetworkFactoryRequests(NET_CAPABILITY_EIMS); 3338 tryNetworkFactoryRequests(NET_CAPABILITY_NOT_METERED); 3339 tryNetworkFactoryRequests(NET_CAPABILITY_INTERNET); 3340 tryNetworkFactoryRequests(NET_CAPABILITY_TRUSTED); 3341 tryNetworkFactoryRequests(NET_CAPABILITY_NOT_VPN); 3342 tryNetworkFactoryRequests(NET_CAPABILITY_VSIM); 3343 tryNetworkFactoryRequests(NET_CAPABILITY_BIP); 3344 // Skipping VALIDATED and CAPTIVE_PORTAL as they're disallowed. 3345 } 3346 3347 @Test 3348 public void testRegisterIgnoringScore() throws Exception { 3349 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3350 mWiFiNetworkAgent.setScore(new NetworkScore.Builder().setLegacyInt(90).build()); 3351 mWiFiNetworkAgent.connect(true /* validated */); 3352 3353 // Make sure the factory sees the default network 3354 final NetworkCapabilities filter = new NetworkCapabilities(); 3355 filter.addTransportType(TRANSPORT_CELLULAR); 3356 filter.addCapability(NET_CAPABILITY_INTERNET); 3357 filter.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED); 3358 final HandlerThread handlerThread = new HandlerThread("testNetworkFactoryRequests"); 3359 handlerThread.start(); 3360 final MockNetworkFactory testFactory = new MockNetworkFactory(handlerThread.getLooper(), 3361 mServiceContext, "testFactory", filter, mCsHandlerThread); 3362 testFactory.register(); 3363 3364 final MockNetworkFactory testFactoryAll = new MockNetworkFactory(handlerThread.getLooper(), 3365 mServiceContext, "testFactoryAll", filter, mCsHandlerThread); 3366 testFactoryAll.registerIgnoringScore(); 3367 3368 // The regular test factory should not see the request, because WiFi is stronger than cell. 3369 expectNoRequestChanged(testFactory); 3370 // With ignoringScore though the request is seen. 3371 testFactoryAll.expectRequestAdd(); 3372 3373 // The legacy int will be ignored anyway, set the only other knob to true 3374 mWiFiNetworkAgent.setScore(new NetworkScore.Builder().setLegacyInt(110) 3375 .setTransportPrimary(true).build()); 3376 3377 expectNoRequestChanged(testFactory); // still not seeing the request 3378 expectNoRequestChanged(testFactoryAll); // still seeing the request 3379 3380 mWiFiNetworkAgent.disconnect(); 3381 } 3382 3383 @Test 3384 public void testNetworkFactoryUnregister() throws Exception { 3385 // Make sure the factory sees the default network 3386 final NetworkCapabilities filter = new NetworkCapabilities(); 3387 filter.addCapability(NET_CAPABILITY_INTERNET); 3388 filter.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED); 3389 3390 final HandlerThread handlerThread = new HandlerThread("testNetworkFactoryRequests"); 3391 handlerThread.start(); 3392 3393 // Checks that calling setScoreFilter on a NetworkFactory immediately before closing it 3394 // does not crash. 3395 for (int i = 0; i < 100; i++) { 3396 final MockNetworkFactory testFactory = new MockNetworkFactory(handlerThread.getLooper(), 3397 mServiceContext, "testFactory", filter, mCsHandlerThread); 3398 // Register the factory and don't be surprised when the default request arrives. 3399 testFactory.register(); 3400 testFactory.expectRequestAdd(); 3401 3402 testFactory.setScoreFilter(42); 3403 testFactory.terminate(); 3404 3405 if (i % 2 == 0) { 3406 try { 3407 testFactory.register(); 3408 fail("Re-registering terminated NetworkFactory should throw"); 3409 } catch (IllegalStateException expected) { 3410 } 3411 } 3412 } 3413 handlerThread.quit(); 3414 } 3415 3416 @Test 3417 public void testNoMutableNetworkRequests() throws Exception { 3418 final PendingIntent pendingIntent = PendingIntent.getBroadcast( 3419 mContext, 0 /* requestCode */, new Intent("a"), FLAG_IMMUTABLE); 3420 NetworkRequest request1 = new NetworkRequest.Builder() 3421 .addCapability(NET_CAPABILITY_VALIDATED) 3422 .build(); 3423 NetworkRequest request2 = new NetworkRequest.Builder() 3424 .addCapability(NET_CAPABILITY_CAPTIVE_PORTAL) 3425 .build(); 3426 3427 Class<IllegalArgumentException> expected = IllegalArgumentException.class; 3428 assertThrows(expected, () -> mCm.requestNetwork(request1, new NetworkCallback())); 3429 assertThrows(expected, () -> mCm.requestNetwork(request1, pendingIntent)); 3430 assertThrows(expected, () -> mCm.requestNetwork(request2, new NetworkCallback())); 3431 assertThrows(expected, () -> mCm.requestNetwork(request2, pendingIntent)); 3432 } 3433 3434 @Test 3435 public void testMMSonWiFi() throws Exception { 3436 // Test bringing up cellular without MMS NetworkRequest gets reaped 3437 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 3438 mCellNetworkAgent.addCapability(NET_CAPABILITY_MMS); 3439 mCellNetworkAgent.connectWithoutInternet(); 3440 mCellNetworkAgent.expectDisconnected(); 3441 waitForIdle(); 3442 assertEmpty(mCm.getAllNetworks()); 3443 verifyNoNetwork(); 3444 3445 // Test bringing up validated WiFi. 3446 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3447 final ExpectedBroadcast b = expectConnectivityAction(TYPE_WIFI, DetailedState.CONNECTED); 3448 mWiFiNetworkAgent.connect(true); 3449 b.expectBroadcast(); 3450 verifyActiveNetwork(TRANSPORT_WIFI); 3451 3452 // Register MMS NetworkRequest 3453 NetworkRequest.Builder builder = new NetworkRequest.Builder(); 3454 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_MMS); 3455 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 3456 mCm.requestNetwork(builder.build(), networkCallback); 3457 3458 // Test bringing up unvalidated cellular with MMS 3459 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 3460 mCellNetworkAgent.addCapability(NET_CAPABILITY_MMS); 3461 mCellNetworkAgent.connectWithoutInternet(); 3462 networkCallback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent); 3463 verifyActiveNetwork(TRANSPORT_WIFI); 3464 3465 // Test releasing NetworkRequest disconnects cellular with MMS 3466 mCm.unregisterNetworkCallback(networkCallback); 3467 mCellNetworkAgent.expectDisconnected(); 3468 verifyActiveNetwork(TRANSPORT_WIFI); 3469 } 3470 3471 @Test 3472 public void testMMSonCell() throws Exception { 3473 // Test bringing up cellular without MMS 3474 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 3475 ExpectedBroadcast b = expectConnectivityAction(TYPE_MOBILE, DetailedState.CONNECTED); 3476 mCellNetworkAgent.connect(false); 3477 b.expectBroadcast(); 3478 verifyActiveNetwork(TRANSPORT_CELLULAR); 3479 3480 // Register MMS NetworkRequest 3481 NetworkRequest.Builder builder = new NetworkRequest.Builder(); 3482 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_MMS); 3483 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 3484 mCm.requestNetwork(builder.build(), networkCallback); 3485 3486 // Test bringing up MMS cellular network 3487 TestNetworkAgentWrapper 3488 mmsNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 3489 mmsNetworkAgent.addCapability(NET_CAPABILITY_MMS); 3490 mmsNetworkAgent.connectWithoutInternet(); 3491 networkCallback.expectAvailableCallbacksUnvalidated(mmsNetworkAgent); 3492 verifyActiveNetwork(TRANSPORT_CELLULAR); 3493 3494 // Test releasing MMS NetworkRequest does not disconnect main cellular NetworkAgent 3495 mCm.unregisterNetworkCallback(networkCallback); 3496 mmsNetworkAgent.expectDisconnected(); 3497 verifyActiveNetwork(TRANSPORT_CELLULAR); 3498 } 3499 3500 @Test 3501 public void testPartialConnectivity() throws Exception { 3502 // Register network callback. 3503 NetworkRequest request = new NetworkRequest.Builder() 3504 .clearCapabilities().addCapability(NET_CAPABILITY_INTERNET) 3505 .build(); 3506 TestNetworkCallback callback = new TestNetworkCallback(); 3507 mCm.registerNetworkCallback(request, callback); 3508 3509 // Bring up validated mobile data. 3510 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 3511 mCellNetworkAgent.connect(true); 3512 callback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 3513 3514 // Bring up wifi with partial connectivity. 3515 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3516 mWiFiNetworkAgent.connectWithPartialConnectivity(); 3517 callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 3518 callback.expectCapabilitiesWith(NET_CAPABILITY_PARTIAL_CONNECTIVITY, mWiFiNetworkAgent); 3519 3520 // Mobile data should be the default network. 3521 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 3522 callback.assertNoCallback(); 3523 3524 // With HTTPS probe disabled, NetworkMonitor should pass the network validation with http 3525 // probe. 3526 mWiFiNetworkAgent.setNetworkPartialValid(false /* isStrictMode */); 3527 // If the user chooses yes to use this partial connectivity wifi, switch the default 3528 // network to wifi and check if wifi becomes valid or not. 3529 mCm.setAcceptPartialConnectivity(mWiFiNetworkAgent.getNetwork(), true /* accept */, 3530 false /* always */); 3531 // If user accepts partial connectivity network, 3532 // NetworkMonitor#setAcceptPartialConnectivity() should be called too. 3533 waitForIdle(); 3534 verify(mWiFiNetworkAgent.mNetworkMonitor, times(1)).setAcceptPartialConnectivity(); 3535 3536 // Need a trigger point to let NetworkMonitor tell ConnectivityService that network is 3537 // validated. 3538 mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), true); 3539 callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent); 3540 NetworkCapabilities nc = callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, 3541 mWiFiNetworkAgent); 3542 assertTrue(nc.hasCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY)); 3543 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 3544 3545 // Disconnect and reconnect wifi with partial connectivity again. 3546 mWiFiNetworkAgent.disconnect(); 3547 callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 3548 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3549 mWiFiNetworkAgent.connectWithPartialConnectivity(); 3550 callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 3551 callback.expectCapabilitiesWith(NET_CAPABILITY_PARTIAL_CONNECTIVITY, mWiFiNetworkAgent); 3552 3553 // Mobile data should be the default network. 3554 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 3555 3556 // If the user chooses no, disconnect wifi immediately. 3557 mCm.setAcceptPartialConnectivity(mWiFiNetworkAgent.getNetwork(), false/* accept */, 3558 false /* always */); 3559 callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 3560 3561 // If user accepted partial connectivity before, and device reconnects to that network 3562 // again, but now the network has full connectivity. The network shouldn't contain 3563 // NET_CAPABILITY_PARTIAL_CONNECTIVITY. 3564 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3565 // acceptUnvalidated is also used as setting for accepting partial networks. 3566 mWiFiNetworkAgent.explicitlySelected(true /* explicitlySelected */, 3567 true /* acceptUnvalidated */); 3568 mWiFiNetworkAgent.connect(true); 3569 3570 // If user accepted partial connectivity network before, 3571 // NetworkMonitor#setAcceptPartialConnectivity() will be called in 3572 // ConnectivityService#updateNetworkInfo(). 3573 callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 3574 verify(mWiFiNetworkAgent.mNetworkMonitor, times(1)).setAcceptPartialConnectivity(); 3575 callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent); 3576 nc = callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent); 3577 assertFalse(nc.hasCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY)); 3578 3579 // Wifi should be the default network. 3580 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 3581 mWiFiNetworkAgent.disconnect(); 3582 callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 3583 3584 // The user accepted partial connectivity and selected "don't ask again". Now the user 3585 // reconnects to the partial connectivity network. Switch to wifi as soon as partial 3586 // connectivity is detected. 3587 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3588 mWiFiNetworkAgent.explicitlySelected(true /* explicitlySelected */, 3589 true /* acceptUnvalidated */); 3590 mWiFiNetworkAgent.connectWithPartialConnectivity(); 3591 // If user accepted partial connectivity network before, 3592 // NetworkMonitor#setAcceptPartialConnectivity() will be called in 3593 // ConnectivityService#updateNetworkInfo(). 3594 callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 3595 verify(mWiFiNetworkAgent.mNetworkMonitor, times(1)).setAcceptPartialConnectivity(); 3596 callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent); 3597 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 3598 callback.expectCapabilitiesWith(NET_CAPABILITY_PARTIAL_CONNECTIVITY, mWiFiNetworkAgent); 3599 mWiFiNetworkAgent.setNetworkValid(false /* isStrictMode */); 3600 3601 // Need a trigger point to let NetworkMonitor tell ConnectivityService that network is 3602 // validated. 3603 mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), true); 3604 callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent); 3605 mWiFiNetworkAgent.disconnect(); 3606 callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 3607 3608 // If the user accepted partial connectivity, and the device auto-reconnects to the partial 3609 // connectivity network, it should contain both PARTIAL_CONNECTIVITY and VALIDATED. 3610 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3611 mWiFiNetworkAgent.explicitlySelected(false /* explicitlySelected */, 3612 true /* acceptUnvalidated */); 3613 3614 // NetworkMonitor will immediately (once the HTTPS probe fails...) report the network as 3615 // valid, because ConnectivityService calls setAcceptPartialConnectivity before it calls 3616 // notifyNetworkConnected. 3617 mWiFiNetworkAgent.connectWithPartialValidConnectivity(false /* isStrictMode */); 3618 callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 3619 verify(mWiFiNetworkAgent.mNetworkMonitor, times(1)).setAcceptPartialConnectivity(); 3620 callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent); 3621 callback.expectCapabilitiesWith( 3622 NET_CAPABILITY_PARTIAL_CONNECTIVITY | NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent); 3623 mWiFiNetworkAgent.disconnect(); 3624 callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 3625 } 3626 3627 @Test 3628 public void testCaptivePortalOnPartialConnectivity() throws Exception { 3629 final TestNetworkCallback captivePortalCallback = new TestNetworkCallback(); 3630 final NetworkRequest captivePortalRequest = new NetworkRequest.Builder() 3631 .addCapability(NET_CAPABILITY_CAPTIVE_PORTAL).build(); 3632 mCm.registerNetworkCallback(captivePortalRequest, captivePortalCallback); 3633 3634 final TestNetworkCallback validatedCallback = new TestNetworkCallback(); 3635 final NetworkRequest validatedRequest = new NetworkRequest.Builder() 3636 .addCapability(NET_CAPABILITY_VALIDATED).build(); 3637 mCm.registerNetworkCallback(validatedRequest, validatedCallback); 3638 3639 // Bring up a network with a captive portal. 3640 // Expect onAvailable callback of listen for NET_CAPABILITY_CAPTIVE_PORTAL. 3641 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3642 String redirectUrl = "http://android.com/path"; 3643 mWiFiNetworkAgent.connectWithCaptivePortal(redirectUrl, false /* isStrictMode */); 3644 captivePortalCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 3645 assertEquals(mWiFiNetworkAgent.waitForRedirectUrl(), redirectUrl); 3646 3647 // Check that startCaptivePortalApp sends the expected command to NetworkMonitor. 3648 mCm.startCaptivePortalApp(mWiFiNetworkAgent.getNetwork()); 3649 verify(mWiFiNetworkAgent.mNetworkMonitor, timeout(TIMEOUT_MS).times(1)) 3650 .launchCaptivePortalApp(); 3651 3652 // Report that the captive portal is dismissed with partial connectivity, and check that 3653 // callbacks are fired. 3654 mWiFiNetworkAgent.setNetworkPartial(); 3655 mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), true); 3656 waitForIdle(); 3657 captivePortalCallback.expectCapabilitiesWith(NET_CAPABILITY_PARTIAL_CONNECTIVITY, 3658 mWiFiNetworkAgent); 3659 3660 // Report partial connectivity is accepted. 3661 mWiFiNetworkAgent.setNetworkPartialValid(false /* isStrictMode */); 3662 mCm.setAcceptPartialConnectivity(mWiFiNetworkAgent.getNetwork(), true /* accept */, 3663 false /* always */); 3664 waitForIdle(); 3665 mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), true); 3666 captivePortalCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 3667 validatedCallback.expectAvailableCallbacksValidated(mWiFiNetworkAgent); 3668 NetworkCapabilities nc = 3669 validatedCallback.expectCapabilitiesWith(NET_CAPABILITY_PARTIAL_CONNECTIVITY, 3670 mWiFiNetworkAgent); 3671 3672 mCm.unregisterNetworkCallback(captivePortalCallback); 3673 mCm.unregisterNetworkCallback(validatedCallback); 3674 } 3675 3676 @Test 3677 public void testCaptivePortal() throws Exception { 3678 final TestNetworkCallback captivePortalCallback = new TestNetworkCallback(); 3679 final NetworkRequest captivePortalRequest = new NetworkRequest.Builder() 3680 .addCapability(NET_CAPABILITY_CAPTIVE_PORTAL).build(); 3681 mCm.registerNetworkCallback(captivePortalRequest, captivePortalCallback); 3682 3683 final TestNetworkCallback validatedCallback = new TestNetworkCallback(); 3684 final NetworkRequest validatedRequest = new NetworkRequest.Builder() 3685 .addCapability(NET_CAPABILITY_VALIDATED).build(); 3686 mCm.registerNetworkCallback(validatedRequest, validatedCallback); 3687 3688 // Bring up a network with a captive portal. 3689 // Expect onAvailable callback of listen for NET_CAPABILITY_CAPTIVE_PORTAL. 3690 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3691 String firstRedirectUrl = "http://example.com/firstPath"; 3692 mWiFiNetworkAgent.connectWithCaptivePortal(firstRedirectUrl, false /* isStrictMode */); 3693 captivePortalCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 3694 assertEquals(mWiFiNetworkAgent.waitForRedirectUrl(), firstRedirectUrl); 3695 3696 // Take down network. 3697 // Expect onLost callback. 3698 mWiFiNetworkAgent.disconnect(); 3699 captivePortalCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 3700 3701 // Bring up a network with a captive portal. 3702 // Expect onAvailable callback of listen for NET_CAPABILITY_CAPTIVE_PORTAL. 3703 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3704 String secondRedirectUrl = "http://example.com/secondPath"; 3705 mWiFiNetworkAgent.connectWithCaptivePortal(secondRedirectUrl, false /* isStrictMode */); 3706 captivePortalCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 3707 assertEquals(mWiFiNetworkAgent.waitForRedirectUrl(), secondRedirectUrl); 3708 3709 // Make captive portal disappear then revalidate. 3710 // Expect onLost callback because network no longer provides NET_CAPABILITY_CAPTIVE_PORTAL. 3711 mWiFiNetworkAgent.setNetworkValid(false /* isStrictMode */); 3712 mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), true); 3713 captivePortalCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 3714 3715 // Expect NET_CAPABILITY_VALIDATED onAvailable callback. 3716 validatedCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent); 3717 3718 // Break network connectivity. 3719 // Expect NET_CAPABILITY_VALIDATED onLost callback. 3720 mWiFiNetworkAgent.setNetworkInvalid(false /* isStrictMode */); 3721 mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), false); 3722 validatedCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 3723 } 3724 3725 @Test 3726 public void testCaptivePortalApp() throws Exception { 3727 final TestNetworkCallback captivePortalCallback = new TestNetworkCallback(); 3728 final NetworkRequest captivePortalRequest = new NetworkRequest.Builder() 3729 .addCapability(NET_CAPABILITY_CAPTIVE_PORTAL).build(); 3730 mCm.registerNetworkCallback(captivePortalRequest, captivePortalCallback); 3731 3732 final TestNetworkCallback validatedCallback = new TestNetworkCallback(); 3733 final NetworkRequest validatedRequest = new NetworkRequest.Builder() 3734 .addCapability(NET_CAPABILITY_VALIDATED).build(); 3735 mCm.registerNetworkCallback(validatedRequest, validatedCallback); 3736 3737 // Bring up wifi. 3738 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3739 mWiFiNetworkAgent.connect(true); 3740 validatedCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent); 3741 Network wifiNetwork = mWiFiNetworkAgent.getNetwork(); 3742 3743 // Check that calling startCaptivePortalApp does nothing. 3744 final int fastTimeoutMs = 100; 3745 mCm.startCaptivePortalApp(wifiNetwork); 3746 waitForIdle(); 3747 verify(mWiFiNetworkAgent.mNetworkMonitor, never()).launchCaptivePortalApp(); 3748 mServiceContext.expectNoStartActivityIntent(fastTimeoutMs); 3749 3750 // Turn into a captive portal. 3751 mWiFiNetworkAgent.setNetworkPortal("http://example.com", false /* isStrictMode */); 3752 mCm.reportNetworkConnectivity(wifiNetwork, false); 3753 captivePortalCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 3754 validatedCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 3755 3756 // Check that startCaptivePortalApp sends the expected command to NetworkMonitor. 3757 mCm.startCaptivePortalApp(wifiNetwork); 3758 waitForIdle(); 3759 verify(mWiFiNetworkAgent.mNetworkMonitor).launchCaptivePortalApp(); 3760 3761 // NetworkMonitor uses startCaptivePortal(Network, Bundle) (startCaptivePortalAppInternal) 3762 final Bundle testBundle = new Bundle(); 3763 final String testKey = "testkey"; 3764 final String testValue = "testvalue"; 3765 testBundle.putString(testKey, testValue); 3766 mServiceContext.setPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, 3767 PERMISSION_GRANTED); 3768 mCm.startCaptivePortalApp(wifiNetwork, testBundle); 3769 final Intent signInIntent = mServiceContext.expectStartActivityIntent(TIMEOUT_MS); 3770 assertEquals(ACTION_CAPTIVE_PORTAL_SIGN_IN, signInIntent.getAction()); 3771 assertEquals(testValue, signInIntent.getStringExtra(testKey)); 3772 3773 // Report that the captive portal is dismissed, and check that callbacks are fired 3774 mWiFiNetworkAgent.setNetworkValid(false /* isStrictMode */); 3775 mWiFiNetworkAgent.mNetworkMonitor.forceReevaluation(Process.myUid()); 3776 validatedCallback.expectAvailableCallbacksValidated(mWiFiNetworkAgent); 3777 captivePortalCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 3778 3779 mCm.unregisterNetworkCallback(validatedCallback); 3780 mCm.unregisterNetworkCallback(captivePortalCallback); 3781 } 3782 3783 @Test 3784 public void testAvoidOrIgnoreCaptivePortals() throws Exception { 3785 final TestNetworkCallback captivePortalCallback = new TestNetworkCallback(); 3786 final NetworkRequest captivePortalRequest = new NetworkRequest.Builder() 3787 .addCapability(NET_CAPABILITY_CAPTIVE_PORTAL).build(); 3788 mCm.registerNetworkCallback(captivePortalRequest, captivePortalCallback); 3789 3790 final TestNetworkCallback validatedCallback = new TestNetworkCallback(); 3791 final NetworkRequest validatedRequest = new NetworkRequest.Builder() 3792 .addCapability(NET_CAPABILITY_VALIDATED).build(); 3793 mCm.registerNetworkCallback(validatedRequest, validatedCallback); 3794 3795 setCaptivePortalMode(ConnectivitySettingsManager.CAPTIVE_PORTAL_MODE_AVOID); 3796 // Bring up a network with a captive portal. 3797 // Expect it to fail to connect and not result in any callbacks. 3798 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3799 String firstRedirectUrl = "http://example.com/firstPath"; 3800 3801 mWiFiNetworkAgent.connectWithCaptivePortal(firstRedirectUrl, false /* isStrictMode */); 3802 mWiFiNetworkAgent.expectDisconnected(); 3803 mWiFiNetworkAgent.expectPreventReconnectReceived(); 3804 3805 assertNoCallbacks(captivePortalCallback, validatedCallback); 3806 } 3807 3808 @Test 3809 public void testCaptivePortalApi() throws Exception { 3810 mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_GRANTED); 3811 3812 final TestNetworkCallback captivePortalCallback = new TestNetworkCallback(); 3813 final NetworkRequest captivePortalRequest = new NetworkRequest.Builder() 3814 .addCapability(NET_CAPABILITY_CAPTIVE_PORTAL).build(); 3815 mCm.registerNetworkCallback(captivePortalRequest, captivePortalCallback); 3816 3817 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3818 final String redirectUrl = "http://example.com/firstPath"; 3819 3820 mWiFiNetworkAgent.connectWithCaptivePortal(redirectUrl, false /* isStrictMode */); 3821 captivePortalCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 3822 3823 final CaptivePortalData testData = new CaptivePortalData.Builder() 3824 .setUserPortalUrl(Uri.parse(redirectUrl)) 3825 .setBytesRemaining(12345L) 3826 .build(); 3827 3828 mWiFiNetworkAgent.notifyCapportApiDataChanged(testData); 3829 3830 captivePortalCallback.expectLinkPropertiesThat(mWiFiNetworkAgent, 3831 lp -> testData.equals(lp.getCaptivePortalData())); 3832 3833 final LinkProperties newLps = new LinkProperties(); 3834 newLps.setMtu(1234); 3835 mWiFiNetworkAgent.sendLinkProperties(newLps); 3836 // CaptivePortalData is not lost and unchanged when LPs are received from the NetworkAgent 3837 captivePortalCallback.expectLinkPropertiesThat(mWiFiNetworkAgent, 3838 lp -> testData.equals(lp.getCaptivePortalData()) && lp.getMtu() == 1234); 3839 } 3840 3841 private TestNetworkCallback setupNetworkCallbackAndConnectToWifi() throws Exception { 3842 // Grant NETWORK_SETTINGS permission to be able to receive LinkProperties change callbacks 3843 // with sensitive (captive portal) data 3844 mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_GRANTED); 3845 3846 final TestNetworkCallback captivePortalCallback = new TestNetworkCallback(); 3847 final NetworkRequest captivePortalRequest = new NetworkRequest.Builder() 3848 .addCapability(NET_CAPABILITY_CAPTIVE_PORTAL).build(); 3849 mCm.registerNetworkCallback(captivePortalRequest, captivePortalCallback); 3850 3851 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3852 3853 mWiFiNetworkAgent.connectWithCaptivePortal(TEST_REDIRECT_URL, false /* isStrictMode */); 3854 captivePortalCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 3855 return captivePortalCallback; 3856 } 3857 3858 private class CaptivePortalTestData { 3859 CaptivePortalTestData(CaptivePortalData naPasspointData, CaptivePortalData capportData, 3860 CaptivePortalData naOtherData, CaptivePortalData expectedMergedPasspointData, 3861 CaptivePortalData expectedMergedOtherData) { 3862 mNaPasspointData = naPasspointData; 3863 mCapportData = capportData; 3864 mNaOtherData = naOtherData; 3865 mExpectedMergedPasspointData = expectedMergedPasspointData; 3866 mExpectedMergedOtherData = expectedMergedOtherData; 3867 } 3868 3869 public final CaptivePortalData mNaPasspointData; 3870 public final CaptivePortalData mCapportData; 3871 public final CaptivePortalData mNaOtherData; 3872 public final CaptivePortalData mExpectedMergedPasspointData; 3873 public final CaptivePortalData mExpectedMergedOtherData; 3874 3875 } 3876 3877 private CaptivePortalTestData setupCaptivePortalData() { 3878 final CaptivePortalData capportData = new CaptivePortalData.Builder() 3879 .setUserPortalUrl(Uri.parse(TEST_REDIRECT_URL)) 3880 .setVenueInfoUrl(Uri.parse(TEST_VENUE_URL_CAPPORT)) 3881 .setUserPortalUrl(Uri.parse(TEST_USER_PORTAL_API_URL_CAPPORT)) 3882 .setExpiryTime(1000000L) 3883 .setBytesRemaining(12345L) 3884 .build(); 3885 3886 final CaptivePortalData naPasspointData = new CaptivePortalData.Builder() 3887 .setBytesRemaining(80802L) 3888 .setVenueInfoUrl(Uri.parse(TEST_VENUE_URL_NA_PASSPOINT), 3889 CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT) 3890 .setUserPortalUrl(Uri.parse(TEST_TERMS_AND_CONDITIONS_URL_NA_PASSPOINT), 3891 CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT) 3892 .setVenueFriendlyName(TEST_FRIENDLY_NAME).build(); 3893 3894 final CaptivePortalData naOtherData = new CaptivePortalData.Builder() 3895 .setBytesRemaining(80802L) 3896 .setVenueInfoUrl(Uri.parse(TEST_VENUE_URL_NA_OTHER), 3897 CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_OTHER) 3898 .setUserPortalUrl(Uri.parse(TEST_TERMS_AND_CONDITIONS_URL_NA_OTHER), 3899 CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_OTHER) 3900 .setVenueFriendlyName(TEST_FRIENDLY_NAME).build(); 3901 3902 final CaptivePortalData expectedMergedPasspointData = new CaptivePortalData.Builder() 3903 .setUserPortalUrl(Uri.parse(TEST_REDIRECT_URL)) 3904 .setBytesRemaining(12345L) 3905 .setExpiryTime(1000000L) 3906 .setVenueInfoUrl(Uri.parse(TEST_VENUE_URL_NA_PASSPOINT), 3907 CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT) 3908 .setUserPortalUrl(Uri.parse(TEST_TERMS_AND_CONDITIONS_URL_NA_PASSPOINT), 3909 CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT) 3910 .setVenueFriendlyName(TEST_FRIENDLY_NAME).build(); 3911 3912 final CaptivePortalData expectedMergedOtherData = new CaptivePortalData.Builder() 3913 .setUserPortalUrl(Uri.parse(TEST_REDIRECT_URL)) 3914 .setBytesRemaining(12345L) 3915 .setExpiryTime(1000000L) 3916 .setVenueInfoUrl(Uri.parse(TEST_VENUE_URL_CAPPORT)) 3917 .setUserPortalUrl(Uri.parse(TEST_USER_PORTAL_API_URL_CAPPORT)) 3918 .setVenueFriendlyName(TEST_FRIENDLY_NAME).build(); 3919 return new CaptivePortalTestData(naPasspointData, capportData, naOtherData, 3920 expectedMergedPasspointData, expectedMergedOtherData); 3921 } 3922 3923 @Test 3924 public void testMergeCaptivePortalApiWithFriendlyNameAndVenueUrl() throws Exception { 3925 final TestNetworkCallback captivePortalCallback = setupNetworkCallbackAndConnectToWifi(); 3926 final CaptivePortalTestData captivePortalTestData = setupCaptivePortalData(); 3927 3928 // Baseline capport data 3929 mWiFiNetworkAgent.notifyCapportApiDataChanged(captivePortalTestData.mCapportData); 3930 3931 captivePortalCallback.expectLinkPropertiesThat(mWiFiNetworkAgent, 3932 lp -> captivePortalTestData.mCapportData.equals(lp.getCaptivePortalData())); 3933 3934 // Venue URL, T&C URL and friendly name from Network agent with Passpoint source, confirm 3935 // that API data gets precedence on the bytes remaining. 3936 final LinkProperties linkProperties = new LinkProperties(); 3937 linkProperties.setCaptivePortalData(captivePortalTestData.mNaPasspointData); 3938 mWiFiNetworkAgent.sendLinkProperties(linkProperties); 3939 3940 // Make sure that the capport data is merged 3941 captivePortalCallback.expectLinkPropertiesThat(mWiFiNetworkAgent, 3942 lp -> captivePortalTestData.mExpectedMergedPasspointData 3943 .equals(lp.getCaptivePortalData())); 3944 3945 // Now send this information from non-Passpoint source, confirm that Capport data takes 3946 // precedence 3947 linkProperties.setCaptivePortalData(captivePortalTestData.mNaOtherData); 3948 mWiFiNetworkAgent.sendLinkProperties(linkProperties); 3949 3950 // Make sure that the capport data is merged 3951 captivePortalCallback.expectLinkPropertiesThat(mWiFiNetworkAgent, 3952 lp -> captivePortalTestData.mExpectedMergedOtherData 3953 .equals(lp.getCaptivePortalData())); 3954 3955 // Create a new LP with no Network agent capport data 3956 final LinkProperties newLps = new LinkProperties(); 3957 newLps.setMtu(1234); 3958 mWiFiNetworkAgent.sendLinkProperties(newLps); 3959 // CaptivePortalData is not lost and has the original values when LPs are received from the 3960 // NetworkAgent 3961 captivePortalCallback.expectLinkPropertiesThat(mWiFiNetworkAgent, 3962 lp -> captivePortalTestData.mCapportData.equals(lp.getCaptivePortalData()) 3963 && lp.getMtu() == 1234); 3964 3965 // Now send capport data only from the Network agent 3966 mWiFiNetworkAgent.notifyCapportApiDataChanged(null); 3967 captivePortalCallback.expectLinkPropertiesThat(mWiFiNetworkAgent, 3968 lp -> lp.getCaptivePortalData() == null); 3969 3970 newLps.setCaptivePortalData(captivePortalTestData.mNaPasspointData); 3971 mWiFiNetworkAgent.sendLinkProperties(newLps); 3972 3973 // Make sure that only the network agent capport data is available 3974 captivePortalCallback.expectLinkPropertiesThat(mWiFiNetworkAgent, 3975 lp -> captivePortalTestData.mNaPasspointData.equals(lp.getCaptivePortalData())); 3976 } 3977 3978 @Test 3979 public void testMergeCaptivePortalDataFromNetworkAgentFirstThenCapport() throws Exception { 3980 final TestNetworkCallback captivePortalCallback = setupNetworkCallbackAndConnectToWifi(); 3981 final CaptivePortalTestData captivePortalTestData = setupCaptivePortalData(); 3982 3983 // Venue URL and friendly name from Network agent, confirm that API data gets precedence 3984 // on the bytes remaining. 3985 final LinkProperties linkProperties = new LinkProperties(); 3986 linkProperties.setCaptivePortalData(captivePortalTestData.mNaPasspointData); 3987 mWiFiNetworkAgent.sendLinkProperties(linkProperties); 3988 3989 // Make sure that the data is saved correctly 3990 captivePortalCallback.expectLinkPropertiesThat(mWiFiNetworkAgent, 3991 lp -> captivePortalTestData.mNaPasspointData.equals(lp.getCaptivePortalData())); 3992 3993 // Expected merged data: Network agent data is preferred, and values that are not used by 3994 // it are merged from capport data 3995 mWiFiNetworkAgent.notifyCapportApiDataChanged(captivePortalTestData.mCapportData); 3996 3997 // Make sure that the Capport data is merged correctly 3998 captivePortalCallback.expectLinkPropertiesThat(mWiFiNetworkAgent, 3999 lp -> captivePortalTestData.mExpectedMergedPasspointData.equals( 4000 lp.getCaptivePortalData())); 4001 4002 // Now set the naData to null 4003 linkProperties.setCaptivePortalData(null); 4004 mWiFiNetworkAgent.sendLinkProperties(linkProperties); 4005 4006 // Make sure that the Capport data is retained correctly 4007 captivePortalCallback.expectLinkPropertiesThat(mWiFiNetworkAgent, 4008 lp -> captivePortalTestData.mCapportData.equals(lp.getCaptivePortalData())); 4009 } 4010 4011 @Test 4012 public void testMergeCaptivePortalDataFromNetworkAgentOtherSourceFirstThenCapport() 4013 throws Exception { 4014 final TestNetworkCallback captivePortalCallback = setupNetworkCallbackAndConnectToWifi(); 4015 final CaptivePortalTestData captivePortalTestData = setupCaptivePortalData(); 4016 4017 // Venue URL and friendly name from Network agent, confirm that API data gets precedence 4018 // on the bytes remaining. 4019 final LinkProperties linkProperties = new LinkProperties(); 4020 linkProperties.setCaptivePortalData(captivePortalTestData.mNaOtherData); 4021 mWiFiNetworkAgent.sendLinkProperties(linkProperties); 4022 4023 // Make sure that the data is saved correctly 4024 captivePortalCallback.expectLinkPropertiesThat(mWiFiNetworkAgent, 4025 lp -> captivePortalTestData.mNaOtherData.equals(lp.getCaptivePortalData())); 4026 4027 // Expected merged data: Network agent data is preferred, and values that are not used by 4028 // it are merged from capport data 4029 mWiFiNetworkAgent.notifyCapportApiDataChanged(captivePortalTestData.mCapportData); 4030 4031 // Make sure that the Capport data is merged correctly 4032 captivePortalCallback.expectLinkPropertiesThat(mWiFiNetworkAgent, 4033 lp -> captivePortalTestData.mExpectedMergedOtherData.equals( 4034 lp.getCaptivePortalData())); 4035 } 4036 4037 private NetworkRequest.Builder newWifiRequestBuilder() { 4038 return new NetworkRequest.Builder().addTransportType(TRANSPORT_WIFI); 4039 } 4040 4041 /** 4042 * Verify request matching behavior with network specifiers. 4043 * 4044 * This test does not check updating the specifier on a live network because the specifier is 4045 * immutable and this triggers a WTF in 4046 * {@link ConnectivityService#mixInCapabilities(NetworkAgentInfo, NetworkCapabilities)}. 4047 */ 4048 @Test 4049 public void testNetworkSpecifier() throws Exception { 4050 // A NetworkSpecifier subclass that matches all networks but must not be visible to apps. 4051 class ConfidentialMatchAllNetworkSpecifier extends NetworkSpecifier implements 4052 Parcelable { 4053 @Override 4054 public boolean canBeSatisfiedBy(NetworkSpecifier other) { 4055 return true; 4056 } 4057 4058 @Override 4059 public int describeContents() { 4060 return 0; 4061 } 4062 4063 @Override 4064 public void writeToParcel(Parcel dest, int flags) {} 4065 4066 @Override 4067 public NetworkSpecifier redact() { 4068 return null; 4069 } 4070 } 4071 4072 // A network specifier that matches either another LocalNetworkSpecifier with the same 4073 // string or a ConfidentialMatchAllNetworkSpecifier, and can be passed to apps as is. 4074 class LocalStringNetworkSpecifier extends NetworkSpecifier implements Parcelable { 4075 private String mString; 4076 4077 LocalStringNetworkSpecifier(String string) { 4078 mString = string; 4079 } 4080 4081 @Override 4082 public boolean canBeSatisfiedBy(NetworkSpecifier other) { 4083 if (other instanceof LocalStringNetworkSpecifier) { 4084 return TextUtils.equals(mString, 4085 ((LocalStringNetworkSpecifier) other).mString); 4086 } 4087 if (other instanceof ConfidentialMatchAllNetworkSpecifier) return true; 4088 return false; 4089 } 4090 4091 @Override 4092 public int describeContents() { 4093 return 0; 4094 } 4095 @Override 4096 public void writeToParcel(Parcel dest, int flags) {} 4097 } 4098 4099 4100 NetworkRequest rEmpty1 = newWifiRequestBuilder().build(); 4101 NetworkRequest rEmpty2 = newWifiRequestBuilder().setNetworkSpecifier((String) null).build(); 4102 NetworkRequest rEmpty3 = newWifiRequestBuilder().setNetworkSpecifier("").build(); 4103 NetworkRequest rEmpty4 = newWifiRequestBuilder().setNetworkSpecifier( 4104 (NetworkSpecifier) null).build(); 4105 NetworkRequest rFoo = newWifiRequestBuilder().setNetworkSpecifier( 4106 new LocalStringNetworkSpecifier("foo")).build(); 4107 NetworkRequest rBar = newWifiRequestBuilder().setNetworkSpecifier( 4108 new LocalStringNetworkSpecifier("bar")).build(); 4109 4110 TestNetworkCallback cEmpty1 = new TestNetworkCallback(); 4111 TestNetworkCallback cEmpty2 = new TestNetworkCallback(); 4112 TestNetworkCallback cEmpty3 = new TestNetworkCallback(); 4113 TestNetworkCallback cEmpty4 = new TestNetworkCallback(); 4114 TestNetworkCallback cFoo = new TestNetworkCallback(); 4115 TestNetworkCallback cBar = new TestNetworkCallback(); 4116 TestNetworkCallback[] emptyCallbacks = new TestNetworkCallback[] { 4117 cEmpty1, cEmpty2, cEmpty3, cEmpty4 }; 4118 4119 mCm.registerNetworkCallback(rEmpty1, cEmpty1); 4120 mCm.registerNetworkCallback(rEmpty2, cEmpty2); 4121 mCm.registerNetworkCallback(rEmpty3, cEmpty3); 4122 mCm.registerNetworkCallback(rEmpty4, cEmpty4); 4123 mCm.registerNetworkCallback(rFoo, cFoo); 4124 mCm.registerNetworkCallback(rBar, cBar); 4125 4126 LocalStringNetworkSpecifier nsFoo = new LocalStringNetworkSpecifier("foo"); 4127 LocalStringNetworkSpecifier nsBar = new LocalStringNetworkSpecifier("bar"); 4128 4129 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4130 mWiFiNetworkAgent.connect(false); 4131 expectAvailableCallbacksUnvalidatedWithSpecifier(mWiFiNetworkAgent, null /* specifier */, 4132 cEmpty1, cEmpty2, cEmpty3, cEmpty4); 4133 assertNoCallbacks(cFoo, cBar); 4134 4135 mWiFiNetworkAgent.disconnect(); 4136 expectOnLost(mWiFiNetworkAgent, cEmpty1, cEmpty2, cEmpty3, cEmpty4); 4137 4138 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4139 mWiFiNetworkAgent.setNetworkSpecifier(nsFoo); 4140 mWiFiNetworkAgent.connect(false); 4141 expectAvailableCallbacksUnvalidatedWithSpecifier(mWiFiNetworkAgent, nsFoo, 4142 cEmpty1, cEmpty2, cEmpty3, cEmpty4, cFoo); 4143 cBar.assertNoCallback(); 4144 assertEquals(nsFoo, 4145 mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).getNetworkSpecifier()); 4146 assertNoCallbacks(cEmpty1, cEmpty2, cEmpty3, cEmpty4, cFoo); 4147 4148 mWiFiNetworkAgent.disconnect(); 4149 expectOnLost(mWiFiNetworkAgent, cEmpty1, cEmpty2, cEmpty3, cEmpty4, cFoo); 4150 4151 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4152 mWiFiNetworkAgent.setNetworkSpecifier(nsBar); 4153 mWiFiNetworkAgent.connect(false); 4154 expectAvailableCallbacksUnvalidatedWithSpecifier(mWiFiNetworkAgent, nsBar, 4155 cEmpty1, cEmpty2, cEmpty3, cEmpty4, cBar); 4156 cFoo.assertNoCallback(); 4157 assertEquals(nsBar, 4158 mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).getNetworkSpecifier()); 4159 4160 mWiFiNetworkAgent.disconnect(); 4161 expectOnLost(mWiFiNetworkAgent, cEmpty1, cEmpty2, cEmpty3, cEmpty4, cBar); 4162 cFoo.assertNoCallback(); 4163 4164 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4165 mWiFiNetworkAgent.setNetworkSpecifier(new ConfidentialMatchAllNetworkSpecifier()); 4166 mWiFiNetworkAgent.connect(false); 4167 expectAvailableCallbacksUnvalidatedWithSpecifier(mWiFiNetworkAgent, null /* specifier */, 4168 cEmpty1, cEmpty2, cEmpty3, cEmpty4, cFoo, cBar); 4169 assertNull( 4170 mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).getNetworkSpecifier()); 4171 4172 mWiFiNetworkAgent.disconnect(); 4173 expectOnLost(mWiFiNetworkAgent, cEmpty1, cEmpty2, cEmpty3, cEmpty4, cFoo, cBar); 4174 } 4175 4176 /** 4177 * @return the context's attribution tag 4178 */ 4179 private String getAttributionTag() { 4180 return mContext.getAttributionTag(); 4181 } 4182 4183 @Test 4184 public void testInvalidNetworkSpecifier() { 4185 assertThrows(IllegalArgumentException.class, () -> { 4186 NetworkRequest.Builder builder = new NetworkRequest.Builder(); 4187 builder.setNetworkSpecifier(new MatchAllNetworkSpecifier()); 4188 }); 4189 4190 assertThrows(IllegalArgumentException.class, () -> { 4191 NetworkCapabilities networkCapabilities = new NetworkCapabilities(); 4192 networkCapabilities.addTransportType(TRANSPORT_WIFI) 4193 .setNetworkSpecifier(new MatchAllNetworkSpecifier()); 4194 mService.requestNetwork(Process.INVALID_UID, networkCapabilities, 4195 NetworkRequest.Type.REQUEST.ordinal(), null, 0, null, 4196 ConnectivityManager.TYPE_WIFI, NetworkCallback.FLAG_NONE, 4197 mContext.getPackageName(), getAttributionTag()); 4198 }); 4199 4200 class NonParcelableSpecifier extends NetworkSpecifier { 4201 @Override 4202 public boolean canBeSatisfiedBy(NetworkSpecifier other) { 4203 return false; 4204 } 4205 }; 4206 class ParcelableSpecifier extends NonParcelableSpecifier implements Parcelable { 4207 @Override public int describeContents() { return 0; } 4208 @Override public void writeToParcel(Parcel p, int flags) {} 4209 } 4210 4211 final NetworkRequest.Builder builder = 4212 new NetworkRequest.Builder().addTransportType(TRANSPORT_ETHERNET); 4213 assertThrows(ClassCastException.class, () -> { 4214 builder.setNetworkSpecifier(new NonParcelableSpecifier()); 4215 Parcel parcelW = Parcel.obtain(); 4216 builder.build().writeToParcel(parcelW, 0); 4217 }); 4218 4219 final NetworkRequest nr = 4220 new NetworkRequest.Builder().addTransportType(TRANSPORT_ETHERNET) 4221 .setNetworkSpecifier(new ParcelableSpecifier()) 4222 .build(); 4223 assertNotNull(nr); 4224 4225 assertThrows(BadParcelableException.class, () -> { 4226 Parcel parcelW = Parcel.obtain(); 4227 nr.writeToParcel(parcelW, 0); 4228 byte[] bytes = parcelW.marshall(); 4229 parcelW.recycle(); 4230 4231 Parcel parcelR = Parcel.obtain(); 4232 parcelR.unmarshall(bytes, 0, bytes.length); 4233 parcelR.setDataPosition(0); 4234 NetworkRequest rereadNr = NetworkRequest.CREATOR.createFromParcel(parcelR); 4235 }); 4236 } 4237 4238 @Test 4239 public void testNetworkRequestUidSpoofSecurityException() throws Exception { 4240 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4241 mWiFiNetworkAgent.connect(false); 4242 NetworkRequest networkRequest = newWifiRequestBuilder().build(); 4243 TestNetworkCallback networkCallback = new TestNetworkCallback(); 4244 doThrow(new SecurityException()).when(mAppOpsManager).checkPackage(anyInt(), anyString()); 4245 assertThrows(SecurityException.class, () -> { 4246 mCm.requestNetwork(networkRequest, networkCallback); 4247 }); 4248 } 4249 4250 @Test 4251 public void testInvalidSignalStrength() { 4252 NetworkRequest r = new NetworkRequest.Builder() 4253 .addCapability(NET_CAPABILITY_INTERNET) 4254 .addTransportType(TRANSPORT_WIFI) 4255 .setSignalStrength(-75) 4256 .build(); 4257 // Registering a NetworkCallback with signal strength but w/o NETWORK_SIGNAL_STRENGTH_WAKEUP 4258 // permission should get SecurityException. 4259 assertThrows(SecurityException.class, () -> 4260 mCm.registerNetworkCallback(r, new NetworkCallback())); 4261 4262 assertThrows(SecurityException.class, () -> 4263 mCm.registerNetworkCallback(r, PendingIntent.getService( 4264 mServiceContext, 0 /* requestCode */, new Intent(), FLAG_IMMUTABLE))); 4265 4266 // Requesting a Network with signal strength should get IllegalArgumentException. 4267 assertThrows(IllegalArgumentException.class, () -> 4268 mCm.requestNetwork(r, new NetworkCallback())); 4269 4270 assertThrows(IllegalArgumentException.class, () -> 4271 mCm.requestNetwork(r, PendingIntent.getService( 4272 mServiceContext, 0 /* requestCode */, new Intent(), FLAG_IMMUTABLE))); 4273 } 4274 4275 @Test 4276 public void testRegisterDefaultNetworkCallback() throws Exception { 4277 // NETWORK_SETTINGS is necessary to call registerSystemDefaultNetworkCallback. 4278 mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_GRANTED); 4279 4280 final TestNetworkCallback defaultNetworkCallback = new TestNetworkCallback(); 4281 mCm.registerDefaultNetworkCallback(defaultNetworkCallback); 4282 defaultNetworkCallback.assertNoCallback(); 4283 4284 final Handler handler = new Handler(ConnectivityThread.getInstanceLooper()); 4285 final TestNetworkCallback systemDefaultCallback = new TestNetworkCallback(); 4286 mCm.registerSystemDefaultNetworkCallback(systemDefaultCallback, handler); 4287 systemDefaultCallback.assertNoCallback(); 4288 4289 // Create a TRANSPORT_CELLULAR request to keep the mobile interface up 4290 // whenever Wi-Fi is up. Without this, the mobile network agent is 4291 // reaped before any other activity can take place. 4292 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback(); 4293 final NetworkRequest cellRequest = new NetworkRequest.Builder() 4294 .addTransportType(TRANSPORT_CELLULAR).build(); 4295 mCm.requestNetwork(cellRequest, cellNetworkCallback); 4296 cellNetworkCallback.assertNoCallback(); 4297 4298 // Bring up cell and expect CALLBACK_AVAILABLE. 4299 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 4300 mCellNetworkAgent.connect(true); 4301 cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 4302 defaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 4303 systemDefaultCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 4304 assertEquals(defaultNetworkCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 4305 assertEquals(systemDefaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 4306 4307 // Bring up wifi and expect CALLBACK_AVAILABLE. 4308 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4309 mWiFiNetworkAgent.connect(true); 4310 cellNetworkCallback.assertNoCallback(); 4311 defaultNetworkCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent); 4312 systemDefaultCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent); 4313 assertEquals(defaultNetworkCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 4314 assertEquals(systemDefaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 4315 4316 // Bring down cell. Expect no default network callback, since it wasn't the default. 4317 mCellNetworkAgent.disconnect(); 4318 cellNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 4319 defaultNetworkCallback.assertNoCallback(); 4320 systemDefaultCallback.assertNoCallback(); 4321 assertEquals(defaultNetworkCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 4322 assertEquals(systemDefaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 4323 4324 // Bring up cell. Expect no default network callback, since it won't be the default. 4325 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 4326 mCellNetworkAgent.connect(true); 4327 cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 4328 defaultNetworkCallback.assertNoCallback(); 4329 systemDefaultCallback.assertNoCallback(); 4330 assertEquals(defaultNetworkCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 4331 assertEquals(systemDefaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 4332 4333 // Bring down wifi. Expect the default network callback to notified of LOST wifi 4334 // followed by AVAILABLE cell. 4335 mWiFiNetworkAgent.disconnect(); 4336 cellNetworkCallback.assertNoCallback(); 4337 defaultNetworkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 4338 defaultNetworkCallback.expectAvailableCallbacksValidated(mCellNetworkAgent); 4339 systemDefaultCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 4340 systemDefaultCallback.expectAvailableCallbacksValidated(mCellNetworkAgent); 4341 mCellNetworkAgent.disconnect(); 4342 cellNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 4343 defaultNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 4344 systemDefaultCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 4345 waitForIdle(); 4346 assertEquals(null, mCm.getActiveNetwork()); 4347 4348 mMockVpn.establishForMyUid(); 4349 assertUidRangesUpdatedForMyUid(true); 4350 defaultNetworkCallback.expectAvailableThenValidatedCallbacks(mMockVpn); 4351 systemDefaultCallback.assertNoCallback(); 4352 assertEquals(defaultNetworkCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 4353 assertEquals(null, systemDefaultCallback.getLastAvailableNetwork()); 4354 4355 mMockVpn.disconnect(); 4356 defaultNetworkCallback.expectCallback(CallbackEntry.LOST, mMockVpn); 4357 systemDefaultCallback.assertNoCallback(); 4358 waitForIdle(); 4359 assertEquals(null, mCm.getActiveNetwork()); 4360 } 4361 4362 @Test 4363 public void testAdditionalStateCallbacks() throws Exception { 4364 // File a network request for mobile. 4365 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback(); 4366 final NetworkRequest cellRequest = new NetworkRequest.Builder() 4367 .addTransportType(TRANSPORT_CELLULAR).build(); 4368 mCm.requestNetwork(cellRequest, cellNetworkCallback); 4369 4370 // Bring up the mobile network. 4371 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 4372 mCellNetworkAgent.connect(true); 4373 4374 // We should get onAvailable(), onCapabilitiesChanged(), and 4375 // onLinkPropertiesChanged() in rapid succession. Additionally, we 4376 // should get onCapabilitiesChanged() when the mobile network validates. 4377 cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 4378 cellNetworkCallback.assertNoCallback(); 4379 4380 // Update LinkProperties. 4381 final LinkProperties lp = new LinkProperties(); 4382 lp.setInterfaceName("foonet_data0"); 4383 mCellNetworkAgent.sendLinkProperties(lp); 4384 // We should get onLinkPropertiesChanged(). 4385 cellNetworkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, 4386 mCellNetworkAgent); 4387 cellNetworkCallback.assertNoCallback(); 4388 4389 // Suspend the network. 4390 mCellNetworkAgent.suspend(); 4391 cellNetworkCallback.expectCapabilitiesWithout(NET_CAPABILITY_NOT_SUSPENDED, 4392 mCellNetworkAgent); 4393 cellNetworkCallback.expectCallback(CallbackEntry.SUSPENDED, mCellNetworkAgent); 4394 cellNetworkCallback.assertNoCallback(); 4395 assertEquals(NetworkInfo.State.SUSPENDED, mCm.getActiveNetworkInfo().getState()); 4396 4397 // Register a garden variety default network request. 4398 TestNetworkCallback dfltNetworkCallback = new TestNetworkCallback(); 4399 mCm.registerDefaultNetworkCallback(dfltNetworkCallback); 4400 // We should get onAvailable(), onCapabilitiesChanged(), onLinkPropertiesChanged(), 4401 // as well as onNetworkSuspended() in rapid succession. 4402 dfltNetworkCallback.expectAvailableAndSuspendedCallbacks(mCellNetworkAgent, true); 4403 dfltNetworkCallback.assertNoCallback(); 4404 mCm.unregisterNetworkCallback(dfltNetworkCallback); 4405 4406 mCellNetworkAgent.resume(); 4407 cellNetworkCallback.expectCapabilitiesWith(NET_CAPABILITY_NOT_SUSPENDED, 4408 mCellNetworkAgent); 4409 cellNetworkCallback.expectCallback(CallbackEntry.RESUMED, mCellNetworkAgent); 4410 cellNetworkCallback.assertNoCallback(); 4411 assertEquals(NetworkInfo.State.CONNECTED, mCm.getActiveNetworkInfo().getState()); 4412 4413 dfltNetworkCallback = new TestNetworkCallback(); 4414 mCm.registerDefaultNetworkCallback(dfltNetworkCallback); 4415 // This time onNetworkSuspended should not be called. 4416 dfltNetworkCallback.expectAvailableCallbacksValidated(mCellNetworkAgent); 4417 dfltNetworkCallback.assertNoCallback(); 4418 4419 mCm.unregisterNetworkCallback(dfltNetworkCallback); 4420 mCm.unregisterNetworkCallback(cellNetworkCallback); 4421 } 4422 4423 @Test 4424 public void testRegisterPrivilegedDefaultCallbacksRequireNetworkSettings() throws Exception { 4425 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 4426 mCellNetworkAgent.connect(false /* validated */); 4427 4428 final Handler handler = new Handler(ConnectivityThread.getInstanceLooper()); 4429 final TestNetworkCallback callback = new TestNetworkCallback(); 4430 assertThrows(SecurityException.class, 4431 () -> mCm.registerSystemDefaultNetworkCallback(callback, handler)); 4432 callback.assertNoCallback(); 4433 assertThrows(SecurityException.class, 4434 () -> mCm.registerDefaultNetworkCallbackForUid(APP1_UID, callback, handler)); 4435 callback.assertNoCallback(); 4436 4437 mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_GRANTED); 4438 mCm.registerSystemDefaultNetworkCallback(callback, handler); 4439 callback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent); 4440 mCm.unregisterNetworkCallback(callback); 4441 4442 mCm.registerDefaultNetworkCallbackForUid(APP1_UID, callback, handler); 4443 callback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent); 4444 mCm.unregisterNetworkCallback(callback); 4445 } 4446 4447 @Test 4448 public void testNetworkCallbackWithNullUids() throws Exception { 4449 final NetworkRequest request = new NetworkRequest.Builder() 4450 .removeCapability(NET_CAPABILITY_NOT_VPN) 4451 .build(); 4452 final TestNetworkCallback callback = new TestNetworkCallback(); 4453 mCm.registerNetworkCallback(request, callback); 4454 4455 // Attempt to file a callback for networks applying to another UID. This does not actually 4456 // work, because this code does not currently have permission to do so. The callback behaves 4457 // exactly the same as the one registered just above. 4458 final int otherUid = UserHandle.getUid(RESTRICTED_USER, VPN_UID); 4459 final NetworkRequest otherUidRequest = new NetworkRequest.Builder() 4460 .removeCapability(NET_CAPABILITY_NOT_VPN) 4461 .setUids(UidRange.toIntRanges(uidRangesForUids(otherUid))) 4462 .build(); 4463 final TestNetworkCallback otherUidCallback = new TestNetworkCallback(); 4464 mCm.registerNetworkCallback(otherUidRequest, otherUidCallback); 4465 4466 final NetworkRequest includeOtherUidsRequest = new NetworkRequest.Builder() 4467 .removeCapability(NET_CAPABILITY_NOT_VPN) 4468 .setIncludeOtherUidNetworks(true) 4469 .build(); 4470 final TestNetworkCallback includeOtherUidsCallback = new TestNetworkCallback(); 4471 mCm.registerNetworkCallback(includeOtherUidsRequest, includeOtherUidsCallback); 4472 4473 // Both callbacks see a network with no specifier that applies to their UID. 4474 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4475 mWiFiNetworkAgent.connect(false /* validated */); 4476 callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 4477 otherUidCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 4478 includeOtherUidsCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 4479 mWiFiNetworkAgent.disconnect(); 4480 callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 4481 otherUidCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 4482 includeOtherUidsCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 4483 4484 // Only the includeOtherUidsCallback sees a VPN that does not apply to its UID. 4485 final UidRange range = UidRange.createForUser(UserHandle.of(RESTRICTED_USER)); 4486 final Set<UidRange> vpnRanges = Collections.singleton(range); 4487 mMockVpn.establish(new LinkProperties(), VPN_UID, vpnRanges); 4488 includeOtherUidsCallback.expectAvailableThenValidatedCallbacks(mMockVpn); 4489 callback.assertNoCallback(); 4490 otherUidCallback.assertNoCallback(); 4491 4492 mMockVpn.disconnect(); 4493 includeOtherUidsCallback.expectCallback(CallbackEntry.LOST, mMockVpn); 4494 callback.assertNoCallback(); 4495 otherUidCallback.assertNoCallback(); 4496 } 4497 4498 private static class RedactableNetworkSpecifier extends NetworkSpecifier { 4499 public static final int ID_INVALID = -1; 4500 4501 public final int networkId; 4502 4503 RedactableNetworkSpecifier(int networkId) { 4504 this.networkId = networkId; 4505 } 4506 4507 @Override 4508 public boolean canBeSatisfiedBy(NetworkSpecifier other) { 4509 return other instanceof RedactableNetworkSpecifier 4510 && this.networkId == ((RedactableNetworkSpecifier) other).networkId; 4511 } 4512 4513 @Override 4514 public NetworkSpecifier redact() { 4515 return new RedactableNetworkSpecifier(ID_INVALID); 4516 } 4517 } 4518 4519 @Test 4520 public void testNetworkCallbackWithNullUidsRedactsSpecifier() throws Exception { 4521 final RedactableNetworkSpecifier specifier = new RedactableNetworkSpecifier(42); 4522 final NetworkRequest request = new NetworkRequest.Builder() 4523 .addCapability(NET_CAPABILITY_INTERNET) 4524 .addTransportType(TRANSPORT_WIFI) 4525 .setNetworkSpecifier(specifier) 4526 .build(); 4527 final TestNetworkCallback callback = new TestNetworkCallback(); 4528 mCm.registerNetworkCallback(request, callback); 4529 4530 // Attempt to file a callback for networks applying to another UID. This does not actually 4531 // work, because this code does not currently have permission to do so. The callback behaves 4532 // exactly the same as the one registered just above. 4533 final int otherUid = UserHandle.getUid(RESTRICTED_USER, VPN_UID); 4534 final NetworkRequest otherUidRequest = new NetworkRequest.Builder() 4535 .addCapability(NET_CAPABILITY_INTERNET) 4536 .addTransportType(TRANSPORT_WIFI) 4537 .setNetworkSpecifier(specifier) 4538 .setUids(UidRange.toIntRanges(uidRangesForUids(otherUid))) 4539 .build(); 4540 final TestNetworkCallback otherUidCallback = new TestNetworkCallback(); 4541 mCm.registerNetworkCallback(otherUidRequest, otherUidCallback); 4542 4543 final NetworkRequest includeOtherUidsRequest = new NetworkRequest.Builder() 4544 .addCapability(NET_CAPABILITY_INTERNET) 4545 .addTransportType(TRANSPORT_WIFI) 4546 .setNetworkSpecifier(specifier) 4547 .setIncludeOtherUidNetworks(true) 4548 .build(); 4549 final TestNetworkCallback includeOtherUidsCallback = new TestNetworkCallback(); 4550 mCm.registerNetworkCallback(includeOtherUidsRequest, callback); 4551 4552 // Only the regular callback sees the network, because callbacks filed with no UID have 4553 // their specifiers redacted. 4554 final LinkProperties emptyLp = new LinkProperties(); 4555 final NetworkCapabilities ncTemplate = new NetworkCapabilities() 4556 .addTransportType(TRANSPORT_WIFI) 4557 .setNetworkSpecifier(specifier); 4558 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, emptyLp, ncTemplate); 4559 mWiFiNetworkAgent.connect(false /* validated */); 4560 callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 4561 otherUidCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 4562 includeOtherUidsCallback.assertNoCallback(); 4563 } 4564 4565 private void setCaptivePortalMode(int mode) { 4566 ContentResolver cr = mServiceContext.getContentResolver(); 4567 Settings.Global.putInt(cr, ConnectivitySettingsManager.CAPTIVE_PORTAL_MODE, mode); 4568 } 4569 4570 private void setAlwaysOnNetworks(boolean enable) { 4571 ContentResolver cr = mServiceContext.getContentResolver(); 4572 Settings.Global.putInt(cr, ConnectivitySettingsManager.MOBILE_DATA_ALWAYS_ON, 4573 enable ? 1 : 0); 4574 mService.updateAlwaysOnNetworks(); 4575 waitForIdle(); 4576 } 4577 4578 private void setPrivateDnsSettings(int mode, String specifier) { 4579 ConnectivitySettingsManager.setPrivateDnsMode(mServiceContext, mode); 4580 ConnectivitySettingsManager.setPrivateDnsHostname(mServiceContext, specifier); 4581 mService.updatePrivateDnsSettings(); 4582 waitForIdle(); 4583 } 4584 4585 private boolean isForegroundNetwork(TestNetworkAgentWrapper network) { 4586 NetworkCapabilities nc = mCm.getNetworkCapabilities(network.getNetwork()); 4587 assertNotNull(nc); 4588 return nc.hasCapability(NET_CAPABILITY_FOREGROUND); 4589 } 4590 4591 @Test 4592 public void testBackgroundNetworks() throws Exception { 4593 // Create a cellular background request. 4594 grantUsingBackgroundNetworksPermissionForUid(Binder.getCallingUid()); 4595 final TestNetworkCallback cellBgCallback = new TestNetworkCallback(); 4596 mCm.requestBackgroundNetwork(new NetworkRequest.Builder() 4597 .addTransportType(TRANSPORT_CELLULAR).build(), 4598 cellBgCallback, mCsHandlerThread.getThreadHandler()); 4599 4600 // Make callbacks for monitoring. 4601 final NetworkRequest request = new NetworkRequest.Builder().build(); 4602 final NetworkRequest fgRequest = new NetworkRequest.Builder() 4603 .addCapability(NET_CAPABILITY_FOREGROUND).build(); 4604 final TestNetworkCallback callback = new TestNetworkCallback(); 4605 final TestNetworkCallback fgCallback = new TestNetworkCallback(); 4606 mCm.registerNetworkCallback(request, callback); 4607 mCm.registerNetworkCallback(fgRequest, fgCallback); 4608 4609 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 4610 mCellNetworkAgent.connect(true); 4611 callback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 4612 fgCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 4613 assertTrue(isForegroundNetwork(mCellNetworkAgent)); 4614 4615 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4616 mWiFiNetworkAgent.connect(true); 4617 4618 // When wifi connects, cell lingers. 4619 callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 4620 callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent); 4621 callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent); 4622 fgCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 4623 fgCallback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent); 4624 fgCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent); 4625 assertTrue(isForegroundNetwork(mCellNetworkAgent)); 4626 assertTrue(isForegroundNetwork(mWiFiNetworkAgent)); 4627 4628 // When lingering is complete, cell is still there but is now in the background. 4629 waitForIdle(); 4630 int timeoutMs = TEST_LINGER_DELAY_MS + TEST_LINGER_DELAY_MS / 4; 4631 fgCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent, timeoutMs); 4632 // Expect a network capabilities update sans FOREGROUND. 4633 callback.expectCapabilitiesWithout(NET_CAPABILITY_FOREGROUND, mCellNetworkAgent); 4634 assertFalse(isForegroundNetwork(mCellNetworkAgent)); 4635 assertTrue(isForegroundNetwork(mWiFiNetworkAgent)); 4636 4637 // File a cell request and check that cell comes into the foreground. 4638 final NetworkRequest cellRequest = new NetworkRequest.Builder() 4639 .addTransportType(TRANSPORT_CELLULAR).build(); 4640 final TestNetworkCallback cellCallback = new TestNetworkCallback(); 4641 mCm.requestNetwork(cellRequest, cellCallback); 4642 cellCallback.expectAvailableCallbacksValidated(mCellNetworkAgent); 4643 fgCallback.expectAvailableCallbacksValidated(mCellNetworkAgent); 4644 // Expect a network capabilities update with FOREGROUND, because the most recent 4645 // request causes its state to change. 4646 cellCallback.expectCapabilitiesWith(NET_CAPABILITY_FOREGROUND, mCellNetworkAgent); 4647 callback.expectCapabilitiesWith(NET_CAPABILITY_FOREGROUND, mCellNetworkAgent); 4648 assertTrue(isForegroundNetwork(mCellNetworkAgent)); 4649 assertTrue(isForegroundNetwork(mWiFiNetworkAgent)); 4650 4651 // Release the request. The network immediately goes into the background, since it was not 4652 // lingering. 4653 mCm.unregisterNetworkCallback(cellCallback); 4654 fgCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 4655 // Expect a network capabilities update sans FOREGROUND. 4656 callback.expectCapabilitiesWithout(NET_CAPABILITY_FOREGROUND, mCellNetworkAgent); 4657 assertFalse(isForegroundNetwork(mCellNetworkAgent)); 4658 assertTrue(isForegroundNetwork(mWiFiNetworkAgent)); 4659 4660 // Disconnect wifi and check that cell is foreground again. 4661 mWiFiNetworkAgent.disconnect(); 4662 callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 4663 fgCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 4664 fgCallback.expectAvailableCallbacksValidated(mCellNetworkAgent); 4665 assertTrue(isForegroundNetwork(mCellNetworkAgent)); 4666 4667 mCm.unregisterNetworkCallback(callback); 4668 mCm.unregisterNetworkCallback(fgCallback); 4669 mCm.unregisterNetworkCallback(cellBgCallback); 4670 } 4671 4672 @Ignore // This test has instrinsic chances of spurious failures: ignore for continuous testing. 4673 public void benchmarkRequestRegistrationAndCallbackDispatch() throws Exception { 4674 // TODO: turn this unit test into a real benchmarking test. 4675 // Benchmarks connecting and switching performance in the presence of a large number of 4676 // NetworkRequests. 4677 // 1. File NUM_REQUESTS requests. 4678 // 2. Have a network connect. Wait for NUM_REQUESTS onAvailable callbacks to fire. 4679 // 3. Have a new network connect and outscore the previous. Wait for NUM_REQUESTS onLosing 4680 // and NUM_REQUESTS onAvailable callbacks to fire. 4681 // See how long it took. 4682 final int NUM_REQUESTS = 90; 4683 final int REGISTER_TIME_LIMIT_MS = 200; 4684 final int CONNECT_TIME_LIMIT_MS = 60; 4685 final int SWITCH_TIME_LIMIT_MS = 60; 4686 final int UNREGISTER_TIME_LIMIT_MS = 20; 4687 4688 final NetworkRequest request = new NetworkRequest.Builder().clearCapabilities().build(); 4689 final NetworkCallback[] callbacks = new NetworkCallback[NUM_REQUESTS]; 4690 final CountDownLatch availableLatch = new CountDownLatch(NUM_REQUESTS); 4691 final CountDownLatch losingLatch = new CountDownLatch(NUM_REQUESTS); 4692 4693 for (int i = 0; i < NUM_REQUESTS; i++) { 4694 callbacks[i] = new NetworkCallback() { 4695 @Override public void onAvailable(Network n) { availableLatch.countDown(); } 4696 @Override public void onLosing(Network n, int t) { losingLatch.countDown(); } 4697 }; 4698 } 4699 4700 assertRunsInAtMost("Registering callbacks", REGISTER_TIME_LIMIT_MS, () -> { 4701 for (NetworkCallback cb : callbacks) { 4702 mCm.registerNetworkCallback(request, cb); 4703 } 4704 }); 4705 4706 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 4707 // Don't request that the network validate, because otherwise connect() will block until 4708 // the network gets NET_CAPABILITY_VALIDATED, after all the callbacks below have fired, 4709 // and we won't actually measure anything. 4710 mCellNetworkAgent.connect(false); 4711 4712 long onAvailableDispatchingDuration = durationOf(() -> { 4713 await(availableLatch, 10 * CONNECT_TIME_LIMIT_MS); 4714 }); 4715 Log.d(TAG, String.format("Dispatched %d of %d onAvailable callbacks in %dms", 4716 NUM_REQUESTS - availableLatch.getCount(), NUM_REQUESTS, 4717 onAvailableDispatchingDuration)); 4718 assertTrue(String.format("Dispatching %d onAvailable callbacks in %dms, expected %dms", 4719 NUM_REQUESTS, onAvailableDispatchingDuration, CONNECT_TIME_LIMIT_MS), 4720 onAvailableDispatchingDuration <= CONNECT_TIME_LIMIT_MS); 4721 4722 // Give wifi a high enough score that we'll linger cell when wifi comes up. 4723 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4724 mWiFiNetworkAgent.adjustScore(40); 4725 mWiFiNetworkAgent.connect(false); 4726 4727 long onLostDispatchingDuration = durationOf(() -> { 4728 await(losingLatch, 10 * SWITCH_TIME_LIMIT_MS); 4729 }); 4730 Log.d(TAG, String.format("Dispatched %d of %d onLosing callbacks in %dms", 4731 NUM_REQUESTS - losingLatch.getCount(), NUM_REQUESTS, onLostDispatchingDuration)); 4732 assertTrue(String.format("Dispatching %d onLosing callbacks in %dms, expected %dms", 4733 NUM_REQUESTS, onLostDispatchingDuration, SWITCH_TIME_LIMIT_MS), 4734 onLostDispatchingDuration <= SWITCH_TIME_LIMIT_MS); 4735 4736 assertRunsInAtMost("Unregistering callbacks", UNREGISTER_TIME_LIMIT_MS, () -> { 4737 for (NetworkCallback cb : callbacks) { 4738 mCm.unregisterNetworkCallback(cb); 4739 } 4740 }); 4741 } 4742 4743 @Test 4744 public void testMobileDataAlwaysOn() throws Exception { 4745 grantUsingBackgroundNetworksPermissionForUid(Binder.getCallingUid()); 4746 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback(); 4747 final NetworkRequest cellRequest = new NetworkRequest.Builder() 4748 .addTransportType(TRANSPORT_CELLULAR).build(); 4749 mCm.registerNetworkCallback(cellRequest, cellNetworkCallback); 4750 4751 final HandlerThread handlerThread = new HandlerThread("MobileDataAlwaysOnFactory"); 4752 handlerThread.start(); 4753 NetworkCapabilities filter = new NetworkCapabilities() 4754 .addTransportType(TRANSPORT_CELLULAR) 4755 .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED) 4756 .addCapability(NET_CAPABILITY_INTERNET); 4757 final MockNetworkFactory testFactory = new MockNetworkFactory(handlerThread.getLooper(), 4758 mServiceContext, "testFactory", filter, mCsHandlerThread); 4759 testFactory.setScoreFilter(40); 4760 4761 // Register the factory and expect it to start looking for a network. 4762 testFactory.register(); 4763 4764 try { 4765 // Expect the factory to receive the default network request. 4766 testFactory.expectRequestAdd(); 4767 testFactory.assertRequestCountEquals(1); 4768 assertTrue(testFactory.getMyStartRequested()); 4769 4770 // Bring up wifi. The factory stops looking for a network. 4771 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4772 // Score 60 - 40 penalty for not validated yet, then 60 when it validates 4773 mWiFiNetworkAgent.connect(true); 4774 // The network connects with a low score, so the offer can still beat it and 4775 // nothing happens. Then the network validates, and the offer with its filter score 4776 // of 40 can no longer beat it and the request is removed. 4777 testFactory.expectRequestRemove(); 4778 testFactory.assertRequestCountEquals(0); 4779 4780 assertFalse(testFactory.getMyStartRequested()); 4781 4782 // Turn on mobile data always on. This request will not match the wifi request, so 4783 // it will be sent to the test factory whose filters allow to see it. 4784 setAlwaysOnNetworks(true); 4785 testFactory.expectRequestAdd(); 4786 testFactory.assertRequestCountEquals(1); 4787 4788 assertTrue(testFactory.getMyStartRequested()); 4789 4790 // Bring up cell data and check that the factory stops looking. 4791 assertLength(1, mCm.getAllNetworks()); 4792 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 4793 mCellNetworkAgent.connect(false); 4794 cellNetworkCallback.expectAvailableCallbacks(mCellNetworkAgent, false, false, false, 4795 TEST_CALLBACK_TIMEOUT_MS); 4796 // When cell connects, it will satisfy the "mobile always on request" right away 4797 // by virtue of being the only network that can satisfy the request. However, its 4798 // score is low (50 - 40 = 10) so the test factory can still hope to beat it. 4799 expectNoRequestChanged(testFactory); 4800 4801 // Next, cell validates. This gives it a score of 50 and the test factory can't 4802 // hope to beat that according to its filters. It will see the message that its 4803 // offer is now unnecessary. 4804 mCellNetworkAgent.setNetworkValid(true); 4805 // Need a trigger point to let NetworkMonitor tell ConnectivityService that network is 4806 // validated – see testPartialConnectivity. 4807 mCm.reportNetworkConnectivity(mCellNetworkAgent.getNetwork(), true); 4808 cellNetworkCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mCellNetworkAgent); 4809 testFactory.expectRequestRemove(); 4810 testFactory.assertRequestCountEquals(0); 4811 // Accordingly, the factory shouldn't be started. 4812 assertFalse(testFactory.getMyStartRequested()); 4813 4814 // Check that cell data stays up. 4815 waitForIdle(); 4816 verifyActiveNetwork(TRANSPORT_WIFI); 4817 assertLength(2, mCm.getAllNetworks()); 4818 4819 // Cell disconnects. There is still the "mobile data always on" request outstanding, 4820 // and the test factory should see it now that it isn't hopelessly outscored. 4821 mCellNetworkAgent.disconnect(); 4822 cellNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 4823 assertLength(1, mCm.getAllNetworks()); 4824 testFactory.expectRequestAdd(); 4825 testFactory.assertRequestCountEquals(1); 4826 4827 // Reconnect cell validated, see the request disappear again. Then withdraw the 4828 // mobile always on request. This will tear down cell, and there shouldn't be a 4829 // blip where the test factory briefly sees the request or anything. 4830 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 4831 mCellNetworkAgent.connect(true); 4832 cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 4833 assertLength(2, mCm.getAllNetworks()); 4834 testFactory.expectRequestRemove(); 4835 testFactory.assertRequestCountEquals(0); 4836 setAlwaysOnNetworks(false); 4837 expectNoRequestChanged(testFactory); 4838 testFactory.assertRequestCountEquals(0); 4839 assertFalse(testFactory.getMyStartRequested()); 4840 // ... and cell data to be torn down immediately since it is no longer nascent. 4841 cellNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 4842 waitForIdle(); 4843 assertLength(1, mCm.getAllNetworks()); 4844 } finally { 4845 testFactory.terminate(); 4846 mCm.unregisterNetworkCallback(cellNetworkCallback); 4847 handlerThread.quit(); 4848 } 4849 } 4850 4851 @Test 4852 public void testSetAllowBadWifiUntil() throws Exception { 4853 runAsShell(NETWORK_SETTINGS, 4854 () -> mService.setTestAllowBadWifiUntil(System.currentTimeMillis() + 5_000L)); 4855 waitForIdle(); 4856 testAvoidBadWifiConfig_controlledBySettings(); 4857 4858 runAsShell(NETWORK_SETTINGS, 4859 () -> mService.setTestAllowBadWifiUntil(System.currentTimeMillis() - 5_000L)); 4860 waitForIdle(); 4861 testAvoidBadWifiConfig_ignoreSettings(); 4862 } 4863 4864 private void testAvoidBadWifiConfig_controlledBySettings() { 4865 final ContentResolver cr = mServiceContext.getContentResolver(); 4866 final String settingName = ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI; 4867 4868 Settings.Global.putString(cr, settingName, "0"); 4869 mPolicyTracker.reevaluate(); 4870 waitForIdle(); 4871 assertFalse(mService.avoidBadWifi()); 4872 assertFalse(mPolicyTracker.shouldNotifyWifiUnvalidated()); 4873 4874 Settings.Global.putString(cr, settingName, "1"); 4875 mPolicyTracker.reevaluate(); 4876 waitForIdle(); 4877 assertTrue(mService.avoidBadWifi()); 4878 assertFalse(mPolicyTracker.shouldNotifyWifiUnvalidated()); 4879 4880 Settings.Global.putString(cr, settingName, null); 4881 mPolicyTracker.reevaluate(); 4882 waitForIdle(); 4883 assertFalse(mService.avoidBadWifi()); 4884 assertTrue(mPolicyTracker.shouldNotifyWifiUnvalidated()); 4885 } 4886 4887 private void testAvoidBadWifiConfig_ignoreSettings() { 4888 final ContentResolver cr = mServiceContext.getContentResolver(); 4889 final String settingName = ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI; 4890 4891 String[] values = new String[] {null, "0", "1"}; 4892 for (int i = 0; i < values.length; i++) { 4893 Settings.Global.putString(cr, settingName, values[i]); 4894 mPolicyTracker.reevaluate(); 4895 waitForIdle(); 4896 String msg = String.format("config=false, setting=%s", values[i]); 4897 assertTrue(mService.avoidBadWifi()); 4898 assertFalse(msg, mPolicyTracker.shouldNotifyWifiUnvalidated()); 4899 } 4900 } 4901 4902 @Test 4903 public void testAvoidBadWifiSetting() throws Exception { 4904 final ContentResolver cr = mServiceContext.getContentResolver(); 4905 final String settingName = ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI; 4906 4907 doReturn(1).when(mResources).getInteger(R.integer.config_networkAvoidBadWifi); 4908 testAvoidBadWifiConfig_ignoreSettings(); 4909 4910 doReturn(0).when(mResources).getInteger(R.integer.config_networkAvoidBadWifi); 4911 testAvoidBadWifiConfig_controlledBySettings(); 4912 } 4913 4914 @Ignore("Refactoring in progress b/178071397") 4915 @Test 4916 public void testAvoidBadWifi() throws Exception { 4917 final ContentResolver cr = mServiceContext.getContentResolver(); 4918 4919 // Pretend we're on a carrier that restricts switching away from bad wifi. 4920 doReturn(0).when(mResources).getInteger(R.integer.config_networkAvoidBadWifi); 4921 4922 // File a request for cell to ensure it doesn't go down. 4923 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback(); 4924 final NetworkRequest cellRequest = new NetworkRequest.Builder() 4925 .addTransportType(TRANSPORT_CELLULAR).build(); 4926 mCm.requestNetwork(cellRequest, cellNetworkCallback); 4927 4928 TestNetworkCallback defaultCallback = new TestNetworkCallback(); 4929 mCm.registerDefaultNetworkCallback(defaultCallback); 4930 4931 NetworkRequest validatedWifiRequest = new NetworkRequest.Builder() 4932 .addTransportType(TRANSPORT_WIFI) 4933 .addCapability(NET_CAPABILITY_VALIDATED) 4934 .build(); 4935 TestNetworkCallback validatedWifiCallback = new TestNetworkCallback(); 4936 mCm.registerNetworkCallback(validatedWifiRequest, validatedWifiCallback); 4937 4938 Settings.Global.putInt(cr, ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI, 0); 4939 mPolicyTracker.reevaluate(); 4940 4941 // Bring up validated cell. 4942 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 4943 mCellNetworkAgent.connect(true); 4944 cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 4945 defaultCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 4946 Network cellNetwork = mCellNetworkAgent.getNetwork(); 4947 4948 // Bring up validated wifi. 4949 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4950 mWiFiNetworkAgent.connect(true); 4951 defaultCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent); 4952 validatedWifiCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent); 4953 Network wifiNetwork = mWiFiNetworkAgent.getNetwork(); 4954 4955 // Fail validation on wifi. 4956 mWiFiNetworkAgent.setNetworkInvalid(false /* isStrictMode */); 4957 mCm.reportNetworkConnectivity(wifiNetwork, false); 4958 defaultCallback.expectCapabilitiesWithout(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent); 4959 validatedWifiCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 4960 4961 // Because avoid bad wifi is off, we don't switch to cellular. 4962 defaultCallback.assertNoCallback(); 4963 assertFalse(mCm.getNetworkCapabilities(wifiNetwork).hasCapability( 4964 NET_CAPABILITY_VALIDATED)); 4965 assertTrue(mCm.getNetworkCapabilities(cellNetwork).hasCapability( 4966 NET_CAPABILITY_VALIDATED)); 4967 assertEquals(mCm.getActiveNetwork(), wifiNetwork); 4968 4969 // Simulate switching to a carrier that does not restrict avoiding bad wifi, and expect 4970 // that we switch back to cell. 4971 doReturn(1).when(mResources).getInteger(R.integer.config_networkAvoidBadWifi); 4972 mPolicyTracker.reevaluate(); 4973 defaultCallback.expectAvailableCallbacksValidated(mCellNetworkAgent); 4974 assertEquals(mCm.getActiveNetwork(), cellNetwork); 4975 4976 // Switch back to a restrictive carrier. 4977 doReturn(0).when(mResources).getInteger(R.integer.config_networkAvoidBadWifi); 4978 mPolicyTracker.reevaluate(); 4979 defaultCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 4980 assertEquals(mCm.getActiveNetwork(), wifiNetwork); 4981 4982 // Simulate the user selecting "switch" on the dialog, and check that we switch to cell. 4983 mCm.setAvoidUnvalidated(wifiNetwork); 4984 defaultCallback.expectAvailableCallbacksValidated(mCellNetworkAgent); 4985 assertFalse(mCm.getNetworkCapabilities(wifiNetwork).hasCapability( 4986 NET_CAPABILITY_VALIDATED)); 4987 assertTrue(mCm.getNetworkCapabilities(cellNetwork).hasCapability( 4988 NET_CAPABILITY_VALIDATED)); 4989 assertEquals(mCm.getActiveNetwork(), cellNetwork); 4990 4991 // Disconnect and reconnect wifi to clear the one-time switch above. 4992 mWiFiNetworkAgent.disconnect(); 4993 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4994 mWiFiNetworkAgent.connect(true); 4995 defaultCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent); 4996 validatedWifiCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent); 4997 wifiNetwork = mWiFiNetworkAgent.getNetwork(); 4998 4999 // Fail validation on wifi and expect the dialog to appear. 5000 mWiFiNetworkAgent.setNetworkInvalid(false /* isStrictMode */); 5001 mCm.reportNetworkConnectivity(wifiNetwork, false); 5002 defaultCallback.expectCapabilitiesWithout(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent); 5003 validatedWifiCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 5004 5005 // Simulate the user selecting "switch" and checking the don't ask again checkbox. 5006 Settings.Global.putInt(cr, ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI, 1); 5007 mPolicyTracker.reevaluate(); 5008 5009 // We now switch to cell. 5010 defaultCallback.expectAvailableCallbacksValidated(mCellNetworkAgent); 5011 assertFalse(mCm.getNetworkCapabilities(wifiNetwork).hasCapability( 5012 NET_CAPABILITY_VALIDATED)); 5013 assertTrue(mCm.getNetworkCapabilities(cellNetwork).hasCapability( 5014 NET_CAPABILITY_VALIDATED)); 5015 assertEquals(mCm.getActiveNetwork(), cellNetwork); 5016 5017 // Simulate the user turning the cellular fallback setting off and then on. 5018 // We switch to wifi and then to cell. 5019 Settings.Global.putString(cr, ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI, null); 5020 mPolicyTracker.reevaluate(); 5021 defaultCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 5022 assertEquals(mCm.getActiveNetwork(), wifiNetwork); 5023 Settings.Global.putInt(cr, ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI, 1); 5024 mPolicyTracker.reevaluate(); 5025 defaultCallback.expectAvailableCallbacksValidated(mCellNetworkAgent); 5026 assertEquals(mCm.getActiveNetwork(), cellNetwork); 5027 5028 // If cell goes down, we switch to wifi. 5029 mCellNetworkAgent.disconnect(); 5030 defaultCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 5031 defaultCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 5032 validatedWifiCallback.assertNoCallback(); 5033 5034 mCm.unregisterNetworkCallback(cellNetworkCallback); 5035 mCm.unregisterNetworkCallback(validatedWifiCallback); 5036 mCm.unregisterNetworkCallback(defaultCallback); 5037 } 5038 5039 @Test 5040 public void testMeteredMultipathPreferenceSetting() throws Exception { 5041 final ContentResolver cr = mServiceContext.getContentResolver(); 5042 final String settingName = ConnectivitySettingsManager.NETWORK_METERED_MULTIPATH_PREFERENCE; 5043 5044 for (int config : Arrays.asList(0, 3, 2)) { 5045 for (String setting: Arrays.asList(null, "0", "2", "1")) { 5046 mPolicyTracker.mConfigMeteredMultipathPreference = config; 5047 Settings.Global.putString(cr, settingName, setting); 5048 mPolicyTracker.reevaluate(); 5049 waitForIdle(); 5050 5051 final int expected = (setting != null) ? Integer.parseInt(setting) : config; 5052 String msg = String.format("config=%d, setting=%s", config, setting); 5053 assertEquals(msg, expected, mCm.getMultipathPreference(null)); 5054 } 5055 } 5056 } 5057 5058 /** 5059 * Validate that a satisfied network request does not trigger onUnavailable() once the 5060 * time-out period expires. 5061 */ 5062 @Test 5063 public void testSatisfiedNetworkRequestDoesNotTriggerOnUnavailable() throws Exception { 5064 NetworkRequest nr = new NetworkRequest.Builder().addTransportType( 5065 NetworkCapabilities.TRANSPORT_WIFI).build(); 5066 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 5067 mCm.requestNetwork(nr, networkCallback, TEST_REQUEST_TIMEOUT_MS); 5068 5069 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 5070 mWiFiNetworkAgent.connect(false); 5071 networkCallback.expectAvailableCallbacks(mWiFiNetworkAgent, false, false, false, 5072 TEST_CALLBACK_TIMEOUT_MS); 5073 5074 // pass timeout and validate that UNAVAILABLE is not called 5075 networkCallback.assertNoCallback(); 5076 } 5077 5078 /** 5079 * Validate that a satisfied network request followed by a disconnected (lost) network does 5080 * not trigger onUnavailable() once the time-out period expires. 5081 */ 5082 @Test 5083 public void testSatisfiedThenLostNetworkRequestDoesNotTriggerOnUnavailable() throws Exception { 5084 NetworkRequest nr = new NetworkRequest.Builder().addTransportType( 5085 NetworkCapabilities.TRANSPORT_WIFI).build(); 5086 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 5087 mCm.requestNetwork(nr, networkCallback, TEST_REQUEST_TIMEOUT_MS); 5088 5089 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 5090 mWiFiNetworkAgent.connect(false); 5091 networkCallback.expectAvailableCallbacks(mWiFiNetworkAgent, false, false, false, 5092 TEST_CALLBACK_TIMEOUT_MS); 5093 mWiFiNetworkAgent.disconnect(); 5094 networkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 5095 5096 // Validate that UNAVAILABLE is not called 5097 networkCallback.assertNoCallback(); 5098 } 5099 5100 /** 5101 * Validate that when a time-out is specified for a network request the onUnavailable() 5102 * callback is called when time-out expires. Then validate that if network request is 5103 * (somehow) satisfied - the callback isn't called later. 5104 */ 5105 @Test 5106 public void testTimedoutNetworkRequest() throws Exception { 5107 NetworkRequest nr = new NetworkRequest.Builder().addTransportType( 5108 NetworkCapabilities.TRANSPORT_WIFI).build(); 5109 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 5110 final int timeoutMs = 10; 5111 mCm.requestNetwork(nr, networkCallback, timeoutMs); 5112 5113 // pass timeout and validate that UNAVAILABLE is called 5114 networkCallback.expectCallback(CallbackEntry.UNAVAILABLE, (Network) null); 5115 5116 // create a network satisfying request - validate that request not triggered 5117 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 5118 mWiFiNetworkAgent.connect(false); 5119 networkCallback.assertNoCallback(); 5120 } 5121 5122 /** 5123 * Validate that when a network request is unregistered (cancelled), no posterior event can 5124 * trigger the callback. 5125 */ 5126 @Test 5127 public void testNoCallbackAfterUnregisteredNetworkRequest() throws Exception { 5128 NetworkRequest nr = new NetworkRequest.Builder().addTransportType( 5129 NetworkCapabilities.TRANSPORT_WIFI).build(); 5130 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 5131 final int timeoutMs = 10; 5132 5133 mCm.requestNetwork(nr, networkCallback, timeoutMs); 5134 mCm.unregisterNetworkCallback(networkCallback); 5135 // Regardless of the timeout, unregistering the callback in ConnectivityManager ensures 5136 // that this callback will not be called. 5137 networkCallback.assertNoCallback(); 5138 5139 // create a network satisfying request - validate that request not triggered 5140 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 5141 mWiFiNetworkAgent.connect(false); 5142 networkCallback.assertNoCallback(); 5143 } 5144 5145 @Test 5146 public void testUnfulfillableNetworkRequest() throws Exception { 5147 runUnfulfillableNetworkRequest(false); 5148 } 5149 5150 @Test 5151 public void testUnfulfillableNetworkRequestAfterUnregister() throws Exception { 5152 runUnfulfillableNetworkRequest(true); 5153 } 5154 5155 /** 5156 * Validate the callback flow for a factory releasing a request as unfulfillable. 5157 */ 5158 private void runUnfulfillableNetworkRequest(boolean preUnregister) throws Exception { 5159 NetworkRequest nr = new NetworkRequest.Builder().addTransportType( 5160 NetworkCapabilities.TRANSPORT_WIFI).build(); 5161 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 5162 5163 final HandlerThread handlerThread = new HandlerThread("testUnfulfillableNetworkRequest"); 5164 handlerThread.start(); 5165 NetworkCapabilities filter = new NetworkCapabilities() 5166 .addTransportType(TRANSPORT_WIFI) 5167 .addCapability(NET_CAPABILITY_INTERNET) 5168 .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED); 5169 final MockNetworkFactory testFactory = new MockNetworkFactory(handlerThread.getLooper(), 5170 mServiceContext, "testFactory", filter, mCsHandlerThread); 5171 testFactory.setScoreFilter(40); 5172 5173 // Register the factory and expect it to receive the default request. 5174 testFactory.register(); 5175 testFactory.expectRequestAdd(); 5176 5177 try { 5178 // Now file the test request and expect it. 5179 mCm.requestNetwork(nr, networkCallback); 5180 final NetworkRequest newRequest = testFactory.expectRequestAdd().request; 5181 5182 if (preUnregister) { 5183 mCm.unregisterNetworkCallback(networkCallback); 5184 5185 // The request has been released : the factory should see it removed 5186 // immediately. 5187 testFactory.expectRequestRemove(); 5188 5189 // Simulate the factory releasing the request as unfulfillable: no-op since 5190 // the callback has already been unregistered (but a test that no exceptions are 5191 // thrown). 5192 testFactory.triggerUnfulfillable(newRequest); 5193 } else { 5194 // Simulate the factory releasing the request as unfulfillable and expect 5195 // onUnavailable! 5196 testFactory.triggerUnfulfillable(newRequest); 5197 5198 networkCallback.expectCallback(CallbackEntry.UNAVAILABLE, (Network) null); 5199 5200 // Declaring a request unfulfillable releases it automatically. 5201 testFactory.expectRequestRemove(); 5202 5203 // unregister network callback - a no-op (since already freed by the 5204 // on-unavailable), but should not fail or throw exceptions. 5205 mCm.unregisterNetworkCallback(networkCallback); 5206 5207 // The factory should not see any further removal, as this request has 5208 // already been removed. 5209 } 5210 } finally { 5211 testFactory.terminate(); 5212 handlerThread.quit(); 5213 } 5214 } 5215 5216 private static class TestKeepaliveCallback extends PacketKeepaliveCallback { 5217 5218 public enum CallbackType { ON_STARTED, ON_STOPPED, ON_ERROR } 5219 5220 private class CallbackValue { 5221 public CallbackType callbackType; 5222 public int error; 5223 5224 public CallbackValue(CallbackType type) { 5225 this.callbackType = type; 5226 this.error = PacketKeepalive.SUCCESS; 5227 assertTrue("onError callback must have error", type != CallbackType.ON_ERROR); 5228 } 5229 5230 public CallbackValue(CallbackType type, int error) { 5231 this.callbackType = type; 5232 this.error = error; 5233 assertEquals("error can only be set for onError", type, CallbackType.ON_ERROR); 5234 } 5235 5236 @Override 5237 public boolean equals(Object o) { 5238 return o instanceof CallbackValue && 5239 this.callbackType == ((CallbackValue) o).callbackType && 5240 this.error == ((CallbackValue) o).error; 5241 } 5242 5243 @Override 5244 public String toString() { 5245 return String.format("%s(%s, %d)", getClass().getSimpleName(), callbackType, error); 5246 } 5247 } 5248 5249 private final LinkedBlockingQueue<CallbackValue> mCallbacks = new LinkedBlockingQueue<>(); 5250 5251 @Override 5252 public void onStarted() { 5253 mCallbacks.add(new CallbackValue(CallbackType.ON_STARTED)); 5254 } 5255 5256 @Override 5257 public void onStopped() { 5258 mCallbacks.add(new CallbackValue(CallbackType.ON_STOPPED)); 5259 } 5260 5261 @Override 5262 public void onError(int error) { 5263 mCallbacks.add(new CallbackValue(CallbackType.ON_ERROR, error)); 5264 } 5265 5266 private void expectCallback(CallbackValue callbackValue) throws InterruptedException { 5267 assertEquals(callbackValue, mCallbacks.poll(TIMEOUT_MS, TimeUnit.MILLISECONDS)); 5268 } 5269 5270 public void expectStarted() throws Exception { 5271 expectCallback(new CallbackValue(CallbackType.ON_STARTED)); 5272 } 5273 5274 public void expectStopped() throws Exception { 5275 expectCallback(new CallbackValue(CallbackType.ON_STOPPED)); 5276 } 5277 5278 public void expectError(int error) throws Exception { 5279 expectCallback(new CallbackValue(CallbackType.ON_ERROR, error)); 5280 } 5281 } 5282 5283 private static class TestSocketKeepaliveCallback extends SocketKeepalive.Callback { 5284 5285 public enum CallbackType { ON_STARTED, ON_STOPPED, ON_ERROR }; 5286 5287 private class CallbackValue { 5288 public CallbackType callbackType; 5289 public int error; 5290 5291 CallbackValue(CallbackType type) { 5292 this.callbackType = type; 5293 this.error = SocketKeepalive.SUCCESS; 5294 assertTrue("onError callback must have error", type != CallbackType.ON_ERROR); 5295 } 5296 5297 CallbackValue(CallbackType type, int error) { 5298 this.callbackType = type; 5299 this.error = error; 5300 assertEquals("error can only be set for onError", type, CallbackType.ON_ERROR); 5301 } 5302 5303 @Override 5304 public boolean equals(Object o) { 5305 return o instanceof CallbackValue 5306 && this.callbackType == ((CallbackValue) o).callbackType 5307 && this.error == ((CallbackValue) o).error; 5308 } 5309 5310 @Override 5311 public String toString() { 5312 return String.format("%s(%s, %d)", getClass().getSimpleName(), callbackType, 5313 error); 5314 } 5315 } 5316 5317 private LinkedBlockingQueue<CallbackValue> mCallbacks = new LinkedBlockingQueue<>(); 5318 private final Executor mExecutor; 5319 5320 TestSocketKeepaliveCallback(@NonNull Executor executor) { 5321 mExecutor = executor; 5322 } 5323 5324 @Override 5325 public void onStarted() { 5326 mCallbacks.add(new CallbackValue(CallbackType.ON_STARTED)); 5327 } 5328 5329 @Override 5330 public void onStopped() { 5331 mCallbacks.add(new CallbackValue(CallbackType.ON_STOPPED)); 5332 } 5333 5334 @Override 5335 public void onError(int error) { 5336 mCallbacks.add(new CallbackValue(CallbackType.ON_ERROR, error)); 5337 } 5338 5339 private void expectCallback(CallbackValue callbackValue) throws InterruptedException { 5340 assertEquals(callbackValue, mCallbacks.poll(TIMEOUT_MS, TimeUnit.MILLISECONDS)); 5341 5342 } 5343 5344 public void expectStarted() throws InterruptedException { 5345 expectCallback(new CallbackValue(CallbackType.ON_STARTED)); 5346 } 5347 5348 public void expectStopped() throws InterruptedException { 5349 expectCallback(new CallbackValue(CallbackType.ON_STOPPED)); 5350 } 5351 5352 public void expectError(int error) throws InterruptedException { 5353 expectCallback(new CallbackValue(CallbackType.ON_ERROR, error)); 5354 } 5355 5356 public void assertNoCallback() { 5357 waitForIdleSerialExecutor(mExecutor, TIMEOUT_MS); 5358 CallbackValue cv = mCallbacks.peek(); 5359 assertNull("Unexpected callback: " + cv, cv); 5360 } 5361 } 5362 5363 private Network connectKeepaliveNetwork(LinkProperties lp) throws Exception { 5364 // Ensure the network is disconnected before anything else occurs 5365 if (mWiFiNetworkAgent != null) { 5366 assertNull(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork())); 5367 } 5368 5369 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 5370 ExpectedBroadcast b = expectConnectivityAction(TYPE_WIFI, DetailedState.CONNECTED); 5371 mWiFiNetworkAgent.connect(true); 5372 b.expectBroadcast(); 5373 verifyActiveNetwork(TRANSPORT_WIFI); 5374 mWiFiNetworkAgent.sendLinkProperties(lp); 5375 waitForIdle(); 5376 return mWiFiNetworkAgent.getNetwork(); 5377 } 5378 5379 @Test 5380 public void testPacketKeepalives() throws Exception { 5381 InetAddress myIPv4 = InetAddress.getByName("192.0.2.129"); 5382 InetAddress notMyIPv4 = InetAddress.getByName("192.0.2.35"); 5383 InetAddress myIPv6 = InetAddress.getByName("2001:db8::1"); 5384 InetAddress dstIPv4 = InetAddress.getByName("8.8.8.8"); 5385 InetAddress dstIPv6 = InetAddress.getByName("2001:4860:4860::8888"); 5386 5387 final int validKaInterval = 15; 5388 final int invalidKaInterval = 9; 5389 5390 LinkProperties lp = new LinkProperties(); 5391 lp.setInterfaceName("wlan12"); 5392 lp.addLinkAddress(new LinkAddress(myIPv6, 64)); 5393 lp.addLinkAddress(new LinkAddress(myIPv4, 25)); 5394 lp.addRoute(new RouteInfo(InetAddress.getByName("fe80::1234"))); 5395 lp.addRoute(new RouteInfo(InetAddress.getByName("192.0.2.254"))); 5396 5397 Network notMyNet = new Network(61234); 5398 Network myNet = connectKeepaliveNetwork(lp); 5399 5400 TestKeepaliveCallback callback = new TestKeepaliveCallback(); 5401 PacketKeepalive ka; 5402 5403 // Attempt to start keepalives with invalid parameters and check for errors. 5404 ka = mCm.startNattKeepalive(notMyNet, validKaInterval, callback, myIPv4, 1234, dstIPv4); 5405 callback.expectError(PacketKeepalive.ERROR_INVALID_NETWORK); 5406 5407 ka = mCm.startNattKeepalive(myNet, invalidKaInterval, callback, myIPv4, 1234, dstIPv4); 5408 callback.expectError(PacketKeepalive.ERROR_INVALID_INTERVAL); 5409 5410 ka = mCm.startNattKeepalive(myNet, validKaInterval, callback, myIPv4, 1234, dstIPv6); 5411 callback.expectError(PacketKeepalive.ERROR_INVALID_IP_ADDRESS); 5412 5413 ka = mCm.startNattKeepalive(myNet, validKaInterval, callback, myIPv6, 1234, dstIPv4); 5414 callback.expectError(PacketKeepalive.ERROR_INVALID_IP_ADDRESS); 5415 5416 // NAT-T is only supported for IPv4. 5417 ka = mCm.startNattKeepalive(myNet, validKaInterval, callback, myIPv6, 1234, dstIPv6); 5418 callback.expectError(PacketKeepalive.ERROR_INVALID_IP_ADDRESS); 5419 5420 ka = mCm.startNattKeepalive(myNet, validKaInterval, callback, myIPv4, 123456, dstIPv4); 5421 callback.expectError(PacketKeepalive.ERROR_INVALID_PORT); 5422 5423 ka = mCm.startNattKeepalive(myNet, validKaInterval, callback, myIPv4, 123456, dstIPv4); 5424 callback.expectError(PacketKeepalive.ERROR_INVALID_PORT); 5425 5426 ka = mCm.startNattKeepalive(myNet, validKaInterval, callback, myIPv4, 12345, dstIPv4); 5427 callback.expectError(PacketKeepalive.ERROR_HARDWARE_UNSUPPORTED); 5428 5429 ka = mCm.startNattKeepalive(myNet, validKaInterval, callback, myIPv4, 12345, dstIPv4); 5430 callback.expectError(PacketKeepalive.ERROR_HARDWARE_UNSUPPORTED); 5431 5432 // Check that a started keepalive can be stopped. 5433 mWiFiNetworkAgent.setStartKeepaliveEvent(PacketKeepalive.SUCCESS); 5434 ka = mCm.startNattKeepalive(myNet, validKaInterval, callback, myIPv4, 12345, dstIPv4); 5435 callback.expectStarted(); 5436 mWiFiNetworkAgent.setStopKeepaliveEvent(PacketKeepalive.SUCCESS); 5437 ka.stop(); 5438 callback.expectStopped(); 5439 5440 // Check that deleting the IP address stops the keepalive. 5441 LinkProperties bogusLp = new LinkProperties(lp); 5442 ka = mCm.startNattKeepalive(myNet, validKaInterval, callback, myIPv4, 12345, dstIPv4); 5443 callback.expectStarted(); 5444 bogusLp.removeLinkAddress(new LinkAddress(myIPv4, 25)); 5445 bogusLp.addLinkAddress(new LinkAddress(notMyIPv4, 25)); 5446 mWiFiNetworkAgent.sendLinkProperties(bogusLp); 5447 callback.expectError(PacketKeepalive.ERROR_INVALID_IP_ADDRESS); 5448 mWiFiNetworkAgent.sendLinkProperties(lp); 5449 5450 // Check that a started keepalive is stopped correctly when the network disconnects. 5451 ka = mCm.startNattKeepalive(myNet, validKaInterval, callback, myIPv4, 12345, dstIPv4); 5452 callback.expectStarted(); 5453 mWiFiNetworkAgent.disconnect(); 5454 mWiFiNetworkAgent.expectDisconnected(); 5455 callback.expectError(PacketKeepalive.ERROR_INVALID_NETWORK); 5456 5457 // ... and that stopping it after that has no adverse effects. 5458 waitForIdle(); 5459 final Network myNetAlias = myNet; 5460 assertNull(mCm.getNetworkCapabilities(myNetAlias)); 5461 ka.stop(); 5462 5463 // Reconnect. 5464 myNet = connectKeepaliveNetwork(lp); 5465 mWiFiNetworkAgent.setStartKeepaliveEvent(PacketKeepalive.SUCCESS); 5466 5467 // Check that keepalive slots start from 1 and increment. The first one gets slot 1. 5468 mWiFiNetworkAgent.setExpectedKeepaliveSlot(1); 5469 ka = mCm.startNattKeepalive(myNet, validKaInterval, callback, myIPv4, 12345, dstIPv4); 5470 callback.expectStarted(); 5471 5472 // The second one gets slot 2. 5473 mWiFiNetworkAgent.setExpectedKeepaliveSlot(2); 5474 TestKeepaliveCallback callback2 = new TestKeepaliveCallback(); 5475 PacketKeepalive ka2 = mCm.startNattKeepalive( 5476 myNet, validKaInterval, callback2, myIPv4, 6789, dstIPv4); 5477 callback2.expectStarted(); 5478 5479 // Now stop the first one and create a third. This also gets slot 1. 5480 ka.stop(); 5481 callback.expectStopped(); 5482 5483 mWiFiNetworkAgent.setExpectedKeepaliveSlot(1); 5484 TestKeepaliveCallback callback3 = new TestKeepaliveCallback(); 5485 PacketKeepalive ka3 = mCm.startNattKeepalive( 5486 myNet, validKaInterval, callback3, myIPv4, 9876, dstIPv4); 5487 callback3.expectStarted(); 5488 5489 ka2.stop(); 5490 callback2.expectStopped(); 5491 5492 ka3.stop(); 5493 callback3.expectStopped(); 5494 } 5495 5496 // Helper method to prepare the executor and run test 5497 private void runTestWithSerialExecutors(ExceptionUtils.ThrowingConsumer<Executor> functor) 5498 throws Exception { 5499 final ExecutorService executorSingleThread = Executors.newSingleThreadExecutor(); 5500 final Executor executorInline = (Runnable r) -> r.run(); 5501 functor.accept(executorSingleThread); 5502 executorSingleThread.shutdown(); 5503 functor.accept(executorInline); 5504 } 5505 5506 @Test 5507 public void testNattSocketKeepalives() throws Exception { 5508 runTestWithSerialExecutors(executor -> doTestNattSocketKeepalivesWithExecutor(executor)); 5509 runTestWithSerialExecutors(executor -> doTestNattSocketKeepalivesFdWithExecutor(executor)); 5510 } 5511 5512 private void doTestNattSocketKeepalivesWithExecutor(Executor executor) throws Exception { 5513 // TODO: 1. Move this outside of ConnectivityServiceTest. 5514 // 2. Make test to verify that Nat-T keepalive socket is created by IpSecService. 5515 // 3. Mock ipsec service. 5516 final InetAddress myIPv4 = InetAddress.getByName("192.0.2.129"); 5517 final InetAddress notMyIPv4 = InetAddress.getByName("192.0.2.35"); 5518 final InetAddress myIPv6 = InetAddress.getByName("2001:db8::1"); 5519 final InetAddress dstIPv4 = InetAddress.getByName("8.8.8.8"); 5520 final InetAddress dstIPv6 = InetAddress.getByName("2001:4860:4860::8888"); 5521 5522 final int validKaInterval = 15; 5523 final int invalidKaInterval = 9; 5524 5525 final IpSecManager mIpSec = (IpSecManager) mContext.getSystemService(Context.IPSEC_SERVICE); 5526 final UdpEncapsulationSocket testSocket = mIpSec.openUdpEncapsulationSocket(); 5527 final int srcPort = testSocket.getPort(); 5528 5529 LinkProperties lp = new LinkProperties(); 5530 lp.setInterfaceName("wlan12"); 5531 lp.addLinkAddress(new LinkAddress(myIPv6, 64)); 5532 lp.addLinkAddress(new LinkAddress(myIPv4, 25)); 5533 lp.addRoute(new RouteInfo(InetAddress.getByName("fe80::1234"))); 5534 lp.addRoute(new RouteInfo(InetAddress.getByName("192.0.2.254"))); 5535 5536 Network notMyNet = new Network(61234); 5537 Network myNet = connectKeepaliveNetwork(lp); 5538 5539 TestSocketKeepaliveCallback callback = new TestSocketKeepaliveCallback(executor); 5540 5541 // Attempt to start keepalives with invalid parameters and check for errors. 5542 // Invalid network. 5543 try (SocketKeepalive ka = mCm.createSocketKeepalive( 5544 notMyNet, testSocket, myIPv4, dstIPv4, executor, callback)) { 5545 ka.start(validKaInterval); 5546 callback.expectError(SocketKeepalive.ERROR_INVALID_NETWORK); 5547 } 5548 5549 // Invalid interval. 5550 try (SocketKeepalive ka = mCm.createSocketKeepalive( 5551 myNet, testSocket, myIPv4, dstIPv4, executor, callback)) { 5552 ka.start(invalidKaInterval); 5553 callback.expectError(SocketKeepalive.ERROR_INVALID_INTERVAL); 5554 } 5555 5556 // Invalid destination. 5557 try (SocketKeepalive ka = mCm.createSocketKeepalive( 5558 myNet, testSocket, myIPv4, dstIPv6, executor, callback)) { 5559 ka.start(validKaInterval); 5560 callback.expectError(SocketKeepalive.ERROR_INVALID_IP_ADDRESS); 5561 } 5562 5563 // Invalid source; 5564 try (SocketKeepalive ka = mCm.createSocketKeepalive( 5565 myNet, testSocket, myIPv6, dstIPv4, executor, callback)) { 5566 ka.start(validKaInterval); 5567 callback.expectError(SocketKeepalive.ERROR_INVALID_IP_ADDRESS); 5568 } 5569 5570 // NAT-T is only supported for IPv4. 5571 try (SocketKeepalive ka = mCm.createSocketKeepalive( 5572 myNet, testSocket, myIPv6, dstIPv6, executor, callback)) { 5573 ka.start(validKaInterval); 5574 callback.expectError(SocketKeepalive.ERROR_INVALID_IP_ADDRESS); 5575 } 5576 5577 // Basic check before testing started keepalive. 5578 try (SocketKeepalive ka = mCm.createSocketKeepalive( 5579 myNet, testSocket, myIPv4, dstIPv4, executor, callback)) { 5580 ka.start(validKaInterval); 5581 callback.expectError(SocketKeepalive.ERROR_UNSUPPORTED); 5582 } 5583 5584 // Check that a started keepalive can be stopped. 5585 mWiFiNetworkAgent.setStartKeepaliveEvent(SocketKeepalive.SUCCESS); 5586 try (SocketKeepalive ka = mCm.createSocketKeepalive( 5587 myNet, testSocket, myIPv4, dstIPv4, executor, callback)) { 5588 ka.start(validKaInterval); 5589 callback.expectStarted(); 5590 mWiFiNetworkAgent.setStopKeepaliveEvent(SocketKeepalive.SUCCESS); 5591 ka.stop(); 5592 callback.expectStopped(); 5593 5594 // Check that keepalive could be restarted. 5595 ka.start(validKaInterval); 5596 callback.expectStarted(); 5597 ka.stop(); 5598 callback.expectStopped(); 5599 5600 // Check that keepalive can be restarted without waiting for callback. 5601 ka.start(validKaInterval); 5602 callback.expectStarted(); 5603 ka.stop(); 5604 ka.start(validKaInterval); 5605 callback.expectStopped(); 5606 callback.expectStarted(); 5607 ka.stop(); 5608 callback.expectStopped(); 5609 } 5610 5611 // Check that deleting the IP address stops the keepalive. 5612 LinkProperties bogusLp = new LinkProperties(lp); 5613 try (SocketKeepalive ka = mCm.createSocketKeepalive( 5614 myNet, testSocket, myIPv4, dstIPv4, executor, callback)) { 5615 ka.start(validKaInterval); 5616 callback.expectStarted(); 5617 bogusLp.removeLinkAddress(new LinkAddress(myIPv4, 25)); 5618 bogusLp.addLinkAddress(new LinkAddress(notMyIPv4, 25)); 5619 mWiFiNetworkAgent.sendLinkProperties(bogusLp); 5620 callback.expectError(SocketKeepalive.ERROR_INVALID_IP_ADDRESS); 5621 mWiFiNetworkAgent.sendLinkProperties(lp); 5622 } 5623 5624 // Check that a started keepalive is stopped correctly when the network disconnects. 5625 try (SocketKeepalive ka = mCm.createSocketKeepalive( 5626 myNet, testSocket, myIPv4, dstIPv4, executor, callback)) { 5627 ka.start(validKaInterval); 5628 callback.expectStarted(); 5629 mWiFiNetworkAgent.disconnect(); 5630 mWiFiNetworkAgent.expectDisconnected(); 5631 callback.expectError(SocketKeepalive.ERROR_INVALID_NETWORK); 5632 5633 // ... and that stopping it after that has no adverse effects. 5634 waitForIdle(); 5635 final Network myNetAlias = myNet; 5636 assertNull(mCm.getNetworkCapabilities(myNetAlias)); 5637 ka.stop(); 5638 callback.assertNoCallback(); 5639 } 5640 5641 // Reconnect. 5642 myNet = connectKeepaliveNetwork(lp); 5643 mWiFiNetworkAgent.setStartKeepaliveEvent(SocketKeepalive.SUCCESS); 5644 5645 // Check that a stop followed by network disconnects does not result in crash. 5646 try (SocketKeepalive ka = mCm.createSocketKeepalive( 5647 myNet, testSocket, myIPv4, dstIPv4, executor, callback)) { 5648 ka.start(validKaInterval); 5649 callback.expectStarted(); 5650 // Delay the response of keepalive events in networkAgent long enough to make sure 5651 // the follow-up network disconnection will be processed first. 5652 mWiFiNetworkAgent.setKeepaliveResponseDelay(3 * TIMEOUT_MS); 5653 ka.stop(); 5654 // Call stop() twice shouldn't result in crash, b/182586681. 5655 ka.stop(); 5656 5657 // Make sure the stop has been processed. Wait for executor idle is needed to prevent 5658 // flaky since the actual stop call to the service is delegated to executor thread. 5659 waitForIdleSerialExecutor(executor, TIMEOUT_MS); 5660 waitForIdle(); 5661 5662 mWiFiNetworkAgent.disconnect(); 5663 mWiFiNetworkAgent.expectDisconnected(); 5664 callback.expectStopped(); 5665 callback.assertNoCallback(); 5666 } 5667 5668 // Reconnect. 5669 waitForIdle(); 5670 myNet = connectKeepaliveNetwork(lp); 5671 mWiFiNetworkAgent.setStartKeepaliveEvent(SocketKeepalive.SUCCESS); 5672 5673 // Check that keepalive slots start from 1 and increment. The first one gets slot 1. 5674 mWiFiNetworkAgent.setExpectedKeepaliveSlot(1); 5675 int srcPort2 = 0; 5676 try (SocketKeepalive ka = mCm.createSocketKeepalive( 5677 myNet, testSocket, myIPv4, dstIPv4, executor, callback)) { 5678 ka.start(validKaInterval); 5679 callback.expectStarted(); 5680 5681 // The second one gets slot 2. 5682 mWiFiNetworkAgent.setExpectedKeepaliveSlot(2); 5683 final UdpEncapsulationSocket testSocket2 = mIpSec.openUdpEncapsulationSocket(); 5684 srcPort2 = testSocket2.getPort(); 5685 TestSocketKeepaliveCallback callback2 = new TestSocketKeepaliveCallback(executor); 5686 try (SocketKeepalive ka2 = mCm.createSocketKeepalive( 5687 myNet, testSocket2, myIPv4, dstIPv4, executor, callback2)) { 5688 ka2.start(validKaInterval); 5689 callback2.expectStarted(); 5690 5691 ka.stop(); 5692 callback.expectStopped(); 5693 5694 ka2.stop(); 5695 callback2.expectStopped(); 5696 5697 testSocket.close(); 5698 testSocket2.close(); 5699 } 5700 } 5701 5702 // Check that there is no port leaked after all keepalives and sockets are closed. 5703 // TODO: enable this check after ensuring a valid free port. See b/129512753#comment7. 5704 // assertFalse(isUdpPortInUse(srcPort)); 5705 // assertFalse(isUdpPortInUse(srcPort2)); 5706 5707 mWiFiNetworkAgent.disconnect(); 5708 mWiFiNetworkAgent.expectDisconnected(); 5709 mWiFiNetworkAgent = null; 5710 } 5711 5712 @Test 5713 public void testTcpSocketKeepalives() throws Exception { 5714 runTestWithSerialExecutors(executor -> doTestTcpSocketKeepalivesWithExecutor(executor)); 5715 } 5716 5717 private void doTestTcpSocketKeepalivesWithExecutor(Executor executor) throws Exception { 5718 final int srcPortV4 = 12345; 5719 final int srcPortV6 = 23456; 5720 final InetAddress myIPv4 = InetAddress.getByName("127.0.0.1"); 5721 final InetAddress myIPv6 = InetAddress.getByName("::1"); 5722 5723 final int validKaInterval = 15; 5724 5725 final LinkProperties lp = new LinkProperties(); 5726 lp.setInterfaceName("wlan12"); 5727 lp.addLinkAddress(new LinkAddress(myIPv6, 64)); 5728 lp.addLinkAddress(new LinkAddress(myIPv4, 25)); 5729 lp.addRoute(new RouteInfo(InetAddress.getByName("fe80::1234"))); 5730 lp.addRoute(new RouteInfo(InetAddress.getByName("127.0.0.254"))); 5731 5732 final Network notMyNet = new Network(61234); 5733 final Network myNet = connectKeepaliveNetwork(lp); 5734 5735 final Socket testSocketV4 = new Socket(); 5736 final Socket testSocketV6 = new Socket(); 5737 5738 TestSocketKeepaliveCallback callback = new TestSocketKeepaliveCallback(executor); 5739 5740 // Attempt to start Tcp keepalives with invalid parameters and check for errors. 5741 // Invalid network. 5742 try (SocketKeepalive ka = mCm.createSocketKeepalive( 5743 notMyNet, testSocketV4, executor, callback)) { 5744 ka.start(validKaInterval); 5745 callback.expectError(SocketKeepalive.ERROR_INVALID_NETWORK); 5746 } 5747 5748 // Invalid Socket (socket is not bound with IPv4 address). 5749 try (SocketKeepalive ka = mCm.createSocketKeepalive( 5750 myNet, testSocketV4, executor, callback)) { 5751 ka.start(validKaInterval); 5752 callback.expectError(SocketKeepalive.ERROR_INVALID_SOCKET); 5753 } 5754 5755 // Invalid Socket (socket is not bound with IPv6 address). 5756 try (SocketKeepalive ka = mCm.createSocketKeepalive( 5757 myNet, testSocketV6, executor, callback)) { 5758 ka.start(validKaInterval); 5759 callback.expectError(SocketKeepalive.ERROR_INVALID_SOCKET); 5760 } 5761 5762 // Bind the socket address 5763 testSocketV4.bind(new InetSocketAddress(myIPv4, srcPortV4)); 5764 testSocketV6.bind(new InetSocketAddress(myIPv6, srcPortV6)); 5765 5766 // Invalid Socket (socket is bound with IPv4 address). 5767 try (SocketKeepalive ka = mCm.createSocketKeepalive( 5768 myNet, testSocketV4, executor, callback)) { 5769 ka.start(validKaInterval); 5770 callback.expectError(SocketKeepalive.ERROR_INVALID_SOCKET); 5771 } 5772 5773 // Invalid Socket (socket is bound with IPv6 address). 5774 try (SocketKeepalive ka = mCm.createSocketKeepalive( 5775 myNet, testSocketV6, executor, callback)) { 5776 ka.start(validKaInterval); 5777 callback.expectError(SocketKeepalive.ERROR_INVALID_SOCKET); 5778 } 5779 5780 testSocketV4.close(); 5781 testSocketV6.close(); 5782 5783 mWiFiNetworkAgent.disconnect(); 5784 mWiFiNetworkAgent.expectDisconnected(); 5785 mWiFiNetworkAgent = null; 5786 } 5787 5788 private void doTestNattSocketKeepalivesFdWithExecutor(Executor executor) throws Exception { 5789 final InetAddress myIPv4 = InetAddress.getByName("192.0.2.129"); 5790 final InetAddress anyIPv4 = InetAddress.getByName("0.0.0.0"); 5791 final InetAddress dstIPv4 = InetAddress.getByName("8.8.8.8"); 5792 final int validKaInterval = 15; 5793 5794 // Prepare the target network. 5795 LinkProperties lp = new LinkProperties(); 5796 lp.setInterfaceName("wlan12"); 5797 lp.addLinkAddress(new LinkAddress(myIPv4, 25)); 5798 lp.addRoute(new RouteInfo(InetAddress.getByName("192.0.2.254"))); 5799 Network myNet = connectKeepaliveNetwork(lp); 5800 mWiFiNetworkAgent.setStartKeepaliveEvent(SocketKeepalive.SUCCESS); 5801 mWiFiNetworkAgent.setStopKeepaliveEvent(SocketKeepalive.SUCCESS); 5802 5803 TestSocketKeepaliveCallback callback = new TestSocketKeepaliveCallback(executor); 5804 5805 // Prepare the target file descriptor, keep only one instance. 5806 final IpSecManager mIpSec = (IpSecManager) mContext.getSystemService(Context.IPSEC_SERVICE); 5807 final UdpEncapsulationSocket testSocket = mIpSec.openUdpEncapsulationSocket(); 5808 final int srcPort = testSocket.getPort(); 5809 final ParcelFileDescriptor testPfd = 5810 ParcelFileDescriptor.dup(testSocket.getFileDescriptor()); 5811 testSocket.close(); 5812 assertTrue(isUdpPortInUse(srcPort)); 5813 5814 // Start keepalive and explicit make the variable goes out of scope with try-with-resources 5815 // block. 5816 try (SocketKeepalive ka = mCm.createNattKeepalive( 5817 myNet, testPfd, myIPv4, dstIPv4, executor, callback)) { 5818 ka.start(validKaInterval); 5819 callback.expectStarted(); 5820 ka.stop(); 5821 callback.expectStopped(); 5822 } 5823 5824 // Check that the ParcelFileDescriptor is still valid after keepalive stopped, 5825 // ErrnoException with EBADF will be thrown if the socket is closed when checking local 5826 // address. 5827 assertTrue(isUdpPortInUse(srcPort)); 5828 final InetSocketAddress sa = 5829 (InetSocketAddress) Os.getsockname(testPfd.getFileDescriptor()); 5830 assertEquals(anyIPv4, sa.getAddress()); 5831 5832 testPfd.close(); 5833 // TODO: enable this check after ensuring a valid free port. See b/129512753#comment7. 5834 // assertFalse(isUdpPortInUse(srcPort)); 5835 5836 mWiFiNetworkAgent.disconnect(); 5837 mWiFiNetworkAgent.expectDisconnected(); 5838 mWiFiNetworkAgent = null; 5839 } 5840 5841 private static boolean isUdpPortInUse(int port) { 5842 try (DatagramSocket ignored = new DatagramSocket(port)) { 5843 return false; 5844 } catch (IOException alreadyInUse) { 5845 return true; 5846 } 5847 } 5848 5849 @Test 5850 public void testGetCaptivePortalServerUrl() throws Exception { 5851 String url = mCm.getCaptivePortalServerUrl(); 5852 assertEquals("http://connectivitycheck.gstatic.com/generate_204", url); 5853 } 5854 5855 private static class TestNetworkPinner extends NetworkPinner { 5856 public static boolean awaitPin(int timeoutMs) throws InterruptedException { 5857 synchronized(sLock) { 5858 if (sNetwork == null) { 5859 sLock.wait(timeoutMs); 5860 } 5861 return sNetwork != null; 5862 } 5863 } 5864 5865 public static boolean awaitUnpin(int timeoutMs) throws InterruptedException { 5866 synchronized(sLock) { 5867 if (sNetwork != null) { 5868 sLock.wait(timeoutMs); 5869 } 5870 return sNetwork == null; 5871 } 5872 } 5873 } 5874 5875 private void assertPinnedToWifiWithCellDefault() { 5876 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getBoundNetworkForProcess()); 5877 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 5878 } 5879 5880 private void assertPinnedToWifiWithWifiDefault() { 5881 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getBoundNetworkForProcess()); 5882 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 5883 } 5884 5885 private void assertNotPinnedToWifi() { 5886 assertNull(mCm.getBoundNetworkForProcess()); 5887 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 5888 } 5889 5890 @Test 5891 public void testNetworkPinner() throws Exception { 5892 NetworkRequest wifiRequest = new NetworkRequest.Builder() 5893 .addTransportType(TRANSPORT_WIFI) 5894 .build(); 5895 assertNull(mCm.getBoundNetworkForProcess()); 5896 5897 TestNetworkPinner.pin(mServiceContext, wifiRequest); 5898 assertNull(mCm.getBoundNetworkForProcess()); 5899 5900 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 5901 mCellNetworkAgent.connect(true); 5902 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 5903 mWiFiNetworkAgent.connect(false); 5904 5905 // When wi-fi connects, expect to be pinned. 5906 assertTrue(TestNetworkPinner.awaitPin(100)); 5907 assertPinnedToWifiWithCellDefault(); 5908 5909 // Disconnect and expect the pin to drop. 5910 mWiFiNetworkAgent.disconnect(); 5911 assertTrue(TestNetworkPinner.awaitUnpin(100)); 5912 assertNotPinnedToWifi(); 5913 5914 // Reconnecting does not cause the pin to come back. 5915 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 5916 mWiFiNetworkAgent.connect(false); 5917 assertFalse(TestNetworkPinner.awaitPin(100)); 5918 assertNotPinnedToWifi(); 5919 5920 // Pinning while connected causes the pin to take effect immediately. 5921 TestNetworkPinner.pin(mServiceContext, wifiRequest); 5922 assertTrue(TestNetworkPinner.awaitPin(100)); 5923 assertPinnedToWifiWithCellDefault(); 5924 5925 // Explicitly unpin and expect to use the default network again. 5926 TestNetworkPinner.unpin(); 5927 assertNotPinnedToWifi(); 5928 5929 // Disconnect cell and wifi. 5930 ExpectedBroadcast b = registerConnectivityBroadcast(3); // cell down, wifi up, wifi down. 5931 mCellNetworkAgent.disconnect(); 5932 mWiFiNetworkAgent.disconnect(); 5933 b.expectBroadcast(); 5934 5935 // Pinning takes effect even if the pinned network is the default when the pin is set... 5936 TestNetworkPinner.pin(mServiceContext, wifiRequest); 5937 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 5938 mWiFiNetworkAgent.connect(false); 5939 assertTrue(TestNetworkPinner.awaitPin(100)); 5940 assertPinnedToWifiWithWifiDefault(); 5941 5942 // ... and is maintained even when that network is no longer the default. 5943 b = registerConnectivityBroadcast(1); 5944 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 5945 mCellNetworkAgent.connect(true); 5946 b.expectBroadcast(); 5947 assertPinnedToWifiWithCellDefault(); 5948 } 5949 5950 @Test 5951 public void testNetworkCallbackMaximum() throws Exception { 5952 final int MAX_REQUESTS = 100; 5953 final int CALLBACKS = 87; 5954 final int DIFF_INTENTS = 10; 5955 final int SAME_INTENTS = 10; 5956 final int SYSTEM_ONLY_MAX_REQUESTS = 250; 5957 // Assert 1 (Default request filed before testing) + CALLBACKS + DIFF_INTENTS + 5958 // 1 (same intent) = MAX_REQUESTS - 1, since the capacity is MAX_REQUEST - 1. 5959 assertEquals(MAX_REQUESTS - 1, 1 + CALLBACKS + DIFF_INTENTS + 1); 5960 5961 NetworkRequest networkRequest = new NetworkRequest.Builder().build(); 5962 ArrayList<Object> registered = new ArrayList<>(); 5963 5964 for (int j = 0; j < CALLBACKS; j++) { 5965 final NetworkCallback cb = new NetworkCallback(); 5966 if (j < CALLBACKS / 2) { 5967 mCm.requestNetwork(networkRequest, cb); 5968 } else { 5969 mCm.registerNetworkCallback(networkRequest, cb); 5970 } 5971 registered.add(cb); 5972 } 5973 5974 // Since ConnectivityService will de-duplicate the request with the same intent, 5975 // register multiple times does not really increase multiple requests. 5976 final PendingIntent same_pi = PendingIntent.getBroadcast(mContext, 0 /* requestCode */, 5977 new Intent("same"), FLAG_IMMUTABLE); 5978 for (int j = 0; j < SAME_INTENTS; j++) { 5979 mCm.registerNetworkCallback(networkRequest, same_pi); 5980 // Wait for the requests with the same intent to be de-duplicated. Because 5981 // ConnectivityService side incrementCountOrThrow in binder, decrementCount in handler 5982 // thread, waitForIdle is needed to ensure decrementCount being invoked for same intent 5983 // requests before doing further tests. 5984 waitForIdle(); 5985 } 5986 for (int j = 0; j < SAME_INTENTS; j++) { 5987 mCm.requestNetwork(networkRequest, same_pi); 5988 // Wait for the requests with the same intent to be de-duplicated. 5989 // Refer to the reason above. 5990 waitForIdle(); 5991 } 5992 registered.add(same_pi); 5993 5994 for (int j = 0; j < DIFF_INTENTS; j++) { 5995 if (j < DIFF_INTENTS / 2) { 5996 final PendingIntent pi = PendingIntent.getBroadcast(mContext, 0 /* requestCode */, 5997 new Intent("a" + j), FLAG_IMMUTABLE); 5998 mCm.requestNetwork(networkRequest, pi); 5999 registered.add(pi); 6000 } else { 6001 final PendingIntent pi = PendingIntent.getBroadcast(mContext, 0 /* requestCode */, 6002 new Intent("b" + j), FLAG_IMMUTABLE); 6003 mCm.registerNetworkCallback(networkRequest, pi); 6004 registered.add(pi); 6005 } 6006 } 6007 6008 // Test that the limit is enforced when MAX_REQUESTS simultaneous requests are added. 6009 assertThrows(TooManyRequestsException.class, () -> 6010 mCm.requestNetwork(networkRequest, new NetworkCallback()) 6011 ); 6012 assertThrows(TooManyRequestsException.class, () -> 6013 mCm.registerNetworkCallback(networkRequest, new NetworkCallback()) 6014 ); 6015 assertThrows(TooManyRequestsException.class, () -> 6016 mCm.requestNetwork(networkRequest, 6017 PendingIntent.getBroadcast(mContext, 0 /* requestCode */, 6018 new Intent("c"), FLAG_IMMUTABLE)) 6019 ); 6020 assertThrows(TooManyRequestsException.class, () -> 6021 mCm.registerNetworkCallback(networkRequest, 6022 PendingIntent.getBroadcast(mContext, 0 /* requestCode */, 6023 new Intent("d"), FLAG_IMMUTABLE)) 6024 ); 6025 6026 // The system gets another SYSTEM_ONLY_MAX_REQUESTS slots. 6027 final Handler handler = new Handler(ConnectivityThread.getInstanceLooper()); 6028 withPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, () -> { 6029 ArrayList<NetworkCallback> systemRegistered = new ArrayList<>(); 6030 for (int i = 0; i < SYSTEM_ONLY_MAX_REQUESTS - 1; i++) { 6031 NetworkCallback cb = new NetworkCallback(); 6032 if (i % 2 == 0) { 6033 mCm.registerDefaultNetworkCallbackForUid(1000000 + i, cb, handler); 6034 } else { 6035 mCm.registerNetworkCallback(networkRequest, cb); 6036 } 6037 systemRegistered.add(cb); 6038 } 6039 waitForIdle(); 6040 6041 assertThrows(TooManyRequestsException.class, () -> 6042 mCm.registerDefaultNetworkCallbackForUid(1001042, new NetworkCallback(), 6043 handler)); 6044 assertThrows(TooManyRequestsException.class, () -> 6045 mCm.registerNetworkCallback(networkRequest, new NetworkCallback())); 6046 6047 for (NetworkCallback callback : systemRegistered) { 6048 mCm.unregisterNetworkCallback(callback); 6049 } 6050 waitForIdle(); // Wait for requests to be unregistered before giving up the permission. 6051 }); 6052 6053 for (Object o : registered) { 6054 if (o instanceof NetworkCallback) { 6055 mCm.unregisterNetworkCallback((NetworkCallback) o); 6056 } 6057 if (o instanceof PendingIntent) { 6058 mCm.unregisterNetworkCallback((PendingIntent) o); 6059 } 6060 } 6061 waitForIdle(); 6062 6063 // Test that the limit is not hit when MAX_REQUESTS requests are added and removed. 6064 for (int i = 0; i < MAX_REQUESTS; i++) { 6065 NetworkCallback networkCallback = new NetworkCallback(); 6066 mCm.requestNetwork(networkRequest, networkCallback); 6067 mCm.unregisterNetworkCallback(networkCallback); 6068 } 6069 waitForIdle(); 6070 6071 for (int i = 0; i < MAX_REQUESTS; i++) { 6072 NetworkCallback networkCallback = new NetworkCallback(); 6073 mCm.registerNetworkCallback(networkRequest, networkCallback); 6074 mCm.unregisterNetworkCallback(networkCallback); 6075 } 6076 waitForIdle(); 6077 6078 for (int i = 0; i < MAX_REQUESTS; i++) { 6079 NetworkCallback networkCallback = new NetworkCallback(); 6080 mCm.registerDefaultNetworkCallback(networkCallback); 6081 mCm.unregisterNetworkCallback(networkCallback); 6082 } 6083 waitForIdle(); 6084 6085 for (int i = 0; i < MAX_REQUESTS; i++) { 6086 NetworkCallback networkCallback = new NetworkCallback(); 6087 mCm.registerDefaultNetworkCallback(networkCallback); 6088 mCm.unregisterNetworkCallback(networkCallback); 6089 } 6090 waitForIdle(); 6091 6092 withPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, () -> { 6093 for (int i = 0; i < MAX_REQUESTS; i++) { 6094 NetworkCallback networkCallback = new NetworkCallback(); 6095 mCm.registerDefaultNetworkCallbackForUid(1000000 + i, networkCallback, 6096 new Handler(ConnectivityThread.getInstanceLooper())); 6097 mCm.unregisterNetworkCallback(networkCallback); 6098 } 6099 }); 6100 waitForIdle(); 6101 6102 for (int i = 0; i < MAX_REQUESTS; i++) { 6103 final PendingIntent pendingIntent = PendingIntent.getBroadcast( 6104 mContext, 0 /* requestCode */, new Intent("e" + i), FLAG_IMMUTABLE); 6105 mCm.requestNetwork(networkRequest, pendingIntent); 6106 mCm.unregisterNetworkCallback(pendingIntent); 6107 } 6108 waitForIdle(); 6109 6110 for (int i = 0; i < MAX_REQUESTS; i++) { 6111 final PendingIntent pendingIntent = PendingIntent.getBroadcast( 6112 mContext, 0 /* requestCode */, new Intent("f" + i), FLAG_IMMUTABLE); 6113 mCm.registerNetworkCallback(networkRequest, pendingIntent); 6114 mCm.unregisterNetworkCallback(pendingIntent); 6115 } 6116 } 6117 6118 @Test 6119 public void testNetworkInfoOfTypeNone() throws Exception { 6120 ExpectedBroadcast b = registerConnectivityBroadcast(1); 6121 6122 verifyNoNetwork(); 6123 TestNetworkAgentWrapper wifiAware = new TestNetworkAgentWrapper(TRANSPORT_WIFI_AWARE); 6124 assertNull(mCm.getActiveNetworkInfo()); 6125 6126 Network[] allNetworks = mCm.getAllNetworks(); 6127 assertLength(1, allNetworks); 6128 Network network = allNetworks[0]; 6129 NetworkCapabilities capabilities = mCm.getNetworkCapabilities(network); 6130 assertTrue(capabilities.hasTransport(TRANSPORT_WIFI_AWARE)); 6131 6132 final NetworkRequest request = 6133 new NetworkRequest.Builder().addTransportType(TRANSPORT_WIFI_AWARE).build(); 6134 final TestNetworkCallback callback = new TestNetworkCallback(); 6135 mCm.registerNetworkCallback(request, callback); 6136 6137 // Bring up wifi aware network. 6138 wifiAware.connect(false, false, false /* isStrictMode */); 6139 callback.expectAvailableCallbacksUnvalidated(wifiAware); 6140 6141 assertNull(mCm.getActiveNetworkInfo()); 6142 assertNull(mCm.getActiveNetwork()); 6143 // TODO: getAllNetworkInfo is dirty and returns a non-empty array right from the start 6144 // of this test. Fix it and uncomment the assert below. 6145 //assertEmpty(mCm.getAllNetworkInfo()); 6146 6147 // Disconnect wifi aware network. 6148 wifiAware.disconnect(); 6149 callback.expectCallbackThat(TIMEOUT_MS, (info) -> info instanceof CallbackEntry.Lost); 6150 mCm.unregisterNetworkCallback(callback); 6151 6152 verifyNoNetwork(); 6153 b.expectNoBroadcast(10); 6154 } 6155 6156 @Test 6157 public void testDeprecatedAndUnsupportedOperations() throws Exception { 6158 final int TYPE_NONE = ConnectivityManager.TYPE_NONE; 6159 assertNull(mCm.getNetworkInfo(TYPE_NONE)); 6160 assertNull(mCm.getNetworkForType(TYPE_NONE)); 6161 assertNull(mCm.getLinkProperties(TYPE_NONE)); 6162 assertFalse(mCm.isNetworkSupported(TYPE_NONE)); 6163 6164 assertThrows(IllegalArgumentException.class, 6165 () -> mCm.networkCapabilitiesForType(TYPE_NONE)); 6166 6167 Class<UnsupportedOperationException> unsupported = UnsupportedOperationException.class; 6168 assertThrows(unsupported, () -> mCm.startUsingNetworkFeature(TYPE_WIFI, "")); 6169 assertThrows(unsupported, () -> mCm.stopUsingNetworkFeature(TYPE_WIFI, "")); 6170 // TODO: let test context have configuration application target sdk version 6171 // and test that pre-M requesting for TYPE_NONE sends back APN_REQUEST_FAILED 6172 assertThrows(unsupported, () -> mCm.startUsingNetworkFeature(TYPE_NONE, "")); 6173 assertThrows(unsupported, () -> mCm.stopUsingNetworkFeature(TYPE_NONE, "")); 6174 assertThrows(unsupported, () -> mCm.requestRouteToHostAddress(TYPE_NONE, null)); 6175 } 6176 6177 @Test 6178 public void testLinkPropertiesEnsuresDirectlyConnectedRoutes() throws Exception { 6179 final NetworkRequest networkRequest = new NetworkRequest.Builder() 6180 .addTransportType(TRANSPORT_WIFI).build(); 6181 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 6182 mCm.registerNetworkCallback(networkRequest, networkCallback); 6183 6184 LinkProperties lp = new LinkProperties(); 6185 lp.setInterfaceName(WIFI_IFNAME); 6186 LinkAddress myIpv4Address = new LinkAddress("192.168.12.3/24"); 6187 RouteInfo myIpv4DefaultRoute = new RouteInfo((IpPrefix) null, 6188 InetAddresses.parseNumericAddress("192.168.12.1"), lp.getInterfaceName()); 6189 lp.addLinkAddress(myIpv4Address); 6190 lp.addRoute(myIpv4DefaultRoute); 6191 6192 // Verify direct routes are added when network agent is first registered in 6193 // ConnectivityService. 6194 TestNetworkAgentWrapper networkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, lp); 6195 networkAgent.connect(true); 6196 networkCallback.expectCallback(CallbackEntry.AVAILABLE, networkAgent); 6197 networkCallback.expectCallback(CallbackEntry.NETWORK_CAPS_UPDATED, networkAgent); 6198 CallbackEntry.LinkPropertiesChanged cbi = 6199 networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, 6200 networkAgent); 6201 networkCallback.expectCallback(CallbackEntry.BLOCKED_STATUS, networkAgent); 6202 networkCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, networkAgent); 6203 networkCallback.assertNoCallback(); 6204 checkDirectlyConnectedRoutes(cbi.getLp(), Arrays.asList(myIpv4Address), 6205 Arrays.asList(myIpv4DefaultRoute)); 6206 checkDirectlyConnectedRoutes(mCm.getLinkProperties(networkAgent.getNetwork()), 6207 Arrays.asList(myIpv4Address), Arrays.asList(myIpv4DefaultRoute)); 6208 6209 // Verify direct routes are added during subsequent link properties updates. 6210 LinkProperties newLp = new LinkProperties(lp); 6211 LinkAddress myIpv6Address1 = new LinkAddress("fe80::cafe/64"); 6212 LinkAddress myIpv6Address2 = new LinkAddress("2001:db8::2/64"); 6213 newLp.addLinkAddress(myIpv6Address1); 6214 newLp.addLinkAddress(myIpv6Address2); 6215 networkAgent.sendLinkProperties(newLp); 6216 cbi = networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, networkAgent); 6217 networkCallback.assertNoCallback(); 6218 checkDirectlyConnectedRoutes(cbi.getLp(), 6219 Arrays.asList(myIpv4Address, myIpv6Address1, myIpv6Address2), 6220 Arrays.asList(myIpv4DefaultRoute)); 6221 mCm.unregisterNetworkCallback(networkCallback); 6222 } 6223 6224 private void expectNotifyNetworkStatus(List<Network> networks, String defaultIface, 6225 Integer vpnUid, String vpnIfname, List<String> underlyingIfaces) throws Exception { 6226 ArgumentCaptor<List<Network>> networksCaptor = ArgumentCaptor.forClass(List.class); 6227 ArgumentCaptor<List<UnderlyingNetworkInfo>> vpnInfosCaptor = 6228 ArgumentCaptor.forClass(List.class); 6229 6230 verify(mStatsManager, atLeastOnce()).notifyNetworkStatus(networksCaptor.capture(), 6231 any(List.class), eq(defaultIface), vpnInfosCaptor.capture()); 6232 6233 assertSameElements(networks, networksCaptor.getValue()); 6234 6235 List<UnderlyingNetworkInfo> infos = vpnInfosCaptor.getValue(); 6236 if (vpnUid != null) { 6237 assertEquals("Should have exactly one VPN:", 1, infos.size()); 6238 UnderlyingNetworkInfo info = infos.get(0); 6239 assertEquals("Unexpected VPN owner:", (int) vpnUid, info.getOwnerUid()); 6240 assertEquals("Unexpected VPN interface:", vpnIfname, info.getInterface()); 6241 assertSameElements(underlyingIfaces, info.getUnderlyingInterfaces()); 6242 } else { 6243 assertEquals(0, infos.size()); 6244 return; 6245 } 6246 } 6247 6248 private void expectNotifyNetworkStatus( 6249 List<Network> networks, String defaultIface) throws Exception { 6250 expectNotifyNetworkStatus(networks, defaultIface, null, null, List.of()); 6251 } 6252 6253 @Test 6254 public void testStatsIfacesChanged() throws Exception { 6255 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 6256 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 6257 6258 final List<Network> onlyCell = List.of(mCellNetworkAgent.getNetwork()); 6259 final List<Network> onlyWifi = List.of(mWiFiNetworkAgent.getNetwork()); 6260 6261 LinkProperties cellLp = new LinkProperties(); 6262 cellLp.setInterfaceName(MOBILE_IFNAME); 6263 LinkProperties wifiLp = new LinkProperties(); 6264 wifiLp.setInterfaceName(WIFI_IFNAME); 6265 6266 // Simple connection should have updated ifaces 6267 mCellNetworkAgent.connect(false); 6268 mCellNetworkAgent.sendLinkProperties(cellLp); 6269 waitForIdle(); 6270 expectNotifyNetworkStatus(onlyCell, MOBILE_IFNAME); 6271 reset(mStatsManager); 6272 6273 // Default network switch should update ifaces. 6274 mWiFiNetworkAgent.connect(false); 6275 mWiFiNetworkAgent.sendLinkProperties(wifiLp); 6276 waitForIdle(); 6277 assertEquals(wifiLp, mService.getActiveLinkProperties()); 6278 expectNotifyNetworkStatus(onlyWifi, WIFI_IFNAME); 6279 reset(mStatsManager); 6280 6281 // Disconnect should update ifaces. 6282 mWiFiNetworkAgent.disconnect(); 6283 waitForIdle(); 6284 expectNotifyNetworkStatus(onlyCell, MOBILE_IFNAME); 6285 reset(mStatsManager); 6286 6287 // Metered change should update ifaces 6288 mCellNetworkAgent.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED); 6289 waitForIdle(); 6290 expectNotifyNetworkStatus(onlyCell, MOBILE_IFNAME); 6291 reset(mStatsManager); 6292 6293 mCellNetworkAgent.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED); 6294 waitForIdle(); 6295 expectNotifyNetworkStatus(onlyCell, MOBILE_IFNAME); 6296 reset(mStatsManager); 6297 6298 // Temp metered change shouldn't update ifaces 6299 mCellNetworkAgent.addCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED); 6300 waitForIdle(); 6301 verify(mStatsManager, never()).notifyNetworkStatus(eq(onlyCell), 6302 any(List.class), eq(MOBILE_IFNAME), any(List.class)); 6303 reset(mStatsManager); 6304 6305 // Roaming change should update ifaces 6306 mCellNetworkAgent.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING); 6307 waitForIdle(); 6308 expectNotifyNetworkStatus(onlyCell, MOBILE_IFNAME); 6309 reset(mStatsManager); 6310 6311 // Test VPNs. 6312 final LinkProperties lp = new LinkProperties(); 6313 lp.setInterfaceName(VPN_IFNAME); 6314 6315 mMockVpn.establishForMyUid(lp); 6316 assertUidRangesUpdatedForMyUid(true); 6317 6318 final List<Network> cellAndVpn = 6319 List.of(mCellNetworkAgent.getNetwork(), mMockVpn.getNetwork()); 6320 6321 // A VPN with default (null) underlying networks sets the underlying network's interfaces... 6322 expectNotifyNetworkStatus(cellAndVpn, MOBILE_IFNAME, Process.myUid(), VPN_IFNAME, 6323 List.of(MOBILE_IFNAME)); 6324 6325 // ...and updates them as the default network switches. 6326 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 6327 mWiFiNetworkAgent.connect(false); 6328 mWiFiNetworkAgent.sendLinkProperties(wifiLp); 6329 final Network[] onlyNull = new Network[]{null}; 6330 final List<Network> wifiAndVpn = 6331 List.of(mWiFiNetworkAgent.getNetwork(), mMockVpn.getNetwork()); 6332 final List<Network> cellAndWifi = 6333 List.of(mCellNetworkAgent.getNetwork(), mWiFiNetworkAgent.getNetwork()); 6334 final Network[] cellNullAndWifi = 6335 new Network[]{mCellNetworkAgent.getNetwork(), null, mWiFiNetworkAgent.getNetwork()}; 6336 6337 waitForIdle(); 6338 assertEquals(wifiLp, mService.getActiveLinkProperties()); 6339 expectNotifyNetworkStatus(wifiAndVpn, WIFI_IFNAME, Process.myUid(), VPN_IFNAME, 6340 List.of(WIFI_IFNAME)); 6341 reset(mStatsManager); 6342 6343 // A VPN that sets its underlying networks passes the underlying interfaces, and influences 6344 // the default interface sent to NetworkStatsService by virtue of applying to the system 6345 // server UID (or, in this test, to the test's UID). This is the reason for sending 6346 // MOBILE_IFNAME even though the default network is wifi. 6347 // TODO: fix this to pass in the actual default network interface. Whether or not the VPN 6348 // applies to the system server UID should not have any bearing on network stats. 6349 mMockVpn.setUnderlyingNetworks(onlyCell.toArray(new Network[0])); 6350 waitForIdle(); 6351 expectNotifyNetworkStatus(wifiAndVpn, MOBILE_IFNAME, Process.myUid(), VPN_IFNAME, 6352 List.of(MOBILE_IFNAME)); 6353 reset(mStatsManager); 6354 6355 mMockVpn.setUnderlyingNetworks(cellAndWifi.toArray(new Network[0])); 6356 waitForIdle(); 6357 expectNotifyNetworkStatus(wifiAndVpn, MOBILE_IFNAME, Process.myUid(), VPN_IFNAME, 6358 List.of(MOBILE_IFNAME, WIFI_IFNAME)); 6359 reset(mStatsManager); 6360 6361 // Null underlying networks are ignored. 6362 mMockVpn.setUnderlyingNetworks(cellNullAndWifi); 6363 waitForIdle(); 6364 expectNotifyNetworkStatus(wifiAndVpn, MOBILE_IFNAME, Process.myUid(), VPN_IFNAME, 6365 List.of(MOBILE_IFNAME, WIFI_IFNAME)); 6366 reset(mStatsManager); 6367 6368 // If an underlying network disconnects, that interface should no longer be underlying. 6369 // This doesn't actually work because disconnectAndDestroyNetwork only notifies 6370 // NetworkStatsService before the underlying network is actually removed. So the underlying 6371 // network will only be removed if notifyIfacesChangedForNetworkStats is called again. This 6372 // could result in incorrect data usage measurements if the interface used by the 6373 // disconnected network is reused by a system component that does not register an agent for 6374 // it (e.g., tethering). 6375 mCellNetworkAgent.disconnect(); 6376 waitForIdle(); 6377 assertNull(mService.getLinkProperties(mCellNetworkAgent.getNetwork())); 6378 expectNotifyNetworkStatus(wifiAndVpn, MOBILE_IFNAME, Process.myUid(), VPN_IFNAME, 6379 List.of(MOBILE_IFNAME, WIFI_IFNAME)); 6380 6381 // Confirm that we never tell NetworkStatsService that cell is no longer the underlying 6382 // network for the VPN... 6383 verify(mStatsManager, never()).notifyNetworkStatus(any(List.class), 6384 any(List.class), any() /* anyString() doesn't match null */, 6385 argThat(infos -> infos.get(0).getUnderlyingInterfaces().size() == 1 6386 && WIFI_IFNAME.equals(infos.get(0).getUnderlyingInterfaces().get(0)))); 6387 verifyNoMoreInteractions(mStatsManager); 6388 reset(mStatsManager); 6389 6390 // ... but if something else happens that causes notifyIfacesChangedForNetworkStats to be 6391 // called again, it does. For example, connect Ethernet, but with a low score, such that it 6392 // does not become the default network. 6393 mEthernetNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_ETHERNET); 6394 mEthernetNetworkAgent.setScore( 6395 new NetworkScore.Builder().setLegacyInt(30).setExiting(true).build()); 6396 mEthernetNetworkAgent.connect(false); 6397 waitForIdle(); 6398 verify(mStatsManager).notifyNetworkStatus(any(List.class), 6399 any(List.class), any() /* anyString() doesn't match null */, 6400 argThat(vpnInfos -> vpnInfos.get(0).getUnderlyingInterfaces().size() == 1 6401 && WIFI_IFNAME.equals(vpnInfos.get(0).getUnderlyingInterfaces().get(0)))); 6402 mEthernetNetworkAgent.disconnect(); 6403 waitForIdle(); 6404 reset(mStatsManager); 6405 6406 // When a VPN declares no underlying networks (i.e., no connectivity), getAllVpnInfo 6407 // does not return the VPN, so CS does not pass it to NetworkStatsService. This causes 6408 // NetworkStatsFactory#adjustForTunAnd464Xlat not to attempt any VPN data migration, which 6409 // is probably a performance improvement (though it's very unlikely that a VPN would declare 6410 // no underlying networks). 6411 // Also, for the same reason as above, the active interface passed in is null. 6412 mMockVpn.setUnderlyingNetworks(new Network[0]); 6413 waitForIdle(); 6414 expectNotifyNetworkStatus(wifiAndVpn, null); 6415 reset(mStatsManager); 6416 6417 // Specifying only a null underlying network is the same as no networks. 6418 mMockVpn.setUnderlyingNetworks(onlyNull); 6419 waitForIdle(); 6420 expectNotifyNetworkStatus(wifiAndVpn, null); 6421 reset(mStatsManager); 6422 6423 // Specifying networks that are all disconnected is the same as specifying no networks. 6424 mMockVpn.setUnderlyingNetworks(onlyCell.toArray(new Network[0])); 6425 waitForIdle(); 6426 expectNotifyNetworkStatus(wifiAndVpn, null); 6427 reset(mStatsManager); 6428 6429 // Passing in null again means follow the default network again. 6430 mMockVpn.setUnderlyingNetworks(null); 6431 waitForIdle(); 6432 expectNotifyNetworkStatus(wifiAndVpn, WIFI_IFNAME, Process.myUid(), VPN_IFNAME, 6433 List.of(WIFI_IFNAME)); 6434 reset(mStatsManager); 6435 } 6436 6437 @Test 6438 public void testNonVpnUnderlyingNetworks() throws Exception { 6439 // Ensure wifi and cellular are not torn down. 6440 for (int transport : new int[]{TRANSPORT_CELLULAR, TRANSPORT_WIFI}) { 6441 final NetworkRequest request = new NetworkRequest.Builder() 6442 .addTransportType(transport) 6443 .removeCapability(NET_CAPABILITY_NOT_VCN_MANAGED) 6444 .build(); 6445 mCm.requestNetwork(request, new NetworkCallback()); 6446 } 6447 6448 // Connect a VCN-managed wifi network. 6449 final LinkProperties wifiLp = new LinkProperties(); 6450 wifiLp.setInterfaceName(WIFI_IFNAME); 6451 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, wifiLp); 6452 mWiFiNetworkAgent.removeCapability(NET_CAPABILITY_NOT_VCN_MANAGED); 6453 mWiFiNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED); 6454 mWiFiNetworkAgent.connect(true /* validated */); 6455 6456 final List<Network> none = List.of(); 6457 expectNotifyNetworkStatus(none, null); // Wifi is not the default network 6458 6459 // Create a virtual network based on the wifi network. 6460 final int ownerUid = 10042; 6461 NetworkCapabilities nc = new NetworkCapabilities.Builder() 6462 .setOwnerUid(ownerUid) 6463 .setAdministratorUids(new int[]{ownerUid}) 6464 .build(); 6465 final String vcnIface = "ipsec42"; 6466 final LinkProperties lp = new LinkProperties(); 6467 lp.setInterfaceName(vcnIface); 6468 final TestNetworkAgentWrapper vcn = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, lp, nc); 6469 vcn.setUnderlyingNetworks(List.of(mWiFiNetworkAgent.getNetwork())); 6470 vcn.connect(false /* validated */); 6471 6472 final TestNetworkCallback callback = new TestNetworkCallback(); 6473 mCm.registerDefaultNetworkCallback(callback); 6474 callback.expectAvailableCallbacksUnvalidated(vcn); 6475 6476 // The underlying wifi network's capabilities are not propagated to the virtual network, 6477 // but NetworkStatsService is informed of the underlying interface. 6478 nc = mCm.getNetworkCapabilities(vcn.getNetwork()); 6479 assertFalse(nc.hasTransport(TRANSPORT_WIFI)); 6480 assertFalse(nc.hasCapability(NET_CAPABILITY_NOT_METERED)); 6481 final List<Network> onlyVcn = List.of(vcn.getNetwork()); 6482 expectNotifyNetworkStatus(onlyVcn, vcnIface, ownerUid, vcnIface, List.of(WIFI_IFNAME)); 6483 6484 // Add NOT_METERED to the underlying network, check that it is not propagated. 6485 mWiFiNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED); 6486 callback.assertNoCallback(); 6487 nc = mCm.getNetworkCapabilities(vcn.getNetwork()); 6488 assertFalse(nc.hasCapability(NET_CAPABILITY_NOT_METERED)); 6489 6490 // Switch underlying networks. 6491 final LinkProperties cellLp = new LinkProperties(); 6492 cellLp.setInterfaceName(MOBILE_IFNAME); 6493 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp); 6494 mCellNetworkAgent.removeCapability(NET_CAPABILITY_NOT_VCN_MANAGED); 6495 mCellNetworkAgent.addCapability(NET_CAPABILITY_NOT_ROAMING); 6496 mCellNetworkAgent.connect(false /* validated */); 6497 vcn.setUnderlyingNetworks(List.of(mCellNetworkAgent.getNetwork())); 6498 6499 // The underlying capability changes do not propagate to the virtual network, but 6500 // NetworkStatsService is informed of the new underlying interface. 6501 callback.assertNoCallback(); 6502 nc = mCm.getNetworkCapabilities(vcn.getNetwork()); 6503 assertFalse(nc.hasTransport(TRANSPORT_WIFI)); 6504 assertFalse(nc.hasCapability(NET_CAPABILITY_NOT_ROAMING)); 6505 expectNotifyNetworkStatus(onlyVcn, vcnIface, ownerUid, vcnIface, List.of(MOBILE_IFNAME)); 6506 } 6507 6508 @Test 6509 public void testBasicDnsConfigurationPushed() throws Exception { 6510 setPrivateDnsSettings(PRIVATE_DNS_MODE_OPPORTUNISTIC, "ignored.example.com"); 6511 6512 // Clear any interactions that occur as a result of CS starting up. 6513 reset(mMockDnsResolver); 6514 6515 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 6516 waitForIdle(); 6517 verify(mMockDnsResolver, never()).setResolverConfiguration(any()); 6518 verifyNoMoreInteractions(mMockDnsResolver); 6519 6520 final LinkProperties cellLp = new LinkProperties(); 6521 cellLp.setInterfaceName(MOBILE_IFNAME); 6522 // Add IPv4 and IPv6 default routes, because DNS-over-TLS code does 6523 // "is-reachable" testing in order to not program netd with unreachable 6524 // nameservers that it might try repeated to validate. 6525 cellLp.addLinkAddress(new LinkAddress("192.0.2.4/24")); 6526 cellLp.addRoute(new RouteInfo((IpPrefix) null, InetAddress.getByName("192.0.2.4"), 6527 MOBILE_IFNAME)); 6528 cellLp.addLinkAddress(new LinkAddress("2001:db8:1::1/64")); 6529 cellLp.addRoute(new RouteInfo((IpPrefix) null, InetAddress.getByName("2001:db8:1::1"), 6530 MOBILE_IFNAME)); 6531 mCellNetworkAgent.sendLinkProperties(cellLp); 6532 mCellNetworkAgent.connect(false); 6533 waitForIdle(); 6534 6535 verify(mMockDnsResolver, times(1)).createNetworkCache( 6536 eq(mCellNetworkAgent.getNetwork().netId)); 6537 // CS tells dnsresolver about the empty DNS config for this network. 6538 verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration(any()); 6539 reset(mMockDnsResolver); 6540 6541 cellLp.addDnsServer(InetAddress.getByName("2001:db8::1")); 6542 mCellNetworkAgent.sendLinkProperties(cellLp); 6543 waitForIdle(); 6544 verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration( 6545 mResolverParamsParcelCaptor.capture()); 6546 ResolverParamsParcel resolvrParams = mResolverParamsParcelCaptor.getValue(); 6547 assertEquals(1, resolvrParams.servers.length); 6548 assertTrue(ArrayUtils.contains(resolvrParams.servers, "2001:db8::1")); 6549 // Opportunistic mode. 6550 assertTrue(ArrayUtils.contains(resolvrParams.tlsServers, "2001:db8::1")); 6551 reset(mMockDnsResolver); 6552 6553 cellLp.addDnsServer(InetAddress.getByName("192.0.2.1")); 6554 mCellNetworkAgent.sendLinkProperties(cellLp); 6555 waitForIdle(); 6556 verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration( 6557 mResolverParamsParcelCaptor.capture()); 6558 resolvrParams = mResolverParamsParcelCaptor.getValue(); 6559 assertEquals(2, resolvrParams.servers.length); 6560 assertTrue(ArrayUtils.containsAll(resolvrParams.servers, 6561 new String[]{"2001:db8::1", "192.0.2.1"})); 6562 // Opportunistic mode. 6563 assertEquals(2, resolvrParams.tlsServers.length); 6564 assertTrue(ArrayUtils.containsAll(resolvrParams.tlsServers, 6565 new String[]{"2001:db8::1", "192.0.2.1"})); 6566 reset(mMockDnsResolver); 6567 6568 final String TLS_SPECIFIER = "tls.example.com"; 6569 final String TLS_SERVER6 = "2001:db8:53::53"; 6570 final InetAddress[] TLS_IPS = new InetAddress[]{ InetAddress.getByName(TLS_SERVER6) }; 6571 final String[] TLS_SERVERS = new String[]{ TLS_SERVER6 }; 6572 mCellNetworkAgent.mNmCallbacks.notifyPrivateDnsConfigResolved( 6573 new PrivateDnsConfig(TLS_SPECIFIER, TLS_IPS).toParcel()); 6574 6575 waitForIdle(); 6576 verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration( 6577 mResolverParamsParcelCaptor.capture()); 6578 resolvrParams = mResolverParamsParcelCaptor.getValue(); 6579 assertEquals(2, resolvrParams.servers.length); 6580 assertTrue(ArrayUtils.containsAll(resolvrParams.servers, 6581 new String[]{"2001:db8::1", "192.0.2.1"})); 6582 reset(mMockDnsResolver); 6583 } 6584 6585 @Test 6586 public void testDnsConfigurationTransTypesPushed() throws Exception { 6587 // Clear any interactions that occur as a result of CS starting up. 6588 reset(mMockDnsResolver); 6589 6590 final NetworkRequest request = new NetworkRequest.Builder() 6591 .clearCapabilities().addCapability(NET_CAPABILITY_INTERNET) 6592 .build(); 6593 final TestNetworkCallback callback = new TestNetworkCallback(); 6594 mCm.registerNetworkCallback(request, callback); 6595 6596 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 6597 mWiFiNetworkAgent.connect(false); 6598 callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 6599 verify(mMockDnsResolver, times(1)).createNetworkCache( 6600 eq(mWiFiNetworkAgent.getNetwork().netId)); 6601 verify(mMockDnsResolver, times(2)).setResolverConfiguration( 6602 mResolverParamsParcelCaptor.capture()); 6603 final ResolverParamsParcel resolverParams = mResolverParamsParcelCaptor.getValue(); 6604 assertContainsExactly(resolverParams.transportTypes, TRANSPORT_WIFI); 6605 reset(mMockDnsResolver); 6606 } 6607 6608 @Test 6609 public void testPrivateDnsNotification() throws Exception { 6610 NetworkRequest request = new NetworkRequest.Builder() 6611 .clearCapabilities().addCapability(NET_CAPABILITY_INTERNET) 6612 .build(); 6613 TestNetworkCallback callback = new TestNetworkCallback(); 6614 mCm.registerNetworkCallback(request, callback); 6615 // Bring up wifi. 6616 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 6617 mWiFiNetworkAgent.connect(false); 6618 callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 6619 // Private DNS resolution failed, checking if the notification will be shown or not. 6620 mWiFiNetworkAgent.setNetworkInvalid(true /* isStrictMode */); 6621 mWiFiNetworkAgent.mNetworkMonitor.forceReevaluation(Process.myUid()); 6622 waitForIdle(); 6623 // If network validation failed, NetworkMonitor will re-evaluate the network. 6624 // ConnectivityService should filter the redundant notification. This part is trying to 6625 // simulate that situation and check if ConnectivityService could filter that case. 6626 mWiFiNetworkAgent.mNetworkMonitor.forceReevaluation(Process.myUid()); 6627 waitForIdle(); 6628 verify(mNotificationManager, timeout(TIMEOUT_MS).times(1)).notify(anyString(), 6629 eq(NotificationType.PRIVATE_DNS_BROKEN.eventId), any()); 6630 // If private DNS resolution successful, the PRIVATE_DNS_BROKEN notification shouldn't be 6631 // shown. 6632 mWiFiNetworkAgent.setNetworkValid(true /* isStrictMode */); 6633 mWiFiNetworkAgent.mNetworkMonitor.forceReevaluation(Process.myUid()); 6634 waitForIdle(); 6635 verify(mNotificationManager, timeout(TIMEOUT_MS).times(1)).cancel(anyString(), 6636 eq(NotificationType.PRIVATE_DNS_BROKEN.eventId)); 6637 // If private DNS resolution failed again, the PRIVATE_DNS_BROKEN notification should be 6638 // shown again. 6639 mWiFiNetworkAgent.setNetworkInvalid(true /* isStrictMode */); 6640 mWiFiNetworkAgent.mNetworkMonitor.forceReevaluation(Process.myUid()); 6641 waitForIdle(); 6642 verify(mNotificationManager, timeout(TIMEOUT_MS).times(2)).notify(anyString(), 6643 eq(NotificationType.PRIVATE_DNS_BROKEN.eventId), any()); 6644 } 6645 6646 @Test 6647 public void testPrivateDnsSettingsChange() throws Exception { 6648 // Clear any interactions that occur as a result of CS starting up. 6649 reset(mMockDnsResolver); 6650 6651 // The default on Android is opportunistic mode ("Automatic"). 6652 setPrivateDnsSettings(PRIVATE_DNS_MODE_OPPORTUNISTIC, "ignored.example.com"); 6653 6654 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback(); 6655 final NetworkRequest cellRequest = new NetworkRequest.Builder() 6656 .addTransportType(TRANSPORT_CELLULAR).build(); 6657 mCm.requestNetwork(cellRequest, cellNetworkCallback); 6658 6659 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 6660 waitForIdle(); 6661 // CS tells netd about the empty DNS config for this network. 6662 verify(mMockDnsResolver, never()).setResolverConfiguration(any()); 6663 verifyNoMoreInteractions(mMockDnsResolver); 6664 6665 final LinkProperties cellLp = new LinkProperties(); 6666 cellLp.setInterfaceName(MOBILE_IFNAME); 6667 // Add IPv4 and IPv6 default routes, because DNS-over-TLS code does 6668 // "is-reachable" testing in order to not program netd with unreachable 6669 // nameservers that it might try repeated to validate. 6670 cellLp.addLinkAddress(new LinkAddress("192.0.2.4/24")); 6671 cellLp.addRoute(new RouteInfo((IpPrefix) null, InetAddress.getByName("192.0.2.4"), 6672 MOBILE_IFNAME)); 6673 cellLp.addLinkAddress(new LinkAddress("2001:db8:1::1/64")); 6674 cellLp.addRoute(new RouteInfo((IpPrefix) null, InetAddress.getByName("2001:db8:1::1"), 6675 MOBILE_IFNAME)); 6676 cellLp.addDnsServer(InetAddress.getByName("2001:db8::1")); 6677 cellLp.addDnsServer(InetAddress.getByName("192.0.2.1")); 6678 6679 mCellNetworkAgent.sendLinkProperties(cellLp); 6680 mCellNetworkAgent.connect(false); 6681 waitForIdle(); 6682 verify(mMockDnsResolver, times(1)).createNetworkCache( 6683 eq(mCellNetworkAgent.getNetwork().netId)); 6684 verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration( 6685 mResolverParamsParcelCaptor.capture()); 6686 ResolverParamsParcel resolvrParams = mResolverParamsParcelCaptor.getValue(); 6687 assertEquals(2, resolvrParams.tlsServers.length); 6688 assertTrue(ArrayUtils.containsAll(resolvrParams.tlsServers, 6689 new String[] { "2001:db8::1", "192.0.2.1" })); 6690 // Opportunistic mode. 6691 assertEquals(2, resolvrParams.tlsServers.length); 6692 assertTrue(ArrayUtils.containsAll(resolvrParams.tlsServers, 6693 new String[] { "2001:db8::1", "192.0.2.1" })); 6694 reset(mMockDnsResolver); 6695 cellNetworkCallback.expectCallback(CallbackEntry.AVAILABLE, mCellNetworkAgent); 6696 cellNetworkCallback.expectCallback(CallbackEntry.NETWORK_CAPS_UPDATED, 6697 mCellNetworkAgent); 6698 CallbackEntry.LinkPropertiesChanged cbi = cellNetworkCallback.expectCallback( 6699 CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent); 6700 cellNetworkCallback.expectCallback(CallbackEntry.BLOCKED_STATUS, mCellNetworkAgent); 6701 cellNetworkCallback.assertNoCallback(); 6702 assertFalse(cbi.getLp().isPrivateDnsActive()); 6703 assertNull(cbi.getLp().getPrivateDnsServerName()); 6704 6705 setPrivateDnsSettings(PRIVATE_DNS_MODE_OFF, "ignored.example.com"); 6706 verify(mMockDnsResolver, times(1)).setResolverConfiguration( 6707 mResolverParamsParcelCaptor.capture()); 6708 resolvrParams = mResolverParamsParcelCaptor.getValue(); 6709 assertEquals(2, resolvrParams.servers.length); 6710 assertTrue(ArrayUtils.containsAll(resolvrParams.servers, 6711 new String[] { "2001:db8::1", "192.0.2.1" })); 6712 reset(mMockDnsResolver); 6713 cellNetworkCallback.assertNoCallback(); 6714 6715 setPrivateDnsSettings(PRIVATE_DNS_MODE_OPPORTUNISTIC, "ignored.example.com"); 6716 verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration( 6717 mResolverParamsParcelCaptor.capture()); 6718 resolvrParams = mResolverParamsParcelCaptor.getValue(); 6719 assertEquals(2, resolvrParams.servers.length); 6720 assertTrue(ArrayUtils.containsAll(resolvrParams.servers, 6721 new String[] { "2001:db8::1", "192.0.2.1" })); 6722 assertEquals(2, resolvrParams.tlsServers.length); 6723 assertTrue(ArrayUtils.containsAll(resolvrParams.tlsServers, 6724 new String[] { "2001:db8::1", "192.0.2.1" })); 6725 reset(mMockDnsResolver); 6726 cellNetworkCallback.assertNoCallback(); 6727 6728 setPrivateDnsSettings(PRIVATE_DNS_MODE_PROVIDER_HOSTNAME, "strict.example.com"); 6729 // Can't test dns configuration for strict mode without properly mocking 6730 // out the DNS lookups, but can test that LinkProperties is updated. 6731 cbi = cellNetworkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, 6732 mCellNetworkAgent); 6733 cellNetworkCallback.assertNoCallback(); 6734 assertTrue(cbi.getLp().isPrivateDnsActive()); 6735 assertEquals("strict.example.com", cbi.getLp().getPrivateDnsServerName()); 6736 } 6737 6738 private PrivateDnsValidationEventParcel makePrivateDnsValidationEvent( 6739 final int netId, final String ipAddress, final String hostname, final int validation) { 6740 final PrivateDnsValidationEventParcel event = new PrivateDnsValidationEventParcel(); 6741 event.netId = netId; 6742 event.ipAddress = ipAddress; 6743 event.hostname = hostname; 6744 event.validation = validation; 6745 return event; 6746 } 6747 6748 @Test 6749 public void testLinkPropertiesWithPrivateDnsValidationEvents() throws Exception { 6750 // The default on Android is opportunistic mode ("Automatic"). 6751 setPrivateDnsSettings(PRIVATE_DNS_MODE_OPPORTUNISTIC, "ignored.example.com"); 6752 6753 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback(); 6754 final NetworkRequest cellRequest = new NetworkRequest.Builder() 6755 .addTransportType(TRANSPORT_CELLULAR).build(); 6756 mCm.requestNetwork(cellRequest, cellNetworkCallback); 6757 6758 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 6759 waitForIdle(); 6760 LinkProperties lp = new LinkProperties(); 6761 mCellNetworkAgent.sendLinkProperties(lp); 6762 mCellNetworkAgent.connect(false); 6763 waitForIdle(); 6764 cellNetworkCallback.expectCallback(CallbackEntry.AVAILABLE, mCellNetworkAgent); 6765 cellNetworkCallback.expectCallback(CallbackEntry.NETWORK_CAPS_UPDATED, 6766 mCellNetworkAgent); 6767 CallbackEntry.LinkPropertiesChanged cbi = cellNetworkCallback.expectCallback( 6768 CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent); 6769 cellNetworkCallback.expectCallback(CallbackEntry.BLOCKED_STATUS, mCellNetworkAgent); 6770 cellNetworkCallback.assertNoCallback(); 6771 assertFalse(cbi.getLp().isPrivateDnsActive()); 6772 assertNull(cbi.getLp().getPrivateDnsServerName()); 6773 Set<InetAddress> dnsServers = new HashSet<>(); 6774 checkDnsServers(cbi.getLp(), dnsServers); 6775 6776 // Send a validation event for a server that is not part of the current 6777 // resolver config. The validation event should be ignored. 6778 mService.mResolverUnsolEventCallback.onPrivateDnsValidationEvent( 6779 makePrivateDnsValidationEvent(mCellNetworkAgent.getNetwork().netId, "", 6780 "145.100.185.18", VALIDATION_RESULT_SUCCESS)); 6781 cellNetworkCallback.assertNoCallback(); 6782 6783 // Add a dns server to the LinkProperties. 6784 LinkProperties lp2 = new LinkProperties(lp); 6785 lp2.addDnsServer(InetAddress.getByName("145.100.185.16")); 6786 mCellNetworkAgent.sendLinkProperties(lp2); 6787 cbi = cellNetworkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, 6788 mCellNetworkAgent); 6789 cellNetworkCallback.assertNoCallback(); 6790 assertFalse(cbi.getLp().isPrivateDnsActive()); 6791 assertNull(cbi.getLp().getPrivateDnsServerName()); 6792 dnsServers.add(InetAddress.getByName("145.100.185.16")); 6793 checkDnsServers(cbi.getLp(), dnsServers); 6794 6795 // Send a validation event containing a hostname that is not part of 6796 // the current resolver config. The validation event should be ignored. 6797 mService.mResolverUnsolEventCallback.onPrivateDnsValidationEvent( 6798 makePrivateDnsValidationEvent(mCellNetworkAgent.getNetwork().netId, 6799 "145.100.185.16", "hostname", VALIDATION_RESULT_SUCCESS)); 6800 cellNetworkCallback.assertNoCallback(); 6801 6802 // Send a validation event where validation failed. 6803 mService.mResolverUnsolEventCallback.onPrivateDnsValidationEvent( 6804 makePrivateDnsValidationEvent(mCellNetworkAgent.getNetwork().netId, 6805 "145.100.185.16", "", VALIDATION_RESULT_FAILURE)); 6806 cellNetworkCallback.assertNoCallback(); 6807 6808 // Send a validation event where validation succeeded for a server in 6809 // the current resolver config. A LinkProperties callback with updated 6810 // private dns fields should be sent. 6811 mService.mResolverUnsolEventCallback.onPrivateDnsValidationEvent( 6812 makePrivateDnsValidationEvent(mCellNetworkAgent.getNetwork().netId, 6813 "145.100.185.16", "", VALIDATION_RESULT_SUCCESS)); 6814 cbi = cellNetworkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, 6815 mCellNetworkAgent); 6816 cellNetworkCallback.assertNoCallback(); 6817 assertTrue(cbi.getLp().isPrivateDnsActive()); 6818 assertNull(cbi.getLp().getPrivateDnsServerName()); 6819 checkDnsServers(cbi.getLp(), dnsServers); 6820 6821 // The private dns fields in LinkProperties should be preserved when 6822 // the network agent sends unrelated changes. 6823 LinkProperties lp3 = new LinkProperties(lp2); 6824 lp3.setMtu(1300); 6825 mCellNetworkAgent.sendLinkProperties(lp3); 6826 cbi = cellNetworkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, 6827 mCellNetworkAgent); 6828 cellNetworkCallback.assertNoCallback(); 6829 assertTrue(cbi.getLp().isPrivateDnsActive()); 6830 assertNull(cbi.getLp().getPrivateDnsServerName()); 6831 checkDnsServers(cbi.getLp(), dnsServers); 6832 assertEquals(1300, cbi.getLp().getMtu()); 6833 6834 // Removing the only validated server should affect the private dns 6835 // fields in LinkProperties. 6836 LinkProperties lp4 = new LinkProperties(lp3); 6837 lp4.removeDnsServer(InetAddress.getByName("145.100.185.16")); 6838 mCellNetworkAgent.sendLinkProperties(lp4); 6839 cbi = cellNetworkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, 6840 mCellNetworkAgent); 6841 cellNetworkCallback.assertNoCallback(); 6842 assertFalse(cbi.getLp().isPrivateDnsActive()); 6843 assertNull(cbi.getLp().getPrivateDnsServerName()); 6844 dnsServers.remove(InetAddress.getByName("145.100.185.16")); 6845 checkDnsServers(cbi.getLp(), dnsServers); 6846 assertEquals(1300, cbi.getLp().getMtu()); 6847 } 6848 6849 private void checkDirectlyConnectedRoutes(Object callbackObj, 6850 Collection<LinkAddress> linkAddresses, Collection<RouteInfo> otherRoutes) { 6851 assertTrue(callbackObj instanceof LinkProperties); 6852 LinkProperties lp = (LinkProperties) callbackObj; 6853 6854 Set<RouteInfo> expectedRoutes = new ArraySet<>(); 6855 expectedRoutes.addAll(otherRoutes); 6856 for (LinkAddress address : linkAddresses) { 6857 RouteInfo localRoute = new RouteInfo(address, null, lp.getInterfaceName()); 6858 // Duplicates in linkAddresses are considered failures 6859 assertTrue(expectedRoutes.add(localRoute)); 6860 } 6861 List<RouteInfo> observedRoutes = lp.getRoutes(); 6862 assertEquals(expectedRoutes.size(), observedRoutes.size()); 6863 assertTrue(observedRoutes.containsAll(expectedRoutes)); 6864 } 6865 6866 private static void checkDnsServers(Object callbackObj, Set<InetAddress> dnsServers) { 6867 assertTrue(callbackObj instanceof LinkProperties); 6868 LinkProperties lp = (LinkProperties) callbackObj; 6869 assertEquals(dnsServers.size(), lp.getDnsServers().size()); 6870 assertTrue(lp.getDnsServers().containsAll(dnsServers)); 6871 } 6872 6873 @Test 6874 public void testApplyUnderlyingCapabilities() throws Exception { 6875 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 6876 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 6877 mCellNetworkAgent.connect(false /* validated */); 6878 mWiFiNetworkAgent.connect(false /* validated */); 6879 6880 final NetworkCapabilities cellNc = new NetworkCapabilities() 6881 .addTransportType(TRANSPORT_CELLULAR) 6882 .addCapability(NET_CAPABILITY_INTERNET) 6883 .addCapability(NET_CAPABILITY_NOT_CONGESTED) 6884 .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED) 6885 .setLinkDownstreamBandwidthKbps(10); 6886 final NetworkCapabilities wifiNc = new NetworkCapabilities() 6887 .addTransportType(TRANSPORT_WIFI) 6888 .addCapability(NET_CAPABILITY_INTERNET) 6889 .addCapability(NET_CAPABILITY_NOT_METERED) 6890 .addCapability(NET_CAPABILITY_NOT_ROAMING) 6891 .addCapability(NET_CAPABILITY_NOT_CONGESTED) 6892 .addCapability(NET_CAPABILITY_NOT_SUSPENDED) 6893 .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED) 6894 .setLinkUpstreamBandwidthKbps(20); 6895 mCellNetworkAgent.setNetworkCapabilities(cellNc, true /* sendToConnectivityService */); 6896 mWiFiNetworkAgent.setNetworkCapabilities(wifiNc, true /* sendToConnectivityService */); 6897 waitForIdle(); 6898 6899 final Network mobile = mCellNetworkAgent.getNetwork(); 6900 final Network wifi = mWiFiNetworkAgent.getNetwork(); 6901 6902 final NetworkCapabilities initialCaps = new NetworkCapabilities(); 6903 initialCaps.addTransportType(TRANSPORT_VPN); 6904 initialCaps.addCapability(NET_CAPABILITY_INTERNET); 6905 initialCaps.removeCapability(NET_CAPABILITY_NOT_VPN); 6906 6907 final NetworkCapabilities withNoUnderlying = new NetworkCapabilities(); 6908 withNoUnderlying.addCapability(NET_CAPABILITY_INTERNET); 6909 withNoUnderlying.addCapability(NET_CAPABILITY_NOT_CONGESTED); 6910 withNoUnderlying.addCapability(NET_CAPABILITY_NOT_ROAMING); 6911 withNoUnderlying.addCapability(NET_CAPABILITY_NOT_SUSPENDED); 6912 withNoUnderlying.addTransportType(TRANSPORT_VPN); 6913 withNoUnderlying.removeCapability(NET_CAPABILITY_NOT_VPN); 6914 6915 final NetworkCapabilities withMobileUnderlying = new NetworkCapabilities(withNoUnderlying); 6916 withMobileUnderlying.addTransportType(TRANSPORT_CELLULAR); 6917 withMobileUnderlying.removeCapability(NET_CAPABILITY_NOT_ROAMING); 6918 withMobileUnderlying.removeCapability(NET_CAPABILITY_NOT_SUSPENDED); 6919 withMobileUnderlying.setLinkDownstreamBandwidthKbps(10); 6920 6921 final NetworkCapabilities withWifiUnderlying = new NetworkCapabilities(withNoUnderlying); 6922 withWifiUnderlying.addTransportType(TRANSPORT_WIFI); 6923 withWifiUnderlying.addCapability(NET_CAPABILITY_NOT_METERED); 6924 withWifiUnderlying.setLinkUpstreamBandwidthKbps(20); 6925 6926 final NetworkCapabilities withWifiAndMobileUnderlying = 6927 new NetworkCapabilities(withNoUnderlying); 6928 withWifiAndMobileUnderlying.addTransportType(TRANSPORT_CELLULAR); 6929 withWifiAndMobileUnderlying.addTransportType(TRANSPORT_WIFI); 6930 withWifiAndMobileUnderlying.removeCapability(NET_CAPABILITY_NOT_METERED); 6931 withWifiAndMobileUnderlying.removeCapability(NET_CAPABILITY_NOT_ROAMING); 6932 withWifiAndMobileUnderlying.setLinkDownstreamBandwidthKbps(10); 6933 withWifiAndMobileUnderlying.setLinkUpstreamBandwidthKbps(20); 6934 6935 final NetworkCapabilities initialCapsNotMetered = new NetworkCapabilities(initialCaps); 6936 initialCapsNotMetered.addCapability(NET_CAPABILITY_NOT_METERED); 6937 6938 NetworkCapabilities caps = new NetworkCapabilities(initialCaps); 6939 mService.applyUnderlyingCapabilities(new Network[]{}, initialCapsNotMetered, caps); 6940 assertEquals(withNoUnderlying, caps); 6941 6942 caps = new NetworkCapabilities(initialCaps); 6943 mService.applyUnderlyingCapabilities(new Network[]{null}, initialCapsNotMetered, caps); 6944 assertEquals(withNoUnderlying, caps); 6945 6946 caps = new NetworkCapabilities(initialCaps); 6947 mService.applyUnderlyingCapabilities(new Network[]{mobile}, initialCapsNotMetered, caps); 6948 assertEquals(withMobileUnderlying, caps); 6949 6950 mService.applyUnderlyingCapabilities(new Network[]{wifi}, initialCapsNotMetered, caps); 6951 assertEquals(withWifiUnderlying, caps); 6952 6953 withWifiUnderlying.removeCapability(NET_CAPABILITY_NOT_METERED); 6954 caps = new NetworkCapabilities(initialCaps); 6955 mService.applyUnderlyingCapabilities(new Network[]{wifi}, initialCaps, caps); 6956 assertEquals(withWifiUnderlying, caps); 6957 6958 caps = new NetworkCapabilities(initialCaps); 6959 mService.applyUnderlyingCapabilities(new Network[]{mobile, wifi}, initialCaps, caps); 6960 assertEquals(withWifiAndMobileUnderlying, caps); 6961 6962 withWifiUnderlying.addCapability(NET_CAPABILITY_NOT_METERED); 6963 caps = new NetworkCapabilities(initialCaps); 6964 mService.applyUnderlyingCapabilities(new Network[]{null, mobile, null, wifi}, 6965 initialCapsNotMetered, caps); 6966 assertEquals(withWifiAndMobileUnderlying, caps); 6967 6968 caps = new NetworkCapabilities(initialCaps); 6969 mService.applyUnderlyingCapabilities(new Network[]{null, mobile, null, wifi}, 6970 initialCapsNotMetered, caps); 6971 assertEquals(withWifiAndMobileUnderlying, caps); 6972 6973 mService.applyUnderlyingCapabilities(null, initialCapsNotMetered, caps); 6974 assertEquals(withWifiUnderlying, caps); 6975 } 6976 6977 @Test 6978 public void testVpnConnectDisconnectUnderlyingNetwork() throws Exception { 6979 final TestNetworkCallback callback = new TestNetworkCallback(); 6980 final NetworkRequest request = new NetworkRequest.Builder() 6981 .removeCapability(NET_CAPABILITY_NOT_VPN).build(); 6982 6983 mCm.registerNetworkCallback(request, callback); 6984 6985 // Bring up a VPN that specifies an underlying network that does not exist yet. 6986 // Note: it's sort of meaningless for a VPN app to declare a network that doesn't exist yet, 6987 // (and doing so is difficult without using reflection) but it's good to test that the code 6988 // behaves approximately correctly. 6989 mMockVpn.establishForMyUid(false, true, false); 6990 assertUidRangesUpdatedForMyUid(true); 6991 final Network wifiNetwork = new Network(mNetIdManager.peekNextNetId()); 6992 mMockVpn.setUnderlyingNetworks(new Network[]{wifiNetwork}); 6993 callback.expectAvailableCallbacksUnvalidated(mMockVpn); 6994 assertTrue(mCm.getNetworkCapabilities(mMockVpn.getNetwork()) 6995 .hasTransport(TRANSPORT_VPN)); 6996 assertFalse(mCm.getNetworkCapabilities(mMockVpn.getNetwork()) 6997 .hasTransport(TRANSPORT_WIFI)); 6998 6999 // Make that underlying network connect, and expect to see its capabilities immediately 7000 // reflected in the VPN's capabilities. 7001 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 7002 assertEquals(wifiNetwork, mWiFiNetworkAgent.getNetwork()); 7003 mWiFiNetworkAgent.connect(false); 7004 // TODO: the callback for the VPN happens before any callbacks are called for the wifi 7005 // network that has just connected. There appear to be two issues here: 7006 // 1. The VPN code will accept an underlying network as soon as getNetworkCapabilities() for 7007 // it returns non-null (which happens very early, during handleRegisterNetworkAgent). 7008 // This is not correct because that that point the network is not connected and cannot 7009 // pass any traffic. 7010 // 2. When a network connects, updateNetworkInfo propagates underlying network capabilities 7011 // before rematching networks. 7012 // Given that this scenario can't really happen, this is probably fine for now. 7013 callback.expectCallback(CallbackEntry.NETWORK_CAPS_UPDATED, mMockVpn); 7014 callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 7015 assertTrue(mCm.getNetworkCapabilities(mMockVpn.getNetwork()) 7016 .hasTransport(TRANSPORT_VPN)); 7017 assertTrue(mCm.getNetworkCapabilities(mMockVpn.getNetwork()) 7018 .hasTransport(TRANSPORT_WIFI)); 7019 7020 // Disconnect the network, and expect to see the VPN capabilities change accordingly. 7021 mWiFiNetworkAgent.disconnect(); 7022 callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 7023 callback.expectCapabilitiesThat(mMockVpn, (nc) -> 7024 nc.getTransportTypes().length == 1 && nc.hasTransport(TRANSPORT_VPN)); 7025 7026 mMockVpn.disconnect(); 7027 mCm.unregisterNetworkCallback(callback); 7028 } 7029 7030 private void assertGetNetworkInfoOfGetActiveNetworkIsConnected(boolean expectedConnectivity) { 7031 // What Chromium used to do before https://chromium-review.googlesource.com/2605304 7032 assertEquals("Unexpected result for getActiveNetworkInfo(getActiveNetwork())", 7033 expectedConnectivity, mCm.getNetworkInfo(mCm.getActiveNetwork()).isConnected()); 7034 } 7035 7036 @Test 7037 public void testVpnUnderlyingNetworkSuspended() throws Exception { 7038 final TestNetworkCallback callback = new TestNetworkCallback(); 7039 mCm.registerDefaultNetworkCallback(callback); 7040 7041 // Connect a VPN. 7042 mMockVpn.establishForMyUid(false /* validated */, true /* hasInternet */, 7043 false /* isStrictMode */); 7044 callback.expectAvailableCallbacksUnvalidated(mMockVpn); 7045 7046 // Connect cellular data. 7047 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 7048 mCellNetworkAgent.connect(false /* validated */); 7049 callback.expectCapabilitiesThat(mMockVpn, 7050 nc -> nc.hasCapability(NET_CAPABILITY_NOT_SUSPENDED) 7051 && nc.hasTransport(TRANSPORT_CELLULAR)); 7052 callback.assertNoCallback(); 7053 7054 assertTrue(mCm.getNetworkCapabilities(mMockVpn.getNetwork()) 7055 .hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 7056 assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 7057 assertNetworkInfo(TYPE_WIFI, DetailedState.DISCONNECTED); 7058 assertNetworkInfo(TYPE_VPN, DetailedState.CONNECTED); 7059 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 7060 assertGetNetworkInfoOfGetActiveNetworkIsConnected(true); 7061 7062 // Suspend the cellular network and expect the VPN to be suspended. 7063 mCellNetworkAgent.suspend(); 7064 callback.expectCapabilitiesThat(mMockVpn, 7065 nc -> !nc.hasCapability(NET_CAPABILITY_NOT_SUSPENDED) 7066 && nc.hasTransport(TRANSPORT_CELLULAR)); 7067 callback.expectCallback(CallbackEntry.SUSPENDED, mMockVpn); 7068 callback.assertNoCallback(); 7069 7070 assertFalse(mCm.getNetworkCapabilities(mMockVpn.getNetwork()) 7071 .hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 7072 assertNetworkInfo(TYPE_MOBILE, DetailedState.SUSPENDED); 7073 assertNetworkInfo(TYPE_WIFI, DetailedState.DISCONNECTED); 7074 assertNetworkInfo(TYPE_VPN, DetailedState.SUSPENDED); 7075 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.SUSPENDED); 7076 // VPN's main underlying network is suspended, so no connectivity. 7077 assertGetNetworkInfoOfGetActiveNetworkIsConnected(false); 7078 7079 // Switch to another network. The VPN should no longer be suspended. 7080 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 7081 mWiFiNetworkAgent.connect(false /* validated */); 7082 callback.expectCapabilitiesThat(mMockVpn, 7083 nc -> nc.hasCapability(NET_CAPABILITY_NOT_SUSPENDED) 7084 && nc.hasTransport(TRANSPORT_WIFI)); 7085 callback.expectCallback(CallbackEntry.RESUMED, mMockVpn); 7086 callback.assertNoCallback(); 7087 7088 assertTrue(mCm.getNetworkCapabilities(mMockVpn.getNetwork()) 7089 .hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 7090 assertNetworkInfo(TYPE_MOBILE, DetailedState.DISCONNECTED); 7091 assertNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 7092 assertNetworkInfo(TYPE_VPN, DetailedState.CONNECTED); 7093 assertActiveNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 7094 assertGetNetworkInfoOfGetActiveNetworkIsConnected(true); 7095 7096 // Unsuspend cellular and then switch back to it. The VPN remains not suspended. 7097 mCellNetworkAgent.resume(); 7098 callback.assertNoCallback(); 7099 mWiFiNetworkAgent.disconnect(); 7100 callback.expectCapabilitiesThat(mMockVpn, 7101 nc -> nc.hasCapability(NET_CAPABILITY_NOT_SUSPENDED) 7102 && nc.hasTransport(TRANSPORT_CELLULAR)); 7103 // Spurious double callback? 7104 callback.expectCapabilitiesThat(mMockVpn, 7105 nc -> nc.hasCapability(NET_CAPABILITY_NOT_SUSPENDED) 7106 && nc.hasTransport(TRANSPORT_CELLULAR)); 7107 callback.assertNoCallback(); 7108 7109 assertTrue(mCm.getNetworkCapabilities(mMockVpn.getNetwork()) 7110 .hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 7111 assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 7112 assertNetworkInfo(TYPE_WIFI, DetailedState.DISCONNECTED); 7113 assertNetworkInfo(TYPE_VPN, DetailedState.CONNECTED); 7114 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 7115 assertGetNetworkInfoOfGetActiveNetworkIsConnected(true); 7116 7117 // Suspend cellular and expect no connectivity. 7118 mCellNetworkAgent.suspend(); 7119 callback.expectCapabilitiesThat(mMockVpn, 7120 nc -> !nc.hasCapability(NET_CAPABILITY_NOT_SUSPENDED) 7121 && nc.hasTransport(TRANSPORT_CELLULAR)); 7122 callback.expectCallback(CallbackEntry.SUSPENDED, mMockVpn); 7123 callback.assertNoCallback(); 7124 7125 assertFalse(mCm.getNetworkCapabilities(mMockVpn.getNetwork()) 7126 .hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 7127 assertNetworkInfo(TYPE_MOBILE, DetailedState.SUSPENDED); 7128 assertNetworkInfo(TYPE_WIFI, DetailedState.DISCONNECTED); 7129 assertNetworkInfo(TYPE_VPN, DetailedState.SUSPENDED); 7130 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.SUSPENDED); 7131 assertGetNetworkInfoOfGetActiveNetworkIsConnected(false); 7132 7133 // Resume cellular and expect that connectivity comes back. 7134 mCellNetworkAgent.resume(); 7135 callback.expectCapabilitiesThat(mMockVpn, 7136 nc -> nc.hasCapability(NET_CAPABILITY_NOT_SUSPENDED) 7137 && nc.hasTransport(TRANSPORT_CELLULAR)); 7138 callback.expectCallback(CallbackEntry.RESUMED, mMockVpn); 7139 callback.assertNoCallback(); 7140 7141 assertTrue(mCm.getNetworkCapabilities(mMockVpn.getNetwork()) 7142 .hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 7143 assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 7144 assertNetworkInfo(TYPE_WIFI, DetailedState.DISCONNECTED); 7145 assertNetworkInfo(TYPE_VPN, DetailedState.CONNECTED); 7146 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 7147 assertGetNetworkInfoOfGetActiveNetworkIsConnected(true); 7148 } 7149 7150 @Test 7151 public void testVpnNetworkActive() throws Exception { 7152 // NETWORK_SETTINGS is necessary to call registerSystemDefaultNetworkCallback. 7153 mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_GRANTED); 7154 7155 final int uid = Process.myUid(); 7156 7157 final TestNetworkCallback genericNetworkCallback = new TestNetworkCallback(); 7158 final TestNetworkCallback genericNotVpnNetworkCallback = new TestNetworkCallback(); 7159 final TestNetworkCallback wifiNetworkCallback = new TestNetworkCallback(); 7160 final TestNetworkCallback vpnNetworkCallback = new TestNetworkCallback(); 7161 final TestNetworkCallback defaultCallback = new TestNetworkCallback(); 7162 final TestNetworkCallback systemDefaultCallback = new TestNetworkCallback(); 7163 final NetworkRequest genericNotVpnRequest = new NetworkRequest.Builder().build(); 7164 final NetworkRequest genericRequest = new NetworkRequest.Builder() 7165 .removeCapability(NET_CAPABILITY_NOT_VPN).build(); 7166 final NetworkRequest wifiRequest = new NetworkRequest.Builder() 7167 .addTransportType(TRANSPORT_WIFI).build(); 7168 final NetworkRequest vpnNetworkRequest = new NetworkRequest.Builder() 7169 .removeCapability(NET_CAPABILITY_NOT_VPN) 7170 .addTransportType(TRANSPORT_VPN).build(); 7171 mCm.registerNetworkCallback(genericRequest, genericNetworkCallback); 7172 mCm.registerNetworkCallback(genericNotVpnRequest, genericNotVpnNetworkCallback); 7173 mCm.registerNetworkCallback(wifiRequest, wifiNetworkCallback); 7174 mCm.registerNetworkCallback(vpnNetworkRequest, vpnNetworkCallback); 7175 mCm.registerDefaultNetworkCallback(defaultCallback); 7176 mCm.registerSystemDefaultNetworkCallback(systemDefaultCallback, 7177 new Handler(ConnectivityThread.getInstanceLooper())); 7178 defaultCallback.assertNoCallback(); 7179 7180 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 7181 mWiFiNetworkAgent.connect(false); 7182 7183 genericNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 7184 genericNotVpnNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 7185 wifiNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 7186 defaultCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 7187 systemDefaultCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 7188 vpnNetworkCallback.assertNoCallback(); 7189 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 7190 7191 final Set<UidRange> ranges = uidRangesForUids(uid); 7192 mMockVpn.registerAgent(ranges); 7193 mMockVpn.setUnderlyingNetworks(new Network[0]); 7194 7195 // VPN networks do not satisfy the default request and are automatically validated 7196 // by NetworkMonitor 7197 assertFalse(NetworkMonitorUtils.isValidationRequired( 7198 mMockVpn.getAgent().getNetworkCapabilities())); 7199 mMockVpn.getAgent().setNetworkValid(false /* isStrictMode */); 7200 7201 mMockVpn.connect(false); 7202 7203 genericNetworkCallback.expectAvailableThenValidatedCallbacks(mMockVpn); 7204 genericNotVpnNetworkCallback.assertNoCallback(); 7205 wifiNetworkCallback.assertNoCallback(); 7206 vpnNetworkCallback.expectAvailableThenValidatedCallbacks(mMockVpn); 7207 defaultCallback.expectAvailableThenValidatedCallbacks(mMockVpn); 7208 systemDefaultCallback.assertNoCallback(); 7209 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 7210 assertEquals(mWiFiNetworkAgent.getNetwork(), 7211 systemDefaultCallback.getLastAvailableNetwork()); 7212 7213 ranges.clear(); 7214 mMockVpn.setUids(ranges); 7215 7216 genericNetworkCallback.expectCallback(CallbackEntry.LOST, mMockVpn); 7217 genericNotVpnNetworkCallback.assertNoCallback(); 7218 wifiNetworkCallback.assertNoCallback(); 7219 vpnNetworkCallback.expectCallback(CallbackEntry.LOST, mMockVpn); 7220 7221 // TODO : The default network callback should actually get a LOST call here (also see the 7222 // comment below for AVAILABLE). This is because ConnectivityService does not look at UID 7223 // ranges at all when determining whether a network should be rematched. In practice, VPNs 7224 // can't currently update their UIDs without disconnecting, so this does not matter too 7225 // much, but that is the reason the test here has to check for an update to the 7226 // capabilities instead of the expected LOST then AVAILABLE. 7227 defaultCallback.expectCallback(CallbackEntry.NETWORK_CAPS_UPDATED, mMockVpn); 7228 systemDefaultCallback.assertNoCallback(); 7229 7230 ranges.add(new UidRange(uid, uid)); 7231 mMockVpn.setUids(ranges); 7232 7233 genericNetworkCallback.expectAvailableCallbacksValidated(mMockVpn); 7234 genericNotVpnNetworkCallback.assertNoCallback(); 7235 wifiNetworkCallback.assertNoCallback(); 7236 vpnNetworkCallback.expectAvailableCallbacksValidated(mMockVpn); 7237 // TODO : Here like above, AVAILABLE would be correct, but because this can't actually 7238 // happen outside of the test, ConnectivityService does not rematch callbacks. 7239 defaultCallback.expectCallback(CallbackEntry.NETWORK_CAPS_UPDATED, mMockVpn); 7240 systemDefaultCallback.assertNoCallback(); 7241 7242 mWiFiNetworkAgent.disconnect(); 7243 7244 genericNetworkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 7245 genericNotVpnNetworkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 7246 wifiNetworkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 7247 vpnNetworkCallback.assertNoCallback(); 7248 defaultCallback.assertNoCallback(); 7249 systemDefaultCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 7250 7251 mMockVpn.disconnect(); 7252 7253 genericNetworkCallback.expectCallback(CallbackEntry.LOST, mMockVpn); 7254 genericNotVpnNetworkCallback.assertNoCallback(); 7255 wifiNetworkCallback.assertNoCallback(); 7256 vpnNetworkCallback.expectCallback(CallbackEntry.LOST, mMockVpn); 7257 defaultCallback.expectCallback(CallbackEntry.LOST, mMockVpn); 7258 systemDefaultCallback.assertNoCallback(); 7259 assertEquals(null, mCm.getActiveNetwork()); 7260 7261 mCm.unregisterNetworkCallback(genericNetworkCallback); 7262 mCm.unregisterNetworkCallback(wifiNetworkCallback); 7263 mCm.unregisterNetworkCallback(vpnNetworkCallback); 7264 mCm.unregisterNetworkCallback(defaultCallback); 7265 mCm.unregisterNetworkCallback(systemDefaultCallback); 7266 } 7267 7268 @Test 7269 public void testVpnWithoutInternet() throws Exception { 7270 final int uid = Process.myUid(); 7271 7272 final TestNetworkCallback defaultCallback = new TestNetworkCallback(); 7273 mCm.registerDefaultNetworkCallback(defaultCallback); 7274 7275 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 7276 mWiFiNetworkAgent.connect(true); 7277 7278 defaultCallback.expectAvailableThenValidatedCallbacks(mWiFiNetworkAgent); 7279 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 7280 7281 mMockVpn.establishForMyUid(true /* validated */, false /* hasInternet */, 7282 false /* isStrictMode */); 7283 assertUidRangesUpdatedForMyUid(true); 7284 7285 defaultCallback.assertNoCallback(); 7286 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 7287 7288 mMockVpn.disconnect(); 7289 defaultCallback.assertNoCallback(); 7290 7291 mCm.unregisterNetworkCallback(defaultCallback); 7292 } 7293 7294 @Test 7295 public void testVpnWithInternet() throws Exception { 7296 final int uid = Process.myUid(); 7297 7298 final TestNetworkCallback defaultCallback = new TestNetworkCallback(); 7299 mCm.registerDefaultNetworkCallback(defaultCallback); 7300 7301 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 7302 mWiFiNetworkAgent.connect(true); 7303 7304 defaultCallback.expectAvailableThenValidatedCallbacks(mWiFiNetworkAgent); 7305 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 7306 7307 mMockVpn.establishForMyUid(true /* validated */, true /* hasInternet */, 7308 false /* isStrictMode */); 7309 assertUidRangesUpdatedForMyUid(true); 7310 7311 defaultCallback.expectAvailableThenValidatedCallbacks(mMockVpn); 7312 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 7313 7314 mMockVpn.disconnect(); 7315 defaultCallback.expectCallback(CallbackEntry.LOST, mMockVpn); 7316 defaultCallback.expectAvailableCallbacksValidated(mWiFiNetworkAgent); 7317 7318 mCm.unregisterNetworkCallback(defaultCallback); 7319 } 7320 7321 @Test 7322 public void testVpnUnvalidated() throws Exception { 7323 final TestNetworkCallback callback = new TestNetworkCallback(); 7324 mCm.registerDefaultNetworkCallback(callback); 7325 7326 // Bring up Ethernet. 7327 mEthernetNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_ETHERNET); 7328 mEthernetNetworkAgent.connect(true); 7329 callback.expectAvailableThenValidatedCallbacks(mEthernetNetworkAgent); 7330 callback.assertNoCallback(); 7331 7332 // Bring up a VPN that has the INTERNET capability, initially unvalidated. 7333 mMockVpn.establishForMyUid(false /* validated */, true /* hasInternet */, 7334 false /* isStrictMode */); 7335 assertUidRangesUpdatedForMyUid(true); 7336 7337 // Even though the VPN is unvalidated, it becomes the default network for our app. 7338 callback.expectAvailableCallbacksUnvalidated(mMockVpn); 7339 callback.assertNoCallback(); 7340 7341 assertEquals(mMockVpn.getNetwork(), mCm.getActiveNetwork()); 7342 7343 NetworkCapabilities nc = mCm.getNetworkCapabilities(mMockVpn.getNetwork()); 7344 assertFalse(nc.hasCapability(NET_CAPABILITY_VALIDATED)); 7345 assertTrue(nc.hasCapability(NET_CAPABILITY_INTERNET)); 7346 7347 assertFalse(NetworkMonitorUtils.isValidationRequired( 7348 mMockVpn.getAgent().getNetworkCapabilities())); 7349 assertTrue(NetworkMonitorUtils.isPrivateDnsValidationRequired( 7350 mMockVpn.getAgent().getNetworkCapabilities())); 7351 7352 // Pretend that the VPN network validates. 7353 mMockVpn.getAgent().setNetworkValid(false /* isStrictMode */); 7354 mMockVpn.getAgent().mNetworkMonitor.forceReevaluation(Process.myUid()); 7355 // Expect to see the validated capability, but no other changes, because the VPN is already 7356 // the default network for the app. 7357 callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mMockVpn); 7358 callback.assertNoCallback(); 7359 7360 mMockVpn.disconnect(); 7361 callback.expectCallback(CallbackEntry.LOST, mMockVpn); 7362 callback.expectAvailableCallbacksValidated(mEthernetNetworkAgent); 7363 } 7364 7365 @Test 7366 public void testVpnStartsWithUnderlyingCaps() throws Exception { 7367 final int uid = Process.myUid(); 7368 7369 final TestNetworkCallback vpnNetworkCallback = new TestNetworkCallback(); 7370 final NetworkRequest vpnNetworkRequest = new NetworkRequest.Builder() 7371 .removeCapability(NET_CAPABILITY_NOT_VPN) 7372 .addTransportType(TRANSPORT_VPN) 7373 .build(); 7374 mCm.registerNetworkCallback(vpnNetworkRequest, vpnNetworkCallback); 7375 vpnNetworkCallback.assertNoCallback(); 7376 7377 // Connect cell. It will become the default network, and in the absence of setting 7378 // underlying networks explicitly it will become the sole underlying network for the vpn. 7379 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 7380 mCellNetworkAgent.addCapability(NET_CAPABILITY_NOT_SUSPENDED); 7381 mCellNetworkAgent.connect(true); 7382 7383 mMockVpn.establishForMyUid(true /* validated */, false /* hasInternet */, 7384 false /* isStrictMode */); 7385 assertUidRangesUpdatedForMyUid(true); 7386 7387 vpnNetworkCallback.expectAvailableCallbacks(mMockVpn.getNetwork(), 7388 false /* suspended */, false /* validated */, false /* blocked */, TIMEOUT_MS); 7389 vpnNetworkCallback.expectCapabilitiesThat(mMockVpn.getNetwork(), TIMEOUT_MS, 7390 nc -> nc.hasCapability(NET_CAPABILITY_VALIDATED)); 7391 7392 final NetworkCapabilities nc = mCm.getNetworkCapabilities(mMockVpn.getNetwork()); 7393 assertTrue(nc.hasTransport(TRANSPORT_VPN)); 7394 assertTrue(nc.hasTransport(TRANSPORT_CELLULAR)); 7395 assertFalse(nc.hasTransport(TRANSPORT_WIFI)); 7396 assertTrue(nc.hasCapability(NET_CAPABILITY_VALIDATED)); 7397 assertFalse(nc.hasCapability(NET_CAPABILITY_NOT_METERED)); 7398 assertTrue(nc.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 7399 7400 assertVpnTransportInfo(nc, VpnManager.TYPE_VPN_SERVICE); 7401 } 7402 7403 private void assertDefaultNetworkCapabilities(int userId, NetworkAgentWrapper... networks) { 7404 final NetworkCapabilities[] defaultCaps = mService.getDefaultNetworkCapabilitiesForUser( 7405 userId, "com.android.calling.package", "com.test"); 7406 final String defaultCapsString = Arrays.toString(defaultCaps); 7407 assertEquals(defaultCapsString, defaultCaps.length, networks.length); 7408 final Set<NetworkCapabilities> defaultCapsSet = new ArraySet<>(defaultCaps); 7409 for (NetworkAgentWrapper network : networks) { 7410 final NetworkCapabilities nc = mCm.getNetworkCapabilities(network.getNetwork()); 7411 final String msg = "Did not find " + nc + " in " + Arrays.toString(defaultCaps); 7412 assertTrue(msg, defaultCapsSet.contains(nc)); 7413 } 7414 } 7415 7416 @Test 7417 public void testVpnSetUnderlyingNetworks() throws Exception { 7418 final TestNetworkCallback vpnNetworkCallback = new TestNetworkCallback(); 7419 final NetworkRequest vpnNetworkRequest = new NetworkRequest.Builder() 7420 .removeCapability(NET_CAPABILITY_NOT_VPN) 7421 .addTransportType(TRANSPORT_VPN) 7422 .build(); 7423 NetworkCapabilities nc; 7424 mCm.registerNetworkCallback(vpnNetworkRequest, vpnNetworkCallback); 7425 vpnNetworkCallback.assertNoCallback(); 7426 7427 mMockVpn.establishForMyUid(true /* validated */, false /* hasInternet */, 7428 false /* isStrictMode */); 7429 assertUidRangesUpdatedForMyUid(true); 7430 7431 vpnNetworkCallback.expectAvailableThenValidatedCallbacks(mMockVpn); 7432 nc = mCm.getNetworkCapabilities(mMockVpn.getNetwork()); 7433 assertTrue(nc.hasTransport(TRANSPORT_VPN)); 7434 assertFalse(nc.hasTransport(TRANSPORT_CELLULAR)); 7435 assertFalse(nc.hasTransport(TRANSPORT_WIFI)); 7436 // For safety reasons a VPN without underlying networks is considered metered. 7437 assertFalse(nc.hasCapability(NET_CAPABILITY_NOT_METERED)); 7438 // A VPN without underlying networks is not suspended. 7439 assertTrue(nc.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 7440 assertVpnTransportInfo(nc, VpnManager.TYPE_VPN_SERVICE); 7441 7442 final int userId = UserHandle.getUserId(Process.myUid()); 7443 assertDefaultNetworkCapabilities(userId /* no networks */); 7444 7445 // Connect cell and use it as an underlying network. 7446 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 7447 mCellNetworkAgent.addCapability(NET_CAPABILITY_NOT_SUSPENDED); 7448 mCellNetworkAgent.connect(true); 7449 7450 mMockVpn.setUnderlyingNetworks( 7451 new Network[] { mCellNetworkAgent.getNetwork() }); 7452 7453 vpnNetworkCallback.expectCapabilitiesThat(mMockVpn, 7454 (caps) -> caps.hasTransport(TRANSPORT_VPN) 7455 && caps.hasTransport(TRANSPORT_CELLULAR) && !caps.hasTransport(TRANSPORT_WIFI) 7456 && !caps.hasCapability(NET_CAPABILITY_NOT_METERED) 7457 && caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 7458 assertDefaultNetworkCapabilities(userId, mCellNetworkAgent); 7459 7460 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 7461 mWiFiNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED); 7462 mWiFiNetworkAgent.addCapability(NET_CAPABILITY_NOT_SUSPENDED); 7463 mWiFiNetworkAgent.connect(true); 7464 7465 mMockVpn.setUnderlyingNetworks( 7466 new Network[] { mCellNetworkAgent.getNetwork(), mWiFiNetworkAgent.getNetwork() }); 7467 7468 vpnNetworkCallback.expectCapabilitiesThat(mMockVpn, 7469 (caps) -> caps.hasTransport(TRANSPORT_VPN) 7470 && caps.hasTransport(TRANSPORT_CELLULAR) && caps.hasTransport(TRANSPORT_WIFI) 7471 && !caps.hasCapability(NET_CAPABILITY_NOT_METERED) 7472 && caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 7473 assertDefaultNetworkCapabilities(userId, mCellNetworkAgent, mWiFiNetworkAgent); 7474 7475 // Don't disconnect, but note the VPN is not using wifi any more. 7476 mMockVpn.setUnderlyingNetworks( 7477 new Network[] { mCellNetworkAgent.getNetwork() }); 7478 7479 vpnNetworkCallback.expectCapabilitiesThat(mMockVpn, 7480 (caps) -> caps.hasTransport(TRANSPORT_VPN) 7481 && caps.hasTransport(TRANSPORT_CELLULAR) && !caps.hasTransport(TRANSPORT_WIFI) 7482 && !caps.hasCapability(NET_CAPABILITY_NOT_METERED) 7483 && caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 7484 // The return value of getDefaultNetworkCapabilitiesForUser always includes the default 7485 // network (wifi) as well as the underlying networks (cell). 7486 assertDefaultNetworkCapabilities(userId, mCellNetworkAgent, mWiFiNetworkAgent); 7487 7488 // Remove NOT_SUSPENDED from the only network and observe VPN is now suspended. 7489 mCellNetworkAgent.removeCapability(NET_CAPABILITY_NOT_SUSPENDED); 7490 vpnNetworkCallback.expectCapabilitiesThat(mMockVpn, 7491 (caps) -> caps.hasTransport(TRANSPORT_VPN) 7492 && caps.hasTransport(TRANSPORT_CELLULAR) && !caps.hasTransport(TRANSPORT_WIFI) 7493 && !caps.hasCapability(NET_CAPABILITY_NOT_METERED) 7494 && !caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 7495 vpnNetworkCallback.expectCallback(CallbackEntry.SUSPENDED, mMockVpn); 7496 7497 // Add NOT_SUSPENDED again and observe VPN is no longer suspended. 7498 mCellNetworkAgent.addCapability(NET_CAPABILITY_NOT_SUSPENDED); 7499 vpnNetworkCallback.expectCapabilitiesThat(mMockVpn, 7500 (caps) -> caps.hasTransport(TRANSPORT_VPN) 7501 && caps.hasTransport(TRANSPORT_CELLULAR) && !caps.hasTransport(TRANSPORT_WIFI) 7502 && !caps.hasCapability(NET_CAPABILITY_NOT_METERED) 7503 && caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 7504 vpnNetworkCallback.expectCallback(CallbackEntry.RESUMED, mMockVpn); 7505 7506 // Use Wifi but not cell. Note the VPN is now unmetered and not suspended. 7507 mMockVpn.setUnderlyingNetworks( 7508 new Network[] { mWiFiNetworkAgent.getNetwork() }); 7509 7510 vpnNetworkCallback.expectCapabilitiesThat(mMockVpn, 7511 (caps) -> caps.hasTransport(TRANSPORT_VPN) 7512 && !caps.hasTransport(TRANSPORT_CELLULAR) && caps.hasTransport(TRANSPORT_WIFI) 7513 && caps.hasCapability(NET_CAPABILITY_NOT_METERED) 7514 && caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 7515 assertDefaultNetworkCapabilities(userId, mWiFiNetworkAgent); 7516 7517 // Use both again. 7518 mMockVpn.setUnderlyingNetworks( 7519 new Network[] { mCellNetworkAgent.getNetwork(), mWiFiNetworkAgent.getNetwork() }); 7520 7521 vpnNetworkCallback.expectCapabilitiesThat(mMockVpn, 7522 (caps) -> caps.hasTransport(TRANSPORT_VPN) 7523 && caps.hasTransport(TRANSPORT_CELLULAR) && caps.hasTransport(TRANSPORT_WIFI) 7524 && !caps.hasCapability(NET_CAPABILITY_NOT_METERED) 7525 && caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 7526 assertDefaultNetworkCapabilities(userId, mCellNetworkAgent, mWiFiNetworkAgent); 7527 7528 // Cell is suspended again. As WiFi is not, this should not cause a callback. 7529 mCellNetworkAgent.removeCapability(NET_CAPABILITY_NOT_SUSPENDED); 7530 vpnNetworkCallback.assertNoCallback(); 7531 7532 // Stop using WiFi. The VPN is suspended again. 7533 mMockVpn.setUnderlyingNetworks( 7534 new Network[] { mCellNetworkAgent.getNetwork() }); 7535 vpnNetworkCallback.expectCapabilitiesThat(mMockVpn, 7536 (caps) -> caps.hasTransport(TRANSPORT_VPN) 7537 && caps.hasTransport(TRANSPORT_CELLULAR) 7538 && !caps.hasCapability(NET_CAPABILITY_NOT_METERED) 7539 && !caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 7540 vpnNetworkCallback.expectCallback(CallbackEntry.SUSPENDED, mMockVpn); 7541 assertDefaultNetworkCapabilities(userId, mCellNetworkAgent, mWiFiNetworkAgent); 7542 7543 // Use both again. 7544 mMockVpn.setUnderlyingNetworks( 7545 new Network[] { mCellNetworkAgent.getNetwork(), mWiFiNetworkAgent.getNetwork() }); 7546 7547 vpnNetworkCallback.expectCapabilitiesThat(mMockVpn, 7548 (caps) -> caps.hasTransport(TRANSPORT_VPN) 7549 && caps.hasTransport(TRANSPORT_CELLULAR) && caps.hasTransport(TRANSPORT_WIFI) 7550 && !caps.hasCapability(NET_CAPABILITY_NOT_METERED) 7551 && caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 7552 vpnNetworkCallback.expectCallback(CallbackEntry.RESUMED, mMockVpn); 7553 assertDefaultNetworkCapabilities(userId, mCellNetworkAgent, mWiFiNetworkAgent); 7554 7555 // Disconnect cell. Receive update without even removing the dead network from the 7556 // underlying networks – it's dead anyway. Not metered any more. 7557 mCellNetworkAgent.disconnect(); 7558 vpnNetworkCallback.expectCapabilitiesThat(mMockVpn, 7559 (caps) -> caps.hasTransport(TRANSPORT_VPN) 7560 && !caps.hasTransport(TRANSPORT_CELLULAR) && caps.hasTransport(TRANSPORT_WIFI) 7561 && caps.hasCapability(NET_CAPABILITY_NOT_METERED)); 7562 assertDefaultNetworkCapabilities(userId, mWiFiNetworkAgent); 7563 7564 // Disconnect wifi too. No underlying networks means this is now metered. 7565 mWiFiNetworkAgent.disconnect(); 7566 vpnNetworkCallback.expectCapabilitiesThat(mMockVpn, 7567 (caps) -> caps.hasTransport(TRANSPORT_VPN) 7568 && !caps.hasTransport(TRANSPORT_CELLULAR) && !caps.hasTransport(TRANSPORT_WIFI) 7569 && !caps.hasCapability(NET_CAPABILITY_NOT_METERED)); 7570 // When a network disconnects, the callbacks are fired before all state is updated, so for a 7571 // short time, synchronous calls will behave as if the network is still connected. Wait for 7572 // things to settle. 7573 waitForIdle(); 7574 assertDefaultNetworkCapabilities(userId /* no networks */); 7575 7576 mMockVpn.disconnect(); 7577 } 7578 7579 @Test 7580 public void testNullUnderlyingNetworks() throws Exception { 7581 final int uid = Process.myUid(); 7582 7583 final TestNetworkCallback vpnNetworkCallback = new TestNetworkCallback(); 7584 final NetworkRequest vpnNetworkRequest = new NetworkRequest.Builder() 7585 .removeCapability(NET_CAPABILITY_NOT_VPN) 7586 .addTransportType(TRANSPORT_VPN) 7587 .build(); 7588 NetworkCapabilities nc; 7589 mCm.registerNetworkCallback(vpnNetworkRequest, vpnNetworkCallback); 7590 vpnNetworkCallback.assertNoCallback(); 7591 7592 mMockVpn.establishForMyUid(true /* validated */, false /* hasInternet */, 7593 false /* isStrictMode */); 7594 assertUidRangesUpdatedForMyUid(true); 7595 7596 vpnNetworkCallback.expectAvailableThenValidatedCallbacks(mMockVpn); 7597 nc = mCm.getNetworkCapabilities(mMockVpn.getNetwork()); 7598 assertTrue(nc.hasTransport(TRANSPORT_VPN)); 7599 assertFalse(nc.hasTransport(TRANSPORT_CELLULAR)); 7600 assertFalse(nc.hasTransport(TRANSPORT_WIFI)); 7601 // By default, VPN is set to track default network (i.e. its underlying networks is null). 7602 // In case of no default network, VPN is considered metered. 7603 assertFalse(nc.hasCapability(NET_CAPABILITY_NOT_METERED)); 7604 assertVpnTransportInfo(nc, VpnManager.TYPE_VPN_SERVICE); 7605 7606 // Connect to Cell; Cell is the default network. 7607 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 7608 mCellNetworkAgent.connect(true); 7609 7610 vpnNetworkCallback.expectCapabilitiesThat(mMockVpn, 7611 (caps) -> caps.hasTransport(TRANSPORT_VPN) 7612 && caps.hasTransport(TRANSPORT_CELLULAR) && !caps.hasTransport(TRANSPORT_WIFI) 7613 && !caps.hasCapability(NET_CAPABILITY_NOT_METERED)); 7614 7615 // Connect to WiFi; WiFi is the new default. 7616 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 7617 mWiFiNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED); 7618 mWiFiNetworkAgent.connect(true); 7619 7620 vpnNetworkCallback.expectCapabilitiesThat(mMockVpn, 7621 (caps) -> caps.hasTransport(TRANSPORT_VPN) 7622 && !caps.hasTransport(TRANSPORT_CELLULAR) && caps.hasTransport(TRANSPORT_WIFI) 7623 && caps.hasCapability(NET_CAPABILITY_NOT_METERED)); 7624 7625 // Disconnect Cell. The default network did not change, so there shouldn't be any changes in 7626 // the capabilities. 7627 mCellNetworkAgent.disconnect(); 7628 7629 // Disconnect wifi too. Now we have no default network. 7630 mWiFiNetworkAgent.disconnect(); 7631 7632 vpnNetworkCallback.expectCapabilitiesThat(mMockVpn, 7633 (caps) -> caps.hasTransport(TRANSPORT_VPN) 7634 && !caps.hasTransport(TRANSPORT_CELLULAR) && !caps.hasTransport(TRANSPORT_WIFI) 7635 && !caps.hasCapability(NET_CAPABILITY_NOT_METERED)); 7636 7637 mMockVpn.disconnect(); 7638 } 7639 7640 @Test 7641 public void testRestrictedProfileAffectsVpnUidRanges() throws Exception { 7642 // NETWORK_SETTINGS is necessary to see the UID ranges in NetworkCapabilities. 7643 mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_GRANTED); 7644 7645 final NetworkRequest request = new NetworkRequest.Builder() 7646 .removeCapability(NET_CAPABILITY_NOT_VPN) 7647 .build(); 7648 final TestNetworkCallback callback = new TestNetworkCallback(); 7649 mCm.registerNetworkCallback(request, callback); 7650 7651 // Bring up a VPN 7652 mMockVpn.establishForMyUid(); 7653 assertUidRangesUpdatedForMyUid(true); 7654 callback.expectAvailableThenValidatedCallbacks(mMockVpn); 7655 callback.assertNoCallback(); 7656 7657 final int uid = Process.myUid(); 7658 NetworkCapabilities nc = mCm.getNetworkCapabilities(mMockVpn.getNetwork()); 7659 assertNotNull("nc=" + nc, nc.getUids()); 7660 assertEquals(nc.getUids(), UidRange.toIntRanges(uidRangesForUids(uid))); 7661 assertVpnTransportInfo(nc, VpnManager.TYPE_VPN_SERVICE); 7662 7663 // Set an underlying network and expect to see the VPN transports change. 7664 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 7665 mWiFiNetworkAgent.connect(true); 7666 callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 7667 callback.expectCapabilitiesThat(mMockVpn, (caps) 7668 -> caps.hasTransport(TRANSPORT_VPN) 7669 && caps.hasTransport(TRANSPORT_WIFI)); 7670 callback.expectCapabilitiesThat(mWiFiNetworkAgent, (caps) 7671 -> caps.hasCapability(NET_CAPABILITY_VALIDATED)); 7672 7673 when(mPackageManager.getPackageUidAsUser(ALWAYS_ON_PACKAGE, RESTRICTED_USER)) 7674 .thenReturn(UserHandle.getUid(RESTRICTED_USER, VPN_UID)); 7675 7676 final Intent addedIntent = new Intent(ACTION_USER_ADDED); 7677 addedIntent.putExtra(Intent.EXTRA_USER, UserHandle.of(RESTRICTED_USER)); 7678 addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, RESTRICTED_USER); 7679 7680 // Send a USER_ADDED broadcast for it. 7681 processBroadcast(addedIntent); 7682 7683 // Expect that the VPN UID ranges contain both |uid| and the UID range for the newly-added 7684 // restricted user. 7685 final UidRange rRange = UidRange.createForUser(UserHandle.of(RESTRICTED_USER)); 7686 final Range<Integer> restrictUidRange = new Range<Integer>(rRange.start, rRange.stop); 7687 final Range<Integer> singleUidRange = new Range<Integer>(uid, uid); 7688 callback.expectCapabilitiesThat(mMockVpn, (caps) 7689 -> caps.getUids().size() == 2 7690 && caps.getUids().contains(singleUidRange) 7691 && caps.getUids().contains(restrictUidRange) 7692 && caps.hasTransport(TRANSPORT_VPN) 7693 && caps.hasTransport(TRANSPORT_WIFI)); 7694 7695 // Change the VPN's capabilities somehow (specifically, disconnect wifi). 7696 mWiFiNetworkAgent.disconnect(); 7697 callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 7698 callback.expectCapabilitiesThat(mMockVpn, (caps) 7699 -> caps.getUids().size() == 2 7700 && caps.getUids().contains(singleUidRange) 7701 && caps.getUids().contains(restrictUidRange) 7702 && caps.hasTransport(TRANSPORT_VPN) 7703 && !caps.hasTransport(TRANSPORT_WIFI)); 7704 7705 // Send a USER_REMOVED broadcast and expect to lose the UID range for the restricted user. 7706 final Intent removedIntent = new Intent(ACTION_USER_REMOVED); 7707 removedIntent.putExtra(Intent.EXTRA_USER, UserHandle.of(RESTRICTED_USER)); 7708 removedIntent.putExtra(Intent.EXTRA_USER_HANDLE, RESTRICTED_USER); 7709 processBroadcast(removedIntent); 7710 7711 // Expect that the VPN gains the UID range for the restricted user, and that the capability 7712 // change made just before that (i.e., loss of TRANSPORT_WIFI) is preserved. 7713 callback.expectCapabilitiesThat(mMockVpn, (caps) 7714 -> caps.getUids().size() == 1 7715 && caps.getUids().contains(singleUidRange) 7716 && caps.hasTransport(TRANSPORT_VPN) 7717 && !caps.hasTransport(TRANSPORT_WIFI)); 7718 } 7719 7720 @Test 7721 public void testLockdownVpnWithRestrictedProfiles() throws Exception { 7722 // For ConnectivityService#setAlwaysOnVpnPackage. 7723 mServiceContext.setPermission( 7724 Manifest.permission.CONTROL_ALWAYS_ON_VPN, PERMISSION_GRANTED); 7725 // For call Vpn#setAlwaysOnPackage. 7726 mServiceContext.setPermission( 7727 Manifest.permission.CONTROL_VPN, PERMISSION_GRANTED); 7728 // Necessary to see the UID ranges in NetworkCapabilities. 7729 mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_GRANTED); 7730 7731 final NetworkRequest request = new NetworkRequest.Builder() 7732 .removeCapability(NET_CAPABILITY_NOT_VPN) 7733 .build(); 7734 final TestNetworkCallback callback = new TestNetworkCallback(); 7735 mCm.registerNetworkCallback(request, callback); 7736 7737 final int uid = Process.myUid(); 7738 7739 // Connect wifi and check that UIDs in the main and restricted profiles have network access. 7740 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 7741 mWiFiNetworkAgent.connect(true /* validated */); 7742 final int restrictedUid = UserHandle.getUid(RESTRICTED_USER, 42 /* appId */); 7743 assertNotNull(mCm.getActiveNetworkForUid(uid)); 7744 assertNotNull(mCm.getActiveNetworkForUid(restrictedUid)); 7745 7746 // Enable always-on VPN lockdown. The main user loses network access because no VPN is up. 7747 final ArrayList<String> allowList = new ArrayList<>(); 7748 mVpnManagerService.setAlwaysOnVpnPackage(PRIMARY_USER, ALWAYS_ON_PACKAGE, 7749 true /* lockdown */, allowList); 7750 waitForIdle(); 7751 assertNull(mCm.getActiveNetworkForUid(uid)); 7752 // This is arguably overspecified: a UID that is not running doesn't have an active network. 7753 // But it's useful to check that non-default users do not lose network access, and to prove 7754 // that the loss of connectivity below is indeed due to the restricted profile coming up. 7755 assertNotNull(mCm.getActiveNetworkForUid(restrictedUid)); 7756 7757 // Start the restricted profile, and check that the UID within it loses network access. 7758 when(mPackageManager.getPackageUidAsUser(ALWAYS_ON_PACKAGE, RESTRICTED_USER)) 7759 .thenReturn(UserHandle.getUid(RESTRICTED_USER, VPN_UID)); 7760 when(mUserManager.getAliveUsers()).thenReturn(Arrays.asList(PRIMARY_USER_INFO, 7761 RESTRICTED_USER_INFO)); 7762 // TODO: check that VPN app within restricted profile still has access, etc. 7763 final Intent addedIntent = new Intent(ACTION_USER_ADDED); 7764 addedIntent.putExtra(Intent.EXTRA_USER, UserHandle.of(RESTRICTED_USER)); 7765 addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, RESTRICTED_USER); 7766 processBroadcast(addedIntent); 7767 assertNull(mCm.getActiveNetworkForUid(uid)); 7768 assertNull(mCm.getActiveNetworkForUid(restrictedUid)); 7769 7770 // Stop the restricted profile, and check that the UID within it has network access again. 7771 when(mUserManager.getAliveUsers()).thenReturn(Arrays.asList(PRIMARY_USER_INFO)); 7772 7773 // Send a USER_REMOVED broadcast and expect to lose the UID range for the restricted user. 7774 final Intent removedIntent = new Intent(ACTION_USER_REMOVED); 7775 removedIntent.putExtra(Intent.EXTRA_USER, UserHandle.of(RESTRICTED_USER)); 7776 removedIntent.putExtra(Intent.EXTRA_USER_HANDLE, RESTRICTED_USER); 7777 processBroadcast(removedIntent); 7778 assertNull(mCm.getActiveNetworkForUid(uid)); 7779 assertNotNull(mCm.getActiveNetworkForUid(restrictedUid)); 7780 7781 mVpnManagerService.setAlwaysOnVpnPackage(PRIMARY_USER, null, false /* lockdown */, 7782 allowList); 7783 waitForIdle(); 7784 } 7785 7786 @Test 7787 public void testIsActiveNetworkMeteredOverWifi() throws Exception { 7788 // Returns true by default when no network is available. 7789 assertTrue(mCm.isActiveNetworkMetered()); 7790 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 7791 mWiFiNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED); 7792 mWiFiNetworkAgent.connect(true); 7793 waitForIdle(); 7794 7795 assertFalse(mCm.isActiveNetworkMetered()); 7796 } 7797 7798 @Test 7799 public void testIsActiveNetworkMeteredOverCell() throws Exception { 7800 // Returns true by default when no network is available. 7801 assertTrue(mCm.isActiveNetworkMetered()); 7802 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 7803 mCellNetworkAgent.removeCapability(NET_CAPABILITY_NOT_METERED); 7804 mCellNetworkAgent.connect(true); 7805 waitForIdle(); 7806 7807 assertTrue(mCm.isActiveNetworkMetered()); 7808 } 7809 7810 @Test 7811 public void testIsActiveNetworkMeteredOverVpnTrackingPlatformDefault() throws Exception { 7812 // Returns true by default when no network is available. 7813 assertTrue(mCm.isActiveNetworkMetered()); 7814 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 7815 mCellNetworkAgent.removeCapability(NET_CAPABILITY_NOT_METERED); 7816 mCellNetworkAgent.connect(true); 7817 waitForIdle(); 7818 assertTrue(mCm.isActiveNetworkMetered()); 7819 7820 // Connect VPN network. By default it is using current default network (Cell). 7821 mMockVpn.establishForMyUid(); 7822 assertUidRangesUpdatedForMyUid(true); 7823 7824 // Ensure VPN is now the active network. 7825 assertEquals(mMockVpn.getNetwork(), mCm.getActiveNetwork()); 7826 7827 // Expect VPN to be metered. 7828 assertTrue(mCm.isActiveNetworkMetered()); 7829 7830 // Connect WiFi. 7831 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 7832 mWiFiNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED); 7833 mWiFiNetworkAgent.connect(true); 7834 waitForIdle(); 7835 // VPN should still be the active network. 7836 assertEquals(mMockVpn.getNetwork(), mCm.getActiveNetwork()); 7837 7838 // Expect VPN to be unmetered as it should now be using WiFi (new default). 7839 assertFalse(mCm.isActiveNetworkMetered()); 7840 7841 // Disconnecting Cell should not affect VPN's meteredness. 7842 mCellNetworkAgent.disconnect(); 7843 waitForIdle(); 7844 7845 assertFalse(mCm.isActiveNetworkMetered()); 7846 7847 // Disconnect WiFi; Now there is no platform default network. 7848 mWiFiNetworkAgent.disconnect(); 7849 waitForIdle(); 7850 7851 // VPN without any underlying networks is treated as metered. 7852 assertTrue(mCm.isActiveNetworkMetered()); 7853 7854 mMockVpn.disconnect(); 7855 } 7856 7857 @Test 7858 public void testIsActiveNetworkMeteredOverVpnSpecifyingUnderlyingNetworks() throws Exception { 7859 // Returns true by default when no network is available. 7860 assertTrue(mCm.isActiveNetworkMetered()); 7861 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 7862 mCellNetworkAgent.removeCapability(NET_CAPABILITY_NOT_METERED); 7863 mCellNetworkAgent.connect(true); 7864 waitForIdle(); 7865 assertTrue(mCm.isActiveNetworkMetered()); 7866 7867 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 7868 mWiFiNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED); 7869 mWiFiNetworkAgent.connect(true); 7870 waitForIdle(); 7871 assertFalse(mCm.isActiveNetworkMetered()); 7872 7873 // Connect VPN network. 7874 mMockVpn.establishForMyUid(); 7875 assertUidRangesUpdatedForMyUid(true); 7876 7877 // Ensure VPN is now the active network. 7878 assertEquals(mMockVpn.getNetwork(), mCm.getActiveNetwork()); 7879 // VPN is using Cell 7880 mMockVpn.setUnderlyingNetworks( 7881 new Network[] { mCellNetworkAgent.getNetwork() }); 7882 waitForIdle(); 7883 7884 // Expect VPN to be metered. 7885 assertTrue(mCm.isActiveNetworkMetered()); 7886 7887 // VPN is now using WiFi 7888 mMockVpn.setUnderlyingNetworks( 7889 new Network[] { mWiFiNetworkAgent.getNetwork() }); 7890 waitForIdle(); 7891 7892 // Expect VPN to be unmetered 7893 assertFalse(mCm.isActiveNetworkMetered()); 7894 7895 // VPN is using Cell | WiFi. 7896 mMockVpn.setUnderlyingNetworks( 7897 new Network[] { mCellNetworkAgent.getNetwork(), mWiFiNetworkAgent.getNetwork() }); 7898 waitForIdle(); 7899 7900 // Expect VPN to be metered. 7901 assertTrue(mCm.isActiveNetworkMetered()); 7902 7903 // VPN is using WiFi | Cell. 7904 mMockVpn.setUnderlyingNetworks( 7905 new Network[] { mWiFiNetworkAgent.getNetwork(), mCellNetworkAgent.getNetwork() }); 7906 waitForIdle(); 7907 7908 // Order should not matter and VPN should still be metered. 7909 assertTrue(mCm.isActiveNetworkMetered()); 7910 7911 // VPN is not using any underlying networks. 7912 mMockVpn.setUnderlyingNetworks(new Network[0]); 7913 waitForIdle(); 7914 7915 // VPN without underlying networks is treated as metered. 7916 assertTrue(mCm.isActiveNetworkMetered()); 7917 7918 mMockVpn.disconnect(); 7919 } 7920 7921 @Test 7922 public void testIsActiveNetworkMeteredOverAlwaysMeteredVpn() throws Exception { 7923 // Returns true by default when no network is available. 7924 assertTrue(mCm.isActiveNetworkMetered()); 7925 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 7926 mWiFiNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED); 7927 mWiFiNetworkAgent.connect(true); 7928 waitForIdle(); 7929 assertFalse(mCm.isActiveNetworkMetered()); 7930 7931 // Connect VPN network. 7932 mMockVpn.registerAgent(true /* isAlwaysMetered */, uidRangesForUids(Process.myUid()), 7933 new LinkProperties()); 7934 mMockVpn.connect(true); 7935 waitForIdle(); 7936 assertEquals(mMockVpn.getNetwork(), mCm.getActiveNetwork()); 7937 7938 // VPN is tracking current platform default (WiFi). 7939 mMockVpn.setUnderlyingNetworks(null); 7940 waitForIdle(); 7941 7942 // Despite VPN using WiFi (which is unmetered), VPN itself is marked as always metered. 7943 assertTrue(mCm.isActiveNetworkMetered()); 7944 7945 7946 // VPN explicitly declares WiFi as its underlying network. 7947 mMockVpn.setUnderlyingNetworks( 7948 new Network[] { mWiFiNetworkAgent.getNetwork() }); 7949 waitForIdle(); 7950 7951 // Doesn't really matter whether VPN declares its underlying networks explicitly. 7952 assertTrue(mCm.isActiveNetworkMetered()); 7953 7954 // With WiFi lost, VPN is basically without any underlying networks. And in that case it is 7955 // anyways suppose to be metered. 7956 mWiFiNetworkAgent.disconnect(); 7957 waitForIdle(); 7958 7959 assertTrue(mCm.isActiveNetworkMetered()); 7960 7961 mMockVpn.disconnect(); 7962 } 7963 7964 private class DetailedBlockedStatusCallback extends TestNetworkCallback { 7965 public void expectAvailableThenValidatedCallbacks(HasNetwork n, int blockedStatus) { 7966 super.expectAvailableThenValidatedCallbacks(n.getNetwork(), blockedStatus, TIMEOUT_MS); 7967 } 7968 public void expectBlockedStatusCallback(HasNetwork n, int blockedStatus) { 7969 // This doesn't work: 7970 // super.expectBlockedStatusCallback(blockedStatus, n.getNetwork()); 7971 super.expectBlockedStatusCallback(blockedStatus, n.getNetwork(), TIMEOUT_MS); 7972 } 7973 public void onBlockedStatusChanged(Network network, int blockedReasons) { 7974 getHistory().add(new CallbackEntry.BlockedStatusInt(network, blockedReasons)); 7975 } 7976 } 7977 7978 @Test 7979 public void testNetworkBlockedStatus() throws Exception { 7980 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback(); 7981 final NetworkRequest cellRequest = new NetworkRequest.Builder() 7982 .addTransportType(TRANSPORT_CELLULAR) 7983 .build(); 7984 mCm.registerNetworkCallback(cellRequest, cellNetworkCallback); 7985 final DetailedBlockedStatusCallback detailedCallback = new DetailedBlockedStatusCallback(); 7986 mCm.registerNetworkCallback(cellRequest, detailedCallback); 7987 7988 mockUidNetworkingBlocked(); 7989 7990 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 7991 mCellNetworkAgent.connect(true); 7992 cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 7993 detailedCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent, 7994 BLOCKED_REASON_NONE); 7995 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 7996 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 7997 assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 7998 assertExtraInfoFromCmPresent(mCellNetworkAgent); 7999 8000 setBlockedReasonChanged(BLOCKED_REASON_BATTERY_SAVER); 8001 cellNetworkCallback.expectBlockedStatusCallback(true, mCellNetworkAgent); 8002 detailedCallback.expectBlockedStatusCallback(mCellNetworkAgent, 8003 BLOCKED_REASON_BATTERY_SAVER); 8004 assertNull(mCm.getActiveNetwork()); 8005 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); 8006 assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); 8007 assertExtraInfoFromCmBlocked(mCellNetworkAgent); 8008 8009 // If blocked state does not change but blocked reason does, the boolean callback is called. 8010 // TODO: investigate de-duplicating. 8011 setBlockedReasonChanged(BLOCKED_METERED_REASON_USER_RESTRICTED); 8012 cellNetworkCallback.expectBlockedStatusCallback(true, mCellNetworkAgent); 8013 detailedCallback.expectBlockedStatusCallback(mCellNetworkAgent, 8014 BLOCKED_METERED_REASON_USER_RESTRICTED); 8015 8016 setBlockedReasonChanged(BLOCKED_REASON_NONE); 8017 cellNetworkCallback.expectBlockedStatusCallback(false, mCellNetworkAgent); 8018 detailedCallback.expectBlockedStatusCallback(mCellNetworkAgent, BLOCKED_REASON_NONE); 8019 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 8020 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 8021 assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 8022 assertExtraInfoFromCmPresent(mCellNetworkAgent); 8023 8024 setBlockedReasonChanged(BLOCKED_METERED_REASON_DATA_SAVER); 8025 cellNetworkCallback.expectBlockedStatusCallback(true, mCellNetworkAgent); 8026 detailedCallback.expectBlockedStatusCallback(mCellNetworkAgent, 8027 BLOCKED_METERED_REASON_DATA_SAVER); 8028 assertNull(mCm.getActiveNetwork()); 8029 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); 8030 assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); 8031 assertExtraInfoFromCmBlocked(mCellNetworkAgent); 8032 8033 // Restrict the network based on UID rule and NOT_METERED capability change. 8034 mCellNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED); 8035 cellNetworkCallback.expectCapabilitiesWith(NET_CAPABILITY_NOT_METERED, mCellNetworkAgent); 8036 cellNetworkCallback.expectBlockedStatusCallback(false, mCellNetworkAgent); 8037 detailedCallback.expectCapabilitiesWith(NET_CAPABILITY_NOT_METERED, mCellNetworkAgent); 8038 detailedCallback.expectBlockedStatusCallback(mCellNetworkAgent, BLOCKED_REASON_NONE); 8039 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 8040 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 8041 assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 8042 assertExtraInfoFromCmPresent(mCellNetworkAgent); 8043 8044 mCellNetworkAgent.removeCapability(NET_CAPABILITY_NOT_METERED); 8045 cellNetworkCallback.expectCapabilitiesWithout(NET_CAPABILITY_NOT_METERED, 8046 mCellNetworkAgent); 8047 cellNetworkCallback.expectBlockedStatusCallback(true, mCellNetworkAgent); 8048 detailedCallback.expectCapabilitiesWithout(NET_CAPABILITY_NOT_METERED, 8049 mCellNetworkAgent); 8050 detailedCallback.expectBlockedStatusCallback(mCellNetworkAgent, 8051 BLOCKED_METERED_REASON_DATA_SAVER); 8052 assertNull(mCm.getActiveNetwork()); 8053 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); 8054 assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); 8055 assertExtraInfoFromCmBlocked(mCellNetworkAgent); 8056 8057 setBlockedReasonChanged(BLOCKED_REASON_NONE); 8058 cellNetworkCallback.expectBlockedStatusCallback(false, mCellNetworkAgent); 8059 detailedCallback.expectBlockedStatusCallback(mCellNetworkAgent, BLOCKED_REASON_NONE); 8060 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 8061 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 8062 assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 8063 assertExtraInfoFromCmPresent(mCellNetworkAgent); 8064 8065 setBlockedReasonChanged(BLOCKED_REASON_NONE); 8066 cellNetworkCallback.assertNoCallback(); 8067 detailedCallback.assertNoCallback(); 8068 8069 // Restrict background data. Networking is not blocked because the network is unmetered. 8070 setBlockedReasonChanged(BLOCKED_METERED_REASON_DATA_SAVER); 8071 cellNetworkCallback.expectBlockedStatusCallback(true, mCellNetworkAgent); 8072 detailedCallback.expectBlockedStatusCallback(mCellNetworkAgent, 8073 BLOCKED_METERED_REASON_DATA_SAVER); 8074 assertNull(mCm.getActiveNetwork()); 8075 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); 8076 assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); 8077 assertExtraInfoFromCmBlocked(mCellNetworkAgent); 8078 setBlockedReasonChanged(BLOCKED_METERED_REASON_DATA_SAVER); 8079 cellNetworkCallback.assertNoCallback(); 8080 8081 setBlockedReasonChanged(BLOCKED_REASON_NONE); 8082 cellNetworkCallback.expectBlockedStatusCallback(false, mCellNetworkAgent); 8083 detailedCallback.expectBlockedStatusCallback(mCellNetworkAgent, BLOCKED_REASON_NONE); 8084 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 8085 assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 8086 assertExtraInfoFromCmPresent(mCellNetworkAgent); 8087 8088 setBlockedReasonChanged(BLOCKED_REASON_NONE); 8089 cellNetworkCallback.assertNoCallback(); 8090 detailedCallback.assertNoCallback(); 8091 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 8092 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 8093 assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 8094 assertExtraInfoFromCmPresent(mCellNetworkAgent); 8095 8096 mCm.unregisterNetworkCallback(cellNetworkCallback); 8097 } 8098 8099 @Test 8100 public void testNetworkBlockedStatusBeforeAndAfterConnect() throws Exception { 8101 final TestNetworkCallback defaultCallback = new TestNetworkCallback(); 8102 mCm.registerDefaultNetworkCallback(defaultCallback); 8103 mockUidNetworkingBlocked(); 8104 8105 // No Networkcallbacks invoked before any network is active. 8106 setBlockedReasonChanged(BLOCKED_REASON_BATTERY_SAVER); 8107 setBlockedReasonChanged(BLOCKED_REASON_NONE); 8108 setBlockedReasonChanged(BLOCKED_METERED_REASON_DATA_SAVER); 8109 defaultCallback.assertNoCallback(); 8110 8111 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 8112 mCellNetworkAgent.connect(true); 8113 defaultCallback.expectAvailableCallbacksUnvalidatedAndBlocked(mCellNetworkAgent); 8114 defaultCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mCellNetworkAgent); 8115 8116 // Allow to use the network after switching to NOT_METERED network. 8117 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 8118 mWiFiNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED); 8119 mWiFiNetworkAgent.connect(true); 8120 defaultCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent); 8121 8122 // Switch to METERED network. Restrict the use of the network. 8123 mWiFiNetworkAgent.disconnect(); 8124 defaultCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 8125 defaultCallback.expectAvailableCallbacksValidatedAndBlocked(mCellNetworkAgent); 8126 8127 // Network becomes NOT_METERED. 8128 mCellNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED); 8129 defaultCallback.expectCapabilitiesWith(NET_CAPABILITY_NOT_METERED, mCellNetworkAgent); 8130 defaultCallback.expectBlockedStatusCallback(false, mCellNetworkAgent); 8131 8132 // Verify there's no Networkcallbacks invoked after data saver on/off. 8133 setBlockedReasonChanged(BLOCKED_METERED_REASON_DATA_SAVER); 8134 setBlockedReasonChanged(BLOCKED_REASON_NONE); 8135 defaultCallback.assertNoCallback(); 8136 8137 mCellNetworkAgent.disconnect(); 8138 defaultCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 8139 defaultCallback.assertNoCallback(); 8140 8141 mCm.unregisterNetworkCallback(defaultCallback); 8142 } 8143 8144 private void expectNetworkRejectNonSecureVpn(InOrder inOrder, boolean add, 8145 UidRangeParcel... expected) throws Exception { 8146 inOrder.verify(mMockNetd).networkRejectNonSecureVpn(eq(add), aryEq(expected)); 8147 } 8148 8149 private void checkNetworkInfo(NetworkInfo ni, int type, DetailedState state) { 8150 assertNotNull(ni); 8151 assertEquals(type, ni.getType()); 8152 assertEquals(ConnectivityManager.getNetworkTypeName(type), state, ni.getDetailedState()); 8153 if (state == DetailedState.CONNECTED || state == DetailedState.SUSPENDED) { 8154 assertNotNull(ni.getExtraInfo()); 8155 } else { 8156 // Technically speaking, a network that's in CONNECTING state will generally have a 8157 // non-null extraInfo. This doesn't actually happen in this test because it never calls 8158 // a legacy API while a network is connecting. When a network is in CONNECTING state 8159 // because of legacy lockdown VPN, its extraInfo is always null. 8160 assertNull(ni.getExtraInfo()); 8161 } 8162 } 8163 8164 private void assertActiveNetworkInfo(int type, DetailedState state) { 8165 checkNetworkInfo(mCm.getActiveNetworkInfo(), type, state); 8166 } 8167 private void assertNetworkInfo(int type, DetailedState state) { 8168 checkNetworkInfo(mCm.getNetworkInfo(type), type, state); 8169 } 8170 8171 private void assertExtraInfoFromCm(TestNetworkAgentWrapper network, boolean present) { 8172 final NetworkInfo niForNetwork = mCm.getNetworkInfo(network.getNetwork()); 8173 final NetworkInfo niForType = mCm.getNetworkInfo(network.getLegacyType()); 8174 if (present) { 8175 assertEquals(network.getExtraInfo(), niForNetwork.getExtraInfo()); 8176 assertEquals(network.getExtraInfo(), niForType.getExtraInfo()); 8177 } else { 8178 assertNull(niForNetwork.getExtraInfo()); 8179 assertNull(niForType.getExtraInfo()); 8180 } 8181 } 8182 8183 private void assertExtraInfoFromCmBlocked(TestNetworkAgentWrapper network) { 8184 assertExtraInfoFromCm(network, false); 8185 } 8186 8187 private void assertExtraInfoFromCmPresent(TestNetworkAgentWrapper network) { 8188 assertExtraInfoFromCm(network, true); 8189 } 8190 8191 // Checks that each of the |agents| receive a blocked status change callback with the specified 8192 // |blocked| value, in any order. This is needed because when an event affects multiple 8193 // networks, ConnectivityService does not guarantee the order in which callbacks are fired. 8194 private void assertBlockedCallbackInAnyOrder(TestNetworkCallback callback, boolean blocked, 8195 TestNetworkAgentWrapper... agents) { 8196 final List<Network> expectedNetworks = Arrays.asList(agents).stream() 8197 .map((agent) -> agent.getNetwork()) 8198 .collect(Collectors.toList()); 8199 8200 // Expect exactly one blocked callback for each agent. 8201 for (int i = 0; i < agents.length; i++) { 8202 CallbackEntry e = callback.expectCallbackThat(TIMEOUT_MS, (c) -> 8203 c instanceof CallbackEntry.BlockedStatus 8204 && ((CallbackEntry.BlockedStatus) c).getBlocked() == blocked); 8205 Network network = e.getNetwork(); 8206 assertTrue("Received unexpected blocked callback for network " + network, 8207 expectedNetworks.remove(network)); 8208 } 8209 } 8210 8211 @Test 8212 public void testNetworkBlockedStatusAlwaysOnVpn() throws Exception { 8213 mServiceContext.setPermission( 8214 Manifest.permission.CONTROL_ALWAYS_ON_VPN, PERMISSION_GRANTED); 8215 mServiceContext.setPermission( 8216 Manifest.permission.CONTROL_VPN, PERMISSION_GRANTED); 8217 mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_GRANTED); 8218 8219 final TestNetworkCallback callback = new TestNetworkCallback(); 8220 final NetworkRequest request = new NetworkRequest.Builder() 8221 .removeCapability(NET_CAPABILITY_NOT_VPN) 8222 .build(); 8223 mCm.registerNetworkCallback(request, callback); 8224 8225 final TestNetworkCallback defaultCallback = new TestNetworkCallback(); 8226 mCm.registerDefaultNetworkCallback(defaultCallback); 8227 8228 final TestNetworkCallback vpnUidCallback = new TestNetworkCallback(); 8229 final NetworkRequest vpnUidRequest = new NetworkRequest.Builder().build(); 8230 registerNetworkCallbackAsUid(vpnUidRequest, vpnUidCallback, VPN_UID); 8231 8232 final TestNetworkCallback vpnUidDefaultCallback = new TestNetworkCallback(); 8233 registerDefaultNetworkCallbackAsUid(vpnUidDefaultCallback, VPN_UID); 8234 8235 final TestNetworkCallback vpnDefaultCallbackAsUid = new TestNetworkCallback(); 8236 mCm.registerDefaultNetworkCallbackForUid(VPN_UID, vpnDefaultCallbackAsUid, 8237 new Handler(ConnectivityThread.getInstanceLooper())); 8238 8239 final int uid = Process.myUid(); 8240 final int userId = UserHandle.getUserId(uid); 8241 final ArrayList<String> allowList = new ArrayList<>(); 8242 mVpnManagerService.setAlwaysOnVpnPackage(userId, ALWAYS_ON_PACKAGE, true /* lockdown */, 8243 allowList); 8244 waitForIdle(); 8245 8246 UidRangeParcel firstHalf = new UidRangeParcel(1, VPN_UID - 1); 8247 UidRangeParcel secondHalf = new UidRangeParcel(VPN_UID + 1, 99999); 8248 InOrder inOrder = inOrder(mMockNetd); 8249 expectNetworkRejectNonSecureVpn(inOrder, true, firstHalf, secondHalf); 8250 8251 // Connect a network when lockdown is active, expect to see it blocked. 8252 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 8253 mWiFiNetworkAgent.connect(false /* validated */); 8254 callback.expectAvailableCallbacksUnvalidatedAndBlocked(mWiFiNetworkAgent); 8255 defaultCallback.expectAvailableCallbacksUnvalidatedAndBlocked(mWiFiNetworkAgent); 8256 vpnUidCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 8257 vpnUidDefaultCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 8258 vpnDefaultCallbackAsUid.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 8259 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetworkForUid(VPN_UID)); 8260 assertNull(mCm.getActiveNetwork()); 8261 assertActiveNetworkInfo(TYPE_WIFI, DetailedState.BLOCKED); 8262 // Mobile is BLOCKED even though it's not actually connected. 8263 assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); 8264 assertNetworkInfo(TYPE_WIFI, DetailedState.BLOCKED); 8265 8266 // Disable lockdown, expect to see the network unblocked. 8267 mVpnManagerService.setAlwaysOnVpnPackage(userId, null, false /* lockdown */, allowList); 8268 callback.expectBlockedStatusCallback(false, mWiFiNetworkAgent); 8269 defaultCallback.expectBlockedStatusCallback(false, mWiFiNetworkAgent); 8270 vpnUidCallback.assertNoCallback(); 8271 vpnUidDefaultCallback.assertNoCallback(); 8272 vpnDefaultCallbackAsUid.assertNoCallback(); 8273 expectNetworkRejectNonSecureVpn(inOrder, false, firstHalf, secondHalf); 8274 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetworkForUid(VPN_UID)); 8275 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 8276 assertActiveNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 8277 assertNetworkInfo(TYPE_MOBILE, DetailedState.DISCONNECTED); 8278 assertNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 8279 8280 // Add our UID to the allowlist and re-enable lockdown, expect network is not blocked. 8281 allowList.add(TEST_PACKAGE_NAME); 8282 mVpnManagerService.setAlwaysOnVpnPackage(userId, ALWAYS_ON_PACKAGE, true /* lockdown */, 8283 allowList); 8284 callback.assertNoCallback(); 8285 defaultCallback.assertNoCallback(); 8286 vpnUidCallback.assertNoCallback(); 8287 vpnUidDefaultCallback.assertNoCallback(); 8288 vpnDefaultCallbackAsUid.assertNoCallback(); 8289 8290 // The following requires that the UID of this test package is greater than VPN_UID. This 8291 // is always true in practice because a plain AOSP build with no apps installed has almost 8292 // 200 packages installed. 8293 final UidRangeParcel piece1 = new UidRangeParcel(1, VPN_UID - 1); 8294 final UidRangeParcel piece2 = new UidRangeParcel(VPN_UID + 1, uid - 1); 8295 final UidRangeParcel piece3 = new UidRangeParcel(uid + 1, 99999); 8296 expectNetworkRejectNonSecureVpn(inOrder, true, piece1, piece2, piece3); 8297 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetworkForUid(VPN_UID)); 8298 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 8299 assertActiveNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 8300 assertNetworkInfo(TYPE_MOBILE, DetailedState.DISCONNECTED); 8301 assertNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 8302 8303 // Connect a new network, expect it to be unblocked. 8304 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 8305 mCellNetworkAgent.connect(false /* validated */); 8306 callback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent); 8307 defaultCallback.assertNoCallback(); 8308 vpnUidCallback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent); 8309 vpnUidDefaultCallback.assertNoCallback(); 8310 vpnDefaultCallbackAsUid.assertNoCallback(); 8311 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetworkForUid(VPN_UID)); 8312 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 8313 assertActiveNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 8314 // Cellular is DISCONNECTED because it's not the default and there are no requests for it. 8315 assertNetworkInfo(TYPE_MOBILE, DetailedState.DISCONNECTED); 8316 assertNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 8317 8318 // Disable lockdown, remove our UID from the allowlist, and re-enable lockdown. 8319 // Everything should now be blocked. 8320 mVpnManagerService.setAlwaysOnVpnPackage(userId, null, false /* lockdown */, allowList); 8321 waitForIdle(); 8322 expectNetworkRejectNonSecureVpn(inOrder, false, piece1, piece2, piece3); 8323 allowList.clear(); 8324 mVpnManagerService.setAlwaysOnVpnPackage(userId, ALWAYS_ON_PACKAGE, true /* lockdown */, 8325 allowList); 8326 waitForIdle(); 8327 expectNetworkRejectNonSecureVpn(inOrder, true, firstHalf, secondHalf); 8328 defaultCallback.expectBlockedStatusCallback(true, mWiFiNetworkAgent); 8329 assertBlockedCallbackInAnyOrder(callback, true, mWiFiNetworkAgent, mCellNetworkAgent); 8330 vpnUidCallback.assertNoCallback(); 8331 vpnUidDefaultCallback.assertNoCallback(); 8332 vpnDefaultCallbackAsUid.assertNoCallback(); 8333 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetworkForUid(VPN_UID)); 8334 assertNull(mCm.getActiveNetwork()); 8335 assertActiveNetworkInfo(TYPE_WIFI, DetailedState.BLOCKED); 8336 assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); 8337 assertNetworkInfo(TYPE_WIFI, DetailedState.BLOCKED); 8338 8339 // Disable lockdown. Everything is unblocked. 8340 mVpnManagerService.setAlwaysOnVpnPackage(userId, null, false /* lockdown */, allowList); 8341 defaultCallback.expectBlockedStatusCallback(false, mWiFiNetworkAgent); 8342 assertBlockedCallbackInAnyOrder(callback, false, mWiFiNetworkAgent, mCellNetworkAgent); 8343 vpnUidCallback.assertNoCallback(); 8344 vpnUidDefaultCallback.assertNoCallback(); 8345 vpnDefaultCallbackAsUid.assertNoCallback(); 8346 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetworkForUid(VPN_UID)); 8347 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 8348 assertActiveNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 8349 assertNetworkInfo(TYPE_MOBILE, DetailedState.DISCONNECTED); 8350 assertNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 8351 8352 // Enable and disable an always-on VPN package without lockdown. Expect no changes. 8353 reset(mMockNetd); 8354 mVpnManagerService.setAlwaysOnVpnPackage(userId, ALWAYS_ON_PACKAGE, false /* lockdown */, 8355 allowList); 8356 inOrder.verify(mMockNetd, never()).networkRejectNonSecureVpn(anyBoolean(), any()); 8357 callback.assertNoCallback(); 8358 defaultCallback.assertNoCallback(); 8359 vpnUidCallback.assertNoCallback(); 8360 vpnUidDefaultCallback.assertNoCallback(); 8361 vpnDefaultCallbackAsUid.assertNoCallback(); 8362 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetworkForUid(VPN_UID)); 8363 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 8364 assertActiveNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 8365 assertNetworkInfo(TYPE_MOBILE, DetailedState.DISCONNECTED); 8366 assertNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 8367 8368 mVpnManagerService.setAlwaysOnVpnPackage(userId, null, false /* lockdown */, allowList); 8369 inOrder.verify(mMockNetd, never()).networkRejectNonSecureVpn(anyBoolean(), any()); 8370 callback.assertNoCallback(); 8371 defaultCallback.assertNoCallback(); 8372 vpnUidCallback.assertNoCallback(); 8373 vpnUidDefaultCallback.assertNoCallback(); 8374 vpnDefaultCallbackAsUid.assertNoCallback(); 8375 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetworkForUid(VPN_UID)); 8376 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 8377 assertActiveNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 8378 assertNetworkInfo(TYPE_MOBILE, DetailedState.DISCONNECTED); 8379 assertNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 8380 8381 // Enable lockdown and connect a VPN. The VPN is not blocked. 8382 mVpnManagerService.setAlwaysOnVpnPackage(userId, ALWAYS_ON_PACKAGE, true /* lockdown */, 8383 allowList); 8384 defaultCallback.expectBlockedStatusCallback(true, mWiFiNetworkAgent); 8385 assertBlockedCallbackInAnyOrder(callback, true, mWiFiNetworkAgent, mCellNetworkAgent); 8386 vpnUidCallback.assertNoCallback(); 8387 vpnUidDefaultCallback.assertNoCallback(); 8388 vpnDefaultCallbackAsUid.assertNoCallback(); 8389 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetworkForUid(VPN_UID)); 8390 assertNull(mCm.getActiveNetwork()); 8391 assertActiveNetworkInfo(TYPE_WIFI, DetailedState.BLOCKED); 8392 assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); 8393 assertNetworkInfo(TYPE_WIFI, DetailedState.BLOCKED); 8394 8395 mMockVpn.establishForMyUid(); 8396 assertUidRangesUpdatedForMyUid(true); 8397 defaultCallback.expectAvailableThenValidatedCallbacks(mMockVpn); 8398 vpnUidCallback.assertNoCallback(); // vpnUidCallback has NOT_VPN capability. 8399 vpnUidDefaultCallback.assertNoCallback(); // VPN does not apply to VPN_UID 8400 vpnDefaultCallbackAsUid.assertNoCallback(); 8401 assertEquals(mMockVpn.getNetwork(), mCm.getActiveNetwork()); 8402 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetworkForUid(VPN_UID)); 8403 assertActiveNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 8404 assertNetworkInfo(TYPE_MOBILE, DetailedState.DISCONNECTED); 8405 assertNetworkInfo(TYPE_VPN, DetailedState.CONNECTED); 8406 assertNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 8407 8408 mMockVpn.disconnect(); 8409 defaultCallback.expectCallback(CallbackEntry.LOST, mMockVpn); 8410 defaultCallback.expectAvailableCallbacksUnvalidatedAndBlocked(mWiFiNetworkAgent); 8411 vpnUidCallback.assertNoCallback(); 8412 vpnUidDefaultCallback.assertNoCallback(); 8413 vpnDefaultCallbackAsUid.assertNoCallback(); 8414 assertNull(mCm.getActiveNetwork()); 8415 8416 mCm.unregisterNetworkCallback(callback); 8417 mCm.unregisterNetworkCallback(defaultCallback); 8418 mCm.unregisterNetworkCallback(vpnUidCallback); 8419 mCm.unregisterNetworkCallback(vpnUidDefaultCallback); 8420 mCm.unregisterNetworkCallback(vpnDefaultCallbackAsUid); 8421 } 8422 8423 private void setupLegacyLockdownVpn() { 8424 final String profileName = "testVpnProfile"; 8425 final byte[] profileTag = profileName.getBytes(StandardCharsets.UTF_8); 8426 when(mVpnProfileStore.get(Credentials.LOCKDOWN_VPN)).thenReturn(profileTag); 8427 8428 final VpnProfile profile = new VpnProfile(profileName); 8429 profile.name = "My VPN"; 8430 profile.server = "192.0.2.1"; 8431 profile.dnsServers = "8.8.8.8"; 8432 profile.type = VpnProfile.TYPE_IPSEC_XAUTH_PSK; 8433 final byte[] encodedProfile = profile.encode(); 8434 when(mVpnProfileStore.get(Credentials.VPN + profileName)).thenReturn(encodedProfile); 8435 } 8436 8437 private void establishLegacyLockdownVpn(Network underlying) throws Exception { 8438 // The legacy lockdown VPN only supports userId 0, and must have an underlying network. 8439 assertNotNull(underlying); 8440 mMockVpn.setVpnType(VpnManager.TYPE_VPN_LEGACY); 8441 // The legacy lockdown VPN only supports userId 0. 8442 final Set<UidRange> ranges = Collections.singleton(PRIMARY_UIDRANGE); 8443 mMockVpn.registerAgent(ranges); 8444 mMockVpn.setUnderlyingNetworks(new Network[]{underlying}); 8445 mMockVpn.connect(true); 8446 } 8447 8448 @Test 8449 public void testLegacyLockdownVpn() throws Exception { 8450 mServiceContext.setPermission( 8451 Manifest.permission.CONTROL_VPN, PERMISSION_GRANTED); 8452 // For LockdownVpnTracker to call registerSystemDefaultNetworkCallback. 8453 mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_GRANTED); 8454 8455 final NetworkRequest request = new NetworkRequest.Builder().clearCapabilities().build(); 8456 final TestNetworkCallback callback = new TestNetworkCallback(); 8457 mCm.registerNetworkCallback(request, callback); 8458 8459 final TestNetworkCallback defaultCallback = new TestNetworkCallback(); 8460 mCm.registerDefaultNetworkCallback(defaultCallback); 8461 8462 final TestNetworkCallback systemDefaultCallback = new TestNetworkCallback(); 8463 mCm.registerSystemDefaultNetworkCallback(systemDefaultCallback, 8464 new Handler(ConnectivityThread.getInstanceLooper())); 8465 8466 // Pretend lockdown VPN was configured. 8467 setupLegacyLockdownVpn(); 8468 8469 // LockdownVpnTracker disables the Vpn teardown code and enables lockdown. 8470 // Check the VPN's state before it does so. 8471 assertTrue(mMockVpn.getEnableTeardown()); 8472 assertFalse(mMockVpn.getLockdown()); 8473 8474 // Send a USER_UNLOCKED broadcast so CS starts LockdownVpnTracker. 8475 final int userId = UserHandle.getUserId(Process.myUid()); 8476 final Intent addedIntent = new Intent(ACTION_USER_UNLOCKED); 8477 addedIntent.putExtra(Intent.EXTRA_USER, UserHandle.of(userId)); 8478 addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 8479 processBroadcast(addedIntent); 8480 8481 // Lockdown VPN disables teardown and enables lockdown. 8482 assertFalse(mMockVpn.getEnableTeardown()); 8483 assertTrue(mMockVpn.getLockdown()); 8484 8485 // Bring up a network. 8486 // Expect nothing to happen because the network does not have an IPv4 default route: legacy 8487 // VPN only supports IPv4. 8488 final LinkProperties cellLp = new LinkProperties(); 8489 cellLp.setInterfaceName("rmnet0"); 8490 cellLp.addLinkAddress(new LinkAddress("2001:db8::1/64")); 8491 cellLp.addRoute(new RouteInfo(new IpPrefix("::/0"), null, "rmnet0")); 8492 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp); 8493 mCellNetworkAgent.connect(false /* validated */); 8494 callback.expectAvailableCallbacksUnvalidatedAndBlocked(mCellNetworkAgent); 8495 defaultCallback.expectAvailableCallbacksUnvalidatedAndBlocked(mCellNetworkAgent); 8496 systemDefaultCallback.expectAvailableCallbacksUnvalidatedAndBlocked(mCellNetworkAgent); 8497 waitForIdle(); 8498 assertNull(mMockVpn.getAgent()); 8499 8500 // Add an IPv4 address. Ideally the VPN should start, but it doesn't because nothing calls 8501 // LockdownVpnTracker#handleStateChangedLocked. This is a bug. 8502 // TODO: consider fixing this. 8503 cellLp.addLinkAddress(new LinkAddress("192.0.2.2/25")); 8504 cellLp.addRoute(new RouteInfo(new IpPrefix("0.0.0.0/0"), null, "rmnet0")); 8505 mCellNetworkAgent.sendLinkProperties(cellLp); 8506 callback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent); 8507 defaultCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent); 8508 systemDefaultCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, 8509 mCellNetworkAgent); 8510 waitForIdle(); 8511 assertNull(mMockVpn.getAgent()); 8512 8513 // Disconnect, then try again with a network that supports IPv4 at connection time. 8514 // Expect lockdown VPN to come up. 8515 ExpectedBroadcast b1 = expectConnectivityAction(TYPE_MOBILE, DetailedState.DISCONNECTED); 8516 mCellNetworkAgent.disconnect(); 8517 callback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 8518 defaultCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 8519 systemDefaultCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 8520 b1.expectBroadcast(); 8521 8522 // When lockdown VPN is active, the NetworkInfo state in CONNECTIVITY_ACTION is overwritten 8523 // with the state of the VPN network. So expect a CONNECTING broadcast. 8524 b1 = expectConnectivityAction(TYPE_MOBILE, DetailedState.CONNECTING); 8525 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp); 8526 mCellNetworkAgent.connect(false /* validated */); 8527 callback.expectAvailableCallbacksUnvalidatedAndBlocked(mCellNetworkAgent); 8528 defaultCallback.expectAvailableCallbacksUnvalidatedAndBlocked(mCellNetworkAgent); 8529 systemDefaultCallback.expectAvailableCallbacksUnvalidatedAndBlocked(mCellNetworkAgent); 8530 b1.expectBroadcast(); 8531 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); 8532 assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); 8533 assertNetworkInfo(TYPE_WIFI, DetailedState.BLOCKED); 8534 assertNetworkInfo(TYPE_VPN, DetailedState.BLOCKED); 8535 assertExtraInfoFromCmBlocked(mCellNetworkAgent); 8536 8537 // TODO: it would be nice if we could simply rely on the production code here, and have 8538 // LockdownVpnTracker start the VPN, have the VPN code register its NetworkAgent with 8539 // ConnectivityService, etc. That would require duplicating a fair bit of code from the 8540 // Vpn tests around how to mock out LegacyVpnRunner. But even if we did that, this does not 8541 // work for at least two reasons: 8542 // 1. In this test, calling registerNetworkAgent does not actually result in an agent being 8543 // registered. This is because nothing calls onNetworkMonitorCreated, which is what 8544 // actually ends up causing handleRegisterNetworkAgent to be called. Code in this test 8545 // that wants to register an agent must use TestNetworkAgentWrapper. 8546 // 2. Even if we exposed Vpn#agentConnect to the test, and made MockVpn#agentConnect call 8547 // the TestNetworkAgentWrapper code, this would deadlock because the 8548 // TestNetworkAgentWrapper code cannot be called on the handler thread since it calls 8549 // waitForIdle(). 8550 mMockVpn.expectStartLegacyVpnRunner(); 8551 b1 = expectConnectivityAction(TYPE_VPN, DetailedState.CONNECTED); 8552 ExpectedBroadcast b2 = expectConnectivityAction(TYPE_MOBILE, DetailedState.CONNECTED); 8553 establishLegacyLockdownVpn(mCellNetworkAgent.getNetwork()); 8554 callback.expectAvailableThenValidatedCallbacks(mMockVpn); 8555 defaultCallback.expectAvailableThenValidatedCallbacks(mMockVpn); 8556 systemDefaultCallback.assertNoCallback(); 8557 NetworkCapabilities vpnNc = mCm.getNetworkCapabilities(mMockVpn.getNetwork()); 8558 b1.expectBroadcast(); 8559 b2.expectBroadcast(); 8560 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 8561 assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 8562 assertNetworkInfo(TYPE_WIFI, DetailedState.DISCONNECTED); 8563 assertNetworkInfo(TYPE_VPN, DetailedState.CONNECTED); 8564 assertExtraInfoFromCmPresent(mCellNetworkAgent); 8565 assertTrue(vpnNc.hasTransport(TRANSPORT_VPN)); 8566 assertTrue(vpnNc.hasTransport(TRANSPORT_CELLULAR)); 8567 assertFalse(vpnNc.hasTransport(TRANSPORT_WIFI)); 8568 assertFalse(vpnNc.hasCapability(NET_CAPABILITY_NOT_METERED)); 8569 assertVpnTransportInfo(vpnNc, VpnManager.TYPE_VPN_LEGACY); 8570 8571 // Switch default network from cell to wifi. Expect VPN to disconnect and reconnect. 8572 final LinkProperties wifiLp = new LinkProperties(); 8573 wifiLp.setInterfaceName("wlan0"); 8574 wifiLp.addLinkAddress(new LinkAddress("192.0.2.163/25")); 8575 wifiLp.addRoute(new RouteInfo(new IpPrefix("0.0.0.0/0"), null, "wlan0")); 8576 final NetworkCapabilities wifiNc = new NetworkCapabilities(); 8577 wifiNc.addTransportType(TRANSPORT_WIFI); 8578 wifiNc.addCapability(NET_CAPABILITY_NOT_METERED); 8579 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, wifiLp, wifiNc); 8580 8581 b1 = expectConnectivityAction(TYPE_MOBILE, DetailedState.DISCONNECTED); 8582 // Wifi is CONNECTING because the VPN isn't up yet. 8583 b2 = expectConnectivityAction(TYPE_WIFI, DetailedState.CONNECTING); 8584 ExpectedBroadcast b3 = expectConnectivityAction(TYPE_VPN, DetailedState.DISCONNECTED); 8585 mWiFiNetworkAgent.connect(false /* validated */); 8586 b1.expectBroadcast(); 8587 b2.expectBroadcast(); 8588 b3.expectBroadcast(); 8589 mMockVpn.expectStopVpnRunnerPrivileged(); 8590 mMockVpn.expectStartLegacyVpnRunner(); 8591 8592 // TODO: why is wifi not blocked? Is it because when this callback is sent, the VPN is still 8593 // connected, so the network is not considered blocked by the lockdown UID ranges? But the 8594 // fact that a VPN is connected should only result in the VPN itself being unblocked, not 8595 // any other network. Bug in isUidBlockedByVpn? 8596 callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 8597 callback.expectCallback(CallbackEntry.LOST, mMockVpn); 8598 defaultCallback.expectCallback(CallbackEntry.LOST, mMockVpn); 8599 defaultCallback.expectAvailableCallbacksUnvalidatedAndBlocked(mWiFiNetworkAgent); 8600 systemDefaultCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 8601 8602 // While the VPN is reconnecting on the new network, everything is blocked. 8603 assertActiveNetworkInfo(TYPE_WIFI, DetailedState.BLOCKED); 8604 assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); 8605 assertNetworkInfo(TYPE_WIFI, DetailedState.BLOCKED); 8606 assertNetworkInfo(TYPE_VPN, DetailedState.BLOCKED); 8607 assertExtraInfoFromCmBlocked(mWiFiNetworkAgent); 8608 8609 // The VPN comes up again on wifi. 8610 b1 = expectConnectivityAction(TYPE_VPN, DetailedState.CONNECTED); 8611 b2 = expectConnectivityAction(TYPE_WIFI, DetailedState.CONNECTED); 8612 establishLegacyLockdownVpn(mWiFiNetworkAgent.getNetwork()); 8613 callback.expectAvailableThenValidatedCallbacks(mMockVpn); 8614 defaultCallback.expectAvailableThenValidatedCallbacks(mMockVpn); 8615 systemDefaultCallback.assertNoCallback(); 8616 b1.expectBroadcast(); 8617 b2.expectBroadcast(); 8618 assertActiveNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 8619 assertNetworkInfo(TYPE_MOBILE, DetailedState.DISCONNECTED); 8620 assertNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 8621 assertNetworkInfo(TYPE_VPN, DetailedState.CONNECTED); 8622 assertExtraInfoFromCmPresent(mWiFiNetworkAgent); 8623 vpnNc = mCm.getNetworkCapabilities(mMockVpn.getNetwork()); 8624 assertTrue(vpnNc.hasTransport(TRANSPORT_VPN)); 8625 assertTrue(vpnNc.hasTransport(TRANSPORT_WIFI)); 8626 assertFalse(vpnNc.hasTransport(TRANSPORT_CELLULAR)); 8627 assertTrue(vpnNc.hasCapability(NET_CAPABILITY_NOT_METERED)); 8628 8629 // Disconnect cell. Nothing much happens since it's not the default network. 8630 mCellNetworkAgent.disconnect(); 8631 callback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 8632 defaultCallback.assertNoCallback(); 8633 systemDefaultCallback.assertNoCallback(); 8634 8635 assertActiveNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 8636 assertNetworkInfo(TYPE_MOBILE, DetailedState.DISCONNECTED); 8637 assertNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 8638 assertNetworkInfo(TYPE_VPN, DetailedState.CONNECTED); 8639 assertExtraInfoFromCmPresent(mWiFiNetworkAgent); 8640 8641 b1 = expectConnectivityAction(TYPE_WIFI, DetailedState.DISCONNECTED); 8642 b2 = expectConnectivityAction(TYPE_VPN, DetailedState.DISCONNECTED); 8643 mWiFiNetworkAgent.disconnect(); 8644 callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 8645 systemDefaultCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 8646 b1.expectBroadcast(); 8647 callback.expectCapabilitiesThat(mMockVpn, nc -> !nc.hasTransport(TRANSPORT_WIFI)); 8648 mMockVpn.expectStopVpnRunnerPrivileged(); 8649 callback.expectCallback(CallbackEntry.LOST, mMockVpn); 8650 b2.expectBroadcast(); 8651 } 8652 8653 /** 8654 * Test mutable and requestable network capabilities such as 8655 * {@link NetworkCapabilities#NET_CAPABILITY_TRUSTED} and 8656 * {@link NetworkCapabilities#NET_CAPABILITY_NOT_VCN_MANAGED}. Verify that the 8657 * {@code ConnectivityService} re-assign the networks accordingly. 8658 */ 8659 @Test 8660 public final void testLoseMutableAndRequestableCaps() throws Exception { 8661 final int[] testCaps = new int [] { 8662 NET_CAPABILITY_TRUSTED, 8663 NET_CAPABILITY_NOT_VCN_MANAGED 8664 }; 8665 for (final int testCap : testCaps) { 8666 // Create requests with and without the testing capability. 8667 final TestNetworkCallback callbackWithCap = new TestNetworkCallback(); 8668 final TestNetworkCallback callbackWithoutCap = new TestNetworkCallback(); 8669 mCm.requestNetwork(new NetworkRequest.Builder().addCapability(testCap).build(), 8670 callbackWithCap); 8671 mCm.requestNetwork(new NetworkRequest.Builder().removeCapability(testCap).build(), 8672 callbackWithoutCap); 8673 8674 // Setup networks with testing capability and verify the default network changes. 8675 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 8676 mCellNetworkAgent.addCapability(testCap); 8677 mCellNetworkAgent.connect(true); 8678 callbackWithCap.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 8679 callbackWithoutCap.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 8680 verify(mMockNetd).networkSetDefault(eq(mCellNetworkAgent.getNetwork().netId)); 8681 reset(mMockNetd); 8682 8683 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 8684 mWiFiNetworkAgent.addCapability(testCap); 8685 mWiFiNetworkAgent.connect(true); 8686 callbackWithCap.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent); 8687 callbackWithoutCap.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent); 8688 verify(mMockNetd).networkSetDefault(eq(mWiFiNetworkAgent.getNetwork().netId)); 8689 reset(mMockNetd); 8690 8691 // Remove the testing capability on wifi, verify the callback and default network 8692 // changes back to cellular. 8693 mWiFiNetworkAgent.removeCapability(testCap); 8694 callbackWithCap.expectAvailableCallbacksValidated(mCellNetworkAgent); 8695 callbackWithoutCap.expectCapabilitiesWithout(testCap, mWiFiNetworkAgent); 8696 verify(mMockNetd).networkSetDefault(eq(mCellNetworkAgent.getNetwork().netId)); 8697 reset(mMockNetd); 8698 8699 mCellNetworkAgent.removeCapability(testCap); 8700 callbackWithCap.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 8701 callbackWithoutCap.assertNoCallback(); 8702 verify(mMockNetd).networkClearDefault(); 8703 8704 mCm.unregisterNetworkCallback(callbackWithCap); 8705 mCm.unregisterNetworkCallback(callbackWithoutCap); 8706 } 8707 } 8708 8709 @Test 8710 public final void testBatteryStatsNetworkType() throws Exception { 8711 final LinkProperties cellLp = new LinkProperties(); 8712 cellLp.setInterfaceName("cell0"); 8713 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp); 8714 mCellNetworkAgent.connect(true); 8715 waitForIdle(); 8716 verify(mDeps).reportNetworkInterfaceForTransports(mServiceContext, 8717 cellLp.getInterfaceName(), 8718 new int[] { TRANSPORT_CELLULAR }); 8719 8720 final LinkProperties wifiLp = new LinkProperties(); 8721 wifiLp.setInterfaceName("wifi0"); 8722 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, wifiLp); 8723 mWiFiNetworkAgent.connect(true); 8724 waitForIdle(); 8725 verify(mDeps).reportNetworkInterfaceForTransports(mServiceContext, 8726 wifiLp.getInterfaceName(), 8727 new int[] { TRANSPORT_WIFI }); 8728 8729 mCellNetworkAgent.disconnect(); 8730 mWiFiNetworkAgent.disconnect(); 8731 8732 cellLp.setInterfaceName("wifi0"); 8733 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp); 8734 mCellNetworkAgent.connect(true); 8735 waitForIdle(); 8736 verify(mDeps).reportNetworkInterfaceForTransports(mServiceContext, 8737 cellLp.getInterfaceName(), 8738 new int[] { TRANSPORT_CELLULAR }); 8739 mCellNetworkAgent.disconnect(); 8740 } 8741 8742 /** 8743 * Make simulated InterfaceConfigParcel for Nat464Xlat to query clat lower layer info. 8744 */ 8745 private InterfaceConfigurationParcel getClatInterfaceConfigParcel(LinkAddress la) { 8746 final InterfaceConfigurationParcel cfg = new InterfaceConfigurationParcel(); 8747 cfg.hwAddr = "11:22:33:44:55:66"; 8748 cfg.ipv4Addr = la.getAddress().getHostAddress(); 8749 cfg.prefixLength = la.getPrefixLength(); 8750 return cfg; 8751 } 8752 8753 /** 8754 * Make expected stack link properties, copied from Nat464Xlat. 8755 */ 8756 private LinkProperties makeClatLinkProperties(LinkAddress la) { 8757 LinkAddress clatAddress = la; 8758 LinkProperties stacked = new LinkProperties(); 8759 stacked.setInterfaceName(CLAT_MOBILE_IFNAME); 8760 RouteInfo ipv4Default = new RouteInfo( 8761 new LinkAddress(Inet4Address.ANY, 0), 8762 clatAddress.getAddress(), CLAT_MOBILE_IFNAME); 8763 stacked.addRoute(ipv4Default); 8764 stacked.addLinkAddress(clatAddress); 8765 return stacked; 8766 } 8767 8768 private Nat64PrefixEventParcel makeNat64PrefixEvent(final int netId, final int prefixOperation, 8769 final String prefixAddress, final int prefixLength) { 8770 final Nat64PrefixEventParcel event = new Nat64PrefixEventParcel(); 8771 event.netId = netId; 8772 event.prefixOperation = prefixOperation; 8773 event.prefixAddress = prefixAddress; 8774 event.prefixLength = prefixLength; 8775 return event; 8776 } 8777 8778 @Test 8779 public void testStackedLinkProperties() throws Exception { 8780 final LinkAddress myIpv4 = new LinkAddress("1.2.3.4/24"); 8781 final LinkAddress myIpv6 = new LinkAddress("2001:db8:1::1/64"); 8782 final String kNat64PrefixString = "2001:db8:64:64:64:64::"; 8783 final IpPrefix kNat64Prefix = new IpPrefix(InetAddress.getByName(kNat64PrefixString), 96); 8784 final String kOtherNat64PrefixString = "64:ff9b::"; 8785 final IpPrefix kOtherNat64Prefix = new IpPrefix( 8786 InetAddress.getByName(kOtherNat64PrefixString), 96); 8787 final RouteInfo ipv6Default = 8788 new RouteInfo((IpPrefix) null, myIpv6.getAddress(), MOBILE_IFNAME); 8789 final RouteInfo ipv6Subnet = new RouteInfo(myIpv6, null, MOBILE_IFNAME); 8790 final RouteInfo ipv4Subnet = new RouteInfo(myIpv4, null, MOBILE_IFNAME); 8791 final RouteInfo stackedDefault = 8792 new RouteInfo((IpPrefix) null, myIpv4.getAddress(), CLAT_MOBILE_IFNAME); 8793 8794 final NetworkRequest networkRequest = new NetworkRequest.Builder() 8795 .addTransportType(TRANSPORT_CELLULAR) 8796 .addCapability(NET_CAPABILITY_INTERNET) 8797 .build(); 8798 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 8799 mCm.registerNetworkCallback(networkRequest, networkCallback); 8800 8801 // Prepare ipv6 only link properties. 8802 final LinkProperties cellLp = new LinkProperties(); 8803 cellLp.setInterfaceName(MOBILE_IFNAME); 8804 cellLp.addLinkAddress(myIpv6); 8805 cellLp.addRoute(ipv6Default); 8806 cellLp.addRoute(ipv6Subnet); 8807 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp); 8808 reset(mMockDnsResolver); 8809 reset(mMockNetd); 8810 8811 // Connect with ipv6 link properties. Expect prefix discovery to be started. 8812 mCellNetworkAgent.connect(true); 8813 int cellNetId = mCellNetworkAgent.getNetwork().netId; 8814 waitForIdle(); 8815 8816 verify(mMockNetd, times(1)).networkCreate(nativeNetworkConfigPhysical(cellNetId, 8817 INetd.PERMISSION_NONE)); 8818 assertRoutesAdded(cellNetId, ipv6Subnet, ipv6Default); 8819 verify(mMockDnsResolver, times(1)).createNetworkCache(eq(cellNetId)); 8820 verify(mMockNetd, times(1)).networkAddInterface(cellNetId, MOBILE_IFNAME); 8821 verify(mDeps).reportNetworkInterfaceForTransports(mServiceContext, 8822 cellLp.getInterfaceName(), 8823 new int[] { TRANSPORT_CELLULAR }); 8824 8825 networkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 8826 verify(mMockDnsResolver, times(1)).startPrefix64Discovery(cellNetId); 8827 8828 // Switching default network updates TCP buffer sizes. 8829 verifyTcpBufferSizeChange(ConnectivityService.DEFAULT_TCP_BUFFER_SIZES); 8830 // Add an IPv4 address. Expect prefix discovery to be stopped. Netd doesn't tell us that 8831 // the NAT64 prefix was removed because one was never discovered. 8832 cellLp.addLinkAddress(myIpv4); 8833 mCellNetworkAgent.sendLinkProperties(cellLp); 8834 networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent); 8835 assertRoutesAdded(cellNetId, ipv4Subnet); 8836 verify(mMockDnsResolver, times(1)).stopPrefix64Discovery(cellNetId); 8837 verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration(any()); 8838 8839 // Make sure BatteryStats was not told about any v4- interfaces, as none should have 8840 // come online yet. 8841 waitForIdle(); 8842 verify(mDeps, never()) 8843 .reportNetworkInterfaceForTransports(eq(mServiceContext), startsWith("v4-"), any()); 8844 8845 verifyNoMoreInteractions(mMockNetd); 8846 verifyNoMoreInteractions(mMockDnsResolver); 8847 reset(mMockNetd); 8848 reset(mMockDnsResolver); 8849 when(mMockNetd.interfaceGetCfg(CLAT_MOBILE_IFNAME)) 8850 .thenReturn(getClatInterfaceConfigParcel(myIpv4)); 8851 8852 // Remove IPv4 address. Expect prefix discovery to be started again. 8853 cellLp.removeLinkAddress(myIpv4); 8854 mCellNetworkAgent.sendLinkProperties(cellLp); 8855 networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent); 8856 verify(mMockDnsResolver, times(1)).startPrefix64Discovery(cellNetId); 8857 assertRoutesRemoved(cellNetId, ipv4Subnet); 8858 8859 // When NAT64 prefix discovery succeeds, LinkProperties are updated and clatd is started. 8860 Nat464Xlat clat = getNat464Xlat(mCellNetworkAgent); 8861 assertNull(mCm.getLinkProperties(mCellNetworkAgent.getNetwork()).getNat64Prefix()); 8862 mService.mResolverUnsolEventCallback.onNat64PrefixEvent( 8863 makeNat64PrefixEvent(cellNetId, PREFIX_OPERATION_ADDED, kNat64PrefixString, 96)); 8864 LinkProperties lpBeforeClat = networkCallback.expectCallback( 8865 CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent).getLp(); 8866 assertEquals(0, lpBeforeClat.getStackedLinks().size()); 8867 assertEquals(kNat64Prefix, lpBeforeClat.getNat64Prefix()); 8868 verify(mMockNetd, times(1)).clatdStart(MOBILE_IFNAME, kNat64Prefix.toString()); 8869 8870 // Clat iface comes up. Expect stacked link to be added. 8871 clat.interfaceLinkStateChanged(CLAT_MOBILE_IFNAME, true); 8872 networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent); 8873 List<LinkProperties> stackedLps = mCm.getLinkProperties(mCellNetworkAgent.getNetwork()) 8874 .getStackedLinks(); 8875 assertEquals(makeClatLinkProperties(myIpv4), stackedLps.get(0)); 8876 assertRoutesAdded(cellNetId, stackedDefault); 8877 verify(mMockNetd, times(1)).networkAddInterface(cellNetId, CLAT_MOBILE_IFNAME); 8878 // Change trivial linkproperties and see if stacked link is preserved. 8879 cellLp.addDnsServer(InetAddress.getByName("8.8.8.8")); 8880 mCellNetworkAgent.sendLinkProperties(cellLp); 8881 networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent); 8882 8883 List<LinkProperties> stackedLpsAfterChange = 8884 mCm.getLinkProperties(mCellNetworkAgent.getNetwork()).getStackedLinks(); 8885 assertNotEquals(stackedLpsAfterChange, Collections.EMPTY_LIST); 8886 assertEquals(makeClatLinkProperties(myIpv4), stackedLpsAfterChange.get(0)); 8887 8888 verify(mMockDnsResolver, times(1)).setResolverConfiguration( 8889 mResolverParamsParcelCaptor.capture()); 8890 ResolverParamsParcel resolvrParams = mResolverParamsParcelCaptor.getValue(); 8891 assertEquals(1, resolvrParams.servers.length); 8892 assertTrue(ArrayUtils.contains(resolvrParams.servers, "8.8.8.8")); 8893 8894 for (final LinkProperties stackedLp : stackedLpsAfterChange) { 8895 verify(mDeps).reportNetworkInterfaceForTransports( 8896 mServiceContext, stackedLp.getInterfaceName(), 8897 new int[] { TRANSPORT_CELLULAR }); 8898 } 8899 reset(mMockNetd); 8900 when(mMockNetd.interfaceGetCfg(CLAT_MOBILE_IFNAME)) 8901 .thenReturn(getClatInterfaceConfigParcel(myIpv4)); 8902 // Change the NAT64 prefix without first removing it. 8903 // Expect clatd to be stopped and started with the new prefix. 8904 mService.mResolverUnsolEventCallback.onNat64PrefixEvent(makeNat64PrefixEvent( 8905 cellNetId, PREFIX_OPERATION_ADDED, kOtherNat64PrefixString, 96)); 8906 networkCallback.expectLinkPropertiesThat(mCellNetworkAgent, 8907 (lp) -> lp.getStackedLinks().size() == 0); 8908 verify(mMockNetd, times(1)).clatdStop(MOBILE_IFNAME); 8909 assertRoutesRemoved(cellNetId, stackedDefault); 8910 verify(mMockNetd, times(1)).networkRemoveInterface(cellNetId, CLAT_MOBILE_IFNAME); 8911 8912 verify(mMockNetd, times(1)).clatdStart(MOBILE_IFNAME, kOtherNat64Prefix.toString()); 8913 networkCallback.expectLinkPropertiesThat(mCellNetworkAgent, 8914 (lp) -> lp.getNat64Prefix().equals(kOtherNat64Prefix)); 8915 clat.interfaceLinkStateChanged(CLAT_MOBILE_IFNAME, true); 8916 networkCallback.expectLinkPropertiesThat(mCellNetworkAgent, 8917 (lp) -> lp.getStackedLinks().size() == 1); 8918 assertRoutesAdded(cellNetId, stackedDefault); 8919 verify(mMockNetd, times(1)).networkAddInterface(cellNetId, CLAT_MOBILE_IFNAME); 8920 reset(mMockNetd); 8921 8922 // Add ipv4 address, expect that clatd and prefix discovery are stopped and stacked 8923 // linkproperties are cleaned up. 8924 cellLp.addLinkAddress(myIpv4); 8925 cellLp.addRoute(ipv4Subnet); 8926 mCellNetworkAgent.sendLinkProperties(cellLp); 8927 networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent); 8928 assertRoutesAdded(cellNetId, ipv4Subnet); 8929 verify(mMockNetd, times(1)).clatdStop(MOBILE_IFNAME); 8930 verify(mMockDnsResolver, times(1)).stopPrefix64Discovery(cellNetId); 8931 8932 // As soon as stop is called, the linkproperties lose the stacked interface. 8933 networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent); 8934 LinkProperties actualLpAfterIpv4 = mCm.getLinkProperties(mCellNetworkAgent.getNetwork()); 8935 LinkProperties expected = new LinkProperties(cellLp); 8936 expected.setNat64Prefix(kOtherNat64Prefix); 8937 assertEquals(expected, actualLpAfterIpv4); 8938 assertEquals(0, actualLpAfterIpv4.getStackedLinks().size()); 8939 assertRoutesRemoved(cellNetId, stackedDefault); 8940 8941 // The interface removed callback happens but has no effect after stop is called. 8942 clat.interfaceRemoved(CLAT_MOBILE_IFNAME); 8943 networkCallback.assertNoCallback(); 8944 verify(mMockNetd, times(1)).networkRemoveInterface(cellNetId, CLAT_MOBILE_IFNAME); 8945 verifyNoMoreInteractions(mMockNetd); 8946 verifyNoMoreInteractions(mMockDnsResolver); 8947 reset(mMockNetd); 8948 reset(mMockDnsResolver); 8949 when(mMockNetd.interfaceGetCfg(CLAT_MOBILE_IFNAME)) 8950 .thenReturn(getClatInterfaceConfigParcel(myIpv4)); 8951 8952 // Stopping prefix discovery causes netd to tell us that the NAT64 prefix is gone. 8953 mService.mResolverUnsolEventCallback.onNat64PrefixEvent(makeNat64PrefixEvent( 8954 cellNetId, PREFIX_OPERATION_REMOVED, kOtherNat64PrefixString, 96)); 8955 networkCallback.expectLinkPropertiesThat(mCellNetworkAgent, 8956 (lp) -> lp.getNat64Prefix() == null); 8957 8958 // Remove IPv4 address and expect prefix discovery and clatd to be started again. 8959 cellLp.removeLinkAddress(myIpv4); 8960 cellLp.removeRoute(new RouteInfo(myIpv4, null, MOBILE_IFNAME)); 8961 cellLp.removeDnsServer(InetAddress.getByName("8.8.8.8")); 8962 mCellNetworkAgent.sendLinkProperties(cellLp); 8963 networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent); 8964 assertRoutesRemoved(cellNetId, ipv4Subnet); // Directly-connected routes auto-added. 8965 verify(mMockDnsResolver, times(1)).startPrefix64Discovery(cellNetId); 8966 mService.mResolverUnsolEventCallback.onNat64PrefixEvent(makeNat64PrefixEvent( 8967 cellNetId, PREFIX_OPERATION_ADDED, kNat64PrefixString, 96)); 8968 networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent); 8969 verify(mMockNetd, times(1)).clatdStart(MOBILE_IFNAME, kNat64Prefix.toString()); 8970 8971 // Clat iface comes up. Expect stacked link to be added. 8972 clat.interfaceLinkStateChanged(CLAT_MOBILE_IFNAME, true); 8973 networkCallback.expectLinkPropertiesThat(mCellNetworkAgent, 8974 (lp) -> lp.getStackedLinks().size() == 1 && lp.getNat64Prefix() != null); 8975 assertRoutesAdded(cellNetId, stackedDefault); 8976 verify(mMockNetd, times(1)).networkAddInterface(cellNetId, CLAT_MOBILE_IFNAME); 8977 8978 // NAT64 prefix is removed. Expect that clat is stopped. 8979 mService.mResolverUnsolEventCallback.onNat64PrefixEvent(makeNat64PrefixEvent( 8980 cellNetId, PREFIX_OPERATION_REMOVED, kNat64PrefixString, 96)); 8981 networkCallback.expectLinkPropertiesThat(mCellNetworkAgent, 8982 (lp) -> lp.getStackedLinks().size() == 0 && lp.getNat64Prefix() == null); 8983 assertRoutesRemoved(cellNetId, ipv4Subnet, stackedDefault); 8984 8985 // Stop has no effect because clat is already stopped. 8986 verify(mMockNetd, times(1)).clatdStop(MOBILE_IFNAME); 8987 networkCallback.expectLinkPropertiesThat(mCellNetworkAgent, 8988 (lp) -> lp.getStackedLinks().size() == 0); 8989 verify(mMockNetd, times(1)).networkRemoveInterface(cellNetId, CLAT_MOBILE_IFNAME); 8990 verify(mMockNetd, times(1)).interfaceGetCfg(CLAT_MOBILE_IFNAME); 8991 // Clean up. 8992 mCellNetworkAgent.disconnect(); 8993 networkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 8994 networkCallback.assertNoCallback(); 8995 verify(mMockNetd, times(1)).idletimerRemoveInterface(eq(MOBILE_IFNAME), anyInt(), 8996 eq(Integer.toString(TRANSPORT_CELLULAR))); 8997 verify(mMockNetd).networkDestroy(cellNetId); 8998 verifyNoMoreInteractions(mMockNetd); 8999 reset(mMockNetd); 9000 9001 // Test disconnecting a network that is running 464xlat. 9002 9003 // Connect a network with a NAT64 prefix. 9004 when(mMockNetd.interfaceGetCfg(CLAT_MOBILE_IFNAME)) 9005 .thenReturn(getClatInterfaceConfigParcel(myIpv4)); 9006 cellLp.setNat64Prefix(kNat64Prefix); 9007 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp); 9008 mCellNetworkAgent.connect(false /* validated */); 9009 networkCallback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent); 9010 cellNetId = mCellNetworkAgent.getNetwork().netId; 9011 verify(mMockNetd, times(1)).networkCreate(nativeNetworkConfigPhysical(cellNetId, 9012 INetd.PERMISSION_NONE)); 9013 assertRoutesAdded(cellNetId, ipv6Subnet, ipv6Default); 9014 9015 // Clatd is started and clat iface comes up. Expect stacked link to be added. 9016 verify(mMockNetd).clatdStart(MOBILE_IFNAME, kNat64Prefix.toString()); 9017 clat = getNat464Xlat(mCellNetworkAgent); 9018 clat.interfaceLinkStateChanged(CLAT_MOBILE_IFNAME, true /* up */); 9019 networkCallback.expectLinkPropertiesThat(mCellNetworkAgent, 9020 (lp) -> lp.getStackedLinks().size() == 1 9021 && lp.getNat64Prefix().equals(kNat64Prefix)); 9022 verify(mMockNetd).networkAddInterface(cellNetId, CLAT_MOBILE_IFNAME); 9023 // assertRoutesAdded sees all calls since last mMockNetd reset, so expect IPv6 routes again. 9024 assertRoutesAdded(cellNetId, ipv6Subnet, ipv6Default, stackedDefault); 9025 reset(mMockNetd); 9026 9027 // Disconnect the network. clat is stopped and the network is destroyed. 9028 mCellNetworkAgent.disconnect(); 9029 networkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 9030 networkCallback.assertNoCallback(); 9031 verify(mMockNetd).clatdStop(MOBILE_IFNAME); 9032 verify(mMockNetd).idletimerRemoveInterface(eq(MOBILE_IFNAME), anyInt(), 9033 eq(Integer.toString(TRANSPORT_CELLULAR))); 9034 verify(mMockNetd).networkDestroy(cellNetId); 9035 verifyNoMoreInteractions(mMockNetd); 9036 9037 mCm.unregisterNetworkCallback(networkCallback); 9038 } 9039 9040 private void expectNat64PrefixChange(TestableNetworkCallback callback, 9041 TestNetworkAgentWrapper agent, IpPrefix prefix) { 9042 callback.expectLinkPropertiesThat(agent, x -> Objects.equals(x.getNat64Prefix(), prefix)); 9043 } 9044 9045 @Test 9046 public void testNat64PrefixMultipleSources() throws Exception { 9047 final String iface = "wlan0"; 9048 final String pref64FromRaStr = "64:ff9b::"; 9049 final String pref64FromDnsStr = "2001:db8:64::"; 9050 final IpPrefix pref64FromRa = new IpPrefix(InetAddress.getByName(pref64FromRaStr), 96); 9051 final IpPrefix pref64FromDns = new IpPrefix(InetAddress.getByName(pref64FromDnsStr), 96); 9052 final IpPrefix newPref64FromRa = new IpPrefix("2001:db8:64:64:64:64::/96"); 9053 9054 final NetworkRequest request = new NetworkRequest.Builder() 9055 .addCapability(NET_CAPABILITY_INTERNET) 9056 .build(); 9057 final TestNetworkCallback callback = new TestNetworkCallback(); 9058 mCm.registerNetworkCallback(request, callback); 9059 9060 final LinkProperties baseLp = new LinkProperties(); 9061 baseLp.setInterfaceName(iface); 9062 baseLp.addLinkAddress(new LinkAddress("2001:db8:1::1/64")); 9063 baseLp.addDnsServer(InetAddress.getByName("2001:4860:4860::6464")); 9064 9065 reset(mMockNetd, mMockDnsResolver); 9066 InOrder inOrder = inOrder(mMockNetd, mMockDnsResolver); 9067 9068 // If a network already has a NAT64 prefix on connect, clatd is started immediately and 9069 // prefix discovery is never started. 9070 LinkProperties lp = new LinkProperties(baseLp); 9071 lp.setNat64Prefix(pref64FromRa); 9072 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, lp); 9073 mWiFiNetworkAgent.connect(false); 9074 final Network network = mWiFiNetworkAgent.getNetwork(); 9075 int netId = network.getNetId(); 9076 callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 9077 inOrder.verify(mMockNetd).clatdStart(iface, pref64FromRa.toString()); 9078 inOrder.verify(mMockDnsResolver).setPrefix64(netId, pref64FromRa.toString()); 9079 inOrder.verify(mMockDnsResolver, never()).startPrefix64Discovery(netId); 9080 callback.assertNoCallback(); 9081 assertEquals(pref64FromRa, mCm.getLinkProperties(network).getNat64Prefix()); 9082 9083 // If the RA prefix is withdrawn, clatd is stopped and prefix discovery is started. 9084 lp.setNat64Prefix(null); 9085 mWiFiNetworkAgent.sendLinkProperties(lp); 9086 expectNat64PrefixChange(callback, mWiFiNetworkAgent, null); 9087 inOrder.verify(mMockNetd).clatdStop(iface); 9088 inOrder.verify(mMockDnsResolver).setPrefix64(netId, ""); 9089 inOrder.verify(mMockDnsResolver).startPrefix64Discovery(netId); 9090 9091 // If the RA prefix appears while DNS discovery is in progress, discovery is stopped and 9092 // clatd is started with the prefix from the RA. 9093 lp.setNat64Prefix(pref64FromRa); 9094 mWiFiNetworkAgent.sendLinkProperties(lp); 9095 expectNat64PrefixChange(callback, mWiFiNetworkAgent, pref64FromRa); 9096 inOrder.verify(mMockNetd).clatdStart(iface, pref64FromRa.toString()); 9097 inOrder.verify(mMockDnsResolver).stopPrefix64Discovery(netId); 9098 inOrder.verify(mMockDnsResolver).setPrefix64(netId, pref64FromRa.toString()); 9099 9100 // Withdraw the RA prefix so we can test the case where an RA prefix appears after DNS 9101 // discovery has succeeded. 9102 lp.setNat64Prefix(null); 9103 mWiFiNetworkAgent.sendLinkProperties(lp); 9104 expectNat64PrefixChange(callback, mWiFiNetworkAgent, null); 9105 inOrder.verify(mMockNetd).clatdStop(iface); 9106 inOrder.verify(mMockDnsResolver).setPrefix64(netId, ""); 9107 inOrder.verify(mMockDnsResolver).startPrefix64Discovery(netId); 9108 9109 mService.mResolverUnsolEventCallback.onNat64PrefixEvent( 9110 makeNat64PrefixEvent(netId, PREFIX_OPERATION_ADDED, pref64FromDnsStr, 96)); 9111 expectNat64PrefixChange(callback, mWiFiNetworkAgent, pref64FromDns); 9112 inOrder.verify(mMockNetd).clatdStart(iface, pref64FromDns.toString()); 9113 9114 // If an RA advertises the same prefix that was discovered by DNS, nothing happens: prefix 9115 // discovery is not stopped, and there are no callbacks. 9116 lp.setNat64Prefix(pref64FromDns); 9117 mWiFiNetworkAgent.sendLinkProperties(lp); 9118 callback.assertNoCallback(); 9119 inOrder.verify(mMockNetd, never()).clatdStop(iface); 9120 inOrder.verify(mMockNetd, never()).clatdStart(eq(iface), anyString()); 9121 inOrder.verify(mMockDnsResolver, never()).stopPrefix64Discovery(netId); 9122 inOrder.verify(mMockDnsResolver, never()).startPrefix64Discovery(netId); 9123 inOrder.verify(mMockDnsResolver, never()).setPrefix64(eq(netId), anyString()); 9124 9125 // If the RA is later withdrawn, nothing happens again. 9126 lp.setNat64Prefix(null); 9127 mWiFiNetworkAgent.sendLinkProperties(lp); 9128 callback.assertNoCallback(); 9129 inOrder.verify(mMockNetd, never()).clatdStop(iface); 9130 inOrder.verify(mMockNetd, never()).clatdStart(eq(iface), anyString()); 9131 inOrder.verify(mMockDnsResolver, never()).stopPrefix64Discovery(netId); 9132 inOrder.verify(mMockDnsResolver, never()).startPrefix64Discovery(netId); 9133 inOrder.verify(mMockDnsResolver, never()).setPrefix64(eq(netId), anyString()); 9134 9135 // If the RA prefix changes, clatd is restarted and prefix discovery is stopped. 9136 lp.setNat64Prefix(pref64FromRa); 9137 mWiFiNetworkAgent.sendLinkProperties(lp); 9138 expectNat64PrefixChange(callback, mWiFiNetworkAgent, pref64FromRa); 9139 inOrder.verify(mMockNetd).clatdStop(iface); 9140 inOrder.verify(mMockDnsResolver).stopPrefix64Discovery(netId); 9141 9142 // Stopping prefix discovery results in a prefix removed notification. 9143 mService.mResolverUnsolEventCallback.onNat64PrefixEvent( 9144 makeNat64PrefixEvent(netId, PREFIX_OPERATION_REMOVED, pref64FromDnsStr, 96)); 9145 9146 inOrder.verify(mMockNetd).clatdStart(iface, pref64FromRa.toString()); 9147 inOrder.verify(mMockDnsResolver).setPrefix64(netId, pref64FromRa.toString()); 9148 inOrder.verify(mMockDnsResolver, never()).startPrefix64Discovery(netId); 9149 9150 // If the RA prefix changes, clatd is restarted and prefix discovery is not started. 9151 lp.setNat64Prefix(newPref64FromRa); 9152 mWiFiNetworkAgent.sendLinkProperties(lp); 9153 expectNat64PrefixChange(callback, mWiFiNetworkAgent, newPref64FromRa); 9154 inOrder.verify(mMockNetd).clatdStop(iface); 9155 inOrder.verify(mMockDnsResolver).setPrefix64(netId, ""); 9156 inOrder.verify(mMockNetd).clatdStart(iface, newPref64FromRa.toString()); 9157 inOrder.verify(mMockDnsResolver).setPrefix64(netId, newPref64FromRa.toString()); 9158 inOrder.verify(mMockDnsResolver, never()).stopPrefix64Discovery(netId); 9159 inOrder.verify(mMockDnsResolver, never()).startPrefix64Discovery(netId); 9160 9161 // If the RA prefix changes to the same value, nothing happens. 9162 lp.setNat64Prefix(newPref64FromRa); 9163 mWiFiNetworkAgent.sendLinkProperties(lp); 9164 callback.assertNoCallback(); 9165 assertEquals(newPref64FromRa, mCm.getLinkProperties(network).getNat64Prefix()); 9166 inOrder.verify(mMockNetd, never()).clatdStop(iface); 9167 inOrder.verify(mMockNetd, never()).clatdStart(eq(iface), anyString()); 9168 inOrder.verify(mMockDnsResolver, never()).stopPrefix64Discovery(netId); 9169 inOrder.verify(mMockDnsResolver, never()).startPrefix64Discovery(netId); 9170 inOrder.verify(mMockDnsResolver, never()).setPrefix64(eq(netId), anyString()); 9171 9172 // The transition between no prefix and DNS prefix is tested in testStackedLinkProperties. 9173 9174 // If the same prefix is learned first by DNS and then by RA, and clat is later stopped, 9175 // (e.g., because the network disconnects) setPrefix64(netid, "") is never called. 9176 lp.setNat64Prefix(null); 9177 mWiFiNetworkAgent.sendLinkProperties(lp); 9178 expectNat64PrefixChange(callback, mWiFiNetworkAgent, null); 9179 inOrder.verify(mMockNetd).clatdStop(iface); 9180 inOrder.verify(mMockDnsResolver).setPrefix64(netId, ""); 9181 inOrder.verify(mMockDnsResolver).startPrefix64Discovery(netId); 9182 mService.mResolverUnsolEventCallback.onNat64PrefixEvent( 9183 makeNat64PrefixEvent(netId, PREFIX_OPERATION_ADDED, pref64FromDnsStr, 96)); 9184 expectNat64PrefixChange(callback, mWiFiNetworkAgent, pref64FromDns); 9185 inOrder.verify(mMockNetd).clatdStart(iface, pref64FromDns.toString()); 9186 inOrder.verify(mMockDnsResolver, never()).setPrefix64(eq(netId), any()); 9187 9188 lp.setNat64Prefix(pref64FromDns); 9189 mWiFiNetworkAgent.sendLinkProperties(lp); 9190 callback.assertNoCallback(); 9191 inOrder.verify(mMockNetd, never()).clatdStop(iface); 9192 inOrder.verify(mMockNetd, never()).clatdStart(eq(iface), anyString()); 9193 inOrder.verify(mMockDnsResolver, never()).stopPrefix64Discovery(netId); 9194 inOrder.verify(mMockDnsResolver, never()).startPrefix64Discovery(netId); 9195 inOrder.verify(mMockDnsResolver, never()).setPrefix64(eq(netId), anyString()); 9196 9197 // When tearing down a network, clat state is only updated after CALLBACK_LOST is fired, but 9198 // before CONNECTIVITY_ACTION is sent. Wait for CONNECTIVITY_ACTION before verifying that 9199 // clat has been stopped, or the test will be flaky. 9200 ExpectedBroadcast b = expectConnectivityAction(TYPE_WIFI, DetailedState.DISCONNECTED); 9201 mWiFiNetworkAgent.disconnect(); 9202 callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 9203 b.expectBroadcast(); 9204 9205 inOrder.verify(mMockNetd).clatdStop(iface); 9206 inOrder.verify(mMockDnsResolver).stopPrefix64Discovery(netId); 9207 inOrder.verify(mMockDnsResolver, never()).setPrefix64(eq(netId), anyString()); 9208 9209 mCm.unregisterNetworkCallback(callback); 9210 } 9211 9212 @Test 9213 public void testWith464XlatDisable() throws Exception { 9214 doReturn(false).when(mDeps).getCellular464XlatEnabled(); 9215 9216 final TestNetworkCallback callback = new TestNetworkCallback(); 9217 final TestNetworkCallback defaultCallback = new TestNetworkCallback(); 9218 final NetworkRequest networkRequest = new NetworkRequest.Builder() 9219 .addCapability(NET_CAPABILITY_INTERNET) 9220 .build(); 9221 mCm.registerNetworkCallback(networkRequest, callback); 9222 mCm.registerDefaultNetworkCallback(defaultCallback); 9223 9224 // Bring up validated cell. 9225 final LinkProperties cellLp = new LinkProperties(); 9226 cellLp.setInterfaceName(MOBILE_IFNAME); 9227 cellLp.addLinkAddress(new LinkAddress("2001:db8:1::1/64")); 9228 cellLp.addRoute(new RouteInfo(new IpPrefix("::/0"), null, MOBILE_IFNAME)); 9229 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 9230 9231 mCellNetworkAgent.sendLinkProperties(cellLp); 9232 mCellNetworkAgent.connect(true); 9233 callback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 9234 defaultCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 9235 final int cellNetId = mCellNetworkAgent.getNetwork().netId; 9236 waitForIdle(); 9237 9238 verify(mMockDnsResolver, never()).startPrefix64Discovery(cellNetId); 9239 Nat464Xlat clat = getNat464Xlat(mCellNetworkAgent); 9240 assertTrue("Nat464Xlat was not IDLE", !clat.isStarted()); 9241 9242 // This cannot happen because prefix discovery cannot succeed if it is never started. 9243 mService.mResolverUnsolEventCallback.onNat64PrefixEvent( 9244 makeNat64PrefixEvent(cellNetId, PREFIX_OPERATION_ADDED, "64:ff9b::", 96)); 9245 9246 // ... but still, check that even if it did, clatd would not be started. 9247 verify(mMockNetd, never()).clatdStart(anyString(), anyString()); 9248 assertTrue("Nat464Xlat was not IDLE", !clat.isStarted()); 9249 } 9250 9251 @Test 9252 public void testDataActivityTracking() throws Exception { 9253 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 9254 final NetworkRequest networkRequest = new NetworkRequest.Builder() 9255 .addCapability(NET_CAPABILITY_INTERNET) 9256 .build(); 9257 mCm.registerNetworkCallback(networkRequest, networkCallback); 9258 9259 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 9260 final LinkProperties cellLp = new LinkProperties(); 9261 cellLp.setInterfaceName(MOBILE_IFNAME); 9262 mCellNetworkAgent.sendLinkProperties(cellLp); 9263 mCellNetworkAgent.connect(true); 9264 networkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 9265 verify(mMockNetd, times(1)).idletimerAddInterface(eq(MOBILE_IFNAME), anyInt(), 9266 eq(Integer.toString(TRANSPORT_CELLULAR))); 9267 9268 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 9269 final LinkProperties wifiLp = new LinkProperties(); 9270 wifiLp.setInterfaceName(WIFI_IFNAME); 9271 mWiFiNetworkAgent.sendLinkProperties(wifiLp); 9272 9273 // Network switch 9274 mWiFiNetworkAgent.connect(true); 9275 networkCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 9276 networkCallback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent); 9277 networkCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent); 9278 verify(mMockNetd, times(1)).idletimerAddInterface(eq(WIFI_IFNAME), anyInt(), 9279 eq(Integer.toString(TRANSPORT_WIFI))); 9280 verify(mMockNetd, times(1)).idletimerRemoveInterface(eq(MOBILE_IFNAME), anyInt(), 9281 eq(Integer.toString(TRANSPORT_CELLULAR))); 9282 9283 // Disconnect wifi and switch back to cell 9284 reset(mMockNetd); 9285 mWiFiNetworkAgent.disconnect(); 9286 networkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 9287 assertNoCallbacks(networkCallback); 9288 verify(mMockNetd, times(1)).idletimerRemoveInterface(eq(WIFI_IFNAME), anyInt(), 9289 eq(Integer.toString(TRANSPORT_WIFI))); 9290 verify(mMockNetd, times(1)).idletimerAddInterface(eq(MOBILE_IFNAME), anyInt(), 9291 eq(Integer.toString(TRANSPORT_CELLULAR))); 9292 9293 // reconnect wifi 9294 reset(mMockNetd); 9295 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 9296 wifiLp.setInterfaceName(WIFI_IFNAME); 9297 mWiFiNetworkAgent.sendLinkProperties(wifiLp); 9298 mWiFiNetworkAgent.connect(true); 9299 networkCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 9300 networkCallback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent); 9301 networkCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent); 9302 verify(mMockNetd, times(1)).idletimerAddInterface(eq(WIFI_IFNAME), anyInt(), 9303 eq(Integer.toString(TRANSPORT_WIFI))); 9304 verify(mMockNetd, times(1)).idletimerRemoveInterface(eq(MOBILE_IFNAME), anyInt(), 9305 eq(Integer.toString(TRANSPORT_CELLULAR))); 9306 9307 // Disconnect cell 9308 reset(mMockNetd); 9309 mCellNetworkAgent.disconnect(); 9310 networkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 9311 // LOST callback is triggered earlier than removing idle timer. Broadcast should also be 9312 // sent as network being switched. Ensure rule removal for cell will not be triggered 9313 // unexpectedly before network being removed. 9314 waitForIdle(); 9315 verify(mMockNetd, times(0)).idletimerRemoveInterface(eq(MOBILE_IFNAME), anyInt(), 9316 eq(Integer.toString(TRANSPORT_CELLULAR))); 9317 verify(mMockNetd, times(1)).networkDestroy(eq(mCellNetworkAgent.getNetwork().netId)); 9318 verify(mMockDnsResolver, times(1)) 9319 .destroyNetworkCache(eq(mCellNetworkAgent.getNetwork().netId)); 9320 9321 // Disconnect wifi 9322 ExpectedBroadcast b = expectConnectivityAction(TYPE_WIFI, DetailedState.DISCONNECTED); 9323 mWiFiNetworkAgent.disconnect(); 9324 b.expectBroadcast(); 9325 verify(mMockNetd, times(1)).idletimerRemoveInterface(eq(WIFI_IFNAME), anyInt(), 9326 eq(Integer.toString(TRANSPORT_WIFI))); 9327 9328 // Clean up 9329 mCm.unregisterNetworkCallback(networkCallback); 9330 } 9331 9332 private void verifyTcpBufferSizeChange(String tcpBufferSizes) throws Exception { 9333 String[] values = tcpBufferSizes.split(","); 9334 String rmemValues = String.join(" ", values[0], values[1], values[2]); 9335 String wmemValues = String.join(" ", values[3], values[4], values[5]); 9336 verify(mMockNetd, atLeastOnce()).setTcpRWmemorySize(rmemValues, wmemValues); 9337 reset(mMockNetd); 9338 } 9339 9340 @Test 9341 public void testTcpBufferReset() throws Exception { 9342 final String testTcpBufferSizes = "1,2,3,4,5,6"; 9343 final NetworkRequest networkRequest = new NetworkRequest.Builder() 9344 .addTransportType(TRANSPORT_CELLULAR) 9345 .addCapability(NET_CAPABILITY_INTERNET) 9346 .build(); 9347 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 9348 mCm.registerNetworkCallback(networkRequest, networkCallback); 9349 9350 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 9351 reset(mMockNetd); 9352 // Switching default network updates TCP buffer sizes. 9353 mCellNetworkAgent.connect(false); 9354 networkCallback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent); 9355 verifyTcpBufferSizeChange(ConnectivityService.DEFAULT_TCP_BUFFER_SIZES); 9356 // Change link Properties should have updated tcp buffer size. 9357 LinkProperties lp = new LinkProperties(); 9358 lp.setTcpBufferSizes(testTcpBufferSizes); 9359 mCellNetworkAgent.sendLinkProperties(lp); 9360 networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent); 9361 verifyTcpBufferSizeChange(testTcpBufferSizes); 9362 // Clean up. 9363 mCellNetworkAgent.disconnect(); 9364 networkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 9365 networkCallback.assertNoCallback(); 9366 mCm.unregisterNetworkCallback(networkCallback); 9367 } 9368 9369 @Test 9370 public void testGetGlobalProxyForNetwork() throws Exception { 9371 final ProxyInfo testProxyInfo = ProxyInfo.buildDirectProxy("test", 8888); 9372 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 9373 final Network wifiNetwork = mWiFiNetworkAgent.getNetwork(); 9374 when(mService.mProxyTracker.getGlobalProxy()).thenReturn(testProxyInfo); 9375 assertEquals(testProxyInfo, mService.getProxyForNetwork(wifiNetwork)); 9376 } 9377 9378 @Test 9379 public void testGetProxyForActiveNetwork() throws Exception { 9380 final ProxyInfo testProxyInfo = ProxyInfo.buildDirectProxy("test", 8888); 9381 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 9382 mWiFiNetworkAgent.connect(true); 9383 waitForIdle(); 9384 assertNull(mService.getProxyForNetwork(null)); 9385 9386 final LinkProperties testLinkProperties = new LinkProperties(); 9387 testLinkProperties.setHttpProxy(testProxyInfo); 9388 9389 mWiFiNetworkAgent.sendLinkProperties(testLinkProperties); 9390 waitForIdle(); 9391 9392 assertEquals(testProxyInfo, mService.getProxyForNetwork(null)); 9393 } 9394 9395 @Test 9396 public void testGetProxyForVPN() throws Exception { 9397 final ProxyInfo testProxyInfo = ProxyInfo.buildDirectProxy("test", 8888); 9398 9399 // Set up a WiFi network with no proxy 9400 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 9401 mWiFiNetworkAgent.connect(true); 9402 waitForIdle(); 9403 assertNull(mService.getProxyForNetwork(null)); 9404 9405 // Connect a VPN network with a proxy. 9406 LinkProperties testLinkProperties = new LinkProperties(); 9407 testLinkProperties.setHttpProxy(testProxyInfo); 9408 mMockVpn.establishForMyUid(testLinkProperties); 9409 assertUidRangesUpdatedForMyUid(true); 9410 9411 // Test that the VPN network returns a proxy, and the WiFi does not. 9412 assertEquals(testProxyInfo, mService.getProxyForNetwork(mMockVpn.getNetwork())); 9413 assertEquals(testProxyInfo, mService.getProxyForNetwork(null)); 9414 assertNull(mService.getProxyForNetwork(mWiFiNetworkAgent.getNetwork())); 9415 9416 // Test that the VPN network returns no proxy when it is set to null. 9417 testLinkProperties.setHttpProxy(null); 9418 mMockVpn.sendLinkProperties(testLinkProperties); 9419 waitForIdle(); 9420 assertNull(mService.getProxyForNetwork(mMockVpn.getNetwork())); 9421 assertNull(mService.getProxyForNetwork(null)); 9422 9423 // Set WiFi proxy and check that the vpn proxy is still null. 9424 testLinkProperties.setHttpProxy(testProxyInfo); 9425 mWiFiNetworkAgent.sendLinkProperties(testLinkProperties); 9426 waitForIdle(); 9427 assertNull(mService.getProxyForNetwork(null)); 9428 9429 // Disconnect from VPN and check that the active network, which is now the WiFi, has the 9430 // correct proxy setting. 9431 mMockVpn.disconnect(); 9432 waitForIdle(); 9433 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 9434 assertEquals(testProxyInfo, mService.getProxyForNetwork(mWiFiNetworkAgent.getNetwork())); 9435 assertEquals(testProxyInfo, mService.getProxyForNetwork(null)); 9436 } 9437 9438 @Test 9439 public void testFullyRoutedVpnResultsInInterfaceFilteringRules() throws Exception { 9440 LinkProperties lp = new LinkProperties(); 9441 lp.setInterfaceName("tun0"); 9442 lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), null)); 9443 lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), RTN_UNREACHABLE)); 9444 // The uid range needs to cover the test app so the network is visible to it. 9445 final Set<UidRange> vpnRange = Collections.singleton(PRIMARY_UIDRANGE); 9446 mMockVpn.establish(lp, VPN_UID, vpnRange); 9447 assertVpnUidRangesUpdated(true, vpnRange, VPN_UID); 9448 9449 // A connected VPN should have interface rules set up. There are two expected invocations, 9450 // one during the VPN initial connection, one during the VPN LinkProperties update. 9451 ArgumentCaptor<int[]> uidCaptor = ArgumentCaptor.forClass(int[].class); 9452 verify(mMockNetd, times(2)).firewallAddUidInterfaceRules(eq("tun0"), uidCaptor.capture()); 9453 assertContainsExactly(uidCaptor.getAllValues().get(0), APP1_UID, APP2_UID); 9454 assertContainsExactly(uidCaptor.getAllValues().get(1), APP1_UID, APP2_UID); 9455 assertTrue(mService.mPermissionMonitor.getVpnUidRanges("tun0").equals(vpnRange)); 9456 9457 mMockVpn.disconnect(); 9458 waitForIdle(); 9459 9460 // Disconnected VPN should have interface rules removed 9461 verify(mMockNetd).firewallRemoveUidInterfaceRules(uidCaptor.capture()); 9462 assertContainsExactly(uidCaptor.getValue(), APP1_UID, APP2_UID); 9463 assertNull(mService.mPermissionMonitor.getVpnUidRanges("tun0")); 9464 } 9465 9466 @Test 9467 public void testLegacyVpnDoesNotResultInInterfaceFilteringRule() throws Exception { 9468 LinkProperties lp = new LinkProperties(); 9469 lp.setInterfaceName("tun0"); 9470 lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), null)); 9471 lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), null)); 9472 // The uid range needs to cover the test app so the network is visible to it. 9473 final Set<UidRange> vpnRange = Collections.singleton(PRIMARY_UIDRANGE); 9474 mMockVpn.establish(lp, Process.SYSTEM_UID, vpnRange); 9475 assertVpnUidRangesUpdated(true, vpnRange, Process.SYSTEM_UID); 9476 9477 // Legacy VPN should not have interface rules set up 9478 verify(mMockNetd, never()).firewallAddUidInterfaceRules(any(), any()); 9479 } 9480 9481 @Test 9482 public void testLocalIpv4OnlyVpnDoesNotResultInInterfaceFilteringRule() 9483 throws Exception { 9484 LinkProperties lp = new LinkProperties(); 9485 lp.setInterfaceName("tun0"); 9486 lp.addRoute(new RouteInfo(new IpPrefix("192.0.2.0/24"), null, "tun0")); 9487 lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), RTN_UNREACHABLE)); 9488 // The uid range needs to cover the test app so the network is visible to it. 9489 final Set<UidRange> vpnRange = Collections.singleton(PRIMARY_UIDRANGE); 9490 mMockVpn.establish(lp, Process.SYSTEM_UID, vpnRange); 9491 assertVpnUidRangesUpdated(true, vpnRange, Process.SYSTEM_UID); 9492 9493 // IPv6 unreachable route should not be misinterpreted as a default route 9494 verify(mMockNetd, never()).firewallAddUidInterfaceRules(any(), any()); 9495 } 9496 9497 @Test 9498 public void testVpnHandoverChangesInterfaceFilteringRule() throws Exception { 9499 LinkProperties lp = new LinkProperties(); 9500 lp.setInterfaceName("tun0"); 9501 lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), null)); 9502 lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), null)); 9503 // The uid range needs to cover the test app so the network is visible to it. 9504 final Set<UidRange> vpnRange = Collections.singleton(PRIMARY_UIDRANGE); 9505 mMockVpn.establish(lp, VPN_UID, vpnRange); 9506 assertVpnUidRangesUpdated(true, vpnRange, VPN_UID); 9507 9508 // Connected VPN should have interface rules set up. There are two expected invocations, 9509 // one during VPN uid update, one during VPN LinkProperties update 9510 ArgumentCaptor<int[]> uidCaptor = ArgumentCaptor.forClass(int[].class); 9511 verify(mMockNetd, times(2)).firewallAddUidInterfaceRules(eq("tun0"), uidCaptor.capture()); 9512 assertContainsExactly(uidCaptor.getAllValues().get(0), APP1_UID, APP2_UID); 9513 assertContainsExactly(uidCaptor.getAllValues().get(1), APP1_UID, APP2_UID); 9514 9515 reset(mMockNetd); 9516 InOrder inOrder = inOrder(mMockNetd); 9517 lp.setInterfaceName("tun1"); 9518 mMockVpn.sendLinkProperties(lp); 9519 waitForIdle(); 9520 // VPN handover (switch to a new interface) should result in rules being updated (old rules 9521 // removed first, then new rules added) 9522 inOrder.verify(mMockNetd).firewallRemoveUidInterfaceRules(uidCaptor.capture()); 9523 assertContainsExactly(uidCaptor.getValue(), APP1_UID, APP2_UID); 9524 inOrder.verify(mMockNetd).firewallAddUidInterfaceRules(eq("tun1"), uidCaptor.capture()); 9525 assertContainsExactly(uidCaptor.getValue(), APP1_UID, APP2_UID); 9526 9527 reset(mMockNetd); 9528 lp = new LinkProperties(); 9529 lp.setInterfaceName("tun1"); 9530 lp.addRoute(new RouteInfo(new IpPrefix("192.0.2.0/24"), null, "tun1")); 9531 mMockVpn.sendLinkProperties(lp); 9532 waitForIdle(); 9533 // VPN not routing everything should no longer have interface filtering rules 9534 verify(mMockNetd).firewallRemoveUidInterfaceRules(uidCaptor.capture()); 9535 assertContainsExactly(uidCaptor.getValue(), APP1_UID, APP2_UID); 9536 9537 reset(mMockNetd); 9538 lp = new LinkProperties(); 9539 lp.setInterfaceName("tun1"); 9540 lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), RTN_UNREACHABLE)); 9541 lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), null)); 9542 mMockVpn.sendLinkProperties(lp); 9543 waitForIdle(); 9544 // Back to routing all IPv6 traffic should have filtering rules 9545 verify(mMockNetd).firewallAddUidInterfaceRules(eq("tun1"), uidCaptor.capture()); 9546 assertContainsExactly(uidCaptor.getValue(), APP1_UID, APP2_UID); 9547 } 9548 9549 @Test 9550 public void testStartVpnProfileFromDiffPackage() throws Exception { 9551 final String notMyVpnPkg = "com.not.my.vpn"; 9552 assertThrows( 9553 SecurityException.class, () -> mVpnManagerService.startVpnProfile(notMyVpnPkg)); 9554 } 9555 9556 @Test 9557 public void testStopVpnProfileFromDiffPackage() throws Exception { 9558 final String notMyVpnPkg = "com.not.my.vpn"; 9559 assertThrows(SecurityException.class, () -> mVpnManagerService.stopVpnProfile(notMyVpnPkg)); 9560 } 9561 9562 @Test 9563 public void testUidUpdateChangesInterfaceFilteringRule() throws Exception { 9564 LinkProperties lp = new LinkProperties(); 9565 lp.setInterfaceName("tun0"); 9566 lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), RTN_UNREACHABLE)); 9567 lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), null)); 9568 // The uid range needs to cover the test app so the network is visible to it. 9569 final UidRange vpnRange = PRIMARY_UIDRANGE; 9570 final Set<UidRange> vpnRanges = Collections.singleton(vpnRange); 9571 mMockVpn.establish(lp, VPN_UID, vpnRanges); 9572 assertVpnUidRangesUpdated(true, vpnRanges, VPN_UID); 9573 9574 reset(mMockNetd); 9575 InOrder inOrder = inOrder(mMockNetd); 9576 9577 // Update to new range which is old range minus APP1, i.e. only APP2 9578 final Set<UidRange> newRanges = new HashSet<>(Arrays.asList( 9579 new UidRange(vpnRange.start, APP1_UID - 1), 9580 new UidRange(APP1_UID + 1, vpnRange.stop))); 9581 mMockVpn.setUids(newRanges); 9582 waitForIdle(); 9583 9584 ArgumentCaptor<int[]> uidCaptor = ArgumentCaptor.forClass(int[].class); 9585 // Verify old rules are removed before new rules are added 9586 inOrder.verify(mMockNetd).firewallRemoveUidInterfaceRules(uidCaptor.capture()); 9587 assertContainsExactly(uidCaptor.getValue(), APP1_UID, APP2_UID); 9588 inOrder.verify(mMockNetd).firewallAddUidInterfaceRules(eq("tun0"), uidCaptor.capture()); 9589 assertContainsExactly(uidCaptor.getValue(), APP2_UID); 9590 } 9591 9592 @Test 9593 public void testLinkPropertiesWithWakeOnLanForActiveNetwork() throws Exception { 9594 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 9595 9596 LinkProperties wifiLp = new LinkProperties(); 9597 wifiLp.setInterfaceName(WIFI_WOL_IFNAME); 9598 wifiLp.setWakeOnLanSupported(false); 9599 9600 // Default network switch should update ifaces. 9601 mWiFiNetworkAgent.connect(false); 9602 mWiFiNetworkAgent.sendLinkProperties(wifiLp); 9603 waitForIdle(); 9604 9605 // ConnectivityService should have changed the WakeOnLanSupported to true 9606 wifiLp.setWakeOnLanSupported(true); 9607 assertEquals(wifiLp, mService.getActiveLinkProperties()); 9608 } 9609 9610 @Test 9611 public void testLegacyExtraInfoSentToNetworkMonitor() throws Exception { 9612 class TestNetworkAgent extends NetworkAgent { 9613 TestNetworkAgent(Context context, Looper looper, NetworkAgentConfig config) { 9614 super(context, looper, "MockAgent", new NetworkCapabilities(), 9615 new LinkProperties(), 40 , config, null /* provider */); 9616 } 9617 } 9618 final NetworkAgent naNoExtraInfo = new TestNetworkAgent( 9619 mServiceContext, mCsHandlerThread.getLooper(), new NetworkAgentConfig()); 9620 naNoExtraInfo.register(); 9621 verify(mNetworkStack).makeNetworkMonitor(any(), isNull(String.class), any()); 9622 naNoExtraInfo.unregister(); 9623 9624 reset(mNetworkStack); 9625 final NetworkAgentConfig config = 9626 new NetworkAgentConfig.Builder().setLegacyExtraInfo("legacyinfo").build(); 9627 final NetworkAgent naExtraInfo = new TestNetworkAgent( 9628 mServiceContext, mCsHandlerThread.getLooper(), config); 9629 naExtraInfo.register(); 9630 verify(mNetworkStack).makeNetworkMonitor(any(), eq("legacyinfo"), any()); 9631 naExtraInfo.unregister(); 9632 } 9633 9634 // To avoid granting location permission bypass. 9635 private void denyAllLocationPrivilegedPermissions() { 9636 mServiceContext.setPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, 9637 PERMISSION_DENIED); 9638 mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_DENIED); 9639 mServiceContext.setPermission(NETWORK_STACK, PERMISSION_DENIED); 9640 mServiceContext.setPermission(Manifest.permission.NETWORK_SETUP_WIZARD, 9641 PERMISSION_DENIED); 9642 } 9643 9644 private void setupLocationPermissions( 9645 int targetSdk, boolean locationToggle, String op, String perm) throws Exception { 9646 denyAllLocationPrivilegedPermissions(); 9647 9648 final ApplicationInfo applicationInfo = new ApplicationInfo(); 9649 applicationInfo.targetSdkVersion = targetSdk; 9650 when(mPackageManager.getApplicationInfoAsUser(anyString(), anyInt(), any())) 9651 .thenReturn(applicationInfo); 9652 when(mPackageManager.getTargetSdkVersion(any())).thenReturn(targetSdk); 9653 9654 when(mLocationManager.isLocationEnabledForUser(any())).thenReturn(locationToggle); 9655 9656 if (op != null) { 9657 when(mAppOpsManager.noteOp(eq(op), eq(Process.myUid()), 9658 eq(mContext.getPackageName()), eq(getAttributionTag()), anyString())) 9659 .thenReturn(AppOpsManager.MODE_ALLOWED); 9660 } 9661 9662 if (perm != null) { 9663 mServiceContext.setPermission(perm, PERMISSION_GRANTED); 9664 } 9665 } 9666 9667 private int getOwnerUidNetCapsPermission(int ownerUid, int callerUid, 9668 boolean includeLocationSensitiveInfo) { 9669 final NetworkCapabilities netCap = new NetworkCapabilities().setOwnerUid(ownerUid); 9670 9671 return mService.createWithLocationInfoSanitizedIfNecessaryWhenParceled( 9672 netCap, includeLocationSensitiveInfo, Process.myUid(), callerUid, 9673 mContext.getPackageName(), getAttributionTag()) 9674 .getOwnerUid(); 9675 } 9676 9677 private void verifyTransportInfoCopyNetCapsPermission( 9678 int callerUid, boolean includeLocationSensitiveInfo, 9679 boolean shouldMakeCopyWithLocationSensitiveFieldsParcelable) { 9680 final TransportInfo transportInfo = mock(TransportInfo.class); 9681 when(transportInfo.getApplicableRedactions()).thenReturn(REDACT_FOR_ACCESS_FINE_LOCATION); 9682 final NetworkCapabilities netCap = 9683 new NetworkCapabilities().setTransportInfo(transportInfo); 9684 9685 mService.createWithLocationInfoSanitizedIfNecessaryWhenParceled( 9686 netCap, includeLocationSensitiveInfo, Process.myPid(), callerUid, 9687 mContext.getPackageName(), getAttributionTag()); 9688 if (shouldMakeCopyWithLocationSensitiveFieldsParcelable) { 9689 verify(transportInfo).makeCopy(REDACT_NONE); 9690 } else { 9691 verify(transportInfo).makeCopy(REDACT_FOR_ACCESS_FINE_LOCATION); 9692 } 9693 } 9694 9695 private void verifyOwnerUidAndTransportInfoNetCapsPermission( 9696 boolean shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag, 9697 boolean shouldInclLocationSensitiveOwnerUidWithIncludeFlag, 9698 boolean shouldInclLocationSensitiveTransportInfoWithoutIncludeFlag, 9699 boolean shouldInclLocationSensitiveTransportInfoWithIncludeFlag) { 9700 final int myUid = Process.myUid(); 9701 9702 final int expectedOwnerUidWithoutIncludeFlag = 9703 shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag 9704 ? myUid : INVALID_UID; 9705 assertEquals(expectedOwnerUidWithoutIncludeFlag, getOwnerUidNetCapsPermission( 9706 myUid, myUid, false /* includeLocationSensitiveInfo */)); 9707 9708 final int expectedOwnerUidWithIncludeFlag = 9709 shouldInclLocationSensitiveOwnerUidWithIncludeFlag ? myUid : INVALID_UID; 9710 assertEquals(expectedOwnerUidWithIncludeFlag, getOwnerUidNetCapsPermission( 9711 myUid, myUid, true /* includeLocationSensitiveInfo */)); 9712 9713 verifyTransportInfoCopyNetCapsPermission(myUid, 9714 false, /* includeLocationSensitiveInfo */ 9715 shouldInclLocationSensitiveTransportInfoWithoutIncludeFlag); 9716 9717 verifyTransportInfoCopyNetCapsPermission(myUid, 9718 true, /* includeLocationSensitiveInfo */ 9719 shouldInclLocationSensitiveTransportInfoWithIncludeFlag); 9720 9721 } 9722 9723 private void verifyOwnerUidAndTransportInfoNetCapsPermissionPreS() { 9724 verifyOwnerUidAndTransportInfoNetCapsPermission( 9725 // Ensure that owner uid is included even if the request asks to remove it (which is 9726 // the default) since the app has necessary permissions and targetSdk < S. 9727 true, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */ 9728 true, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */ 9729 // Ensure that location info is removed if the request asks to remove it even if the 9730 // app has necessary permissions. 9731 false, /* shouldInclLocationSensitiveTransportInfoWithoutIncludeFlag */ 9732 true /* shouldInclLocationSensitiveTransportInfoWithIncludeFlag */ 9733 ); 9734 } 9735 9736 @Test 9737 public void testCreateWithLocationInfoSanitizedWithFineLocationAfterQPreS() 9738 throws Exception { 9739 setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION, 9740 Manifest.permission.ACCESS_FINE_LOCATION); 9741 9742 verifyOwnerUidAndTransportInfoNetCapsPermissionPreS(); 9743 } 9744 9745 @Test 9746 public void testCreateWithLocationInfoSanitizedWithFineLocationPreSWithAndWithoutCallbackFlag() 9747 throws Exception { 9748 setupLocationPermissions(Build.VERSION_CODES.R, true, AppOpsManager.OPSTR_FINE_LOCATION, 9749 Manifest.permission.ACCESS_FINE_LOCATION); 9750 9751 verifyOwnerUidAndTransportInfoNetCapsPermissionPreS(); 9752 } 9753 9754 @Test 9755 public void 9756 testCreateWithLocationInfoSanitizedWithFineLocationAfterSWithAndWithoutCallbackFlag() 9757 throws Exception { 9758 setupLocationPermissions(Build.VERSION_CODES.S, true, AppOpsManager.OPSTR_FINE_LOCATION, 9759 Manifest.permission.ACCESS_FINE_LOCATION); 9760 9761 verifyOwnerUidAndTransportInfoNetCapsPermission( 9762 // Ensure that the owner UID is removed if the request asks us to remove it even 9763 // if the app has necessary permissions since targetSdk >= S. 9764 false, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */ 9765 true, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */ 9766 // Ensure that location info is removed if the request asks to remove it even if the 9767 // app has necessary permissions. 9768 false, /* shouldInclLocationSensitiveTransportInfoWithoutIncludeFlag */ 9769 true /* shouldInclLocationSensitiveTransportInfoWithIncludeFlag */ 9770 ); 9771 } 9772 9773 @Test 9774 public void testCreateWithLocationInfoSanitizedWithCoarseLocationPreQ() 9775 throws Exception { 9776 setupLocationPermissions(Build.VERSION_CODES.P, true, AppOpsManager.OPSTR_COARSE_LOCATION, 9777 Manifest.permission.ACCESS_COARSE_LOCATION); 9778 9779 verifyOwnerUidAndTransportInfoNetCapsPermissionPreS(); 9780 } 9781 9782 private void verifyOwnerUidAndTransportInfoNetCapsNotIncluded() { 9783 verifyOwnerUidAndTransportInfoNetCapsPermission( 9784 false, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */ 9785 false, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */ 9786 false, /* shouldInclLocationSensitiveTransportInfoWithoutIncludeFlag */ 9787 false /* shouldInclLocationSensitiveTransportInfoWithIncludeFlag */ 9788 ); 9789 } 9790 9791 @Test 9792 public void testCreateWithLocationInfoSanitizedLocationOff() throws Exception { 9793 // Test that even with fine location permission, and UIDs matching, the UID is sanitized. 9794 setupLocationPermissions(Build.VERSION_CODES.Q, false, AppOpsManager.OPSTR_FINE_LOCATION, 9795 Manifest.permission.ACCESS_FINE_LOCATION); 9796 9797 verifyOwnerUidAndTransportInfoNetCapsNotIncluded(); 9798 } 9799 9800 @Test 9801 public void testCreateWithLocationInfoSanitizedWrongUid() throws Exception { 9802 // Test that even with fine location permission, not being the owner leads to sanitization. 9803 setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION, 9804 Manifest.permission.ACCESS_FINE_LOCATION); 9805 9806 final int myUid = Process.myUid(); 9807 assertEquals(Process.INVALID_UID, 9808 getOwnerUidNetCapsPermission(myUid + 1, myUid, 9809 true /* includeLocationSensitiveInfo */)); 9810 } 9811 9812 @Test 9813 public void testCreateWithLocationInfoSanitizedWithCoarseLocationAfterQ() 9814 throws Exception { 9815 // Test that not having fine location permission leads to sanitization. 9816 setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_COARSE_LOCATION, 9817 Manifest.permission.ACCESS_COARSE_LOCATION); 9818 9819 verifyOwnerUidAndTransportInfoNetCapsNotIncluded(); 9820 } 9821 9822 @Test 9823 public void testCreateWithLocationInfoSanitizedWithCoarseLocationAfterS() 9824 throws Exception { 9825 // Test that not having fine location permission leads to sanitization. 9826 setupLocationPermissions(Build.VERSION_CODES.S, true, AppOpsManager.OPSTR_COARSE_LOCATION, 9827 Manifest.permission.ACCESS_COARSE_LOCATION); 9828 9829 verifyOwnerUidAndTransportInfoNetCapsNotIncluded(); 9830 } 9831 9832 @Test 9833 public void testCreateForCallerWithLocalMacAddressSanitizedWithLocalMacAddressPermission() 9834 throws Exception { 9835 mServiceContext.setPermission(Manifest.permission.LOCAL_MAC_ADDRESS, PERMISSION_GRANTED); 9836 9837 final TransportInfo transportInfo = mock(TransportInfo.class); 9838 when(transportInfo.getApplicableRedactions()) 9839 .thenReturn(REDACT_FOR_ACCESS_FINE_LOCATION | REDACT_FOR_LOCAL_MAC_ADDRESS); 9840 final NetworkCapabilities netCap = 9841 new NetworkCapabilities().setTransportInfo(transportInfo); 9842 9843 mService.createWithLocationInfoSanitizedIfNecessaryWhenParceled( 9844 netCap, false /* includeLocationSensitiveInfoInTransportInfo */, 9845 Process.myPid(), Process.myUid(), 9846 mContext.getPackageName(), getAttributionTag()); 9847 // don't redact MAC_ADDRESS fields, only location sensitive fields. 9848 verify(transportInfo).makeCopy(REDACT_FOR_ACCESS_FINE_LOCATION); 9849 } 9850 9851 @Test 9852 public void testCreateForCallerWithLocalMacAddressSanitizedWithoutLocalMacAddressPermission() 9853 throws Exception { 9854 mServiceContext.setPermission(Manifest.permission.LOCAL_MAC_ADDRESS, PERMISSION_DENIED); 9855 9856 final TransportInfo transportInfo = mock(TransportInfo.class); 9857 when(transportInfo.getApplicableRedactions()) 9858 .thenReturn(REDACT_FOR_ACCESS_FINE_LOCATION | REDACT_FOR_LOCAL_MAC_ADDRESS); 9859 final NetworkCapabilities netCap = 9860 new NetworkCapabilities().setTransportInfo(transportInfo); 9861 9862 mService.createWithLocationInfoSanitizedIfNecessaryWhenParceled( 9863 netCap, false /* includeLocationSensitiveInfoInTransportInfo */, 9864 Process.myPid(), Process.myUid(), 9865 mContext.getPackageName(), getAttributionTag()); 9866 // redact both MAC_ADDRESS & location sensitive fields. 9867 verify(transportInfo).makeCopy(REDACT_FOR_ACCESS_FINE_LOCATION 9868 | REDACT_FOR_LOCAL_MAC_ADDRESS); 9869 } 9870 9871 @Test 9872 public void testCreateForCallerWithLocalMacAddressSanitizedWithSettingsPermission() 9873 throws Exception { 9874 mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_GRANTED); 9875 9876 final TransportInfo transportInfo = mock(TransportInfo.class); 9877 when(transportInfo.getApplicableRedactions()) 9878 .thenReturn(REDACT_FOR_ACCESS_FINE_LOCATION | REDACT_FOR_NETWORK_SETTINGS); 9879 final NetworkCapabilities netCap = 9880 new NetworkCapabilities().setTransportInfo(transportInfo); 9881 9882 mService.createWithLocationInfoSanitizedIfNecessaryWhenParceled( 9883 netCap, false /* includeLocationSensitiveInfoInTransportInfo */, 9884 Process.myPid(), Process.myUid(), 9885 mContext.getPackageName(), getAttributionTag()); 9886 // don't redact NETWORK_SETTINGS fields, only location sensitive fields. 9887 verify(transportInfo).makeCopy(REDACT_FOR_ACCESS_FINE_LOCATION); 9888 } 9889 9890 @Test 9891 public void testCreateForCallerWithLocalMacAddressSanitizedWithoutSettingsPermission() 9892 throws Exception { 9893 mServiceContext.setPermission(Manifest.permission.LOCAL_MAC_ADDRESS, PERMISSION_DENIED); 9894 9895 final TransportInfo transportInfo = mock(TransportInfo.class); 9896 when(transportInfo.getApplicableRedactions()) 9897 .thenReturn(REDACT_FOR_ACCESS_FINE_LOCATION | REDACT_FOR_NETWORK_SETTINGS); 9898 final NetworkCapabilities netCap = 9899 new NetworkCapabilities().setTransportInfo(transportInfo); 9900 9901 mService.createWithLocationInfoSanitizedIfNecessaryWhenParceled( 9902 netCap, false /* includeLocationSensitiveInfoInTransportInfo */, 9903 Process.myPid(), Process.myUid(), 9904 mContext.getPackageName(), getAttributionTag()); 9905 // redact both NETWORK_SETTINGS & location sensitive fields. 9906 verify(transportInfo).makeCopy( 9907 REDACT_FOR_ACCESS_FINE_LOCATION | REDACT_FOR_NETWORK_SETTINGS); 9908 } 9909 9910 /** 9911 * Test TransportInfo to verify redaction mechanism. 9912 */ 9913 private static class TestTransportInfo implements TransportInfo { 9914 public final boolean locationRedacted; 9915 public final boolean localMacAddressRedacted; 9916 public final boolean settingsRedacted; 9917 9918 TestTransportInfo() { 9919 locationRedacted = false; 9920 localMacAddressRedacted = false; 9921 settingsRedacted = false; 9922 } 9923 9924 TestTransportInfo(boolean locationRedacted, boolean localMacAddressRedacted, 9925 boolean settingsRedacted) { 9926 this.locationRedacted = locationRedacted; 9927 this.localMacAddressRedacted = 9928 localMacAddressRedacted; 9929 this.settingsRedacted = settingsRedacted; 9930 } 9931 9932 @Override 9933 public TransportInfo makeCopy(@NetworkCapabilities.RedactionType long redactions) { 9934 return new TestTransportInfo( 9935 locationRedacted | (redactions & REDACT_FOR_ACCESS_FINE_LOCATION) != 0, 9936 localMacAddressRedacted | (redactions & REDACT_FOR_LOCAL_MAC_ADDRESS) != 0, 9937 settingsRedacted | (redactions & REDACT_FOR_NETWORK_SETTINGS) != 0 9938 ); 9939 } 9940 9941 @Override 9942 public @NetworkCapabilities.RedactionType long getApplicableRedactions() { 9943 return REDACT_FOR_ACCESS_FINE_LOCATION | REDACT_FOR_LOCAL_MAC_ADDRESS 9944 | REDACT_FOR_NETWORK_SETTINGS; 9945 } 9946 9947 @Override 9948 public boolean equals(Object other) { 9949 if (!(other instanceof TestTransportInfo)) return false; 9950 TestTransportInfo that = (TestTransportInfo) other; 9951 return that.locationRedacted == this.locationRedacted 9952 && that.localMacAddressRedacted == this.localMacAddressRedacted 9953 && that.settingsRedacted == this.settingsRedacted; 9954 } 9955 9956 @Override 9957 public int hashCode() { 9958 return Objects.hash(locationRedacted, localMacAddressRedacted, settingsRedacted); 9959 } 9960 9961 @Override 9962 public String toString() { 9963 return String.format( 9964 "TestTransportInfo{locationRedacted=%s macRedacted=%s settingsRedacted=%s}", 9965 locationRedacted, localMacAddressRedacted, settingsRedacted); 9966 } 9967 } 9968 9969 private TestTransportInfo getTestTransportInfo(NetworkCapabilities nc) { 9970 return (TestTransportInfo) nc.getTransportInfo(); 9971 } 9972 9973 private TestTransportInfo getTestTransportInfo(TestNetworkAgentWrapper n) { 9974 final NetworkCapabilities nc = mCm.getNetworkCapabilities(n.getNetwork()); 9975 assertNotNull(nc); 9976 return getTestTransportInfo(nc); 9977 } 9978 9979 9980 private void verifyNetworkCallbackLocationDataInclusionUsingTransportInfoAndOwnerUidInNetCaps( 9981 @NonNull TestNetworkCallback wifiNetworkCallback, int actualOwnerUid, 9982 @NonNull TransportInfo actualTransportInfo, int expectedOwnerUid, 9983 @NonNull TransportInfo expectedTransportInfo) throws Exception { 9984 when(mPackageManager.getTargetSdkVersion(anyString())).thenReturn(Build.VERSION_CODES.S); 9985 final NetworkCapabilities ncTemplate = 9986 new NetworkCapabilities() 9987 .addTransportType(TRANSPORT_WIFI) 9988 .setOwnerUid(actualOwnerUid); 9989 9990 final NetworkRequest wifiRequest = new NetworkRequest.Builder() 9991 .addTransportType(TRANSPORT_WIFI).build(); 9992 mCm.registerNetworkCallback(wifiRequest, wifiNetworkCallback); 9993 9994 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, new LinkProperties(), 9995 ncTemplate); 9996 mWiFiNetworkAgent.connect(false); 9997 9998 wifiNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 9999 10000 // Send network capabilities update with TransportInfo to trigger capabilities changed 10001 // callback. 10002 mWiFiNetworkAgent.setNetworkCapabilities( 10003 ncTemplate.setTransportInfo(actualTransportInfo), true); 10004 10005 wifiNetworkCallback.expectCapabilitiesThat(mWiFiNetworkAgent, 10006 nc -> Objects.equals(expectedOwnerUid, nc.getOwnerUid()) 10007 && Objects.equals(expectedTransportInfo, nc.getTransportInfo())); 10008 } 10009 10010 @Test 10011 public void testVerifyLocationDataIsNotIncludedWhenInclFlagNotSet() throws Exception { 10012 final TestNetworkCallback wifiNetworkCallack = new TestNetworkCallback(); 10013 final int ownerUid = Process.myUid(); 10014 final TransportInfo transportInfo = new TestTransportInfo(); 10015 // Even though the test uid holds privileged permissions, mask location fields since 10016 // the callback did not explicitly opt-in to get location data. 10017 final TransportInfo sanitizedTransportInfo = new TestTransportInfo( 10018 true, /* locationRedacted */ 10019 true, /* localMacAddressRedacted */ 10020 true /* settingsRedacted */ 10021 ); 10022 // Should not expect location data since the callback does not set the flag for including 10023 // location data. 10024 verifyNetworkCallbackLocationDataInclusionUsingTransportInfoAndOwnerUidInNetCaps( 10025 wifiNetworkCallack, ownerUid, transportInfo, INVALID_UID, sanitizedTransportInfo); 10026 } 10027 10028 @Test 10029 public void testTransportInfoRedactionInSynchronousCalls() throws Exception { 10030 final NetworkCapabilities ncTemplate = new NetworkCapabilities() 10031 .addTransportType(TRANSPORT_WIFI) 10032 .setTransportInfo(new TestTransportInfo()); 10033 10034 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, new LinkProperties(), 10035 ncTemplate); 10036 mWiFiNetworkAgent.connect(true /* validated; waits for callback */); 10037 10038 // NETWORK_SETTINGS redaction is controlled by the NETWORK_SETTINGS permission 10039 assertTrue(getTestTransportInfo(mWiFiNetworkAgent).settingsRedacted); 10040 withPermission(NETWORK_SETTINGS, () -> { 10041 assertFalse(getTestTransportInfo(mWiFiNetworkAgent).settingsRedacted); 10042 }); 10043 assertTrue(getTestTransportInfo(mWiFiNetworkAgent).settingsRedacted); 10044 10045 // LOCAL_MAC_ADDRESS redaction is controlled by the LOCAL_MAC_ADDRESS permission 10046 assertTrue(getTestTransportInfo(mWiFiNetworkAgent).localMacAddressRedacted); 10047 withPermission(LOCAL_MAC_ADDRESS, () -> { 10048 assertFalse(getTestTransportInfo(mWiFiNetworkAgent).localMacAddressRedacted); 10049 }); 10050 assertTrue(getTestTransportInfo(mWiFiNetworkAgent).localMacAddressRedacted); 10051 10052 // Synchronous getNetworkCapabilities calls never return unredacted location-sensitive 10053 // information. 10054 assertTrue(getTestTransportInfo(mWiFiNetworkAgent).locationRedacted); 10055 setupLocationPermissions(Build.VERSION_CODES.S, true, AppOpsManager.OPSTR_FINE_LOCATION, 10056 Manifest.permission.ACCESS_FINE_LOCATION); 10057 assertTrue(getTestTransportInfo(mWiFiNetworkAgent).locationRedacted); 10058 denyAllLocationPrivilegedPermissions(); 10059 assertTrue(getTestTransportInfo(mWiFiNetworkAgent).locationRedacted); 10060 } 10061 10062 private void setupConnectionOwnerUid(int vpnOwnerUid, @VpnManager.VpnType int vpnType) 10063 throws Exception { 10064 final Set<UidRange> vpnRange = Collections.singleton(PRIMARY_UIDRANGE); 10065 mMockVpn.setVpnType(vpnType); 10066 mMockVpn.establish(new LinkProperties(), vpnOwnerUid, vpnRange); 10067 assertVpnUidRangesUpdated(true, vpnRange, vpnOwnerUid); 10068 10069 final UnderlyingNetworkInfo underlyingNetworkInfo = 10070 new UnderlyingNetworkInfo(vpnOwnerUid, VPN_IFNAME, new ArrayList<String>()); 10071 mMockVpn.setUnderlyingNetworkInfo(underlyingNetworkInfo); 10072 when(mDeps.getConnectionOwnerUid(anyInt(), any(), any())).thenReturn(42); 10073 } 10074 10075 private void setupConnectionOwnerUidAsVpnApp(int vpnOwnerUid, @VpnManager.VpnType int vpnType) 10076 throws Exception { 10077 setupConnectionOwnerUid(vpnOwnerUid, vpnType); 10078 10079 // Test as VPN app 10080 mServiceContext.setPermission(NETWORK_STACK, PERMISSION_DENIED); 10081 mServiceContext.setPermission( 10082 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, PERMISSION_DENIED); 10083 } 10084 10085 private ConnectionInfo getTestConnectionInfo() throws Exception { 10086 return new ConnectionInfo( 10087 IPPROTO_TCP, 10088 new InetSocketAddress(InetAddresses.parseNumericAddress("1.2.3.4"), 1234), 10089 new InetSocketAddress(InetAddresses.parseNumericAddress("2.3.4.5"), 2345)); 10090 } 10091 10092 @Test 10093 public void testGetConnectionOwnerUidPlatformVpn() throws Exception { 10094 final int myUid = Process.myUid(); 10095 setupConnectionOwnerUidAsVpnApp(myUid, VpnManager.TYPE_VPN_PLATFORM); 10096 10097 assertEquals(INVALID_UID, mService.getConnectionOwnerUid(getTestConnectionInfo())); 10098 } 10099 10100 @Test 10101 public void testGetConnectionOwnerUidVpnServiceWrongUser() throws Exception { 10102 final int myUid = Process.myUid(); 10103 setupConnectionOwnerUidAsVpnApp(myUid + 1, VpnManager.TYPE_VPN_SERVICE); 10104 10105 assertEquals(INVALID_UID, mService.getConnectionOwnerUid(getTestConnectionInfo())); 10106 } 10107 10108 @Test 10109 public void testGetConnectionOwnerUidVpnServiceDoesNotThrow() throws Exception { 10110 final int myUid = Process.myUid(); 10111 setupConnectionOwnerUidAsVpnApp(myUid, VpnManager.TYPE_VPN_SERVICE); 10112 10113 assertEquals(42, mService.getConnectionOwnerUid(getTestConnectionInfo())); 10114 } 10115 10116 @Test 10117 public void testGetConnectionOwnerUidVpnServiceNetworkStackDoesNotThrow() throws Exception { 10118 final int myUid = Process.myUid(); 10119 setupConnectionOwnerUid(myUid, VpnManager.TYPE_VPN_SERVICE); 10120 mServiceContext.setPermission(NETWORK_STACK, PERMISSION_GRANTED); 10121 10122 assertEquals(42, mService.getConnectionOwnerUid(getTestConnectionInfo())); 10123 } 10124 10125 @Test 10126 public void testGetConnectionOwnerUidVpnServiceMainlineNetworkStackDoesNotThrow() 10127 throws Exception { 10128 final int myUid = Process.myUid(); 10129 setupConnectionOwnerUid(myUid, VpnManager.TYPE_VPN_SERVICE); 10130 mServiceContext.setPermission( 10131 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, PERMISSION_GRANTED); 10132 10133 assertEquals(42, mService.getConnectionOwnerUid(getTestConnectionInfo())); 10134 } 10135 10136 private static PackageInfo buildPackageInfo(boolean hasSystemPermission, int uid) { 10137 final PackageInfo packageInfo = new PackageInfo(); 10138 if (hasSystemPermission) { 10139 packageInfo.requestedPermissions = new String[] { 10140 CHANGE_NETWORK_STATE, CONNECTIVITY_USE_RESTRICTED_NETWORKS }; 10141 packageInfo.requestedPermissionsFlags = new int[] { 10142 REQUESTED_PERMISSION_GRANTED, REQUESTED_PERMISSION_GRANTED }; 10143 } else { 10144 packageInfo.requestedPermissions = new String[0]; 10145 } 10146 packageInfo.applicationInfo = new ApplicationInfo(); 10147 packageInfo.applicationInfo.privateFlags = 0; 10148 packageInfo.applicationInfo.uid = UserHandle.getUid(UserHandle.USER_SYSTEM, 10149 UserHandle.getAppId(uid)); 10150 return packageInfo; 10151 } 10152 10153 @Test 10154 public void testRegisterConnectivityDiagnosticsCallbackInvalidRequest() throws Exception { 10155 final NetworkRequest request = 10156 new NetworkRequest( 10157 new NetworkCapabilities(), TYPE_ETHERNET, 0, NetworkRequest.Type.NONE); 10158 try { 10159 mService.registerConnectivityDiagnosticsCallback( 10160 mConnectivityDiagnosticsCallback, request, mContext.getPackageName()); 10161 fail("registerConnectivityDiagnosticsCallback should throw on invalid NetworkRequest"); 10162 } catch (IllegalArgumentException expected) { 10163 } 10164 } 10165 10166 private void assertRouteInfoParcelMatches(RouteInfo route, RouteInfoParcel parcel) { 10167 assertEquals(route.getDestination().toString(), parcel.destination); 10168 assertEquals(route.getInterface(), parcel.ifName); 10169 assertEquals(route.getMtu(), parcel.mtu); 10170 10171 switch (route.getType()) { 10172 case RouteInfo.RTN_UNICAST: 10173 if (route.hasGateway()) { 10174 assertEquals(route.getGateway().getHostAddress(), parcel.nextHop); 10175 } else { 10176 assertEquals(INetd.NEXTHOP_NONE, parcel.nextHop); 10177 } 10178 break; 10179 case RouteInfo.RTN_UNREACHABLE: 10180 assertEquals(INetd.NEXTHOP_UNREACHABLE, parcel.nextHop); 10181 break; 10182 case RouteInfo.RTN_THROW: 10183 assertEquals(INetd.NEXTHOP_THROW, parcel.nextHop); 10184 break; 10185 default: 10186 assertEquals(INetd.NEXTHOP_NONE, parcel.nextHop); 10187 break; 10188 } 10189 } 10190 10191 private void assertRoutesAdded(int netId, RouteInfo... routes) throws Exception { 10192 // TODO: add @JavaDerive(equals=true) to RouteInfoParcel, use eq() directly, and delete 10193 // assertRouteInfoParcelMatches above. 10194 ArgumentCaptor<RouteInfoParcel> captor = ArgumentCaptor.forClass(RouteInfoParcel.class); 10195 verify(mMockNetd, times(routes.length)).networkAddRouteParcel(eq(netId), captor.capture()); 10196 for (int i = 0; i < routes.length; i++) { 10197 assertRouteInfoParcelMatches(routes[i], captor.getAllValues().get(i)); 10198 } 10199 } 10200 10201 private void assertRoutesRemoved(int netId, RouteInfo... routes) throws Exception { 10202 ArgumentCaptor<RouteInfoParcel> captor = ArgumentCaptor.forClass(RouteInfoParcel.class); 10203 verify(mMockNetd, times(routes.length)).networkRemoveRouteParcel(eq(netId), 10204 captor.capture()); 10205 for (int i = 0; i < routes.length; i++) { 10206 assertRouteInfoParcelMatches(routes[i], captor.getAllValues().get(i)); 10207 } 10208 } 10209 10210 @Test 10211 public void testRegisterUnregisterConnectivityDiagnosticsCallback() throws Exception { 10212 final NetworkRequest wifiRequest = 10213 new NetworkRequest.Builder().addTransportType(TRANSPORT_WIFI).build(); 10214 when(mConnectivityDiagnosticsCallback.asBinder()).thenReturn(mIBinder); 10215 10216 mService.registerConnectivityDiagnosticsCallback( 10217 mConnectivityDiagnosticsCallback, wifiRequest, mContext.getPackageName()); 10218 10219 // Block until all other events are done processing. 10220 HandlerUtils.waitForIdle(mCsHandlerThread, TIMEOUT_MS); 10221 10222 verify(mIBinder).linkToDeath(any(ConnectivityDiagnosticsCallbackInfo.class), anyInt()); 10223 verify(mConnectivityDiagnosticsCallback).asBinder(); 10224 assertTrue(mService.mConnectivityDiagnosticsCallbacks.containsKey(mIBinder)); 10225 10226 mService.unregisterConnectivityDiagnosticsCallback(mConnectivityDiagnosticsCallback); 10227 verify(mIBinder, timeout(TIMEOUT_MS)) 10228 .unlinkToDeath(any(ConnectivityDiagnosticsCallbackInfo.class), anyInt()); 10229 assertFalse(mService.mConnectivityDiagnosticsCallbacks.containsKey(mIBinder)); 10230 verify(mConnectivityDiagnosticsCallback, atLeastOnce()).asBinder(); 10231 } 10232 10233 @Test 10234 public void testRegisterDuplicateConnectivityDiagnosticsCallback() throws Exception { 10235 final NetworkRequest wifiRequest = 10236 new NetworkRequest.Builder().addTransportType(TRANSPORT_WIFI).build(); 10237 when(mConnectivityDiagnosticsCallback.asBinder()).thenReturn(mIBinder); 10238 10239 mService.registerConnectivityDiagnosticsCallback( 10240 mConnectivityDiagnosticsCallback, wifiRequest, mContext.getPackageName()); 10241 10242 // Block until all other events are done processing. 10243 HandlerUtils.waitForIdle(mCsHandlerThread, TIMEOUT_MS); 10244 10245 verify(mIBinder).linkToDeath(any(ConnectivityDiagnosticsCallbackInfo.class), anyInt()); 10246 verify(mConnectivityDiagnosticsCallback).asBinder(); 10247 assertTrue(mService.mConnectivityDiagnosticsCallbacks.containsKey(mIBinder)); 10248 10249 // Register the same callback again 10250 mService.registerConnectivityDiagnosticsCallback( 10251 mConnectivityDiagnosticsCallback, wifiRequest, mContext.getPackageName()); 10252 10253 // Block until all other events are done processing. 10254 HandlerUtils.waitForIdle(mCsHandlerThread, TIMEOUT_MS); 10255 10256 assertTrue(mService.mConnectivityDiagnosticsCallbacks.containsKey(mIBinder)); 10257 } 10258 10259 public NetworkAgentInfo fakeMobileNai(NetworkCapabilities nc) { 10260 final NetworkCapabilities cellNc = new NetworkCapabilities.Builder(nc) 10261 .addTransportType(TRANSPORT_CELLULAR).build(); 10262 final NetworkInfo info = new NetworkInfo(TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_LTE, 10263 ConnectivityManager.getNetworkTypeName(TYPE_MOBILE), 10264 TelephonyManager.getNetworkTypeName(TelephonyManager.NETWORK_TYPE_LTE)); 10265 return fakeNai(cellNc, info); 10266 } 10267 10268 private NetworkAgentInfo fakeWifiNai(NetworkCapabilities nc) { 10269 final NetworkCapabilities wifiNc = new NetworkCapabilities.Builder(nc) 10270 .addTransportType(TRANSPORT_WIFI).build(); 10271 final NetworkInfo info = new NetworkInfo(TYPE_WIFI, 0 /* subtype */, 10272 ConnectivityManager.getNetworkTypeName(TYPE_WIFI), "" /* subtypeName */); 10273 return fakeNai(wifiNc, info); 10274 } 10275 10276 private NetworkAgentInfo fakeNai(NetworkCapabilities nc, NetworkInfo networkInfo) { 10277 return new NetworkAgentInfo(null, new Network(NET_ID), networkInfo, new LinkProperties(), 10278 nc, new NetworkScore.Builder().setLegacyInt(0).build(), 10279 mServiceContext, null, new NetworkAgentConfig(), mService, null, null, 0, 10280 INVALID_UID, TEST_LINGER_DELAY_MS, mQosCallbackTracker, 10281 new ConnectivityService.Dependencies()); 10282 } 10283 10284 @Test 10285 public void testCheckConnectivityDiagnosticsPermissionsNetworkStack() throws Exception { 10286 final NetworkAgentInfo naiWithoutUid = fakeMobileNai(new NetworkCapabilities()); 10287 10288 mServiceContext.setPermission(NETWORK_STACK, PERMISSION_GRANTED); 10289 assertTrue( 10290 "NetworkStack permission not applied", 10291 mService.checkConnectivityDiagnosticsPermissions( 10292 Process.myPid(), Process.myUid(), naiWithoutUid, 10293 mContext.getOpPackageName())); 10294 } 10295 10296 @Test 10297 public void testCheckConnectivityDiagnosticsPermissionsWrongUidPackageName() throws Exception { 10298 final int wrongUid = Process.myUid() + 1; 10299 10300 final NetworkCapabilities nc = new NetworkCapabilities(); 10301 nc.setAdministratorUids(new int[] {wrongUid}); 10302 final NetworkAgentInfo naiWithUid = fakeWifiNai(nc); 10303 10304 mServiceContext.setPermission(NETWORK_STACK, PERMISSION_DENIED); 10305 10306 assertFalse( 10307 "Mismatched uid/package name should not pass the location permission check", 10308 mService.checkConnectivityDiagnosticsPermissions( 10309 Process.myPid() + 1, wrongUid, naiWithUid, mContext.getOpPackageName())); 10310 } 10311 10312 private void verifyConnectivityDiagnosticsPermissionsWithNetworkAgentInfo( 10313 NetworkAgentInfo info, boolean expectPermission) { 10314 mServiceContext.setPermission(NETWORK_STACK, PERMISSION_DENIED); 10315 10316 assertEquals( 10317 "Unexpected ConnDiags permission", 10318 expectPermission, 10319 mService.checkConnectivityDiagnosticsPermissions( 10320 Process.myPid(), Process.myUid(), info, mContext.getOpPackageName())); 10321 } 10322 10323 @Test 10324 public void testCheckConnectivityDiagnosticsPermissionsCellularNoLocationPermission() 10325 throws Exception { 10326 final NetworkCapabilities nc = new NetworkCapabilities(); 10327 nc.setAdministratorUids(new int[] {Process.myUid()}); 10328 final NetworkAgentInfo naiWithUid = fakeMobileNai(nc); 10329 10330 verifyConnectivityDiagnosticsPermissionsWithNetworkAgentInfo(naiWithUid, 10331 true /* expectPermission */); 10332 } 10333 10334 @Test 10335 public void testCheckConnectivityDiagnosticsPermissionsWifiNoLocationPermission() 10336 throws Exception { 10337 final NetworkCapabilities nc = new NetworkCapabilities(); 10338 nc.setAdministratorUids(new int[] {Process.myUid()}); 10339 final NetworkAgentInfo naiWithUid = fakeWifiNai(nc); 10340 10341 verifyConnectivityDiagnosticsPermissionsWithNetworkAgentInfo(naiWithUid, 10342 false /* expectPermission */); 10343 } 10344 10345 @Test 10346 public void testCheckConnectivityDiagnosticsPermissionsActiveVpn() throws Exception { 10347 final NetworkAgentInfo naiWithoutUid = fakeMobileNai(new NetworkCapabilities()); 10348 10349 mMockVpn.establishForMyUid(); 10350 assertUidRangesUpdatedForMyUid(true); 10351 10352 // Wait for networks to connect and broadcasts to be sent before removing permissions. 10353 waitForIdle(); 10354 setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION, 10355 Manifest.permission.ACCESS_FINE_LOCATION); 10356 10357 assertTrue(mMockVpn.setUnderlyingNetworks(new Network[] {naiWithoutUid.network})); 10358 waitForIdle(); 10359 assertTrue( 10360 "Active VPN permission not applied", 10361 mService.checkConnectivityDiagnosticsPermissions( 10362 Process.myPid(), Process.myUid(), naiWithoutUid, 10363 mContext.getOpPackageName())); 10364 10365 assertTrue(mMockVpn.setUnderlyingNetworks(null)); 10366 waitForIdle(); 10367 assertFalse( 10368 "VPN shouldn't receive callback on non-underlying network", 10369 mService.checkConnectivityDiagnosticsPermissions( 10370 Process.myPid(), Process.myUid(), naiWithoutUid, 10371 mContext.getOpPackageName())); 10372 } 10373 10374 @Test 10375 public void testCheckConnectivityDiagnosticsPermissionsNetworkAdministrator() throws Exception { 10376 final NetworkCapabilities nc = new NetworkCapabilities(); 10377 nc.setAdministratorUids(new int[] {Process.myUid()}); 10378 final NetworkAgentInfo naiWithUid = fakeMobileNai(nc); 10379 10380 setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION, 10381 Manifest.permission.ACCESS_FINE_LOCATION); 10382 mServiceContext.setPermission(NETWORK_STACK, PERMISSION_DENIED); 10383 10384 assertTrue( 10385 "NetworkCapabilities administrator uid permission not applied", 10386 mService.checkConnectivityDiagnosticsPermissions( 10387 Process.myPid(), Process.myUid(), naiWithUid, mContext.getOpPackageName())); 10388 } 10389 10390 @Test 10391 public void testCheckConnectivityDiagnosticsPermissionsFails() throws Exception { 10392 final NetworkCapabilities nc = new NetworkCapabilities(); 10393 nc.setOwnerUid(Process.myUid()); 10394 nc.setAdministratorUids(new int[] {Process.myUid()}); 10395 final NetworkAgentInfo naiWithUid = fakeMobileNai(nc); 10396 10397 setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION, 10398 Manifest.permission.ACCESS_FINE_LOCATION); 10399 mServiceContext.setPermission(NETWORK_STACK, PERMISSION_DENIED); 10400 10401 // Use wrong pid and uid 10402 assertFalse( 10403 "Permissions allowed when they shouldn't be granted", 10404 mService.checkConnectivityDiagnosticsPermissions( 10405 Process.myPid() + 1, Process.myUid() + 1, naiWithUid, 10406 mContext.getOpPackageName())); 10407 } 10408 10409 @Test 10410 public void testRegisterConnectivityDiagnosticsCallbackCallsOnConnectivityReport() 10411 throws Exception { 10412 // Set up the Network, which leads to a ConnectivityReport being cached for the network. 10413 final TestNetworkCallback callback = new TestNetworkCallback(); 10414 mCm.registerDefaultNetworkCallback(callback); 10415 final LinkProperties linkProperties = new LinkProperties(); 10416 linkProperties.setInterfaceName(INTERFACE_NAME); 10417 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, linkProperties); 10418 mCellNetworkAgent.connect(true); 10419 callback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 10420 callback.assertNoCallback(); 10421 10422 final NetworkRequest request = new NetworkRequest.Builder().build(); 10423 when(mConnectivityDiagnosticsCallback.asBinder()).thenReturn(mIBinder); 10424 10425 mServiceContext.setPermission(NETWORK_STACK, PERMISSION_GRANTED); 10426 10427 mService.registerConnectivityDiagnosticsCallback( 10428 mConnectivityDiagnosticsCallback, request, mContext.getPackageName()); 10429 10430 // Block until all other events are done processing. 10431 HandlerUtils.waitForIdle(mCsHandlerThread, TIMEOUT_MS); 10432 10433 verify(mConnectivityDiagnosticsCallback) 10434 .onConnectivityReportAvailable(argThat(report -> { 10435 return INTERFACE_NAME.equals(report.getLinkProperties().getInterfaceName()) 10436 && report.getNetworkCapabilities().hasTransport(TRANSPORT_CELLULAR); 10437 })); 10438 } 10439 10440 private void setUpConnectivityDiagnosticsCallback() throws Exception { 10441 final NetworkRequest request = new NetworkRequest.Builder().build(); 10442 when(mConnectivityDiagnosticsCallback.asBinder()).thenReturn(mIBinder); 10443 10444 mServiceContext.setPermission(NETWORK_STACK, PERMISSION_GRANTED); 10445 10446 mService.registerConnectivityDiagnosticsCallback( 10447 mConnectivityDiagnosticsCallback, request, mContext.getPackageName()); 10448 10449 // Block until all other events are done processing. 10450 HandlerUtils.waitForIdle(mCsHandlerThread, TIMEOUT_MS); 10451 10452 // Connect the cell agent verify that it notifies TestNetworkCallback that it is available 10453 final TestNetworkCallback callback = new TestNetworkCallback(); 10454 mCm.registerDefaultNetworkCallback(callback); 10455 10456 final NetworkCapabilities ncTemplate = new NetworkCapabilities() 10457 .addTransportType(TRANSPORT_CELLULAR) 10458 .setTransportInfo(new TestTransportInfo()); 10459 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, new LinkProperties(), 10460 ncTemplate); 10461 mCellNetworkAgent.connect(true); 10462 callback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 10463 callback.assertNoCallback(); 10464 } 10465 10466 private boolean areConnDiagCapsRedacted(NetworkCapabilities nc) { 10467 TestTransportInfo ti = (TestTransportInfo) nc.getTransportInfo(); 10468 return nc.getUids() == null 10469 && nc.getAdministratorUids().length == 0 10470 && nc.getOwnerUid() == Process.INVALID_UID 10471 && getTestTransportInfo(nc).locationRedacted 10472 && getTestTransportInfo(nc).localMacAddressRedacted 10473 && getTestTransportInfo(nc).settingsRedacted; 10474 } 10475 10476 @Test 10477 public void testConnectivityDiagnosticsCallbackOnConnectivityReportAvailable() 10478 throws Exception { 10479 setUpConnectivityDiagnosticsCallback(); 10480 10481 // Block until all other events are done processing. 10482 HandlerUtils.waitForIdle(mCsHandlerThread, TIMEOUT_MS); 10483 10484 // Verify onConnectivityReport fired 10485 verify(mConnectivityDiagnosticsCallback).onConnectivityReportAvailable( 10486 argThat(report -> areConnDiagCapsRedacted(report.getNetworkCapabilities()))); 10487 } 10488 10489 @Test 10490 public void testConnectivityDiagnosticsCallbackOnDataStallSuspected() throws Exception { 10491 setUpConnectivityDiagnosticsCallback(); 10492 10493 // Trigger notifyDataStallSuspected() on the INetworkMonitorCallbacks instance in the 10494 // cellular network agent 10495 mCellNetworkAgent.notifyDataStallSuspected(); 10496 10497 // Block until all other events are done processing. 10498 HandlerUtils.waitForIdle(mCsHandlerThread, TIMEOUT_MS); 10499 10500 // Verify onDataStallSuspected fired 10501 verify(mConnectivityDiagnosticsCallback).onDataStallSuspected( 10502 argThat(report -> areConnDiagCapsRedacted(report.getNetworkCapabilities()))); 10503 } 10504 10505 @Test 10506 public void testConnectivityDiagnosticsCallbackOnConnectivityReported() throws Exception { 10507 setUpConnectivityDiagnosticsCallback(); 10508 10509 final Network n = mCellNetworkAgent.getNetwork(); 10510 final boolean hasConnectivity = true; 10511 mService.reportNetworkConnectivity(n, hasConnectivity); 10512 10513 // Block until all other events are done processing. 10514 HandlerUtils.waitForIdle(mCsHandlerThread, TIMEOUT_MS); 10515 10516 // Verify onNetworkConnectivityReported fired 10517 verify(mConnectivityDiagnosticsCallback) 10518 .onNetworkConnectivityReported(eq(n), eq(hasConnectivity)); 10519 10520 final boolean noConnectivity = false; 10521 mService.reportNetworkConnectivity(n, noConnectivity); 10522 10523 // Block until all other events are done processing. 10524 HandlerUtils.waitForIdle(mCsHandlerThread, TIMEOUT_MS); 10525 10526 // Wait for onNetworkConnectivityReported to fire 10527 verify(mConnectivityDiagnosticsCallback) 10528 .onNetworkConnectivityReported(eq(n), eq(noConnectivity)); 10529 } 10530 10531 @Test 10532 public void testRouteAddDeleteUpdate() throws Exception { 10533 final NetworkRequest request = new NetworkRequest.Builder().build(); 10534 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 10535 mCm.registerNetworkCallback(request, networkCallback); 10536 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 10537 reset(mMockNetd); 10538 mCellNetworkAgent.connect(false); 10539 networkCallback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent); 10540 final int netId = mCellNetworkAgent.getNetwork().netId; 10541 10542 final String iface = "rmnet_data0"; 10543 final InetAddress gateway = InetAddress.getByName("fe80::5678"); 10544 RouteInfo direct = RouteInfo.makeHostRoute(gateway, iface); 10545 RouteInfo rio1 = new RouteInfo(new IpPrefix("2001:db8:1::/48"), gateway, iface); 10546 RouteInfo rio2 = new RouteInfo(new IpPrefix("2001:db8:2::/48"), gateway, iface); 10547 RouteInfo defaultRoute = new RouteInfo((IpPrefix) null, gateway, iface); 10548 RouteInfo defaultWithMtu = new RouteInfo(null, gateway, iface, RouteInfo.RTN_UNICAST, 10549 1280 /* mtu */); 10550 10551 // Send LinkProperties and check that we ask netd to add routes. 10552 LinkProperties lp = new LinkProperties(); 10553 lp.setInterfaceName(iface); 10554 lp.addRoute(direct); 10555 lp.addRoute(rio1); 10556 lp.addRoute(defaultRoute); 10557 mCellNetworkAgent.sendLinkProperties(lp); 10558 networkCallback.expectLinkPropertiesThat(mCellNetworkAgent, x -> x.getRoutes().size() == 3); 10559 10560 assertRoutesAdded(netId, direct, rio1, defaultRoute); 10561 reset(mMockNetd); 10562 10563 // Send updated LinkProperties and check that we ask netd to add, remove, update routes. 10564 assertTrue(lp.getRoutes().contains(defaultRoute)); 10565 lp.removeRoute(rio1); 10566 lp.addRoute(rio2); 10567 lp.addRoute(defaultWithMtu); 10568 // Ensure adding the same route with a different MTU replaces the previous route. 10569 assertFalse(lp.getRoutes().contains(defaultRoute)); 10570 assertTrue(lp.getRoutes().contains(defaultWithMtu)); 10571 10572 mCellNetworkAgent.sendLinkProperties(lp); 10573 networkCallback.expectLinkPropertiesThat(mCellNetworkAgent, 10574 x -> x.getRoutes().contains(rio2)); 10575 10576 assertRoutesRemoved(netId, rio1); 10577 assertRoutesAdded(netId, rio2); 10578 10579 ArgumentCaptor<RouteInfoParcel> captor = ArgumentCaptor.forClass(RouteInfoParcel.class); 10580 verify(mMockNetd).networkUpdateRouteParcel(eq(netId), captor.capture()); 10581 assertRouteInfoParcelMatches(defaultWithMtu, captor.getValue()); 10582 10583 10584 mCm.unregisterNetworkCallback(networkCallback); 10585 } 10586 10587 @Test 10588 public void testDumpDoesNotCrash() { 10589 mServiceContext.setPermission(DUMP, PERMISSION_GRANTED); 10590 // Filing a couple requests prior to testing the dump. 10591 final TestNetworkCallback genericNetworkCallback = new TestNetworkCallback(); 10592 final TestNetworkCallback wifiNetworkCallback = new TestNetworkCallback(); 10593 final NetworkRequest genericRequest = new NetworkRequest.Builder() 10594 .clearCapabilities().build(); 10595 final NetworkRequest wifiRequest = new NetworkRequest.Builder() 10596 .addTransportType(TRANSPORT_WIFI).build(); 10597 mCm.registerNetworkCallback(genericRequest, genericNetworkCallback); 10598 mCm.registerNetworkCallback(wifiRequest, wifiNetworkCallback); 10599 final StringWriter stringWriter = new StringWriter(); 10600 10601 mService.dump(new FileDescriptor(), new PrintWriter(stringWriter), new String[0]); 10602 10603 assertFalse(stringWriter.toString().isEmpty()); 10604 } 10605 10606 @Test 10607 public void testRequestsSortedByIdSortsCorrectly() { 10608 final TestNetworkCallback genericNetworkCallback = new TestNetworkCallback(); 10609 final TestNetworkCallback wifiNetworkCallback = new TestNetworkCallback(); 10610 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback(); 10611 final NetworkRequest genericRequest = new NetworkRequest.Builder() 10612 .clearCapabilities().build(); 10613 final NetworkRequest wifiRequest = new NetworkRequest.Builder() 10614 .addTransportType(TRANSPORT_WIFI).build(); 10615 final NetworkRequest cellRequest = new NetworkRequest.Builder() 10616 .addTransportType(TRANSPORT_CELLULAR).build(); 10617 mCm.registerNetworkCallback(genericRequest, genericNetworkCallback); 10618 mCm.registerNetworkCallback(wifiRequest, wifiNetworkCallback); 10619 mCm.registerNetworkCallback(cellRequest, cellNetworkCallback); 10620 waitForIdle(); 10621 10622 final NetworkRequestInfo[] nriOutput = mService.requestsSortedById(); 10623 10624 assertTrue(nriOutput.length > 1); 10625 for (int i = 0; i < nriOutput.length - 1; i++) { 10626 final boolean isRequestIdInOrder = 10627 nriOutput[i].mRequests.get(0).requestId 10628 < nriOutput[i + 1].mRequests.get(0).requestId; 10629 assertTrue(isRequestIdInOrder); 10630 } 10631 } 10632 10633 private void assertUidRangesUpdatedForMyUid(boolean add) throws Exception { 10634 final int uid = Process.myUid(); 10635 assertVpnUidRangesUpdated(add, uidRangesForUids(uid), uid); 10636 } 10637 10638 private void assertVpnUidRangesUpdated(boolean add, Set<UidRange> vpnRanges, int exemptUid) 10639 throws Exception { 10640 InOrder inOrder = inOrder(mMockNetd); 10641 ArgumentCaptor<int[]> exemptUidCaptor = ArgumentCaptor.forClass(int[].class); 10642 10643 inOrder.verify(mMockNetd, times(1)).socketDestroy(eq(toUidRangeStableParcels(vpnRanges)), 10644 exemptUidCaptor.capture()); 10645 assertContainsExactly(exemptUidCaptor.getValue(), Process.VPN_UID, exemptUid); 10646 10647 if (add) { 10648 inOrder.verify(mMockNetd, times(1)).networkAddUidRangesParcel( 10649 new NativeUidRangeConfig(mMockVpn.getNetwork().getNetId(), 10650 toUidRangeStableParcels(vpnRanges), PREFERENCE_PRIORITY_VPN)); 10651 } else { 10652 inOrder.verify(mMockNetd, times(1)).networkRemoveUidRangesParcel( 10653 new NativeUidRangeConfig(mMockVpn.getNetwork().getNetId(), 10654 toUidRangeStableParcels(vpnRanges), PREFERENCE_PRIORITY_VPN)); 10655 } 10656 10657 inOrder.verify(mMockNetd, times(1)).socketDestroy(eq(toUidRangeStableParcels(vpnRanges)), 10658 exemptUidCaptor.capture()); 10659 assertContainsExactly(exemptUidCaptor.getValue(), Process.VPN_UID, exemptUid); 10660 } 10661 10662 @Test 10663 public void testVpnUidRangesUpdate() throws Exception { 10664 // Set up a WiFi network without proxy. 10665 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 10666 mWiFiNetworkAgent.connect(true); 10667 assertNull(mService.getProxyForNetwork(null)); 10668 assertNull(mCm.getDefaultProxy()); 10669 10670 final LinkProperties lp = new LinkProperties(); 10671 lp.setInterfaceName("tun0"); 10672 lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), null)); 10673 lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), null)); 10674 final UidRange vpnRange = PRIMARY_UIDRANGE; 10675 final Set<UidRange> vpnRanges = Collections.singleton(vpnRange); 10676 mMockVpn.establish(lp, VPN_UID, vpnRanges); 10677 assertVpnUidRangesUpdated(true, vpnRanges, VPN_UID); 10678 // VPN is connected but proxy is not set, so there is no need to send proxy broadcast. 10679 verify(mProxyTracker, never()).sendProxyBroadcast(); 10680 10681 // Update to new range which is old range minus APP1, i.e. only APP2 10682 final Set<UidRange> newRanges = new HashSet<>(Arrays.asList( 10683 new UidRange(vpnRange.start, APP1_UID - 1), 10684 new UidRange(APP1_UID + 1, vpnRange.stop))); 10685 mMockVpn.setUids(newRanges); 10686 waitForIdle(); 10687 10688 assertVpnUidRangesUpdated(true, newRanges, VPN_UID); 10689 assertVpnUidRangesUpdated(false, vpnRanges, VPN_UID); 10690 10691 // Uid has changed but proxy is not set, so there is no need to send proxy broadcast. 10692 verify(mProxyTracker, never()).sendProxyBroadcast(); 10693 10694 final ProxyInfo testProxyInfo = ProxyInfo.buildDirectProxy("test", 8888); 10695 lp.setHttpProxy(testProxyInfo); 10696 mMockVpn.sendLinkProperties(lp); 10697 waitForIdle(); 10698 // Proxy is set, so send a proxy broadcast. 10699 verify(mProxyTracker, times(1)).sendProxyBroadcast(); 10700 reset(mProxyTracker); 10701 10702 mMockVpn.setUids(vpnRanges); 10703 waitForIdle(); 10704 // Uid has changed and proxy is already set, so send a proxy broadcast. 10705 verify(mProxyTracker, times(1)).sendProxyBroadcast(); 10706 reset(mProxyTracker); 10707 10708 // Proxy is removed, send a proxy broadcast. 10709 lp.setHttpProxy(null); 10710 mMockVpn.sendLinkProperties(lp); 10711 waitForIdle(); 10712 verify(mProxyTracker, times(1)).sendProxyBroadcast(); 10713 reset(mProxyTracker); 10714 10715 // Proxy is added in WiFi(default network), setDefaultProxy will be called. 10716 final LinkProperties wifiLp = mCm.getLinkProperties(mWiFiNetworkAgent.getNetwork()); 10717 assertNotNull(wifiLp); 10718 wifiLp.setHttpProxy(testProxyInfo); 10719 mWiFiNetworkAgent.sendLinkProperties(wifiLp); 10720 waitForIdle(); 10721 verify(mProxyTracker, times(1)).setDefaultProxy(eq(testProxyInfo)); 10722 reset(mProxyTracker); 10723 } 10724 10725 @Test 10726 public void testProxyBroadcastWillBeSentWhenVpnHasProxyAndConnects() throws Exception { 10727 // Set up a WiFi network without proxy. 10728 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 10729 mWiFiNetworkAgent.connect(true); 10730 assertNull(mService.getProxyForNetwork(null)); 10731 assertNull(mCm.getDefaultProxy()); 10732 10733 final LinkProperties lp = new LinkProperties(); 10734 lp.setInterfaceName("tun0"); 10735 lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), null)); 10736 lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), null)); 10737 final ProxyInfo testProxyInfo = ProxyInfo.buildDirectProxy("test", 8888); 10738 lp.setHttpProxy(testProxyInfo); 10739 final UidRange vpnRange = PRIMARY_UIDRANGE; 10740 final Set<UidRange> vpnRanges = Collections.singleton(vpnRange); 10741 mMockVpn.setOwnerAndAdminUid(VPN_UID); 10742 mMockVpn.registerAgent(false, vpnRanges, lp); 10743 // In any case, the proxy broadcast won't be sent before VPN goes into CONNECTED state. 10744 // Otherwise, the app that calls ConnectivityManager#getDefaultProxy() when it receives the 10745 // proxy broadcast will get null. 10746 verify(mProxyTracker, never()).sendProxyBroadcast(); 10747 mMockVpn.connect(true /* validated */, true /* hasInternet */, false /* isStrictMode */); 10748 waitForIdle(); 10749 assertVpnUidRangesUpdated(true, vpnRanges, VPN_UID); 10750 // Vpn is connected with proxy, so the proxy broadcast will be sent to inform the apps to 10751 // update their proxy data. 10752 verify(mProxyTracker, times(1)).sendProxyBroadcast(); 10753 } 10754 10755 @Test 10756 public void testProxyBroadcastWillBeSentWhenTheProxyOfNonDefaultNetworkHasChanged() 10757 throws Exception { 10758 // Set up a CELLULAR network without proxy. 10759 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 10760 mCellNetworkAgent.connect(true); 10761 assertNull(mService.getProxyForNetwork(null)); 10762 assertNull(mCm.getDefaultProxy()); 10763 // CELLULAR network should be the default network. 10764 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 10765 10766 // Set up a WiFi network without proxy. 10767 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 10768 mWiFiNetworkAgent.connect(true); 10769 assertNull(mService.getProxyForNetwork(null)); 10770 assertNull(mCm.getDefaultProxy()); 10771 // WiFi network should be the default network. 10772 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 10773 // CELLULAR network is not the default network. 10774 assertNotEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 10775 10776 // CELLULAR network is not the system default network, but it might be a per-app default 10777 // network. The proxy broadcast should be sent once its proxy has changed. 10778 final LinkProperties cellularLp = new LinkProperties(); 10779 cellularLp.setInterfaceName(MOBILE_IFNAME); 10780 final ProxyInfo testProxyInfo = ProxyInfo.buildDirectProxy("test", 8888); 10781 cellularLp.setHttpProxy(testProxyInfo); 10782 mCellNetworkAgent.sendLinkProperties(cellularLp); 10783 waitForIdle(); 10784 verify(mProxyTracker, times(1)).sendProxyBroadcast(); 10785 } 10786 10787 @Test 10788 public void testInvalidRequestTypes() { 10789 final int[] invalidReqTypeInts = new int[]{-1, NetworkRequest.Type.NONE.ordinal(), 10790 NetworkRequest.Type.LISTEN.ordinal(), NetworkRequest.Type.values().length}; 10791 final NetworkCapabilities nc = new NetworkCapabilities().addTransportType(TRANSPORT_WIFI); 10792 10793 for (int reqTypeInt : invalidReqTypeInts) { 10794 assertThrows("Expect throws for invalid request type " + reqTypeInt, 10795 IllegalArgumentException.class, 10796 () -> mService.requestNetwork(Process.INVALID_UID, nc, reqTypeInt, null, 0, 10797 null, ConnectivityManager.TYPE_NONE, NetworkCallback.FLAG_NONE, 10798 mContext.getPackageName(), getAttributionTag()) 10799 ); 10800 } 10801 } 10802 10803 @Test 10804 public void testKeepConnected() throws Exception { 10805 setAlwaysOnNetworks(false); 10806 registerDefaultNetworkCallbacks(); 10807 final TestNetworkCallback allNetworksCb = new TestNetworkCallback(); 10808 final NetworkRequest allNetworksRequest = new NetworkRequest.Builder().clearCapabilities() 10809 .build(); 10810 mCm.registerNetworkCallback(allNetworksRequest, allNetworksCb); 10811 10812 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 10813 mCellNetworkAgent.connect(true /* validated */); 10814 10815 mDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 10816 allNetworksCb.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 10817 10818 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 10819 mWiFiNetworkAgent.connect(true /* validated */); 10820 10821 mDefaultNetworkCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent); 10822 // While the default callback doesn't see the network before it's validated, the listen 10823 // sees the network come up and validate later 10824 allNetworksCb.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 10825 allNetworksCb.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent); 10826 allNetworksCb.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent); 10827 allNetworksCb.expectCallback(CallbackEntry.LOST, mCellNetworkAgent, 10828 TEST_LINGER_DELAY_MS * 2); 10829 10830 // The cell network has disconnected (see LOST above) because it was outscored and 10831 // had no requests (see setAlwaysOnNetworks(false) above) 10832 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 10833 final NetworkScore score = new NetworkScore.Builder().setLegacyInt(30).build(); 10834 mCellNetworkAgent.setScore(score); 10835 mCellNetworkAgent.connect(false /* validated */); 10836 10837 // The cell network gets torn down right away. 10838 allNetworksCb.expectAvailableCallbacksUnvalidated(mCellNetworkAgent); 10839 allNetworksCb.expectCallback(CallbackEntry.LOST, mCellNetworkAgent, 10840 TEST_NASCENT_DELAY_MS * 2); 10841 allNetworksCb.assertNoCallback(); 10842 10843 // Now create a cell network with KEEP_CONNECTED_FOR_HANDOVER and make sure it's 10844 // not disconnected immediately when outscored. 10845 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 10846 final NetworkScore scoreKeepup = new NetworkScore.Builder().setLegacyInt(30) 10847 .setKeepConnectedReason(KEEP_CONNECTED_FOR_HANDOVER).build(); 10848 mCellNetworkAgent.setScore(scoreKeepup); 10849 mCellNetworkAgent.connect(true /* validated */); 10850 10851 allNetworksCb.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 10852 mDefaultNetworkCallback.assertNoCallback(); 10853 10854 mWiFiNetworkAgent.disconnect(); 10855 10856 allNetworksCb.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 10857 mDefaultNetworkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 10858 mDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellNetworkAgent); 10859 10860 // Reconnect a WiFi network and make sure the cell network is still not torn down. 10861 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 10862 mWiFiNetworkAgent.connect(true /* validated */); 10863 10864 allNetworksCb.expectAvailableThenValidatedCallbacks(mWiFiNetworkAgent); 10865 mDefaultNetworkCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent); 10866 10867 // Now remove the reason to keep connected and make sure the network lingers and is 10868 // torn down. 10869 mCellNetworkAgent.setScore(new NetworkScore.Builder().setLegacyInt(30).build()); 10870 allNetworksCb.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent, 10871 TEST_NASCENT_DELAY_MS * 2); 10872 allNetworksCb.expectCallback(CallbackEntry.LOST, mCellNetworkAgent, 10873 TEST_LINGER_DELAY_MS * 2); 10874 mDefaultNetworkCallback.assertNoCallback(); 10875 10876 mCm.unregisterNetworkCallback(allNetworksCb); 10877 // mDefaultNetworkCallback will be unregistered by tearDown() 10878 } 10879 10880 private class QosCallbackMockHelper { 10881 @NonNull public final QosFilter mFilter; 10882 @NonNull public final IQosCallback mCallback; 10883 @NonNull public final TestNetworkAgentWrapper mAgentWrapper; 10884 @NonNull private final List<IQosCallback> mCallbacks = new ArrayList(); 10885 10886 QosCallbackMockHelper() throws Exception { 10887 Log.d(TAG, "QosCallbackMockHelper: "); 10888 mFilter = mock(QosFilter.class); 10889 10890 // Ensure the network is disconnected before anything else occurs 10891 assertNull(mCellNetworkAgent); 10892 10893 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 10894 mCellNetworkAgent.connect(true); 10895 10896 verifyActiveNetwork(TRANSPORT_CELLULAR); 10897 waitForIdle(); 10898 final Network network = mCellNetworkAgent.getNetwork(); 10899 10900 final Pair<IQosCallback, IBinder> pair = createQosCallback(); 10901 mCallback = pair.first; 10902 10903 when(mFilter.getNetwork()).thenReturn(network); 10904 when(mFilter.validate()).thenReturn(QosCallbackException.EX_TYPE_FILTER_NONE); 10905 mAgentWrapper = mCellNetworkAgent; 10906 } 10907 10908 void registerQosCallback(@NonNull final QosFilter filter, 10909 @NonNull final IQosCallback callback) { 10910 mCallbacks.add(callback); 10911 final NetworkAgentInfo nai = 10912 mService.getNetworkAgentInfoForNetwork(filter.getNetwork()); 10913 mService.registerQosCallbackInternal(filter, callback, nai); 10914 } 10915 10916 void tearDown() { 10917 for (int i = 0; i < mCallbacks.size(); i++) { 10918 mService.unregisterQosCallback(mCallbacks.get(i)); 10919 } 10920 } 10921 } 10922 10923 private Pair<IQosCallback, IBinder> createQosCallback() { 10924 final IQosCallback callback = mock(IQosCallback.class); 10925 final IBinder binder = mock(Binder.class); 10926 when(callback.asBinder()).thenReturn(binder); 10927 when(binder.isBinderAlive()).thenReturn(true); 10928 return new Pair<>(callback, binder); 10929 } 10930 10931 10932 @Test 10933 public void testQosCallbackRegistration() throws Exception { 10934 mQosCallbackMockHelper = new QosCallbackMockHelper(); 10935 final NetworkAgentWrapper wrapper = mQosCallbackMockHelper.mAgentWrapper; 10936 10937 when(mQosCallbackMockHelper.mFilter.validate()) 10938 .thenReturn(QosCallbackException.EX_TYPE_FILTER_NONE); 10939 mQosCallbackMockHelper.registerQosCallback( 10940 mQosCallbackMockHelper.mFilter, mQosCallbackMockHelper.mCallback); 10941 10942 final NetworkAgentWrapper.CallbackType.OnQosCallbackRegister cbRegister1 = 10943 (NetworkAgentWrapper.CallbackType.OnQosCallbackRegister) 10944 wrapper.getCallbackHistory().poll(1000, x -> true); 10945 assertNotNull(cbRegister1); 10946 10947 final int registerCallbackId = cbRegister1.mQosCallbackId; 10948 mService.unregisterQosCallback(mQosCallbackMockHelper.mCallback); 10949 final NetworkAgentWrapper.CallbackType.OnQosCallbackUnregister cbUnregister; 10950 cbUnregister = (NetworkAgentWrapper.CallbackType.OnQosCallbackUnregister) 10951 wrapper.getCallbackHistory().poll(1000, x -> true); 10952 assertNotNull(cbUnregister); 10953 assertEquals(registerCallbackId, cbUnregister.mQosCallbackId); 10954 assertNull(wrapper.getCallbackHistory().poll(200, x -> true)); 10955 } 10956 10957 @Test 10958 public void testQosCallbackNoRegistrationOnValidationError() throws Exception { 10959 mQosCallbackMockHelper = new QosCallbackMockHelper(); 10960 10961 when(mQosCallbackMockHelper.mFilter.validate()) 10962 .thenReturn(QosCallbackException.EX_TYPE_FILTER_NETWORK_RELEASED); 10963 mQosCallbackMockHelper.registerQosCallback( 10964 mQosCallbackMockHelper.mFilter, mQosCallbackMockHelper.mCallback); 10965 waitForIdle(); 10966 verify(mQosCallbackMockHelper.mCallback) 10967 .onError(eq(QosCallbackException.EX_TYPE_FILTER_NETWORK_RELEASED)); 10968 } 10969 10970 @Test 10971 public void testQosCallbackAvailableAndLost() throws Exception { 10972 mQosCallbackMockHelper = new QosCallbackMockHelper(); 10973 final int sessionId = 10; 10974 final int qosCallbackId = 1; 10975 10976 when(mQosCallbackMockHelper.mFilter.validate()) 10977 .thenReturn(QosCallbackException.EX_TYPE_FILTER_NONE); 10978 mQosCallbackMockHelper.registerQosCallback( 10979 mQosCallbackMockHelper.mFilter, mQosCallbackMockHelper.mCallback); 10980 waitForIdle(); 10981 10982 final EpsBearerQosSessionAttributes attributes = new EpsBearerQosSessionAttributes( 10983 1, 2, 3, 4, 5, new ArrayList<>()); 10984 mQosCallbackMockHelper.mAgentWrapper.getNetworkAgent() 10985 .sendQosSessionAvailable(qosCallbackId, sessionId, attributes); 10986 waitForIdle(); 10987 10988 verify(mQosCallbackMockHelper.mCallback).onQosEpsBearerSessionAvailable(argThat(session -> 10989 session.getSessionId() == sessionId 10990 && session.getSessionType() == QosSession.TYPE_EPS_BEARER), eq(attributes)); 10991 10992 mQosCallbackMockHelper.mAgentWrapper.getNetworkAgent() 10993 .sendQosSessionLost(qosCallbackId, sessionId, QosSession.TYPE_EPS_BEARER); 10994 waitForIdle(); 10995 verify(mQosCallbackMockHelper.mCallback).onQosSessionLost(argThat(session -> 10996 session.getSessionId() == sessionId 10997 && session.getSessionType() == QosSession.TYPE_EPS_BEARER)); 10998 } 10999 11000 @Test 11001 public void testNrQosCallbackAvailableAndLost() throws Exception { 11002 mQosCallbackMockHelper = new QosCallbackMockHelper(); 11003 final int sessionId = 10; 11004 final int qosCallbackId = 1; 11005 11006 when(mQosCallbackMockHelper.mFilter.validate()) 11007 .thenReturn(QosCallbackException.EX_TYPE_FILTER_NONE); 11008 mQosCallbackMockHelper.registerQosCallback( 11009 mQosCallbackMockHelper.mFilter, mQosCallbackMockHelper.mCallback); 11010 waitForIdle(); 11011 11012 final NrQosSessionAttributes attributes = new NrQosSessionAttributes( 11013 1, 2, 3, 4, 5, 6, 7, new ArrayList<>()); 11014 mQosCallbackMockHelper.mAgentWrapper.getNetworkAgent() 11015 .sendQosSessionAvailable(qosCallbackId, sessionId, attributes); 11016 waitForIdle(); 11017 11018 verify(mQosCallbackMockHelper.mCallback).onNrQosSessionAvailable(argThat(session -> 11019 session.getSessionId() == sessionId 11020 && session.getSessionType() == QosSession.TYPE_NR_BEARER), eq(attributes)); 11021 11022 mQosCallbackMockHelper.mAgentWrapper.getNetworkAgent() 11023 .sendQosSessionLost(qosCallbackId, sessionId, QosSession.TYPE_NR_BEARER); 11024 waitForIdle(); 11025 verify(mQosCallbackMockHelper.mCallback).onQosSessionLost(argThat(session -> 11026 session.getSessionId() == sessionId 11027 && session.getSessionType() == QosSession.TYPE_NR_BEARER)); 11028 } 11029 11030 @Test 11031 public void testQosCallbackTooManyRequests() throws Exception { 11032 mQosCallbackMockHelper = new QosCallbackMockHelper(); 11033 11034 when(mQosCallbackMockHelper.mFilter.validate()) 11035 .thenReturn(QosCallbackException.EX_TYPE_FILTER_NONE); 11036 for (int i = 0; i < 100; i++) { 11037 final Pair<IQosCallback, IBinder> pair = createQosCallback(); 11038 11039 try { 11040 mQosCallbackMockHelper.registerQosCallback( 11041 mQosCallbackMockHelper.mFilter, pair.first); 11042 } catch (ServiceSpecificException e) { 11043 assertEquals(e.errorCode, ConnectivityManager.Errors.TOO_MANY_REQUESTS); 11044 if (i < 50) { 11045 fail("TOO_MANY_REQUESTS thrown too early, the count is " + i); 11046 } 11047 11048 // As long as there is at least 50 requests, it is safe to assume it works. 11049 // Note: The count isn't being tested precisely against 100 because the counter 11050 // is shared with request network. 11051 return; 11052 } 11053 } 11054 fail("TOO_MANY_REQUESTS never thrown"); 11055 } 11056 11057 private void mockGetApplicationInfo(@NonNull final String packageName, final int uid) { 11058 mockGetApplicationInfo(packageName, uid, PRIMARY_USER_HANDLE); 11059 } 11060 11061 private void mockGetApplicationInfo(@NonNull final String packageName, final int uid, 11062 @NonNull final UserHandle user) { 11063 final ApplicationInfo applicationInfo = new ApplicationInfo(); 11064 applicationInfo.uid = uid; 11065 try { 11066 when(mPackageManager.getApplicationInfoAsUser(eq(packageName), anyInt(), eq(user))) 11067 .thenReturn(applicationInfo); 11068 } catch (Exception e) { 11069 fail(e.getMessage()); 11070 } 11071 } 11072 11073 private void mockGetApplicationInfoThrowsNameNotFound(@NonNull final String packageName, 11074 @NonNull final UserHandle user) 11075 throws Exception { 11076 when(mPackageManager.getApplicationInfoAsUser(eq(packageName), anyInt(), eq(user))) 11077 .thenThrow(new PackageManager.NameNotFoundException(packageName)); 11078 } 11079 11080 private void mockHasSystemFeature(@NonNull final String featureName, final boolean hasFeature) { 11081 when(mPackageManager.hasSystemFeature(eq(featureName))) 11082 .thenReturn(hasFeature); 11083 } 11084 11085 private Range<Integer> getNriFirstUidRange(@NonNull final NetworkRequestInfo nri) { 11086 return nri.mRequests.get(0).networkCapabilities.getUids().iterator().next(); 11087 } 11088 11089 private OemNetworkPreferences createDefaultOemNetworkPreferences( 11090 @OemNetworkPreferences.OemNetworkPreference final int preference) { 11091 // Arrange PackageManager mocks 11092 mockGetApplicationInfo(TEST_PACKAGE_NAME, TEST_PACKAGE_UID); 11093 11094 // Build OemNetworkPreferences object 11095 return new OemNetworkPreferences.Builder() 11096 .addNetworkPreference(TEST_PACKAGE_NAME, preference) 11097 .build(); 11098 } 11099 11100 @Test 11101 public void testOemNetworkRequestFactoryPreferenceUninitializedThrowsError() { 11102 @OemNetworkPreferences.OemNetworkPreference final int prefToTest = 11103 OEM_NETWORK_PREFERENCE_UNINITIALIZED; 11104 11105 // Act on OemNetworkRequestFactory.createNrisFromOemNetworkPreferences() 11106 assertThrows(IllegalArgumentException.class, 11107 () -> mService.new OemNetworkRequestFactory() 11108 .createNrisFromOemNetworkPreferences( 11109 createDefaultOemNetworkPreferences(prefToTest))); 11110 } 11111 11112 @Test 11113 public void testOemNetworkRequestFactoryPreferenceOemPaid() 11114 throws Exception { 11115 // Expectations 11116 final int expectedNumOfNris = 1; 11117 final int expectedNumOfRequests = 3; 11118 11119 @OemNetworkPreferences.OemNetworkPreference final int prefToTest = 11120 OEM_NETWORK_PREFERENCE_OEM_PAID; 11121 11122 // Act on OemNetworkRequestFactory.createNrisFromOemNetworkPreferences() 11123 final ArraySet<NetworkRequestInfo> nris = 11124 mService.new OemNetworkRequestFactory() 11125 .createNrisFromOemNetworkPreferences( 11126 createDefaultOemNetworkPreferences(prefToTest)); 11127 final NetworkRequestInfo nri = nris.iterator().next(); 11128 assertEquals(PREFERENCE_PRIORITY_OEM, nri.mPreferencePriority); 11129 final List<NetworkRequest> mRequests = nri.mRequests; 11130 assertEquals(expectedNumOfNris, nris.size()); 11131 assertEquals(expectedNumOfRequests, mRequests.size()); 11132 assertTrue(mRequests.get(0).isListen()); 11133 assertTrue(mRequests.get(0).hasCapability(NET_CAPABILITY_NOT_METERED)); 11134 assertTrue(mRequests.get(0).hasCapability(NET_CAPABILITY_VALIDATED)); 11135 assertTrue(mRequests.get(1).isRequest()); 11136 assertTrue(mRequests.get(1).hasCapability(NET_CAPABILITY_OEM_PAID)); 11137 assertEquals(NetworkRequest.Type.TRACK_DEFAULT, mRequests.get(2).type); 11138 assertTrue(mService.getDefaultRequest().networkCapabilities.equalsNetCapabilities( 11139 mRequests.get(2).networkCapabilities)); 11140 } 11141 11142 @Test 11143 public void testOemNetworkRequestFactoryPreferenceOemPaidNoFallback() 11144 throws Exception { 11145 // Expectations 11146 final int expectedNumOfNris = 1; 11147 final int expectedNumOfRequests = 2; 11148 11149 @OemNetworkPreferences.OemNetworkPreference final int prefToTest = 11150 OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK; 11151 11152 // Act on OemNetworkRequestFactory.createNrisFromOemNetworkPreferences() 11153 final ArraySet<NetworkRequestInfo> nris = 11154 mService.new OemNetworkRequestFactory() 11155 .createNrisFromOemNetworkPreferences( 11156 createDefaultOemNetworkPreferences(prefToTest)); 11157 final NetworkRequestInfo nri = nris.iterator().next(); 11158 assertEquals(PREFERENCE_PRIORITY_OEM, nri.mPreferencePriority); 11159 final List<NetworkRequest> mRequests = nri.mRequests; 11160 assertEquals(expectedNumOfNris, nris.size()); 11161 assertEquals(expectedNumOfRequests, mRequests.size()); 11162 assertTrue(mRequests.get(0).isListen()); 11163 assertTrue(mRequests.get(0).hasCapability(NET_CAPABILITY_NOT_METERED)); 11164 assertTrue(mRequests.get(0).hasCapability(NET_CAPABILITY_VALIDATED)); 11165 assertTrue(mRequests.get(1).isRequest()); 11166 assertTrue(mRequests.get(1).hasCapability(NET_CAPABILITY_OEM_PAID)); 11167 } 11168 11169 @Test 11170 public void testOemNetworkRequestFactoryPreferenceOemPaidOnly() 11171 throws Exception { 11172 // Expectations 11173 final int expectedNumOfNris = 1; 11174 final int expectedNumOfRequests = 1; 11175 11176 @OemNetworkPreferences.OemNetworkPreference final int prefToTest = 11177 OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY; 11178 11179 // Act on OemNetworkRequestFactory.createNrisFromOemNetworkPreferences() 11180 final ArraySet<NetworkRequestInfo> nris = 11181 mService.new OemNetworkRequestFactory() 11182 .createNrisFromOemNetworkPreferences( 11183 createDefaultOemNetworkPreferences(prefToTest)); 11184 final NetworkRequestInfo nri = nris.iterator().next(); 11185 assertEquals(PREFERENCE_PRIORITY_OEM, nri.mPreferencePriority); 11186 final List<NetworkRequest> mRequests = nri.mRequests; 11187 assertEquals(expectedNumOfNris, nris.size()); 11188 assertEquals(expectedNumOfRequests, mRequests.size()); 11189 assertTrue(mRequests.get(0).isRequest()); 11190 assertTrue(mRequests.get(0).hasCapability(NET_CAPABILITY_OEM_PAID)); 11191 } 11192 11193 @Test 11194 public void testOemNetworkRequestFactoryPreferenceOemPrivateOnly() 11195 throws Exception { 11196 // Expectations 11197 final int expectedNumOfNris = 1; 11198 final int expectedNumOfRequests = 1; 11199 11200 @OemNetworkPreferences.OemNetworkPreference final int prefToTest = 11201 OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY; 11202 11203 // Act on OemNetworkRequestFactory.createNrisFromOemNetworkPreferences() 11204 final ArraySet<NetworkRequestInfo> nris = 11205 mService.new OemNetworkRequestFactory() 11206 .createNrisFromOemNetworkPreferences( 11207 createDefaultOemNetworkPreferences(prefToTest)); 11208 final NetworkRequestInfo nri = nris.iterator().next(); 11209 assertEquals(PREFERENCE_PRIORITY_OEM, nri.mPreferencePriority); 11210 final List<NetworkRequest> mRequests = nri.mRequests; 11211 assertEquals(expectedNumOfNris, nris.size()); 11212 assertEquals(expectedNumOfRequests, mRequests.size()); 11213 assertTrue(mRequests.get(0).isRequest()); 11214 assertTrue(mRequests.get(0).hasCapability(NET_CAPABILITY_OEM_PRIVATE)); 11215 assertFalse(mRequests.get(0).hasCapability(NET_CAPABILITY_OEM_PAID)); 11216 } 11217 11218 @Test 11219 public void testOemNetworkRequestFactoryCreatesCorrectNumOfNris() 11220 throws Exception { 11221 // Expectations 11222 final int expectedNumOfNris = 2; 11223 11224 // Arrange PackageManager mocks 11225 final String testPackageName2 = "com.google.apps.dialer"; 11226 mockGetApplicationInfo(TEST_PACKAGE_NAME, TEST_PACKAGE_UID); 11227 mockGetApplicationInfo(testPackageName2, TEST_PACKAGE_UID); 11228 11229 // Build OemNetworkPreferences object 11230 final int testOemPref = OEM_NETWORK_PREFERENCE_OEM_PAID; 11231 final int testOemPref2 = OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK; 11232 final OemNetworkPreferences pref = new OemNetworkPreferences.Builder() 11233 .addNetworkPreference(TEST_PACKAGE_NAME, testOemPref) 11234 .addNetworkPreference(testPackageName2, testOemPref2) 11235 .build(); 11236 11237 // Act on OemNetworkRequestFactory.createNrisFromOemNetworkPreferences() 11238 final ArraySet<NetworkRequestInfo> nris = 11239 mService.new OemNetworkRequestFactory().createNrisFromOemNetworkPreferences(pref); 11240 11241 assertNotNull(nris); 11242 assertEquals(expectedNumOfNris, nris.size()); 11243 } 11244 11245 @Test 11246 public void testOemNetworkRequestFactoryMultiplePrefsCorrectlySetsUids() 11247 throws Exception { 11248 // Arrange PackageManager mocks 11249 final String testPackageName2 = "com.google.apps.dialer"; 11250 final int testPackageNameUid2 = 456; 11251 mockGetApplicationInfo(TEST_PACKAGE_NAME, TEST_PACKAGE_UID); 11252 mockGetApplicationInfo(testPackageName2, testPackageNameUid2); 11253 11254 // Build OemNetworkPreferences object 11255 final int testOemPref = OEM_NETWORK_PREFERENCE_OEM_PAID; 11256 final int testOemPref2 = OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK; 11257 final OemNetworkPreferences pref = new OemNetworkPreferences.Builder() 11258 .addNetworkPreference(TEST_PACKAGE_NAME, testOemPref) 11259 .addNetworkPreference(testPackageName2, testOemPref2) 11260 .build(); 11261 11262 // Act on OemNetworkRequestFactory.createNrisFromOemNetworkPreferences() 11263 final List<NetworkRequestInfo> nris = 11264 new ArrayList<>( 11265 mService.new OemNetworkRequestFactory().createNrisFromOemNetworkPreferences( 11266 pref)); 11267 11268 // Sort by uid to access nris by index 11269 nris.sort(Comparator.comparingInt(nri -> getNriFirstUidRange(nri).getLower())); 11270 assertEquals(TEST_PACKAGE_UID, (int) getNriFirstUidRange(nris.get(0)).getLower()); 11271 assertEquals(TEST_PACKAGE_UID, (int) getNriFirstUidRange(nris.get(0)).getUpper()); 11272 assertEquals(testPackageNameUid2, (int) getNriFirstUidRange(nris.get(1)).getLower()); 11273 assertEquals(testPackageNameUid2, (int) getNriFirstUidRange(nris.get(1)).getUpper()); 11274 } 11275 11276 @Test 11277 public void testOemNetworkRequestFactoryMultipleUsersSetsUids() 11278 throws Exception { 11279 // Arrange users 11280 final int secondUserTestPackageUid = UserHandle.getUid(SECONDARY_USER, TEST_PACKAGE_UID); 11281 final int thirdUserTestPackageUid = UserHandle.getUid(TERTIARY_USER, TEST_PACKAGE_UID); 11282 when(mUserManager.getUserHandles(anyBoolean())).thenReturn( 11283 Arrays.asList(PRIMARY_USER_HANDLE, SECONDARY_USER_HANDLE, TERTIARY_USER_HANDLE)); 11284 11285 // Arrange PackageManager mocks testing for users who have and don't have a package. 11286 mockGetApplicationInfoThrowsNameNotFound(TEST_PACKAGE_NAME, PRIMARY_USER_HANDLE); 11287 mockGetApplicationInfo(TEST_PACKAGE_NAME, secondUserTestPackageUid, SECONDARY_USER_HANDLE); 11288 mockGetApplicationInfo(TEST_PACKAGE_NAME, thirdUserTestPackageUid, TERTIARY_USER_HANDLE); 11289 11290 // Build OemNetworkPreferences object 11291 final int testOemPref = OEM_NETWORK_PREFERENCE_OEM_PAID; 11292 final OemNetworkPreferences pref = new OemNetworkPreferences.Builder() 11293 .addNetworkPreference(TEST_PACKAGE_NAME, testOemPref) 11294 .build(); 11295 11296 // Act on OemNetworkRequestFactory.createNrisFromOemNetworkPreferences() 11297 final List<NetworkRequestInfo> nris = 11298 new ArrayList<>( 11299 mService.new OemNetworkRequestFactory().createNrisFromOemNetworkPreferences( 11300 pref)); 11301 11302 // UIDs for users with installed packages should be present. 11303 // Three users exist, but only two have the test package installed. 11304 final int expectedUidSize = 2; 11305 final List<Range<Integer>> uids = 11306 new ArrayList<>(nris.get(0).mRequests.get(0).networkCapabilities.getUids()); 11307 assertEquals(expectedUidSize, uids.size()); 11308 11309 // Sort by uid to access nris by index 11310 uids.sort(Comparator.comparingInt(uid -> uid.getLower())); 11311 assertEquals(secondUserTestPackageUid, (int) uids.get(0).getLower()); 11312 assertEquals(secondUserTestPackageUid, (int) uids.get(0).getUpper()); 11313 assertEquals(thirdUserTestPackageUid, (int) uids.get(1).getLower()); 11314 assertEquals(thirdUserTestPackageUid, (int) uids.get(1).getUpper()); 11315 } 11316 11317 @Test 11318 public void testOemNetworkRequestFactoryAddsPackagesToCorrectPreference() 11319 throws Exception { 11320 // Expectations 11321 final int expectedNumOfNris = 1; 11322 final int expectedNumOfAppUids = 2; 11323 11324 // Arrange PackageManager mocks 11325 final String testPackageName2 = "com.google.apps.dialer"; 11326 final int testPackageNameUid2 = 456; 11327 mockGetApplicationInfo(TEST_PACKAGE_NAME, TEST_PACKAGE_UID); 11328 mockGetApplicationInfo(testPackageName2, testPackageNameUid2); 11329 11330 // Build OemNetworkPreferences object 11331 final int testOemPref = OEM_NETWORK_PREFERENCE_OEM_PAID; 11332 final OemNetworkPreferences pref = new OemNetworkPreferences.Builder() 11333 .addNetworkPreference(TEST_PACKAGE_NAME, testOemPref) 11334 .addNetworkPreference(testPackageName2, testOemPref) 11335 .build(); 11336 11337 // Act on OemNetworkRequestFactory.createNrisFromOemNetworkPreferences() 11338 final ArraySet<NetworkRequestInfo> nris = 11339 mService.new OemNetworkRequestFactory().createNrisFromOemNetworkPreferences(pref); 11340 11341 assertEquals(expectedNumOfNris, nris.size()); 11342 assertEquals(expectedNumOfAppUids, 11343 nris.iterator().next().mRequests.get(0).networkCapabilities.getUids().size()); 11344 } 11345 11346 @Test 11347 public void testSetOemNetworkPreferenceNullListenerAndPrefParamThrowsNpe() { 11348 mockHasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, true); 11349 11350 // Act on ConnectivityService.setOemNetworkPreference() 11351 assertThrows(NullPointerException.class, 11352 () -> mService.setOemNetworkPreference( 11353 null, 11354 null)); 11355 } 11356 11357 @Test 11358 public void testSetOemNetworkPreferenceFailsForNonAutomotive() 11359 throws Exception { 11360 mockHasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, false); 11361 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 11362 OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY; 11363 11364 // Act on ConnectivityService.setOemNetworkPreference() 11365 assertThrows(UnsupportedOperationException.class, 11366 () -> mService.setOemNetworkPreference( 11367 createDefaultOemNetworkPreferences(networkPref), 11368 null)); 11369 } 11370 11371 @Test 11372 public void testSetOemNetworkPreferenceFailsForTestRequestWithoutPermission() { 11373 // Calling setOemNetworkPreference() with a test pref requires the permission 11374 // MANAGE_TEST_NETWORKS. 11375 mockHasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, false); 11376 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 11377 OEM_NETWORK_PREFERENCE_TEST; 11378 11379 // Act on ConnectivityService.setOemNetworkPreference() 11380 assertThrows(SecurityException.class, 11381 () -> mService.setOemNetworkPreference( 11382 createDefaultOemNetworkPreferences(networkPref), 11383 null)); 11384 } 11385 11386 @Test 11387 public void testSetOemNetworkPreferenceFailsForInvalidTestRequest() { 11388 assertSetOemNetworkPreferenceFailsForInvalidTestRequest(OEM_NETWORK_PREFERENCE_TEST); 11389 } 11390 11391 @Test 11392 public void testSetOemNetworkPreferenceFailsForInvalidTestOnlyRequest() { 11393 assertSetOemNetworkPreferenceFailsForInvalidTestRequest(OEM_NETWORK_PREFERENCE_TEST_ONLY); 11394 } 11395 11396 private void assertSetOemNetworkPreferenceFailsForInvalidTestRequest( 11397 @OemNetworkPreferences.OemNetworkPreference final int oemNetworkPreferenceForTest) { 11398 mockHasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, true); 11399 final String secondPackage = "does.not.matter"; 11400 11401 // A valid test request would only have a single mapping. 11402 final OemNetworkPreferences pref = new OemNetworkPreferences.Builder() 11403 .addNetworkPreference(TEST_PACKAGE_NAME, oemNetworkPreferenceForTest) 11404 .addNetworkPreference(secondPackage, oemNetworkPreferenceForTest) 11405 .build(); 11406 11407 // Act on ConnectivityService.setOemNetworkPreference() 11408 assertThrows(IllegalArgumentException.class, 11409 () -> mService.setOemNetworkPreference(pref, null)); 11410 } 11411 11412 private void setOemNetworkPreferenceAgentConnected(final int transportType, 11413 final boolean connectAgent) throws Exception { 11414 switch(transportType) { 11415 // Corresponds to a metered cellular network. Will be used for the default network. 11416 case TRANSPORT_CELLULAR: 11417 if (!connectAgent) { 11418 mCellNetworkAgent.disconnect(); 11419 break; 11420 } 11421 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 11422 mCellNetworkAgent.removeCapability(NET_CAPABILITY_NOT_METERED); 11423 mCellNetworkAgent.connect(true); 11424 break; 11425 // Corresponds to a restricted ethernet network with OEM_PAID/OEM_PRIVATE. 11426 case TRANSPORT_ETHERNET: 11427 if (!connectAgent) { 11428 stopOemManagedNetwork(); 11429 break; 11430 } 11431 startOemManagedNetwork(true); 11432 break; 11433 // Corresponds to unmetered Wi-Fi. 11434 case TRANSPORT_WIFI: 11435 if (!connectAgent) { 11436 mWiFiNetworkAgent.disconnect(); 11437 break; 11438 } 11439 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 11440 mWiFiNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED); 11441 mWiFiNetworkAgent.connect(true); 11442 break; 11443 default: 11444 throw new AssertionError("Unsupported transport type passed in."); 11445 11446 } 11447 waitForIdle(); 11448 } 11449 11450 private void startOemManagedNetwork(final boolean isOemPaid) throws Exception { 11451 mEthernetNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_ETHERNET); 11452 mEthernetNetworkAgent.addCapability( 11453 isOemPaid ? NET_CAPABILITY_OEM_PAID : NET_CAPABILITY_OEM_PRIVATE); 11454 mEthernetNetworkAgent.removeCapability(NET_CAPABILITY_NOT_RESTRICTED); 11455 mEthernetNetworkAgent.connect(true); 11456 } 11457 11458 private void stopOemManagedNetwork() { 11459 mEthernetNetworkAgent.disconnect(); 11460 waitForIdle(); 11461 } 11462 11463 private void verifyMultipleDefaultNetworksTracksCorrectly( 11464 final int expectedOemRequestsSize, 11465 @NonNull final Network expectedDefaultNetwork, 11466 @NonNull final Network expectedPerAppNetwork) { 11467 // The current test setup assumes two tracked default network requests; one for the default 11468 // network and the other for the OEM network preference being tested. This will be validated 11469 // each time to confirm it doesn't change under test. 11470 final int expectedDefaultNetworkRequestsSize = 2; 11471 assertEquals(expectedDefaultNetworkRequestsSize, mService.mDefaultNetworkRequests.size()); 11472 for (final NetworkRequestInfo defaultRequest : mService.mDefaultNetworkRequests) { 11473 final Network defaultNetwork = defaultRequest.getSatisfier() == null 11474 ? null : defaultRequest.getSatisfier().network(); 11475 // If this is the default request. 11476 if (defaultRequest == mService.mDefaultRequest) { 11477 assertEquals( 11478 expectedDefaultNetwork, 11479 defaultNetwork); 11480 // Make sure this value doesn't change. 11481 assertEquals(1, defaultRequest.mRequests.size()); 11482 continue; 11483 } 11484 assertEquals(expectedPerAppNetwork, defaultNetwork); 11485 assertEquals(expectedOemRequestsSize, defaultRequest.mRequests.size()); 11486 } 11487 verifyMultipleDefaultCallbacks(expectedDefaultNetwork, expectedPerAppNetwork); 11488 } 11489 11490 /** 11491 * Verify default callbacks for 'available' fire as expected. This will only run if 11492 * registerDefaultNetworkCallbacks() was executed prior and will only be different if the 11493 * setOemNetworkPreference() per-app API was used for the current process. 11494 * @param expectedSystemDefault the expected network for the system default. 11495 * @param expectedPerAppDefault the expected network for the current process's default. 11496 */ 11497 private void verifyMultipleDefaultCallbacks( 11498 @NonNull final Network expectedSystemDefault, 11499 @NonNull final Network expectedPerAppDefault) { 11500 if (null != mSystemDefaultNetworkCallback && null != expectedSystemDefault 11501 && mService.mNoServiceNetwork.network() != expectedSystemDefault) { 11502 // getLastAvailableNetwork() is used as this method can be called successively with 11503 // the same network to validate therefore expectAvailableThenValidatedCallbacks 11504 // can't be used. 11505 assertEquals(mSystemDefaultNetworkCallback.getLastAvailableNetwork(), 11506 expectedSystemDefault); 11507 } 11508 if (null != mDefaultNetworkCallback && null != expectedPerAppDefault 11509 && mService.mNoServiceNetwork.network() != expectedPerAppDefault) { 11510 assertEquals(mDefaultNetworkCallback.getLastAvailableNetwork(), 11511 expectedPerAppDefault); 11512 } 11513 } 11514 11515 private void registerDefaultNetworkCallbacks() { 11516 if (mSystemDefaultNetworkCallback != null || mDefaultNetworkCallback != null 11517 || mProfileDefaultNetworkCallback != null 11518 || mTestPackageDefaultNetworkCallback != null) { 11519 throw new IllegalStateException("Default network callbacks already registered"); 11520 } 11521 11522 // Using Manifest.permission.NETWORK_SETTINGS for registerSystemDefaultNetworkCallback() 11523 mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_GRANTED); 11524 mSystemDefaultNetworkCallback = new TestNetworkCallback(); 11525 mDefaultNetworkCallback = new TestNetworkCallback(); 11526 mProfileDefaultNetworkCallback = new TestNetworkCallback(); 11527 mTestPackageDefaultNetworkCallback = new TestNetworkCallback(); 11528 mCm.registerSystemDefaultNetworkCallback(mSystemDefaultNetworkCallback, 11529 new Handler(ConnectivityThread.getInstanceLooper())); 11530 mCm.registerDefaultNetworkCallback(mDefaultNetworkCallback); 11531 registerDefaultNetworkCallbackAsUid(mProfileDefaultNetworkCallback, 11532 TEST_WORK_PROFILE_APP_UID); 11533 registerDefaultNetworkCallbackAsUid(mTestPackageDefaultNetworkCallback, TEST_PACKAGE_UID); 11534 // TODO: test using ConnectivityManager#registerDefaultNetworkCallbackAsUid as well. 11535 mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_DENIED); 11536 } 11537 11538 private void unregisterDefaultNetworkCallbacks() { 11539 if (null != mDefaultNetworkCallback) { 11540 mCm.unregisterNetworkCallback(mDefaultNetworkCallback); 11541 } 11542 if (null != mSystemDefaultNetworkCallback) { 11543 mCm.unregisterNetworkCallback(mSystemDefaultNetworkCallback); 11544 } 11545 if (null != mProfileDefaultNetworkCallback) { 11546 mCm.unregisterNetworkCallback(mProfileDefaultNetworkCallback); 11547 } 11548 if (null != mTestPackageDefaultNetworkCallback) { 11549 mCm.unregisterNetworkCallback(mTestPackageDefaultNetworkCallback); 11550 } 11551 } 11552 11553 private void setupMultipleDefaultNetworksForOemNetworkPreferenceNotCurrentUidTest( 11554 @OemNetworkPreferences.OemNetworkPreference final int networkPrefToSetup) 11555 throws Exception { 11556 final int testPackageNameUid = TEST_PACKAGE_UID; 11557 final String testPackageName = "per.app.defaults.package"; 11558 setupMultipleDefaultNetworksForOemNetworkPreferenceTest( 11559 networkPrefToSetup, testPackageNameUid, testPackageName); 11560 } 11561 11562 private void setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest( 11563 @OemNetworkPreferences.OemNetworkPreference final int networkPrefToSetup) 11564 throws Exception { 11565 final int testPackageNameUid = Process.myUid(); 11566 final String testPackageName = "per.app.defaults.package"; 11567 setupMultipleDefaultNetworksForOemNetworkPreferenceTest( 11568 networkPrefToSetup, testPackageNameUid, testPackageName); 11569 } 11570 11571 private void setupMultipleDefaultNetworksForOemNetworkPreferenceTest( 11572 @OemNetworkPreferences.OemNetworkPreference final int networkPrefToSetup, 11573 final int testPackageUid, @NonNull final String testPackageName) throws Exception { 11574 // Only the default request should be included at start. 11575 assertEquals(1, mService.mDefaultNetworkRequests.size()); 11576 11577 final UidRangeParcel[] uidRanges = 11578 toUidRangeStableParcels(uidRangesForUids(testPackageUid)); 11579 setupSetOemNetworkPreferenceForPreferenceTest( 11580 networkPrefToSetup, uidRanges, testPackageName); 11581 } 11582 11583 private void setupSetOemNetworkPreferenceForPreferenceTest( 11584 @OemNetworkPreferences.OemNetworkPreference final int networkPrefToSetup, 11585 @NonNull final UidRangeParcel[] uidRanges, 11586 @NonNull final String testPackageName) throws Exception { 11587 setupSetOemNetworkPreferenceForPreferenceTest(networkPrefToSetup, uidRanges, 11588 testPackageName, PRIMARY_USER_HANDLE, true /* hasAutomotiveFeature */); 11589 } 11590 11591 private void setupSetOemNetworkPreferenceForPreferenceTest( 11592 @OemNetworkPreferences.OemNetworkPreference final int networkPrefToSetup, 11593 @NonNull final UidRangeParcel[] uidRanges, 11594 @NonNull final String testPackageName, 11595 @NonNull final UserHandle user) throws Exception { 11596 setupSetOemNetworkPreferenceForPreferenceTest(networkPrefToSetup, uidRanges, 11597 testPackageName, user, true /* hasAutomotiveFeature */); 11598 } 11599 11600 private void setupSetOemNetworkPreferenceForPreferenceTest( 11601 @OemNetworkPreferences.OemNetworkPreference final int networkPrefToSetup, 11602 @NonNull final UidRangeParcel[] uidRanges, 11603 @NonNull final String testPackageName, 11604 @NonNull final UserHandle user, 11605 final boolean hasAutomotiveFeature) throws Exception { 11606 mockHasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, hasAutomotiveFeature); 11607 11608 // These tests work off a single UID therefore using 'start' is valid. 11609 mockGetApplicationInfo(testPackageName, uidRanges[0].start, user); 11610 11611 setOemNetworkPreference(networkPrefToSetup, testPackageName); 11612 } 11613 11614 private void setOemNetworkPreference(final int networkPrefToSetup, 11615 @NonNull final String... testPackageNames) 11616 throws Exception { 11617 mockHasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, true); 11618 11619 // Build OemNetworkPreferences object 11620 final OemNetworkPreferences.Builder builder = new OemNetworkPreferences.Builder(); 11621 for (final String packageName : testPackageNames) { 11622 builder.addNetworkPreference(packageName, networkPrefToSetup); 11623 } 11624 final OemNetworkPreferences pref = builder.build(); 11625 11626 // Act on ConnectivityService.setOemNetworkPreference() 11627 final TestOemListenerCallback oemPrefListener = new TestOemListenerCallback(); 11628 mService.setOemNetworkPreference(pref, oemPrefListener); 11629 11630 // Verify call returned successfully 11631 oemPrefListener.expectOnComplete(); 11632 } 11633 11634 private static class TestOemListenerCallback implements IOnCompleteListener { 11635 final CompletableFuture<Object> mDone = new CompletableFuture<>(); 11636 11637 @Override 11638 public void onComplete() { 11639 mDone.complete(new Object()); 11640 } 11641 11642 void expectOnComplete() { 11643 try { 11644 mDone.get(TIMEOUT_MS, TimeUnit.MILLISECONDS); 11645 } catch (TimeoutException e) { 11646 fail("Expected onComplete() not received after " + TIMEOUT_MS + " ms"); 11647 } catch (Exception e) { 11648 fail(e.getMessage()); 11649 } 11650 } 11651 11652 @Override 11653 public IBinder asBinder() { 11654 return null; 11655 } 11656 } 11657 11658 @Test 11659 public void testMultiDefaultGetActiveNetworkIsCorrect() throws Exception { 11660 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 11661 OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY; 11662 final int expectedOemPrefRequestSize = 1; 11663 registerDefaultNetworkCallbacks(); 11664 11665 // Setup the test process to use networkPref for their default network. 11666 setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest(networkPref); 11667 11668 // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID. 11669 // The active network for the default should be null at this point as this is a retricted 11670 // network. 11671 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true); 11672 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 11673 null, 11674 mEthernetNetworkAgent.getNetwork()); 11675 11676 // Verify that the active network is correct 11677 verifyActiveNetwork(TRANSPORT_ETHERNET); 11678 // default NCs will be unregistered in tearDown 11679 } 11680 11681 @Test 11682 public void testMultiDefaultIsActiveNetworkMeteredIsCorrect() throws Exception { 11683 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 11684 OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY; 11685 final int expectedOemPrefRequestSize = 1; 11686 registerDefaultNetworkCallbacks(); 11687 11688 // Setup the test process to use networkPref for their default network. 11689 setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest(networkPref); 11690 11691 // Returns true by default when no network is available. 11692 assertTrue(mCm.isActiveNetworkMetered()); 11693 11694 // Connect to an unmetered restricted network that will only be available to the OEM pref. 11695 mEthernetNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_ETHERNET); 11696 mEthernetNetworkAgent.addCapability(NET_CAPABILITY_OEM_PAID); 11697 mEthernetNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED); 11698 mEthernetNetworkAgent.removeCapability(NET_CAPABILITY_NOT_RESTRICTED); 11699 mEthernetNetworkAgent.connect(true); 11700 waitForIdle(); 11701 11702 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 11703 null, 11704 mEthernetNetworkAgent.getNetwork()); 11705 11706 assertFalse(mCm.isActiveNetworkMetered()); 11707 // default NCs will be unregistered in tearDown 11708 } 11709 11710 @Test 11711 public void testPerAppDefaultRegisterDefaultNetworkCallback() throws Exception { 11712 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 11713 OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY; 11714 final int expectedOemPrefRequestSize = 1; 11715 final TestNetworkCallback defaultNetworkCallback = new TestNetworkCallback(); 11716 11717 // Register the default network callback before the pref is already set. This means that 11718 // the policy will be applied to the callback on setOemNetworkPreference(). 11719 mCm.registerDefaultNetworkCallback(defaultNetworkCallback); 11720 defaultNetworkCallback.assertNoCallback(); 11721 11722 final TestNetworkCallback otherUidDefaultCallback = new TestNetworkCallback(); 11723 withPermission(NETWORK_SETTINGS, () -> 11724 mCm.registerDefaultNetworkCallbackForUid(TEST_PACKAGE_UID, otherUidDefaultCallback, 11725 new Handler(ConnectivityThread.getInstanceLooper()))); 11726 11727 // Setup the test process to use networkPref for their default network. 11728 setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest(networkPref); 11729 11730 // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID. 11731 // The active nai for the default is null at this point as this is a restricted network. 11732 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true); 11733 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 11734 null, 11735 mEthernetNetworkAgent.getNetwork()); 11736 11737 // At this point with a restricted network used, the available callback should trigger. 11738 defaultNetworkCallback.expectAvailableThenValidatedCallbacks(mEthernetNetworkAgent); 11739 assertEquals(defaultNetworkCallback.getLastAvailableNetwork(), 11740 mEthernetNetworkAgent.getNetwork()); 11741 otherUidDefaultCallback.assertNoCallback(); 11742 11743 // Now bring down the default network which should trigger a LOST callback. 11744 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, false); 11745 11746 // At this point, with no network is available, the lost callback should trigger 11747 defaultNetworkCallback.expectCallback(CallbackEntry.LOST, mEthernetNetworkAgent); 11748 otherUidDefaultCallback.assertNoCallback(); 11749 11750 // Confirm we can unregister without issues. 11751 mCm.unregisterNetworkCallback(defaultNetworkCallback); 11752 mCm.unregisterNetworkCallback(otherUidDefaultCallback); 11753 } 11754 11755 @Test 11756 public void testPerAppDefaultRegisterDefaultNetworkCallbackAfterPrefSet() throws Exception { 11757 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 11758 OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY; 11759 final int expectedOemPrefRequestSize = 1; 11760 final TestNetworkCallback defaultNetworkCallback = new TestNetworkCallback(); 11761 11762 // Setup the test process to use networkPref for their default network. 11763 setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest(networkPref); 11764 11765 // Register the default network callback after the pref is already set. This means that 11766 // the policy will be applied to the callback on requestNetwork(). 11767 mCm.registerDefaultNetworkCallback(defaultNetworkCallback); 11768 defaultNetworkCallback.assertNoCallback(); 11769 11770 final TestNetworkCallback otherUidDefaultCallback = new TestNetworkCallback(); 11771 withPermission(NETWORK_SETTINGS, () -> 11772 mCm.registerDefaultNetworkCallbackForUid(TEST_PACKAGE_UID, otherUidDefaultCallback, 11773 new Handler(ConnectivityThread.getInstanceLooper()))); 11774 11775 // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID. 11776 // The active nai for the default is null at this point as this is a restricted network. 11777 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true); 11778 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 11779 null, 11780 mEthernetNetworkAgent.getNetwork()); 11781 11782 // At this point with a restricted network used, the available callback should trigger 11783 defaultNetworkCallback.expectAvailableThenValidatedCallbacks(mEthernetNetworkAgent); 11784 assertEquals(defaultNetworkCallback.getLastAvailableNetwork(), 11785 mEthernetNetworkAgent.getNetwork()); 11786 otherUidDefaultCallback.assertNoCallback(); 11787 11788 // Now bring down the default network which should trigger a LOST callback. 11789 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, false); 11790 otherUidDefaultCallback.assertNoCallback(); 11791 11792 // At this point, with no network is available, the lost callback should trigger 11793 defaultNetworkCallback.expectCallback(CallbackEntry.LOST, mEthernetNetworkAgent); 11794 otherUidDefaultCallback.assertNoCallback(); 11795 11796 // Confirm we can unregister without issues. 11797 mCm.unregisterNetworkCallback(defaultNetworkCallback); 11798 mCm.unregisterNetworkCallback(otherUidDefaultCallback); 11799 } 11800 11801 @Test 11802 public void testPerAppDefaultRegisterDefaultNetworkCallbackDoesNotFire() throws Exception { 11803 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 11804 OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY; 11805 final int expectedOemPrefRequestSize = 1; 11806 final TestNetworkCallback defaultNetworkCallback = new TestNetworkCallback(); 11807 final int userId = UserHandle.getUserId(Process.myUid()); 11808 11809 mCm.registerDefaultNetworkCallback(defaultNetworkCallback); 11810 defaultNetworkCallback.assertNoCallback(); 11811 11812 final TestNetworkCallback otherUidDefaultCallback = new TestNetworkCallback(); 11813 withPermission(NETWORK_SETTINGS, () -> 11814 mCm.registerDefaultNetworkCallbackForUid(TEST_PACKAGE_UID, otherUidDefaultCallback, 11815 new Handler(ConnectivityThread.getInstanceLooper()))); 11816 11817 // Setup a process different than the test process to use the default network. This means 11818 // that the defaultNetworkCallback won't be tracked by the per-app policy. 11819 setupMultipleDefaultNetworksForOemNetworkPreferenceNotCurrentUidTest(networkPref); 11820 11821 // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID. 11822 // The active nai for the default is null at this point as this is a restricted network. 11823 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true); 11824 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 11825 null, 11826 mEthernetNetworkAgent.getNetwork()); 11827 11828 // As this callback does not have access to the OEM_PAID network, it will not fire. 11829 defaultNetworkCallback.assertNoCallback(); 11830 assertDefaultNetworkCapabilities(userId /* no networks */); 11831 11832 // The other UID does have access, and gets a callback. 11833 otherUidDefaultCallback.expectAvailableThenValidatedCallbacks(mEthernetNetworkAgent); 11834 11835 // Bring up unrestricted cellular. This should now satisfy the default network. 11836 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); 11837 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 11838 mCellNetworkAgent.getNetwork(), 11839 mEthernetNetworkAgent.getNetwork()); 11840 11841 // At this point with an unrestricted network used, the available callback should trigger 11842 // The other UID is unaffected and remains on the paid network. 11843 defaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 11844 assertEquals(defaultNetworkCallback.getLastAvailableNetwork(), 11845 mCellNetworkAgent.getNetwork()); 11846 assertDefaultNetworkCapabilities(userId, mCellNetworkAgent); 11847 otherUidDefaultCallback.assertNoCallback(); 11848 11849 // Now bring down the per-app network. 11850 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, false); 11851 11852 // Since the callback didn't use the per-app network, only the other UID gets a callback. 11853 // Because the preference specifies no fallback, it does not switch to cellular. 11854 defaultNetworkCallback.assertNoCallback(); 11855 otherUidDefaultCallback.expectCallback(CallbackEntry.LOST, mEthernetNetworkAgent); 11856 11857 // Now bring down the default network. 11858 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, false); 11859 11860 // As this callback was tracking the default, this should now trigger. 11861 defaultNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 11862 otherUidDefaultCallback.assertNoCallback(); 11863 11864 // Confirm we can unregister without issues. 11865 mCm.unregisterNetworkCallback(defaultNetworkCallback); 11866 mCm.unregisterNetworkCallback(otherUidDefaultCallback); 11867 } 11868 11869 /** 11870 * This method assumes that the same uidRanges input will be used to verify that dependencies 11871 * are called as expected. 11872 */ 11873 private void verifySetOemNetworkPreferenceForPreference( 11874 @NonNull final UidRangeParcel[] uidRanges, 11875 final int addUidRangesNetId, 11876 final int addUidRangesTimes, 11877 final int removeUidRangesNetId, 11878 final int removeUidRangesTimes, 11879 final boolean shouldDestroyNetwork) throws RemoteException { 11880 verifySetOemNetworkPreferenceForPreference(uidRanges, uidRanges, 11881 addUidRangesNetId, addUidRangesTimes, removeUidRangesNetId, removeUidRangesTimes, 11882 shouldDestroyNetwork); 11883 } 11884 11885 private void verifySetOemNetworkPreferenceForPreference( 11886 @NonNull final UidRangeParcel[] addedUidRanges, 11887 @NonNull final UidRangeParcel[] removedUidRanges, 11888 final int addUidRangesNetId, 11889 final int addUidRangesTimes, 11890 final int removeUidRangesNetId, 11891 final int removeUidRangesTimes, 11892 final boolean shouldDestroyNetwork) throws RemoteException { 11893 final boolean useAnyIdForAdd = OEM_PREF_ANY_NET_ID == addUidRangesNetId; 11894 final boolean useAnyIdForRemove = OEM_PREF_ANY_NET_ID == removeUidRangesNetId; 11895 11896 // Validate that add/remove uid range (with oem priority) to/from netd. 11897 verify(mMockNetd, times(addUidRangesTimes)).networkAddUidRangesParcel(argThat(config -> 11898 (useAnyIdForAdd ? true : addUidRangesNetId == config.netId) 11899 && Arrays.equals(addedUidRanges, config.uidRanges) 11900 && PREFERENCE_PRIORITY_OEM == config.subPriority)); 11901 verify(mMockNetd, times(removeUidRangesTimes)).networkRemoveUidRangesParcel( 11902 argThat(config -> (useAnyIdForRemove ? true : removeUidRangesNetId == config.netId) 11903 && Arrays.equals(removedUidRanges, config.uidRanges) 11904 && PREFERENCE_PRIORITY_OEM == config.subPriority)); 11905 if (shouldDestroyNetwork) { 11906 verify(mMockNetd, times(1)) 11907 .networkDestroy((useAnyIdForRemove ? anyInt() : eq(removeUidRangesNetId))); 11908 } 11909 reset(mMockNetd); 11910 } 11911 11912 /** 11913 * Test the tracked default requests allows test requests without standard setup. 11914 */ 11915 @Test 11916 public void testSetOemNetworkPreferenceAllowsValidTestRequestWithoutChecks() throws Exception { 11917 @OemNetworkPreferences.OemNetworkPreference int networkPref = 11918 OEM_NETWORK_PREFERENCE_TEST; 11919 validateSetOemNetworkPreferenceAllowsValidTestPrefRequest(networkPref); 11920 } 11921 11922 /** 11923 * Test the tracked default requests allows test only requests without standard setup. 11924 */ 11925 @Test 11926 public void testSetOemNetworkPreferenceAllowsValidTestOnlyRequestWithoutChecks() 11927 throws Exception { 11928 @OemNetworkPreferences.OemNetworkPreference int networkPref = 11929 OEM_NETWORK_PREFERENCE_TEST_ONLY; 11930 validateSetOemNetworkPreferenceAllowsValidTestPrefRequest(networkPref); 11931 } 11932 11933 private void validateSetOemNetworkPreferenceAllowsValidTestPrefRequest(int networkPref) 11934 throws Exception { 11935 // The caller must have the MANAGE_TEST_NETWORKS permission. 11936 final int testPackageUid = 123; 11937 final String validTestPackageName = "does.not.matter"; 11938 final UidRangeParcel[] uidRanges = 11939 toUidRangeStableParcels(uidRangesForUids(testPackageUid)); 11940 mServiceContext.setPermission( 11941 Manifest.permission.MANAGE_TEST_NETWORKS, PERMISSION_GRANTED); 11942 11943 // Put the system into a state in which setOemNetworkPreference() would normally fail. This 11944 // will confirm that a valid test request can bypass these checks. 11945 mockHasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, false); 11946 mServiceContext.setPermission( 11947 Manifest.permission.CONTROL_OEM_PAID_NETWORK_PREFERENCE, PERMISSION_DENIED); 11948 11949 // Validate the starting requests only includes the system default request. 11950 assertEquals(1, mService.mDefaultNetworkRequests.size()); 11951 11952 // Add an OEM default network request to track. 11953 setupSetOemNetworkPreferenceForPreferenceTest( 11954 networkPref, uidRanges, validTestPackageName, PRIMARY_USER_HANDLE, 11955 false /* hasAutomotiveFeature */); 11956 11957 // Two requests should now exist; the system default and the test request. 11958 assertEquals(2, mService.mDefaultNetworkRequests.size()); 11959 } 11960 11961 /** 11962 * Test the tracked default requests clear previous OEM requests on setOemNetworkPreference(). 11963 */ 11964 @Test 11965 public void testSetOemNetworkPreferenceClearPreviousOemValues() throws Exception { 11966 @OemNetworkPreferences.OemNetworkPreference int networkPref = 11967 OEM_NETWORK_PREFERENCE_OEM_PAID; 11968 final int testPackageUid = 123; 11969 final String testPackageName = "com.google.apps.contacts"; 11970 final UidRangeParcel[] uidRanges = 11971 toUidRangeStableParcels(uidRangesForUids(testPackageUid)); 11972 11973 // Validate the starting requests only includes the system default request. 11974 assertEquals(1, mService.mDefaultNetworkRequests.size()); 11975 11976 // Add an OEM default network request to track. 11977 setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges, testPackageName); 11978 11979 // Two requests should exist, one for the fallback and one for the pref. 11980 assertEquals(2, mService.mDefaultNetworkRequests.size()); 11981 11982 networkPref = OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY; 11983 setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges, testPackageName); 11984 11985 // Two requests should still exist validating the previous per-app request was replaced. 11986 assertEquals(2, mService.mDefaultNetworkRequests.size()); 11987 } 11988 11989 /** 11990 * Test network priority for preference OEM_NETWORK_PREFERENCE_OEM_PAID in the following order: 11991 * NET_CAPABILITY_NOT_METERED -> NET_CAPABILITY_OEM_PAID -> fallback 11992 */ 11993 @Test 11994 public void testMultilayerForPreferenceOemPaidEvaluatesCorrectly() 11995 throws Exception { 11996 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 11997 OEM_NETWORK_PREFERENCE_OEM_PAID; 11998 11999 // Arrange PackageManager mocks 12000 final UidRangeParcel[] uidRanges = 12001 toUidRangeStableParcels(uidRangesForUids(TEST_PACKAGE_UID)); 12002 setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges, TEST_PACKAGE_NAME); 12003 12004 // Verify the starting state. No networks should be connected. 12005 verifySetOemNetworkPreferenceForPreference(uidRanges, 12006 OEM_PREF_ANY_NET_ID, 0 /* times */, 12007 OEM_PREF_ANY_NET_ID, 0 /* times */, 12008 false /* shouldDestroyNetwork */); 12009 12010 // Test lowest to highest priority requests. 12011 // Bring up metered cellular. This will satisfy the fallback network. 12012 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); 12013 verifySetOemNetworkPreferenceForPreference(uidRanges, 12014 mCellNetworkAgent.getNetwork().netId, 1 /* times */, 12015 OEM_PREF_ANY_NET_ID, 0 /* times */, 12016 false /* shouldDestroyNetwork */); 12017 12018 // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID. 12019 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true); 12020 verifySetOemNetworkPreferenceForPreference(uidRanges, 12021 mEthernetNetworkAgent.getNetwork().netId, 1 /* times */, 12022 mCellNetworkAgent.getNetwork().netId, 1 /* times */, 12023 false /* shouldDestroyNetwork */); 12024 12025 // Bring up unmetered Wi-Fi. This will satisfy NET_CAPABILITY_NOT_METERED. 12026 setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, true); 12027 verifySetOemNetworkPreferenceForPreference(uidRanges, 12028 mWiFiNetworkAgent.getNetwork().netId, 1 /* times */, 12029 mEthernetNetworkAgent.getNetwork().netId, 1 /* times */, 12030 false /* shouldDestroyNetwork */); 12031 12032 // Disconnecting OEM_PAID should have no effect as it is lower in priority then unmetered. 12033 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, false); 12034 // netd should not be called as default networks haven't changed. 12035 verifySetOemNetworkPreferenceForPreference(uidRanges, 12036 OEM_PREF_ANY_NET_ID, 0 /* times */, 12037 OEM_PREF_ANY_NET_ID, 0 /* times */, 12038 false /* shouldDestroyNetwork */); 12039 12040 // Disconnecting unmetered should put PANS on lowest priority fallback request. 12041 setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, false); 12042 verifySetOemNetworkPreferenceForPreference(uidRanges, 12043 mCellNetworkAgent.getNetwork().netId, 1 /* times */, 12044 mWiFiNetworkAgent.getNetwork().netId, 0 /* times */, 12045 true /* shouldDestroyNetwork */); 12046 12047 // Disconnecting the fallback network should result in no connectivity. 12048 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, false); 12049 verifySetOemNetworkPreferenceForPreference(uidRanges, 12050 OEM_PREF_ANY_NET_ID, 0 /* times */, 12051 mCellNetworkAgent.getNetwork().netId, 0 /* times */, 12052 true /* shouldDestroyNetwork */); 12053 } 12054 12055 /** 12056 * Test network priority for OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK in the following order: 12057 * NET_CAPABILITY_NOT_METERED -> NET_CAPABILITY_OEM_PAID 12058 */ 12059 @Test 12060 public void testMultilayerForPreferenceOemPaidNoFallbackEvaluatesCorrectly() 12061 throws Exception { 12062 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 12063 OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK; 12064 12065 // Arrange PackageManager mocks 12066 final UidRangeParcel[] uidRanges = 12067 toUidRangeStableParcels(uidRangesForUids(TEST_PACKAGE_UID)); 12068 setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges, TEST_PACKAGE_NAME); 12069 12070 // Verify the starting state. This preference doesn't support using the fallback network 12071 // therefore should be on the disconnected network as it has no networks to connect to. 12072 verifySetOemNetworkPreferenceForPreference(uidRanges, 12073 mService.mNoServiceNetwork.network.getNetId(), 1 /* times */, 12074 OEM_PREF_ANY_NET_ID, 0 /* times */, 12075 false /* shouldDestroyNetwork */); 12076 12077 // Test lowest to highest priority requests. 12078 // Bring up metered cellular. This will satisfy the fallback network. 12079 // This preference should not use this network as it doesn't support fallback usage. 12080 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); 12081 verifySetOemNetworkPreferenceForPreference(uidRanges, 12082 OEM_PREF_ANY_NET_ID, 0 /* times */, 12083 OEM_PREF_ANY_NET_ID, 0 /* times */, 12084 false /* shouldDestroyNetwork */); 12085 12086 // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID. 12087 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true); 12088 verifySetOemNetworkPreferenceForPreference(uidRanges, 12089 mEthernetNetworkAgent.getNetwork().netId, 1 /* times */, 12090 mService.mNoServiceNetwork.network.getNetId(), 1 /* times */, 12091 false /* shouldDestroyNetwork */); 12092 12093 // Bring up unmetered Wi-Fi. This will satisfy NET_CAPABILITY_NOT_METERED. 12094 setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, true); 12095 verifySetOemNetworkPreferenceForPreference(uidRanges, 12096 mWiFiNetworkAgent.getNetwork().netId, 1 /* times */, 12097 mEthernetNetworkAgent.getNetwork().netId, 1 /* times */, 12098 false /* shouldDestroyNetwork */); 12099 12100 // Disconnecting unmetered should put PANS on OEM_PAID. 12101 setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, false); 12102 verifySetOemNetworkPreferenceForPreference(uidRanges, 12103 mEthernetNetworkAgent.getNetwork().netId, 1 /* times */, 12104 mWiFiNetworkAgent.getNetwork().netId, 0 /* times */, 12105 true /* shouldDestroyNetwork */); 12106 12107 // Disconnecting OEM_PAID should result in no connectivity. 12108 // OEM_PAID_NO_FALLBACK not supporting a fallback now uses the disconnected network. 12109 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, false); 12110 verifySetOemNetworkPreferenceForPreference(uidRanges, 12111 mService.mNoServiceNetwork.network.getNetId(), 1 /* times */, 12112 mEthernetNetworkAgent.getNetwork().netId, 0 /* times */, 12113 true /* shouldDestroyNetwork */); 12114 } 12115 12116 /** 12117 * Test network priority for OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY in the following order: 12118 * NET_CAPABILITY_OEM_PAID 12119 * This preference should only apply to OEM_PAID networks. 12120 */ 12121 @Test 12122 public void testMultilayerForPreferenceOemPaidOnlyEvaluatesCorrectly() 12123 throws Exception { 12124 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 12125 OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY; 12126 12127 // Arrange PackageManager mocks 12128 final UidRangeParcel[] uidRanges = 12129 toUidRangeStableParcels(uidRangesForUids(TEST_PACKAGE_UID)); 12130 setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges, TEST_PACKAGE_NAME); 12131 12132 // Verify the starting state. This preference doesn't support using the fallback network 12133 // therefore should be on the disconnected network as it has no networks to connect to. 12134 verifySetOemNetworkPreferenceForPreference(uidRanges, 12135 mService.mNoServiceNetwork.network.getNetId(), 1 /* times */, 12136 OEM_PREF_ANY_NET_ID, 0 /* times */, 12137 false /* shouldDestroyNetwork */); 12138 12139 // Bring up metered cellular. This should not apply to this preference. 12140 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); 12141 verifySetOemNetworkPreferenceForPreference(uidRanges, 12142 OEM_PREF_ANY_NET_ID, 0 /* times */, 12143 OEM_PREF_ANY_NET_ID, 0 /* times */, 12144 false /* shouldDestroyNetwork */); 12145 12146 // Bring up unmetered Wi-Fi. This should not apply to this preference. 12147 setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, true); 12148 verifySetOemNetworkPreferenceForPreference(uidRanges, 12149 OEM_PREF_ANY_NET_ID, 0 /* times */, 12150 OEM_PREF_ANY_NET_ID, 0 /* times */, 12151 false /* shouldDestroyNetwork */); 12152 12153 // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID. 12154 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true); 12155 verifySetOemNetworkPreferenceForPreference(uidRanges, 12156 mEthernetNetworkAgent.getNetwork().netId, 1 /* times */, 12157 mService.mNoServiceNetwork.network.getNetId(), 1 /* times */, 12158 false /* shouldDestroyNetwork */); 12159 12160 // Disconnecting OEM_PAID should result in no connectivity. 12161 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, false); 12162 verifySetOemNetworkPreferenceForPreference(uidRanges, 12163 mService.mNoServiceNetwork.network.getNetId(), 1 /* times */, 12164 mEthernetNetworkAgent.getNetwork().netId, 0 /* times */, 12165 true /* shouldDestroyNetwork */); 12166 } 12167 12168 /** 12169 * Test network priority for OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY in the following order: 12170 * NET_CAPABILITY_OEM_PRIVATE 12171 * This preference should only apply to OEM_PRIVATE networks. 12172 */ 12173 @Test 12174 public void testMultilayerForPreferenceOemPrivateOnlyEvaluatesCorrectly() 12175 throws Exception { 12176 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 12177 OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY; 12178 12179 // Arrange PackageManager mocks 12180 final UidRangeParcel[] uidRanges = 12181 toUidRangeStableParcels(uidRangesForUids(TEST_PACKAGE_UID)); 12182 setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges, TEST_PACKAGE_NAME); 12183 12184 // Verify the starting state. This preference doesn't support using the fallback network 12185 // therefore should be on the disconnected network as it has no networks to connect to. 12186 verifySetOemNetworkPreferenceForPreference(uidRanges, 12187 mService.mNoServiceNetwork.network.getNetId(), 1 /* times */, 12188 OEM_PREF_ANY_NET_ID, 0 /* times */, 12189 false /* shouldDestroyNetwork */); 12190 12191 // Bring up metered cellular. This should not apply to this preference. 12192 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); 12193 verifySetOemNetworkPreferenceForPreference(uidRanges, 12194 OEM_PREF_ANY_NET_ID, 0 /* times */, 12195 OEM_PREF_ANY_NET_ID, 0 /* times */, 12196 false /* shouldDestroyNetwork */); 12197 12198 // Bring up unmetered Wi-Fi. This should not apply to this preference. 12199 setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, true); 12200 verifySetOemNetworkPreferenceForPreference(uidRanges, 12201 OEM_PREF_ANY_NET_ID, 0 /* times */, 12202 OEM_PREF_ANY_NET_ID, 0 /* times */, 12203 false /* shouldDestroyNetwork */); 12204 12205 // Bring up ethernet with OEM_PRIVATE. This will satisfy NET_CAPABILITY_OEM_PRIVATE. 12206 startOemManagedNetwork(false); 12207 verifySetOemNetworkPreferenceForPreference(uidRanges, 12208 mEthernetNetworkAgent.getNetwork().netId, 1 /* times */, 12209 mService.mNoServiceNetwork.network.getNetId(), 1 /* times */, 12210 false /* shouldDestroyNetwork */); 12211 12212 // Disconnecting OEM_PRIVATE should result in no connectivity. 12213 stopOemManagedNetwork(); 12214 verifySetOemNetworkPreferenceForPreference(uidRanges, 12215 mService.mNoServiceNetwork.network.getNetId(), 1 /* times */, 12216 mEthernetNetworkAgent.getNetwork().netId, 0 /* times */, 12217 true /* shouldDestroyNetwork */); 12218 } 12219 12220 @Test 12221 public void testMultilayerForMultipleUsersEvaluatesCorrectly() 12222 throws Exception { 12223 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 12224 OEM_NETWORK_PREFERENCE_OEM_PAID; 12225 12226 // Arrange users 12227 final int secondUser = 10; 12228 final UserHandle secondUserHandle = new UserHandle(secondUser); 12229 when(mUserManager.getUserHandles(anyBoolean())).thenReturn( 12230 Arrays.asList(PRIMARY_USER_HANDLE, secondUserHandle)); 12231 12232 // Arrange PackageManager mocks 12233 final int secondUserTestPackageUid = UserHandle.getUid(secondUser, TEST_PACKAGE_UID); 12234 final UidRangeParcel[] uidRanges = 12235 toUidRangeStableParcels( 12236 uidRangesForUids(TEST_PACKAGE_UID, secondUserTestPackageUid)); 12237 mockGetApplicationInfo(TEST_PACKAGE_NAME, secondUserTestPackageUid, secondUserHandle); 12238 setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges, TEST_PACKAGE_NAME); 12239 12240 // Verify the starting state. No networks should be connected. 12241 verifySetOemNetworkPreferenceForPreference(uidRanges, 12242 OEM_PREF_ANY_NET_ID, 0 /* times */, 12243 OEM_PREF_ANY_NET_ID, 0 /* times */, 12244 false /* shouldDestroyNetwork */); 12245 12246 // Test that we correctly add the expected values for multiple users. 12247 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); 12248 verifySetOemNetworkPreferenceForPreference(uidRanges, 12249 mCellNetworkAgent.getNetwork().netId, 1 /* times */, 12250 OEM_PREF_ANY_NET_ID, 0 /* times */, 12251 false /* shouldDestroyNetwork */); 12252 12253 // Test that we correctly remove the expected values for multiple users. 12254 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, false); 12255 verifySetOemNetworkPreferenceForPreference(uidRanges, 12256 OEM_PREF_ANY_NET_ID, 0 /* times */, 12257 mCellNetworkAgent.getNetwork().netId, 0 /* times */, 12258 true /* shouldDestroyNetwork */); 12259 } 12260 12261 @Test 12262 public void testMultilayerForBroadcastedUsersEvaluatesCorrectly() 12263 throws Exception { 12264 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 12265 OEM_NETWORK_PREFERENCE_OEM_PAID; 12266 12267 // Arrange users 12268 final int secondUser = 10; 12269 final UserHandle secondUserHandle = new UserHandle(secondUser); 12270 when(mUserManager.getUserHandles(anyBoolean())).thenReturn( 12271 Arrays.asList(PRIMARY_USER_HANDLE)); 12272 12273 // Arrange PackageManager mocks 12274 final int secondUserTestPackageUid = UserHandle.getUid(secondUser, TEST_PACKAGE_UID); 12275 final UidRangeParcel[] uidRangesSingleUser = 12276 toUidRangeStableParcels(uidRangesForUids(TEST_PACKAGE_UID)); 12277 final UidRangeParcel[] uidRangesBothUsers = 12278 toUidRangeStableParcels( 12279 uidRangesForUids(TEST_PACKAGE_UID, secondUserTestPackageUid)); 12280 mockGetApplicationInfo(TEST_PACKAGE_NAME, secondUserTestPackageUid, secondUserHandle); 12281 setupSetOemNetworkPreferenceForPreferenceTest( 12282 networkPref, uidRangesSingleUser, TEST_PACKAGE_NAME); 12283 12284 // Verify the starting state. No networks should be connected. 12285 verifySetOemNetworkPreferenceForPreference(uidRangesSingleUser, 12286 OEM_PREF_ANY_NET_ID, 0 /* times */, 12287 OEM_PREF_ANY_NET_ID, 0 /* times */, 12288 false /* shouldDestroyNetwork */); 12289 12290 // Test that we correctly add the expected values for multiple users. 12291 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); 12292 verifySetOemNetworkPreferenceForPreference(uidRangesSingleUser, 12293 mCellNetworkAgent.getNetwork().netId, 1 /* times */, 12294 OEM_PREF_ANY_NET_ID, 0 /* times */, 12295 false /* shouldDestroyNetwork */); 12296 12297 // Send a broadcast indicating a user was added. 12298 when(mUserManager.getUserHandles(anyBoolean())).thenReturn( 12299 Arrays.asList(PRIMARY_USER_HANDLE, secondUserHandle)); 12300 final Intent addedIntent = new Intent(ACTION_USER_ADDED); 12301 addedIntent.putExtra(Intent.EXTRA_USER, UserHandle.of(secondUser)); 12302 processBroadcast(addedIntent); 12303 12304 // Test that we correctly add values for all users and remove for the single user. 12305 verifySetOemNetworkPreferenceForPreference(uidRangesBothUsers, uidRangesSingleUser, 12306 mCellNetworkAgent.getNetwork().netId, 1 /* times */, 12307 mCellNetworkAgent.getNetwork().netId, 1 /* times */, 12308 false /* shouldDestroyNetwork */); 12309 12310 // Send a broadcast indicating a user was removed. 12311 when(mUserManager.getUserHandles(anyBoolean())).thenReturn( 12312 Arrays.asList(PRIMARY_USER_HANDLE)); 12313 final Intent removedIntent = new Intent(ACTION_USER_REMOVED); 12314 removedIntent.putExtra(Intent.EXTRA_USER, UserHandle.of(secondUser)); 12315 processBroadcast(removedIntent); 12316 12317 // Test that we correctly add values for the single user and remove for the all users. 12318 verifySetOemNetworkPreferenceForPreference(uidRangesSingleUser, uidRangesBothUsers, 12319 mCellNetworkAgent.getNetwork().netId, 1 /* times */, 12320 mCellNetworkAgent.getNetwork().netId, 1 /* times */, 12321 false /* shouldDestroyNetwork */); 12322 } 12323 12324 @Test 12325 public void testMultilayerForPackageChangesEvaluatesCorrectly() 12326 throws Exception { 12327 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 12328 OEM_NETWORK_PREFERENCE_OEM_PAID; 12329 final String packageScheme = "package:"; 12330 12331 // Arrange PackageManager mocks 12332 final String packageToInstall = "package.to.install"; 12333 final int packageToInstallUid = 81387; 12334 final UidRangeParcel[] uidRangesSinglePackage = 12335 toUidRangeStableParcels(uidRangesForUids(TEST_PACKAGE_UID)); 12336 mockGetApplicationInfo(TEST_PACKAGE_NAME, TEST_PACKAGE_UID); 12337 mockGetApplicationInfoThrowsNameNotFound(packageToInstall, PRIMARY_USER_HANDLE); 12338 setOemNetworkPreference(networkPref, TEST_PACKAGE_NAME, packageToInstall); 12339 grantUsingBackgroundNetworksPermissionForUid(Binder.getCallingUid(), packageToInstall); 12340 12341 // Verify the starting state. No networks should be connected. 12342 verifySetOemNetworkPreferenceForPreference(uidRangesSinglePackage, 12343 OEM_PREF_ANY_NET_ID, 0 /* times */, 12344 OEM_PREF_ANY_NET_ID, 0 /* times */, 12345 false /* shouldDestroyNetwork */); 12346 12347 // Test that we correctly add the expected values for installed packages. 12348 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); 12349 verifySetOemNetworkPreferenceForPreference(uidRangesSinglePackage, 12350 mCellNetworkAgent.getNetwork().netId, 1 /* times */, 12351 OEM_PREF_ANY_NET_ID, 0 /* times */, 12352 false /* shouldDestroyNetwork */); 12353 12354 // Set the system to recognize the package to be installed 12355 mockGetApplicationInfo(packageToInstall, packageToInstallUid); 12356 final UidRangeParcel[] uidRangesAllPackages = 12357 toUidRangeStableParcels(uidRangesForUids(TEST_PACKAGE_UID, packageToInstallUid)); 12358 12359 // Send a broadcast indicating a package was installed. 12360 final Intent addedIntent = new Intent(ACTION_PACKAGE_ADDED); 12361 addedIntent.setData(Uri.parse(packageScheme + packageToInstall)); 12362 processBroadcast(addedIntent); 12363 12364 // Test the single package is removed and the combined packages are added. 12365 verifySetOemNetworkPreferenceForPreference(uidRangesAllPackages, uidRangesSinglePackage, 12366 mCellNetworkAgent.getNetwork().netId, 1 /* times */, 12367 mCellNetworkAgent.getNetwork().netId, 1 /* times */, 12368 false /* shouldDestroyNetwork */); 12369 12370 // Set the system to no longer recognize the package to be installed 12371 mockGetApplicationInfoThrowsNameNotFound(packageToInstall, PRIMARY_USER_HANDLE); 12372 12373 // Send a broadcast indicating a package was removed. 12374 final Intent removedIntent = new Intent(ACTION_PACKAGE_REMOVED); 12375 removedIntent.setData(Uri.parse(packageScheme + packageToInstall)); 12376 processBroadcast(removedIntent); 12377 12378 // Test the combined packages are removed and the single package is added. 12379 verifySetOemNetworkPreferenceForPreference(uidRangesSinglePackage, uidRangesAllPackages, 12380 mCellNetworkAgent.getNetwork().netId, 1 /* times */, 12381 mCellNetworkAgent.getNetwork().netId, 1 /* times */, 12382 false /* shouldDestroyNetwork */); 12383 12384 // Set the system to change the installed package's uid 12385 final int replacedTestPackageUid = TEST_PACKAGE_UID + 1; 12386 mockGetApplicationInfo(TEST_PACKAGE_NAME, replacedTestPackageUid); 12387 final UidRangeParcel[] uidRangesReplacedPackage = 12388 toUidRangeStableParcels(uidRangesForUids(replacedTestPackageUid)); 12389 12390 // Send a broadcast indicating a package was replaced. 12391 final Intent replacedIntent = new Intent(ACTION_PACKAGE_REPLACED); 12392 replacedIntent.setData(Uri.parse(packageScheme + TEST_PACKAGE_NAME)); 12393 processBroadcast(replacedIntent); 12394 12395 // Test the original uid is removed and is replaced with the new uid. 12396 verifySetOemNetworkPreferenceForPreference(uidRangesReplacedPackage, uidRangesSinglePackage, 12397 mCellNetworkAgent.getNetwork().netId, 1 /* times */, 12398 mCellNetworkAgent.getNetwork().netId, 1 /* times */, 12399 false /* shouldDestroyNetwork */); 12400 } 12401 12402 /** 12403 * Test network priority for preference OEM_NETWORK_PREFERENCE_OEM_PAID in the following order: 12404 * NET_CAPABILITY_NOT_METERED -> NET_CAPABILITY_OEM_PAID -> fallback 12405 */ 12406 @Test 12407 public void testMultipleDefaultNetworksTracksOemNetworkPreferenceOemPaidCorrectly() 12408 throws Exception { 12409 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 12410 OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID; 12411 setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest(networkPref); 12412 final int expectedDefaultRequestSize = 2; 12413 final int expectedOemPrefRequestSize = 3; 12414 registerDefaultNetworkCallbacks(); 12415 12416 // The fallback as well as the OEM preference should now be tracked. 12417 assertEquals(expectedDefaultRequestSize, mService.mDefaultNetworkRequests.size()); 12418 12419 // Test lowest to highest priority requests. 12420 // Bring up metered cellular. This will satisfy the fallback network. 12421 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); 12422 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 12423 mCellNetworkAgent.getNetwork(), 12424 mCellNetworkAgent.getNetwork()); 12425 12426 // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID. 12427 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true); 12428 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 12429 mCellNetworkAgent.getNetwork(), 12430 mEthernetNetworkAgent.getNetwork()); 12431 12432 // Bring up unmetered Wi-Fi. This will satisfy NET_CAPABILITY_NOT_METERED. 12433 setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, true); 12434 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 12435 mWiFiNetworkAgent.getNetwork(), 12436 mWiFiNetworkAgent.getNetwork()); 12437 12438 // Disconnecting unmetered Wi-Fi will put the pref on OEM_PAID and fallback on cellular. 12439 setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, false); 12440 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 12441 mCellNetworkAgent.getNetwork(), 12442 mEthernetNetworkAgent.getNetwork()); 12443 12444 // Disconnecting cellular should keep OEM network on OEM_PAID and fallback will be null. 12445 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, false); 12446 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 12447 null, 12448 mEthernetNetworkAgent.getNetwork()); 12449 12450 // Disconnecting OEM_PAID will put both on null as it is the last network. 12451 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, false); 12452 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 12453 null, 12454 null); 12455 12456 // default callbacks will be unregistered in tearDown 12457 } 12458 12459 @Test 12460 public void testNetworkFactoryRequestsWithMultilayerRequest() 12461 throws Exception { 12462 // First use OEM_PAID preference to create a multi-layer request : 1. listen for 12463 // unmetered, 2. request network with cap OEM_PAID, 3, request the default network for 12464 // fallback. 12465 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 12466 OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID; 12467 setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest(networkPref); 12468 12469 final HandlerThread handlerThread = new HandlerThread("MockFactory"); 12470 handlerThread.start(); 12471 NetworkCapabilities internetFilter = new NetworkCapabilities() 12472 .addCapability(NET_CAPABILITY_INTERNET) 12473 .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED); 12474 final MockNetworkFactory internetFactory = new MockNetworkFactory(handlerThread.getLooper(), 12475 mServiceContext, "internetFactory", internetFilter, mCsHandlerThread); 12476 internetFactory.setScoreFilter(40); 12477 internetFactory.register(); 12478 // Default internet request only. The unmetered request is never sent to factories (it's a 12479 // LISTEN, not requestable). The 3rd (fallback) request in OEM_PAID NRI is TRACK_DEFAULT 12480 // which is also not sent to factories. Finally, the OEM_PAID request doesn't match the 12481 // internetFactory filter. 12482 internetFactory.expectRequestAdds(1); 12483 internetFactory.assertRequestCountEquals(1); 12484 12485 NetworkCapabilities oemPaidFilter = new NetworkCapabilities() 12486 .addCapability(NET_CAPABILITY_INTERNET) 12487 .addCapability(NET_CAPABILITY_OEM_PAID) 12488 .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED) 12489 .removeCapability(NET_CAPABILITY_NOT_RESTRICTED); 12490 final MockNetworkFactory oemPaidFactory = new MockNetworkFactory(handlerThread.getLooper(), 12491 mServiceContext, "oemPaidFactory", oemPaidFilter, mCsHandlerThread); 12492 oemPaidFactory.setScoreFilter(40); 12493 oemPaidFactory.register(); 12494 oemPaidFactory.expectRequestAdd(); // Because nobody satisfies the request 12495 12496 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 12497 mCellNetworkAgent.connect(true); 12498 12499 // A network connected that satisfies the default internet request. For the OEM_PAID 12500 // preference, this is not as good as an OEM_PAID network, so even if the score of 12501 // the network is better than the factory announced, it still should try to bring up 12502 // the network. 12503 expectNoRequestChanged(oemPaidFactory); 12504 oemPaidFactory.assertRequestCountEquals(1); 12505 // The internet factory however is outscored, and should lose its requests. 12506 internetFactory.expectRequestRemove(); 12507 internetFactory.assertRequestCountEquals(0); 12508 12509 final NetworkCapabilities oemPaidNc = new NetworkCapabilities(); 12510 oemPaidNc.addCapability(NET_CAPABILITY_OEM_PAID); 12511 oemPaidNc.removeCapability(NET_CAPABILITY_NOT_RESTRICTED); 12512 final TestNetworkAgentWrapper oemPaidAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, 12513 new LinkProperties(), oemPaidNc); 12514 oemPaidAgent.connect(true); 12515 12516 // The oemPaidAgent has score 50/cell transport, so it beats what the oemPaidFactory can 12517 // provide, therefore it loses the request. 12518 oemPaidFactory.expectRequestRemove(); 12519 oemPaidFactory.assertRequestCountEquals(0); 12520 expectNoRequestChanged(internetFactory); 12521 internetFactory.assertRequestCountEquals(0); 12522 12523 oemPaidAgent.setScore(new NetworkScore.Builder().setLegacyInt(20).setExiting(true).build()); 12524 // Now the that the agent is weak, the oemPaidFactory can beat the existing network for the 12525 // OEM_PAID request. The internet factory however can't beat a network that has OEM_PAID 12526 // for the preference request, so it doesn't see the request. 12527 oemPaidFactory.expectRequestAdd(); 12528 oemPaidFactory.assertRequestCountEquals(1); 12529 expectNoRequestChanged(internetFactory); 12530 internetFactory.assertRequestCountEquals(0); 12531 12532 mCellNetworkAgent.disconnect(); 12533 // The network satisfying the default internet request has disconnected, so the 12534 // internetFactory sees the default request again. However there is a network with OEM_PAID 12535 // connected, so the 2nd OEM_PAID req is already satisfied, so the oemPaidFactory doesn't 12536 // care about networks that don't have OEM_PAID. 12537 expectNoRequestChanged(oemPaidFactory); 12538 oemPaidFactory.assertRequestCountEquals(1); 12539 internetFactory.expectRequestAdd(); 12540 internetFactory.assertRequestCountEquals(1); 12541 12542 // Cell connects again, still with score 50. Back to the previous state. 12543 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 12544 mCellNetworkAgent.connect(true); 12545 expectNoRequestChanged(oemPaidFactory); 12546 oemPaidFactory.assertRequestCountEquals(1); 12547 internetFactory.expectRequestRemove(); 12548 internetFactory.assertRequestCountEquals(0); 12549 12550 // Create a request that holds the upcoming wifi network. 12551 final TestNetworkCallback wifiCallback = new TestNetworkCallback(); 12552 mCm.requestNetwork(new NetworkRequest.Builder().addTransportType(TRANSPORT_WIFI).build(), 12553 wifiCallback); 12554 12555 // Now WiFi connects and it's unmetered, but it's weaker than cell. 12556 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 12557 mWiFiNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED); 12558 mWiFiNetworkAgent.setScore(new NetworkScore.Builder().setLegacyInt(30).setExiting(true) 12559 .build()); // Not the best Internet network, but unmetered 12560 mWiFiNetworkAgent.connect(true); 12561 12562 // The OEM_PAID preference prefers an unmetered network to an OEM_PAID network, so 12563 // the oemPaidFactory can't beat wifi no matter how high its score. 12564 oemPaidFactory.expectRequestRemove(); 12565 expectNoRequestChanged(internetFactory); 12566 12567 mCellNetworkAgent.disconnect(); 12568 // Now that the best internet network (cell, with its 50 score compared to 30 for WiFi 12569 // at this point), the default internet request is satisfied by a network worse than 12570 // the internetFactory announced, so it gets the request. However, there is still an 12571 // unmetered network, so the oemPaidNetworkFactory still can't beat this. 12572 expectNoRequestChanged(oemPaidFactory); 12573 internetFactory.expectRequestAdd(); 12574 mCm.unregisterNetworkCallback(wifiCallback); 12575 } 12576 12577 /** 12578 * Test network priority for OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK in the following order: 12579 * NET_CAPABILITY_NOT_METERED -> NET_CAPABILITY_OEM_PAID 12580 */ 12581 @Test 12582 public void testMultipleDefaultNetworksTracksOemNetworkPreferenceOemPaidNoFallbackCorrectly() 12583 throws Exception { 12584 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 12585 OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK; 12586 setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest(networkPref); 12587 final int expectedDefaultRequestSize = 2; 12588 final int expectedOemPrefRequestSize = 2; 12589 registerDefaultNetworkCallbacks(); 12590 12591 // The fallback as well as the OEM preference should now be tracked. 12592 assertEquals(expectedDefaultRequestSize, mService.mDefaultNetworkRequests.size()); 12593 12594 // Test lowest to highest priority requests. 12595 // Bring up metered cellular. This will satisfy the fallback network but not the pref. 12596 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); 12597 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 12598 mCellNetworkAgent.getNetwork(), 12599 mService.mNoServiceNetwork.network()); 12600 12601 // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID. 12602 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true); 12603 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 12604 mCellNetworkAgent.getNetwork(), 12605 mEthernetNetworkAgent.getNetwork()); 12606 12607 // Bring up unmetered Wi-Fi. This will satisfy NET_CAPABILITY_NOT_METERED. 12608 setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, true); 12609 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 12610 mWiFiNetworkAgent.getNetwork(), 12611 mWiFiNetworkAgent.getNetwork()); 12612 12613 // Disconnecting unmetered Wi-Fi will put the OEM pref on OEM_PAID and fallback on cellular. 12614 setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, false); 12615 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 12616 mCellNetworkAgent.getNetwork(), 12617 mEthernetNetworkAgent.getNetwork()); 12618 12619 // Disconnecting cellular should keep OEM network on OEM_PAID and fallback will be null. 12620 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, false); 12621 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 12622 null, 12623 mEthernetNetworkAgent.getNetwork()); 12624 12625 // Disconnecting OEM_PAID puts the fallback on null and the pref on the disconnected net. 12626 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, false); 12627 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 12628 null, 12629 mService.mNoServiceNetwork.network()); 12630 12631 // default callbacks will be unregistered in tearDown 12632 } 12633 12634 /** 12635 * Test network priority for OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY in the following order: 12636 * NET_CAPABILITY_OEM_PAID 12637 * This preference should only apply to OEM_PAID networks. 12638 */ 12639 @Test 12640 public void testMultipleDefaultNetworksTracksOemNetworkPreferenceOemPaidOnlyCorrectly() 12641 throws Exception { 12642 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 12643 OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY; 12644 setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest(networkPref); 12645 final int expectedDefaultRequestSize = 2; 12646 final int expectedOemPrefRequestSize = 1; 12647 registerDefaultNetworkCallbacks(); 12648 12649 // The fallback as well as the OEM preference should now be tracked. 12650 assertEquals(expectedDefaultRequestSize, mService.mDefaultNetworkRequests.size()); 12651 12652 // Test lowest to highest priority requests. 12653 // Bring up metered cellular. This will satisfy the fallback network. 12654 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); 12655 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 12656 mCellNetworkAgent.getNetwork(), 12657 mService.mNoServiceNetwork.network()); 12658 12659 // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID. 12660 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true); 12661 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 12662 mCellNetworkAgent.getNetwork(), 12663 mEthernetNetworkAgent.getNetwork()); 12664 12665 // Bring up unmetered Wi-Fi. The OEM network shouldn't change, the fallback will take Wi-Fi. 12666 setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, true); 12667 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 12668 mWiFiNetworkAgent.getNetwork(), 12669 mEthernetNetworkAgent.getNetwork()); 12670 12671 // Disconnecting unmetered Wi-Fi shouldn't change the OEM network with fallback on cellular. 12672 setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, false); 12673 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 12674 mCellNetworkAgent.getNetwork(), 12675 mEthernetNetworkAgent.getNetwork()); 12676 12677 // Disconnecting OEM_PAID will keep the fallback on cellular and nothing for OEM_PAID. 12678 // OEM_PAID_ONLY not supporting a fallback now uses the disconnected network. 12679 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, false); 12680 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 12681 mCellNetworkAgent.getNetwork(), 12682 mService.mNoServiceNetwork.network()); 12683 12684 // Disconnecting cellular will put the fallback on null and the pref on disconnected. 12685 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, false); 12686 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 12687 null, 12688 mService.mNoServiceNetwork.network()); 12689 12690 // default callbacks will be unregistered in tearDown 12691 } 12692 12693 /** 12694 * Test network priority for OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY in the following order: 12695 * NET_CAPABILITY_OEM_PRIVATE 12696 * This preference should only apply to OEM_PRIVATE networks. 12697 */ 12698 @Test 12699 public void testMultipleDefaultNetworksTracksOemNetworkPreferenceOemPrivateOnlyCorrectly() 12700 throws Exception { 12701 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 12702 OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY; 12703 setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest(networkPref); 12704 final int expectedDefaultRequestSize = 2; 12705 final int expectedOemPrefRequestSize = 1; 12706 registerDefaultNetworkCallbacks(); 12707 12708 // The fallback as well as the OEM preference should now be tracked. 12709 assertEquals(expectedDefaultRequestSize, mService.mDefaultNetworkRequests.size()); 12710 12711 // Test lowest to highest priority requests. 12712 // Bring up metered cellular. This will satisfy the fallback network. 12713 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); 12714 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 12715 mCellNetworkAgent.getNetwork(), 12716 mService.mNoServiceNetwork.network()); 12717 12718 // Bring up ethernet with OEM_PRIVATE. This will satisfy NET_CAPABILITY_OEM_PRIVATE. 12719 startOemManagedNetwork(false); 12720 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 12721 mCellNetworkAgent.getNetwork(), 12722 mEthernetNetworkAgent.getNetwork()); 12723 12724 // Bring up unmetered Wi-Fi. The OEM network shouldn't change, the fallback will take Wi-Fi. 12725 setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, true); 12726 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 12727 mWiFiNetworkAgent.getNetwork(), 12728 mEthernetNetworkAgent.getNetwork()); 12729 12730 // Disconnecting unmetered Wi-Fi shouldn't change the OEM network with fallback on cellular. 12731 setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, false); 12732 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 12733 mCellNetworkAgent.getNetwork(), 12734 mEthernetNetworkAgent.getNetwork()); 12735 12736 // Disconnecting OEM_PRIVATE will keep the fallback on cellular. 12737 // OEM_PRIVATE_ONLY not supporting a fallback now uses to the disconnected network. 12738 stopOemManagedNetwork(); 12739 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 12740 mCellNetworkAgent.getNetwork(), 12741 mService.mNoServiceNetwork.network()); 12742 12743 // Disconnecting cellular will put the fallback on null and pref on disconnected. 12744 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, false); 12745 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 12746 null, 12747 mService.mNoServiceNetwork.network()); 12748 12749 // default callbacks will be unregistered in tearDown 12750 } 12751 12752 @Test 12753 public void testCapabilityWithOemNetworkPreference() throws Exception { 12754 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 12755 OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY; 12756 setupMultipleDefaultNetworksForOemNetworkPreferenceNotCurrentUidTest(networkPref); 12757 registerDefaultNetworkCallbacks(); 12758 12759 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); 12760 12761 mSystemDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 12762 mDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 12763 12764 mCellNetworkAgent.addCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED); 12765 mSystemDefaultNetworkCallback.expectCapabilitiesThat(mCellNetworkAgent, nc -> 12766 nc.hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED)); 12767 mDefaultNetworkCallback.expectCapabilitiesThat(mCellNetworkAgent, nc -> 12768 nc.hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED)); 12769 12770 // default callbacks will be unregistered in tearDown 12771 } 12772 12773 @Test 12774 public void testSetOemNetworkPreferenceLogsRequest() throws Exception { 12775 mServiceContext.setPermission(DUMP, PERMISSION_GRANTED); 12776 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 12777 OEM_NETWORK_PREFERENCE_OEM_PAID; 12778 final StringWriter stringWriter = new StringWriter(); 12779 final String logIdentifier = "UPDATE INITIATED: OemNetworkPreferences"; 12780 final Pattern pattern = Pattern.compile(logIdentifier); 12781 12782 final int expectedNumLogs = 2; 12783 final UidRangeParcel[] uidRanges = 12784 toUidRangeStableParcels(uidRangesForUids(TEST_PACKAGE_UID)); 12785 12786 // Call twice to generate two logs. 12787 setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges, TEST_PACKAGE_NAME); 12788 setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges, TEST_PACKAGE_NAME); 12789 mService.dump(new FileDescriptor(), new PrintWriter(stringWriter), new String[0]); 12790 12791 final String dumpOutput = stringWriter.toString(); 12792 final Matcher matcher = pattern.matcher(dumpOutput); 12793 int count = 0; 12794 while (matcher.find()) { 12795 count++; 12796 } 12797 assertEquals(expectedNumLogs, count); 12798 } 12799 12800 @Test 12801 public void testGetAllNetworkStateSnapshots() throws Exception { 12802 verifyNoNetwork(); 12803 12804 // Setup test cellular network with specified LinkProperties and NetworkCapabilities, 12805 // verify the content of the snapshot matches. 12806 final LinkProperties cellLp = new LinkProperties(); 12807 final LinkAddress myIpv4Addr = new LinkAddress(InetAddress.getByName("192.0.2.129"), 25); 12808 final LinkAddress myIpv6Addr = new LinkAddress(InetAddress.getByName("2001:db8::1"), 64); 12809 cellLp.setInterfaceName("test01"); 12810 cellLp.addLinkAddress(myIpv4Addr); 12811 cellLp.addLinkAddress(myIpv6Addr); 12812 cellLp.addRoute(new RouteInfo(InetAddress.getByName("fe80::1234"))); 12813 cellLp.addRoute(new RouteInfo(InetAddress.getByName("192.0.2.254"))); 12814 cellLp.addRoute(new RouteInfo(myIpv4Addr, null)); 12815 cellLp.addRoute(new RouteInfo(myIpv6Addr, null)); 12816 final NetworkCapabilities cellNcTemplate = new NetworkCapabilities.Builder() 12817 .addTransportType(TRANSPORT_CELLULAR).addCapability(NET_CAPABILITY_MMS).build(); 12818 12819 final TestNetworkCallback cellCb = new TestNetworkCallback(); 12820 mCm.requestNetwork(new NetworkRequest.Builder().addCapability(NET_CAPABILITY_MMS).build(), 12821 cellCb); 12822 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp, cellNcTemplate); 12823 mCellNetworkAgent.connect(true); 12824 cellCb.expectAvailableCallbacksUnvalidated(mCellNetworkAgent); 12825 List<NetworkStateSnapshot> snapshots = mCm.getAllNetworkStateSnapshots(); 12826 assertLength(1, snapshots); 12827 12828 // Compose the expected cellular snapshot for verification. 12829 final NetworkCapabilities cellNc = 12830 mCm.getNetworkCapabilities(mCellNetworkAgent.getNetwork()); 12831 final NetworkStateSnapshot cellSnapshot = new NetworkStateSnapshot( 12832 mCellNetworkAgent.getNetwork(), cellNc, cellLp, 12833 null, ConnectivityManager.TYPE_MOBILE); 12834 assertEquals(cellSnapshot, snapshots.get(0)); 12835 12836 // Connect wifi and verify the snapshots. 12837 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 12838 mWiFiNetworkAgent.connect(true); 12839 waitForIdle(); 12840 // Compose the expected wifi snapshot for verification. 12841 final NetworkCapabilities wifiNc = 12842 mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()); 12843 final NetworkStateSnapshot wifiSnapshot = new NetworkStateSnapshot( 12844 mWiFiNetworkAgent.getNetwork(), wifiNc, new LinkProperties(), null, 12845 ConnectivityManager.TYPE_WIFI); 12846 12847 snapshots = mCm.getAllNetworkStateSnapshots(); 12848 assertLength(2, snapshots); 12849 assertContainsAll(snapshots, cellSnapshot, wifiSnapshot); 12850 12851 // Set cellular as suspended, verify the snapshots will not contain suspended networks. 12852 // TODO: Consider include SUSPENDED networks, which should be considered as 12853 // temporary shortage of connectivity of a connected network. 12854 mCellNetworkAgent.suspend(); 12855 waitForIdle(); 12856 snapshots = mCm.getAllNetworkStateSnapshots(); 12857 assertLength(1, snapshots); 12858 assertEquals(wifiSnapshot, snapshots.get(0)); 12859 12860 // Disconnect wifi, verify the snapshots contain nothing. 12861 mWiFiNetworkAgent.disconnect(); 12862 waitForIdle(); 12863 snapshots = mCm.getAllNetworkStateSnapshots(); 12864 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 12865 assertLength(0, snapshots); 12866 12867 mCellNetworkAgent.resume(); 12868 waitForIdle(); 12869 snapshots = mCm.getAllNetworkStateSnapshots(); 12870 assertLength(1, snapshots); 12871 assertEquals(cellSnapshot, snapshots.get(0)); 12872 12873 mCellNetworkAgent.disconnect(); 12874 waitForIdle(); 12875 verifyNoNetwork(); 12876 mCm.unregisterNetworkCallback(cellCb); 12877 } 12878 12879 // Cannot be part of MockNetworkFactory since it requires method of the test. 12880 private void expectNoRequestChanged(@NonNull MockNetworkFactory factory) { 12881 waitForIdle(); 12882 factory.assertNoRequestChanged(); 12883 } 12884 12885 @Test 12886 public void testRegisterBestMatchingNetworkCallback_noIssueToFactory() throws Exception { 12887 // Prepare mock mms factory. 12888 final HandlerThread handlerThread = new HandlerThread("MockCellularFactory"); 12889 handlerThread.start(); 12890 NetworkCapabilities filter = new NetworkCapabilities() 12891 .addTransportType(TRANSPORT_CELLULAR) 12892 .addCapability(NET_CAPABILITY_MMS); 12893 final MockNetworkFactory testFactory = new MockNetworkFactory(handlerThread.getLooper(), 12894 mServiceContext, "testFactory", filter, mCsHandlerThread); 12895 testFactory.setScoreFilter(40); 12896 12897 try { 12898 // Register the factory. It doesn't see the default request because its filter does 12899 // not include INTERNET. 12900 testFactory.register(); 12901 expectNoRequestChanged(testFactory); 12902 testFactory.assertRequestCountEquals(0); 12903 // The factory won't try to start the network since the default request doesn't 12904 // match the filter (no INTERNET capability). 12905 assertFalse(testFactory.getMyStartRequested()); 12906 12907 // Register callback for listening best matching network. Verify that the request won't 12908 // be sent to factory. 12909 final TestNetworkCallback bestMatchingCb = new TestNetworkCallback(); 12910 mCm.registerBestMatchingNetworkCallback( 12911 new NetworkRequest.Builder().addCapability(NET_CAPABILITY_MMS).build(), 12912 bestMatchingCb, mCsHandlerThread.getThreadHandler()); 12913 bestMatchingCb.assertNoCallback(); 12914 expectNoRequestChanged(testFactory); 12915 testFactory.assertRequestCountEquals(0); 12916 assertFalse(testFactory.getMyStartRequested()); 12917 12918 // Fire a normal mms request, verify the factory will only see the request. 12919 final TestNetworkCallback mmsNetworkCallback = new TestNetworkCallback(); 12920 final NetworkRequest mmsRequest = new NetworkRequest.Builder() 12921 .addCapability(NET_CAPABILITY_MMS).build(); 12922 mCm.requestNetwork(mmsRequest, mmsNetworkCallback); 12923 testFactory.expectRequestAdd(); 12924 testFactory.assertRequestCountEquals(1); 12925 assertTrue(testFactory.getMyStartRequested()); 12926 12927 // Unregister best matching callback, verify factory see no change. 12928 mCm.unregisterNetworkCallback(bestMatchingCb); 12929 expectNoRequestChanged(testFactory); 12930 testFactory.assertRequestCountEquals(1); 12931 assertTrue(testFactory.getMyStartRequested()); 12932 } finally { 12933 testFactory.terminate(); 12934 } 12935 } 12936 12937 @Test 12938 public void testRegisterBestMatchingNetworkCallback_trackBestNetwork() throws Exception { 12939 final TestNetworkCallback bestMatchingCb = new TestNetworkCallback(); 12940 mCm.registerBestMatchingNetworkCallback( 12941 new NetworkRequest.Builder().addCapability(NET_CAPABILITY_TRUSTED).build(), 12942 bestMatchingCb, mCsHandlerThread.getThreadHandler()); 12943 12944 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 12945 mCellNetworkAgent.connect(true); 12946 bestMatchingCb.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 12947 12948 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 12949 mWiFiNetworkAgent.connect(true); 12950 bestMatchingCb.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent); 12951 12952 // Change something on cellular to trigger capabilities changed, since the callback 12953 // only cares about the best network, verify it received nothing from cellular. 12954 mCellNetworkAgent.addCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED); 12955 bestMatchingCb.assertNoCallback(); 12956 12957 // Make cellular the best network again, verify the callback now tracks cellular. 12958 mWiFiNetworkAgent.adjustScore(-50); 12959 bestMatchingCb.expectAvailableCallbacksValidated(mCellNetworkAgent); 12960 12961 // Make cellular temporary non-trusted, which will not satisfying the request. 12962 // Verify the callback switch from/to the other network accordingly. 12963 mCellNetworkAgent.removeCapability(NET_CAPABILITY_TRUSTED); 12964 bestMatchingCb.expectAvailableCallbacksValidated(mWiFiNetworkAgent); 12965 mCellNetworkAgent.addCapability(NET_CAPABILITY_TRUSTED); 12966 bestMatchingCb.expectAvailableDoubleValidatedCallbacks(mCellNetworkAgent); 12967 12968 // Verify the callback doesn't care about wifi disconnect. 12969 mWiFiNetworkAgent.disconnect(); 12970 bestMatchingCb.assertNoCallback(); 12971 mCellNetworkAgent.disconnect(); 12972 bestMatchingCb.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 12973 } 12974 12975 private UidRangeParcel[] uidRangeFor(final UserHandle handle) { 12976 UidRange range = UidRange.createForUser(handle); 12977 return new UidRangeParcel[] { new UidRangeParcel(range.start, range.stop) }; 12978 } 12979 12980 private static class TestOnCompleteListener implements Runnable { 12981 final class OnComplete {} 12982 final ArrayTrackRecord<OnComplete>.ReadHead mHistory = 12983 new ArrayTrackRecord<OnComplete>().newReadHead(); 12984 12985 @Override 12986 public void run() { 12987 mHistory.add(new OnComplete()); 12988 } 12989 12990 public void expectOnComplete() { 12991 assertNotNull(mHistory.poll(TIMEOUT_MS, it -> true)); 12992 } 12993 } 12994 12995 private TestNetworkAgentWrapper makeEnterpriseNetworkAgent() throws Exception { 12996 final NetworkCapabilities workNc = new NetworkCapabilities(); 12997 workNc.addCapability(NET_CAPABILITY_ENTERPRISE); 12998 workNc.removeCapability(NET_CAPABILITY_NOT_RESTRICTED); 12999 return new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, new LinkProperties(), workNc); 13000 } 13001 13002 private TestNetworkCallback mEnterpriseCallback; 13003 private UserHandle setupEnterpriseNetwork() { 13004 final UserHandle userHandle = UserHandle.of(TEST_WORK_PROFILE_USER_ID); 13005 mServiceContext.setWorkProfile(userHandle, true); 13006 13007 // File a request to avoid the enterprise network being disconnected as soon as the default 13008 // request goes away – it would make impossible to test that networkRemoveUidRanges 13009 // is called, as the network would disconnect first for lack of a request. 13010 mEnterpriseCallback = new TestNetworkCallback(); 13011 final NetworkRequest keepUpRequest = new NetworkRequest.Builder() 13012 .addCapability(NET_CAPABILITY_ENTERPRISE) 13013 .build(); 13014 mCm.requestNetwork(keepUpRequest, mEnterpriseCallback); 13015 return userHandle; 13016 } 13017 13018 private void maybeTearDownEnterpriseNetwork() { 13019 if (null != mEnterpriseCallback) { 13020 mCm.unregisterNetworkCallback(mEnterpriseCallback); 13021 } 13022 } 13023 13024 /** 13025 * Make sure per-profile networking preference behaves as expected when the enterprise network 13026 * goes up and down while the preference is active. Make sure they behave as expected whether 13027 * there is a general default network or not. 13028 */ 13029 @Test 13030 public void testPreferenceForUserNetworkUpDown() throws Exception { 13031 final InOrder inOrder = inOrder(mMockNetd); 13032 final UserHandle testHandle = setupEnterpriseNetwork(); 13033 registerDefaultNetworkCallbacks(); 13034 13035 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 13036 mCellNetworkAgent.connect(true); 13037 13038 mSystemDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 13039 mDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 13040 mProfileDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 13041 inOrder.verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( 13042 mCellNetworkAgent.getNetwork().netId, INetd.PERMISSION_NONE)); 13043 13044 13045 final TestOnCompleteListener listener = new TestOnCompleteListener(); 13046 mCm.setProfileNetworkPreference(testHandle, PROFILE_NETWORK_PREFERENCE_ENTERPRISE, 13047 r -> r.run(), listener); 13048 listener.expectOnComplete(); 13049 13050 // Setting a network preference for this user will create a new set of routing rules for 13051 // the UID range that corresponds to this user, so as to define the default network 13052 // for these apps separately. This is true because the multi-layer request relevant to 13053 // this UID range contains a TRACK_DEFAULT, so the range will be moved through UID-specific 13054 // rules to the correct network – in this case the system default network. The case where 13055 // the default network for the profile happens to be the same as the system default 13056 // is not handled specially, the rules are always active as long as a preference is set. 13057 inOrder.verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 13058 mCellNetworkAgent.getNetwork().netId, uidRangeFor(testHandle), 13059 PREFERENCE_PRIORITY_PROFILE)); 13060 13061 // The enterprise network is not ready yet. 13062 assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback, 13063 mProfileDefaultNetworkCallback); 13064 13065 final TestNetworkAgentWrapper workAgent = makeEnterpriseNetworkAgent(); 13066 workAgent.connect(false); 13067 13068 mProfileDefaultNetworkCallback.expectAvailableCallbacksUnvalidated(workAgent); 13069 mSystemDefaultNetworkCallback.assertNoCallback(); 13070 mDefaultNetworkCallback.assertNoCallback(); 13071 inOrder.verify(mMockNetd).networkCreate( 13072 nativeNetworkConfigPhysical(workAgent.getNetwork().netId, INetd.PERMISSION_SYSTEM)); 13073 inOrder.verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 13074 workAgent.getNetwork().netId, uidRangeFor(testHandle), 13075 PREFERENCE_PRIORITY_PROFILE)); 13076 inOrder.verify(mMockNetd).networkRemoveUidRangesParcel(new NativeUidRangeConfig( 13077 mCellNetworkAgent.getNetwork().netId, uidRangeFor(testHandle), 13078 PREFERENCE_PRIORITY_PROFILE)); 13079 13080 // Make sure changes to the work agent send callbacks to the app in the work profile, but 13081 // not to the other apps. 13082 workAgent.setNetworkValid(true /* isStrictMode */); 13083 workAgent.mNetworkMonitor.forceReevaluation(Process.myUid()); 13084 mProfileDefaultNetworkCallback.expectCapabilitiesThat(workAgent, 13085 nc -> nc.hasCapability(NET_CAPABILITY_VALIDATED) 13086 && nc.hasCapability(NET_CAPABILITY_ENTERPRISE)); 13087 assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback); 13088 13089 workAgent.addCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED); 13090 mProfileDefaultNetworkCallback.expectCapabilitiesThat(workAgent, nc -> 13091 nc.hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED)); 13092 assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback); 13093 13094 // Conversely, change a capability on the system-wide default network and make sure 13095 // that only the apps outside of the work profile receive the callbacks. 13096 mCellNetworkAgent.addCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED); 13097 mSystemDefaultNetworkCallback.expectCapabilitiesThat(mCellNetworkAgent, nc -> 13098 nc.hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED)); 13099 mDefaultNetworkCallback.expectCapabilitiesThat(mCellNetworkAgent, nc -> 13100 nc.hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED)); 13101 mProfileDefaultNetworkCallback.assertNoCallback(); 13102 13103 // Disconnect and reconnect the system-wide default network and make sure that the 13104 // apps on this network see the appropriate callbacks, and the app on the work profile 13105 // doesn't because it continues to use the enterprise network. 13106 mCellNetworkAgent.disconnect(); 13107 mSystemDefaultNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 13108 mDefaultNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 13109 mProfileDefaultNetworkCallback.assertNoCallback(); 13110 inOrder.verify(mMockNetd).networkDestroy(mCellNetworkAgent.getNetwork().netId); 13111 13112 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 13113 mCellNetworkAgent.connect(true); 13114 mSystemDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 13115 mDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 13116 mProfileDefaultNetworkCallback.assertNoCallback(); 13117 inOrder.verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( 13118 mCellNetworkAgent.getNetwork().netId, INetd.PERMISSION_NONE)); 13119 13120 // When the agent disconnects, test that the app on the work profile falls back to the 13121 // default network. 13122 workAgent.disconnect(); 13123 mProfileDefaultNetworkCallback.expectCallback(CallbackEntry.LOST, workAgent); 13124 mProfileDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellNetworkAgent); 13125 assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback); 13126 inOrder.verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 13127 mCellNetworkAgent.getNetwork().netId, uidRangeFor(testHandle), 13128 PREFERENCE_PRIORITY_PROFILE)); 13129 inOrder.verify(mMockNetd).networkDestroy(workAgent.getNetwork().netId); 13130 13131 mCellNetworkAgent.disconnect(); 13132 mSystemDefaultNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 13133 mDefaultNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 13134 mProfileDefaultNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 13135 13136 // Waiting for the handler to be idle before checking for networkDestroy is necessary 13137 // here because ConnectivityService calls onLost before the network is fully torn down. 13138 waitForIdle(); 13139 inOrder.verify(mMockNetd).networkDestroy(mCellNetworkAgent.getNetwork().netId); 13140 13141 // If the control comes here, callbacks seem to behave correctly in the presence of 13142 // a default network when the enterprise network goes up and down. Now, make sure they 13143 // also behave correctly in the absence of a system-wide default network. 13144 final TestNetworkAgentWrapper workAgent2 = makeEnterpriseNetworkAgent(); 13145 workAgent2.connect(false); 13146 13147 mProfileDefaultNetworkCallback.expectAvailableCallbacksUnvalidated(workAgent2); 13148 assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback); 13149 inOrder.verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( 13150 workAgent2.getNetwork().netId, INetd.PERMISSION_SYSTEM)); 13151 inOrder.verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 13152 workAgent2.getNetwork().netId, uidRangeFor(testHandle), 13153 PREFERENCE_PRIORITY_PROFILE)); 13154 13155 workAgent2.setNetworkValid(true /* isStrictMode */); 13156 workAgent2.mNetworkMonitor.forceReevaluation(Process.myUid()); 13157 mProfileDefaultNetworkCallback.expectCapabilitiesThat(workAgent2, 13158 nc -> nc.hasCapability(NET_CAPABILITY_ENTERPRISE) 13159 && !nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)); 13160 assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback); 13161 inOrder.verify(mMockNetd, never()).networkAddUidRangesParcel(any()); 13162 13163 // When the agent disconnects, test that the app on the work profile falls back to the 13164 // default network. 13165 workAgent2.disconnect(); 13166 mProfileDefaultNetworkCallback.expectCallback(CallbackEntry.LOST, workAgent2); 13167 assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback); 13168 inOrder.verify(mMockNetd).networkDestroy(workAgent2.getNetwork().netId); 13169 13170 assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback, 13171 mProfileDefaultNetworkCallback); 13172 13173 // Callbacks will be unregistered by tearDown() 13174 } 13175 13176 /** 13177 * Test that, in a given networking context, calling setPreferenceForUser to set per-profile 13178 * defaults on then off works as expected. 13179 */ 13180 @Test 13181 public void testSetPreferenceForUserOnOff() throws Exception { 13182 final InOrder inOrder = inOrder(mMockNetd); 13183 final UserHandle testHandle = setupEnterpriseNetwork(); 13184 13185 // Connect both a regular cell agent and an enterprise network first. 13186 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 13187 mCellNetworkAgent.connect(true); 13188 13189 final TestNetworkAgentWrapper workAgent = makeEnterpriseNetworkAgent(); 13190 workAgent.connect(true); 13191 13192 final TestOnCompleteListener listener = new TestOnCompleteListener(); 13193 mCm.setProfileNetworkPreference(testHandle, PROFILE_NETWORK_PREFERENCE_ENTERPRISE, 13194 r -> r.run(), listener); 13195 listener.expectOnComplete(); 13196 inOrder.verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( 13197 mCellNetworkAgent.getNetwork().netId, INetd.PERMISSION_NONE)); 13198 inOrder.verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 13199 workAgent.getNetwork().netId, uidRangeFor(testHandle), 13200 PREFERENCE_PRIORITY_PROFILE)); 13201 13202 registerDefaultNetworkCallbacks(); 13203 13204 mSystemDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellNetworkAgent); 13205 mDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellNetworkAgent); 13206 mProfileDefaultNetworkCallback.expectAvailableCallbacksValidated(workAgent); 13207 13208 mCm.setProfileNetworkPreference(testHandle, PROFILE_NETWORK_PREFERENCE_DEFAULT, 13209 r -> r.run(), listener); 13210 listener.expectOnComplete(); 13211 13212 mProfileDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellNetworkAgent); 13213 assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback); 13214 inOrder.verify(mMockNetd).networkRemoveUidRangesParcel(new NativeUidRangeConfig( 13215 workAgent.getNetwork().netId, uidRangeFor(testHandle), 13216 PREFERENCE_PRIORITY_PROFILE)); 13217 13218 workAgent.disconnect(); 13219 mCellNetworkAgent.disconnect(); 13220 13221 // Callbacks will be unregistered by tearDown() 13222 } 13223 13224 /** 13225 * Test per-profile default networks for two different profiles concurrently. 13226 */ 13227 @Test 13228 public void testSetPreferenceForTwoProfiles() throws Exception { 13229 final InOrder inOrder = inOrder(mMockNetd); 13230 final UserHandle testHandle2 = setupEnterpriseNetwork(); 13231 final UserHandle testHandle4 = UserHandle.of(TEST_WORK_PROFILE_USER_ID + 2); 13232 mServiceContext.setWorkProfile(testHandle4, true); 13233 registerDefaultNetworkCallbacks(); 13234 13235 final TestNetworkCallback app4Cb = new TestNetworkCallback(); 13236 final int testWorkProfileAppUid4 = 13237 UserHandle.getUid(testHandle4.getIdentifier(), TEST_APP_ID); 13238 registerDefaultNetworkCallbackAsUid(app4Cb, testWorkProfileAppUid4); 13239 13240 // Connect both a regular cell agent and an enterprise network first. 13241 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 13242 mCellNetworkAgent.connect(true); 13243 13244 final TestNetworkAgentWrapper workAgent = makeEnterpriseNetworkAgent(); 13245 workAgent.connect(true); 13246 13247 mSystemDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 13248 mDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 13249 mProfileDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 13250 app4Cb.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 13251 inOrder.verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( 13252 mCellNetworkAgent.getNetwork().netId, INetd.PERMISSION_NONE)); 13253 inOrder.verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( 13254 workAgent.getNetwork().netId, INetd.PERMISSION_SYSTEM)); 13255 13256 final TestOnCompleteListener listener = new TestOnCompleteListener(); 13257 mCm.setProfileNetworkPreference(testHandle2, PROFILE_NETWORK_PREFERENCE_ENTERPRISE, 13258 r -> r.run(), listener); 13259 listener.expectOnComplete(); 13260 inOrder.verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 13261 workAgent.getNetwork().netId, uidRangeFor(testHandle2), 13262 PREFERENCE_PRIORITY_PROFILE)); 13263 13264 mProfileDefaultNetworkCallback.expectAvailableCallbacksValidated(workAgent); 13265 assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback, 13266 app4Cb); 13267 13268 mCm.setProfileNetworkPreference(testHandle4, PROFILE_NETWORK_PREFERENCE_ENTERPRISE, 13269 r -> r.run(), listener); 13270 listener.expectOnComplete(); 13271 inOrder.verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 13272 workAgent.getNetwork().netId, uidRangeFor(testHandle4), 13273 PREFERENCE_PRIORITY_PROFILE)); 13274 13275 app4Cb.expectAvailableCallbacksValidated(workAgent); 13276 assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback, 13277 mProfileDefaultNetworkCallback); 13278 13279 mCm.setProfileNetworkPreference(testHandle2, PROFILE_NETWORK_PREFERENCE_DEFAULT, 13280 r -> r.run(), listener); 13281 listener.expectOnComplete(); 13282 inOrder.verify(mMockNetd).networkRemoveUidRangesParcel(new NativeUidRangeConfig( 13283 workAgent.getNetwork().netId, uidRangeFor(testHandle2), 13284 PREFERENCE_PRIORITY_PROFILE)); 13285 13286 mProfileDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellNetworkAgent); 13287 assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback, 13288 app4Cb); 13289 13290 workAgent.disconnect(); 13291 mCellNetworkAgent.disconnect(); 13292 13293 mCm.unregisterNetworkCallback(app4Cb); 13294 // Other callbacks will be unregistered by tearDown() 13295 } 13296 13297 @Test 13298 public void testProfilePreferenceRemovedUponUserRemoved() throws Exception { 13299 final InOrder inOrder = inOrder(mMockNetd); 13300 final UserHandle testHandle = setupEnterpriseNetwork(); 13301 13302 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 13303 mCellNetworkAgent.connect(true); 13304 13305 final TestOnCompleteListener listener = new TestOnCompleteListener(); 13306 mCm.setProfileNetworkPreference(testHandle, PROFILE_NETWORK_PREFERENCE_ENTERPRISE, 13307 r -> r.run(), listener); 13308 listener.expectOnComplete(); 13309 inOrder.verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( 13310 mCellNetworkAgent.getNetwork().netId, INetd.PERMISSION_NONE)); 13311 inOrder.verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 13312 mCellNetworkAgent.getNetwork().netId, uidRangeFor(testHandle), 13313 PREFERENCE_PRIORITY_PROFILE)); 13314 13315 final Intent removedIntent = new Intent(ACTION_USER_REMOVED); 13316 removedIntent.putExtra(Intent.EXTRA_USER, testHandle); 13317 processBroadcast(removedIntent); 13318 13319 inOrder.verify(mMockNetd).networkRemoveUidRangesParcel(new NativeUidRangeConfig( 13320 mCellNetworkAgent.getNetwork().netId, uidRangeFor(testHandle), 13321 PREFERENCE_PRIORITY_PROFILE)); 13322 } 13323 13324 /** 13325 * Make sure wrong preferences for per-profile default networking are rejected. 13326 */ 13327 @Test 13328 public void testProfileNetworkPrefWrongPreference() throws Exception { 13329 final UserHandle testHandle = UserHandle.of(TEST_WORK_PROFILE_USER_ID); 13330 mServiceContext.setWorkProfile(testHandle, true); 13331 assertThrows("Should not be able to set an illegal preference", 13332 IllegalArgumentException.class, 13333 () -> mCm.setProfileNetworkPreference(testHandle, 13334 PROFILE_NETWORK_PREFERENCE_ENTERPRISE + 1, null, null)); 13335 } 13336 13337 /** 13338 * Make sure requests for per-profile default networking for a non-work profile are 13339 * rejected 13340 */ 13341 @Test 13342 public void testProfileNetworkPrefWrongProfile() throws Exception { 13343 final UserHandle testHandle = UserHandle.of(TEST_WORK_PROFILE_USER_ID); 13344 mServiceContext.setWorkProfile(testHandle, false); 13345 assertThrows("Should not be able to set a user pref for a non-work profile", 13346 IllegalArgumentException.class , () -> 13347 mCm.setProfileNetworkPreference(testHandle, 13348 PROFILE_NETWORK_PREFERENCE_ENTERPRISE, null, null)); 13349 } 13350 13351 @Test 13352 public void testSubIdsClearedWithoutNetworkFactoryPermission() throws Exception { 13353 mServiceContext.setPermission(NETWORK_FACTORY, PERMISSION_DENIED); 13354 final NetworkCapabilities nc = new NetworkCapabilities(); 13355 nc.setSubscriptionIds(Collections.singleton(Process.myUid())); 13356 13357 final NetworkCapabilities result = 13358 mService.networkCapabilitiesRestrictedForCallerPermissions( 13359 nc, Process.myPid(), Process.myUid()); 13360 assertTrue(result.getSubscriptionIds().isEmpty()); 13361 } 13362 13363 @Test 13364 public void testSubIdsExistWithNetworkFactoryPermission() throws Exception { 13365 mServiceContext.setPermission(NETWORK_FACTORY, PERMISSION_GRANTED); 13366 13367 final Set<Integer> subIds = Collections.singleton(Process.myUid()); 13368 final NetworkCapabilities nc = new NetworkCapabilities(); 13369 nc.setSubscriptionIds(subIds); 13370 13371 final NetworkCapabilities result = 13372 mService.networkCapabilitiesRestrictedForCallerPermissions( 13373 nc, Process.myPid(), Process.myUid()); 13374 assertEquals(subIds, result.getSubscriptionIds()); 13375 } 13376 13377 private NetworkRequest getRequestWithSubIds() { 13378 return new NetworkRequest.Builder() 13379 .setSubscriptionIds(Collections.singleton(Process.myUid())) 13380 .build(); 13381 } 13382 13383 @Test 13384 public void testNetworkRequestWithSubIdsWithNetworkFactoryPermission() throws Exception { 13385 mServiceContext.setPermission(NETWORK_FACTORY, PERMISSION_GRANTED); 13386 final PendingIntent pendingIntent = PendingIntent.getBroadcast( 13387 mContext, 0 /* requestCode */, new Intent("a"), FLAG_IMMUTABLE); 13388 final NetworkCallback networkCallback1 = new NetworkCallback(); 13389 final NetworkCallback networkCallback2 = new NetworkCallback(); 13390 13391 mCm.requestNetwork(getRequestWithSubIds(), networkCallback1); 13392 mCm.requestNetwork(getRequestWithSubIds(), pendingIntent); 13393 mCm.registerNetworkCallback(getRequestWithSubIds(), networkCallback2); 13394 13395 mCm.unregisterNetworkCallback(networkCallback1); 13396 mCm.releaseNetworkRequest(pendingIntent); 13397 mCm.unregisterNetworkCallback(networkCallback2); 13398 } 13399 13400 @Test 13401 public void testNetworkRequestWithSubIdsWithoutNetworkFactoryPermission() throws Exception { 13402 mServiceContext.setPermission(NETWORK_FACTORY, PERMISSION_DENIED); 13403 final PendingIntent pendingIntent = PendingIntent.getBroadcast( 13404 mContext, 0 /* requestCode */, new Intent("a"), FLAG_IMMUTABLE); 13405 13406 final Class<SecurityException> expected = SecurityException.class; 13407 assertThrows( 13408 expected, () -> mCm.requestNetwork(getRequestWithSubIds(), new NetworkCallback())); 13409 assertThrows(expected, () -> mCm.requestNetwork(getRequestWithSubIds(), pendingIntent)); 13410 assertThrows( 13411 expected, 13412 () -> mCm.registerNetworkCallback(getRequestWithSubIds(), new NetworkCallback())); 13413 } 13414 13415 /** 13416 * Validate request counts are counted accurately on setProfileNetworkPreference on set/replace. 13417 */ 13418 @Test 13419 public void testProfileNetworkPrefCountsRequestsCorrectlyOnSet() throws Exception { 13420 final UserHandle testHandle = setupEnterpriseNetwork(); 13421 final TestOnCompleteListener listener = new TestOnCompleteListener(); 13422 // Leave one request available so the profile preference can be set. 13423 testRequestCountLimits(1 /* countToLeaveAvailable */, () -> { 13424 withPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, 13425 Process.myPid(), Process.myUid(), () -> { 13426 // Set initially to test the limit prior to having existing requests. 13427 mCm.setProfileNetworkPreference(testHandle, 13428 PROFILE_NETWORK_PREFERENCE_ENTERPRISE, 13429 Runnable::run, listener); 13430 }); 13431 listener.expectOnComplete(); 13432 13433 // Simulate filing requests as some app on the work profile 13434 final int otherAppUid = UserHandle.getUid(TEST_WORK_PROFILE_USER_ID, 13435 UserHandle.getAppId(Process.myUid() + 1)); 13436 final int remainingCount = ConnectivityService.MAX_NETWORK_REQUESTS_PER_UID 13437 - mService.mNetworkRequestCounter.mUidToNetworkRequestCount.get(otherAppUid) 13438 - 1; 13439 final NetworkCallback[] callbacks = new NetworkCallback[remainingCount]; 13440 doAsUid(otherAppUid, () -> { 13441 for (int i = 0; i < remainingCount; ++i) { 13442 callbacks[i] = new TestableNetworkCallback(); 13443 mCm.registerDefaultNetworkCallback(callbacks[i]); 13444 } 13445 }); 13446 13447 withPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, 13448 Process.myPid(), Process.myUid(), () -> { 13449 // re-set so as to test the limit as part of replacing existing requests. 13450 mCm.setProfileNetworkPreference(testHandle, 13451 PROFILE_NETWORK_PREFERENCE_ENTERPRISE, Runnable::run, listener); 13452 }); 13453 listener.expectOnComplete(); 13454 13455 doAsUid(otherAppUid, () -> { 13456 for (final NetworkCallback callback : callbacks) { 13457 mCm.unregisterNetworkCallback(callback); 13458 } 13459 }); 13460 }); 13461 } 13462 13463 /** 13464 * Validate request counts are counted accurately on setOemNetworkPreference on set/replace. 13465 */ 13466 @Test 13467 public void testSetOemNetworkPreferenceCountsRequestsCorrectlyOnSet() throws Exception { 13468 mockHasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, true); 13469 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 13470 OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY; 13471 // Leave one request available so the OEM preference can be set. 13472 testRequestCountLimits(1 /* countToLeaveAvailable */, () -> 13473 withPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, () -> { 13474 // Set initially to test the limit prior to having existing requests. 13475 final TestOemListenerCallback listener = new TestOemListenerCallback(); 13476 mService.setOemNetworkPreference( 13477 createDefaultOemNetworkPreferences(networkPref), listener); 13478 listener.expectOnComplete(); 13479 13480 // re-set so as to test the limit as part of replacing existing requests. 13481 mService.setOemNetworkPreference( 13482 createDefaultOemNetworkPreferences(networkPref), listener); 13483 listener.expectOnComplete(); 13484 })); 13485 } 13486 13487 private void testRequestCountLimits(final int countToLeaveAvailable, 13488 @NonNull final ExceptionalRunnable r) throws Exception { 13489 final ArraySet<TestNetworkCallback> callbacks = new ArraySet<>(); 13490 try { 13491 final int requestCount = mService.mSystemNetworkRequestCounter 13492 .mUidToNetworkRequestCount.get(Process.myUid()); 13493 // The limit is hit when total requests = limit - 1, and exceeded with a crash when 13494 // total requests >= limit. 13495 final int countToFile = 13496 MAX_NETWORK_REQUESTS_PER_SYSTEM_UID - requestCount - countToLeaveAvailable; 13497 // Need permission so registerDefaultNetworkCallback uses mSystemNetworkRequestCounter 13498 withPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, () -> { 13499 for (int i = 1; i < countToFile; i++) { 13500 final TestNetworkCallback cb = new TestNetworkCallback(); 13501 mCm.registerDefaultNetworkCallback(cb); 13502 callbacks.add(cb); 13503 } 13504 assertEquals(MAX_NETWORK_REQUESTS_PER_SYSTEM_UID - 1 - countToLeaveAvailable, 13505 mService.mSystemNetworkRequestCounter 13506 .mUidToNetworkRequestCount.get(Process.myUid())); 13507 }); 13508 // Code to run to check if it triggers a max request count limit error. 13509 r.run(); 13510 } finally { 13511 for (final TestNetworkCallback cb : callbacks) { 13512 mCm.unregisterNetworkCallback(cb); 13513 } 13514 } 13515 } 13516 13517 private void assertCreateNrisFromMobileDataPreferredUids(Set<Integer> uids) { 13518 final Set<NetworkRequestInfo> nris = 13519 mService.createNrisFromMobileDataPreferredUids(uids); 13520 final NetworkRequestInfo nri = nris.iterator().next(); 13521 // Verify that one NRI is created with multilayer requests. Because one NRI can contain 13522 // multiple uid ranges, so it only need create one NRI here. 13523 assertEquals(1, nris.size()); 13524 assertTrue(nri.isMultilayerRequest()); 13525 assertEquals(nri.getUids(), uidRangesForUids(uids)); 13526 assertEquals(PREFERENCE_PRIORITY_MOBILE_DATA_PREFERERRED, nri.mPreferencePriority); 13527 } 13528 13529 /** 13530 * Test createNrisFromMobileDataPreferredUids returns correct NetworkRequestInfo. 13531 */ 13532 @Test 13533 public void testCreateNrisFromMobileDataPreferredUids() { 13534 // Verify that empty uid set should not create any NRI for it. 13535 final Set<NetworkRequestInfo> nrisNoUid = 13536 mService.createNrisFromMobileDataPreferredUids(new ArraySet<>()); 13537 assertEquals(0, nrisNoUid.size()); 13538 13539 final int uid1 = PRIMARY_USER_HANDLE.getUid(TEST_PACKAGE_UID); 13540 final int uid2 = PRIMARY_USER_HANDLE.getUid(TEST_PACKAGE_UID2); 13541 final int uid3 = SECONDARY_USER_HANDLE.getUid(TEST_PACKAGE_UID); 13542 assertCreateNrisFromMobileDataPreferredUids(Set.of(uid1)); 13543 assertCreateNrisFromMobileDataPreferredUids(Set.of(uid1, uid3)); 13544 assertCreateNrisFromMobileDataPreferredUids(Set.of(uid1, uid2)); 13545 } 13546 13547 private void setAndUpdateMobileDataPreferredUids(Set<Integer> uids) { 13548 ConnectivitySettingsManager.setMobileDataPreferredUids(mServiceContext, uids); 13549 mService.updateMobileDataPreferredUids(); 13550 waitForIdle(); 13551 } 13552 13553 /** 13554 * Test that MOBILE_DATA_PREFERRED_UIDS changes will send correct net id and uid ranges to netd. 13555 */ 13556 @Test 13557 public void testMobileDataPreferredUidsChanged() throws Exception { 13558 final InOrder inorder = inOrder(mMockNetd); 13559 registerDefaultNetworkCallbacks(); 13560 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 13561 mCellNetworkAgent.connect(true); 13562 mDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 13563 mTestPackageDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 13564 13565 final int cellNetId = mCellNetworkAgent.getNetwork().netId; 13566 inorder.verify(mMockNetd, times(1)).networkCreate(nativeNetworkConfigPhysical( 13567 cellNetId, INetd.PERMISSION_NONE)); 13568 13569 // Initial mobile data preferred uids status. 13570 setAndUpdateMobileDataPreferredUids(Set.of()); 13571 inorder.verify(mMockNetd, never()).networkAddUidRangesParcel(any()); 13572 inorder.verify(mMockNetd, never()).networkRemoveUidRangesParcel(any()); 13573 13574 // Set MOBILE_DATA_PREFERRED_UIDS setting and verify that net id and uid ranges send to netd 13575 final Set<Integer> uids1 = Set.of(PRIMARY_USER_HANDLE.getUid(TEST_PACKAGE_UID)); 13576 final UidRangeParcel[] uidRanges1 = toUidRangeStableParcels(uidRangesForUids(uids1)); 13577 final NativeUidRangeConfig config1 = new NativeUidRangeConfig(cellNetId, uidRanges1, 13578 PREFERENCE_PRIORITY_MOBILE_DATA_PREFERERRED); 13579 setAndUpdateMobileDataPreferredUids(uids1); 13580 inorder.verify(mMockNetd, times(1)).networkAddUidRangesParcel(config1); 13581 inorder.verify(mMockNetd, never()).networkRemoveUidRangesParcel(any()); 13582 13583 // Set MOBILE_DATA_PREFERRED_UIDS setting again and verify that old rules are removed and 13584 // new rules are added. 13585 final Set<Integer> uids2 = Set.of(PRIMARY_USER_HANDLE.getUid(TEST_PACKAGE_UID), 13586 PRIMARY_USER_HANDLE.getUid(TEST_PACKAGE_UID2), 13587 SECONDARY_USER_HANDLE.getUid(TEST_PACKAGE_UID)); 13588 final UidRangeParcel[] uidRanges2 = toUidRangeStableParcels(uidRangesForUids(uids2)); 13589 final NativeUidRangeConfig config2 = new NativeUidRangeConfig(cellNetId, uidRanges2, 13590 PREFERENCE_PRIORITY_MOBILE_DATA_PREFERERRED); 13591 setAndUpdateMobileDataPreferredUids(uids2); 13592 inorder.verify(mMockNetd, times(1)).networkRemoveUidRangesParcel(config1); 13593 inorder.verify(mMockNetd, times(1)).networkAddUidRangesParcel(config2); 13594 13595 // Clear MOBILE_DATA_PREFERRED_UIDS setting again and verify that old rules are removed and 13596 // new rules are not added. 13597 setAndUpdateMobileDataPreferredUids(Set.of()); 13598 inorder.verify(mMockNetd, times(1)).networkRemoveUidRangesParcel(config2); 13599 inorder.verify(mMockNetd, never()).networkAddUidRangesParcel(any()); 13600 } 13601 13602 /** 13603 * Make sure mobile data preferred uids feature behaves as expected when the mobile network 13604 * goes up and down while the uids is set. Make sure they behave as expected whether 13605 * there is a general default network or not. 13606 */ 13607 @Test 13608 public void testMobileDataPreferenceForMobileNetworkUpDown() throws Exception { 13609 final InOrder inorder = inOrder(mMockNetd); 13610 // File a request for cell to ensure it doesn't go down. 13611 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback(); 13612 final NetworkRequest cellRequest = new NetworkRequest.Builder() 13613 .addTransportType(TRANSPORT_CELLULAR).build(); 13614 mCm.requestNetwork(cellRequest, cellNetworkCallback); 13615 cellNetworkCallback.assertNoCallback(); 13616 13617 registerDefaultNetworkCallbacks(); 13618 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 13619 mWiFiNetworkAgent.connect(true); 13620 mDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mWiFiNetworkAgent); 13621 mTestPackageDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mWiFiNetworkAgent); 13622 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetworkForUid(TEST_PACKAGE_UID)); 13623 13624 final int wifiNetId = mWiFiNetworkAgent.getNetwork().netId; 13625 inorder.verify(mMockNetd, times(1)).networkCreate(nativeNetworkConfigPhysical( 13626 wifiNetId, INetd.PERMISSION_NONE)); 13627 13628 // Initial mobile data preferred uids status. 13629 setAndUpdateMobileDataPreferredUids(Set.of()); 13630 inorder.verify(mMockNetd, never()).networkAddUidRangesParcel(any()); 13631 inorder.verify(mMockNetd, never()).networkRemoveUidRangesParcel(any()); 13632 13633 // Set MOBILE_DATA_PREFERRED_UIDS setting and verify that wifi net id and uid ranges send to 13634 // netd. 13635 final Set<Integer> uids = Set.of(PRIMARY_USER_HANDLE.getUid(TEST_PACKAGE_UID)); 13636 final UidRangeParcel[] uidRanges = toUidRangeStableParcels(uidRangesForUids(uids)); 13637 final NativeUidRangeConfig wifiConfig = new NativeUidRangeConfig(wifiNetId, uidRanges, 13638 PREFERENCE_PRIORITY_MOBILE_DATA_PREFERERRED); 13639 setAndUpdateMobileDataPreferredUids(uids); 13640 inorder.verify(mMockNetd, times(1)).networkAddUidRangesParcel(wifiConfig); 13641 inorder.verify(mMockNetd, never()).networkRemoveUidRangesParcel(any()); 13642 13643 // Cellular network connected. mTestPackageDefaultNetworkCallback should receive 13644 // callback with cellular network and net id and uid ranges should be updated to netd. 13645 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 13646 mCellNetworkAgent.connect(true); 13647 cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 13648 mDefaultNetworkCallback.assertNoCallback(); 13649 mTestPackageDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 13650 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetworkForUid(TEST_PACKAGE_UID)); 13651 13652 final int cellNetId = mCellNetworkAgent.getNetwork().netId; 13653 final NativeUidRangeConfig cellConfig = new NativeUidRangeConfig(cellNetId, uidRanges, 13654 PREFERENCE_PRIORITY_MOBILE_DATA_PREFERERRED); 13655 inorder.verify(mMockNetd, times(1)).networkCreate(nativeNetworkConfigPhysical( 13656 cellNetId, INetd.PERMISSION_NONE)); 13657 inorder.verify(mMockNetd, times(1)).networkAddUidRangesParcel(cellConfig); 13658 inorder.verify(mMockNetd, times(1)).networkRemoveUidRangesParcel(wifiConfig); 13659 13660 // Cellular network disconnected. mTestPackageDefaultNetworkCallback should receive 13661 // callback with wifi network from fallback request. 13662 mCellNetworkAgent.disconnect(); 13663 mDefaultNetworkCallback.assertNoCallback(); 13664 cellNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 13665 mTestPackageDefaultNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 13666 mTestPackageDefaultNetworkCallback.expectAvailableCallbacksValidated(mWiFiNetworkAgent); 13667 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetworkForUid(TEST_PACKAGE_UID)); 13668 inorder.verify(mMockNetd, times(1)).networkAddUidRangesParcel(wifiConfig); 13669 inorder.verify(mMockNetd, never()).networkRemoveUidRangesParcel(any()); 13670 inorder.verify(mMockNetd).networkDestroy(cellNetId); 13671 13672 // Cellular network comes back. mTestPackageDefaultNetworkCallback should receive 13673 // callback with cellular network. 13674 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 13675 mCellNetworkAgent.connect(true); 13676 cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 13677 mDefaultNetworkCallback.assertNoCallback(); 13678 mTestPackageDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 13679 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetworkForUid(TEST_PACKAGE_UID)); 13680 13681 final int cellNetId2 = mCellNetworkAgent.getNetwork().netId; 13682 final NativeUidRangeConfig cellConfig2 = new NativeUidRangeConfig(cellNetId2, uidRanges, 13683 PREFERENCE_PRIORITY_MOBILE_DATA_PREFERERRED); 13684 inorder.verify(mMockNetd, times(1)).networkCreate(nativeNetworkConfigPhysical( 13685 cellNetId2, INetd.PERMISSION_NONE)); 13686 inorder.verify(mMockNetd, times(1)).networkAddUidRangesParcel(cellConfig2); 13687 inorder.verify(mMockNetd, times(1)).networkRemoveUidRangesParcel(wifiConfig); 13688 13689 // Wifi network disconnected. mTestPackageDefaultNetworkCallback should not receive 13690 // any callback. 13691 mWiFiNetworkAgent.disconnect(); 13692 mDefaultNetworkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 13693 mDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellNetworkAgent); 13694 mTestPackageDefaultNetworkCallback.assertNoCallback(); 13695 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetworkForUid(TEST_PACKAGE_UID)); 13696 waitForIdle(); 13697 inorder.verify(mMockNetd, never()).networkAddUidRangesParcel(any()); 13698 inorder.verify(mMockNetd, never()).networkRemoveUidRangesParcel(any()); 13699 inorder.verify(mMockNetd).networkDestroy(wifiNetId); 13700 13701 mCm.unregisterNetworkCallback(cellNetworkCallback); 13702 } 13703 13704 @Test 13705 public void testMultilayerRequestsOfSetMobileDataPreferredUids() throws Exception { 13706 // First set mobile data preferred uid to create a multi-layer requests: 1. request for 13707 // cellular, 2. track the default network for fallback. 13708 setAndUpdateMobileDataPreferredUids( 13709 Set.of(PRIMARY_USER_HANDLE.getUid(TEST_PACKAGE_UID))); 13710 13711 final HandlerThread handlerThread = new HandlerThread("MockFactory"); 13712 handlerThread.start(); 13713 final NetworkCapabilities cellFilter = new NetworkCapabilities() 13714 .addTransportType(TRANSPORT_CELLULAR) 13715 .addCapability(NET_CAPABILITY_INTERNET) 13716 .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED); 13717 final MockNetworkFactory cellFactory = new MockNetworkFactory(handlerThread.getLooper(), 13718 mServiceContext, "cellFactory", cellFilter, mCsHandlerThread); 13719 cellFactory.setScoreFilter(40); 13720 13721 try { 13722 cellFactory.register(); 13723 // Default internet request and the mobile data preferred request. 13724 cellFactory.expectRequestAdds(2); 13725 cellFactory.assertRequestCountEquals(2); 13726 13727 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 13728 mWiFiNetworkAgent.connect(true); 13729 13730 // The cellFactory however is outscored, and should lose default internet request. 13731 // But it should still see mobile data preferred request. 13732 cellFactory.expectRequestRemove(); 13733 cellFactory.assertRequestCountEquals(1); 13734 13735 mWiFiNetworkAgent.disconnect(); 13736 // The network satisfying the default internet request has disconnected, so the 13737 // cellFactory sees the default internet requests again. 13738 cellFactory.expectRequestAdd(); 13739 cellFactory.assertRequestCountEquals(2); 13740 } finally { 13741 cellFactory.terminate(); 13742 handlerThread.quitSafely(); 13743 } 13744 } 13745 13746 /** 13747 * Validate request counts are counted accurately on MOBILE_DATA_PREFERRED_UIDS change 13748 * on set/replace. 13749 */ 13750 @Test 13751 public void testMobileDataPreferredUidsChangedCountsRequestsCorrectlyOnSet() throws Exception { 13752 ConnectivitySettingsManager.setMobileDataPreferredUids(mServiceContext, 13753 Set.of(PRIMARY_USER_HANDLE.getUid(TEST_PACKAGE_UID))); 13754 // Leave one request available so MDO preference set up above can be set. 13755 testRequestCountLimits(1 /* countToLeaveAvailable */, () -> 13756 withPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, 13757 Process.myPid(), Process.myUid(), () -> { 13758 // Set initially to test the limit prior to having existing requests. 13759 mService.updateMobileDataPreferredUids(); 13760 waitForIdle(); 13761 13762 // re-set so as to test the limit as part of replacing existing requests 13763 mService.updateMobileDataPreferredUids(); 13764 waitForIdle(); 13765 })); 13766 } 13767 13768 @Test 13769 public void testAllNetworkPreferencesCanCoexist() 13770 throws Exception { 13771 final InOrder inorder = inOrder(mMockNetd); 13772 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 13773 OEM_NETWORK_PREFERENCE_OEM_PAID; 13774 final UserHandle testHandle = setupEnterpriseNetwork(); 13775 13776 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); 13777 final int cellNetId = mCellNetworkAgent.getNetwork().netId; 13778 inorder.verify(mMockNetd, times(1)).networkCreate(nativeNetworkConfigPhysical( 13779 cellNetId, INetd.PERMISSION_NONE)); 13780 13781 // Set oem network preference 13782 final int[] uids1 = new int[] { PRIMARY_USER_HANDLE.getUid(TEST_PACKAGE_UID) }; 13783 final UidRangeParcel[] uidRanges1 = toUidRangeStableParcels(uidRangesForUids(uids1)); 13784 final NativeUidRangeConfig config1 = new NativeUidRangeConfig(cellNetId, uidRanges1, 13785 PREFERENCE_PRIORITY_OEM); 13786 setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges1, TEST_PACKAGE_NAME); 13787 inorder.verify(mMockNetd, times(1)).networkAddUidRangesParcel(config1); 13788 inorder.verify(mMockNetd, never()).networkRemoveUidRangesParcel(any()); 13789 13790 // Set user profile network preference 13791 final TestNetworkAgentWrapper workAgent = makeEnterpriseNetworkAgent(); 13792 workAgent.connect(true); 13793 13794 final TestOnCompleteListener listener = new TestOnCompleteListener(); 13795 mCm.setProfileNetworkPreference(testHandle, PROFILE_NETWORK_PREFERENCE_ENTERPRISE, 13796 r -> r.run(), listener); 13797 listener.expectOnComplete(); 13798 final NativeUidRangeConfig config2 = new NativeUidRangeConfig(workAgent.getNetwork().netId, 13799 uidRangeFor(testHandle), PREFERENCE_PRIORITY_PROFILE); 13800 inorder.verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( 13801 workAgent.getNetwork().netId, INetd.PERMISSION_SYSTEM)); 13802 inorder.verify(mMockNetd, never()).networkRemoveUidRangesParcel(any()); 13803 inorder.verify(mMockNetd).networkAddUidRangesParcel(config2); 13804 13805 // Set MOBILE_DATA_PREFERRED_UIDS setting 13806 final Set<Integer> uids2 = Set.of(PRIMARY_USER_HANDLE.getUid(TEST_PACKAGE_UID2)); 13807 final UidRangeParcel[] uidRanges2 = toUidRangeStableParcels(uidRangesForUids(uids2)); 13808 final NativeUidRangeConfig config3 = new NativeUidRangeConfig(cellNetId, uidRanges2, 13809 PREFERENCE_PRIORITY_MOBILE_DATA_PREFERERRED); 13810 setAndUpdateMobileDataPreferredUids(uids2); 13811 inorder.verify(mMockNetd, never()).networkRemoveUidRangesParcel(any()); 13812 inorder.verify(mMockNetd, times(1)).networkAddUidRangesParcel(config3); 13813 13814 // Set oem network preference again with different uid. 13815 final Set<Integer> uids3 = Set.of(PRIMARY_USER_HANDLE.getUid(TEST_PACKAGE_UID3)); 13816 final UidRangeParcel[] uidRanges3 = toUidRangeStableParcels(uidRangesForUids(uids3)); 13817 final NativeUidRangeConfig config4 = new NativeUidRangeConfig(cellNetId, uidRanges3, 13818 PREFERENCE_PRIORITY_OEM); 13819 setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges3, "com.android.test"); 13820 inorder.verify(mMockNetd, times(1)).networkRemoveUidRangesParcel(config1); 13821 inorder.verify(mMockNetd, times(1)).networkAddUidRangesParcel(config4); 13822 13823 // Remove user profile network preference 13824 mCm.setProfileNetworkPreference(testHandle, PROFILE_NETWORK_PREFERENCE_DEFAULT, 13825 r -> r.run(), listener); 13826 listener.expectOnComplete(); 13827 inorder.verify(mMockNetd, times(1)).networkRemoveUidRangesParcel(config2); 13828 inorder.verify(mMockNetd, never()).networkAddUidRangesParcel(any()); 13829 13830 // Set MOBILE_DATA_PREFERRED_UIDS setting again with same uid as oem network preference. 13831 final NativeUidRangeConfig config6 = new NativeUidRangeConfig(cellNetId, uidRanges3, 13832 PREFERENCE_PRIORITY_MOBILE_DATA_PREFERERRED); 13833 setAndUpdateMobileDataPreferredUids(uids3); 13834 inorder.verify(mMockNetd, times(1)).networkRemoveUidRangesParcel(config3); 13835 inorder.verify(mMockNetd, times(1)).networkAddUidRangesParcel(config6); 13836 } 13837 13838 @Test 13839 public void testNetworkCallbackAndActiveNetworkForUid_AllNetworkPreferencesEnabled() 13840 throws Exception { 13841 // File a request for cell to ensure it doesn't go down. 13842 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback(); 13843 final NetworkRequest cellRequest = new NetworkRequest.Builder() 13844 .addTransportType(TRANSPORT_CELLULAR).build(); 13845 mCm.requestNetwork(cellRequest, cellNetworkCallback); 13846 cellNetworkCallback.assertNoCallback(); 13847 13848 // Register callbacks and have wifi network as default network. 13849 registerDefaultNetworkCallbacks(); 13850 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 13851 mWiFiNetworkAgent.connect(true); 13852 mDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mWiFiNetworkAgent); 13853 mProfileDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mWiFiNetworkAgent); 13854 mTestPackageDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mWiFiNetworkAgent); 13855 assertEquals(mWiFiNetworkAgent.getNetwork(), 13856 mCm.getActiveNetworkForUid(TEST_WORK_PROFILE_APP_UID)); 13857 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetworkForUid(TEST_PACKAGE_UID)); 13858 13859 // Set MOBILE_DATA_PREFERRED_UIDS setting with TEST_WORK_PROFILE_APP_UID and 13860 // TEST_PACKAGE_UID. Both mProfileDefaultNetworkCallback and 13861 // mTestPackageDefaultNetworkCallback should receive callback with cell network. 13862 setAndUpdateMobileDataPreferredUids(Set.of(TEST_WORK_PROFILE_APP_UID, TEST_PACKAGE_UID)); 13863 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 13864 mCellNetworkAgent.connect(true); 13865 cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 13866 mDefaultNetworkCallback.assertNoCallback(); 13867 mProfileDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 13868 mTestPackageDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 13869 assertEquals(mCellNetworkAgent.getNetwork(), 13870 mCm.getActiveNetworkForUid(TEST_WORK_PROFILE_APP_UID)); 13871 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetworkForUid(TEST_PACKAGE_UID)); 13872 13873 // Set user profile network preference with test profile. mProfileDefaultNetworkCallback 13874 // should receive callback with higher priority network preference (enterprise network). 13875 // The others should have no callbacks. 13876 final UserHandle testHandle = setupEnterpriseNetwork(); 13877 final TestNetworkAgentWrapper workAgent = makeEnterpriseNetworkAgent(); 13878 workAgent.connect(true); 13879 final TestOnCompleteListener listener = new TestOnCompleteListener(); 13880 mCm.setProfileNetworkPreference(testHandle, PROFILE_NETWORK_PREFERENCE_ENTERPRISE, 13881 r -> r.run(), listener); 13882 listener.expectOnComplete(); 13883 assertNoCallbacks(mDefaultNetworkCallback, mTestPackageDefaultNetworkCallback); 13884 mProfileDefaultNetworkCallback.expectAvailableCallbacksValidated(workAgent); 13885 assertEquals(workAgent.getNetwork(), mCm.getActiveNetworkForUid(TEST_WORK_PROFILE_APP_UID)); 13886 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetworkForUid(TEST_PACKAGE_UID)); 13887 13888 // Set oem network preference with TEST_PACKAGE_UID. mTestPackageDefaultNetworkCallback 13889 // should receive callback with higher priority network preference (current default network) 13890 // and the others should have no callbacks. 13891 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 13892 OEM_NETWORK_PREFERENCE_OEM_PAID; 13893 final int[] uids1 = new int[] { TEST_PACKAGE_UID }; 13894 final UidRangeParcel[] uidRanges1 = toUidRangeStableParcels(uidRangesForUids(uids1)); 13895 setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges1, TEST_PACKAGE_NAME); 13896 assertNoCallbacks(mDefaultNetworkCallback, mProfileDefaultNetworkCallback); 13897 mTestPackageDefaultNetworkCallback.expectAvailableCallbacksValidated(mWiFiNetworkAgent); 13898 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetworkForUid(TEST_PACKAGE_UID)); 13899 assertEquals(workAgent.getNetwork(), mCm.getActiveNetworkForUid(TEST_WORK_PROFILE_APP_UID)); 13900 13901 // Set oem network preference with TEST_WORK_PROFILE_APP_UID. Both 13902 // mProfileDefaultNetworkCallback and mTestPackageDefaultNetworkCallback should receive 13903 // callback. 13904 final int[] uids2 = new int[] { TEST_WORK_PROFILE_APP_UID }; 13905 final UidRangeParcel[] uidRanges2 = toUidRangeStableParcels(uidRangesForUids(uids2)); 13906 when(mUserManager.getUserHandles(anyBoolean())).thenReturn(Arrays.asList(testHandle)); 13907 setupSetOemNetworkPreferenceForPreferenceTest( 13908 networkPref, uidRanges2, "com.android.test", testHandle); 13909 mDefaultNetworkCallback.assertNoCallback(); 13910 mProfileDefaultNetworkCallback.expectAvailableCallbacksValidated(mWiFiNetworkAgent); 13911 mTestPackageDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellNetworkAgent); 13912 assertEquals(mWiFiNetworkAgent.getNetwork(), 13913 mCm.getActiveNetworkForUid(TEST_WORK_PROFILE_APP_UID)); 13914 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetworkForUid(TEST_PACKAGE_UID)); 13915 13916 // Remove oem network preference, mProfileDefaultNetworkCallback should receive callback 13917 // with current highest priority network preference (enterprise network) and the others 13918 // should have no callbacks. 13919 final TestOemListenerCallback oemPrefListener = new TestOemListenerCallback(); 13920 mService.setOemNetworkPreference( 13921 new OemNetworkPreferences.Builder().build(), oemPrefListener); 13922 oemPrefListener.expectOnComplete(); 13923 assertNoCallbacks(mDefaultNetworkCallback, mTestPackageDefaultNetworkCallback); 13924 mProfileDefaultNetworkCallback.expectAvailableCallbacksValidated(workAgent); 13925 assertEquals(workAgent.getNetwork(), mCm.getActiveNetworkForUid(TEST_WORK_PROFILE_APP_UID)); 13926 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetworkForUid(TEST_PACKAGE_UID)); 13927 13928 // Remove user profile network preference. 13929 mCm.setProfileNetworkPreference(testHandle, PROFILE_NETWORK_PREFERENCE_DEFAULT, 13930 r -> r.run(), listener); 13931 listener.expectOnComplete(); 13932 assertNoCallbacks(mDefaultNetworkCallback, mTestPackageDefaultNetworkCallback); 13933 mProfileDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellNetworkAgent); 13934 assertEquals(mCellNetworkAgent.getNetwork(), 13935 mCm.getActiveNetworkForUid(TEST_WORK_PROFILE_APP_UID)); 13936 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetworkForUid(TEST_PACKAGE_UID)); 13937 13938 // Disconnect wifi 13939 mWiFiNetworkAgent.disconnect(); 13940 assertNoCallbacks(mProfileDefaultNetworkCallback, mTestPackageDefaultNetworkCallback); 13941 mDefaultNetworkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 13942 mDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellNetworkAgent); 13943 } 13944 13945 @Test 13946 public void testRequestRouteToHostAddress_PackageDoesNotBelongToCaller() { 13947 assertThrows(SecurityException.class, () -> mService.requestRouteToHostAddress( 13948 ConnectivityManager.TYPE_NONE, null /* hostAddress */, "com.not.package.owner", 13949 null /* callingAttributionTag */)); 13950 } 13951 } 13952