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.content.pm.PackageInfo.REQUESTED_PERMISSION_GRANTED; 22 import static android.content.pm.PackageManager.GET_PERMISSIONS; 23 import static android.content.pm.PackageManager.MATCH_ANY_USER; 24 import static android.content.pm.PackageManager.PERMISSION_DENIED; 25 import static android.content.pm.PackageManager.PERMISSION_GRANTED; 26 import static android.net.ConnectivityManager.ACTION_CAPTIVE_PORTAL_SIGN_IN; 27 import static android.net.ConnectivityManager.CONNECTIVITY_ACTION; 28 import static android.net.ConnectivityManager.EXTRA_NETWORK_INFO; 29 import static android.net.ConnectivityManager.EXTRA_NETWORK_TYPE; 30 import static android.net.ConnectivityManager.NETID_UNSET; 31 import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OFF; 32 import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OPPORTUNISTIC; 33 import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_PROVIDER_HOSTNAME; 34 import static android.net.ConnectivityManager.TYPE_ETHERNET; 35 import static android.net.ConnectivityManager.TYPE_MOBILE; 36 import static android.net.ConnectivityManager.TYPE_MOBILE_FOTA; 37 import static android.net.ConnectivityManager.TYPE_MOBILE_MMS; 38 import static android.net.ConnectivityManager.TYPE_MOBILE_SUPL; 39 import static android.net.ConnectivityManager.TYPE_WIFI; 40 import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_DNS; 41 import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_FALLBACK; 42 import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_HTTP; 43 import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_HTTPS; 44 import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_PRIVDNS; 45 import static android.net.INetworkMonitor.NETWORK_VALIDATION_RESULT_PARTIAL; 46 import static android.net.INetworkMonitor.NETWORK_VALIDATION_RESULT_VALID; 47 import static android.net.NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL; 48 import static android.net.NetworkCapabilities.NET_CAPABILITY_CBS; 49 import static android.net.NetworkCapabilities.NET_CAPABILITY_DUN; 50 import static android.net.NetworkCapabilities.NET_CAPABILITY_EIMS; 51 import static android.net.NetworkCapabilities.NET_CAPABILITY_FOREGROUND; 52 import static android.net.NetworkCapabilities.NET_CAPABILITY_FOTA; 53 import static android.net.NetworkCapabilities.NET_CAPABILITY_IA; 54 import static android.net.NetworkCapabilities.NET_CAPABILITY_IMS; 55 import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET; 56 import static android.net.NetworkCapabilities.NET_CAPABILITY_MMS; 57 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED; 58 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED; 59 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED; 60 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN; 61 import static android.net.NetworkCapabilities.NET_CAPABILITY_PARTIAL_CONNECTIVITY; 62 import static android.net.NetworkCapabilities.NET_CAPABILITY_RCS; 63 import static android.net.NetworkCapabilities.NET_CAPABILITY_SUPL; 64 import static android.net.NetworkCapabilities.NET_CAPABILITY_TRUSTED; 65 import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED; 66 import static android.net.NetworkCapabilities.NET_CAPABILITY_WIFI_P2P; 67 import static android.net.NetworkCapabilities.NET_CAPABILITY_XCAP; 68 import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; 69 import static android.net.NetworkCapabilities.TRANSPORT_ETHERNET; 70 import static android.net.NetworkCapabilities.TRANSPORT_VPN; 71 import static android.net.NetworkCapabilities.TRANSPORT_WIFI; 72 import static android.net.NetworkCapabilities.TRANSPORT_WIFI_AWARE; 73 import static android.net.NetworkPolicyManager.RULE_ALLOW_METERED; 74 import static android.net.NetworkPolicyManager.RULE_NONE; 75 import static android.net.NetworkPolicyManager.RULE_REJECT_ALL; 76 import static android.net.NetworkPolicyManager.RULE_REJECT_METERED; 77 import static android.net.RouteInfo.RTN_UNREACHABLE; 78 import static android.os.Process.INVALID_UID; 79 import static android.system.OsConstants.IPPROTO_TCP; 80 81 import static com.android.server.ConnectivityServiceTestUtilsKt.transportToLegacyType; 82 import static com.android.testutils.ConcurrentUtilsKt.await; 83 import static com.android.testutils.ConcurrentUtilsKt.durationOf; 84 import static com.android.testutils.ExceptionUtils.ignoreExceptions; 85 import static com.android.testutils.HandlerUtilsKt.waitForIdleSerialExecutor; 86 import static com.android.testutils.MiscAssertsKt.assertContainsExactly; 87 import static com.android.testutils.MiscAssertsKt.assertEmpty; 88 import static com.android.testutils.MiscAssertsKt.assertLength; 89 import static com.android.testutils.MiscAssertsKt.assertRunsInAtMost; 90 import static com.android.testutils.MiscAssertsKt.assertThrows; 91 92 import static org.junit.Assert.assertEquals; 93 import static org.junit.Assert.assertFalse; 94 import static org.junit.Assert.assertNotEquals; 95 import static org.junit.Assert.assertNotNull; 96 import static org.junit.Assert.assertNull; 97 import static org.junit.Assert.assertTrue; 98 import static org.junit.Assert.fail; 99 import static org.mockito.ArgumentMatchers.anyLong; 100 import static org.mockito.ArgumentMatchers.anyString; 101 import static org.mockito.ArgumentMatchers.argThat; 102 import static org.mockito.ArgumentMatchers.eq; 103 import static org.mockito.ArgumentMatchers.isNull; 104 import static org.mockito.ArgumentMatchers.startsWith; 105 import static org.mockito.Matchers.anyInt; 106 import static org.mockito.Mockito.any; 107 import static org.mockito.Mockito.atLeastOnce; 108 import static org.mockito.Mockito.doAnswer; 109 import static org.mockito.Mockito.doNothing; 110 import static org.mockito.Mockito.doReturn; 111 import static org.mockito.Mockito.doThrow; 112 import static org.mockito.Mockito.inOrder; 113 import static org.mockito.Mockito.mock; 114 import static org.mockito.Mockito.never; 115 import static org.mockito.Mockito.reset; 116 import static org.mockito.Mockito.spy; 117 import static org.mockito.Mockito.timeout; 118 import static org.mockito.Mockito.times; 119 import static org.mockito.Mockito.verify; 120 import static org.mockito.Mockito.verifyNoMoreInteractions; 121 import static org.mockito.Mockito.when; 122 123 import android.Manifest; 124 import android.annotation.NonNull; 125 import android.app.AlarmManager; 126 import android.app.AppOpsManager; 127 import android.app.NotificationManager; 128 import android.app.PendingIntent; 129 import android.content.BroadcastReceiver; 130 import android.content.ContentProvider; 131 import android.content.ContentResolver; 132 import android.content.Context; 133 import android.content.Intent; 134 import android.content.IntentFilter; 135 import android.content.pm.ApplicationInfo; 136 import android.content.pm.PackageInfo; 137 import android.content.pm.PackageManager; 138 import android.content.pm.UserInfo; 139 import android.content.res.Resources; 140 import android.location.LocationManager; 141 import android.net.CaptivePortalData; 142 import android.net.ConnectionInfo; 143 import android.net.ConnectivityManager; 144 import android.net.ConnectivityManager.NetworkCallback; 145 import android.net.ConnectivityManager.PacketKeepalive; 146 import android.net.ConnectivityManager.PacketKeepaliveCallback; 147 import android.net.ConnectivityManager.TooManyRequestsException; 148 import android.net.ConnectivityThread; 149 import android.net.DataStallReportParcelable; 150 import android.net.IConnectivityDiagnosticsCallback; 151 import android.net.IDnsResolver; 152 import android.net.IIpConnectivityMetrics; 153 import android.net.INetd; 154 import android.net.INetworkMonitor; 155 import android.net.INetworkMonitorCallbacks; 156 import android.net.INetworkPolicyListener; 157 import android.net.INetworkPolicyManager; 158 import android.net.INetworkStatsService; 159 import android.net.InetAddresses; 160 import android.net.InterfaceConfiguration; 161 import android.net.IpPrefix; 162 import android.net.IpSecManager; 163 import android.net.IpSecManager.UdpEncapsulationSocket; 164 import android.net.LinkAddress; 165 import android.net.LinkProperties; 166 import android.net.MatchAllNetworkSpecifier; 167 import android.net.Network; 168 import android.net.NetworkAgent; 169 import android.net.NetworkAgentConfig; 170 import android.net.NetworkCapabilities; 171 import android.net.NetworkFactory; 172 import android.net.NetworkInfo; 173 import android.net.NetworkRequest; 174 import android.net.NetworkSpecifier; 175 import android.net.NetworkStack; 176 import android.net.NetworkStackClient; 177 import android.net.NetworkState; 178 import android.net.NetworkTestResultParcelable; 179 import android.net.NetworkUtils; 180 import android.net.ProxyInfo; 181 import android.net.ResolverParamsParcel; 182 import android.net.RouteInfo; 183 import android.net.RouteInfoParcel; 184 import android.net.SocketKeepalive; 185 import android.net.UidRange; 186 import android.net.Uri; 187 import android.net.VpnManager; 188 import android.net.metrics.IpConnectivityLog; 189 import android.net.shared.NetworkMonitorUtils; 190 import android.net.shared.PrivateDnsConfig; 191 import android.net.util.MultinetworkPolicyTracker; 192 import android.os.BadParcelableException; 193 import android.os.Binder; 194 import android.os.Build; 195 import android.os.Bundle; 196 import android.os.ConditionVariable; 197 import android.os.Handler; 198 import android.os.HandlerThread; 199 import android.os.IBinder; 200 import android.os.INetworkManagementService; 201 import android.os.Looper; 202 import android.os.Parcel; 203 import android.os.ParcelFileDescriptor; 204 import android.os.Parcelable; 205 import android.os.Process; 206 import android.os.RemoteException; 207 import android.os.SystemClock; 208 import android.os.UserHandle; 209 import android.os.UserManager; 210 import android.provider.Settings; 211 import android.security.KeyStore; 212 import android.system.Os; 213 import android.telephony.TelephonyManager; 214 import android.test.mock.MockContentResolver; 215 import android.text.TextUtils; 216 import android.util.ArraySet; 217 import android.util.Log; 218 import android.util.SparseArray; 219 220 import androidx.test.InstrumentationRegistry; 221 import androidx.test.filters.FlakyTest; 222 import androidx.test.filters.SmallTest; 223 import androidx.test.runner.AndroidJUnit4; 224 225 import com.android.internal.app.IBatteryStats; 226 import com.android.internal.net.VpnConfig; 227 import com.android.internal.net.VpnInfo; 228 import com.android.internal.util.ArrayUtils; 229 import com.android.internal.util.WakeupMessage; 230 import com.android.internal.util.test.BroadcastInterceptingContext; 231 import com.android.internal.util.test.FakeSettingsProvider; 232 import com.android.server.ConnectivityService.ConnectivityDiagnosticsCallbackInfo; 233 import com.android.server.connectivity.ConnectivityConstants; 234 import com.android.server.connectivity.DefaultNetworkMetrics; 235 import com.android.server.connectivity.IpConnectivityMetrics; 236 import com.android.server.connectivity.MockableSystemProperties; 237 import com.android.server.connectivity.Nat464Xlat; 238 import com.android.server.connectivity.NetworkAgentInfo; 239 import com.android.server.connectivity.NetworkNotificationManager.NotificationType; 240 import com.android.server.connectivity.ProxyTracker; 241 import com.android.server.connectivity.Vpn; 242 import com.android.server.net.NetworkPinner; 243 import com.android.server.net.NetworkPolicyManagerInternal; 244 import com.android.testutils.ExceptionUtils; 245 import com.android.testutils.HandlerUtilsKt; 246 import com.android.testutils.RecorderCallback.CallbackEntry; 247 import com.android.testutils.TestableNetworkCallback; 248 249 import org.junit.After; 250 import org.junit.Before; 251 import org.junit.Ignore; 252 import org.junit.Test; 253 import org.junit.runner.RunWith; 254 import org.mockito.ArgumentCaptor; 255 import org.mockito.InOrder; 256 import org.mockito.Mock; 257 import org.mockito.MockitoAnnotations; 258 import org.mockito.Spy; 259 import org.mockito.stubbing.Answer; 260 261 import java.io.IOException; 262 import java.net.DatagramSocket; 263 import java.net.Inet4Address; 264 import java.net.Inet6Address; 265 import java.net.InetAddress; 266 import java.net.InetSocketAddress; 267 import java.net.Socket; 268 import java.util.ArrayList; 269 import java.util.Arrays; 270 import java.util.Collection; 271 import java.util.Collections; 272 import java.util.HashMap; 273 import java.util.HashSet; 274 import java.util.List; 275 import java.util.Objects; 276 import java.util.Set; 277 import java.util.concurrent.CountDownLatch; 278 import java.util.concurrent.Executor; 279 import java.util.concurrent.ExecutorService; 280 import java.util.concurrent.Executors; 281 import java.util.concurrent.LinkedBlockingQueue; 282 import java.util.concurrent.TimeUnit; 283 import java.util.concurrent.atomic.AtomicBoolean; 284 import java.util.function.Predicate; 285 import java.util.function.Supplier; 286 287 import kotlin.reflect.KClass; 288 289 /** 290 * Tests for {@link ConnectivityService}. 291 * 292 * Build, install and run with: 293 * runtest frameworks-net -c com.android.server.ConnectivityServiceTest 294 */ 295 @RunWith(AndroidJUnit4.class) 296 @SmallTest 297 public class ConnectivityServiceTest { 298 private static final String TAG = "ConnectivityServiceTest"; 299 300 private static final int TIMEOUT_MS = 500; 301 private static final int TEST_LINGER_DELAY_MS = 300; 302 // Chosen to be less than the linger timeout. This ensures that we can distinguish between a 303 // LOST callback that arrives immediately and a LOST callback that arrives after the linger 304 // timeout. For this, our assertions should run fast enough to leave less than 305 // (mService.mLingerDelayMs - TEST_CALLBACK_TIMEOUT_MS) between the time callbacks are 306 // supposedly fired, and the time we call expectCallback. 307 private static final int TEST_CALLBACK_TIMEOUT_MS = 250; 308 // Chosen to be less than TEST_CALLBACK_TIMEOUT_MS. This ensures that requests have time to 309 // complete before callbacks are verified. 310 private static final int TEST_REQUEST_TIMEOUT_MS = 150; 311 312 private static final int UNREASONABLY_LONG_ALARM_WAIT_MS = 1000; 313 314 private static final long TIMESTAMP = 1234L; 315 316 private static final int NET_ID = 110; 317 318 private static final String CLAT_PREFIX = "v4-"; 319 private static final String MOBILE_IFNAME = "test_rmnet_data0"; 320 private static final String WIFI_IFNAME = "test_wlan0"; 321 private static final String WIFI_WOL_IFNAME = "test_wlan_wol"; 322 private static final String TEST_PACKAGE_NAME = "com.android.test.package"; 323 private static final String[] EMPTY_STRING_ARRAY = new String[0]; 324 325 private static final String INTERFACE_NAME = "interface"; 326 327 private MockContext mServiceContext; 328 private HandlerThread mCsHandlerThread; 329 private ConnectivityService mService; 330 private WrappedConnectivityManager mCm; 331 private TestNetworkAgentWrapper mWiFiNetworkAgent; 332 private TestNetworkAgentWrapper mCellNetworkAgent; 333 private TestNetworkAgentWrapper mEthernetNetworkAgent; 334 private MockVpn mMockVpn; 335 private Context mContext; 336 private INetworkPolicyListener mPolicyListener; 337 private WrappedMultinetworkPolicyTracker mPolicyTracker; 338 private HandlerThread mAlarmManagerThread; 339 340 @Mock IIpConnectivityMetrics mIpConnectivityMetrics; 341 @Mock IpConnectivityMetrics.Logger mMetricsService; 342 @Mock DefaultNetworkMetrics mDefaultNetworkMetrics; 343 @Mock INetworkManagementService mNetworkManagementService; 344 @Mock INetworkStatsService mStatsService; 345 @Mock IBatteryStats mBatteryStatsService; 346 @Mock INetworkPolicyManager mNpm; 347 @Mock IDnsResolver mMockDnsResolver; 348 @Mock INetd mMockNetd; 349 @Mock NetworkStackClient mNetworkStack; 350 @Mock PackageManager mPackageManager; 351 @Mock UserManager mUserManager; 352 @Mock NotificationManager mNotificationManager; 353 @Mock AlarmManager mAlarmManager; 354 @Mock IConnectivityDiagnosticsCallback mConnectivityDiagnosticsCallback; 355 @Mock IBinder mIBinder; 356 @Mock LocationManager mLocationManager; 357 @Mock AppOpsManager mAppOpsManager; 358 @Mock TelephonyManager mTelephonyManager; 359 360 private ArgumentCaptor<ResolverParamsParcel> mResolverParamsParcelCaptor = 361 ArgumentCaptor.forClass(ResolverParamsParcel.class); 362 363 // This class exists to test bindProcessToNetwork and getBoundNetworkForProcess. These methods 364 // do not go through ConnectivityService but talk to netd directly, so they don't automatically 365 // reflect the state of our test ConnectivityService. 366 private class WrappedConnectivityManager extends ConnectivityManager { 367 private Network mFakeBoundNetwork; 368 bindProcessToNetwork(Network network)369 public synchronized boolean bindProcessToNetwork(Network network) { 370 mFakeBoundNetwork = network; 371 return true; 372 } 373 getBoundNetworkForProcess()374 public synchronized Network getBoundNetworkForProcess() { 375 return mFakeBoundNetwork; 376 } 377 WrappedConnectivityManager(Context context, ConnectivityService service)378 public WrappedConnectivityManager(Context context, ConnectivityService service) { 379 super(context, service); 380 } 381 } 382 383 private class MockContext extends BroadcastInterceptingContext { 384 private final MockContentResolver mContentResolver; 385 // Contains all registered receivers since this object was created. Useful to clear 386 // them when needed, as BroadcastInterceptingContext does not provide this facility. 387 private final List<BroadcastReceiver> mRegisteredReceivers = new ArrayList<>(); 388 389 @Spy private Resources mResources; 390 private final LinkedBlockingQueue<Intent> mStartedActivities = new LinkedBlockingQueue<>(); 391 // Map of permission name -> PermissionManager.Permission_{GRANTED|DENIED} constant 392 private final HashMap<String, Integer> mMockedPermissions = new HashMap<>(); 393 MockContext(Context base, ContentProvider settingsProvider)394 MockContext(Context base, ContentProvider settingsProvider) { 395 super(base); 396 397 mResources = spy(base.getResources()); 398 when(mResources.getStringArray(com.android.internal.R.array.networkAttributes)). 399 thenReturn(new String[] { 400 "wifi,1,1,1,-1,true", 401 "mobile,0,0,0,-1,true", 402 "mobile_mms,2,0,2,60000,true", 403 "mobile_supl,3,0,2,60000,true", 404 }); 405 406 when(mResources.getStringArray( 407 com.android.internal.R.array.config_wakeonlan_supported_interfaces)) 408 .thenReturn(new String[]{ 409 WIFI_WOL_IFNAME, 410 }); 411 412 mContentResolver = new MockContentResolver(); 413 mContentResolver.addProvider(Settings.AUTHORITY, settingsProvider); 414 } 415 416 @Override startActivityAsUser(Intent intent, UserHandle handle)417 public void startActivityAsUser(Intent intent, UserHandle handle) { 418 mStartedActivities.offer(intent); 419 } 420 expectStartActivityIntent(int timeoutMs)421 public Intent expectStartActivityIntent(int timeoutMs) { 422 Intent intent = null; 423 try { 424 intent = mStartedActivities.poll(timeoutMs, TimeUnit.MILLISECONDS); 425 } catch (InterruptedException e) {} 426 assertNotNull("Did not receive sign-in intent after " + timeoutMs + "ms", intent); 427 return intent; 428 } 429 expectNoStartActivityIntent(int timeoutMs)430 public void expectNoStartActivityIntent(int timeoutMs) { 431 try { 432 assertNull("Received unexpected Intent to start activity", 433 mStartedActivities.poll(timeoutMs, TimeUnit.MILLISECONDS)); 434 } catch (InterruptedException e) {} 435 } 436 437 @Override getSystemService(String name)438 public Object getSystemService(String name) { 439 if (Context.CONNECTIVITY_SERVICE.equals(name)) return mCm; 440 if (Context.NOTIFICATION_SERVICE.equals(name)) return mNotificationManager; 441 if (Context.USER_SERVICE.equals(name)) return mUserManager; 442 if (Context.ALARM_SERVICE.equals(name)) return mAlarmManager; 443 if (Context.LOCATION_SERVICE.equals(name)) return mLocationManager; 444 if (Context.APP_OPS_SERVICE.equals(name)) return mAppOpsManager; 445 if (Context.TELEPHONY_SERVICE.equals(name)) return mTelephonyManager; 446 return super.getSystemService(name); 447 } 448 449 @Override getContentResolver()450 public ContentResolver getContentResolver() { 451 return mContentResolver; 452 } 453 454 @Override getResources()455 public Resources getResources() { 456 return mResources; 457 } 458 459 @Override getPackageManager()460 public PackageManager getPackageManager() { 461 return mPackageManager; 462 } 463 checkMockedPermission(String permission, Supplier<Integer> ifAbsent)464 private int checkMockedPermission(String permission, Supplier<Integer> ifAbsent) { 465 final Integer granted = mMockedPermissions.get(permission); 466 return granted != null ? granted : ifAbsent.get(); 467 } 468 469 @Override checkPermission(String permission, int pid, int uid)470 public int checkPermission(String permission, int pid, int uid) { 471 return checkMockedPermission( 472 permission, () -> super.checkPermission(permission, pid, uid)); 473 } 474 475 @Override checkCallingOrSelfPermission(String permission)476 public int checkCallingOrSelfPermission(String permission) { 477 return checkMockedPermission( 478 permission, () -> super.checkCallingOrSelfPermission(permission)); 479 } 480 481 @Override enforceCallingOrSelfPermission(String permission, String message)482 public void enforceCallingOrSelfPermission(String permission, String message) { 483 final Integer granted = mMockedPermissions.get(permission); 484 if (granted == null) { 485 super.enforceCallingOrSelfPermission(permission, message); 486 return; 487 } 488 489 if (!granted.equals(PERMISSION_GRANTED)) { 490 throw new SecurityException("[Test] permission denied: " + permission); 491 } 492 } 493 494 /** 495 * Mock checks for the specified permission, and have them behave as per {@code granted}. 496 * 497 * <p>Passing null reverts to default behavior, which does a real permission check on the 498 * test package. 499 * @param granted One of {@link PackageManager#PERMISSION_GRANTED} or 500 * {@link PackageManager#PERMISSION_DENIED}. 501 */ setPermission(String permission, Integer granted)502 public void setPermission(String permission, Integer granted) { 503 mMockedPermissions.put(permission, granted); 504 } 505 506 @Override registerReceiver(BroadcastReceiver receiver, IntentFilter filter)507 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) { 508 mRegisteredReceivers.add(receiver); 509 return super.registerReceiver(receiver, filter); 510 } 511 clearRegisteredReceivers()512 public void clearRegisteredReceivers() { 513 // super.unregisterReceiver is a no-op for receivers that are not registered (because 514 // they haven't been registered or because they have already been unregistered). 515 // For the same reason, don't bother clearing mRegisteredReceivers. 516 for (final BroadcastReceiver rcv : mRegisteredReceivers) unregisterReceiver(rcv); 517 } 518 } 519 waitForIdle()520 private void waitForIdle() { 521 HandlerUtilsKt.waitForIdle(mCsHandlerThread, TIMEOUT_MS); 522 waitForIdle(mCellNetworkAgent, TIMEOUT_MS); 523 waitForIdle(mWiFiNetworkAgent, TIMEOUT_MS); 524 waitForIdle(mEthernetNetworkAgent, TIMEOUT_MS); 525 HandlerUtilsKt.waitForIdle(mCsHandlerThread, TIMEOUT_MS); 526 HandlerUtilsKt.waitForIdle(ConnectivityThread.get(), TIMEOUT_MS); 527 } 528 waitForIdle(TestNetworkAgentWrapper agent, long timeoutMs)529 private void waitForIdle(TestNetworkAgentWrapper agent, long timeoutMs) { 530 if (agent == null) { 531 return; 532 } 533 agent.waitForIdle(timeoutMs); 534 } 535 536 @Test testWaitForIdle()537 public void testWaitForIdle() throws Exception { 538 final int attempts = 50; // Causes the test to take about 200ms on bullhead-eng. 539 540 // Tests that waitForIdle returns immediately if the service is already idle. 541 for (int i = 0; i < attempts; i++) { 542 waitForIdle(); 543 } 544 545 // Bring up a network that we can use to send messages to ConnectivityService. 546 ConditionVariable cv = registerConnectivityBroadcast(1); 547 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 548 mWiFiNetworkAgent.connect(false); 549 waitFor(cv); 550 Network n = mWiFiNetworkAgent.getNetwork(); 551 assertNotNull(n); 552 553 // Tests that calling waitForIdle waits for messages to be processed. 554 for (int i = 0; i < attempts; i++) { 555 mWiFiNetworkAgent.setSignalStrength(i); 556 waitForIdle(); 557 assertEquals(i, mCm.getNetworkCapabilities(n).getSignalStrength()); 558 } 559 } 560 561 // This test has an inherent race condition in it, and cannot be enabled for continuous testing 562 // or presubmit tests. It is kept for manual runs and documentation purposes. 563 @Ignore verifyThatNotWaitingForIdleCausesRaceConditions()564 public void verifyThatNotWaitingForIdleCausesRaceConditions() throws Exception { 565 // Bring up a network that we can use to send messages to ConnectivityService. 566 ConditionVariable cv = registerConnectivityBroadcast(1); 567 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 568 mWiFiNetworkAgent.connect(false); 569 waitFor(cv); 570 Network n = mWiFiNetworkAgent.getNetwork(); 571 assertNotNull(n); 572 573 // Ensure that not calling waitForIdle causes a race condition. 574 final int attempts = 50; // Causes the test to take about 200ms on bullhead-eng. 575 for (int i = 0; i < attempts; i++) { 576 mWiFiNetworkAgent.setSignalStrength(i); 577 if (i != mCm.getNetworkCapabilities(n).getSignalStrength()) { 578 // We hit a race condition, as expected. Pass the test. 579 return; 580 } 581 } 582 583 // No race? There is a bug in this test. 584 fail("expected race condition at least once in " + attempts + " attempts"); 585 } 586 587 private class TestNetworkAgentWrapper extends NetworkAgentWrapper { 588 private static final int VALIDATION_RESULT_INVALID = 0; 589 590 private static final long DATA_STALL_TIMESTAMP = 10L; 591 private static final int DATA_STALL_DETECTION_METHOD = 1; 592 593 private INetworkMonitor mNetworkMonitor; 594 private INetworkMonitorCallbacks mNmCallbacks; 595 private int mNmValidationResult = VALIDATION_RESULT_INVALID; 596 private int mProbesCompleted; 597 private int mProbesSucceeded; 598 private String mNmValidationRedirectUrl = null; 599 private boolean mNmProvNotificationRequested = false; 600 601 private final ConditionVariable mNetworkStatusReceived = new ConditionVariable(); 602 // Contains the redirectUrl from networkStatus(). Before reading, wait for 603 // mNetworkStatusReceived. 604 private String mRedirectUrl; 605 TestNetworkAgentWrapper(int transport)606 TestNetworkAgentWrapper(int transport) throws Exception { 607 this(transport, new LinkProperties()); 608 } 609 TestNetworkAgentWrapper(int transport, LinkProperties linkProperties)610 TestNetworkAgentWrapper(int transport, LinkProperties linkProperties) 611 throws Exception { 612 super(transport, linkProperties, mServiceContext); 613 614 // Waits for the NetworkAgent to be registered, which includes the creation of the 615 // NetworkMonitor. 616 waitForIdle(TIMEOUT_MS); 617 HandlerUtilsKt.waitForIdle(mCsHandlerThread, TIMEOUT_MS); 618 HandlerUtilsKt.waitForIdle(ConnectivityThread.get(), TIMEOUT_MS); 619 } 620 621 @Override makeNetworkAgent(LinkProperties linkProperties)622 protected InstrumentedNetworkAgent makeNetworkAgent(LinkProperties linkProperties) 623 throws Exception { 624 mNetworkMonitor = mock(INetworkMonitor.class); 625 626 final Answer validateAnswer = inv -> { 627 new Thread(ignoreExceptions(this::onValidationRequested)).start(); 628 return null; 629 }; 630 631 doAnswer(validateAnswer).when(mNetworkMonitor).notifyNetworkConnected(any(), any()); 632 doAnswer(validateAnswer).when(mNetworkMonitor).forceReevaluation(anyInt()); 633 634 final ArgumentCaptor<Network> nmNetworkCaptor = ArgumentCaptor.forClass(Network.class); 635 final ArgumentCaptor<INetworkMonitorCallbacks> nmCbCaptor = 636 ArgumentCaptor.forClass(INetworkMonitorCallbacks.class); 637 doNothing().when(mNetworkStack).makeNetworkMonitor( 638 nmNetworkCaptor.capture(), 639 any() /* name */, 640 nmCbCaptor.capture()); 641 642 final InstrumentedNetworkAgent na = new InstrumentedNetworkAgent(this, linkProperties) { 643 @Override 644 public void networkStatus(int status, String redirectUrl) { 645 mRedirectUrl = redirectUrl; 646 mNetworkStatusReceived.open(); 647 } 648 }; 649 650 assertEquals(na.getNetwork().netId, nmNetworkCaptor.getValue().netId); 651 mNmCallbacks = nmCbCaptor.getValue(); 652 653 mNmCallbacks.onNetworkMonitorCreated(mNetworkMonitor); 654 655 return na; 656 } 657 onValidationRequested()658 private void onValidationRequested() throws Exception { 659 if (mNmProvNotificationRequested 660 && ((mNmValidationResult & NETWORK_VALIDATION_RESULT_VALID) != 0)) { 661 mNmCallbacks.hideProvisioningNotification(); 662 mNmProvNotificationRequested = false; 663 } 664 665 mNmCallbacks.notifyProbeStatusChanged(mProbesCompleted, mProbesSucceeded); 666 final NetworkTestResultParcelable p = new NetworkTestResultParcelable(); 667 p.result = mNmValidationResult; 668 p.probesAttempted = mProbesCompleted; 669 p.probesSucceeded = mProbesSucceeded; 670 p.redirectUrl = mNmValidationRedirectUrl; 671 p.timestampMillis = TIMESTAMP; 672 mNmCallbacks.notifyNetworkTestedWithExtras(p); 673 674 if (mNmValidationRedirectUrl != null) { 675 mNmCallbacks.showProvisioningNotification( 676 "test_provisioning_notif_action", TEST_PACKAGE_NAME); 677 mNmProvNotificationRequested = true; 678 } 679 } 680 681 /** 682 * Connect without adding any internet capability. 683 */ connectWithoutInternet()684 public void connectWithoutInternet() { 685 super.connect(); 686 } 687 688 /** 689 * Transition this NetworkAgent to CONNECTED state with NET_CAPABILITY_INTERNET. 690 * @param validated Indicate if network should pretend to be validated. 691 */ connect(boolean validated)692 public void connect(boolean validated) { 693 connect(validated, true, false /* isStrictMode */); 694 } 695 696 /** 697 * Transition this NetworkAgent to CONNECTED state. 698 * @param validated Indicate if network should pretend to be validated. 699 * @param hasInternet Indicate if network should pretend to have NET_CAPABILITY_INTERNET. 700 */ connect(boolean validated, boolean hasInternet, boolean isStrictMode)701 public void connect(boolean validated, boolean hasInternet, boolean isStrictMode) { 702 assertFalse(getNetworkCapabilities().hasCapability(NET_CAPABILITY_INTERNET)); 703 704 ConnectivityManager.NetworkCallback callback = null; 705 final ConditionVariable validatedCv = new ConditionVariable(); 706 if (validated) { 707 setNetworkValid(isStrictMode); 708 NetworkRequest request = new NetworkRequest.Builder() 709 .addTransportType(getNetworkCapabilities().getTransportTypes()[0]) 710 .clearCapabilities() 711 .build(); 712 callback = new ConnectivityManager.NetworkCallback() { 713 public void onCapabilitiesChanged(Network network, 714 NetworkCapabilities networkCapabilities) { 715 if (network.equals(getNetwork()) && 716 networkCapabilities.hasCapability(NET_CAPABILITY_VALIDATED)) { 717 validatedCv.open(); 718 } 719 } 720 }; 721 mCm.registerNetworkCallback(request, callback); 722 } 723 if (hasInternet) { 724 addCapability(NET_CAPABILITY_INTERNET); 725 } 726 727 connectWithoutInternet(); 728 729 if (validated) { 730 // Wait for network to validate. 731 waitFor(validatedCv); 732 setNetworkInvalid(isStrictMode); 733 } 734 735 if (callback != null) mCm.unregisterNetworkCallback(callback); 736 } 737 connectWithCaptivePortal(String redirectUrl, boolean isStrictMode)738 public void connectWithCaptivePortal(String redirectUrl, boolean isStrictMode) { 739 setNetworkPortal(redirectUrl, isStrictMode); 740 connect(false, true /* hasInternet */, isStrictMode); 741 } 742 connectWithPartialConnectivity()743 public void connectWithPartialConnectivity() { 744 setNetworkPartial(); 745 connect(false); 746 } 747 connectWithPartialValidConnectivity(boolean isStrictMode)748 public void connectWithPartialValidConnectivity(boolean isStrictMode) { 749 setNetworkPartialValid(isStrictMode); 750 connect(false, true /* hasInternet */, isStrictMode); 751 } 752 setNetworkValid(boolean isStrictMode)753 void setNetworkValid(boolean isStrictMode) { 754 mNmValidationResult = NETWORK_VALIDATION_RESULT_VALID; 755 mNmValidationRedirectUrl = null; 756 int probesSucceeded = NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS; 757 if (isStrictMode) { 758 probesSucceeded |= NETWORK_VALIDATION_PROBE_PRIVDNS; 759 } 760 // The probesCompleted equals to probesSucceeded for the case of valid network, so put 761 // the same value into two different parameter of the method. 762 setProbesStatus(probesSucceeded, probesSucceeded); 763 } 764 setNetworkInvalid(boolean isStrictMode)765 void setNetworkInvalid(boolean isStrictMode) { 766 mNmValidationResult = VALIDATION_RESULT_INVALID; 767 mNmValidationRedirectUrl = null; 768 int probesCompleted = NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS 769 | NETWORK_VALIDATION_PROBE_HTTP; 770 int probesSucceeded = 0; 771 // If the isStrictMode is true, it means the network is invalid when NetworkMonitor 772 // tried to validate the private DNS but failed. 773 if (isStrictMode) { 774 probesCompleted &= ~NETWORK_VALIDATION_PROBE_HTTP; 775 probesSucceeded = probesCompleted; 776 probesCompleted |= NETWORK_VALIDATION_PROBE_PRIVDNS; 777 } 778 setProbesStatus(probesCompleted, probesSucceeded); 779 } 780 setNetworkPortal(String redirectUrl, boolean isStrictMode)781 void setNetworkPortal(String redirectUrl, boolean isStrictMode) { 782 setNetworkInvalid(isStrictMode); 783 mNmValidationRedirectUrl = redirectUrl; 784 // Suppose the portal is found when NetworkMonitor probes NETWORK_VALIDATION_PROBE_HTTP 785 // in the beginning, so the NETWORK_VALIDATION_PROBE_HTTPS hasn't probed yet. 786 int probesCompleted = NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTP; 787 int probesSucceeded = VALIDATION_RESULT_INVALID; 788 if (isStrictMode) { 789 probesCompleted |= NETWORK_VALIDATION_PROBE_PRIVDNS; 790 } 791 setProbesStatus(probesCompleted, probesSucceeded); 792 } 793 setNetworkPartial()794 void setNetworkPartial() { 795 mNmValidationResult = NETWORK_VALIDATION_RESULT_PARTIAL; 796 mNmValidationRedirectUrl = null; 797 int probesCompleted = NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS 798 | NETWORK_VALIDATION_PROBE_FALLBACK; 799 int probesSucceeded = NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_FALLBACK; 800 setProbesStatus(probesCompleted, probesSucceeded); 801 } 802 setNetworkPartialValid(boolean isStrictMode)803 void setNetworkPartialValid(boolean isStrictMode) { 804 setNetworkPartial(); 805 mNmValidationResult |= NETWORK_VALIDATION_RESULT_VALID; 806 int probesCompleted = NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS 807 | NETWORK_VALIDATION_PROBE_HTTP; 808 int probesSucceeded = NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTP; 809 // Suppose the partial network cannot pass the private DNS validation as well, so only 810 // add NETWORK_VALIDATION_PROBE_DNS in probesCompleted but not probesSucceeded. 811 if (isStrictMode) { 812 probesCompleted |= NETWORK_VALIDATION_PROBE_PRIVDNS; 813 } 814 setProbesStatus(probesCompleted, probesSucceeded); 815 } 816 setProbesStatus(int probesCompleted, int probesSucceeded)817 void setProbesStatus(int probesCompleted, int probesSucceeded) { 818 mProbesCompleted = probesCompleted; 819 mProbesSucceeded = probesSucceeded; 820 } 821 notifyCaptivePortalDataChanged(CaptivePortalData data)822 void notifyCaptivePortalDataChanged(CaptivePortalData data) { 823 try { 824 mNmCallbacks.notifyCaptivePortalDataChanged(data); 825 } catch (RemoteException e) { 826 throw new AssertionError("This cannot happen", e); 827 } 828 } 829 waitForRedirectUrl()830 public String waitForRedirectUrl() { 831 assertTrue(mNetworkStatusReceived.block(TIMEOUT_MS)); 832 return mRedirectUrl; 833 } 834 expectDisconnected()835 public void expectDisconnected() { 836 expectDisconnected(TIMEOUT_MS); 837 } 838 expectPreventReconnectReceived()839 public void expectPreventReconnectReceived() { 840 expectPreventReconnectReceived(TIMEOUT_MS); 841 } 842 notifyDataStallSuspected()843 void notifyDataStallSuspected() throws Exception { 844 final DataStallReportParcelable p = new DataStallReportParcelable(); 845 p.detectionMethod = DATA_STALL_DETECTION_METHOD; 846 p.timestampMillis = DATA_STALL_TIMESTAMP; 847 mNmCallbacks.notifyDataStallSuspected(p); 848 } 849 } 850 851 /** 852 * A NetworkFactory that allows tests to wait until any in-flight NetworkRequest add or remove 853 * operations have been processed. Before ConnectivityService can add or remove any requests, 854 * the factory must be told to expect those operations by calling expectAddRequestsWithScores or 855 * expectRemoveRequests. 856 */ 857 private static class MockNetworkFactory extends NetworkFactory { 858 private final ConditionVariable mNetworkStartedCV = new ConditionVariable(); 859 private final ConditionVariable mNetworkStoppedCV = new ConditionVariable(); 860 private final AtomicBoolean mNetworkStarted = new AtomicBoolean(false); 861 862 // Used to expect that requests be removed or added on a separate thread, without sleeping. 863 // Callers can call either expectAddRequestsWithScores() or expectRemoveRequests() exactly 864 // once, then cause some other thread to add or remove requests, then call 865 // waitForRequests(). 866 // It is not possible to wait for both add and remove requests. When adding, the queue 867 // contains the expected score. When removing, the value is unused, all matters is the 868 // number of objects in the queue. 869 private final LinkedBlockingQueue<Integer> mExpectations; 870 871 // Whether we are currently expecting requests to be added or removed. Valid only if 872 // mExpectations is non-empty. 873 private boolean mExpectingAdditions; 874 875 // Used to collect the networks requests managed by this factory. This is a duplicate of 876 // the internal information stored in the NetworkFactory (which is private). 877 private SparseArray<NetworkRequest> mNetworkRequests = new SparseArray<>(); 878 MockNetworkFactory(Looper looper, Context context, String logTag, NetworkCapabilities filter)879 public MockNetworkFactory(Looper looper, Context context, String logTag, 880 NetworkCapabilities filter) { 881 super(looper, context, logTag, filter); 882 mExpectations = new LinkedBlockingQueue<>(); 883 } 884 getMyRequestCount()885 public int getMyRequestCount() { 886 return getRequestCount(); 887 } 888 startNetwork()889 protected void startNetwork() { 890 mNetworkStarted.set(true); 891 mNetworkStartedCV.open(); 892 } 893 stopNetwork()894 protected void stopNetwork() { 895 mNetworkStarted.set(false); 896 mNetworkStoppedCV.open(); 897 } 898 getMyStartRequested()899 public boolean getMyStartRequested() { 900 return mNetworkStarted.get(); 901 } 902 getNetworkStartedCV()903 public ConditionVariable getNetworkStartedCV() { 904 mNetworkStartedCV.close(); 905 return mNetworkStartedCV; 906 } 907 getNetworkStoppedCV()908 public ConditionVariable getNetworkStoppedCV() { 909 mNetworkStoppedCV.close(); 910 return mNetworkStoppedCV; 911 } 912 913 @Override handleAddRequest(NetworkRequest request, int score, int factorySerialNumber)914 protected void handleAddRequest(NetworkRequest request, int score, 915 int factorySerialNumber) { 916 synchronized (mExpectations) { 917 final Integer expectedScore = mExpectations.poll(); // null if the queue is empty 918 919 assertNotNull("Added more requests than expected (" + request + " score : " 920 + score + ")", expectedScore); 921 // If we're expecting anything, we must be expecting additions. 922 if (!mExpectingAdditions) { 923 fail("Can't add requests while expecting requests to be removed"); 924 } 925 if (expectedScore != score) { 926 fail("Expected score was " + expectedScore + " but actual was " + score 927 + " in added request"); 928 } 929 930 // Add the request. 931 mNetworkRequests.put(request.requestId, request); 932 super.handleAddRequest(request, score, factorySerialNumber); 933 mExpectations.notify(); 934 } 935 } 936 937 @Override handleRemoveRequest(NetworkRequest request)938 protected void handleRemoveRequest(NetworkRequest request) { 939 synchronized (mExpectations) { 940 final Integer expectedScore = mExpectations.poll(); // null if the queue is empty 941 942 assertTrue("Removed more requests than expected", expectedScore != null); 943 // If we're expecting anything, we must be expecting removals. 944 if (mExpectingAdditions) { 945 fail("Can't remove requests while expecting requests to be added"); 946 } 947 948 // Remove the request. 949 mNetworkRequests.remove(request.requestId); 950 super.handleRemoveRequest(request); 951 mExpectations.notify(); 952 } 953 } 954 955 // Trigger releasing the request as unfulfillable triggerUnfulfillable(NetworkRequest r)956 public void triggerUnfulfillable(NetworkRequest r) { 957 super.releaseRequestAsUnfulfillableByAnyFactory(r); 958 } 959 assertNoExpectations()960 private void assertNoExpectations() { 961 if (mExpectations.size() != 0) { 962 fail("Can't add expectation, " + mExpectations.size() + " already pending"); 963 } 964 } 965 966 // Expects that requests with the specified scores will be added. expectAddRequestsWithScores(final int... scores)967 public void expectAddRequestsWithScores(final int... scores) { 968 assertNoExpectations(); 969 mExpectingAdditions = true; 970 for (int score : scores) { 971 mExpectations.add(score); 972 } 973 } 974 975 // Expects that count requests will be removed. expectRemoveRequests(final int count)976 public void expectRemoveRequests(final int count) { 977 assertNoExpectations(); 978 mExpectingAdditions = false; 979 for (int i = 0; i < count; ++i) { 980 mExpectations.add(0); // For removals the score is ignored so any value will do. 981 } 982 } 983 984 // Waits for the expected request additions or removals to happen within a timeout. waitForRequests()985 public void waitForRequests() throws InterruptedException { 986 final long deadline = SystemClock.elapsedRealtime() + TIMEOUT_MS; 987 synchronized (mExpectations) { 988 while (mExpectations.size() > 0 && SystemClock.elapsedRealtime() < deadline) { 989 mExpectations.wait(deadline - SystemClock.elapsedRealtime()); 990 } 991 } 992 final long count = mExpectations.size(); 993 final String msg = count + " requests still not " + 994 (mExpectingAdditions ? "added" : "removed") + 995 " after " + TIMEOUT_MS + " ms"; 996 assertEquals(msg, 0, count); 997 } 998 waitForNetworkRequests(final int count)999 public SparseArray<NetworkRequest> waitForNetworkRequests(final int count) 1000 throws InterruptedException { 1001 waitForRequests(); 1002 assertEquals(count, getMyRequestCount()); 1003 return mNetworkRequests; 1004 } 1005 } 1006 startHandlerThreadAndReturnLooper()1007 private static Looper startHandlerThreadAndReturnLooper() { 1008 final HandlerThread handlerThread = new HandlerThread("MockVpnThread"); 1009 handlerThread.start(); 1010 return handlerThread.getLooper(); 1011 } 1012 1013 private class MockVpn extends Vpn { 1014 // TODO : the interactions between this mock and the mock network agent are too 1015 // hard to get right at this moment, because it's unclear in which case which 1016 // target needs to get a method call or both, and in what order. It's because 1017 // MockNetworkAgent wants to manage its own NetworkCapabilities, but the Vpn 1018 // parent class of MockVpn agent wants that responsibility. 1019 // That being said inside the test it should be possible to make the interactions 1020 // harder to get wrong with precise speccing, judicious comments, helper methods 1021 // and a few sprinkled assertions. 1022 1023 private boolean mConnected = false; 1024 // Careful ! This is different from mNetworkAgent, because MockNetworkAgent does 1025 // not inherit from NetworkAgent. 1026 private TestNetworkAgentWrapper mMockNetworkAgent; 1027 private int mVpnType = VpnManager.TYPE_VPN_SERVICE; 1028 1029 private VpnInfo mVpnInfo; 1030 private Network[] mUnderlyingNetworks; 1031 MockVpn(int userId)1032 public MockVpn(int userId) { 1033 super(startHandlerThreadAndReturnLooper(), mServiceContext, mNetworkManagementService, 1034 userId, mock(KeyStore.class)); 1035 } 1036 setNetworkAgent(TestNetworkAgentWrapper agent)1037 public void setNetworkAgent(TestNetworkAgentWrapper agent) { 1038 agent.waitForIdle(TIMEOUT_MS); 1039 mMockNetworkAgent = agent; 1040 mNetworkAgent = agent.getNetworkAgent(); 1041 mNetworkCapabilities.set(agent.getNetworkCapabilities()); 1042 } 1043 setUids(Set<UidRange> uids)1044 public void setUids(Set<UidRange> uids) { 1045 mNetworkCapabilities.setUids(uids); 1046 updateCapabilities(null /* defaultNetwork */); 1047 } 1048 setVpnType(int vpnType)1049 public void setVpnType(int vpnType) { 1050 mVpnType = vpnType; 1051 } 1052 1053 @Override getNetId()1054 public int getNetId() { 1055 if (mMockNetworkAgent == null) { 1056 return NETID_UNSET; 1057 } 1058 return mMockNetworkAgent.getNetwork().netId; 1059 } 1060 1061 @Override appliesToUid(int uid)1062 public boolean appliesToUid(int uid) { 1063 return mConnected; // Trickery to simplify testing. 1064 } 1065 1066 @Override isCallerEstablishedOwnerLocked()1067 protected boolean isCallerEstablishedOwnerLocked() { 1068 return mConnected; // Similar trickery 1069 } 1070 1071 @Override getActiveAppVpnType()1072 public int getActiveAppVpnType() { 1073 return mVpnType; 1074 } 1075 connect(boolean isAlwaysMetered)1076 private void connect(boolean isAlwaysMetered) { 1077 mNetworkCapabilities.set(mMockNetworkAgent.getNetworkCapabilities()); 1078 mConnected = true; 1079 mConfig = new VpnConfig(); 1080 mConfig.isMetered = isAlwaysMetered; 1081 } 1082 connectAsAlwaysMetered()1083 public void connectAsAlwaysMetered() { 1084 connect(true /* isAlwaysMetered */); 1085 } 1086 connect()1087 public void connect() { 1088 connect(false /* isAlwaysMetered */); 1089 } 1090 1091 @Override updateCapabilities(Network defaultNetwork)1092 public NetworkCapabilities updateCapabilities(Network defaultNetwork) { 1093 if (!mConnected) return null; 1094 super.updateCapabilities(defaultNetwork); 1095 // Because super.updateCapabilities will update the capabilities of the agent but 1096 // not the mock agent, the mock agent needs to know about them. 1097 copyCapabilitiesToNetworkAgent(); 1098 return new NetworkCapabilities(mNetworkCapabilities); 1099 } 1100 copyCapabilitiesToNetworkAgent()1101 private void copyCapabilitiesToNetworkAgent() { 1102 if (null != mMockNetworkAgent) { 1103 mMockNetworkAgent.setNetworkCapabilities(mNetworkCapabilities, 1104 false /* sendToConnectivityService */); 1105 } 1106 } 1107 disconnect()1108 public void disconnect() { 1109 mConnected = false; 1110 mConfig = null; 1111 } 1112 1113 @Override getVpnInfo()1114 public synchronized VpnInfo getVpnInfo() { 1115 if (mVpnInfo != null) return mVpnInfo; 1116 1117 return super.getVpnInfo(); 1118 } 1119 setVpnInfo(VpnInfo vpnInfo)1120 private synchronized void setVpnInfo(VpnInfo vpnInfo) { 1121 mVpnInfo = vpnInfo; 1122 } 1123 1124 @Override getUnderlyingNetworks()1125 public synchronized Network[] getUnderlyingNetworks() { 1126 if (mUnderlyingNetworks != null) return mUnderlyingNetworks; 1127 1128 return super.getUnderlyingNetworks(); 1129 } 1130 1131 /** Don't override behavior for {@link Vpn#setUnderlyingNetworks}. */ overrideUnderlyingNetworks(Network[] underlyingNetworks)1132 private synchronized void overrideUnderlyingNetworks(Network[] underlyingNetworks) { 1133 mUnderlyingNetworks = underlyingNetworks; 1134 } 1135 } 1136 mockVpn(int uid)1137 private void mockVpn(int uid) { 1138 synchronized (mService.mVpns) { 1139 int userId = UserHandle.getUserId(uid); 1140 mMockVpn = new MockVpn(userId); 1141 // This has no effect unless the VPN is actually connected, because things like 1142 // getActiveNetworkForUidInternal call getNetworkAgentInfoForNetId on the VPN 1143 // netId, and check if that network is actually connected. 1144 mService.mVpns.put(userId, mMockVpn); 1145 } 1146 } 1147 setUidRulesChanged(int uidRules)1148 private void setUidRulesChanged(int uidRules) throws RemoteException { 1149 mPolicyListener.onUidRulesChanged(Process.myUid(), uidRules); 1150 } 1151 setRestrictBackgroundChanged(boolean restrictBackground)1152 private void setRestrictBackgroundChanged(boolean restrictBackground) throws RemoteException { 1153 mPolicyListener.onRestrictBackgroundChanged(restrictBackground); 1154 } 1155 getNat464Xlat(NetworkAgentWrapper mna)1156 private Nat464Xlat getNat464Xlat(NetworkAgentWrapper mna) { 1157 return mService.getNetworkAgentInfoForNetwork(mna.getNetwork()).clatd; 1158 } 1159 1160 private static class WrappedMultinetworkPolicyTracker extends MultinetworkPolicyTracker { 1161 volatile boolean mConfigRestrictsAvoidBadWifi; 1162 volatile int mConfigMeteredMultipathPreference; 1163 WrappedMultinetworkPolicyTracker(Context c, Handler h, Runnable r)1164 WrappedMultinetworkPolicyTracker(Context c, Handler h, Runnable r) { 1165 super(c, h, r); 1166 } 1167 1168 @Override configRestrictsAvoidBadWifi()1169 public boolean configRestrictsAvoidBadWifi() { 1170 return mConfigRestrictsAvoidBadWifi; 1171 } 1172 1173 @Override configMeteredMultipathPreference()1174 public int configMeteredMultipathPreference() { 1175 return mConfigMeteredMultipathPreference; 1176 } 1177 } 1178 1179 /** 1180 * Wait up to TIMEOUT_MS for {@code conditionVariable} to open. 1181 * Fails if TIMEOUT_MS goes by before {@code conditionVariable} opens. 1182 */ waitFor(ConditionVariable conditionVariable)1183 static private void waitFor(ConditionVariable conditionVariable) { 1184 if (conditionVariable.block(TIMEOUT_MS)) { 1185 return; 1186 } 1187 fail("ConditionVariable was blocked for more than " + TIMEOUT_MS + "ms"); 1188 } 1189 1190 private static final int VPN_USER = 0; 1191 private static final int APP1_UID = UserHandle.getUid(VPN_USER, 10100); 1192 private static final int APP2_UID = UserHandle.getUid(VPN_USER, 10101); 1193 private static final int VPN_UID = UserHandle.getUid(VPN_USER, 10043); 1194 1195 @Before setUp()1196 public void setUp() throws Exception { 1197 mContext = InstrumentationRegistry.getContext(); 1198 1199 MockitoAnnotations.initMocks(this); 1200 when(mMetricsService.defaultNetworkMetrics()).thenReturn(mDefaultNetworkMetrics); 1201 1202 when(mUserManager.getUsers(eq(true))).thenReturn( 1203 Arrays.asList(new UserInfo[] { 1204 new UserInfo(VPN_USER, "", 0), 1205 })); 1206 final ApplicationInfo applicationInfo = new ApplicationInfo(); 1207 applicationInfo.targetSdkVersion = Build.VERSION_CODES.Q; 1208 when(mPackageManager.getApplicationInfoAsUser(anyString(), anyInt(), any())) 1209 .thenReturn(applicationInfo); 1210 1211 // InstrumentationTestRunner prepares a looper, but AndroidJUnitRunner does not. 1212 // http://b/25897652 . 1213 if (Looper.myLooper() == null) { 1214 Looper.prepare(); 1215 } 1216 mockDefaultPackages(); 1217 1218 FakeSettingsProvider.clearSettingsProvider(); 1219 mServiceContext = new MockContext(InstrumentationRegistry.getContext(), 1220 new FakeSettingsProvider()); 1221 LocalServices.removeServiceForTest(NetworkPolicyManagerInternal.class); 1222 LocalServices.addService( 1223 NetworkPolicyManagerInternal.class, mock(NetworkPolicyManagerInternal.class)); 1224 1225 mAlarmManagerThread = new HandlerThread("TestAlarmManager"); 1226 mAlarmManagerThread.start(); 1227 initAlarmManager(mAlarmManager, mAlarmManagerThread.getThreadHandler()); 1228 1229 mCsHandlerThread = new HandlerThread("TestConnectivityService"); 1230 final ConnectivityService.Dependencies deps = makeDependencies(); 1231 mService = new ConnectivityService(mServiceContext, 1232 mNetworkManagementService, 1233 mStatsService, 1234 mNpm, 1235 mMockDnsResolver, 1236 mock(IpConnectivityLog.class), 1237 mMockNetd, 1238 deps); 1239 mService.mLingerDelayMs = TEST_LINGER_DELAY_MS; 1240 verify(deps).makeMultinetworkPolicyTracker(any(), any(), any()); 1241 1242 final ArgumentCaptor<INetworkPolicyListener> policyListenerCaptor = 1243 ArgumentCaptor.forClass(INetworkPolicyListener.class); 1244 verify(mNpm).registerListener(policyListenerCaptor.capture()); 1245 mPolicyListener = policyListenerCaptor.getValue(); 1246 1247 // Create local CM before sending system ready so that we can answer 1248 // getSystemService() correctly. 1249 mCm = new WrappedConnectivityManager(InstrumentationRegistry.getContext(), mService); 1250 mService.systemReady(); 1251 mockVpn(Process.myUid()); 1252 mCm.bindProcessToNetwork(null); 1253 1254 // Ensure that the default setting for Captive Portals is used for most tests 1255 setCaptivePortalMode(Settings.Global.CAPTIVE_PORTAL_MODE_PROMPT); 1256 setAlwaysOnNetworks(false); 1257 setPrivateDnsSettings(PRIVATE_DNS_MODE_OFF, "ignored.example.com"); 1258 } 1259 makeDependencies()1260 private ConnectivityService.Dependencies makeDependencies() { 1261 final MockableSystemProperties systemProperties = spy(new MockableSystemProperties()); 1262 when(systemProperties.getInt("net.tcp.default_init_rwnd", 0)).thenReturn(0); 1263 when(systemProperties.getBoolean("ro.radio.noril", false)).thenReturn(false); 1264 1265 final ConnectivityService.Dependencies deps = mock(ConnectivityService.Dependencies.class); 1266 doReturn(mCsHandlerThread).when(deps).makeHandlerThread(); 1267 doReturn(new TestNetIdManager()).when(deps).makeNetIdManager(); 1268 doReturn(mNetworkStack).when(deps).getNetworkStack(); 1269 doReturn(systemProperties).when(deps).getSystemProperties(); 1270 doReturn(mock(ProxyTracker.class)).when(deps).makeProxyTracker(any(), any()); 1271 doReturn(mMetricsService).when(deps).getMetricsLogger(); 1272 doReturn(true).when(deps).queryUserAccess(anyInt(), anyInt()); 1273 doReturn(mIpConnectivityMetrics).when(deps).getIpConnectivityMetrics(); 1274 doReturn(mBatteryStatsService).when(deps).getBatteryStatsService(); 1275 doReturn(true).when(deps).hasService(Context.ETHERNET_SERVICE); 1276 doAnswer(inv -> { 1277 mPolicyTracker = new WrappedMultinetworkPolicyTracker( 1278 inv.getArgument(0), inv.getArgument(1), inv.getArgument(2)); 1279 return mPolicyTracker; 1280 }).when(deps).makeMultinetworkPolicyTracker(any(), any(), any()); 1281 1282 return deps; 1283 } 1284 initAlarmManager(final AlarmManager am, final Handler alarmHandler)1285 private static void initAlarmManager(final AlarmManager am, final Handler alarmHandler) { 1286 doAnswer(inv -> { 1287 final long when = inv.getArgument(1); 1288 final WakeupMessage wakeupMsg = inv.getArgument(3); 1289 final Handler handler = inv.getArgument(4); 1290 1291 long delayMs = when - SystemClock.elapsedRealtime(); 1292 if (delayMs < 0) delayMs = 0; 1293 if (delayMs > UNREASONABLY_LONG_ALARM_WAIT_MS) { 1294 fail("Attempting to send msg more than " + UNREASONABLY_LONG_ALARM_WAIT_MS 1295 + "ms into the future: " + delayMs); 1296 } 1297 alarmHandler.postDelayed(() -> handler.post(wakeupMsg::onAlarm), wakeupMsg /* token */, 1298 delayMs); 1299 1300 return null; 1301 }).when(am).setExact(eq(AlarmManager.ELAPSED_REALTIME_WAKEUP), anyLong(), anyString(), 1302 any(WakeupMessage.class), any()); 1303 1304 doAnswer(inv -> { 1305 final WakeupMessage wakeupMsg = inv.getArgument(0); 1306 alarmHandler.removeCallbacksAndMessages(wakeupMsg /* token */); 1307 return null; 1308 }).when(am).cancel(any(WakeupMessage.class)); 1309 } 1310 1311 @After tearDown()1312 public void tearDown() throws Exception { 1313 setAlwaysOnNetworks(false); 1314 if (mCellNetworkAgent != null) { 1315 mCellNetworkAgent.disconnect(); 1316 mCellNetworkAgent = null; 1317 } 1318 if (mWiFiNetworkAgent != null) { 1319 mWiFiNetworkAgent.disconnect(); 1320 mWiFiNetworkAgent = null; 1321 } 1322 if (mEthernetNetworkAgent != null) { 1323 mEthernetNetworkAgent.disconnect(); 1324 mEthernetNetworkAgent = null; 1325 } 1326 FakeSettingsProvider.clearSettingsProvider(); 1327 1328 mCsHandlerThread.quitSafely(); 1329 mAlarmManagerThread.quitSafely(); 1330 } 1331 mockDefaultPackages()1332 private void mockDefaultPackages() throws Exception { 1333 final String testPackageName = mContext.getPackageName(); 1334 final PackageInfo testPackageInfo = mContext.getPackageManager().getPackageInfo( 1335 testPackageName, PackageManager.GET_PERMISSIONS); 1336 when(mPackageManager.getPackagesForUid(Binder.getCallingUid())).thenReturn( 1337 new String[] {testPackageName}); 1338 when(mPackageManager.getPackageInfoAsUser(eq(testPackageName), anyInt(), 1339 eq(UserHandle.getCallingUserId()))).thenReturn(testPackageInfo); 1340 1341 when(mPackageManager.getInstalledPackages(eq(GET_PERMISSIONS | MATCH_ANY_USER))).thenReturn( 1342 Arrays.asList(new PackageInfo[] { 1343 buildPackageInfo(/* SYSTEM */ false, APP1_UID), 1344 buildPackageInfo(/* SYSTEM */ false, APP2_UID), 1345 buildPackageInfo(/* SYSTEM */ false, VPN_UID) 1346 })); 1347 } 1348 verifyActiveNetwork(int transport)1349 private void verifyActiveNetwork(int transport) { 1350 // Test getActiveNetworkInfo() 1351 assertNotNull(mCm.getActiveNetworkInfo()); 1352 assertEquals(transportToLegacyType(transport), mCm.getActiveNetworkInfo().getType()); 1353 // Test getActiveNetwork() 1354 assertNotNull(mCm.getActiveNetwork()); 1355 assertEquals(mCm.getActiveNetwork(), mCm.getActiveNetworkForUid(Process.myUid())); 1356 if (!NetworkCapabilities.isValidTransport(transport)) { 1357 throw new IllegalStateException("Unknown transport " + transport); 1358 } 1359 switch (transport) { 1360 case TRANSPORT_WIFI: 1361 assertEquals(mCm.getActiveNetwork(), mWiFiNetworkAgent.getNetwork()); 1362 break; 1363 case TRANSPORT_CELLULAR: 1364 assertEquals(mCm.getActiveNetwork(), mCellNetworkAgent.getNetwork()); 1365 break; 1366 default: 1367 break; 1368 } 1369 // Test getNetworkInfo(Network) 1370 assertNotNull(mCm.getNetworkInfo(mCm.getActiveNetwork())); 1371 assertEquals(transportToLegacyType(transport), 1372 mCm.getNetworkInfo(mCm.getActiveNetwork()).getType()); 1373 // Test getNetworkCapabilities(Network) 1374 assertNotNull(mCm.getNetworkCapabilities(mCm.getActiveNetwork())); 1375 assertTrue(mCm.getNetworkCapabilities(mCm.getActiveNetwork()).hasTransport(transport)); 1376 } 1377 verifyNoNetwork()1378 private void verifyNoNetwork() { 1379 waitForIdle(); 1380 // Test getActiveNetworkInfo() 1381 assertNull(mCm.getActiveNetworkInfo()); 1382 // Test getActiveNetwork() 1383 assertNull(mCm.getActiveNetwork()); 1384 assertNull(mCm.getActiveNetworkForUid(Process.myUid())); 1385 // Test getAllNetworks() 1386 assertEmpty(mCm.getAllNetworks()); 1387 } 1388 1389 /** 1390 * Return a ConditionVariable that opens when {@code count} numbers of CONNECTIVITY_ACTION 1391 * broadcasts are received. 1392 */ registerConnectivityBroadcast(final int count)1393 private ConditionVariable registerConnectivityBroadcast(final int count) { 1394 return registerConnectivityBroadcastThat(count, intent -> true); 1395 } 1396 registerConnectivityBroadcastThat(final int count, @NonNull final Predicate<Intent> filter)1397 private ConditionVariable registerConnectivityBroadcastThat(final int count, 1398 @NonNull final Predicate<Intent> filter) { 1399 final ConditionVariable cv = new ConditionVariable(); 1400 final IntentFilter intentFilter = new IntentFilter(CONNECTIVITY_ACTION); 1401 final BroadcastReceiver receiver = new BroadcastReceiver() { 1402 private int remaining = count; 1403 public void onReceive(Context context, Intent intent) { 1404 if (!filter.test(intent)) return; 1405 if (--remaining == 0) { 1406 cv.open(); 1407 mServiceContext.unregisterReceiver(this); 1408 } 1409 } 1410 }; 1411 mServiceContext.registerReceiver(receiver, intentFilter); 1412 return cv; 1413 } 1414 1415 @Test testNetworkTypes()1416 public void testNetworkTypes() { 1417 // Ensure that our mocks for the networkAttributes config variable work as expected. If they 1418 // don't, then tests that depend on CONNECTIVITY_ACTION broadcasts for these network types 1419 // will fail. Failing here is much easier to debug. 1420 assertTrue(mCm.isNetworkSupported(TYPE_WIFI)); 1421 assertTrue(mCm.isNetworkSupported(TYPE_MOBILE)); 1422 assertTrue(mCm.isNetworkSupported(TYPE_MOBILE_MMS)); 1423 assertFalse(mCm.isNetworkSupported(TYPE_MOBILE_FOTA)); 1424 1425 // Check that TYPE_ETHERNET is supported. Unlike the asserts above, which only validate our 1426 // mocks, this assert exercises the ConnectivityService code path that ensures that 1427 // TYPE_ETHERNET is supported if the ethernet service is running. 1428 assertTrue(mCm.isNetworkSupported(TYPE_ETHERNET)); 1429 } 1430 1431 @Test testNetworkFeature()1432 public void testNetworkFeature() throws Exception { 1433 // Connect the cell agent and wait for the connected broadcast. 1434 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 1435 mCellNetworkAgent.addCapability(NET_CAPABILITY_SUPL); 1436 final ConditionVariable cv1 = registerConnectivityBroadcastThat(1, 1437 intent -> intent.getIntExtra(EXTRA_NETWORK_TYPE, -1) == TYPE_MOBILE); 1438 mCellNetworkAgent.connect(true); 1439 waitFor(cv1); 1440 1441 // Build legacy request for SUPL. 1442 final NetworkCapabilities legacyCaps = new NetworkCapabilities(); 1443 legacyCaps.addTransportType(TRANSPORT_CELLULAR); 1444 legacyCaps.addCapability(NET_CAPABILITY_SUPL); 1445 final NetworkRequest legacyRequest = new NetworkRequest(legacyCaps, TYPE_MOBILE_SUPL, 1446 ConnectivityManager.REQUEST_ID_UNSET, NetworkRequest.Type.REQUEST); 1447 1448 // File request, withdraw it and make sure no broadcast is sent 1449 final ConditionVariable cv2 = registerConnectivityBroadcast(1); 1450 final TestNetworkCallback callback = new TestNetworkCallback(); 1451 mCm.requestNetwork(legacyRequest, callback); 1452 callback.expectCallback(CallbackEntry.AVAILABLE, mCellNetworkAgent); 1453 mCm.unregisterNetworkCallback(callback); 1454 assertFalse(cv2.block(800)); // 800ms long enough to at least flake if this is sent 1455 // As the broadcast did not fire, the receiver was not unregistered. Do this now. 1456 mServiceContext.clearRegisteredReceivers(); 1457 1458 // Disconnect the network and expect mobile disconnected broadcast. Use a small hack to 1459 // check that has been sent. 1460 final AtomicBoolean vanillaAction = new AtomicBoolean(false); 1461 final ConditionVariable cv3 = registerConnectivityBroadcastThat(1, intent -> { 1462 if (intent.getAction().equals(CONNECTIVITY_ACTION)) { 1463 vanillaAction.set(true); 1464 } 1465 return !((NetworkInfo) intent.getExtra(EXTRA_NETWORK_INFO, -1)).isConnected(); 1466 }); 1467 mCellNetworkAgent.disconnect(); 1468 waitFor(cv3); 1469 assertTrue(vanillaAction.get()); 1470 } 1471 1472 @Test testLingering()1473 public void testLingering() throws Exception { 1474 verifyNoNetwork(); 1475 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 1476 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 1477 assertNull(mCm.getActiveNetworkInfo()); 1478 assertNull(mCm.getActiveNetwork()); 1479 // Test bringing up validated cellular. 1480 ConditionVariable cv = registerConnectivityBroadcast(1); 1481 mCellNetworkAgent.connect(true); 1482 waitFor(cv); 1483 verifyActiveNetwork(TRANSPORT_CELLULAR); 1484 assertLength(2, mCm.getAllNetworks()); 1485 assertTrue(mCm.getAllNetworks()[0].equals(mCm.getActiveNetwork()) || 1486 mCm.getAllNetworks()[1].equals(mCm.getActiveNetwork())); 1487 assertTrue(mCm.getAllNetworks()[0].equals(mWiFiNetworkAgent.getNetwork()) || 1488 mCm.getAllNetworks()[1].equals(mWiFiNetworkAgent.getNetwork())); 1489 // Test bringing up validated WiFi. 1490 cv = registerConnectivityBroadcast(2); 1491 mWiFiNetworkAgent.connect(true); 1492 waitFor(cv); 1493 verifyActiveNetwork(TRANSPORT_WIFI); 1494 assertLength(2, mCm.getAllNetworks()); 1495 assertTrue(mCm.getAllNetworks()[0].equals(mCm.getActiveNetwork()) || 1496 mCm.getAllNetworks()[1].equals(mCm.getActiveNetwork())); 1497 assertTrue(mCm.getAllNetworks()[0].equals(mCellNetworkAgent.getNetwork()) || 1498 mCm.getAllNetworks()[1].equals(mCellNetworkAgent.getNetwork())); 1499 // Test cellular linger timeout. 1500 mCellNetworkAgent.expectDisconnected(); 1501 waitForIdle(); 1502 assertLength(1, mCm.getAllNetworks()); 1503 verifyActiveNetwork(TRANSPORT_WIFI); 1504 assertLength(1, mCm.getAllNetworks()); 1505 assertEquals(mCm.getAllNetworks()[0], mCm.getActiveNetwork()); 1506 // Test WiFi disconnect. 1507 cv = registerConnectivityBroadcast(1); 1508 mWiFiNetworkAgent.disconnect(); 1509 waitFor(cv); 1510 verifyNoNetwork(); 1511 } 1512 1513 @Test testValidatedCellularOutscoresUnvalidatedWiFi()1514 public void testValidatedCellularOutscoresUnvalidatedWiFi() throws Exception { 1515 // Test bringing up unvalidated WiFi 1516 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 1517 ConditionVariable cv = registerConnectivityBroadcast(1); 1518 mWiFiNetworkAgent.connect(false); 1519 waitFor(cv); 1520 verifyActiveNetwork(TRANSPORT_WIFI); 1521 // Test bringing up unvalidated cellular 1522 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 1523 mCellNetworkAgent.connect(false); 1524 waitForIdle(); 1525 verifyActiveNetwork(TRANSPORT_WIFI); 1526 // Test cellular disconnect. 1527 mCellNetworkAgent.disconnect(); 1528 waitForIdle(); 1529 verifyActiveNetwork(TRANSPORT_WIFI); 1530 // Test bringing up validated cellular 1531 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 1532 cv = registerConnectivityBroadcast(2); 1533 mCellNetworkAgent.connect(true); 1534 waitFor(cv); 1535 verifyActiveNetwork(TRANSPORT_CELLULAR); 1536 // Test cellular disconnect. 1537 cv = registerConnectivityBroadcast(2); 1538 mCellNetworkAgent.disconnect(); 1539 waitFor(cv); 1540 verifyActiveNetwork(TRANSPORT_WIFI); 1541 // Test WiFi disconnect. 1542 cv = registerConnectivityBroadcast(1); 1543 mWiFiNetworkAgent.disconnect(); 1544 waitFor(cv); 1545 verifyNoNetwork(); 1546 } 1547 1548 @Test testUnvalidatedWifiOutscoresUnvalidatedCellular()1549 public void testUnvalidatedWifiOutscoresUnvalidatedCellular() throws Exception { 1550 // Test bringing up unvalidated cellular. 1551 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 1552 ConditionVariable cv = registerConnectivityBroadcast(1); 1553 mCellNetworkAgent.connect(false); 1554 waitFor(cv); 1555 verifyActiveNetwork(TRANSPORT_CELLULAR); 1556 // Test bringing up unvalidated WiFi. 1557 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 1558 cv = registerConnectivityBroadcast(2); 1559 mWiFiNetworkAgent.connect(false); 1560 waitFor(cv); 1561 verifyActiveNetwork(TRANSPORT_WIFI); 1562 // Test WiFi disconnect. 1563 cv = registerConnectivityBroadcast(2); 1564 mWiFiNetworkAgent.disconnect(); 1565 waitFor(cv); 1566 verifyActiveNetwork(TRANSPORT_CELLULAR); 1567 // Test cellular disconnect. 1568 cv = registerConnectivityBroadcast(1); 1569 mCellNetworkAgent.disconnect(); 1570 waitFor(cv); 1571 verifyNoNetwork(); 1572 } 1573 1574 @Test testUnlingeringDoesNotValidate()1575 public void testUnlingeringDoesNotValidate() throws Exception { 1576 // Test bringing up unvalidated WiFi. 1577 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 1578 ConditionVariable cv = registerConnectivityBroadcast(1); 1579 mWiFiNetworkAgent.connect(false); 1580 waitFor(cv); 1581 verifyActiveNetwork(TRANSPORT_WIFI); 1582 assertFalse(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).hasCapability( 1583 NET_CAPABILITY_VALIDATED)); 1584 // Test bringing up validated cellular. 1585 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 1586 cv = registerConnectivityBroadcast(2); 1587 mCellNetworkAgent.connect(true); 1588 waitFor(cv); 1589 verifyActiveNetwork(TRANSPORT_CELLULAR); 1590 assertFalse(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).hasCapability( 1591 NET_CAPABILITY_VALIDATED)); 1592 // Test cellular disconnect. 1593 cv = registerConnectivityBroadcast(2); 1594 mCellNetworkAgent.disconnect(); 1595 waitFor(cv); 1596 verifyActiveNetwork(TRANSPORT_WIFI); 1597 // Unlingering a network should not cause it to be marked as validated. 1598 assertFalse(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).hasCapability( 1599 NET_CAPABILITY_VALIDATED)); 1600 } 1601 1602 @Test testCellularOutscoresWeakWifi()1603 public void testCellularOutscoresWeakWifi() throws Exception { 1604 // Test bringing up validated cellular. 1605 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 1606 ConditionVariable cv = registerConnectivityBroadcast(1); 1607 mCellNetworkAgent.connect(true); 1608 waitFor(cv); 1609 verifyActiveNetwork(TRANSPORT_CELLULAR); 1610 // Test bringing up validated WiFi. 1611 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 1612 cv = registerConnectivityBroadcast(2); 1613 mWiFiNetworkAgent.connect(true); 1614 waitFor(cv); 1615 verifyActiveNetwork(TRANSPORT_WIFI); 1616 // Test WiFi getting really weak. 1617 cv = registerConnectivityBroadcast(2); 1618 mWiFiNetworkAgent.adjustScore(-11); 1619 waitFor(cv); 1620 verifyActiveNetwork(TRANSPORT_CELLULAR); 1621 // Test WiFi restoring signal strength. 1622 cv = registerConnectivityBroadcast(2); 1623 mWiFiNetworkAgent.adjustScore(11); 1624 waitFor(cv); 1625 verifyActiveNetwork(TRANSPORT_WIFI); 1626 } 1627 1628 @Test testReapingNetwork()1629 public void testReapingNetwork() throws Exception { 1630 // Test bringing up WiFi without NET_CAPABILITY_INTERNET. 1631 // Expect it to be torn down immediately because it satisfies no requests. 1632 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 1633 mWiFiNetworkAgent.connectWithoutInternet(); 1634 mWiFiNetworkAgent.expectDisconnected(); 1635 // Test bringing up cellular without NET_CAPABILITY_INTERNET. 1636 // Expect it to be torn down immediately because it satisfies no requests. 1637 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 1638 mCellNetworkAgent.connectWithoutInternet(); 1639 mCellNetworkAgent.expectDisconnected(); 1640 // Test bringing up validated WiFi. 1641 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 1642 final ConditionVariable cv = registerConnectivityBroadcast(1); 1643 mWiFiNetworkAgent.connect(true); 1644 waitFor(cv); 1645 verifyActiveNetwork(TRANSPORT_WIFI); 1646 // Test bringing up unvalidated cellular. 1647 // Expect it to be torn down because it could never be the highest scoring network 1648 // satisfying the default request even if it validated. 1649 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 1650 mCellNetworkAgent.connect(false); 1651 mCellNetworkAgent.expectDisconnected(); 1652 verifyActiveNetwork(TRANSPORT_WIFI); 1653 mWiFiNetworkAgent.disconnect(); 1654 mWiFiNetworkAgent.expectDisconnected(); 1655 } 1656 1657 @Test testCellularFallback()1658 public void testCellularFallback() throws Exception { 1659 // Test bringing up validated cellular. 1660 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 1661 ConditionVariable cv = registerConnectivityBroadcast(1); 1662 mCellNetworkAgent.connect(true); 1663 waitFor(cv); 1664 verifyActiveNetwork(TRANSPORT_CELLULAR); 1665 // Test bringing up validated WiFi. 1666 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 1667 cv = registerConnectivityBroadcast(2); 1668 mWiFiNetworkAgent.connect(true); 1669 waitFor(cv); 1670 verifyActiveNetwork(TRANSPORT_WIFI); 1671 // Reevaluate WiFi (it'll instantly fail DNS). 1672 cv = registerConnectivityBroadcast(2); 1673 assertTrue(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).hasCapability( 1674 NET_CAPABILITY_VALIDATED)); 1675 mCm.reportBadNetwork(mWiFiNetworkAgent.getNetwork()); 1676 // Should quickly fall back to Cellular. 1677 waitFor(cv); 1678 assertFalse(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).hasCapability( 1679 NET_CAPABILITY_VALIDATED)); 1680 verifyActiveNetwork(TRANSPORT_CELLULAR); 1681 // Reevaluate cellular (it'll instantly fail DNS). 1682 cv = registerConnectivityBroadcast(2); 1683 assertTrue(mCm.getNetworkCapabilities(mCellNetworkAgent.getNetwork()).hasCapability( 1684 NET_CAPABILITY_VALIDATED)); 1685 mCm.reportBadNetwork(mCellNetworkAgent.getNetwork()); 1686 // Should quickly fall back to WiFi. 1687 waitFor(cv); 1688 assertFalse(mCm.getNetworkCapabilities(mCellNetworkAgent.getNetwork()).hasCapability( 1689 NET_CAPABILITY_VALIDATED)); 1690 assertFalse(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).hasCapability( 1691 NET_CAPABILITY_VALIDATED)); 1692 verifyActiveNetwork(TRANSPORT_WIFI); 1693 } 1694 1695 @Test testWiFiFallback()1696 public void testWiFiFallback() throws Exception { 1697 // Test bringing up unvalidated WiFi. 1698 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 1699 ConditionVariable cv = registerConnectivityBroadcast(1); 1700 mWiFiNetworkAgent.connect(false); 1701 waitFor(cv); 1702 verifyActiveNetwork(TRANSPORT_WIFI); 1703 // Test bringing up validated cellular. 1704 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 1705 cv = registerConnectivityBroadcast(2); 1706 mCellNetworkAgent.connect(true); 1707 waitFor(cv); 1708 verifyActiveNetwork(TRANSPORT_CELLULAR); 1709 // Reevaluate cellular (it'll instantly fail DNS). 1710 cv = registerConnectivityBroadcast(2); 1711 assertTrue(mCm.getNetworkCapabilities(mCellNetworkAgent.getNetwork()).hasCapability( 1712 NET_CAPABILITY_VALIDATED)); 1713 mCm.reportBadNetwork(mCellNetworkAgent.getNetwork()); 1714 // Should quickly fall back to WiFi. 1715 waitFor(cv); 1716 assertFalse(mCm.getNetworkCapabilities(mCellNetworkAgent.getNetwork()).hasCapability( 1717 NET_CAPABILITY_VALIDATED)); 1718 verifyActiveNetwork(TRANSPORT_WIFI); 1719 } 1720 1721 @Test testRequiresValidation()1722 public void testRequiresValidation() { 1723 assertTrue(NetworkMonitorUtils.isValidationRequired( 1724 mCm.getDefaultRequest().networkCapabilities)); 1725 } 1726 1727 /** 1728 * Utility NetworkCallback for testing. The caller must explicitly test for all the callbacks 1729 * this class receives, by calling expectCallback() exactly once each time a callback is 1730 * received. assertNoCallback may be called at any time. 1731 */ 1732 private class TestNetworkCallback extends TestableNetworkCallback { TestNetworkCallback()1733 TestNetworkCallback() { 1734 super(TEST_CALLBACK_TIMEOUT_MS); 1735 } 1736 1737 @Override assertNoCallback()1738 public void assertNoCallback() { 1739 // TODO: better support this use case in TestableNetworkCallback 1740 waitForIdle(); 1741 assertNoCallback(0 /* timeout */); 1742 } 1743 1744 @Override expectCallback(final KClass<T> type, final HasNetwork n, final long timeoutMs)1745 public <T extends CallbackEntry> T expectCallback(final KClass<T> type, final HasNetwork n, 1746 final long timeoutMs) { 1747 final T callback = super.expectCallback(type, n, timeoutMs); 1748 if (callback instanceof CallbackEntry.Losing) { 1749 // TODO : move this to the specific test(s) needing this rather than here. 1750 final CallbackEntry.Losing losing = (CallbackEntry.Losing) callback; 1751 final int maxMsToLive = losing.getMaxMsToLive(); 1752 String msg = String.format( 1753 "Invalid linger time value %d, must be between %d and %d", 1754 maxMsToLive, 0, mService.mLingerDelayMs); 1755 assertTrue(msg, 0 <= maxMsToLive && maxMsToLive <= mService.mLingerDelayMs); 1756 } 1757 return callback; 1758 } 1759 } 1760 1761 // Can't be part of TestNetworkCallback because "cannot be declared static; static methods can 1762 // only be declared in a static or top level type". assertNoCallbacks(TestNetworkCallback .... callbacks)1763 static void assertNoCallbacks(TestNetworkCallback ... callbacks) { 1764 for (TestNetworkCallback c : callbacks) { 1765 c.assertNoCallback(); 1766 } 1767 } 1768 1769 @Test testStateChangeNetworkCallbacks()1770 public void testStateChangeNetworkCallbacks() throws Exception { 1771 final TestNetworkCallback genericNetworkCallback = new TestNetworkCallback(); 1772 final TestNetworkCallback wifiNetworkCallback = new TestNetworkCallback(); 1773 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback(); 1774 final NetworkRequest genericRequest = new NetworkRequest.Builder() 1775 .clearCapabilities().build(); 1776 final NetworkRequest wifiRequest = new NetworkRequest.Builder() 1777 .addTransportType(TRANSPORT_WIFI).build(); 1778 final NetworkRequest cellRequest = new NetworkRequest.Builder() 1779 .addTransportType(TRANSPORT_CELLULAR).build(); 1780 mCm.registerNetworkCallback(genericRequest, genericNetworkCallback); 1781 mCm.registerNetworkCallback(wifiRequest, wifiNetworkCallback); 1782 mCm.registerNetworkCallback(cellRequest, cellNetworkCallback); 1783 1784 // Test unvalidated networks 1785 ConditionVariable cv = registerConnectivityBroadcast(1); 1786 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 1787 mCellNetworkAgent.connect(false); 1788 genericNetworkCallback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent); 1789 cellNetworkCallback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent); 1790 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 1791 waitFor(cv); 1792 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback); 1793 1794 // This should not trigger spurious onAvailable() callbacks, b/21762680. 1795 mCellNetworkAgent.adjustScore(-1); 1796 waitForIdle(); 1797 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback); 1798 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 1799 1800 cv = registerConnectivityBroadcast(2); 1801 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 1802 mWiFiNetworkAgent.connect(false); 1803 genericNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 1804 wifiNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 1805 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 1806 waitFor(cv); 1807 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback); 1808 1809 cv = registerConnectivityBroadcast(2); 1810 mWiFiNetworkAgent.disconnect(); 1811 genericNetworkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 1812 wifiNetworkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 1813 cellNetworkCallback.assertNoCallback(); 1814 waitFor(cv); 1815 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback); 1816 1817 cv = registerConnectivityBroadcast(1); 1818 mCellNetworkAgent.disconnect(); 1819 genericNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 1820 cellNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 1821 waitFor(cv); 1822 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback); 1823 1824 // Test validated networks 1825 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 1826 mCellNetworkAgent.connect(true); 1827 genericNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 1828 cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 1829 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 1830 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback); 1831 1832 // This should not trigger spurious onAvailable() callbacks, b/21762680. 1833 mCellNetworkAgent.adjustScore(-1); 1834 waitForIdle(); 1835 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback); 1836 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 1837 1838 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 1839 mWiFiNetworkAgent.connect(true); 1840 genericNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 1841 genericNetworkCallback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent); 1842 genericNetworkCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent); 1843 wifiNetworkCallback.expectAvailableThenValidatedCallbacks(mWiFiNetworkAgent); 1844 cellNetworkCallback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent); 1845 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 1846 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback); 1847 1848 mWiFiNetworkAgent.disconnect(); 1849 genericNetworkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 1850 wifiNetworkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 1851 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback); 1852 1853 mCellNetworkAgent.disconnect(); 1854 genericNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 1855 cellNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 1856 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback); 1857 } 1858 doNetworkCallbacksSanitizationTest(boolean sanitized)1859 private void doNetworkCallbacksSanitizationTest(boolean sanitized) throws Exception { 1860 final TestNetworkCallback callback = new TestNetworkCallback(); 1861 final TestNetworkCallback defaultCallback = new TestNetworkCallback(); 1862 final NetworkRequest wifiRequest = new NetworkRequest.Builder() 1863 .addTransportType(TRANSPORT_WIFI).build(); 1864 mCm.registerNetworkCallback(wifiRequest, callback); 1865 mCm.registerDefaultNetworkCallback(defaultCallback); 1866 1867 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 1868 mWiFiNetworkAgent.connect(false); 1869 callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 1870 defaultCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 1871 1872 final LinkProperties newLp = new LinkProperties(); 1873 final Uri capportUrl = Uri.parse("https://capport.example.com/api"); 1874 final CaptivePortalData capportData = new CaptivePortalData.Builder() 1875 .setCaptive(true).build(); 1876 1877 final Uri expectedCapportUrl = sanitized ? null : capportUrl; 1878 newLp.setCaptivePortalApiUrl(capportUrl); 1879 mWiFiNetworkAgent.sendLinkProperties(newLp); 1880 callback.expectLinkPropertiesThat(mWiFiNetworkAgent, lp -> 1881 Objects.equals(expectedCapportUrl, lp.getCaptivePortalApiUrl())); 1882 defaultCallback.expectLinkPropertiesThat(mWiFiNetworkAgent, lp -> 1883 Objects.equals(expectedCapportUrl, lp.getCaptivePortalApiUrl())); 1884 1885 final CaptivePortalData expectedCapportData = sanitized ? null : capportData; 1886 mWiFiNetworkAgent.notifyCaptivePortalDataChanged(capportData); 1887 callback.expectLinkPropertiesThat(mWiFiNetworkAgent, lp -> 1888 Objects.equals(expectedCapportData, lp.getCaptivePortalData())); 1889 defaultCallback.expectLinkPropertiesThat(mWiFiNetworkAgent, lp -> 1890 Objects.equals(expectedCapportData, lp.getCaptivePortalData())); 1891 1892 final LinkProperties lp = mCm.getLinkProperties(mWiFiNetworkAgent.getNetwork()); 1893 assertEquals(expectedCapportUrl, lp.getCaptivePortalApiUrl()); 1894 assertEquals(expectedCapportData, lp.getCaptivePortalData()); 1895 } 1896 1897 @Test networkCallbacksSanitizationTest_Sanitize()1898 public void networkCallbacksSanitizationTest_Sanitize() throws Exception { 1899 mServiceContext.setPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, 1900 PERMISSION_DENIED); 1901 mServiceContext.setPermission(Manifest.permission.NETWORK_SETTINGS, 1902 PERMISSION_DENIED); 1903 doNetworkCallbacksSanitizationTest(true /* sanitized */); 1904 } 1905 1906 @Test networkCallbacksSanitizationTest_NoSanitize_NetworkStack()1907 public void networkCallbacksSanitizationTest_NoSanitize_NetworkStack() throws Exception { 1908 mServiceContext.setPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, 1909 PERMISSION_GRANTED); 1910 mServiceContext.setPermission(Manifest.permission.NETWORK_SETTINGS, PERMISSION_DENIED); 1911 doNetworkCallbacksSanitizationTest(false /* sanitized */); 1912 } 1913 1914 @Test networkCallbacksSanitizationTest_NoSanitize_Settings()1915 public void networkCallbacksSanitizationTest_NoSanitize_Settings() throws Exception { 1916 mServiceContext.setPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, 1917 PERMISSION_DENIED); 1918 mServiceContext.setPermission(Manifest.permission.NETWORK_SETTINGS, PERMISSION_GRANTED); 1919 doNetworkCallbacksSanitizationTest(false /* sanitized */); 1920 } 1921 1922 @Test testMultipleLingering()1923 public void testMultipleLingering() throws Exception { 1924 // This test would be flaky with the default 120ms timer: that is short enough that 1925 // lingered networks are torn down before assertions can be run. We don't want to mock the 1926 // lingering timer to keep the WakeupMessage logic realistic: this has already proven useful 1927 // in detecting races. 1928 mService.mLingerDelayMs = 300; 1929 1930 NetworkRequest request = new NetworkRequest.Builder() 1931 .clearCapabilities().addCapability(NET_CAPABILITY_NOT_METERED) 1932 .build(); 1933 TestNetworkCallback callback = new TestNetworkCallback(); 1934 mCm.registerNetworkCallback(request, callback); 1935 1936 TestNetworkCallback defaultCallback = new TestNetworkCallback(); 1937 mCm.registerDefaultNetworkCallback(defaultCallback); 1938 1939 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 1940 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 1941 mEthernetNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_ETHERNET); 1942 1943 mCellNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED); 1944 mWiFiNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED); 1945 mEthernetNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED); 1946 1947 mCellNetworkAgent.connect(true); 1948 callback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 1949 defaultCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 1950 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 1951 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 1952 1953 mWiFiNetworkAgent.connect(true); 1954 // We get AVAILABLE on wifi when wifi connects and satisfies our unmetered request. 1955 // We then get LOSING when wifi validates and cell is outscored. 1956 callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 1957 // TODO: Investigate sending validated before losing. 1958 callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent); 1959 callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent); 1960 defaultCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent); 1961 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 1962 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 1963 1964 mEthernetNetworkAgent.connect(true); 1965 callback.expectAvailableCallbacksUnvalidated(mEthernetNetworkAgent); 1966 // TODO: Investigate sending validated before losing. 1967 callback.expectCallback(CallbackEntry.LOSING, mWiFiNetworkAgent); 1968 callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mEthernetNetworkAgent); 1969 defaultCallback.expectAvailableDoubleValidatedCallbacks(mEthernetNetworkAgent); 1970 assertEquals(mEthernetNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 1971 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 1972 1973 mEthernetNetworkAgent.disconnect(); 1974 callback.expectCallback(CallbackEntry.LOST, mEthernetNetworkAgent); 1975 defaultCallback.expectCallback(CallbackEntry.LOST, mEthernetNetworkAgent); 1976 defaultCallback.expectAvailableCallbacksValidated(mWiFiNetworkAgent); 1977 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 1978 1979 for (int i = 0; i < 4; i++) { 1980 TestNetworkAgentWrapper oldNetwork, newNetwork; 1981 if (i % 2 == 0) { 1982 mWiFiNetworkAgent.adjustScore(-15); 1983 oldNetwork = mWiFiNetworkAgent; 1984 newNetwork = mCellNetworkAgent; 1985 } else { 1986 mWiFiNetworkAgent.adjustScore(15); 1987 oldNetwork = mCellNetworkAgent; 1988 newNetwork = mWiFiNetworkAgent; 1989 1990 } 1991 callback.expectCallback(CallbackEntry.LOSING, oldNetwork); 1992 // TODO: should we send an AVAILABLE callback to newNetwork, to indicate that it is no 1993 // longer lingering? 1994 defaultCallback.expectAvailableCallbacksValidated(newNetwork); 1995 assertEquals(newNetwork.getNetwork(), mCm.getActiveNetwork()); 1996 } 1997 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 1998 1999 // Verify that if a network no longer satisfies a request, we send LOST and not LOSING, even 2000 // if the network is still up. 2001 mWiFiNetworkAgent.removeCapability(NET_CAPABILITY_NOT_METERED); 2002 // We expect a notification about the capabilities change, and nothing else. 2003 defaultCallback.expectCapabilitiesWithout(NET_CAPABILITY_NOT_METERED, mWiFiNetworkAgent); 2004 defaultCallback.assertNoCallback(); 2005 callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 2006 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 2007 2008 // Wifi no longer satisfies our listen, which is for an unmetered network. 2009 // But because its score is 55, it's still up (and the default network). 2010 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 2011 2012 // Disconnect our test networks. 2013 mWiFiNetworkAgent.disconnect(); 2014 defaultCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 2015 defaultCallback.expectAvailableCallbacksValidated(mCellNetworkAgent); 2016 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 2017 mCellNetworkAgent.disconnect(); 2018 defaultCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 2019 waitForIdle(); 2020 assertEquals(null, mCm.getActiveNetwork()); 2021 2022 mCm.unregisterNetworkCallback(callback); 2023 waitForIdle(); 2024 2025 // Check that a network is only lingered or torn down if it would not satisfy a request even 2026 // if it validated. 2027 request = new NetworkRequest.Builder().clearCapabilities().build(); 2028 callback = new TestNetworkCallback(); 2029 2030 mCm.registerNetworkCallback(request, callback); 2031 2032 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 2033 mCellNetworkAgent.connect(false); // Score: 10 2034 callback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent); 2035 defaultCallback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent); 2036 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 2037 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 2038 2039 // Bring up wifi with a score of 20. 2040 // Cell stays up because it would satisfy the default request if it validated. 2041 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 2042 mWiFiNetworkAgent.connect(false); // Score: 20 2043 callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 2044 defaultCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 2045 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 2046 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 2047 2048 mWiFiNetworkAgent.disconnect(); 2049 callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 2050 defaultCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 2051 defaultCallback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent); 2052 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 2053 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 2054 2055 // Bring up wifi with a score of 70. 2056 // Cell is lingered because it would not satisfy any request, even if it validated. 2057 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 2058 mWiFiNetworkAgent.adjustScore(50); 2059 mWiFiNetworkAgent.connect(false); // Score: 70 2060 callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 2061 callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent); 2062 defaultCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 2063 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 2064 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 2065 2066 // Tear down wifi. 2067 mWiFiNetworkAgent.disconnect(); 2068 callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 2069 defaultCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 2070 defaultCallback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent); 2071 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 2072 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 2073 2074 // Bring up wifi, then validate it. Previous versions would immediately tear down cell, but 2075 // it's arguably correct to linger it, since it was the default network before it validated. 2076 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 2077 mWiFiNetworkAgent.connect(true); 2078 callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 2079 // TODO: Investigate sending validated before losing. 2080 callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent); 2081 callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent); 2082 defaultCallback.expectAvailableThenValidatedCallbacks(mWiFiNetworkAgent); 2083 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 2084 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 2085 2086 mWiFiNetworkAgent.disconnect(); 2087 callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 2088 defaultCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 2089 defaultCallback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent); 2090 mCellNetworkAgent.disconnect(); 2091 callback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 2092 defaultCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 2093 waitForIdle(); 2094 assertEquals(null, mCm.getActiveNetwork()); 2095 2096 // If a network is lingering, and we add and remove a request from it, resume lingering. 2097 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 2098 mCellNetworkAgent.connect(true); 2099 callback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 2100 defaultCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 2101 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 2102 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 2103 mWiFiNetworkAgent.connect(true); 2104 defaultCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent); 2105 callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 2106 // TODO: Investigate sending validated before losing. 2107 callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent); 2108 callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent); 2109 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 2110 2111 NetworkRequest cellRequest = new NetworkRequest.Builder() 2112 .addTransportType(TRANSPORT_CELLULAR).build(); 2113 NetworkCallback noopCallback = new NetworkCallback(); 2114 mCm.requestNetwork(cellRequest, noopCallback); 2115 // TODO: should this cause an AVAILABLE callback, to indicate that the network is no longer 2116 // lingering? 2117 mCm.unregisterNetworkCallback(noopCallback); 2118 callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent); 2119 2120 // Similar to the above: lingering can start even after the lingered request is removed. 2121 // Disconnect wifi and switch to cell. 2122 mWiFiNetworkAgent.disconnect(); 2123 callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 2124 defaultCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 2125 defaultCallback.expectAvailableCallbacksValidated(mCellNetworkAgent); 2126 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 2127 2128 // Cell is now the default network. Pin it with a cell-specific request. 2129 noopCallback = new NetworkCallback(); // Can't reuse NetworkCallbacks. http://b/20701525 2130 mCm.requestNetwork(cellRequest, noopCallback); 2131 2132 // Now connect wifi, and expect it to become the default network. 2133 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 2134 mWiFiNetworkAgent.connect(true); 2135 callback.expectAvailableThenValidatedCallbacks(mWiFiNetworkAgent); 2136 defaultCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent); 2137 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 2138 // The default request is lingering on cell, but nothing happens to cell, and we send no 2139 // callbacks for it, because it's kept up by cellRequest. 2140 callback.assertNoCallback(); 2141 // Now unregister cellRequest and expect cell to start lingering. 2142 mCm.unregisterNetworkCallback(noopCallback); 2143 callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent); 2144 2145 // Let linger run its course. 2146 callback.assertNoCallback(); 2147 final int lingerTimeoutMs = mService.mLingerDelayMs + mService.mLingerDelayMs / 4; 2148 callback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent, lingerTimeoutMs); 2149 2150 // Register a TRACK_DEFAULT request and check that it does not affect lingering. 2151 TestNetworkCallback trackDefaultCallback = new TestNetworkCallback(); 2152 mCm.registerDefaultNetworkCallback(trackDefaultCallback); 2153 trackDefaultCallback.expectAvailableCallbacksValidated(mWiFiNetworkAgent); 2154 mEthernetNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_ETHERNET); 2155 mEthernetNetworkAgent.connect(true); 2156 callback.expectAvailableCallbacksUnvalidated(mEthernetNetworkAgent); 2157 callback.expectCallback(CallbackEntry.LOSING, mWiFiNetworkAgent); 2158 callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mEthernetNetworkAgent); 2159 trackDefaultCallback.expectAvailableDoubleValidatedCallbacks(mEthernetNetworkAgent); 2160 defaultCallback.expectAvailableDoubleValidatedCallbacks(mEthernetNetworkAgent); 2161 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 2162 2163 // Let linger run its course. 2164 callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent, lingerTimeoutMs); 2165 2166 // Clean up. 2167 mEthernetNetworkAgent.disconnect(); 2168 callback.expectCallback(CallbackEntry.LOST, mEthernetNetworkAgent); 2169 defaultCallback.expectCallback(CallbackEntry.LOST, mEthernetNetworkAgent); 2170 trackDefaultCallback.expectCallback(CallbackEntry.LOST, mEthernetNetworkAgent); 2171 2172 mCm.unregisterNetworkCallback(callback); 2173 mCm.unregisterNetworkCallback(defaultCallback); 2174 mCm.unregisterNetworkCallback(trackDefaultCallback); 2175 } 2176 grantUsingBackgroundNetworksPermissionForUid(final int uid)2177 private void grantUsingBackgroundNetworksPermissionForUid(final int uid) throws Exception { 2178 final String testPackageName = mContext.getPackageName(); 2179 when(mPackageManager.getPackageInfo(eq(testPackageName), eq(GET_PERMISSIONS))) 2180 .thenReturn(buildPackageInfo(true, uid)); 2181 mService.mPermissionMonitor.onPackageAdded(testPackageName, uid); 2182 } 2183 2184 @Test testNetworkGoesIntoBackgroundAfterLinger()2185 public void testNetworkGoesIntoBackgroundAfterLinger() throws Exception { 2186 setAlwaysOnNetworks(true); 2187 grantUsingBackgroundNetworksPermissionForUid(Binder.getCallingUid()); 2188 NetworkRequest request = new NetworkRequest.Builder() 2189 .clearCapabilities() 2190 .build(); 2191 TestNetworkCallback callback = new TestNetworkCallback(); 2192 mCm.registerNetworkCallback(request, callback); 2193 2194 TestNetworkCallback defaultCallback = new TestNetworkCallback(); 2195 mCm.registerDefaultNetworkCallback(defaultCallback); 2196 2197 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 2198 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 2199 2200 mCellNetworkAgent.connect(true); 2201 callback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 2202 defaultCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 2203 2204 // Wifi comes up and cell lingers. 2205 mWiFiNetworkAgent.connect(true); 2206 defaultCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent); 2207 callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 2208 callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent); 2209 callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent); 2210 2211 // File a request for cellular, then release it. 2212 NetworkRequest cellRequest = new NetworkRequest.Builder() 2213 .addTransportType(TRANSPORT_CELLULAR).build(); 2214 NetworkCallback noopCallback = new NetworkCallback(); 2215 mCm.requestNetwork(cellRequest, noopCallback); 2216 mCm.unregisterNetworkCallback(noopCallback); 2217 callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent); 2218 2219 // Let linger run its course. 2220 callback.assertNoCallback(); 2221 final int lingerTimeoutMs = TEST_LINGER_DELAY_MS + TEST_LINGER_DELAY_MS / 4; 2222 callback.expectCapabilitiesWithout(NET_CAPABILITY_FOREGROUND, mCellNetworkAgent, 2223 lingerTimeoutMs); 2224 2225 // Clean up. 2226 mCm.unregisterNetworkCallback(defaultCallback); 2227 mCm.unregisterNetworkCallback(callback); 2228 } 2229 2230 @Test testExplicitlySelected()2231 public void testExplicitlySelected() throws Exception { 2232 NetworkRequest request = new NetworkRequest.Builder() 2233 .clearCapabilities().addCapability(NET_CAPABILITY_INTERNET) 2234 .build(); 2235 TestNetworkCallback callback = new TestNetworkCallback(); 2236 mCm.registerNetworkCallback(request, callback); 2237 2238 // Bring up validated cell. 2239 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 2240 mCellNetworkAgent.connect(true); 2241 callback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 2242 2243 // Bring up unvalidated wifi with explicitlySelected=true. 2244 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 2245 mWiFiNetworkAgent.explicitlySelected(true, false); 2246 mWiFiNetworkAgent.connect(false); 2247 callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 2248 2249 // Cell Remains the default. 2250 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 2251 2252 // Lower wifi's score to below than cell, and check that it doesn't disconnect because 2253 // it's explicitly selected. 2254 mWiFiNetworkAgent.adjustScore(-40); 2255 mWiFiNetworkAgent.adjustScore(40); 2256 callback.assertNoCallback(); 2257 2258 // If the user chooses yes on the "No Internet access, stay connected?" dialog, we switch to 2259 // wifi even though it's unvalidated. 2260 mCm.setAcceptUnvalidated(mWiFiNetworkAgent.getNetwork(), true, false); 2261 callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent); 2262 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 2263 2264 // Disconnect wifi, and then reconnect, again with explicitlySelected=true. 2265 mWiFiNetworkAgent.disconnect(); 2266 callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 2267 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 2268 mWiFiNetworkAgent.explicitlySelected(true, false); 2269 mWiFiNetworkAgent.connect(false); 2270 callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 2271 2272 // If the user chooses no on the "No Internet access, stay connected?" dialog, we ask the 2273 // network to disconnect. 2274 mCm.setAcceptUnvalidated(mWiFiNetworkAgent.getNetwork(), false, false); 2275 callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 2276 2277 // Reconnect, again with explicitlySelected=true, but this time validate. 2278 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 2279 mWiFiNetworkAgent.explicitlySelected(true, false); 2280 mWiFiNetworkAgent.connect(true); 2281 callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 2282 callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent); 2283 callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent); 2284 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 2285 2286 // BUG: the network will no longer linger, even though it's validated and outscored. 2287 // TODO: fix this. 2288 mEthernetNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_ETHERNET); 2289 mEthernetNetworkAgent.connect(true); 2290 callback.expectAvailableThenValidatedCallbacks(mEthernetNetworkAgent); 2291 assertEquals(mEthernetNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 2292 callback.assertNoCallback(); 2293 2294 // Disconnect wifi, and then reconnect as if the user had selected "yes, don't ask again" 2295 // (i.e., with explicitlySelected=true and acceptUnvalidated=true). Expect to switch to 2296 // wifi immediately. 2297 mWiFiNetworkAgent.disconnect(); 2298 callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 2299 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 2300 mWiFiNetworkAgent.explicitlySelected(true, true); 2301 mWiFiNetworkAgent.connect(false); 2302 callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 2303 callback.expectCallback(CallbackEntry.LOSING, mEthernetNetworkAgent); 2304 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 2305 mEthernetNetworkAgent.disconnect(); 2306 callback.expectCallback(CallbackEntry.LOST, mEthernetNetworkAgent); 2307 2308 // Disconnect and reconnect with explicitlySelected=false and acceptUnvalidated=true. 2309 // Check that the network is not scored specially and that the device prefers cell data. 2310 mWiFiNetworkAgent.disconnect(); 2311 callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 2312 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 2313 mWiFiNetworkAgent.explicitlySelected(false, true); 2314 mWiFiNetworkAgent.connect(false); 2315 callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 2316 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 2317 2318 // Clean up. 2319 mWiFiNetworkAgent.disconnect(); 2320 mCellNetworkAgent.disconnect(); 2321 2322 callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 2323 callback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 2324 } 2325 makeIntArray(final int size, final int value)2326 private int[] makeIntArray(final int size, final int value) { 2327 final int[] array = new int[size]; 2328 Arrays.fill(array, value); 2329 return array; 2330 } 2331 tryNetworkFactoryRequests(int capability)2332 private void tryNetworkFactoryRequests(int capability) throws Exception { 2333 // Verify NOT_RESTRICTED is set appropriately 2334 final NetworkCapabilities nc = new NetworkRequest.Builder().addCapability(capability) 2335 .build().networkCapabilities; 2336 if (capability == NET_CAPABILITY_CBS || capability == NET_CAPABILITY_DUN || 2337 capability == NET_CAPABILITY_EIMS || capability == NET_CAPABILITY_FOTA || 2338 capability == NET_CAPABILITY_IA || capability == NET_CAPABILITY_IMS || 2339 capability == NET_CAPABILITY_RCS || capability == NET_CAPABILITY_XCAP) { 2340 assertFalse(nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)); 2341 } else { 2342 assertTrue(nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)); 2343 } 2344 2345 NetworkCapabilities filter = new NetworkCapabilities(); 2346 filter.addCapability(capability); 2347 final HandlerThread handlerThread = new HandlerThread("testNetworkFactoryRequests"); 2348 handlerThread.start(); 2349 final MockNetworkFactory testFactory = new MockNetworkFactory(handlerThread.getLooper(), 2350 mServiceContext, "testFactory", filter); 2351 testFactory.setScoreFilter(40); 2352 ConditionVariable cv = testFactory.getNetworkStartedCV(); 2353 testFactory.expectAddRequestsWithScores(0); 2354 testFactory.register(); 2355 testFactory.waitForNetworkRequests(1); 2356 int expectedRequestCount = 1; 2357 NetworkCallback networkCallback = null; 2358 // For non-INTERNET capabilities we cannot rely on the default request being present, so 2359 // add one. 2360 if (capability != NET_CAPABILITY_INTERNET) { 2361 assertFalse(testFactory.getMyStartRequested()); 2362 NetworkRequest request = new NetworkRequest.Builder().addCapability(capability).build(); 2363 networkCallback = new NetworkCallback(); 2364 testFactory.expectAddRequestsWithScores(0); // New request 2365 mCm.requestNetwork(request, networkCallback); 2366 expectedRequestCount++; 2367 testFactory.waitForNetworkRequests(expectedRequestCount); 2368 } 2369 waitFor(cv); 2370 assertEquals(expectedRequestCount, testFactory.getMyRequestCount()); 2371 assertTrue(testFactory.getMyStartRequested()); 2372 2373 // Now bring in a higher scored network. 2374 TestNetworkAgentWrapper testAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 2375 // Rather than create a validated network which complicates things by registering it's 2376 // own NetworkRequest during startup, just bump up the score to cancel out the 2377 // unvalidated penalty. 2378 testAgent.adjustScore(40); 2379 cv = testFactory.getNetworkStoppedCV(); 2380 2381 // When testAgent connects, ConnectivityService will re-send us all current requests with 2382 // the new score. There are expectedRequestCount such requests, and we must wait for all of 2383 // them. 2384 testFactory.expectAddRequestsWithScores(makeIntArray(expectedRequestCount, 50)); 2385 testAgent.connect(false); 2386 testAgent.addCapability(capability); 2387 waitFor(cv); 2388 testFactory.waitForNetworkRequests(expectedRequestCount); 2389 assertFalse(testFactory.getMyStartRequested()); 2390 2391 // Bring in a bunch of requests. 2392 testFactory.expectAddRequestsWithScores(makeIntArray(10, 50)); 2393 assertEquals(expectedRequestCount, testFactory.getMyRequestCount()); 2394 ConnectivityManager.NetworkCallback[] networkCallbacks = 2395 new ConnectivityManager.NetworkCallback[10]; 2396 for (int i = 0; i< networkCallbacks.length; i++) { 2397 networkCallbacks[i] = new ConnectivityManager.NetworkCallback(); 2398 NetworkRequest.Builder builder = new NetworkRequest.Builder(); 2399 builder.addCapability(capability); 2400 mCm.requestNetwork(builder.build(), networkCallbacks[i]); 2401 } 2402 testFactory.waitForNetworkRequests(10 + expectedRequestCount); 2403 assertFalse(testFactory.getMyStartRequested()); 2404 2405 // Remove the requests. 2406 testFactory.expectRemoveRequests(10); 2407 for (int i = 0; i < networkCallbacks.length; i++) { 2408 mCm.unregisterNetworkCallback(networkCallbacks[i]); 2409 } 2410 testFactory.waitForNetworkRequests(expectedRequestCount); 2411 assertFalse(testFactory.getMyStartRequested()); 2412 2413 // Drop the higher scored network. 2414 cv = testFactory.getNetworkStartedCV(); 2415 // With the default network disconnecting, the requests are sent with score 0 to factories. 2416 testFactory.expectAddRequestsWithScores(makeIntArray(expectedRequestCount, 0)); 2417 testAgent.disconnect(); 2418 waitFor(cv); 2419 testFactory.waitForNetworkRequests(expectedRequestCount); 2420 assertEquals(expectedRequestCount, testFactory.getMyRequestCount()); 2421 assertTrue(testFactory.getMyStartRequested()); 2422 2423 testFactory.terminate(); 2424 if (networkCallback != null) mCm.unregisterNetworkCallback(networkCallback); 2425 handlerThread.quit(); 2426 } 2427 2428 @Test testNetworkFactoryRequests()2429 public void testNetworkFactoryRequests() throws Exception { 2430 tryNetworkFactoryRequests(NET_CAPABILITY_MMS); 2431 tryNetworkFactoryRequests(NET_CAPABILITY_SUPL); 2432 tryNetworkFactoryRequests(NET_CAPABILITY_DUN); 2433 tryNetworkFactoryRequests(NET_CAPABILITY_FOTA); 2434 tryNetworkFactoryRequests(NET_CAPABILITY_IMS); 2435 tryNetworkFactoryRequests(NET_CAPABILITY_CBS); 2436 tryNetworkFactoryRequests(NET_CAPABILITY_WIFI_P2P); 2437 tryNetworkFactoryRequests(NET_CAPABILITY_IA); 2438 tryNetworkFactoryRequests(NET_CAPABILITY_RCS); 2439 tryNetworkFactoryRequests(NET_CAPABILITY_XCAP); 2440 tryNetworkFactoryRequests(NET_CAPABILITY_EIMS); 2441 tryNetworkFactoryRequests(NET_CAPABILITY_NOT_METERED); 2442 tryNetworkFactoryRequests(NET_CAPABILITY_INTERNET); 2443 tryNetworkFactoryRequests(NET_CAPABILITY_TRUSTED); 2444 tryNetworkFactoryRequests(NET_CAPABILITY_NOT_VPN); 2445 // Skipping VALIDATED and CAPTIVE_PORTAL as they're disallowed. 2446 } 2447 2448 @Test testNetworkFactoryUnregister()2449 public void testNetworkFactoryUnregister() throws Exception { 2450 final NetworkCapabilities filter = new NetworkCapabilities(); 2451 filter.clearAll(); 2452 2453 final HandlerThread handlerThread = new HandlerThread("testNetworkFactoryRequests"); 2454 handlerThread.start(); 2455 2456 // Checks that calling setScoreFilter on a NetworkFactory immediately before closing it 2457 // does not crash. 2458 for (int i = 0; i < 100; i++) { 2459 final MockNetworkFactory testFactory = new MockNetworkFactory(handlerThread.getLooper(), 2460 mServiceContext, "testFactory", filter); 2461 // Register the factory and don't be surprised when the default request arrives. 2462 testFactory.expectAddRequestsWithScores(0); 2463 testFactory.register(); 2464 testFactory.waitForNetworkRequests(1); 2465 2466 testFactory.setScoreFilter(42); 2467 testFactory.terminate(); 2468 2469 if (i % 2 == 0) { 2470 try { 2471 testFactory.register(); 2472 fail("Re-registering terminated NetworkFactory should throw"); 2473 } catch (IllegalStateException expected) { 2474 } 2475 } 2476 } 2477 handlerThread.quit(); 2478 } 2479 2480 @Test testNoMutableNetworkRequests()2481 public void testNoMutableNetworkRequests() throws Exception { 2482 PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0, new Intent("a"), 0); 2483 NetworkRequest request1 = new NetworkRequest.Builder() 2484 .addCapability(NET_CAPABILITY_VALIDATED) 2485 .build(); 2486 NetworkRequest request2 = new NetworkRequest.Builder() 2487 .addCapability(NET_CAPABILITY_CAPTIVE_PORTAL) 2488 .build(); 2489 2490 Class<IllegalArgumentException> expected = IllegalArgumentException.class; 2491 assertThrows(expected, () -> mCm.requestNetwork(request1, new NetworkCallback())); 2492 assertThrows(expected, () -> mCm.requestNetwork(request1, pendingIntent)); 2493 assertThrows(expected, () -> mCm.requestNetwork(request2, new NetworkCallback())); 2494 assertThrows(expected, () -> mCm.requestNetwork(request2, pendingIntent)); 2495 } 2496 2497 @Test testMMSonWiFi()2498 public void testMMSonWiFi() throws Exception { 2499 // Test bringing up cellular without MMS NetworkRequest gets reaped 2500 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 2501 mCellNetworkAgent.addCapability(NET_CAPABILITY_MMS); 2502 mCellNetworkAgent.connectWithoutInternet(); 2503 mCellNetworkAgent.expectDisconnected(); 2504 waitForIdle(); 2505 assertEmpty(mCm.getAllNetworks()); 2506 verifyNoNetwork(); 2507 2508 // Test bringing up validated WiFi. 2509 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 2510 final ConditionVariable cv = registerConnectivityBroadcast(1); 2511 mWiFiNetworkAgent.connect(true); 2512 waitFor(cv); 2513 verifyActiveNetwork(TRANSPORT_WIFI); 2514 2515 // Register MMS NetworkRequest 2516 NetworkRequest.Builder builder = new NetworkRequest.Builder(); 2517 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_MMS); 2518 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 2519 mCm.requestNetwork(builder.build(), networkCallback); 2520 2521 // Test bringing up unvalidated cellular with MMS 2522 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 2523 mCellNetworkAgent.addCapability(NET_CAPABILITY_MMS); 2524 mCellNetworkAgent.connectWithoutInternet(); 2525 networkCallback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent); 2526 verifyActiveNetwork(TRANSPORT_WIFI); 2527 2528 // Test releasing NetworkRequest disconnects cellular with MMS 2529 mCm.unregisterNetworkCallback(networkCallback); 2530 mCellNetworkAgent.expectDisconnected(); 2531 verifyActiveNetwork(TRANSPORT_WIFI); 2532 } 2533 2534 @Test testMMSonCell()2535 public void testMMSonCell() throws Exception { 2536 // Test bringing up cellular without MMS 2537 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 2538 ConditionVariable cv = registerConnectivityBroadcast(1); 2539 mCellNetworkAgent.connect(false); 2540 waitFor(cv); 2541 verifyActiveNetwork(TRANSPORT_CELLULAR); 2542 2543 // Register MMS NetworkRequest 2544 NetworkRequest.Builder builder = new NetworkRequest.Builder(); 2545 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_MMS); 2546 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 2547 mCm.requestNetwork(builder.build(), networkCallback); 2548 2549 // Test bringing up MMS cellular network 2550 TestNetworkAgentWrapper 2551 mmsNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 2552 mmsNetworkAgent.addCapability(NET_CAPABILITY_MMS); 2553 mmsNetworkAgent.connectWithoutInternet(); 2554 networkCallback.expectAvailableCallbacksUnvalidated(mmsNetworkAgent); 2555 verifyActiveNetwork(TRANSPORT_CELLULAR); 2556 2557 // Test releasing MMS NetworkRequest does not disconnect main cellular NetworkAgent 2558 mCm.unregisterNetworkCallback(networkCallback); 2559 mmsNetworkAgent.expectDisconnected(); 2560 verifyActiveNetwork(TRANSPORT_CELLULAR); 2561 } 2562 2563 @Test testPartialConnectivity()2564 public void testPartialConnectivity() throws Exception { 2565 // Register network callback. 2566 NetworkRequest request = new NetworkRequest.Builder() 2567 .clearCapabilities().addCapability(NET_CAPABILITY_INTERNET) 2568 .build(); 2569 TestNetworkCallback callback = new TestNetworkCallback(); 2570 mCm.registerNetworkCallback(request, callback); 2571 2572 // Bring up validated mobile data. 2573 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 2574 mCellNetworkAgent.connect(true); 2575 callback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 2576 2577 // Bring up wifi with partial connectivity. 2578 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 2579 mWiFiNetworkAgent.connectWithPartialConnectivity(); 2580 callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 2581 callback.expectCapabilitiesWith(NET_CAPABILITY_PARTIAL_CONNECTIVITY, mWiFiNetworkAgent); 2582 2583 // Mobile data should be the default network. 2584 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 2585 callback.assertNoCallback(); 2586 2587 // With HTTPS probe disabled, NetworkMonitor should pass the network validation with http 2588 // probe. 2589 mWiFiNetworkAgent.setNetworkPartialValid(false /* isStrictMode */); 2590 // If the user chooses yes to use this partial connectivity wifi, switch the default 2591 // network to wifi and check if wifi becomes valid or not. 2592 mCm.setAcceptPartialConnectivity(mWiFiNetworkAgent.getNetwork(), true /* accept */, 2593 false /* always */); 2594 // If user accepts partial connectivity network, 2595 // NetworkMonitor#setAcceptPartialConnectivity() should be called too. 2596 waitForIdle(); 2597 verify(mWiFiNetworkAgent.mNetworkMonitor, times(1)).setAcceptPartialConnectivity(); 2598 2599 // Need a trigger point to let NetworkMonitor tell ConnectivityService that network is 2600 // validated. 2601 mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), true); 2602 callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent); 2603 NetworkCapabilities nc = callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, 2604 mWiFiNetworkAgent); 2605 assertTrue(nc.hasCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY)); 2606 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 2607 2608 // Disconnect and reconnect wifi with partial connectivity again. 2609 mWiFiNetworkAgent.disconnect(); 2610 callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 2611 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 2612 mWiFiNetworkAgent.connectWithPartialConnectivity(); 2613 callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 2614 callback.expectCapabilitiesWith(NET_CAPABILITY_PARTIAL_CONNECTIVITY, mWiFiNetworkAgent); 2615 2616 // Mobile data should be the default network. 2617 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 2618 2619 // If the user chooses no, disconnect wifi immediately. 2620 mCm.setAcceptPartialConnectivity(mWiFiNetworkAgent.getNetwork(), false/* accept */, 2621 false /* always */); 2622 callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 2623 2624 // If user accepted partial connectivity before, and device reconnects to that network 2625 // again, but now the network has full connectivity. The network shouldn't contain 2626 // NET_CAPABILITY_PARTIAL_CONNECTIVITY. 2627 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 2628 // acceptUnvalidated is also used as setting for accepting partial networks. 2629 mWiFiNetworkAgent.explicitlySelected(true /* explicitlySelected */, 2630 true /* acceptUnvalidated */); 2631 mWiFiNetworkAgent.connect(true); 2632 2633 // If user accepted partial connectivity network before, 2634 // NetworkMonitor#setAcceptPartialConnectivity() will be called in 2635 // ConnectivityService#updateNetworkInfo(). 2636 callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 2637 verify(mWiFiNetworkAgent.mNetworkMonitor, times(1)).setAcceptPartialConnectivity(); 2638 callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent); 2639 nc = callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent); 2640 assertFalse(nc.hasCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY)); 2641 2642 // Wifi should be the default network. 2643 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 2644 mWiFiNetworkAgent.disconnect(); 2645 callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 2646 2647 // The user accepted partial connectivity and selected "don't ask again". Now the user 2648 // reconnects to the partial connectivity network. Switch to wifi as soon as partial 2649 // connectivity is detected. 2650 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 2651 mWiFiNetworkAgent.explicitlySelected(true /* explicitlySelected */, 2652 true /* acceptUnvalidated */); 2653 mWiFiNetworkAgent.connectWithPartialConnectivity(); 2654 // If user accepted partial connectivity network before, 2655 // NetworkMonitor#setAcceptPartialConnectivity() will be called in 2656 // ConnectivityService#updateNetworkInfo(). 2657 callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 2658 verify(mWiFiNetworkAgent.mNetworkMonitor, times(1)).setAcceptPartialConnectivity(); 2659 callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent); 2660 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 2661 callback.expectCapabilitiesWith(NET_CAPABILITY_PARTIAL_CONNECTIVITY, mWiFiNetworkAgent); 2662 mWiFiNetworkAgent.setNetworkValid(false /* isStrictMode */); 2663 2664 // Need a trigger point to let NetworkMonitor tell ConnectivityService that network is 2665 // validated. 2666 mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), true); 2667 callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent); 2668 mWiFiNetworkAgent.disconnect(); 2669 callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 2670 2671 // If the user accepted partial connectivity, and the device auto-reconnects to the partial 2672 // connectivity network, it should contain both PARTIAL_CONNECTIVITY and VALIDATED. 2673 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 2674 mWiFiNetworkAgent.explicitlySelected(false /* explicitlySelected */, 2675 true /* acceptUnvalidated */); 2676 2677 // NetworkMonitor will immediately (once the HTTPS probe fails...) report the network as 2678 // valid, because ConnectivityService calls setAcceptPartialConnectivity before it calls 2679 // notifyNetworkConnected. 2680 mWiFiNetworkAgent.connectWithPartialValidConnectivity(false /* isStrictMode */); 2681 callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 2682 verify(mWiFiNetworkAgent.mNetworkMonitor, times(1)).setAcceptPartialConnectivity(); 2683 callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent); 2684 callback.expectCapabilitiesWith( 2685 NET_CAPABILITY_PARTIAL_CONNECTIVITY | NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent); 2686 mWiFiNetworkAgent.disconnect(); 2687 callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 2688 } 2689 2690 @Test testCaptivePortalOnPartialConnectivity()2691 public void testCaptivePortalOnPartialConnectivity() throws Exception { 2692 final TestNetworkCallback captivePortalCallback = new TestNetworkCallback(); 2693 final NetworkRequest captivePortalRequest = new NetworkRequest.Builder() 2694 .addCapability(NET_CAPABILITY_CAPTIVE_PORTAL).build(); 2695 mCm.registerNetworkCallback(captivePortalRequest, captivePortalCallback); 2696 2697 final TestNetworkCallback validatedCallback = new TestNetworkCallback(); 2698 final NetworkRequest validatedRequest = new NetworkRequest.Builder() 2699 .addCapability(NET_CAPABILITY_VALIDATED).build(); 2700 mCm.registerNetworkCallback(validatedRequest, validatedCallback); 2701 2702 // Bring up a network with a captive portal. 2703 // Expect onAvailable callback of listen for NET_CAPABILITY_CAPTIVE_PORTAL. 2704 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 2705 String redirectUrl = "http://android.com/path"; 2706 mWiFiNetworkAgent.connectWithCaptivePortal(redirectUrl, false /* isStrictMode */); 2707 captivePortalCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 2708 assertEquals(mWiFiNetworkAgent.waitForRedirectUrl(), redirectUrl); 2709 2710 // Check that startCaptivePortalApp sends the expected command to NetworkMonitor. 2711 mCm.startCaptivePortalApp(mWiFiNetworkAgent.getNetwork()); 2712 verify(mWiFiNetworkAgent.mNetworkMonitor, timeout(TIMEOUT_MS).times(1)) 2713 .launchCaptivePortalApp(); 2714 2715 // Report that the captive portal is dismissed with partial connectivity, and check that 2716 // callbacks are fired. 2717 mWiFiNetworkAgent.setNetworkPartial(); 2718 mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), true); 2719 waitForIdle(); 2720 captivePortalCallback.expectCapabilitiesWith(NET_CAPABILITY_PARTIAL_CONNECTIVITY, 2721 mWiFiNetworkAgent); 2722 2723 // Report partial connectivity is accepted. 2724 mWiFiNetworkAgent.setNetworkPartialValid(false /* isStrictMode */); 2725 mCm.setAcceptPartialConnectivity(mWiFiNetworkAgent.getNetwork(), true /* accept */, 2726 false /* always */); 2727 waitForIdle(); 2728 mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), true); 2729 captivePortalCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 2730 validatedCallback.expectAvailableCallbacksValidated(mWiFiNetworkAgent); 2731 NetworkCapabilities nc = 2732 validatedCallback.expectCapabilitiesWith(NET_CAPABILITY_PARTIAL_CONNECTIVITY, 2733 mWiFiNetworkAgent); 2734 2735 mCm.unregisterNetworkCallback(captivePortalCallback); 2736 mCm.unregisterNetworkCallback(validatedCallback); 2737 } 2738 2739 @Test testCaptivePortal()2740 public void testCaptivePortal() throws Exception { 2741 final TestNetworkCallback captivePortalCallback = new TestNetworkCallback(); 2742 final NetworkRequest captivePortalRequest = new NetworkRequest.Builder() 2743 .addCapability(NET_CAPABILITY_CAPTIVE_PORTAL).build(); 2744 mCm.registerNetworkCallback(captivePortalRequest, captivePortalCallback); 2745 2746 final TestNetworkCallback validatedCallback = new TestNetworkCallback(); 2747 final NetworkRequest validatedRequest = new NetworkRequest.Builder() 2748 .addCapability(NET_CAPABILITY_VALIDATED).build(); 2749 mCm.registerNetworkCallback(validatedRequest, validatedCallback); 2750 2751 // Bring up a network with a captive portal. 2752 // Expect onAvailable callback of listen for NET_CAPABILITY_CAPTIVE_PORTAL. 2753 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 2754 String firstRedirectUrl = "http://example.com/firstPath"; 2755 mWiFiNetworkAgent.connectWithCaptivePortal(firstRedirectUrl, false /* isStrictMode */); 2756 captivePortalCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 2757 assertEquals(mWiFiNetworkAgent.waitForRedirectUrl(), firstRedirectUrl); 2758 2759 // Take down network. 2760 // Expect onLost callback. 2761 mWiFiNetworkAgent.disconnect(); 2762 captivePortalCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 2763 2764 // Bring up a network with a captive portal. 2765 // Expect onAvailable callback of listen for NET_CAPABILITY_CAPTIVE_PORTAL. 2766 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 2767 String secondRedirectUrl = "http://example.com/secondPath"; 2768 mWiFiNetworkAgent.connectWithCaptivePortal(secondRedirectUrl, false /* isStrictMode */); 2769 captivePortalCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 2770 assertEquals(mWiFiNetworkAgent.waitForRedirectUrl(), secondRedirectUrl); 2771 2772 // Make captive portal disappear then revalidate. 2773 // Expect onLost callback because network no longer provides NET_CAPABILITY_CAPTIVE_PORTAL. 2774 mWiFiNetworkAgent.setNetworkValid(false /* isStrictMode */); 2775 mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), true); 2776 captivePortalCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 2777 2778 // Expect NET_CAPABILITY_VALIDATED onAvailable callback. 2779 validatedCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent); 2780 2781 // Break network connectivity. 2782 // Expect NET_CAPABILITY_VALIDATED onLost callback. 2783 mWiFiNetworkAgent.setNetworkInvalid(false /* isStrictMode */); 2784 mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), false); 2785 validatedCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 2786 } 2787 2788 @Test testCaptivePortalApp()2789 public void testCaptivePortalApp() throws Exception { 2790 final TestNetworkCallback captivePortalCallback = new TestNetworkCallback(); 2791 final NetworkRequest captivePortalRequest = new NetworkRequest.Builder() 2792 .addCapability(NET_CAPABILITY_CAPTIVE_PORTAL).build(); 2793 mCm.registerNetworkCallback(captivePortalRequest, captivePortalCallback); 2794 2795 final TestNetworkCallback validatedCallback = new TestNetworkCallback(); 2796 final NetworkRequest validatedRequest = new NetworkRequest.Builder() 2797 .addCapability(NET_CAPABILITY_VALIDATED).build(); 2798 mCm.registerNetworkCallback(validatedRequest, validatedCallback); 2799 2800 // Bring up wifi. 2801 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 2802 mWiFiNetworkAgent.connect(true); 2803 validatedCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent); 2804 Network wifiNetwork = mWiFiNetworkAgent.getNetwork(); 2805 2806 // Check that calling startCaptivePortalApp does nothing. 2807 final int fastTimeoutMs = 100; 2808 mCm.startCaptivePortalApp(wifiNetwork); 2809 waitForIdle(); 2810 verify(mWiFiNetworkAgent.mNetworkMonitor, never()).launchCaptivePortalApp(); 2811 mServiceContext.expectNoStartActivityIntent(fastTimeoutMs); 2812 2813 // Turn into a captive portal. 2814 mWiFiNetworkAgent.setNetworkPortal("http://example.com", false /* isStrictMode */); 2815 mCm.reportNetworkConnectivity(wifiNetwork, false); 2816 captivePortalCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 2817 validatedCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 2818 2819 // Check that startCaptivePortalApp sends the expected command to NetworkMonitor. 2820 mCm.startCaptivePortalApp(wifiNetwork); 2821 waitForIdle(); 2822 verify(mWiFiNetworkAgent.mNetworkMonitor).launchCaptivePortalApp(); 2823 2824 // NetworkMonitor uses startCaptivePortal(Network, Bundle) (startCaptivePortalAppInternal) 2825 final Bundle testBundle = new Bundle(); 2826 final String testKey = "testkey"; 2827 final String testValue = "testvalue"; 2828 testBundle.putString(testKey, testValue); 2829 mServiceContext.setPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, 2830 PERMISSION_GRANTED); 2831 mCm.startCaptivePortalApp(wifiNetwork, testBundle); 2832 final Intent signInIntent = mServiceContext.expectStartActivityIntent(TIMEOUT_MS); 2833 assertEquals(ACTION_CAPTIVE_PORTAL_SIGN_IN, signInIntent.getAction()); 2834 assertEquals(testValue, signInIntent.getStringExtra(testKey)); 2835 2836 // Report that the captive portal is dismissed, and check that callbacks are fired 2837 mWiFiNetworkAgent.setNetworkValid(false /* isStrictMode */); 2838 mWiFiNetworkAgent.mNetworkMonitor.forceReevaluation(Process.myUid()); 2839 validatedCallback.expectAvailableCallbacksValidated(mWiFiNetworkAgent); 2840 captivePortalCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 2841 2842 mCm.unregisterNetworkCallback(validatedCallback); 2843 mCm.unregisterNetworkCallback(captivePortalCallback); 2844 } 2845 2846 @Test testAvoidOrIgnoreCaptivePortals()2847 public void testAvoidOrIgnoreCaptivePortals() throws Exception { 2848 final TestNetworkCallback captivePortalCallback = new TestNetworkCallback(); 2849 final NetworkRequest captivePortalRequest = new NetworkRequest.Builder() 2850 .addCapability(NET_CAPABILITY_CAPTIVE_PORTAL).build(); 2851 mCm.registerNetworkCallback(captivePortalRequest, captivePortalCallback); 2852 2853 final TestNetworkCallback validatedCallback = new TestNetworkCallback(); 2854 final NetworkRequest validatedRequest = new NetworkRequest.Builder() 2855 .addCapability(NET_CAPABILITY_VALIDATED).build(); 2856 mCm.registerNetworkCallback(validatedRequest, validatedCallback); 2857 2858 setCaptivePortalMode(Settings.Global.CAPTIVE_PORTAL_MODE_AVOID); 2859 // Bring up a network with a captive portal. 2860 // Expect it to fail to connect and not result in any callbacks. 2861 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 2862 String firstRedirectUrl = "http://example.com/firstPath"; 2863 2864 mWiFiNetworkAgent.connectWithCaptivePortal(firstRedirectUrl, false /* isStrictMode */); 2865 mWiFiNetworkAgent.expectDisconnected(); 2866 mWiFiNetworkAgent.expectPreventReconnectReceived(); 2867 2868 assertNoCallbacks(captivePortalCallback, validatedCallback); 2869 } 2870 2871 @Test testCaptivePortalApi()2872 public void testCaptivePortalApi() throws Exception { 2873 mServiceContext.setPermission( 2874 android.Manifest.permission.NETWORK_SETTINGS, PERMISSION_GRANTED); 2875 2876 final TestNetworkCallback captivePortalCallback = new TestNetworkCallback(); 2877 final NetworkRequest captivePortalRequest = new NetworkRequest.Builder() 2878 .addCapability(NET_CAPABILITY_CAPTIVE_PORTAL).build(); 2879 mCm.registerNetworkCallback(captivePortalRequest, captivePortalCallback); 2880 2881 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 2882 final String redirectUrl = "http://example.com/firstPath"; 2883 2884 mWiFiNetworkAgent.connectWithCaptivePortal(redirectUrl, false /* isStrictMode */); 2885 captivePortalCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 2886 2887 final CaptivePortalData testData = new CaptivePortalData.Builder() 2888 .setUserPortalUrl(Uri.parse(redirectUrl)) 2889 .setBytesRemaining(12345L) 2890 .build(); 2891 2892 mWiFiNetworkAgent.notifyCaptivePortalDataChanged(testData); 2893 2894 captivePortalCallback.expectLinkPropertiesThat(mWiFiNetworkAgent, 2895 lp -> testData.equals(lp.getCaptivePortalData())); 2896 2897 final LinkProperties newLps = new LinkProperties(); 2898 newLps.setMtu(1234); 2899 mWiFiNetworkAgent.sendLinkProperties(newLps); 2900 // CaptivePortalData is not lost and unchanged when LPs are received from the NetworkAgent 2901 captivePortalCallback.expectLinkPropertiesThat(mWiFiNetworkAgent, 2902 lp -> testData.equals(lp.getCaptivePortalData()) && lp.getMtu() == 1234); 2903 } 2904 newWifiRequestBuilder()2905 private NetworkRequest.Builder newWifiRequestBuilder() { 2906 return new NetworkRequest.Builder().addTransportType(TRANSPORT_WIFI); 2907 } 2908 2909 /** 2910 * Verify request matching behavior with network specifiers. 2911 * 2912 * Note: this test is somewhat problematic since it involves removing capabilities from 2913 * agents - i.e. agents rejecting requests which they previously accepted. This is flagged 2914 * as a WTF bug in 2915 * {@link ConnectivityService#mixInCapabilities(NetworkAgentInfo, NetworkCapabilities)} but 2916 * does work. 2917 */ 2918 @Test testNetworkSpecifier()2919 public void testNetworkSpecifier() throws Exception { 2920 // A NetworkSpecifier subclass that matches all networks but must not be visible to apps. 2921 class ConfidentialMatchAllNetworkSpecifier extends NetworkSpecifier implements 2922 Parcelable { 2923 @Override 2924 public boolean canBeSatisfiedBy(NetworkSpecifier other) { 2925 return true; 2926 } 2927 2928 @Override 2929 public int describeContents() { 2930 return 0; 2931 } 2932 2933 @Override 2934 public void writeToParcel(Parcel dest, int flags) {} 2935 2936 @Override 2937 public NetworkSpecifier redact() { 2938 return null; 2939 } 2940 } 2941 2942 // A network specifier that matches either another LocalNetworkSpecifier with the same 2943 // string or a ConfidentialMatchAllNetworkSpecifier, and can be passed to apps as is. 2944 class LocalStringNetworkSpecifier extends NetworkSpecifier implements Parcelable { 2945 private String mString; 2946 2947 LocalStringNetworkSpecifier(String string) { 2948 mString = string; 2949 } 2950 2951 @Override 2952 public boolean canBeSatisfiedBy(NetworkSpecifier other) { 2953 if (other instanceof LocalStringNetworkSpecifier) { 2954 return TextUtils.equals(mString, 2955 ((LocalStringNetworkSpecifier) other).mString); 2956 } 2957 if (other instanceof ConfidentialMatchAllNetworkSpecifier) return true; 2958 return false; 2959 } 2960 2961 @Override 2962 public int describeContents() { 2963 return 0; 2964 } 2965 @Override 2966 public void writeToParcel(Parcel dest, int flags) {} 2967 } 2968 2969 2970 NetworkRequest rEmpty1 = newWifiRequestBuilder().build(); 2971 NetworkRequest rEmpty2 = newWifiRequestBuilder().setNetworkSpecifier((String) null).build(); 2972 NetworkRequest rEmpty3 = newWifiRequestBuilder().setNetworkSpecifier("").build(); 2973 NetworkRequest rEmpty4 = newWifiRequestBuilder().setNetworkSpecifier( 2974 (NetworkSpecifier) null).build(); 2975 NetworkRequest rFoo = newWifiRequestBuilder().setNetworkSpecifier( 2976 new LocalStringNetworkSpecifier("foo")).build(); 2977 NetworkRequest rBar = newWifiRequestBuilder().setNetworkSpecifier( 2978 new LocalStringNetworkSpecifier("bar")).build(); 2979 2980 TestNetworkCallback cEmpty1 = new TestNetworkCallback(); 2981 TestNetworkCallback cEmpty2 = new TestNetworkCallback(); 2982 TestNetworkCallback cEmpty3 = new TestNetworkCallback(); 2983 TestNetworkCallback cEmpty4 = new TestNetworkCallback(); 2984 TestNetworkCallback cFoo = new TestNetworkCallback(); 2985 TestNetworkCallback cBar = new TestNetworkCallback(); 2986 TestNetworkCallback[] emptyCallbacks = new TestNetworkCallback[] { 2987 cEmpty1, cEmpty2, cEmpty3, cEmpty4 }; 2988 2989 mCm.registerNetworkCallback(rEmpty1, cEmpty1); 2990 mCm.registerNetworkCallback(rEmpty2, cEmpty2); 2991 mCm.registerNetworkCallback(rEmpty3, cEmpty3); 2992 mCm.registerNetworkCallback(rEmpty4, cEmpty4); 2993 mCm.registerNetworkCallback(rFoo, cFoo); 2994 mCm.registerNetworkCallback(rBar, cBar); 2995 2996 LocalStringNetworkSpecifier nsFoo = new LocalStringNetworkSpecifier("foo"); 2997 LocalStringNetworkSpecifier nsBar = new LocalStringNetworkSpecifier("bar"); 2998 2999 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3000 mWiFiNetworkAgent.connect(false); 3001 cEmpty1.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 3002 cEmpty2.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 3003 cEmpty3.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 3004 cEmpty4.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 3005 assertNoCallbacks(cFoo, cBar); 3006 3007 mWiFiNetworkAgent.setNetworkSpecifier(nsFoo); 3008 cFoo.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 3009 for (TestNetworkCallback c: emptyCallbacks) { 3010 c.expectCapabilitiesThat(mWiFiNetworkAgent, 3011 (caps) -> caps.getNetworkSpecifier().equals(nsFoo)); 3012 } 3013 cFoo.expectCapabilitiesThat(mWiFiNetworkAgent, 3014 (caps) -> caps.getNetworkSpecifier().equals(nsFoo)); 3015 assertEquals(nsFoo, 3016 mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).getNetworkSpecifier()); 3017 cFoo.assertNoCallback(); 3018 3019 mWiFiNetworkAgent.setNetworkSpecifier(nsBar); 3020 cFoo.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 3021 cBar.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 3022 for (TestNetworkCallback c: emptyCallbacks) { 3023 c.expectCapabilitiesThat(mWiFiNetworkAgent, 3024 (caps) -> caps.getNetworkSpecifier().equals(nsBar)); 3025 } 3026 cBar.expectCapabilitiesThat(mWiFiNetworkAgent, 3027 (caps) -> caps.getNetworkSpecifier().equals(nsBar)); 3028 assertEquals(nsBar, 3029 mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).getNetworkSpecifier()); 3030 cBar.assertNoCallback(); 3031 3032 mWiFiNetworkAgent.setNetworkSpecifier(new ConfidentialMatchAllNetworkSpecifier()); 3033 cFoo.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 3034 for (TestNetworkCallback c : emptyCallbacks) { 3035 c.expectCapabilitiesThat(mWiFiNetworkAgent, 3036 (caps) -> caps.getNetworkSpecifier() == null); 3037 } 3038 cFoo.expectCapabilitiesThat(mWiFiNetworkAgent, 3039 (caps) -> caps.getNetworkSpecifier() == null); 3040 cBar.expectCapabilitiesThat(mWiFiNetworkAgent, 3041 (caps) -> caps.getNetworkSpecifier() == null); 3042 assertNull( 3043 mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).getNetworkSpecifier()); 3044 cFoo.assertNoCallback(); 3045 cBar.assertNoCallback(); 3046 3047 mWiFiNetworkAgent.setNetworkSpecifier(null); 3048 cFoo.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 3049 cBar.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 3050 for (TestNetworkCallback c: emptyCallbacks) { 3051 c.expectCallback(CallbackEntry.NETWORK_CAPS_UPDATED, mWiFiNetworkAgent); 3052 } 3053 3054 assertNoCallbacks(cEmpty1, cEmpty2, cEmpty3, cEmpty4, cFoo, cBar); 3055 } 3056 3057 @Test testInvalidNetworkSpecifier()3058 public void testInvalidNetworkSpecifier() { 3059 assertThrows(IllegalArgumentException.class, () -> { 3060 NetworkRequest.Builder builder = new NetworkRequest.Builder(); 3061 builder.setNetworkSpecifier(new MatchAllNetworkSpecifier()); 3062 }); 3063 3064 assertThrows(IllegalArgumentException.class, () -> { 3065 NetworkCapabilities networkCapabilities = new NetworkCapabilities(); 3066 networkCapabilities.addTransportType(TRANSPORT_WIFI) 3067 .setNetworkSpecifier(new MatchAllNetworkSpecifier()); 3068 mService.requestNetwork(networkCapabilities, null, 0, null, 3069 ConnectivityManager.TYPE_WIFI, mContext.getPackageName()); 3070 }); 3071 3072 class NonParcelableSpecifier extends NetworkSpecifier { 3073 @Override 3074 public boolean canBeSatisfiedBy(NetworkSpecifier other) { 3075 return false; 3076 } 3077 }; 3078 class ParcelableSpecifier extends NonParcelableSpecifier implements Parcelable { 3079 @Override public int describeContents() { return 0; } 3080 @Override public void writeToParcel(Parcel p, int flags) {} 3081 } 3082 3083 final NetworkRequest.Builder builder = 3084 new NetworkRequest.Builder().addTransportType(TRANSPORT_ETHERNET); 3085 assertThrows(ClassCastException.class, () -> { 3086 builder.setNetworkSpecifier(new NonParcelableSpecifier()); 3087 Parcel parcelW = Parcel.obtain(); 3088 builder.build().writeToParcel(parcelW, 0); 3089 }); 3090 3091 final NetworkRequest nr = 3092 new NetworkRequest.Builder().addTransportType(TRANSPORT_ETHERNET) 3093 .setNetworkSpecifier(new ParcelableSpecifier()) 3094 .build(); 3095 assertNotNull(nr); 3096 3097 assertThrows(BadParcelableException.class, () -> { 3098 Parcel parcelW = Parcel.obtain(); 3099 nr.writeToParcel(parcelW, 0); 3100 byte[] bytes = parcelW.marshall(); 3101 parcelW.recycle(); 3102 3103 Parcel parcelR = Parcel.obtain(); 3104 parcelR.unmarshall(bytes, 0, bytes.length); 3105 parcelR.setDataPosition(0); 3106 NetworkRequest rereadNr = NetworkRequest.CREATOR.createFromParcel(parcelR); 3107 }); 3108 } 3109 3110 @Test testNetworkRequestUidSpoofSecurityException()3111 public void testNetworkRequestUidSpoofSecurityException() throws Exception { 3112 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3113 mWiFiNetworkAgent.connect(false); 3114 NetworkRequest networkRequest = newWifiRequestBuilder().build(); 3115 TestNetworkCallback networkCallback = new TestNetworkCallback(); 3116 doThrow(new SecurityException()).when(mAppOpsManager).checkPackage(anyInt(), anyString()); 3117 assertThrows(SecurityException.class, () -> { 3118 mCm.requestNetwork(networkRequest, networkCallback); 3119 }); 3120 } 3121 3122 @Test testInvalidSignalStrength()3123 public void testInvalidSignalStrength() { 3124 NetworkRequest r = new NetworkRequest.Builder() 3125 .addCapability(NET_CAPABILITY_INTERNET) 3126 .addTransportType(TRANSPORT_WIFI) 3127 .setSignalStrength(-75) 3128 .build(); 3129 // Registering a NetworkCallback with signal strength but w/o NETWORK_SIGNAL_STRENGTH_WAKEUP 3130 // permission should get SecurityException. 3131 assertThrows(SecurityException.class, () -> 3132 mCm.registerNetworkCallback(r, new NetworkCallback())); 3133 3134 assertThrows(SecurityException.class, () -> 3135 mCm.registerNetworkCallback(r, PendingIntent.getService( 3136 mServiceContext, 0, new Intent(), 0))); 3137 3138 // Requesting a Network with signal strength should get IllegalArgumentException. 3139 assertThrows(IllegalArgumentException.class, () -> 3140 mCm.requestNetwork(r, new NetworkCallback())); 3141 3142 assertThrows(IllegalArgumentException.class, () -> 3143 mCm.requestNetwork(r, PendingIntent.getService( 3144 mServiceContext, 0, new Intent(), 0))); 3145 } 3146 3147 @Test testRegisterDefaultNetworkCallback()3148 public void testRegisterDefaultNetworkCallback() throws Exception { 3149 final TestNetworkCallback defaultNetworkCallback = new TestNetworkCallback(); 3150 mCm.registerDefaultNetworkCallback(defaultNetworkCallback); 3151 defaultNetworkCallback.assertNoCallback(); 3152 3153 // Create a TRANSPORT_CELLULAR request to keep the mobile interface up 3154 // whenever Wi-Fi is up. Without this, the mobile network agent is 3155 // reaped before any other activity can take place. 3156 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback(); 3157 final NetworkRequest cellRequest = new NetworkRequest.Builder() 3158 .addTransportType(TRANSPORT_CELLULAR).build(); 3159 mCm.requestNetwork(cellRequest, cellNetworkCallback); 3160 cellNetworkCallback.assertNoCallback(); 3161 3162 // Bring up cell and expect CALLBACK_AVAILABLE. 3163 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 3164 mCellNetworkAgent.connect(true); 3165 cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 3166 defaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 3167 assertEquals(defaultNetworkCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 3168 3169 // Bring up wifi and expect CALLBACK_AVAILABLE. 3170 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3171 mWiFiNetworkAgent.connect(true); 3172 cellNetworkCallback.assertNoCallback(); 3173 defaultNetworkCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent); 3174 assertEquals(defaultNetworkCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 3175 3176 // Bring down cell. Expect no default network callback, since it wasn't the default. 3177 mCellNetworkAgent.disconnect(); 3178 cellNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 3179 defaultNetworkCallback.assertNoCallback(); 3180 assertEquals(defaultNetworkCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 3181 3182 // Bring up cell. Expect no default network callback, since it won't be the default. 3183 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 3184 mCellNetworkAgent.connect(true); 3185 cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 3186 defaultNetworkCallback.assertNoCallback(); 3187 assertEquals(defaultNetworkCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 3188 3189 // Bring down wifi. Expect the default network callback to notified of LOST wifi 3190 // followed by AVAILABLE cell. 3191 mWiFiNetworkAgent.disconnect(); 3192 cellNetworkCallback.assertNoCallback(); 3193 defaultNetworkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 3194 defaultNetworkCallback.expectAvailableCallbacksValidated(mCellNetworkAgent); 3195 mCellNetworkAgent.disconnect(); 3196 cellNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 3197 defaultNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 3198 waitForIdle(); 3199 assertEquals(null, mCm.getActiveNetwork()); 3200 3201 final int uid = Process.myUid(); 3202 final TestNetworkAgentWrapper 3203 vpnNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_VPN); 3204 final ArraySet<UidRange> ranges = new ArraySet<>(); 3205 ranges.add(new UidRange(uid, uid)); 3206 mMockVpn.setNetworkAgent(vpnNetworkAgent); 3207 mMockVpn.setUids(ranges); 3208 vpnNetworkAgent.connect(true); 3209 mMockVpn.connect(); 3210 defaultNetworkCallback.expectAvailableThenValidatedCallbacks(vpnNetworkAgent); 3211 assertEquals(defaultNetworkCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 3212 3213 vpnNetworkAgent.disconnect(); 3214 defaultNetworkCallback.expectCallback(CallbackEntry.LOST, vpnNetworkAgent); 3215 waitForIdle(); 3216 assertEquals(null, mCm.getActiveNetwork()); 3217 } 3218 3219 @Test testAdditionalStateCallbacks()3220 public void testAdditionalStateCallbacks() throws Exception { 3221 // File a network request for mobile. 3222 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback(); 3223 final NetworkRequest cellRequest = new NetworkRequest.Builder() 3224 .addTransportType(TRANSPORT_CELLULAR).build(); 3225 mCm.requestNetwork(cellRequest, cellNetworkCallback); 3226 3227 // Bring up the mobile network. 3228 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 3229 mCellNetworkAgent.connect(true); 3230 3231 // We should get onAvailable(), onCapabilitiesChanged(), and 3232 // onLinkPropertiesChanged() in rapid succession. Additionally, we 3233 // should get onCapabilitiesChanged() when the mobile network validates. 3234 cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 3235 cellNetworkCallback.assertNoCallback(); 3236 3237 // Update LinkProperties. 3238 final LinkProperties lp = new LinkProperties(); 3239 lp.setInterfaceName("foonet_data0"); 3240 mCellNetworkAgent.sendLinkProperties(lp); 3241 // We should get onLinkPropertiesChanged(). 3242 cellNetworkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, 3243 mCellNetworkAgent); 3244 cellNetworkCallback.assertNoCallback(); 3245 3246 // Suspend the network. 3247 mCellNetworkAgent.suspend(); 3248 cellNetworkCallback.expectCapabilitiesWithout(NET_CAPABILITY_NOT_SUSPENDED, 3249 mCellNetworkAgent); 3250 cellNetworkCallback.expectCallback(CallbackEntry.SUSPENDED, mCellNetworkAgent); 3251 cellNetworkCallback.assertNoCallback(); 3252 assertEquals(NetworkInfo.State.SUSPENDED, mCm.getActiveNetworkInfo().getState()); 3253 3254 // Register a garden variety default network request. 3255 TestNetworkCallback dfltNetworkCallback = new TestNetworkCallback(); 3256 mCm.registerDefaultNetworkCallback(dfltNetworkCallback); 3257 // We should get onAvailable(), onCapabilitiesChanged(), onLinkPropertiesChanged(), 3258 // as well as onNetworkSuspended() in rapid succession. 3259 dfltNetworkCallback.expectAvailableAndSuspendedCallbacks(mCellNetworkAgent, true); 3260 dfltNetworkCallback.assertNoCallback(); 3261 mCm.unregisterNetworkCallback(dfltNetworkCallback); 3262 3263 mCellNetworkAgent.resume(); 3264 cellNetworkCallback.expectCapabilitiesWith(NET_CAPABILITY_NOT_SUSPENDED, 3265 mCellNetworkAgent); 3266 cellNetworkCallback.expectCallback(CallbackEntry.RESUMED, mCellNetworkAgent); 3267 cellNetworkCallback.assertNoCallback(); 3268 assertEquals(NetworkInfo.State.CONNECTED, mCm.getActiveNetworkInfo().getState()); 3269 3270 dfltNetworkCallback = new TestNetworkCallback(); 3271 mCm.registerDefaultNetworkCallback(dfltNetworkCallback); 3272 // This time onNetworkSuspended should not be called. 3273 dfltNetworkCallback.expectAvailableCallbacksValidated(mCellNetworkAgent); 3274 dfltNetworkCallback.assertNoCallback(); 3275 3276 mCm.unregisterNetworkCallback(dfltNetworkCallback); 3277 mCm.unregisterNetworkCallback(cellNetworkCallback); 3278 } 3279 setCaptivePortalMode(int mode)3280 private void setCaptivePortalMode(int mode) { 3281 ContentResolver cr = mServiceContext.getContentResolver(); 3282 Settings.Global.putInt(cr, Settings.Global.CAPTIVE_PORTAL_MODE, mode); 3283 } 3284 setAlwaysOnNetworks(boolean enable)3285 private void setAlwaysOnNetworks(boolean enable) { 3286 ContentResolver cr = mServiceContext.getContentResolver(); 3287 Settings.Global.putInt(cr, Settings.Global.MOBILE_DATA_ALWAYS_ON, enable ? 1 : 0); 3288 mService.updateAlwaysOnNetworks(); 3289 waitForIdle(); 3290 } 3291 setPrivateDnsSettings(String mode, String specifier)3292 private void setPrivateDnsSettings(String mode, String specifier) { 3293 final ContentResolver cr = mServiceContext.getContentResolver(); 3294 Settings.Global.putString(cr, Settings.Global.PRIVATE_DNS_MODE, mode); 3295 Settings.Global.putString(cr, Settings.Global.PRIVATE_DNS_SPECIFIER, specifier); 3296 mService.updatePrivateDnsSettings(); 3297 waitForIdle(); 3298 } 3299 isForegroundNetwork(TestNetworkAgentWrapper network)3300 private boolean isForegroundNetwork(TestNetworkAgentWrapper network) { 3301 NetworkCapabilities nc = mCm.getNetworkCapabilities(network.getNetwork()); 3302 assertNotNull(nc); 3303 return nc.hasCapability(NET_CAPABILITY_FOREGROUND); 3304 } 3305 3306 @Test testBackgroundNetworks()3307 public void testBackgroundNetworks() throws Exception { 3308 // Create a background request. We can't do this ourselves because ConnectivityService 3309 // doesn't have an API for it. So just turn on mobile data always on. 3310 setAlwaysOnNetworks(true); 3311 grantUsingBackgroundNetworksPermissionForUid(Binder.getCallingUid()); 3312 final NetworkRequest request = new NetworkRequest.Builder().build(); 3313 final NetworkRequest fgRequest = new NetworkRequest.Builder() 3314 .addCapability(NET_CAPABILITY_FOREGROUND).build(); 3315 final TestNetworkCallback callback = new TestNetworkCallback(); 3316 final TestNetworkCallback fgCallback = new TestNetworkCallback(); 3317 mCm.registerNetworkCallback(request, callback); 3318 mCm.registerNetworkCallback(fgRequest, fgCallback); 3319 3320 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 3321 mCellNetworkAgent.connect(true); 3322 callback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 3323 fgCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 3324 assertTrue(isForegroundNetwork(mCellNetworkAgent)); 3325 3326 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3327 mWiFiNetworkAgent.connect(true); 3328 3329 // When wifi connects, cell lingers. 3330 callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 3331 callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent); 3332 callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent); 3333 fgCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 3334 fgCallback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent); 3335 fgCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent); 3336 assertTrue(isForegroundNetwork(mCellNetworkAgent)); 3337 assertTrue(isForegroundNetwork(mWiFiNetworkAgent)); 3338 3339 // When lingering is complete, cell is still there but is now in the background. 3340 waitForIdle(); 3341 int timeoutMs = TEST_LINGER_DELAY_MS + TEST_LINGER_DELAY_MS / 4; 3342 fgCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent, timeoutMs); 3343 // Expect a network capabilities update sans FOREGROUND. 3344 callback.expectCapabilitiesWithout(NET_CAPABILITY_FOREGROUND, mCellNetworkAgent); 3345 assertFalse(isForegroundNetwork(mCellNetworkAgent)); 3346 assertTrue(isForegroundNetwork(mWiFiNetworkAgent)); 3347 3348 // File a cell request and check that cell comes into the foreground. 3349 final NetworkRequest cellRequest = new NetworkRequest.Builder() 3350 .addTransportType(TRANSPORT_CELLULAR).build(); 3351 final TestNetworkCallback cellCallback = new TestNetworkCallback(); 3352 mCm.requestNetwork(cellRequest, cellCallback); 3353 cellCallback.expectAvailableCallbacksValidated(mCellNetworkAgent); 3354 fgCallback.expectAvailableCallbacksValidated(mCellNetworkAgent); 3355 // Expect a network capabilities update with FOREGROUND, because the most recent 3356 // request causes its state to change. 3357 cellCallback.expectCapabilitiesWith(NET_CAPABILITY_FOREGROUND, mCellNetworkAgent); 3358 callback.expectCapabilitiesWith(NET_CAPABILITY_FOREGROUND, mCellNetworkAgent); 3359 assertTrue(isForegroundNetwork(mCellNetworkAgent)); 3360 assertTrue(isForegroundNetwork(mWiFiNetworkAgent)); 3361 3362 // Release the request. The network immediately goes into the background, since it was not 3363 // lingering. 3364 mCm.unregisterNetworkCallback(cellCallback); 3365 fgCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 3366 // Expect a network capabilities update sans FOREGROUND. 3367 callback.expectCapabilitiesWithout(NET_CAPABILITY_FOREGROUND, mCellNetworkAgent); 3368 assertFalse(isForegroundNetwork(mCellNetworkAgent)); 3369 assertTrue(isForegroundNetwork(mWiFiNetworkAgent)); 3370 3371 // Disconnect wifi and check that cell is foreground again. 3372 mWiFiNetworkAgent.disconnect(); 3373 callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 3374 fgCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 3375 fgCallback.expectAvailableCallbacksValidated(mCellNetworkAgent); 3376 assertTrue(isForegroundNetwork(mCellNetworkAgent)); 3377 3378 mCm.unregisterNetworkCallback(callback); 3379 mCm.unregisterNetworkCallback(fgCallback); 3380 } 3381 3382 @Ignore // This test has instrinsic chances of spurious failures: ignore for continuous testing. benchmarkRequestRegistrationAndCallbackDispatch()3383 public void benchmarkRequestRegistrationAndCallbackDispatch() throws Exception { 3384 // TODO: turn this unit test into a real benchmarking test. 3385 // Benchmarks connecting and switching performance in the presence of a large number of 3386 // NetworkRequests. 3387 // 1. File NUM_REQUESTS requests. 3388 // 2. Have a network connect. Wait for NUM_REQUESTS onAvailable callbacks to fire. 3389 // 3. Have a new network connect and outscore the previous. Wait for NUM_REQUESTS onLosing 3390 // and NUM_REQUESTS onAvailable callbacks to fire. 3391 // See how long it took. 3392 final int NUM_REQUESTS = 90; 3393 final int REGISTER_TIME_LIMIT_MS = 200; 3394 final int CONNECT_TIME_LIMIT_MS = 60; 3395 final int SWITCH_TIME_LIMIT_MS = 60; 3396 final int UNREGISTER_TIME_LIMIT_MS = 20; 3397 3398 final NetworkRequest request = new NetworkRequest.Builder().clearCapabilities().build(); 3399 final NetworkCallback[] callbacks = new NetworkCallback[NUM_REQUESTS]; 3400 final CountDownLatch availableLatch = new CountDownLatch(NUM_REQUESTS); 3401 final CountDownLatch losingLatch = new CountDownLatch(NUM_REQUESTS); 3402 3403 for (int i = 0; i < NUM_REQUESTS; i++) { 3404 callbacks[i] = new NetworkCallback() { 3405 @Override public void onAvailable(Network n) { availableLatch.countDown(); } 3406 @Override public void onLosing(Network n, int t) { losingLatch.countDown(); } 3407 }; 3408 } 3409 3410 assertRunsInAtMost("Registering callbacks", REGISTER_TIME_LIMIT_MS, () -> { 3411 for (NetworkCallback cb : callbacks) { 3412 mCm.registerNetworkCallback(request, cb); 3413 } 3414 }); 3415 3416 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 3417 // Don't request that the network validate, because otherwise connect() will block until 3418 // the network gets NET_CAPABILITY_VALIDATED, after all the callbacks below have fired, 3419 // and we won't actually measure anything. 3420 mCellNetworkAgent.connect(false); 3421 3422 long onAvailableDispatchingDuration = durationOf(() -> { 3423 await(availableLatch, 10 * CONNECT_TIME_LIMIT_MS); 3424 }); 3425 Log.d(TAG, String.format("Dispatched %d of %d onAvailable callbacks in %dms", 3426 NUM_REQUESTS - availableLatch.getCount(), NUM_REQUESTS, 3427 onAvailableDispatchingDuration)); 3428 assertTrue(String.format("Dispatching %d onAvailable callbacks in %dms, expected %dms", 3429 NUM_REQUESTS, onAvailableDispatchingDuration, CONNECT_TIME_LIMIT_MS), 3430 onAvailableDispatchingDuration <= CONNECT_TIME_LIMIT_MS); 3431 3432 // Give wifi a high enough score that we'll linger cell when wifi comes up. 3433 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3434 mWiFiNetworkAgent.adjustScore(40); 3435 mWiFiNetworkAgent.connect(false); 3436 3437 long onLostDispatchingDuration = durationOf(() -> { 3438 await(losingLatch, 10 * SWITCH_TIME_LIMIT_MS); 3439 }); 3440 Log.d(TAG, String.format("Dispatched %d of %d onLosing callbacks in %dms", 3441 NUM_REQUESTS - losingLatch.getCount(), NUM_REQUESTS, onLostDispatchingDuration)); 3442 assertTrue(String.format("Dispatching %d onLosing callbacks in %dms, expected %dms", 3443 NUM_REQUESTS, onLostDispatchingDuration, SWITCH_TIME_LIMIT_MS), 3444 onLostDispatchingDuration <= SWITCH_TIME_LIMIT_MS); 3445 3446 assertRunsInAtMost("Unregistering callbacks", UNREGISTER_TIME_LIMIT_MS, () -> { 3447 for (NetworkCallback cb : callbacks) { 3448 mCm.unregisterNetworkCallback(cb); 3449 } 3450 }); 3451 } 3452 3453 @Test testMobileDataAlwaysOn()3454 public void testMobileDataAlwaysOn() throws Exception { 3455 grantUsingBackgroundNetworksPermissionForUid(Binder.getCallingUid()); 3456 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback(); 3457 final NetworkRequest cellRequest = new NetworkRequest.Builder() 3458 .addTransportType(TRANSPORT_CELLULAR).build(); 3459 mCm.registerNetworkCallback(cellRequest, cellNetworkCallback); 3460 3461 final HandlerThread handlerThread = new HandlerThread("MobileDataAlwaysOnFactory"); 3462 handlerThread.start(); 3463 NetworkCapabilities filter = new NetworkCapabilities() 3464 .addTransportType(TRANSPORT_CELLULAR) 3465 .addCapability(NET_CAPABILITY_INTERNET); 3466 final MockNetworkFactory testFactory = new MockNetworkFactory(handlerThread.getLooper(), 3467 mServiceContext, "testFactory", filter); 3468 testFactory.setScoreFilter(40); 3469 3470 // Register the factory and expect it to start looking for a network. 3471 testFactory.expectAddRequestsWithScores(0); // Score 0 as the request is not served yet. 3472 testFactory.register(); 3473 testFactory.waitForNetworkRequests(1); 3474 assertTrue(testFactory.getMyStartRequested()); 3475 3476 // Bring up wifi. The factory stops looking for a network. 3477 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3478 // Score 60 - 40 penalty for not validated yet, then 60 when it validates 3479 testFactory.expectAddRequestsWithScores(20, 60); 3480 mWiFiNetworkAgent.connect(true); 3481 testFactory.waitForRequests(); 3482 assertFalse(testFactory.getMyStartRequested()); 3483 3484 ContentResolver cr = mServiceContext.getContentResolver(); 3485 3486 // Turn on mobile data always on. The factory starts looking again. 3487 testFactory.expectAddRequestsWithScores(0); // Always on requests comes up with score 0 3488 setAlwaysOnNetworks(true); 3489 testFactory.waitForNetworkRequests(2); 3490 assertTrue(testFactory.getMyStartRequested()); 3491 3492 // Bring up cell data and check that the factory stops looking. 3493 assertLength(1, mCm.getAllNetworks()); 3494 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 3495 testFactory.expectAddRequestsWithScores(10, 50); // Unvalidated, then validated 3496 mCellNetworkAgent.connect(true); 3497 cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 3498 testFactory.waitForNetworkRequests(2); 3499 assertFalse(testFactory.getMyStartRequested()); // Because the cell network outscores us. 3500 3501 // Check that cell data stays up. 3502 waitForIdle(); 3503 verifyActiveNetwork(TRANSPORT_WIFI); 3504 assertLength(2, mCm.getAllNetworks()); 3505 3506 // Turn off mobile data always on and expect the request to disappear... 3507 testFactory.expectRemoveRequests(1); 3508 setAlwaysOnNetworks(false); 3509 testFactory.waitForNetworkRequests(1); 3510 3511 // ... and cell data to be torn down. 3512 cellNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 3513 assertLength(1, mCm.getAllNetworks()); 3514 3515 testFactory.terminate(); 3516 mCm.unregisterNetworkCallback(cellNetworkCallback); 3517 handlerThread.quit(); 3518 } 3519 3520 @Test testAvoidBadWifiSetting()3521 public void testAvoidBadWifiSetting() throws Exception { 3522 final ContentResolver cr = mServiceContext.getContentResolver(); 3523 final String settingName = Settings.Global.NETWORK_AVOID_BAD_WIFI; 3524 3525 mPolicyTracker.mConfigRestrictsAvoidBadWifi = false; 3526 String[] values = new String[] {null, "0", "1"}; 3527 for (int i = 0; i < values.length; i++) { 3528 Settings.Global.putInt(cr, settingName, 1); 3529 mPolicyTracker.reevaluate(); 3530 waitForIdle(); 3531 String msg = String.format("config=false, setting=%s", values[i]); 3532 assertTrue(mService.avoidBadWifi()); 3533 assertFalse(msg, mPolicyTracker.shouldNotifyWifiUnvalidated()); 3534 } 3535 3536 mPolicyTracker.mConfigRestrictsAvoidBadWifi = true; 3537 3538 Settings.Global.putInt(cr, settingName, 0); 3539 mPolicyTracker.reevaluate(); 3540 waitForIdle(); 3541 assertFalse(mService.avoidBadWifi()); 3542 assertFalse(mPolicyTracker.shouldNotifyWifiUnvalidated()); 3543 3544 Settings.Global.putInt(cr, settingName, 1); 3545 mPolicyTracker.reevaluate(); 3546 waitForIdle(); 3547 assertTrue(mService.avoidBadWifi()); 3548 assertFalse(mPolicyTracker.shouldNotifyWifiUnvalidated()); 3549 3550 Settings.Global.putString(cr, settingName, null); 3551 mPolicyTracker.reevaluate(); 3552 waitForIdle(); 3553 assertFalse(mService.avoidBadWifi()); 3554 assertTrue(mPolicyTracker.shouldNotifyWifiUnvalidated()); 3555 } 3556 3557 @Test testAvoidBadWifi()3558 public void testAvoidBadWifi() throws Exception { 3559 final ContentResolver cr = mServiceContext.getContentResolver(); 3560 3561 // Pretend we're on a carrier that restricts switching away from bad wifi. 3562 mPolicyTracker.mConfigRestrictsAvoidBadWifi = true; 3563 3564 // File a request for cell to ensure it doesn't go down. 3565 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback(); 3566 final NetworkRequest cellRequest = new NetworkRequest.Builder() 3567 .addTransportType(TRANSPORT_CELLULAR).build(); 3568 mCm.requestNetwork(cellRequest, cellNetworkCallback); 3569 3570 TestNetworkCallback defaultCallback = new TestNetworkCallback(); 3571 mCm.registerDefaultNetworkCallback(defaultCallback); 3572 3573 NetworkRequest validatedWifiRequest = new NetworkRequest.Builder() 3574 .addTransportType(TRANSPORT_WIFI) 3575 .addCapability(NET_CAPABILITY_VALIDATED) 3576 .build(); 3577 TestNetworkCallback validatedWifiCallback = new TestNetworkCallback(); 3578 mCm.registerNetworkCallback(validatedWifiRequest, validatedWifiCallback); 3579 3580 Settings.Global.putInt(cr, Settings.Global.NETWORK_AVOID_BAD_WIFI, 0); 3581 mPolicyTracker.reevaluate(); 3582 3583 // Bring up validated cell. 3584 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 3585 mCellNetworkAgent.connect(true); 3586 cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 3587 defaultCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 3588 Network cellNetwork = mCellNetworkAgent.getNetwork(); 3589 3590 // Bring up validated wifi. 3591 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3592 mWiFiNetworkAgent.connect(true); 3593 defaultCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent); 3594 validatedWifiCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent); 3595 Network wifiNetwork = mWiFiNetworkAgent.getNetwork(); 3596 3597 // Fail validation on wifi. 3598 mWiFiNetworkAgent.setNetworkInvalid(false /* isStrictMode */); 3599 mCm.reportNetworkConnectivity(wifiNetwork, false); 3600 defaultCallback.expectCapabilitiesWithout(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent); 3601 validatedWifiCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 3602 3603 // Because avoid bad wifi is off, we don't switch to cellular. 3604 defaultCallback.assertNoCallback(); 3605 assertFalse(mCm.getNetworkCapabilities(wifiNetwork).hasCapability( 3606 NET_CAPABILITY_VALIDATED)); 3607 assertTrue(mCm.getNetworkCapabilities(cellNetwork).hasCapability( 3608 NET_CAPABILITY_VALIDATED)); 3609 assertEquals(mCm.getActiveNetwork(), wifiNetwork); 3610 3611 // Simulate switching to a carrier that does not restrict avoiding bad wifi, and expect 3612 // that we switch back to cell. 3613 mPolicyTracker.mConfigRestrictsAvoidBadWifi = false; 3614 mPolicyTracker.reevaluate(); 3615 defaultCallback.expectAvailableCallbacksValidated(mCellNetworkAgent); 3616 assertEquals(mCm.getActiveNetwork(), cellNetwork); 3617 3618 // Switch back to a restrictive carrier. 3619 mPolicyTracker.mConfigRestrictsAvoidBadWifi = true; 3620 mPolicyTracker.reevaluate(); 3621 defaultCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 3622 assertEquals(mCm.getActiveNetwork(), wifiNetwork); 3623 3624 // Simulate the user selecting "switch" on the dialog, and check that we switch to cell. 3625 mCm.setAvoidUnvalidated(wifiNetwork); 3626 defaultCallback.expectAvailableCallbacksValidated(mCellNetworkAgent); 3627 assertFalse(mCm.getNetworkCapabilities(wifiNetwork).hasCapability( 3628 NET_CAPABILITY_VALIDATED)); 3629 assertTrue(mCm.getNetworkCapabilities(cellNetwork).hasCapability( 3630 NET_CAPABILITY_VALIDATED)); 3631 assertEquals(mCm.getActiveNetwork(), cellNetwork); 3632 3633 // Disconnect and reconnect wifi to clear the one-time switch above. 3634 mWiFiNetworkAgent.disconnect(); 3635 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3636 mWiFiNetworkAgent.connect(true); 3637 defaultCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent); 3638 validatedWifiCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent); 3639 wifiNetwork = mWiFiNetworkAgent.getNetwork(); 3640 3641 // Fail validation on wifi and expect the dialog to appear. 3642 mWiFiNetworkAgent.setNetworkInvalid(false /* isStrictMode */); 3643 mCm.reportNetworkConnectivity(wifiNetwork, false); 3644 defaultCallback.expectCapabilitiesWithout(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent); 3645 validatedWifiCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 3646 3647 // Simulate the user selecting "switch" and checking the don't ask again checkbox. 3648 Settings.Global.putInt(cr, Settings.Global.NETWORK_AVOID_BAD_WIFI, 1); 3649 mPolicyTracker.reevaluate(); 3650 3651 // We now switch to cell. 3652 defaultCallback.expectAvailableCallbacksValidated(mCellNetworkAgent); 3653 assertFalse(mCm.getNetworkCapabilities(wifiNetwork).hasCapability( 3654 NET_CAPABILITY_VALIDATED)); 3655 assertTrue(mCm.getNetworkCapabilities(cellNetwork).hasCapability( 3656 NET_CAPABILITY_VALIDATED)); 3657 assertEquals(mCm.getActiveNetwork(), cellNetwork); 3658 3659 // Simulate the user turning the cellular fallback setting off and then on. 3660 // We switch to wifi and then to cell. 3661 Settings.Global.putString(cr, Settings.Global.NETWORK_AVOID_BAD_WIFI, null); 3662 mPolicyTracker.reevaluate(); 3663 defaultCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 3664 assertEquals(mCm.getActiveNetwork(), wifiNetwork); 3665 Settings.Global.putInt(cr, Settings.Global.NETWORK_AVOID_BAD_WIFI, 1); 3666 mPolicyTracker.reevaluate(); 3667 defaultCallback.expectAvailableCallbacksValidated(mCellNetworkAgent); 3668 assertEquals(mCm.getActiveNetwork(), cellNetwork); 3669 3670 // If cell goes down, we switch to wifi. 3671 mCellNetworkAgent.disconnect(); 3672 defaultCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 3673 defaultCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 3674 validatedWifiCallback.assertNoCallback(); 3675 3676 mCm.unregisterNetworkCallback(cellNetworkCallback); 3677 mCm.unregisterNetworkCallback(validatedWifiCallback); 3678 mCm.unregisterNetworkCallback(defaultCallback); 3679 } 3680 3681 @Test testMeteredMultipathPreferenceSetting()3682 public void testMeteredMultipathPreferenceSetting() throws Exception { 3683 final ContentResolver cr = mServiceContext.getContentResolver(); 3684 final String settingName = Settings.Global.NETWORK_METERED_MULTIPATH_PREFERENCE; 3685 3686 for (int config : Arrays.asList(0, 3, 2)) { 3687 for (String setting: Arrays.asList(null, "0", "2", "1")) { 3688 mPolicyTracker.mConfigMeteredMultipathPreference = config; 3689 Settings.Global.putString(cr, settingName, setting); 3690 mPolicyTracker.reevaluate(); 3691 waitForIdle(); 3692 3693 final int expected = (setting != null) ? Integer.parseInt(setting) : config; 3694 String msg = String.format("config=%d, setting=%s", config, setting); 3695 assertEquals(msg, expected, mCm.getMultipathPreference(null)); 3696 } 3697 } 3698 } 3699 3700 /** 3701 * Validate that a satisfied network request does not trigger onUnavailable() once the 3702 * time-out period expires. 3703 */ 3704 @Test testSatisfiedNetworkRequestDoesNotTriggerOnUnavailable()3705 public void testSatisfiedNetworkRequestDoesNotTriggerOnUnavailable() throws Exception { 3706 NetworkRequest nr = new NetworkRequest.Builder().addTransportType( 3707 NetworkCapabilities.TRANSPORT_WIFI).build(); 3708 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 3709 mCm.requestNetwork(nr, networkCallback, TEST_REQUEST_TIMEOUT_MS); 3710 3711 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3712 mWiFiNetworkAgent.connect(false); 3713 networkCallback.expectAvailableCallbacks(mWiFiNetworkAgent, false, false, false, 3714 TEST_CALLBACK_TIMEOUT_MS); 3715 3716 // pass timeout and validate that UNAVAILABLE is not called 3717 networkCallback.assertNoCallback(); 3718 } 3719 3720 /** 3721 * Validate that a satisfied network request followed by a disconnected (lost) network does 3722 * not trigger onUnavailable() once the time-out period expires. 3723 */ 3724 @Test testSatisfiedThenLostNetworkRequestDoesNotTriggerOnUnavailable()3725 public void testSatisfiedThenLostNetworkRequestDoesNotTriggerOnUnavailable() throws Exception { 3726 NetworkRequest nr = new NetworkRequest.Builder().addTransportType( 3727 NetworkCapabilities.TRANSPORT_WIFI).build(); 3728 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 3729 mCm.requestNetwork(nr, networkCallback, TEST_REQUEST_TIMEOUT_MS); 3730 3731 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3732 mWiFiNetworkAgent.connect(false); 3733 networkCallback.expectAvailableCallbacks(mWiFiNetworkAgent, false, false, false, 3734 TEST_CALLBACK_TIMEOUT_MS); 3735 mWiFiNetworkAgent.disconnect(); 3736 networkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 3737 3738 // Validate that UNAVAILABLE is not called 3739 networkCallback.assertNoCallback(); 3740 } 3741 3742 /** 3743 * Validate that when a time-out is specified for a network request the onUnavailable() 3744 * callback is called when time-out expires. Then validate that if network request is 3745 * (somehow) satisfied - the callback isn't called later. 3746 */ 3747 @Test testTimedoutNetworkRequest()3748 public void testTimedoutNetworkRequest() throws Exception { 3749 NetworkRequest nr = new NetworkRequest.Builder().addTransportType( 3750 NetworkCapabilities.TRANSPORT_WIFI).build(); 3751 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 3752 final int timeoutMs = 10; 3753 mCm.requestNetwork(nr, networkCallback, timeoutMs); 3754 3755 // pass timeout and validate that UNAVAILABLE is called 3756 networkCallback.expectCallback(CallbackEntry.UNAVAILABLE, (Network) null); 3757 3758 // create a network satisfying request - validate that request not triggered 3759 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3760 mWiFiNetworkAgent.connect(false); 3761 networkCallback.assertNoCallback(); 3762 } 3763 3764 /** 3765 * Validate that when a network request is unregistered (cancelled), no posterior event can 3766 * trigger the callback. 3767 */ 3768 @Test testNoCallbackAfterUnregisteredNetworkRequest()3769 public void testNoCallbackAfterUnregisteredNetworkRequest() throws Exception { 3770 NetworkRequest nr = new NetworkRequest.Builder().addTransportType( 3771 NetworkCapabilities.TRANSPORT_WIFI).build(); 3772 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 3773 final int timeoutMs = 10; 3774 3775 mCm.requestNetwork(nr, networkCallback, timeoutMs); 3776 mCm.unregisterNetworkCallback(networkCallback); 3777 // Regardless of the timeout, unregistering the callback in ConnectivityManager ensures 3778 // that this callback will not be called. 3779 networkCallback.assertNoCallback(); 3780 3781 // create a network satisfying request - validate that request not triggered 3782 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3783 mWiFiNetworkAgent.connect(false); 3784 networkCallback.assertNoCallback(); 3785 } 3786 3787 @Test testUnfulfillableNetworkRequest()3788 public void testUnfulfillableNetworkRequest() throws Exception { 3789 runUnfulfillableNetworkRequest(false); 3790 } 3791 3792 @Test testUnfulfillableNetworkRequestAfterUnregister()3793 public void testUnfulfillableNetworkRequestAfterUnregister() throws Exception { 3794 runUnfulfillableNetworkRequest(true); 3795 } 3796 3797 /** 3798 * Validate the callback flow for a factory releasing a request as unfulfillable. 3799 */ runUnfulfillableNetworkRequest(boolean preUnregister)3800 private void runUnfulfillableNetworkRequest(boolean preUnregister) throws Exception { 3801 NetworkRequest nr = new NetworkRequest.Builder().addTransportType( 3802 NetworkCapabilities.TRANSPORT_WIFI).build(); 3803 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 3804 3805 final HandlerThread handlerThread = new HandlerThread("testUnfulfillableNetworkRequest"); 3806 handlerThread.start(); 3807 NetworkCapabilities filter = new NetworkCapabilities() 3808 .addTransportType(TRANSPORT_WIFI) 3809 .addCapability(NET_CAPABILITY_INTERNET); 3810 final MockNetworkFactory testFactory = new MockNetworkFactory(handlerThread.getLooper(), 3811 mServiceContext, "testFactory", filter); 3812 testFactory.setScoreFilter(40); 3813 3814 // Register the factory and expect it to receive the default request. 3815 testFactory.expectAddRequestsWithScores(0); 3816 testFactory.register(); 3817 SparseArray<NetworkRequest> requests = testFactory.waitForNetworkRequests(1); 3818 3819 assertEquals(1, requests.size()); // have 1 request at this point 3820 int origRequestId = requests.valueAt(0).requestId; 3821 3822 // Now file the test request and expect it. 3823 testFactory.expectAddRequestsWithScores(0); 3824 mCm.requestNetwork(nr, networkCallback); 3825 requests = testFactory.waitForNetworkRequests(2); // have 2 requests at this point 3826 3827 int newRequestId = 0; 3828 for (int i = 0; i < requests.size(); ++i) { 3829 if (requests.valueAt(i).requestId != origRequestId) { 3830 newRequestId = requests.valueAt(i).requestId; 3831 break; 3832 } 3833 } 3834 3835 testFactory.expectRemoveRequests(1); 3836 if (preUnregister) { 3837 mCm.unregisterNetworkCallback(networkCallback); 3838 3839 // Simulate the factory releasing the request as unfulfillable: no-op since 3840 // the callback has already been unregistered (but a test that no exceptions are 3841 // thrown). 3842 testFactory.triggerUnfulfillable(requests.get(newRequestId)); 3843 } else { 3844 // Simulate the factory releasing the request as unfulfillable and expect onUnavailable! 3845 testFactory.triggerUnfulfillable(requests.get(newRequestId)); 3846 3847 networkCallback.expectCallback(CallbackEntry.UNAVAILABLE, (Network) null); 3848 testFactory.waitForRequests(); 3849 3850 // unregister network callback - a no-op (since already freed by the 3851 // on-unavailable), but should not fail or throw exceptions. 3852 mCm.unregisterNetworkCallback(networkCallback); 3853 } 3854 3855 testFactory.terminate(); 3856 handlerThread.quit(); 3857 } 3858 3859 private static class TestKeepaliveCallback extends PacketKeepaliveCallback { 3860 3861 public enum CallbackType { ON_STARTED, ON_STOPPED, ON_ERROR } 3862 3863 private class CallbackValue { 3864 public CallbackType callbackType; 3865 public int error; 3866 CallbackValue(CallbackType type)3867 public CallbackValue(CallbackType type) { 3868 this.callbackType = type; 3869 this.error = PacketKeepalive.SUCCESS; 3870 assertTrue("onError callback must have error", type != CallbackType.ON_ERROR); 3871 } 3872 CallbackValue(CallbackType type, int error)3873 public CallbackValue(CallbackType type, int error) { 3874 this.callbackType = type; 3875 this.error = error; 3876 assertEquals("error can only be set for onError", type, CallbackType.ON_ERROR); 3877 } 3878 3879 @Override equals(Object o)3880 public boolean equals(Object o) { 3881 return o instanceof CallbackValue && 3882 this.callbackType == ((CallbackValue) o).callbackType && 3883 this.error == ((CallbackValue) o).error; 3884 } 3885 3886 @Override toString()3887 public String toString() { 3888 return String.format("%s(%s, %d)", getClass().getSimpleName(), callbackType, error); 3889 } 3890 } 3891 3892 private final LinkedBlockingQueue<CallbackValue> mCallbacks = new LinkedBlockingQueue<>(); 3893 3894 @Override onStarted()3895 public void onStarted() { 3896 mCallbacks.add(new CallbackValue(CallbackType.ON_STARTED)); 3897 } 3898 3899 @Override onStopped()3900 public void onStopped() { 3901 mCallbacks.add(new CallbackValue(CallbackType.ON_STOPPED)); 3902 } 3903 3904 @Override onError(int error)3905 public void onError(int error) { 3906 mCallbacks.add(new CallbackValue(CallbackType.ON_ERROR, error)); 3907 } 3908 expectCallback(CallbackValue callbackValue)3909 private void expectCallback(CallbackValue callbackValue) throws InterruptedException { 3910 assertEquals(callbackValue, mCallbacks.poll(TIMEOUT_MS, TimeUnit.MILLISECONDS)); 3911 } 3912 expectStarted()3913 public void expectStarted() throws Exception { 3914 expectCallback(new CallbackValue(CallbackType.ON_STARTED)); 3915 } 3916 expectStopped()3917 public void expectStopped() throws Exception { 3918 expectCallback(new CallbackValue(CallbackType.ON_STOPPED)); 3919 } 3920 expectError(int error)3921 public void expectError(int error) throws Exception { 3922 expectCallback(new CallbackValue(CallbackType.ON_ERROR, error)); 3923 } 3924 } 3925 3926 private static class TestSocketKeepaliveCallback extends SocketKeepalive.Callback { 3927 3928 public enum CallbackType { ON_STARTED, ON_STOPPED, ON_ERROR }; 3929 3930 private class CallbackValue { 3931 public CallbackType callbackType; 3932 public int error; 3933 CallbackValue(CallbackType type)3934 CallbackValue(CallbackType type) { 3935 this.callbackType = type; 3936 this.error = SocketKeepalive.SUCCESS; 3937 assertTrue("onError callback must have error", type != CallbackType.ON_ERROR); 3938 } 3939 CallbackValue(CallbackType type, int error)3940 CallbackValue(CallbackType type, int error) { 3941 this.callbackType = type; 3942 this.error = error; 3943 assertEquals("error can only be set for onError", type, CallbackType.ON_ERROR); 3944 } 3945 3946 @Override equals(Object o)3947 public boolean equals(Object o) { 3948 return o instanceof CallbackValue 3949 && this.callbackType == ((CallbackValue) o).callbackType 3950 && this.error == ((CallbackValue) o).error; 3951 } 3952 3953 @Override toString()3954 public String toString() { 3955 return String.format("%s(%s, %d)", getClass().getSimpleName(), callbackType, 3956 error); 3957 } 3958 } 3959 3960 private LinkedBlockingQueue<CallbackValue> mCallbacks = new LinkedBlockingQueue<>(); 3961 private final Executor mExecutor; 3962 TestSocketKeepaliveCallback(@onNull Executor executor)3963 TestSocketKeepaliveCallback(@NonNull Executor executor) { 3964 mExecutor = executor; 3965 } 3966 3967 @Override onStarted()3968 public void onStarted() { 3969 mCallbacks.add(new CallbackValue(CallbackType.ON_STARTED)); 3970 } 3971 3972 @Override onStopped()3973 public void onStopped() { 3974 mCallbacks.add(new CallbackValue(CallbackType.ON_STOPPED)); 3975 } 3976 3977 @Override onError(int error)3978 public void onError(int error) { 3979 mCallbacks.add(new CallbackValue(CallbackType.ON_ERROR, error)); 3980 } 3981 expectCallback(CallbackValue callbackValue)3982 private void expectCallback(CallbackValue callbackValue) throws InterruptedException { 3983 assertEquals(callbackValue, mCallbacks.poll(TIMEOUT_MS, TimeUnit.MILLISECONDS)); 3984 3985 } 3986 expectStarted()3987 public void expectStarted() throws InterruptedException { 3988 expectCallback(new CallbackValue(CallbackType.ON_STARTED)); 3989 } 3990 expectStopped()3991 public void expectStopped() throws InterruptedException { 3992 expectCallback(new CallbackValue(CallbackType.ON_STOPPED)); 3993 } 3994 expectError(int error)3995 public void expectError(int error) throws InterruptedException { 3996 expectCallback(new CallbackValue(CallbackType.ON_ERROR, error)); 3997 } 3998 assertNoCallback()3999 public void assertNoCallback() { 4000 waitForIdleSerialExecutor(mExecutor, TIMEOUT_MS); 4001 CallbackValue cv = mCallbacks.peek(); 4002 assertNull("Unexpected callback: " + cv, cv); 4003 } 4004 } 4005 connectKeepaliveNetwork(LinkProperties lp)4006 private Network connectKeepaliveNetwork(LinkProperties lp) throws Exception { 4007 // Ensure the network is disconnected before we do anything. 4008 if (mWiFiNetworkAgent != null) { 4009 assertNull(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork())); 4010 } 4011 4012 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4013 ConditionVariable cv = registerConnectivityBroadcast(1); 4014 mWiFiNetworkAgent.connect(true); 4015 waitFor(cv); 4016 verifyActiveNetwork(TRANSPORT_WIFI); 4017 mWiFiNetworkAgent.sendLinkProperties(lp); 4018 waitForIdle(); 4019 return mWiFiNetworkAgent.getNetwork(); 4020 } 4021 4022 @Test 4023 @FlakyTest(bugId = 140305589) testPacketKeepalives()4024 public void testPacketKeepalives() throws Exception { 4025 InetAddress myIPv4 = InetAddress.getByName("192.0.2.129"); 4026 InetAddress notMyIPv4 = InetAddress.getByName("192.0.2.35"); 4027 InetAddress myIPv6 = InetAddress.getByName("2001:db8::1"); 4028 InetAddress dstIPv4 = InetAddress.getByName("8.8.8.8"); 4029 InetAddress dstIPv6 = InetAddress.getByName("2001:4860:4860::8888"); 4030 4031 final int validKaInterval = 15; 4032 final int invalidKaInterval = 9; 4033 4034 LinkProperties lp = new LinkProperties(); 4035 lp.setInterfaceName("wlan12"); 4036 lp.addLinkAddress(new LinkAddress(myIPv6, 64)); 4037 lp.addLinkAddress(new LinkAddress(myIPv4, 25)); 4038 lp.addRoute(new RouteInfo(InetAddress.getByName("fe80::1234"))); 4039 lp.addRoute(new RouteInfo(InetAddress.getByName("192.0.2.254"))); 4040 4041 Network notMyNet = new Network(61234); 4042 Network myNet = connectKeepaliveNetwork(lp); 4043 4044 TestKeepaliveCallback callback = new TestKeepaliveCallback(); 4045 PacketKeepalive ka; 4046 4047 // Attempt to start keepalives with invalid parameters and check for errors. 4048 ka = mCm.startNattKeepalive(notMyNet, validKaInterval, callback, myIPv4, 1234, dstIPv4); 4049 callback.expectError(PacketKeepalive.ERROR_INVALID_NETWORK); 4050 4051 ka = mCm.startNattKeepalive(myNet, invalidKaInterval, callback, myIPv4, 1234, dstIPv4); 4052 callback.expectError(PacketKeepalive.ERROR_INVALID_INTERVAL); 4053 4054 ka = mCm.startNattKeepalive(myNet, validKaInterval, callback, myIPv4, 1234, dstIPv6); 4055 callback.expectError(PacketKeepalive.ERROR_INVALID_IP_ADDRESS); 4056 4057 ka = mCm.startNattKeepalive(myNet, validKaInterval, callback, myIPv6, 1234, dstIPv4); 4058 callback.expectError(PacketKeepalive.ERROR_INVALID_IP_ADDRESS); 4059 4060 // NAT-T is only supported for IPv4. 4061 ka = mCm.startNattKeepalive(myNet, validKaInterval, callback, myIPv6, 1234, dstIPv6); 4062 callback.expectError(PacketKeepalive.ERROR_INVALID_IP_ADDRESS); 4063 4064 ka = mCm.startNattKeepalive(myNet, validKaInterval, callback, myIPv4, 123456, dstIPv4); 4065 callback.expectError(PacketKeepalive.ERROR_INVALID_PORT); 4066 4067 ka = mCm.startNattKeepalive(myNet, validKaInterval, callback, myIPv4, 123456, dstIPv4); 4068 callback.expectError(PacketKeepalive.ERROR_INVALID_PORT); 4069 4070 ka = mCm.startNattKeepalive(myNet, validKaInterval, callback, myIPv4, 12345, dstIPv4); 4071 callback.expectError(PacketKeepalive.ERROR_HARDWARE_UNSUPPORTED); 4072 4073 ka = mCm.startNattKeepalive(myNet, validKaInterval, callback, myIPv4, 12345, dstIPv4); 4074 callback.expectError(PacketKeepalive.ERROR_HARDWARE_UNSUPPORTED); 4075 4076 // Check that a started keepalive can be stopped. 4077 mWiFiNetworkAgent.setStartKeepaliveEvent(PacketKeepalive.SUCCESS); 4078 ka = mCm.startNattKeepalive(myNet, validKaInterval, callback, myIPv4, 12345, dstIPv4); 4079 callback.expectStarted(); 4080 mWiFiNetworkAgent.setStopKeepaliveEvent(PacketKeepalive.SUCCESS); 4081 ka.stop(); 4082 callback.expectStopped(); 4083 4084 // Check that deleting the IP address stops the keepalive. 4085 LinkProperties bogusLp = new LinkProperties(lp); 4086 ka = mCm.startNattKeepalive(myNet, validKaInterval, callback, myIPv4, 12345, dstIPv4); 4087 callback.expectStarted(); 4088 bogusLp.removeLinkAddress(new LinkAddress(myIPv4, 25)); 4089 bogusLp.addLinkAddress(new LinkAddress(notMyIPv4, 25)); 4090 mWiFiNetworkAgent.sendLinkProperties(bogusLp); 4091 callback.expectError(PacketKeepalive.ERROR_INVALID_IP_ADDRESS); 4092 mWiFiNetworkAgent.sendLinkProperties(lp); 4093 4094 // Check that a started keepalive is stopped correctly when the network disconnects. 4095 ka = mCm.startNattKeepalive(myNet, validKaInterval, callback, myIPv4, 12345, dstIPv4); 4096 callback.expectStarted(); 4097 mWiFiNetworkAgent.disconnect(); 4098 mWiFiNetworkAgent.expectDisconnected(); 4099 callback.expectError(PacketKeepalive.ERROR_INVALID_NETWORK); 4100 4101 // ... and that stopping it after that has no adverse effects. 4102 waitForIdle(); 4103 final Network myNetAlias = myNet; 4104 assertNull(mCm.getNetworkCapabilities(myNetAlias)); 4105 ka.stop(); 4106 4107 // Reconnect. 4108 myNet = connectKeepaliveNetwork(lp); 4109 mWiFiNetworkAgent.setStartKeepaliveEvent(PacketKeepalive.SUCCESS); 4110 4111 // Check that keepalive slots start from 1 and increment. The first one gets slot 1. 4112 mWiFiNetworkAgent.setExpectedKeepaliveSlot(1); 4113 ka = mCm.startNattKeepalive(myNet, validKaInterval, callback, myIPv4, 12345, dstIPv4); 4114 callback.expectStarted(); 4115 4116 // The second one gets slot 2. 4117 mWiFiNetworkAgent.setExpectedKeepaliveSlot(2); 4118 TestKeepaliveCallback callback2 = new TestKeepaliveCallback(); 4119 PacketKeepalive ka2 = mCm.startNattKeepalive( 4120 myNet, validKaInterval, callback2, myIPv4, 6789, dstIPv4); 4121 callback2.expectStarted(); 4122 4123 // Now stop the first one and create a third. This also gets slot 1. 4124 ka.stop(); 4125 callback.expectStopped(); 4126 4127 mWiFiNetworkAgent.setExpectedKeepaliveSlot(1); 4128 TestKeepaliveCallback callback3 = new TestKeepaliveCallback(); 4129 PacketKeepalive ka3 = mCm.startNattKeepalive( 4130 myNet, validKaInterval, callback3, myIPv4, 9876, dstIPv4); 4131 callback3.expectStarted(); 4132 4133 ka2.stop(); 4134 callback2.expectStopped(); 4135 4136 ka3.stop(); 4137 callback3.expectStopped(); 4138 } 4139 4140 // Helper method to prepare the executor and run test runTestWithSerialExecutors(ExceptionUtils.ThrowingConsumer<Executor> functor)4141 private void runTestWithSerialExecutors(ExceptionUtils.ThrowingConsumer<Executor> functor) 4142 throws Exception { 4143 final ExecutorService executorSingleThread = Executors.newSingleThreadExecutor(); 4144 final Executor executorInline = (Runnable r) -> r.run(); 4145 functor.accept(executorSingleThread); 4146 executorSingleThread.shutdown(); 4147 functor.accept(executorInline); 4148 } 4149 4150 @Test testNattSocketKeepalives()4151 public void testNattSocketKeepalives() throws Exception { 4152 runTestWithSerialExecutors(executor -> doTestNattSocketKeepalivesWithExecutor(executor)); 4153 runTestWithSerialExecutors(executor -> doTestNattSocketKeepalivesFdWithExecutor(executor)); 4154 } 4155 doTestNattSocketKeepalivesWithExecutor(Executor executor)4156 private void doTestNattSocketKeepalivesWithExecutor(Executor executor) throws Exception { 4157 // TODO: 1. Move this outside of ConnectivityServiceTest. 4158 // 2. Make test to verify that Nat-T keepalive socket is created by IpSecService. 4159 // 3. Mock ipsec service. 4160 final InetAddress myIPv4 = InetAddress.getByName("192.0.2.129"); 4161 final InetAddress notMyIPv4 = InetAddress.getByName("192.0.2.35"); 4162 final InetAddress myIPv6 = InetAddress.getByName("2001:db8::1"); 4163 final InetAddress dstIPv4 = InetAddress.getByName("8.8.8.8"); 4164 final InetAddress dstIPv6 = InetAddress.getByName("2001:4860:4860::8888"); 4165 4166 final int validKaInterval = 15; 4167 final int invalidKaInterval = 9; 4168 4169 final IpSecManager mIpSec = (IpSecManager) mContext.getSystemService(Context.IPSEC_SERVICE); 4170 final UdpEncapsulationSocket testSocket = mIpSec.openUdpEncapsulationSocket(); 4171 final int srcPort = testSocket.getPort(); 4172 4173 LinkProperties lp = new LinkProperties(); 4174 lp.setInterfaceName("wlan12"); 4175 lp.addLinkAddress(new LinkAddress(myIPv6, 64)); 4176 lp.addLinkAddress(new LinkAddress(myIPv4, 25)); 4177 lp.addRoute(new RouteInfo(InetAddress.getByName("fe80::1234"))); 4178 lp.addRoute(new RouteInfo(InetAddress.getByName("192.0.2.254"))); 4179 4180 Network notMyNet = new Network(61234); 4181 Network myNet = connectKeepaliveNetwork(lp); 4182 4183 TestSocketKeepaliveCallback callback = new TestSocketKeepaliveCallback(executor); 4184 4185 // Attempt to start keepalives with invalid parameters and check for errors. 4186 // Invalid network. 4187 try (SocketKeepalive ka = mCm.createSocketKeepalive( 4188 notMyNet, testSocket, myIPv4, dstIPv4, executor, callback)) { 4189 ka.start(validKaInterval); 4190 callback.expectError(SocketKeepalive.ERROR_INVALID_NETWORK); 4191 } 4192 4193 // Invalid interval. 4194 try (SocketKeepalive ka = mCm.createSocketKeepalive( 4195 myNet, testSocket, myIPv4, dstIPv4, executor, callback)) { 4196 ka.start(invalidKaInterval); 4197 callback.expectError(SocketKeepalive.ERROR_INVALID_INTERVAL); 4198 } 4199 4200 // Invalid destination. 4201 try (SocketKeepalive ka = mCm.createSocketKeepalive( 4202 myNet, testSocket, myIPv4, dstIPv6, executor, callback)) { 4203 ka.start(validKaInterval); 4204 callback.expectError(SocketKeepalive.ERROR_INVALID_IP_ADDRESS); 4205 } 4206 4207 // Invalid source; 4208 try (SocketKeepalive ka = mCm.createSocketKeepalive( 4209 myNet, testSocket, myIPv6, dstIPv4, executor, callback)) { 4210 ka.start(validKaInterval); 4211 callback.expectError(SocketKeepalive.ERROR_INVALID_IP_ADDRESS); 4212 } 4213 4214 // NAT-T is only supported for IPv4. 4215 try (SocketKeepalive ka = mCm.createSocketKeepalive( 4216 myNet, testSocket, myIPv6, dstIPv6, executor, callback)) { 4217 ka.start(validKaInterval); 4218 callback.expectError(SocketKeepalive.ERROR_INVALID_IP_ADDRESS); 4219 } 4220 4221 // Sanity check before testing started keepalive. 4222 try (SocketKeepalive ka = mCm.createSocketKeepalive( 4223 myNet, testSocket, myIPv4, dstIPv4, executor, callback)) { 4224 ka.start(validKaInterval); 4225 callback.expectError(SocketKeepalive.ERROR_UNSUPPORTED); 4226 } 4227 4228 // Check that a started keepalive can be stopped. 4229 mWiFiNetworkAgent.setStartKeepaliveEvent(SocketKeepalive.SUCCESS); 4230 try (SocketKeepalive ka = mCm.createSocketKeepalive( 4231 myNet, testSocket, myIPv4, dstIPv4, executor, callback)) { 4232 ka.start(validKaInterval); 4233 callback.expectStarted(); 4234 mWiFiNetworkAgent.setStopKeepaliveEvent(SocketKeepalive.SUCCESS); 4235 ka.stop(); 4236 callback.expectStopped(); 4237 4238 // Check that keepalive could be restarted. 4239 ka.start(validKaInterval); 4240 callback.expectStarted(); 4241 ka.stop(); 4242 callback.expectStopped(); 4243 4244 // Check that keepalive can be restarted without waiting for callback. 4245 ka.start(validKaInterval); 4246 callback.expectStarted(); 4247 ka.stop(); 4248 ka.start(validKaInterval); 4249 callback.expectStopped(); 4250 callback.expectStarted(); 4251 ka.stop(); 4252 callback.expectStopped(); 4253 } 4254 4255 // Check that deleting the IP address stops the keepalive. 4256 LinkProperties bogusLp = new LinkProperties(lp); 4257 try (SocketKeepalive ka = mCm.createSocketKeepalive( 4258 myNet, testSocket, myIPv4, dstIPv4, executor, callback)) { 4259 ka.start(validKaInterval); 4260 callback.expectStarted(); 4261 bogusLp.removeLinkAddress(new LinkAddress(myIPv4, 25)); 4262 bogusLp.addLinkAddress(new LinkAddress(notMyIPv4, 25)); 4263 mWiFiNetworkAgent.sendLinkProperties(bogusLp); 4264 callback.expectError(SocketKeepalive.ERROR_INVALID_IP_ADDRESS); 4265 mWiFiNetworkAgent.sendLinkProperties(lp); 4266 } 4267 4268 // Check that a started keepalive is stopped correctly when the network disconnects. 4269 try (SocketKeepalive ka = mCm.createSocketKeepalive( 4270 myNet, testSocket, myIPv4, dstIPv4, executor, callback)) { 4271 ka.start(validKaInterval); 4272 callback.expectStarted(); 4273 mWiFiNetworkAgent.disconnect(); 4274 mWiFiNetworkAgent.expectDisconnected(); 4275 callback.expectError(SocketKeepalive.ERROR_INVALID_NETWORK); 4276 4277 // ... and that stopping it after that has no adverse effects. 4278 waitForIdle(); 4279 final Network myNetAlias = myNet; 4280 assertNull(mCm.getNetworkCapabilities(myNetAlias)); 4281 ka.stop(); 4282 callback.assertNoCallback(); 4283 } 4284 4285 // Reconnect. 4286 myNet = connectKeepaliveNetwork(lp); 4287 mWiFiNetworkAgent.setStartKeepaliveEvent(SocketKeepalive.SUCCESS); 4288 4289 // Check that keepalive slots start from 1 and increment. The first one gets slot 1. 4290 mWiFiNetworkAgent.setExpectedKeepaliveSlot(1); 4291 int srcPort2 = 0; 4292 try (SocketKeepalive ka = mCm.createSocketKeepalive( 4293 myNet, testSocket, myIPv4, dstIPv4, executor, callback)) { 4294 ka.start(validKaInterval); 4295 callback.expectStarted(); 4296 4297 // The second one gets slot 2. 4298 mWiFiNetworkAgent.setExpectedKeepaliveSlot(2); 4299 final UdpEncapsulationSocket testSocket2 = mIpSec.openUdpEncapsulationSocket(); 4300 srcPort2 = testSocket2.getPort(); 4301 TestSocketKeepaliveCallback callback2 = new TestSocketKeepaliveCallback(executor); 4302 try (SocketKeepalive ka2 = mCm.createSocketKeepalive( 4303 myNet, testSocket2, myIPv4, dstIPv4, executor, callback2)) { 4304 ka2.start(validKaInterval); 4305 callback2.expectStarted(); 4306 4307 ka.stop(); 4308 callback.expectStopped(); 4309 4310 ka2.stop(); 4311 callback2.expectStopped(); 4312 4313 testSocket.close(); 4314 testSocket2.close(); 4315 } 4316 } 4317 4318 // Check that there is no port leaked after all keepalives and sockets are closed. 4319 // TODO: enable this check after ensuring a valid free port. See b/129512753#comment7. 4320 // assertFalse(isUdpPortInUse(srcPort)); 4321 // assertFalse(isUdpPortInUse(srcPort2)); 4322 4323 mWiFiNetworkAgent.disconnect(); 4324 mWiFiNetworkAgent.expectDisconnected(); 4325 mWiFiNetworkAgent = null; 4326 } 4327 4328 @Test testTcpSocketKeepalives()4329 public void testTcpSocketKeepalives() throws Exception { 4330 runTestWithSerialExecutors(executor -> doTestTcpSocketKeepalivesWithExecutor(executor)); 4331 } 4332 doTestTcpSocketKeepalivesWithExecutor(Executor executor)4333 private void doTestTcpSocketKeepalivesWithExecutor(Executor executor) throws Exception { 4334 final int srcPortV4 = 12345; 4335 final int srcPortV6 = 23456; 4336 final InetAddress myIPv4 = InetAddress.getByName("127.0.0.1"); 4337 final InetAddress myIPv6 = InetAddress.getByName("::1"); 4338 4339 final int validKaInterval = 15; 4340 4341 final LinkProperties lp = new LinkProperties(); 4342 lp.setInterfaceName("wlan12"); 4343 lp.addLinkAddress(new LinkAddress(myIPv6, 64)); 4344 lp.addLinkAddress(new LinkAddress(myIPv4, 25)); 4345 lp.addRoute(new RouteInfo(InetAddress.getByName("fe80::1234"))); 4346 lp.addRoute(new RouteInfo(InetAddress.getByName("127.0.0.254"))); 4347 4348 final Network notMyNet = new Network(61234); 4349 final Network myNet = connectKeepaliveNetwork(lp); 4350 4351 final Socket testSocketV4 = new Socket(); 4352 final Socket testSocketV6 = new Socket(); 4353 4354 TestSocketKeepaliveCallback callback = new TestSocketKeepaliveCallback(executor); 4355 4356 // Attempt to start Tcp keepalives with invalid parameters and check for errors. 4357 // Invalid network. 4358 try (SocketKeepalive ka = mCm.createSocketKeepalive( 4359 notMyNet, testSocketV4, executor, callback)) { 4360 ka.start(validKaInterval); 4361 callback.expectError(SocketKeepalive.ERROR_INVALID_NETWORK); 4362 } 4363 4364 // Invalid Socket (socket is not bound with IPv4 address). 4365 try (SocketKeepalive ka = mCm.createSocketKeepalive( 4366 myNet, testSocketV4, executor, callback)) { 4367 ka.start(validKaInterval); 4368 callback.expectError(SocketKeepalive.ERROR_INVALID_SOCKET); 4369 } 4370 4371 // Invalid Socket (socket is not bound with IPv6 address). 4372 try (SocketKeepalive ka = mCm.createSocketKeepalive( 4373 myNet, testSocketV6, executor, callback)) { 4374 ka.start(validKaInterval); 4375 callback.expectError(SocketKeepalive.ERROR_INVALID_SOCKET); 4376 } 4377 4378 // Bind the socket address 4379 testSocketV4.bind(new InetSocketAddress(myIPv4, srcPortV4)); 4380 testSocketV6.bind(new InetSocketAddress(myIPv6, srcPortV6)); 4381 4382 // Invalid Socket (socket is bound with IPv4 address). 4383 try (SocketKeepalive ka = mCm.createSocketKeepalive( 4384 myNet, testSocketV4, executor, callback)) { 4385 ka.start(validKaInterval); 4386 callback.expectError(SocketKeepalive.ERROR_INVALID_SOCKET); 4387 } 4388 4389 // Invalid Socket (socket is bound with IPv6 address). 4390 try (SocketKeepalive ka = mCm.createSocketKeepalive( 4391 myNet, testSocketV6, executor, callback)) { 4392 ka.start(validKaInterval); 4393 callback.expectError(SocketKeepalive.ERROR_INVALID_SOCKET); 4394 } 4395 4396 testSocketV4.close(); 4397 testSocketV6.close(); 4398 4399 mWiFiNetworkAgent.disconnect(); 4400 mWiFiNetworkAgent.expectDisconnected(); 4401 mWiFiNetworkAgent = null; 4402 } 4403 doTestNattSocketKeepalivesFdWithExecutor(Executor executor)4404 private void doTestNattSocketKeepalivesFdWithExecutor(Executor executor) throws Exception { 4405 final InetAddress myIPv4 = InetAddress.getByName("192.0.2.129"); 4406 final InetAddress anyIPv4 = InetAddress.getByName("0.0.0.0"); 4407 final InetAddress dstIPv4 = InetAddress.getByName("8.8.8.8"); 4408 final int validKaInterval = 15; 4409 4410 // Prepare the target network. 4411 LinkProperties lp = new LinkProperties(); 4412 lp.setInterfaceName("wlan12"); 4413 lp.addLinkAddress(new LinkAddress(myIPv4, 25)); 4414 lp.addRoute(new RouteInfo(InetAddress.getByName("192.0.2.254"))); 4415 Network myNet = connectKeepaliveNetwork(lp); 4416 mWiFiNetworkAgent.setStartKeepaliveEvent(SocketKeepalive.SUCCESS); 4417 mWiFiNetworkAgent.setStopKeepaliveEvent(SocketKeepalive.SUCCESS); 4418 4419 TestSocketKeepaliveCallback callback = new TestSocketKeepaliveCallback(executor); 4420 4421 // Prepare the target file descriptor, keep only one instance. 4422 final IpSecManager mIpSec = (IpSecManager) mContext.getSystemService(Context.IPSEC_SERVICE); 4423 final UdpEncapsulationSocket testSocket = mIpSec.openUdpEncapsulationSocket(); 4424 final int srcPort = testSocket.getPort(); 4425 final ParcelFileDescriptor testPfd = 4426 ParcelFileDescriptor.dup(testSocket.getFileDescriptor()); 4427 testSocket.close(); 4428 assertTrue(isUdpPortInUse(srcPort)); 4429 4430 // Start keepalive and explicit make the variable goes out of scope with try-with-resources 4431 // block. 4432 try (SocketKeepalive ka = mCm.createNattKeepalive( 4433 myNet, testPfd, myIPv4, dstIPv4, executor, callback)) { 4434 ka.start(validKaInterval); 4435 callback.expectStarted(); 4436 ka.stop(); 4437 callback.expectStopped(); 4438 } 4439 4440 // Check that the ParcelFileDescriptor is still valid after keepalive stopped, 4441 // ErrnoException with EBADF will be thrown if the socket is closed when checking local 4442 // address. 4443 assertTrue(isUdpPortInUse(srcPort)); 4444 final InetSocketAddress sa = 4445 (InetSocketAddress) Os.getsockname(testPfd.getFileDescriptor()); 4446 assertEquals(anyIPv4, sa.getAddress()); 4447 4448 testPfd.close(); 4449 // TODO: enable this check after ensuring a valid free port. See b/129512753#comment7. 4450 // assertFalse(isUdpPortInUse(srcPort)); 4451 4452 mWiFiNetworkAgent.disconnect(); 4453 mWiFiNetworkAgent.expectDisconnected(); 4454 mWiFiNetworkAgent = null; 4455 } 4456 isUdpPortInUse(int port)4457 private static boolean isUdpPortInUse(int port) { 4458 try (DatagramSocket ignored = new DatagramSocket(port)) { 4459 return false; 4460 } catch (IOException alreadyInUse) { 4461 return true; 4462 } 4463 } 4464 4465 @Test testGetCaptivePortalServerUrl()4466 public void testGetCaptivePortalServerUrl() throws Exception { 4467 String url = mCm.getCaptivePortalServerUrl(); 4468 assertEquals("http://connectivitycheck.gstatic.com/generate_204", url); 4469 } 4470 4471 private static class TestNetworkPinner extends NetworkPinner { awaitPin(int timeoutMs)4472 public static boolean awaitPin(int timeoutMs) throws InterruptedException { 4473 synchronized(sLock) { 4474 if (sNetwork == null) { 4475 sLock.wait(timeoutMs); 4476 } 4477 return sNetwork != null; 4478 } 4479 } 4480 awaitUnpin(int timeoutMs)4481 public static boolean awaitUnpin(int timeoutMs) throws InterruptedException { 4482 synchronized(sLock) { 4483 if (sNetwork != null) { 4484 sLock.wait(timeoutMs); 4485 } 4486 return sNetwork == null; 4487 } 4488 } 4489 } 4490 assertPinnedToWifiWithCellDefault()4491 private void assertPinnedToWifiWithCellDefault() { 4492 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getBoundNetworkForProcess()); 4493 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 4494 } 4495 assertPinnedToWifiWithWifiDefault()4496 private void assertPinnedToWifiWithWifiDefault() { 4497 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getBoundNetworkForProcess()); 4498 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 4499 } 4500 assertNotPinnedToWifi()4501 private void assertNotPinnedToWifi() { 4502 assertNull(mCm.getBoundNetworkForProcess()); 4503 assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 4504 } 4505 4506 @Test testNetworkPinner()4507 public void testNetworkPinner() throws Exception { 4508 NetworkRequest wifiRequest = new NetworkRequest.Builder() 4509 .addTransportType(TRANSPORT_WIFI) 4510 .build(); 4511 assertNull(mCm.getBoundNetworkForProcess()); 4512 4513 TestNetworkPinner.pin(mServiceContext, wifiRequest); 4514 assertNull(mCm.getBoundNetworkForProcess()); 4515 4516 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 4517 mCellNetworkAgent.connect(true); 4518 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4519 mWiFiNetworkAgent.connect(false); 4520 4521 // When wi-fi connects, expect to be pinned. 4522 assertTrue(TestNetworkPinner.awaitPin(100)); 4523 assertPinnedToWifiWithCellDefault(); 4524 4525 // Disconnect and expect the pin to drop. 4526 mWiFiNetworkAgent.disconnect(); 4527 assertTrue(TestNetworkPinner.awaitUnpin(100)); 4528 assertNotPinnedToWifi(); 4529 4530 // Reconnecting does not cause the pin to come back. 4531 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4532 mWiFiNetworkAgent.connect(false); 4533 assertFalse(TestNetworkPinner.awaitPin(100)); 4534 assertNotPinnedToWifi(); 4535 4536 // Pinning while connected causes the pin to take effect immediately. 4537 TestNetworkPinner.pin(mServiceContext, wifiRequest); 4538 assertTrue(TestNetworkPinner.awaitPin(100)); 4539 assertPinnedToWifiWithCellDefault(); 4540 4541 // Explicitly unpin and expect to use the default network again. 4542 TestNetworkPinner.unpin(); 4543 assertNotPinnedToWifi(); 4544 4545 // Disconnect cell and wifi. 4546 ConditionVariable cv = registerConnectivityBroadcast(3); // cell down, wifi up, wifi down. 4547 mCellNetworkAgent.disconnect(); 4548 mWiFiNetworkAgent.disconnect(); 4549 waitFor(cv); 4550 4551 // Pinning takes effect even if the pinned network is the default when the pin is set... 4552 TestNetworkPinner.pin(mServiceContext, wifiRequest); 4553 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4554 mWiFiNetworkAgent.connect(false); 4555 assertTrue(TestNetworkPinner.awaitPin(100)); 4556 assertPinnedToWifiWithWifiDefault(); 4557 4558 // ... and is maintained even when that network is no longer the default. 4559 cv = registerConnectivityBroadcast(1); 4560 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4561 mCellNetworkAgent.connect(true); 4562 waitFor(cv); 4563 assertPinnedToWifiWithCellDefault(); 4564 } 4565 4566 @Test testNetworkCallbackMaximum()4567 public void testNetworkCallbackMaximum() { 4568 // We can only have 99 callbacks, because MultipathPolicyTracker is 4569 // already one of them. 4570 final int MAX_REQUESTS = 99; 4571 final int CALLBACKS = 89; 4572 final int INTENTS = 10; 4573 assertEquals(MAX_REQUESTS, CALLBACKS + INTENTS); 4574 4575 NetworkRequest networkRequest = new NetworkRequest.Builder().build(); 4576 ArrayList<Object> registered = new ArrayList<>(); 4577 4578 int j = 0; 4579 while (j++ < CALLBACKS / 2) { 4580 NetworkCallback cb = new NetworkCallback(); 4581 mCm.requestNetwork(networkRequest, cb); 4582 registered.add(cb); 4583 } 4584 while (j++ < CALLBACKS) { 4585 NetworkCallback cb = new NetworkCallback(); 4586 mCm.registerNetworkCallback(networkRequest, cb); 4587 registered.add(cb); 4588 } 4589 j = 0; 4590 while (j++ < INTENTS / 2) { 4591 PendingIntent pi = PendingIntent.getBroadcast(mContext, 0, new Intent("a" + j), 0); 4592 mCm.requestNetwork(networkRequest, pi); 4593 registered.add(pi); 4594 } 4595 while (j++ < INTENTS) { 4596 PendingIntent pi = PendingIntent.getBroadcast(mContext, 0, new Intent("b" + j), 0); 4597 mCm.registerNetworkCallback(networkRequest, pi); 4598 registered.add(pi); 4599 } 4600 4601 // Test that the limit is enforced when MAX_REQUESTS simultaneous requests are added. 4602 assertThrows(TooManyRequestsException.class, () -> 4603 mCm.requestNetwork(networkRequest, new NetworkCallback()) 4604 ); 4605 assertThrows(TooManyRequestsException.class, () -> 4606 mCm.registerNetworkCallback(networkRequest, new NetworkCallback()) 4607 ); 4608 assertThrows(TooManyRequestsException.class, () -> 4609 mCm.requestNetwork(networkRequest, 4610 PendingIntent.getBroadcast(mContext, 0, new Intent("c"), 0)) 4611 ); 4612 assertThrows(TooManyRequestsException.class, () -> 4613 mCm.registerNetworkCallback(networkRequest, 4614 PendingIntent.getBroadcast(mContext, 0, new Intent("d"), 0)) 4615 ); 4616 4617 for (Object o : registered) { 4618 if (o instanceof NetworkCallback) { 4619 mCm.unregisterNetworkCallback((NetworkCallback)o); 4620 } 4621 if (o instanceof PendingIntent) { 4622 mCm.unregisterNetworkCallback((PendingIntent)o); 4623 } 4624 } 4625 waitForIdle(); 4626 4627 // Test that the limit is not hit when MAX_REQUESTS requests are added and removed. 4628 for (int i = 0; i < MAX_REQUESTS; i++) { 4629 NetworkCallback networkCallback = new NetworkCallback(); 4630 mCm.requestNetwork(networkRequest, networkCallback); 4631 mCm.unregisterNetworkCallback(networkCallback); 4632 } 4633 waitForIdle(); 4634 4635 for (int i = 0; i < MAX_REQUESTS; i++) { 4636 NetworkCallback networkCallback = new NetworkCallback(); 4637 mCm.registerNetworkCallback(networkRequest, networkCallback); 4638 mCm.unregisterNetworkCallback(networkCallback); 4639 } 4640 waitForIdle(); 4641 4642 for (int i = 0; i < MAX_REQUESTS; i++) { 4643 PendingIntent pendingIntent = 4644 PendingIntent.getBroadcast(mContext, 0, new Intent("e" + i), 0); 4645 mCm.requestNetwork(networkRequest, pendingIntent); 4646 mCm.unregisterNetworkCallback(pendingIntent); 4647 } 4648 waitForIdle(); 4649 4650 for (int i = 0; i < MAX_REQUESTS; i++) { 4651 PendingIntent pendingIntent = 4652 PendingIntent.getBroadcast(mContext, 0, new Intent("f" + i), 0); 4653 mCm.registerNetworkCallback(networkRequest, pendingIntent); 4654 mCm.unregisterNetworkCallback(pendingIntent); 4655 } 4656 } 4657 4658 @Test testNetworkInfoOfTypeNone()4659 public void testNetworkInfoOfTypeNone() throws Exception { 4660 ConditionVariable broadcastCV = registerConnectivityBroadcast(1); 4661 4662 verifyNoNetwork(); 4663 TestNetworkAgentWrapper wifiAware = new TestNetworkAgentWrapper(TRANSPORT_WIFI_AWARE); 4664 assertNull(mCm.getActiveNetworkInfo()); 4665 4666 Network[] allNetworks = mCm.getAllNetworks(); 4667 assertLength(1, allNetworks); 4668 Network network = allNetworks[0]; 4669 NetworkCapabilities capabilities = mCm.getNetworkCapabilities(network); 4670 assertTrue(capabilities.hasTransport(TRANSPORT_WIFI_AWARE)); 4671 4672 final NetworkRequest request = 4673 new NetworkRequest.Builder().addTransportType(TRANSPORT_WIFI_AWARE).build(); 4674 final TestNetworkCallback callback = new TestNetworkCallback(); 4675 mCm.registerNetworkCallback(request, callback); 4676 4677 // Bring up wifi aware network. 4678 wifiAware.connect(false, false, false /* isStrictMode */); 4679 callback.expectAvailableCallbacksUnvalidated(wifiAware); 4680 4681 assertNull(mCm.getActiveNetworkInfo()); 4682 assertNull(mCm.getActiveNetwork()); 4683 // TODO: getAllNetworkInfo is dirty and returns a non-empty array right from the start 4684 // of this test. Fix it and uncomment the assert below. 4685 //assertEmpty(mCm.getAllNetworkInfo()); 4686 4687 // Disconnect wifi aware network. 4688 wifiAware.disconnect(); 4689 callback.expectCallbackThat(TIMEOUT_MS, (info) -> info instanceof CallbackEntry.Lost); 4690 mCm.unregisterNetworkCallback(callback); 4691 4692 verifyNoNetwork(); 4693 if (broadcastCV.block(10)) { 4694 fail("expected no broadcast, but got CONNECTIVITY_ACTION broadcast"); 4695 } 4696 } 4697 4698 @Test testDeprecatedAndUnsupportedOperations()4699 public void testDeprecatedAndUnsupportedOperations() throws Exception { 4700 final int TYPE_NONE = ConnectivityManager.TYPE_NONE; 4701 assertNull(mCm.getNetworkInfo(TYPE_NONE)); 4702 assertNull(mCm.getNetworkForType(TYPE_NONE)); 4703 assertNull(mCm.getLinkProperties(TYPE_NONE)); 4704 assertFalse(mCm.isNetworkSupported(TYPE_NONE)); 4705 4706 assertThrows(IllegalArgumentException.class, 4707 () -> mCm.networkCapabilitiesForType(TYPE_NONE)); 4708 4709 Class<UnsupportedOperationException> unsupported = UnsupportedOperationException.class; 4710 assertThrows(unsupported, () -> mCm.startUsingNetworkFeature(TYPE_WIFI, "")); 4711 assertThrows(unsupported, () -> mCm.stopUsingNetworkFeature(TYPE_WIFI, "")); 4712 // TODO: let test context have configuration application target sdk version 4713 // and test that pre-M requesting for TYPE_NONE sends back APN_REQUEST_FAILED 4714 assertThrows(unsupported, () -> mCm.startUsingNetworkFeature(TYPE_NONE, "")); 4715 assertThrows(unsupported, () -> mCm.stopUsingNetworkFeature(TYPE_NONE, "")); 4716 assertThrows(unsupported, () -> mCm.requestRouteToHostAddress(TYPE_NONE, null)); 4717 } 4718 4719 @Test testLinkPropertiesEnsuresDirectlyConnectedRoutes()4720 public void testLinkPropertiesEnsuresDirectlyConnectedRoutes() throws Exception { 4721 final NetworkRequest networkRequest = new NetworkRequest.Builder() 4722 .addTransportType(TRANSPORT_WIFI).build(); 4723 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 4724 mCm.registerNetworkCallback(networkRequest, networkCallback); 4725 4726 LinkProperties lp = new LinkProperties(); 4727 lp.setInterfaceName(WIFI_IFNAME); 4728 LinkAddress myIpv4Address = new LinkAddress("192.168.12.3/24"); 4729 RouteInfo myIpv4DefaultRoute = new RouteInfo((IpPrefix) null, 4730 NetworkUtils.numericToInetAddress("192.168.12.1"), lp.getInterfaceName()); 4731 lp.addLinkAddress(myIpv4Address); 4732 lp.addRoute(myIpv4DefaultRoute); 4733 4734 // Verify direct routes are added when network agent is first registered in 4735 // ConnectivityService. 4736 TestNetworkAgentWrapper networkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, lp); 4737 networkAgent.connect(true); 4738 networkCallback.expectCallback(CallbackEntry.AVAILABLE, networkAgent); 4739 networkCallback.expectCallback(CallbackEntry.NETWORK_CAPS_UPDATED, networkAgent); 4740 CallbackEntry.LinkPropertiesChanged cbi = 4741 networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, 4742 networkAgent); 4743 networkCallback.expectCallback(CallbackEntry.BLOCKED_STATUS, networkAgent); 4744 networkCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, networkAgent); 4745 networkCallback.assertNoCallback(); 4746 checkDirectlyConnectedRoutes(cbi.getLp(), Arrays.asList(myIpv4Address), 4747 Arrays.asList(myIpv4DefaultRoute)); 4748 checkDirectlyConnectedRoutes(mCm.getLinkProperties(networkAgent.getNetwork()), 4749 Arrays.asList(myIpv4Address), Arrays.asList(myIpv4DefaultRoute)); 4750 4751 // Verify direct routes are added during subsequent link properties updates. 4752 LinkProperties newLp = new LinkProperties(lp); 4753 LinkAddress myIpv6Address1 = new LinkAddress("fe80::cafe/64"); 4754 LinkAddress myIpv6Address2 = new LinkAddress("2001:db8::2/64"); 4755 newLp.addLinkAddress(myIpv6Address1); 4756 newLp.addLinkAddress(myIpv6Address2); 4757 networkAgent.sendLinkProperties(newLp); 4758 cbi = networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, networkAgent); 4759 networkCallback.assertNoCallback(); 4760 checkDirectlyConnectedRoutes(cbi.getLp(), 4761 Arrays.asList(myIpv4Address, myIpv6Address1, myIpv6Address2), 4762 Arrays.asList(myIpv4DefaultRoute)); 4763 mCm.unregisterNetworkCallback(networkCallback); 4764 } 4765 4766 @Test testStatsIfacesChanged()4767 public void testStatsIfacesChanged() throws Exception { 4768 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 4769 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4770 4771 Network[] onlyCell = new Network[] {mCellNetworkAgent.getNetwork()}; 4772 Network[] onlyWifi = new Network[] {mWiFiNetworkAgent.getNetwork()}; 4773 4774 LinkProperties cellLp = new LinkProperties(); 4775 cellLp.setInterfaceName(MOBILE_IFNAME); 4776 LinkProperties wifiLp = new LinkProperties(); 4777 wifiLp.setInterfaceName(WIFI_IFNAME); 4778 4779 // Simple connection should have updated ifaces 4780 mCellNetworkAgent.connect(false); 4781 mCellNetworkAgent.sendLinkProperties(cellLp); 4782 waitForIdle(); 4783 verify(mStatsService, atLeastOnce()) 4784 .forceUpdateIfaces(eq(onlyCell), any(NetworkState[].class), eq(MOBILE_IFNAME), 4785 eq(new VpnInfo[0])); 4786 reset(mStatsService); 4787 4788 // Default network switch should update ifaces. 4789 mWiFiNetworkAgent.connect(false); 4790 mWiFiNetworkAgent.sendLinkProperties(wifiLp); 4791 waitForIdle(); 4792 assertEquals(wifiLp, mService.getActiveLinkProperties()); 4793 verify(mStatsService, atLeastOnce()) 4794 .forceUpdateIfaces(eq(onlyWifi), any(NetworkState[].class), eq(WIFI_IFNAME), 4795 eq(new VpnInfo[0])); 4796 reset(mStatsService); 4797 4798 // Disconnect should update ifaces. 4799 mWiFiNetworkAgent.disconnect(); 4800 waitForIdle(); 4801 verify(mStatsService, atLeastOnce()) 4802 .forceUpdateIfaces(eq(onlyCell), any(NetworkState[].class), 4803 eq(MOBILE_IFNAME), eq(new VpnInfo[0])); 4804 reset(mStatsService); 4805 4806 // Metered change should update ifaces 4807 mCellNetworkAgent.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED); 4808 waitForIdle(); 4809 verify(mStatsService, atLeastOnce()) 4810 .forceUpdateIfaces(eq(onlyCell), any(NetworkState[].class), eq(MOBILE_IFNAME), 4811 eq(new VpnInfo[0])); 4812 reset(mStatsService); 4813 4814 mCellNetworkAgent.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED); 4815 waitForIdle(); 4816 verify(mStatsService, atLeastOnce()) 4817 .forceUpdateIfaces(eq(onlyCell), any(NetworkState[].class), eq(MOBILE_IFNAME), 4818 eq(new VpnInfo[0])); 4819 reset(mStatsService); 4820 4821 // Captive portal change shouldn't update ifaces 4822 mCellNetworkAgent.addCapability(NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL); 4823 waitForIdle(); 4824 verify(mStatsService, never()) 4825 .forceUpdateIfaces(eq(onlyCell), any(NetworkState[].class), eq(MOBILE_IFNAME), 4826 eq(new VpnInfo[0])); 4827 reset(mStatsService); 4828 4829 // Roaming change should update ifaces 4830 mCellNetworkAgent.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING); 4831 waitForIdle(); 4832 verify(mStatsService, atLeastOnce()) 4833 .forceUpdateIfaces(eq(onlyCell), any(NetworkState[].class), eq(MOBILE_IFNAME), 4834 eq(new VpnInfo[0])); 4835 reset(mStatsService); 4836 } 4837 4838 @Test testBasicDnsConfigurationPushed()4839 public void testBasicDnsConfigurationPushed() throws Exception { 4840 setPrivateDnsSettings(PRIVATE_DNS_MODE_OPPORTUNISTIC, "ignored.example.com"); 4841 4842 // Clear any interactions that occur as a result of CS starting up. 4843 reset(mMockDnsResolver); 4844 4845 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 4846 waitForIdle(); 4847 verify(mMockDnsResolver, never()).setResolverConfiguration(any()); 4848 verifyNoMoreInteractions(mMockDnsResolver); 4849 4850 final LinkProperties cellLp = new LinkProperties(); 4851 cellLp.setInterfaceName(MOBILE_IFNAME); 4852 // Add IPv4 and IPv6 default routes, because DNS-over-TLS code does 4853 // "is-reachable" testing in order to not program netd with unreachable 4854 // nameservers that it might try repeated to validate. 4855 cellLp.addLinkAddress(new LinkAddress("192.0.2.4/24")); 4856 cellLp.addRoute(new RouteInfo((IpPrefix) null, InetAddress.getByName("192.0.2.4"), 4857 MOBILE_IFNAME)); 4858 cellLp.addLinkAddress(new LinkAddress("2001:db8:1::1/64")); 4859 cellLp.addRoute(new RouteInfo((IpPrefix) null, InetAddress.getByName("2001:db8:1::1"), 4860 MOBILE_IFNAME)); 4861 mCellNetworkAgent.sendLinkProperties(cellLp); 4862 mCellNetworkAgent.connect(false); 4863 waitForIdle(); 4864 4865 verify(mMockDnsResolver, times(1)).createNetworkCache( 4866 eq(mCellNetworkAgent.getNetwork().netId)); 4867 // CS tells dnsresolver about the empty DNS config for this network. 4868 verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration(any()); 4869 reset(mMockDnsResolver); 4870 4871 cellLp.addDnsServer(InetAddress.getByName("2001:db8::1")); 4872 mCellNetworkAgent.sendLinkProperties(cellLp); 4873 waitForIdle(); 4874 verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration( 4875 mResolverParamsParcelCaptor.capture()); 4876 ResolverParamsParcel resolvrParams = mResolverParamsParcelCaptor.getValue(); 4877 assertEquals(1, resolvrParams.servers.length); 4878 assertTrue(ArrayUtils.contains(resolvrParams.servers, "2001:db8::1")); 4879 // Opportunistic mode. 4880 assertTrue(ArrayUtils.contains(resolvrParams.tlsServers, "2001:db8::1")); 4881 reset(mMockDnsResolver); 4882 4883 cellLp.addDnsServer(InetAddress.getByName("192.0.2.1")); 4884 mCellNetworkAgent.sendLinkProperties(cellLp); 4885 waitForIdle(); 4886 verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration( 4887 mResolverParamsParcelCaptor.capture()); 4888 resolvrParams = mResolverParamsParcelCaptor.getValue(); 4889 assertEquals(2, resolvrParams.servers.length); 4890 assertTrue(ArrayUtils.containsAll(resolvrParams.servers, 4891 new String[]{"2001:db8::1", "192.0.2.1"})); 4892 // Opportunistic mode. 4893 assertEquals(2, resolvrParams.tlsServers.length); 4894 assertTrue(ArrayUtils.containsAll(resolvrParams.tlsServers, 4895 new String[]{"2001:db8::1", "192.0.2.1"})); 4896 reset(mMockDnsResolver); 4897 4898 final String TLS_SPECIFIER = "tls.example.com"; 4899 final String TLS_SERVER6 = "2001:db8:53::53"; 4900 final InetAddress[] TLS_IPS = new InetAddress[]{ InetAddress.getByName(TLS_SERVER6) }; 4901 final String[] TLS_SERVERS = new String[]{ TLS_SERVER6 }; 4902 mCellNetworkAgent.mNmCallbacks.notifyPrivateDnsConfigResolved( 4903 new PrivateDnsConfig(TLS_SPECIFIER, TLS_IPS).toParcel()); 4904 4905 waitForIdle(); 4906 verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration( 4907 mResolverParamsParcelCaptor.capture()); 4908 resolvrParams = mResolverParamsParcelCaptor.getValue(); 4909 assertEquals(2, resolvrParams.servers.length); 4910 assertTrue(ArrayUtils.containsAll(resolvrParams.servers, 4911 new String[]{"2001:db8::1", "192.0.2.1"})); 4912 reset(mMockDnsResolver); 4913 } 4914 4915 @Test testDnsConfigurationTransTypesPushed()4916 public void testDnsConfigurationTransTypesPushed() throws Exception { 4917 // Clear any interactions that occur as a result of CS starting up. 4918 reset(mMockDnsResolver); 4919 4920 final NetworkRequest request = new NetworkRequest.Builder() 4921 .clearCapabilities().addCapability(NET_CAPABILITY_INTERNET) 4922 .build(); 4923 final TestNetworkCallback callback = new TestNetworkCallback(); 4924 mCm.registerNetworkCallback(request, callback); 4925 4926 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4927 mWiFiNetworkAgent.connect(false); 4928 callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 4929 verify(mMockDnsResolver, times(1)).createNetworkCache( 4930 eq(mWiFiNetworkAgent.getNetwork().netId)); 4931 verify(mMockDnsResolver, times(2)).setResolverConfiguration( 4932 mResolverParamsParcelCaptor.capture()); 4933 final ResolverParamsParcel resolverParams = mResolverParamsParcelCaptor.getValue(); 4934 assertContainsExactly(resolverParams.transportTypes, TRANSPORT_WIFI); 4935 reset(mMockDnsResolver); 4936 } 4937 4938 @Test testPrivateDnsNotification()4939 public void testPrivateDnsNotification() throws Exception { 4940 NetworkRequest request = new NetworkRequest.Builder() 4941 .clearCapabilities().addCapability(NET_CAPABILITY_INTERNET) 4942 .build(); 4943 TestNetworkCallback callback = new TestNetworkCallback(); 4944 mCm.registerNetworkCallback(request, callback); 4945 // Bring up wifi. 4946 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4947 mWiFiNetworkAgent.connect(false); 4948 callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 4949 // Private DNS resolution failed, checking if the notification will be shown or not. 4950 mWiFiNetworkAgent.setNetworkInvalid(true /* isStrictMode */); 4951 mWiFiNetworkAgent.mNetworkMonitor.forceReevaluation(Process.myUid()); 4952 waitForIdle(); 4953 // If network validation failed, NetworkMonitor will re-evaluate the network. 4954 // ConnectivityService should filter the redundant notification. This part is trying to 4955 // simulate that situation and check if ConnectivityService could filter that case. 4956 mWiFiNetworkAgent.mNetworkMonitor.forceReevaluation(Process.myUid()); 4957 waitForIdle(); 4958 verify(mNotificationManager, timeout(TIMEOUT_MS).times(1)).notifyAsUser(anyString(), 4959 eq(NotificationType.PRIVATE_DNS_BROKEN.eventId), any(), eq(UserHandle.ALL)); 4960 // If private DNS resolution successful, the PRIVATE_DNS_BROKEN notification shouldn't be 4961 // shown. 4962 mWiFiNetworkAgent.setNetworkValid(true /* isStrictMode */); 4963 mWiFiNetworkAgent.mNetworkMonitor.forceReevaluation(Process.myUid()); 4964 waitForIdle(); 4965 verify(mNotificationManager, timeout(TIMEOUT_MS).times(1)).cancelAsUser(anyString(), 4966 eq(NotificationType.PRIVATE_DNS_BROKEN.eventId), eq(UserHandle.ALL)); 4967 // If private DNS resolution failed again, the PRIVATE_DNS_BROKEN notification should be 4968 // shown again. 4969 mWiFiNetworkAgent.setNetworkInvalid(true /* isStrictMode */); 4970 mWiFiNetworkAgent.mNetworkMonitor.forceReevaluation(Process.myUid()); 4971 waitForIdle(); 4972 verify(mNotificationManager, timeout(TIMEOUT_MS).times(2)).notifyAsUser(anyString(), 4973 eq(NotificationType.PRIVATE_DNS_BROKEN.eventId), any(), eq(UserHandle.ALL)); 4974 } 4975 4976 @Test testPrivateDnsSettingsChange()4977 public void testPrivateDnsSettingsChange() throws Exception { 4978 // Clear any interactions that occur as a result of CS starting up. 4979 reset(mMockDnsResolver); 4980 4981 // The default on Android is opportunistic mode ("Automatic"). 4982 setPrivateDnsSettings(PRIVATE_DNS_MODE_OPPORTUNISTIC, "ignored.example.com"); 4983 4984 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback(); 4985 final NetworkRequest cellRequest = new NetworkRequest.Builder() 4986 .addTransportType(TRANSPORT_CELLULAR).build(); 4987 mCm.requestNetwork(cellRequest, cellNetworkCallback); 4988 4989 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 4990 waitForIdle(); 4991 // CS tells netd about the empty DNS config for this network. 4992 verify(mMockDnsResolver, never()).setResolverConfiguration(any()); 4993 verifyNoMoreInteractions(mMockDnsResolver); 4994 4995 final LinkProperties cellLp = new LinkProperties(); 4996 cellLp.setInterfaceName(MOBILE_IFNAME); 4997 // Add IPv4 and IPv6 default routes, because DNS-over-TLS code does 4998 // "is-reachable" testing in order to not program netd with unreachable 4999 // nameservers that it might try repeated to validate. 5000 cellLp.addLinkAddress(new LinkAddress("192.0.2.4/24")); 5001 cellLp.addRoute(new RouteInfo((IpPrefix) null, InetAddress.getByName("192.0.2.4"), 5002 MOBILE_IFNAME)); 5003 cellLp.addLinkAddress(new LinkAddress("2001:db8:1::1/64")); 5004 cellLp.addRoute(new RouteInfo((IpPrefix) null, InetAddress.getByName("2001:db8:1::1"), 5005 MOBILE_IFNAME)); 5006 cellLp.addDnsServer(InetAddress.getByName("2001:db8::1")); 5007 cellLp.addDnsServer(InetAddress.getByName("192.0.2.1")); 5008 5009 mCellNetworkAgent.sendLinkProperties(cellLp); 5010 mCellNetworkAgent.connect(false); 5011 waitForIdle(); 5012 verify(mMockDnsResolver, times(1)).createNetworkCache( 5013 eq(mCellNetworkAgent.getNetwork().netId)); 5014 verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration( 5015 mResolverParamsParcelCaptor.capture()); 5016 ResolverParamsParcel resolvrParams = mResolverParamsParcelCaptor.getValue(); 5017 assertEquals(2, resolvrParams.tlsServers.length); 5018 assertTrue(ArrayUtils.containsAll(resolvrParams.tlsServers, 5019 new String[] { "2001:db8::1", "192.0.2.1" })); 5020 // Opportunistic mode. 5021 assertEquals(2, resolvrParams.tlsServers.length); 5022 assertTrue(ArrayUtils.containsAll(resolvrParams.tlsServers, 5023 new String[] { "2001:db8::1", "192.0.2.1" })); 5024 reset(mMockDnsResolver); 5025 cellNetworkCallback.expectCallback(CallbackEntry.AVAILABLE, mCellNetworkAgent); 5026 cellNetworkCallback.expectCallback(CallbackEntry.NETWORK_CAPS_UPDATED, 5027 mCellNetworkAgent); 5028 CallbackEntry.LinkPropertiesChanged cbi = cellNetworkCallback.expectCallback( 5029 CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent); 5030 cellNetworkCallback.expectCallback(CallbackEntry.BLOCKED_STATUS, mCellNetworkAgent); 5031 cellNetworkCallback.assertNoCallback(); 5032 assertFalse(cbi.getLp().isPrivateDnsActive()); 5033 assertNull(cbi.getLp().getPrivateDnsServerName()); 5034 5035 setPrivateDnsSettings(PRIVATE_DNS_MODE_OFF, "ignored.example.com"); 5036 verify(mMockDnsResolver, times(1)).setResolverConfiguration( 5037 mResolverParamsParcelCaptor.capture()); 5038 resolvrParams = mResolverParamsParcelCaptor.getValue(); 5039 assertEquals(2, resolvrParams.servers.length); 5040 assertTrue(ArrayUtils.containsAll(resolvrParams.servers, 5041 new String[] { "2001:db8::1", "192.0.2.1" })); 5042 reset(mMockDnsResolver); 5043 cellNetworkCallback.assertNoCallback(); 5044 5045 setPrivateDnsSettings(PRIVATE_DNS_MODE_OPPORTUNISTIC, "ignored.example.com"); 5046 verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration( 5047 mResolverParamsParcelCaptor.capture()); 5048 resolvrParams = mResolverParamsParcelCaptor.getValue(); 5049 assertEquals(2, resolvrParams.servers.length); 5050 assertTrue(ArrayUtils.containsAll(resolvrParams.servers, 5051 new String[] { "2001:db8::1", "192.0.2.1" })); 5052 assertEquals(2, resolvrParams.tlsServers.length); 5053 assertTrue(ArrayUtils.containsAll(resolvrParams.tlsServers, 5054 new String[] { "2001:db8::1", "192.0.2.1" })); 5055 reset(mMockDnsResolver); 5056 cellNetworkCallback.assertNoCallback(); 5057 5058 setPrivateDnsSettings(PRIVATE_DNS_MODE_PROVIDER_HOSTNAME, "strict.example.com"); 5059 // Can't test dns configuration for strict mode without properly mocking 5060 // out the DNS lookups, but can test that LinkProperties is updated. 5061 cbi = cellNetworkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, 5062 mCellNetworkAgent); 5063 cellNetworkCallback.assertNoCallback(); 5064 assertTrue(cbi.getLp().isPrivateDnsActive()); 5065 assertEquals("strict.example.com", cbi.getLp().getPrivateDnsServerName()); 5066 } 5067 5068 @Test testLinkPropertiesWithPrivateDnsValidationEvents()5069 public void testLinkPropertiesWithPrivateDnsValidationEvents() throws Exception { 5070 // The default on Android is opportunistic mode ("Automatic"). 5071 setPrivateDnsSettings(PRIVATE_DNS_MODE_OPPORTUNISTIC, "ignored.example.com"); 5072 5073 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback(); 5074 final NetworkRequest cellRequest = new NetworkRequest.Builder() 5075 .addTransportType(TRANSPORT_CELLULAR).build(); 5076 mCm.requestNetwork(cellRequest, cellNetworkCallback); 5077 5078 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 5079 waitForIdle(); 5080 LinkProperties lp = new LinkProperties(); 5081 mCellNetworkAgent.sendLinkProperties(lp); 5082 mCellNetworkAgent.connect(false); 5083 waitForIdle(); 5084 cellNetworkCallback.expectCallback(CallbackEntry.AVAILABLE, mCellNetworkAgent); 5085 cellNetworkCallback.expectCallback(CallbackEntry.NETWORK_CAPS_UPDATED, 5086 mCellNetworkAgent); 5087 CallbackEntry.LinkPropertiesChanged cbi = cellNetworkCallback.expectCallback( 5088 CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent); 5089 cellNetworkCallback.expectCallback(CallbackEntry.BLOCKED_STATUS, mCellNetworkAgent); 5090 cellNetworkCallback.assertNoCallback(); 5091 assertFalse(cbi.getLp().isPrivateDnsActive()); 5092 assertNull(cbi.getLp().getPrivateDnsServerName()); 5093 Set<InetAddress> dnsServers = new HashSet<>(); 5094 checkDnsServers(cbi.getLp(), dnsServers); 5095 5096 // Send a validation event for a server that is not part of the current 5097 // resolver config. The validation event should be ignored. 5098 mService.mNetdEventCallback.onPrivateDnsValidationEvent( 5099 mCellNetworkAgent.getNetwork().netId, "", "145.100.185.18", true); 5100 cellNetworkCallback.assertNoCallback(); 5101 5102 // Add a dns server to the LinkProperties. 5103 LinkProperties lp2 = new LinkProperties(lp); 5104 lp2.addDnsServer(InetAddress.getByName("145.100.185.16")); 5105 mCellNetworkAgent.sendLinkProperties(lp2); 5106 cbi = cellNetworkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, 5107 mCellNetworkAgent); 5108 cellNetworkCallback.assertNoCallback(); 5109 assertFalse(cbi.getLp().isPrivateDnsActive()); 5110 assertNull(cbi.getLp().getPrivateDnsServerName()); 5111 dnsServers.add(InetAddress.getByName("145.100.185.16")); 5112 checkDnsServers(cbi.getLp(), dnsServers); 5113 5114 // Send a validation event containing a hostname that is not part of 5115 // the current resolver config. The validation event should be ignored. 5116 mService.mNetdEventCallback.onPrivateDnsValidationEvent( 5117 mCellNetworkAgent.getNetwork().netId, "145.100.185.16", "hostname", true); 5118 cellNetworkCallback.assertNoCallback(); 5119 5120 // Send a validation event where validation failed. 5121 mService.mNetdEventCallback.onPrivateDnsValidationEvent( 5122 mCellNetworkAgent.getNetwork().netId, "145.100.185.16", "", false); 5123 cellNetworkCallback.assertNoCallback(); 5124 5125 // Send a validation event where validation succeeded for a server in 5126 // the current resolver config. A LinkProperties callback with updated 5127 // private dns fields should be sent. 5128 mService.mNetdEventCallback.onPrivateDnsValidationEvent( 5129 mCellNetworkAgent.getNetwork().netId, "145.100.185.16", "", true); 5130 cbi = cellNetworkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, 5131 mCellNetworkAgent); 5132 cellNetworkCallback.assertNoCallback(); 5133 assertTrue(cbi.getLp().isPrivateDnsActive()); 5134 assertNull(cbi.getLp().getPrivateDnsServerName()); 5135 checkDnsServers(cbi.getLp(), dnsServers); 5136 5137 // The private dns fields in LinkProperties should be preserved when 5138 // the network agent sends unrelated changes. 5139 LinkProperties lp3 = new LinkProperties(lp2); 5140 lp3.setMtu(1300); 5141 mCellNetworkAgent.sendLinkProperties(lp3); 5142 cbi = cellNetworkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, 5143 mCellNetworkAgent); 5144 cellNetworkCallback.assertNoCallback(); 5145 assertTrue(cbi.getLp().isPrivateDnsActive()); 5146 assertNull(cbi.getLp().getPrivateDnsServerName()); 5147 checkDnsServers(cbi.getLp(), dnsServers); 5148 assertEquals(1300, cbi.getLp().getMtu()); 5149 5150 // Removing the only validated server should affect the private dns 5151 // fields in LinkProperties. 5152 LinkProperties lp4 = new LinkProperties(lp3); 5153 lp4.removeDnsServer(InetAddress.getByName("145.100.185.16")); 5154 mCellNetworkAgent.sendLinkProperties(lp4); 5155 cbi = cellNetworkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, 5156 mCellNetworkAgent); 5157 cellNetworkCallback.assertNoCallback(); 5158 assertFalse(cbi.getLp().isPrivateDnsActive()); 5159 assertNull(cbi.getLp().getPrivateDnsServerName()); 5160 dnsServers.remove(InetAddress.getByName("145.100.185.16")); 5161 checkDnsServers(cbi.getLp(), dnsServers); 5162 assertEquals(1300, cbi.getLp().getMtu()); 5163 } 5164 checkDirectlyConnectedRoutes(Object callbackObj, Collection<LinkAddress> linkAddresses, Collection<RouteInfo> otherRoutes)5165 private void checkDirectlyConnectedRoutes(Object callbackObj, 5166 Collection<LinkAddress> linkAddresses, Collection<RouteInfo> otherRoutes) { 5167 assertTrue(callbackObj instanceof LinkProperties); 5168 LinkProperties lp = (LinkProperties) callbackObj; 5169 5170 Set<RouteInfo> expectedRoutes = new ArraySet<>(); 5171 expectedRoutes.addAll(otherRoutes); 5172 for (LinkAddress address : linkAddresses) { 5173 RouteInfo localRoute = new RouteInfo(address, null, lp.getInterfaceName()); 5174 // Duplicates in linkAddresses are considered failures 5175 assertTrue(expectedRoutes.add(localRoute)); 5176 } 5177 List<RouteInfo> observedRoutes = lp.getRoutes(); 5178 assertEquals(expectedRoutes.size(), observedRoutes.size()); 5179 assertTrue(observedRoutes.containsAll(expectedRoutes)); 5180 } 5181 checkDnsServers(Object callbackObj, Set<InetAddress> dnsServers)5182 private static void checkDnsServers(Object callbackObj, Set<InetAddress> dnsServers) { 5183 assertTrue(callbackObj instanceof LinkProperties); 5184 LinkProperties lp = (LinkProperties) callbackObj; 5185 assertEquals(dnsServers.size(), lp.getDnsServers().size()); 5186 assertTrue(lp.getDnsServers().containsAll(dnsServers)); 5187 } 5188 5189 @Test testVpnNetworkActive()5190 public void testVpnNetworkActive() throws Exception { 5191 final int uid = Process.myUid(); 5192 5193 final TestNetworkCallback genericNetworkCallback = new TestNetworkCallback(); 5194 final TestNetworkCallback genericNotVpnNetworkCallback = new TestNetworkCallback(); 5195 final TestNetworkCallback wifiNetworkCallback = new TestNetworkCallback(); 5196 final TestNetworkCallback vpnNetworkCallback = new TestNetworkCallback(); 5197 final TestNetworkCallback defaultCallback = new TestNetworkCallback(); 5198 final NetworkRequest genericNotVpnRequest = new NetworkRequest.Builder().build(); 5199 final NetworkRequest genericRequest = new NetworkRequest.Builder() 5200 .removeCapability(NET_CAPABILITY_NOT_VPN).build(); 5201 final NetworkRequest wifiRequest = new NetworkRequest.Builder() 5202 .addTransportType(TRANSPORT_WIFI).build(); 5203 final NetworkRequest vpnNetworkRequest = new NetworkRequest.Builder() 5204 .removeCapability(NET_CAPABILITY_NOT_VPN) 5205 .addTransportType(TRANSPORT_VPN).build(); 5206 mCm.registerNetworkCallback(genericRequest, genericNetworkCallback); 5207 mCm.registerNetworkCallback(genericNotVpnRequest, genericNotVpnNetworkCallback); 5208 mCm.registerNetworkCallback(wifiRequest, wifiNetworkCallback); 5209 mCm.registerNetworkCallback(vpnNetworkRequest, vpnNetworkCallback); 5210 mCm.registerDefaultNetworkCallback(defaultCallback); 5211 defaultCallback.assertNoCallback(); 5212 5213 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 5214 mWiFiNetworkAgent.connect(false); 5215 5216 genericNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 5217 genericNotVpnNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 5218 wifiNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 5219 defaultCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 5220 vpnNetworkCallback.assertNoCallback(); 5221 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 5222 5223 final TestNetworkAgentWrapper 5224 vpnNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_VPN); 5225 final ArraySet<UidRange> ranges = new ArraySet<>(); 5226 ranges.add(new UidRange(uid, uid)); 5227 mMockVpn.setNetworkAgent(vpnNetworkAgent); 5228 mMockVpn.setUids(ranges); 5229 // VPN networks do not satisfy the default request and are automatically validated 5230 // by NetworkMonitor 5231 assertFalse(NetworkMonitorUtils.isValidationRequired( 5232 vpnNetworkAgent.getNetworkCapabilities())); 5233 vpnNetworkAgent.setNetworkValid(false /* isStrictMode */); 5234 5235 vpnNetworkAgent.connect(false); 5236 mMockVpn.connect(); 5237 mMockVpn.setUnderlyingNetworks(new Network[0]); 5238 5239 genericNetworkCallback.expectAvailableCallbacksUnvalidated(vpnNetworkAgent); 5240 genericNotVpnNetworkCallback.assertNoCallback(); 5241 wifiNetworkCallback.assertNoCallback(); 5242 vpnNetworkCallback.expectAvailableCallbacksUnvalidated(vpnNetworkAgent); 5243 defaultCallback.expectAvailableCallbacksUnvalidated(vpnNetworkAgent); 5244 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 5245 5246 genericNetworkCallback.expectCallback(CallbackEntry.NETWORK_CAPS_UPDATED, vpnNetworkAgent); 5247 genericNotVpnNetworkCallback.assertNoCallback(); 5248 vpnNetworkCallback.expectCapabilitiesThat(vpnNetworkAgent, nc -> null == nc.getUids()); 5249 defaultCallback.expectCallback(CallbackEntry.NETWORK_CAPS_UPDATED, vpnNetworkAgent); 5250 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 5251 5252 ranges.clear(); 5253 vpnNetworkAgent.setUids(ranges); 5254 5255 genericNetworkCallback.expectCallback(CallbackEntry.LOST, vpnNetworkAgent); 5256 genericNotVpnNetworkCallback.assertNoCallback(); 5257 wifiNetworkCallback.assertNoCallback(); 5258 vpnNetworkCallback.expectCallback(CallbackEntry.LOST, vpnNetworkAgent); 5259 5260 // TODO : The default network callback should actually get a LOST call here (also see the 5261 // comment below for AVAILABLE). This is because ConnectivityService does not look at UID 5262 // ranges at all when determining whether a network should be rematched. In practice, VPNs 5263 // can't currently update their UIDs without disconnecting, so this does not matter too 5264 // much, but that is the reason the test here has to check for an update to the 5265 // capabilities instead of the expected LOST then AVAILABLE. 5266 defaultCallback.expectCallback(CallbackEntry.NETWORK_CAPS_UPDATED, vpnNetworkAgent); 5267 5268 ranges.add(new UidRange(uid, uid)); 5269 mMockVpn.setUids(ranges); 5270 vpnNetworkAgent.setUids(ranges); 5271 5272 genericNetworkCallback.expectAvailableCallbacksValidated(vpnNetworkAgent); 5273 genericNotVpnNetworkCallback.assertNoCallback(); 5274 wifiNetworkCallback.assertNoCallback(); 5275 vpnNetworkCallback.expectAvailableCallbacksValidated(vpnNetworkAgent); 5276 // TODO : Here like above, AVAILABLE would be correct, but because this can't actually 5277 // happen outside of the test, ConnectivityService does not rematch callbacks. 5278 defaultCallback.expectCallback(CallbackEntry.NETWORK_CAPS_UPDATED, vpnNetworkAgent); 5279 5280 mWiFiNetworkAgent.disconnect(); 5281 5282 genericNetworkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 5283 genericNotVpnNetworkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 5284 wifiNetworkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 5285 vpnNetworkCallback.assertNoCallback(); 5286 defaultCallback.assertNoCallback(); 5287 5288 vpnNetworkAgent.disconnect(); 5289 5290 genericNetworkCallback.expectCallback(CallbackEntry.LOST, vpnNetworkAgent); 5291 genericNotVpnNetworkCallback.assertNoCallback(); 5292 wifiNetworkCallback.assertNoCallback(); 5293 vpnNetworkCallback.expectCallback(CallbackEntry.LOST, vpnNetworkAgent); 5294 defaultCallback.expectCallback(CallbackEntry.LOST, vpnNetworkAgent); 5295 assertEquals(null, mCm.getActiveNetwork()); 5296 5297 mCm.unregisterNetworkCallback(genericNetworkCallback); 5298 mCm.unregisterNetworkCallback(wifiNetworkCallback); 5299 mCm.unregisterNetworkCallback(vpnNetworkCallback); 5300 mCm.unregisterNetworkCallback(defaultCallback); 5301 } 5302 5303 @Test testVpnWithoutInternet()5304 public void testVpnWithoutInternet() throws Exception { 5305 final int uid = Process.myUid(); 5306 5307 final TestNetworkCallback defaultCallback = new TestNetworkCallback(); 5308 mCm.registerDefaultNetworkCallback(defaultCallback); 5309 5310 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 5311 mWiFiNetworkAgent.connect(true); 5312 5313 defaultCallback.expectAvailableThenValidatedCallbacks(mWiFiNetworkAgent); 5314 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 5315 5316 TestNetworkAgentWrapper 5317 vpnNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_VPN); 5318 final ArraySet<UidRange> ranges = new ArraySet<>(); 5319 ranges.add(new UidRange(uid, uid)); 5320 mMockVpn.setNetworkAgent(vpnNetworkAgent); 5321 mMockVpn.setUids(ranges); 5322 vpnNetworkAgent.connect(true /* validated */, false /* hasInternet */, 5323 false /* isStrictMode */); 5324 mMockVpn.connect(); 5325 5326 defaultCallback.assertNoCallback(); 5327 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 5328 5329 vpnNetworkAgent.disconnect(); 5330 defaultCallback.assertNoCallback(); 5331 5332 mCm.unregisterNetworkCallback(defaultCallback); 5333 } 5334 5335 @Test testVpnWithInternet()5336 public void testVpnWithInternet() throws Exception { 5337 final int uid = Process.myUid(); 5338 5339 final TestNetworkCallback defaultCallback = new TestNetworkCallback(); 5340 mCm.registerDefaultNetworkCallback(defaultCallback); 5341 5342 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 5343 mWiFiNetworkAgent.connect(true); 5344 5345 defaultCallback.expectAvailableThenValidatedCallbacks(mWiFiNetworkAgent); 5346 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 5347 5348 TestNetworkAgentWrapper 5349 vpnNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_VPN); 5350 final ArraySet<UidRange> ranges = new ArraySet<>(); 5351 ranges.add(new UidRange(uid, uid)); 5352 mMockVpn.setNetworkAgent(vpnNetworkAgent); 5353 mMockVpn.setUids(ranges); 5354 vpnNetworkAgent.connect(true /* validated */, true /* hasInternet */, 5355 false /* isStrictMode */); 5356 mMockVpn.connect(); 5357 5358 defaultCallback.expectAvailableThenValidatedCallbacks(vpnNetworkAgent); 5359 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 5360 5361 vpnNetworkAgent.disconnect(); 5362 defaultCallback.expectCallback(CallbackEntry.LOST, vpnNetworkAgent); 5363 defaultCallback.expectAvailableCallbacksValidated(mWiFiNetworkAgent); 5364 5365 mCm.unregisterNetworkCallback(defaultCallback); 5366 } 5367 5368 @Test testVpnUnvalidated()5369 public void testVpnUnvalidated() throws Exception { 5370 final TestNetworkCallback callback = new TestNetworkCallback(); 5371 mCm.registerDefaultNetworkCallback(callback); 5372 5373 // Bring up Ethernet. 5374 mEthernetNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_ETHERNET); 5375 mEthernetNetworkAgent.connect(true); 5376 callback.expectAvailableThenValidatedCallbacks(mEthernetNetworkAgent); 5377 callback.assertNoCallback(); 5378 5379 // Bring up a VPN that has the INTERNET capability, initially unvalidated. 5380 final int uid = Process.myUid(); 5381 final TestNetworkAgentWrapper 5382 vpnNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_VPN); 5383 final ArraySet<UidRange> ranges = new ArraySet<>(); 5384 ranges.add(new UidRange(uid, uid)); 5385 mMockVpn.setNetworkAgent(vpnNetworkAgent); 5386 mMockVpn.setUids(ranges); 5387 vpnNetworkAgent.connect(false /* validated */, true /* hasInternet */, 5388 false /* isStrictMode */); 5389 mMockVpn.connect(); 5390 5391 // Even though the VPN is unvalidated, it becomes the default network for our app. 5392 callback.expectAvailableCallbacksUnvalidated(vpnNetworkAgent); 5393 callback.assertNoCallback(); 5394 5395 assertTrue(vpnNetworkAgent.getScore() > mEthernetNetworkAgent.getScore()); 5396 assertEquals(ConnectivityConstants.VPN_DEFAULT_SCORE, vpnNetworkAgent.getScore()); 5397 assertEquals(vpnNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 5398 5399 NetworkCapabilities nc = mCm.getNetworkCapabilities(vpnNetworkAgent.getNetwork()); 5400 assertFalse(nc.hasCapability(NET_CAPABILITY_VALIDATED)); 5401 assertTrue(nc.hasCapability(NET_CAPABILITY_INTERNET)); 5402 5403 assertFalse(NetworkMonitorUtils.isValidationRequired( 5404 vpnNetworkAgent.getNetworkCapabilities())); 5405 assertTrue(NetworkMonitorUtils.isPrivateDnsValidationRequired( 5406 vpnNetworkAgent.getNetworkCapabilities())); 5407 5408 // Pretend that the VPN network validates. 5409 vpnNetworkAgent.setNetworkValid(false /* isStrictMode */); 5410 vpnNetworkAgent.mNetworkMonitor.forceReevaluation(Process.myUid()); 5411 // Expect to see the validated capability, but no other changes, because the VPN is already 5412 // the default network for the app. 5413 callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, vpnNetworkAgent); 5414 callback.assertNoCallback(); 5415 5416 vpnNetworkAgent.disconnect(); 5417 callback.expectCallback(CallbackEntry.LOST, vpnNetworkAgent); 5418 callback.expectAvailableCallbacksValidated(mEthernetNetworkAgent); 5419 } 5420 5421 @Test testVpnStartsWithUnderlyingCaps()5422 public void testVpnStartsWithUnderlyingCaps() throws Exception { 5423 final int uid = Process.myUid(); 5424 5425 final TestNetworkCallback vpnNetworkCallback = new TestNetworkCallback(); 5426 final NetworkRequest vpnNetworkRequest = new NetworkRequest.Builder() 5427 .removeCapability(NET_CAPABILITY_NOT_VPN) 5428 .addTransportType(TRANSPORT_VPN) 5429 .build(); 5430 mCm.registerNetworkCallback(vpnNetworkRequest, vpnNetworkCallback); 5431 vpnNetworkCallback.assertNoCallback(); 5432 5433 // Connect cell. It will become the default network, and in the absence of setting 5434 // underlying networks explicitly it will become the sole underlying network for the vpn. 5435 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 5436 mCellNetworkAgent.addCapability(NET_CAPABILITY_NOT_SUSPENDED); 5437 mCellNetworkAgent.connect(true); 5438 5439 final TestNetworkAgentWrapper vpnNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_VPN); 5440 final ArraySet<UidRange> ranges = new ArraySet<>(); 5441 ranges.add(new UidRange(uid, uid)); 5442 mMockVpn.setNetworkAgent(vpnNetworkAgent); 5443 mMockVpn.connect(); 5444 mMockVpn.setUids(ranges); 5445 vpnNetworkAgent.connect(true /* validated */, false /* hasInternet */, 5446 false /* isStrictMode */); 5447 5448 vpnNetworkCallback.expectAvailableCallbacks(vpnNetworkAgent.getNetwork(), 5449 false /* suspended */, false /* validated */, false /* blocked */, TIMEOUT_MS); 5450 vpnNetworkCallback.expectCapabilitiesThat(vpnNetworkAgent.getNetwork(), TIMEOUT_MS, 5451 nc -> nc.hasCapability(NET_CAPABILITY_VALIDATED)); 5452 5453 final NetworkCapabilities nc = mCm.getNetworkCapabilities(vpnNetworkAgent.getNetwork()); 5454 assertTrue(nc.hasTransport(TRANSPORT_VPN)); 5455 assertTrue(nc.hasTransport(TRANSPORT_CELLULAR)); 5456 assertFalse(nc.hasTransport(TRANSPORT_WIFI)); 5457 assertTrue(nc.hasCapability(NET_CAPABILITY_VALIDATED)); 5458 assertFalse(nc.hasCapability(NET_CAPABILITY_NOT_METERED)); 5459 assertTrue(nc.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 5460 } 5461 5462 @Test testVpnSetUnderlyingNetworks()5463 public void testVpnSetUnderlyingNetworks() throws Exception { 5464 final int uid = Process.myUid(); 5465 5466 final TestNetworkCallback vpnNetworkCallback = new TestNetworkCallback(); 5467 final NetworkRequest vpnNetworkRequest = new NetworkRequest.Builder() 5468 .removeCapability(NET_CAPABILITY_NOT_VPN) 5469 .addTransportType(TRANSPORT_VPN) 5470 .build(); 5471 NetworkCapabilities nc; 5472 mCm.registerNetworkCallback(vpnNetworkRequest, vpnNetworkCallback); 5473 vpnNetworkCallback.assertNoCallback(); 5474 5475 final TestNetworkAgentWrapper 5476 vpnNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_VPN); 5477 final ArraySet<UidRange> ranges = new ArraySet<>(); 5478 ranges.add(new UidRange(uid, uid)); 5479 mMockVpn.setNetworkAgent(vpnNetworkAgent); 5480 mMockVpn.connect(); 5481 mMockVpn.setUids(ranges); 5482 vpnNetworkAgent.connect(true /* validated */, false /* hasInternet */, 5483 false /* isStrictMode */); 5484 5485 vpnNetworkCallback.expectAvailableThenValidatedCallbacks(vpnNetworkAgent); 5486 nc = mCm.getNetworkCapabilities(vpnNetworkAgent.getNetwork()); 5487 assertTrue(nc.hasTransport(TRANSPORT_VPN)); 5488 assertFalse(nc.hasTransport(TRANSPORT_CELLULAR)); 5489 assertFalse(nc.hasTransport(TRANSPORT_WIFI)); 5490 // For safety reasons a VPN without underlying networks is considered metered. 5491 assertFalse(nc.hasCapability(NET_CAPABILITY_NOT_METERED)); 5492 // A VPN without underlying networks is not suspended. 5493 assertTrue(nc.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 5494 5495 // Connect cell and use it as an underlying network. 5496 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 5497 mCellNetworkAgent.addCapability(NET_CAPABILITY_NOT_SUSPENDED); 5498 mCellNetworkAgent.connect(true); 5499 5500 mService.setUnderlyingNetworksForVpn( 5501 new Network[] { mCellNetworkAgent.getNetwork() }); 5502 5503 vpnNetworkCallback.expectCapabilitiesThat(vpnNetworkAgent, 5504 (caps) -> caps.hasTransport(TRANSPORT_VPN) 5505 && caps.hasTransport(TRANSPORT_CELLULAR) && !caps.hasTransport(TRANSPORT_WIFI) 5506 && !caps.hasCapability(NET_CAPABILITY_NOT_METERED) 5507 && caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 5508 5509 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 5510 mWiFiNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED); 5511 mWiFiNetworkAgent.addCapability(NET_CAPABILITY_NOT_SUSPENDED); 5512 mWiFiNetworkAgent.connect(true); 5513 5514 mService.setUnderlyingNetworksForVpn( 5515 new Network[] { mCellNetworkAgent.getNetwork(), mWiFiNetworkAgent.getNetwork() }); 5516 5517 vpnNetworkCallback.expectCapabilitiesThat(vpnNetworkAgent, 5518 (caps) -> caps.hasTransport(TRANSPORT_VPN) 5519 && caps.hasTransport(TRANSPORT_CELLULAR) && caps.hasTransport(TRANSPORT_WIFI) 5520 && !caps.hasCapability(NET_CAPABILITY_NOT_METERED) 5521 && caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 5522 5523 // Don't disconnect, but note the VPN is not using wifi any more. 5524 mService.setUnderlyingNetworksForVpn( 5525 new Network[] { mCellNetworkAgent.getNetwork() }); 5526 5527 vpnNetworkCallback.expectCapabilitiesThat(vpnNetworkAgent, 5528 (caps) -> caps.hasTransport(TRANSPORT_VPN) 5529 && caps.hasTransport(TRANSPORT_CELLULAR) && !caps.hasTransport(TRANSPORT_WIFI) 5530 && !caps.hasCapability(NET_CAPABILITY_NOT_METERED) 5531 && caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 5532 5533 // Remove NOT_SUSPENDED from the only network and observe VPN is now suspended. 5534 mCellNetworkAgent.removeCapability(NET_CAPABILITY_NOT_SUSPENDED); 5535 vpnNetworkCallback.expectCapabilitiesThat(vpnNetworkAgent, 5536 (caps) -> caps.hasTransport(TRANSPORT_VPN) 5537 && caps.hasTransport(TRANSPORT_CELLULAR) && !caps.hasTransport(TRANSPORT_WIFI) 5538 && !caps.hasCapability(NET_CAPABILITY_NOT_METERED) 5539 && !caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 5540 vpnNetworkCallback.expectCallback(CallbackEntry.SUSPENDED, vpnNetworkAgent); 5541 5542 // Add NOT_SUSPENDED again and observe VPN is no longer suspended. 5543 mCellNetworkAgent.addCapability(NET_CAPABILITY_NOT_SUSPENDED); 5544 vpnNetworkCallback.expectCapabilitiesThat(vpnNetworkAgent, 5545 (caps) -> caps.hasTransport(TRANSPORT_VPN) 5546 && caps.hasTransport(TRANSPORT_CELLULAR) && !caps.hasTransport(TRANSPORT_WIFI) 5547 && !caps.hasCapability(NET_CAPABILITY_NOT_METERED) 5548 && caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 5549 vpnNetworkCallback.expectCallback(CallbackEntry.RESUMED, vpnNetworkAgent); 5550 5551 // Use Wifi but not cell. Note the VPN is now unmetered and not suspended. 5552 mService.setUnderlyingNetworksForVpn( 5553 new Network[] { mWiFiNetworkAgent.getNetwork() }); 5554 5555 vpnNetworkCallback.expectCapabilitiesThat(vpnNetworkAgent, 5556 (caps) -> caps.hasTransport(TRANSPORT_VPN) 5557 && !caps.hasTransport(TRANSPORT_CELLULAR) && caps.hasTransport(TRANSPORT_WIFI) 5558 && caps.hasCapability(NET_CAPABILITY_NOT_METERED) 5559 && caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 5560 5561 // Use both again. 5562 mService.setUnderlyingNetworksForVpn( 5563 new Network[] { mCellNetworkAgent.getNetwork(), mWiFiNetworkAgent.getNetwork() }); 5564 5565 vpnNetworkCallback.expectCapabilitiesThat(vpnNetworkAgent, 5566 (caps) -> caps.hasTransport(TRANSPORT_VPN) 5567 && caps.hasTransport(TRANSPORT_CELLULAR) && caps.hasTransport(TRANSPORT_WIFI) 5568 && !caps.hasCapability(NET_CAPABILITY_NOT_METERED) 5569 && caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 5570 5571 // Cell is suspended again. As WiFi is not, this should not cause a callback. 5572 mCellNetworkAgent.removeCapability(NET_CAPABILITY_NOT_SUSPENDED); 5573 vpnNetworkCallback.assertNoCallback(); 5574 5575 // Stop using WiFi. The VPN is suspended again. 5576 mService.setUnderlyingNetworksForVpn( 5577 new Network[] { mCellNetworkAgent.getNetwork() }); 5578 vpnNetworkCallback.expectCapabilitiesThat(vpnNetworkAgent, 5579 (caps) -> caps.hasTransport(TRANSPORT_VPN) 5580 && caps.hasTransport(TRANSPORT_CELLULAR) 5581 && !caps.hasCapability(NET_CAPABILITY_NOT_METERED) 5582 && !caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 5583 // While the SUSPENDED callback should in theory be sent here, it is not. This is 5584 // a bug in ConnectivityService, but as the SUSPENDED and RESUMED callbacks have never 5585 // been public and are deprecated and slated for removal, there is no sense in spending 5586 // resources fixing this bug now. 5587 5588 // Use both again. 5589 mService.setUnderlyingNetworksForVpn( 5590 new Network[] { mCellNetworkAgent.getNetwork(), mWiFiNetworkAgent.getNetwork() }); 5591 5592 vpnNetworkCallback.expectCapabilitiesThat(vpnNetworkAgent, 5593 (caps) -> caps.hasTransport(TRANSPORT_VPN) 5594 && caps.hasTransport(TRANSPORT_CELLULAR) && caps.hasTransport(TRANSPORT_WIFI) 5595 && !caps.hasCapability(NET_CAPABILITY_NOT_METERED) 5596 && caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 5597 // As above, the RESUMED callback not being sent here is a bug, but not a bug that's 5598 // worth anybody's time to fix. 5599 5600 // Disconnect cell. Receive update without even removing the dead network from the 5601 // underlying networks – it's dead anyway. Not metered any more. 5602 mCellNetworkAgent.disconnect(); 5603 vpnNetworkCallback.expectCapabilitiesThat(vpnNetworkAgent, 5604 (caps) -> caps.hasTransport(TRANSPORT_VPN) 5605 && !caps.hasTransport(TRANSPORT_CELLULAR) && caps.hasTransport(TRANSPORT_WIFI) 5606 && caps.hasCapability(NET_CAPABILITY_NOT_METERED)); 5607 5608 // Disconnect wifi too. No underlying networks means this is now metered. 5609 mWiFiNetworkAgent.disconnect(); 5610 vpnNetworkCallback.expectCapabilitiesThat(vpnNetworkAgent, 5611 (caps) -> caps.hasTransport(TRANSPORT_VPN) 5612 && !caps.hasTransport(TRANSPORT_CELLULAR) && !caps.hasTransport(TRANSPORT_WIFI) 5613 && !caps.hasCapability(NET_CAPABILITY_NOT_METERED)); 5614 5615 mMockVpn.disconnect(); 5616 } 5617 5618 @Test testNullUnderlyingNetworks()5619 public void testNullUnderlyingNetworks() throws Exception { 5620 final int uid = Process.myUid(); 5621 5622 final TestNetworkCallback vpnNetworkCallback = new TestNetworkCallback(); 5623 final NetworkRequest vpnNetworkRequest = new NetworkRequest.Builder() 5624 .removeCapability(NET_CAPABILITY_NOT_VPN) 5625 .addTransportType(TRANSPORT_VPN) 5626 .build(); 5627 NetworkCapabilities nc; 5628 mCm.registerNetworkCallback(vpnNetworkRequest, vpnNetworkCallback); 5629 vpnNetworkCallback.assertNoCallback(); 5630 5631 final TestNetworkAgentWrapper 5632 vpnNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_VPN); 5633 final ArraySet<UidRange> ranges = new ArraySet<>(); 5634 ranges.add(new UidRange(uid, uid)); 5635 mMockVpn.setNetworkAgent(vpnNetworkAgent); 5636 mMockVpn.connect(); 5637 mMockVpn.setUids(ranges); 5638 vpnNetworkAgent.connect(true /* validated */, false /* hasInternet */, 5639 false /* isStrictMode */); 5640 5641 vpnNetworkCallback.expectAvailableThenValidatedCallbacks(vpnNetworkAgent); 5642 nc = mCm.getNetworkCapabilities(vpnNetworkAgent.getNetwork()); 5643 assertTrue(nc.hasTransport(TRANSPORT_VPN)); 5644 assertFalse(nc.hasTransport(TRANSPORT_CELLULAR)); 5645 assertFalse(nc.hasTransport(TRANSPORT_WIFI)); 5646 // By default, VPN is set to track default network (i.e. its underlying networks is null). 5647 // In case of no default network, VPN is considered metered. 5648 assertFalse(nc.hasCapability(NET_CAPABILITY_NOT_METERED)); 5649 5650 // Connect to Cell; Cell is the default network. 5651 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 5652 mCellNetworkAgent.connect(true); 5653 5654 vpnNetworkCallback.expectCapabilitiesThat(vpnNetworkAgent, 5655 (caps) -> caps.hasTransport(TRANSPORT_VPN) 5656 && caps.hasTransport(TRANSPORT_CELLULAR) && !caps.hasTransport(TRANSPORT_WIFI) 5657 && !caps.hasCapability(NET_CAPABILITY_NOT_METERED)); 5658 5659 // Connect to WiFi; WiFi is the new default. 5660 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 5661 mWiFiNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED); 5662 mWiFiNetworkAgent.connect(true); 5663 5664 vpnNetworkCallback.expectCapabilitiesThat(vpnNetworkAgent, 5665 (caps) -> caps.hasTransport(TRANSPORT_VPN) 5666 && !caps.hasTransport(TRANSPORT_CELLULAR) && caps.hasTransport(TRANSPORT_WIFI) 5667 && caps.hasCapability(NET_CAPABILITY_NOT_METERED)); 5668 5669 // Disconnect Cell. The default network did not change, so there shouldn't be any changes in 5670 // the capabilities. 5671 mCellNetworkAgent.disconnect(); 5672 5673 // Disconnect wifi too. Now we have no default network. 5674 mWiFiNetworkAgent.disconnect(); 5675 5676 vpnNetworkCallback.expectCapabilitiesThat(vpnNetworkAgent, 5677 (caps) -> caps.hasTransport(TRANSPORT_VPN) 5678 && !caps.hasTransport(TRANSPORT_CELLULAR) && !caps.hasTransport(TRANSPORT_WIFI) 5679 && !caps.hasCapability(NET_CAPABILITY_NOT_METERED)); 5680 5681 mMockVpn.disconnect(); 5682 } 5683 5684 @Test testIsActiveNetworkMeteredOverWifi()5685 public void testIsActiveNetworkMeteredOverWifi() throws Exception { 5686 // Returns true by default when no network is available. 5687 assertTrue(mCm.isActiveNetworkMetered()); 5688 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 5689 mWiFiNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED); 5690 mWiFiNetworkAgent.connect(true); 5691 waitForIdle(); 5692 5693 assertFalse(mCm.isActiveNetworkMetered()); 5694 } 5695 5696 @Test testIsActiveNetworkMeteredOverCell()5697 public void testIsActiveNetworkMeteredOverCell() throws Exception { 5698 // Returns true by default when no network is available. 5699 assertTrue(mCm.isActiveNetworkMetered()); 5700 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 5701 mCellNetworkAgent.removeCapability(NET_CAPABILITY_NOT_METERED); 5702 mCellNetworkAgent.connect(true); 5703 waitForIdle(); 5704 5705 assertTrue(mCm.isActiveNetworkMetered()); 5706 } 5707 5708 @Test testIsActiveNetworkMeteredOverVpnTrackingPlatformDefault()5709 public void testIsActiveNetworkMeteredOverVpnTrackingPlatformDefault() throws Exception { 5710 // Returns true by default when no network is available. 5711 assertTrue(mCm.isActiveNetworkMetered()); 5712 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 5713 mCellNetworkAgent.removeCapability(NET_CAPABILITY_NOT_METERED); 5714 mCellNetworkAgent.connect(true); 5715 waitForIdle(); 5716 assertTrue(mCm.isActiveNetworkMetered()); 5717 5718 // Connect VPN network. By default it is using current default network (Cell). 5719 TestNetworkAgentWrapper 5720 vpnNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_VPN); 5721 final ArraySet<UidRange> ranges = new ArraySet<>(); 5722 final int uid = Process.myUid(); 5723 ranges.add(new UidRange(uid, uid)); 5724 mMockVpn.setNetworkAgent(vpnNetworkAgent); 5725 mMockVpn.setUids(ranges); 5726 vpnNetworkAgent.connect(true); 5727 mMockVpn.connect(); 5728 waitForIdle(); 5729 // Ensure VPN is now the active network. 5730 assertEquals(vpnNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 5731 5732 // Expect VPN to be metered. 5733 assertTrue(mCm.isActiveNetworkMetered()); 5734 5735 // Connect WiFi. 5736 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 5737 mWiFiNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED); 5738 mWiFiNetworkAgent.connect(true); 5739 waitForIdle(); 5740 // VPN should still be the active network. 5741 assertEquals(vpnNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 5742 5743 // Expect VPN to be unmetered as it should now be using WiFi (new default). 5744 assertFalse(mCm.isActiveNetworkMetered()); 5745 5746 // Disconnecting Cell should not affect VPN's meteredness. 5747 mCellNetworkAgent.disconnect(); 5748 waitForIdle(); 5749 5750 assertFalse(mCm.isActiveNetworkMetered()); 5751 5752 // Disconnect WiFi; Now there is no platform default network. 5753 mWiFiNetworkAgent.disconnect(); 5754 waitForIdle(); 5755 5756 // VPN without any underlying networks is treated as metered. 5757 assertTrue(mCm.isActiveNetworkMetered()); 5758 5759 vpnNetworkAgent.disconnect(); 5760 mMockVpn.disconnect(); 5761 } 5762 5763 @Test testIsActiveNetworkMeteredOverVpnSpecifyingUnderlyingNetworks()5764 public void testIsActiveNetworkMeteredOverVpnSpecifyingUnderlyingNetworks() throws Exception { 5765 // Returns true by default when no network is available. 5766 assertTrue(mCm.isActiveNetworkMetered()); 5767 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 5768 mCellNetworkAgent.removeCapability(NET_CAPABILITY_NOT_METERED); 5769 mCellNetworkAgent.connect(true); 5770 waitForIdle(); 5771 assertTrue(mCm.isActiveNetworkMetered()); 5772 5773 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 5774 mWiFiNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED); 5775 mWiFiNetworkAgent.connect(true); 5776 waitForIdle(); 5777 assertFalse(mCm.isActiveNetworkMetered()); 5778 5779 // Connect VPN network. 5780 TestNetworkAgentWrapper 5781 vpnNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_VPN); 5782 final ArraySet<UidRange> ranges = new ArraySet<>(); 5783 final int uid = Process.myUid(); 5784 ranges.add(new UidRange(uid, uid)); 5785 mMockVpn.setNetworkAgent(vpnNetworkAgent); 5786 mMockVpn.setUids(ranges); 5787 vpnNetworkAgent.connect(true); 5788 mMockVpn.connect(); 5789 waitForIdle(); 5790 // Ensure VPN is now the active network. 5791 assertEquals(vpnNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 5792 // VPN is using Cell 5793 mService.setUnderlyingNetworksForVpn( 5794 new Network[] { mCellNetworkAgent.getNetwork() }); 5795 waitForIdle(); 5796 5797 // Expect VPN to be metered. 5798 assertTrue(mCm.isActiveNetworkMetered()); 5799 5800 // VPN is now using WiFi 5801 mService.setUnderlyingNetworksForVpn( 5802 new Network[] { mWiFiNetworkAgent.getNetwork() }); 5803 waitForIdle(); 5804 5805 // Expect VPN to be unmetered 5806 assertFalse(mCm.isActiveNetworkMetered()); 5807 5808 // VPN is using Cell | WiFi. 5809 mService.setUnderlyingNetworksForVpn( 5810 new Network[] { mCellNetworkAgent.getNetwork(), mWiFiNetworkAgent.getNetwork() }); 5811 waitForIdle(); 5812 5813 // Expect VPN to be metered. 5814 assertTrue(mCm.isActiveNetworkMetered()); 5815 5816 // VPN is using WiFi | Cell. 5817 mService.setUnderlyingNetworksForVpn( 5818 new Network[] { mWiFiNetworkAgent.getNetwork(), mCellNetworkAgent.getNetwork() }); 5819 waitForIdle(); 5820 5821 // Order should not matter and VPN should still be metered. 5822 assertTrue(mCm.isActiveNetworkMetered()); 5823 5824 // VPN is not using any underlying networks. 5825 mService.setUnderlyingNetworksForVpn(new Network[0]); 5826 waitForIdle(); 5827 5828 // VPN without underlying networks is treated as metered. 5829 assertTrue(mCm.isActiveNetworkMetered()); 5830 5831 vpnNetworkAgent.disconnect(); 5832 mMockVpn.disconnect(); 5833 } 5834 5835 @Test testIsActiveNetworkMeteredOverAlwaysMeteredVpn()5836 public void testIsActiveNetworkMeteredOverAlwaysMeteredVpn() throws Exception { 5837 // Returns true by default when no network is available. 5838 assertTrue(mCm.isActiveNetworkMetered()); 5839 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 5840 mWiFiNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED); 5841 mWiFiNetworkAgent.connect(true); 5842 waitForIdle(); 5843 assertFalse(mCm.isActiveNetworkMetered()); 5844 5845 // Connect VPN network. 5846 TestNetworkAgentWrapper 5847 vpnNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_VPN); 5848 final ArraySet<UidRange> ranges = new ArraySet<>(); 5849 final int uid = Process.myUid(); 5850 ranges.add(new UidRange(uid, uid)); 5851 mMockVpn.setNetworkAgent(vpnNetworkAgent); 5852 mMockVpn.setUids(ranges); 5853 vpnNetworkAgent.connect(true); 5854 mMockVpn.connectAsAlwaysMetered(); 5855 waitForIdle(); 5856 assertEquals(vpnNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 5857 5858 // VPN is tracking current platform default (WiFi). 5859 mService.setUnderlyingNetworksForVpn(null); 5860 waitForIdle(); 5861 5862 // Despite VPN using WiFi (which is unmetered), VPN itself is marked as always metered. 5863 assertTrue(mCm.isActiveNetworkMetered()); 5864 5865 // VPN explicitly declares WiFi as its underlying network. 5866 mService.setUnderlyingNetworksForVpn( 5867 new Network[] { mWiFiNetworkAgent.getNetwork() }); 5868 waitForIdle(); 5869 5870 // Doesn't really matter whether VPN declares its underlying networks explicitly. 5871 assertTrue(mCm.isActiveNetworkMetered()); 5872 5873 // With WiFi lost, VPN is basically without any underlying networks. And in that case it is 5874 // anyways suppose to be metered. 5875 mWiFiNetworkAgent.disconnect(); 5876 waitForIdle(); 5877 5878 assertTrue(mCm.isActiveNetworkMetered()); 5879 5880 vpnNetworkAgent.disconnect(); 5881 } 5882 5883 @Test testNetworkBlockedStatus()5884 public void testNetworkBlockedStatus() throws Exception { 5885 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback(); 5886 final NetworkRequest cellRequest = new NetworkRequest.Builder() 5887 .addTransportType(TRANSPORT_CELLULAR) 5888 .build(); 5889 mCm.registerNetworkCallback(cellRequest, cellNetworkCallback); 5890 5891 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 5892 mCellNetworkAgent.connect(true); 5893 cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 5894 5895 setUidRulesChanged(RULE_REJECT_ALL); 5896 cellNetworkCallback.expectBlockedStatusCallback(true, mCellNetworkAgent); 5897 5898 // ConnectivityService should cache it not to invoke the callback again. 5899 setUidRulesChanged(RULE_REJECT_METERED); 5900 cellNetworkCallback.assertNoCallback(); 5901 5902 setUidRulesChanged(RULE_NONE); 5903 cellNetworkCallback.expectBlockedStatusCallback(false, mCellNetworkAgent); 5904 5905 setUidRulesChanged(RULE_REJECT_METERED); 5906 cellNetworkCallback.expectBlockedStatusCallback(true, mCellNetworkAgent); 5907 5908 // Restrict the network based on UID rule and NOT_METERED capability change. 5909 mCellNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED); 5910 cellNetworkCallback.expectCapabilitiesWith(NET_CAPABILITY_NOT_METERED, mCellNetworkAgent); 5911 cellNetworkCallback.expectBlockedStatusCallback(false, mCellNetworkAgent); 5912 mCellNetworkAgent.removeCapability(NET_CAPABILITY_NOT_METERED); 5913 cellNetworkCallback.expectCapabilitiesWithout(NET_CAPABILITY_NOT_METERED, 5914 mCellNetworkAgent); 5915 cellNetworkCallback.expectBlockedStatusCallback(true, mCellNetworkAgent); 5916 setUidRulesChanged(RULE_ALLOW_METERED); 5917 cellNetworkCallback.expectBlockedStatusCallback(false, mCellNetworkAgent); 5918 5919 setUidRulesChanged(RULE_NONE); 5920 cellNetworkCallback.assertNoCallback(); 5921 5922 // Restrict the network based on BackgroundRestricted. 5923 setRestrictBackgroundChanged(true); 5924 cellNetworkCallback.expectBlockedStatusCallback(true, mCellNetworkAgent); 5925 setRestrictBackgroundChanged(true); 5926 cellNetworkCallback.assertNoCallback(); 5927 setRestrictBackgroundChanged(false); 5928 cellNetworkCallback.expectBlockedStatusCallback(false, mCellNetworkAgent); 5929 cellNetworkCallback.assertNoCallback(); 5930 5931 mCm.unregisterNetworkCallback(cellNetworkCallback); 5932 } 5933 5934 @Test testNetworkBlockedStatusBeforeAndAfterConnect()5935 public void testNetworkBlockedStatusBeforeAndAfterConnect() throws Exception { 5936 final TestNetworkCallback defaultCallback = new TestNetworkCallback(); 5937 mCm.registerDefaultNetworkCallback(defaultCallback); 5938 5939 // No Networkcallbacks invoked before any network is active. 5940 setUidRulesChanged(RULE_REJECT_ALL); 5941 setUidRulesChanged(RULE_NONE); 5942 setUidRulesChanged(RULE_REJECT_METERED); 5943 defaultCallback.assertNoCallback(); 5944 5945 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 5946 mCellNetworkAgent.connect(true); 5947 defaultCallback.expectAvailableCallbacksUnvalidatedAndBlocked(mCellNetworkAgent); 5948 defaultCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mCellNetworkAgent); 5949 5950 // Allow to use the network after switching to NOT_METERED network. 5951 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 5952 mWiFiNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED); 5953 mWiFiNetworkAgent.connect(true); 5954 defaultCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent); 5955 5956 // Switch to METERED network. Restrict the use of the network. 5957 mWiFiNetworkAgent.disconnect(); 5958 defaultCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 5959 defaultCallback.expectAvailableCallbacksValidatedAndBlocked(mCellNetworkAgent); 5960 5961 // Network becomes NOT_METERED. 5962 mCellNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED); 5963 defaultCallback.expectCapabilitiesWith(NET_CAPABILITY_NOT_METERED, mCellNetworkAgent); 5964 defaultCallback.expectBlockedStatusCallback(false, mCellNetworkAgent); 5965 5966 // Verify there's no Networkcallbacks invoked after data saver on/off. 5967 setRestrictBackgroundChanged(true); 5968 setRestrictBackgroundChanged(false); 5969 defaultCallback.assertNoCallback(); 5970 5971 mCellNetworkAgent.disconnect(); 5972 defaultCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 5973 defaultCallback.assertNoCallback(); 5974 5975 mCm.unregisterNetworkCallback(defaultCallback); 5976 } 5977 5978 @Test testLoseTrusted()5979 public final void testLoseTrusted() throws Exception { 5980 final NetworkRequest trustedRequest = new NetworkRequest.Builder() 5981 .addCapability(NET_CAPABILITY_TRUSTED) 5982 .build(); 5983 final TestNetworkCallback trustedCallback = new TestNetworkCallback(); 5984 mCm.requestNetwork(trustedRequest, trustedCallback); 5985 5986 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 5987 mCellNetworkAgent.connect(true); 5988 trustedCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 5989 verify(mNetworkManagementService).setDefaultNetId(eq(mCellNetworkAgent.getNetwork().netId)); 5990 reset(mNetworkManagementService); 5991 5992 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 5993 mWiFiNetworkAgent.connect(true); 5994 trustedCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent); 5995 verify(mNetworkManagementService).setDefaultNetId(eq(mWiFiNetworkAgent.getNetwork().netId)); 5996 reset(mNetworkManagementService); 5997 5998 mWiFiNetworkAgent.removeCapability(NET_CAPABILITY_TRUSTED); 5999 trustedCallback.expectAvailableCallbacksValidated(mCellNetworkAgent); 6000 verify(mNetworkManagementService).setDefaultNetId(eq(mCellNetworkAgent.getNetwork().netId)); 6001 reset(mNetworkManagementService); 6002 6003 mCellNetworkAgent.removeCapability(NET_CAPABILITY_TRUSTED); 6004 trustedCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 6005 verify(mNetworkManagementService).clearDefaultNetId(); 6006 6007 mCm.unregisterNetworkCallback(trustedCallback); 6008 } 6009 6010 @Ignore // 40%+ flakiness : figure out why and re-enable. 6011 @Test testBatteryStatsNetworkType()6012 public final void testBatteryStatsNetworkType() throws Exception { 6013 final LinkProperties cellLp = new LinkProperties(); 6014 cellLp.setInterfaceName("cell0"); 6015 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp); 6016 mCellNetworkAgent.connect(true); 6017 waitForIdle(); 6018 verify(mBatteryStatsService).noteNetworkInterfaceType(cellLp.getInterfaceName(), 6019 TYPE_MOBILE); 6020 reset(mBatteryStatsService); 6021 6022 final LinkProperties wifiLp = new LinkProperties(); 6023 wifiLp.setInterfaceName("wifi0"); 6024 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, wifiLp); 6025 mWiFiNetworkAgent.connect(true); 6026 waitForIdle(); 6027 verify(mBatteryStatsService).noteNetworkInterfaceType(wifiLp.getInterfaceName(), 6028 TYPE_WIFI); 6029 reset(mBatteryStatsService); 6030 6031 mCellNetworkAgent.disconnect(); 6032 6033 cellLp.setInterfaceName("wifi0"); 6034 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp); 6035 mCellNetworkAgent.connect(true); 6036 waitForIdle(); 6037 verify(mBatteryStatsService).noteNetworkInterfaceType(cellLp.getInterfaceName(), 6038 TYPE_MOBILE); 6039 } 6040 6041 /** 6042 * Make simulated InterfaceConfig for Nat464Xlat to query clat lower layer info. 6043 */ getClatInterfaceConfig(LinkAddress la)6044 private InterfaceConfiguration getClatInterfaceConfig(LinkAddress la) { 6045 InterfaceConfiguration cfg = new InterfaceConfiguration(); 6046 cfg.setHardwareAddress("11:22:33:44:55:66"); 6047 cfg.setLinkAddress(la); 6048 return cfg; 6049 } 6050 6051 /** 6052 * Make expected stack link properties, copied from Nat464Xlat. 6053 */ makeClatLinkProperties(LinkAddress la)6054 private LinkProperties makeClatLinkProperties(LinkAddress la) { 6055 LinkAddress clatAddress = la; 6056 LinkProperties stacked = new LinkProperties(); 6057 stacked.setInterfaceName(CLAT_PREFIX + MOBILE_IFNAME); 6058 RouteInfo ipv4Default = new RouteInfo( 6059 new LinkAddress(Inet4Address.ANY, 0), 6060 clatAddress.getAddress(), CLAT_PREFIX + MOBILE_IFNAME); 6061 stacked.addRoute(ipv4Default); 6062 stacked.addLinkAddress(clatAddress); 6063 return stacked; 6064 } 6065 6066 @Test testStackedLinkProperties()6067 public void testStackedLinkProperties() throws Exception { 6068 final LinkAddress myIpv4 = new LinkAddress("1.2.3.4/24"); 6069 final LinkAddress myIpv6 = new LinkAddress("2001:db8:1::1/64"); 6070 final String kNat64PrefixString = "2001:db8:64:64:64:64::"; 6071 final IpPrefix kNat64Prefix = new IpPrefix(InetAddress.getByName(kNat64PrefixString), 96); 6072 final String kOtherNat64PrefixString = "64:ff9b::"; 6073 final IpPrefix kOtherNat64Prefix = new IpPrefix( 6074 InetAddress.getByName(kOtherNat64PrefixString), 96); 6075 final RouteInfo defaultRoute = new RouteInfo((IpPrefix) null, myIpv6.getAddress(), 6076 MOBILE_IFNAME); 6077 final RouteInfo ipv6Subnet = new RouteInfo(myIpv6, null, MOBILE_IFNAME); 6078 final RouteInfo ipv4Subnet = new RouteInfo(myIpv4, null, MOBILE_IFNAME); 6079 final RouteInfo stackedDefault = new RouteInfo((IpPrefix) null, myIpv4.getAddress(), 6080 CLAT_PREFIX + MOBILE_IFNAME); 6081 6082 final NetworkRequest networkRequest = new NetworkRequest.Builder() 6083 .addTransportType(TRANSPORT_CELLULAR) 6084 .addCapability(NET_CAPABILITY_INTERNET) 6085 .build(); 6086 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 6087 mCm.registerNetworkCallback(networkRequest, networkCallback); 6088 6089 // Prepare ipv6 only link properties. 6090 final LinkProperties cellLp = new LinkProperties(); 6091 cellLp.setInterfaceName(MOBILE_IFNAME); 6092 cellLp.addLinkAddress(myIpv6); 6093 cellLp.addRoute(defaultRoute); 6094 cellLp.addRoute(ipv6Subnet); 6095 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp); 6096 reset(mNetworkManagementService); 6097 reset(mMockDnsResolver); 6098 reset(mMockNetd); 6099 reset(mBatteryStatsService); 6100 6101 // Connect with ipv6 link properties. Expect prefix discovery to be started. 6102 mCellNetworkAgent.connect(true); 6103 final int cellNetId = mCellNetworkAgent.getNetwork().netId; 6104 waitForIdle(); 6105 6106 verify(mMockNetd, times(1)).networkCreatePhysical(eq(cellNetId), anyInt()); 6107 assertRoutesAdded(cellNetId, ipv6Subnet, defaultRoute); 6108 verify(mMockDnsResolver, times(1)).createNetworkCache(eq(cellNetId)); 6109 verify(mBatteryStatsService).noteNetworkInterfaceType(cellLp.getInterfaceName(), 6110 TYPE_MOBILE); 6111 6112 networkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 6113 verify(mMockDnsResolver, times(1)).startPrefix64Discovery(cellNetId); 6114 6115 // Switching default network updates TCP buffer sizes. 6116 verifyTcpBufferSizeChange(ConnectivityService.DEFAULT_TCP_BUFFER_SIZES); 6117 6118 // Add an IPv4 address. Expect prefix discovery to be stopped. Netd doesn't tell us that 6119 // the NAT64 prefix was removed because one was never discovered. 6120 cellLp.addLinkAddress(myIpv4); 6121 mCellNetworkAgent.sendLinkProperties(cellLp); 6122 networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent); 6123 assertRoutesAdded(cellNetId, ipv4Subnet); 6124 verify(mMockDnsResolver, times(1)).stopPrefix64Discovery(cellNetId); 6125 verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration(any()); 6126 6127 // Make sure BatteryStats was not told about any v4- interfaces, as none should have 6128 // come online yet. 6129 waitForIdle(); 6130 verify(mBatteryStatsService, never()).noteNetworkInterfaceType(startsWith("v4-"), anyInt()); 6131 6132 verifyNoMoreInteractions(mMockNetd); 6133 verifyNoMoreInteractions(mMockDnsResolver); 6134 reset(mNetworkManagementService); 6135 reset(mMockNetd); 6136 reset(mMockDnsResolver); 6137 when(mNetworkManagementService.getInterfaceConfig(CLAT_PREFIX + MOBILE_IFNAME)) 6138 .thenReturn(getClatInterfaceConfig(myIpv4)); 6139 6140 // Remove IPv4 address. Expect prefix discovery to be started again. 6141 cellLp.removeLinkAddress(myIpv4); 6142 mCellNetworkAgent.sendLinkProperties(cellLp); 6143 networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent); 6144 verify(mMockDnsResolver, times(1)).startPrefix64Discovery(cellNetId); 6145 assertRoutesRemoved(cellNetId, ipv4Subnet); 6146 6147 // When NAT64 prefix discovery succeeds, LinkProperties are updated and clatd is started. 6148 Nat464Xlat clat = getNat464Xlat(mCellNetworkAgent); 6149 assertNull(mCm.getLinkProperties(mCellNetworkAgent.getNetwork()).getNat64Prefix()); 6150 mService.mNetdEventCallback.onNat64PrefixEvent(cellNetId, true /* added */, 6151 kNat64PrefixString, 96); 6152 LinkProperties lpBeforeClat = networkCallback.expectCallback( 6153 CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent).getLp(); 6154 assertEquals(0, lpBeforeClat.getStackedLinks().size()); 6155 assertEquals(kNat64Prefix, lpBeforeClat.getNat64Prefix()); 6156 verify(mMockNetd, times(1)).clatdStart(MOBILE_IFNAME, kNat64Prefix.toString()); 6157 6158 // Clat iface comes up. Expect stacked link to be added. 6159 clat.interfaceLinkStateChanged(CLAT_PREFIX + MOBILE_IFNAME, true); 6160 networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent); 6161 List<LinkProperties> stackedLps = mCm.getLinkProperties(mCellNetworkAgent.getNetwork()) 6162 .getStackedLinks(); 6163 assertEquals(makeClatLinkProperties(myIpv4), stackedLps.get(0)); 6164 assertRoutesAdded(cellNetId, stackedDefault); 6165 6166 // Change trivial linkproperties and see if stacked link is preserved. 6167 cellLp.addDnsServer(InetAddress.getByName("8.8.8.8")); 6168 mCellNetworkAgent.sendLinkProperties(cellLp); 6169 networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent); 6170 6171 List<LinkProperties> stackedLpsAfterChange = 6172 mCm.getLinkProperties(mCellNetworkAgent.getNetwork()).getStackedLinks(); 6173 assertNotEquals(stackedLpsAfterChange, Collections.EMPTY_LIST); 6174 assertEquals(makeClatLinkProperties(myIpv4), stackedLpsAfterChange.get(0)); 6175 6176 verify(mMockDnsResolver, times(1)).setResolverConfiguration( 6177 mResolverParamsParcelCaptor.capture()); 6178 ResolverParamsParcel resolvrParams = mResolverParamsParcelCaptor.getValue(); 6179 assertEquals(1, resolvrParams.servers.length); 6180 assertTrue(ArrayUtils.contains(resolvrParams.servers, "8.8.8.8")); 6181 6182 for (final LinkProperties stackedLp : stackedLpsAfterChange) { 6183 verify(mBatteryStatsService).noteNetworkInterfaceType(stackedLp.getInterfaceName(), 6184 TYPE_MOBILE); 6185 } 6186 reset(mMockNetd); 6187 6188 // Change the NAT64 prefix without first removing it. 6189 // Expect clatd to be stopped and started with the new prefix. 6190 mService.mNetdEventCallback.onNat64PrefixEvent(cellNetId, true /* added */, 6191 kOtherNat64PrefixString, 96); 6192 networkCallback.expectLinkPropertiesThat(mCellNetworkAgent, 6193 (lp) -> lp.getStackedLinks().size() == 0); 6194 verify(mMockNetd, times(1)).clatdStop(MOBILE_IFNAME); 6195 assertRoutesRemoved(cellNetId, stackedDefault); 6196 6197 verify(mMockNetd, times(1)).clatdStart(MOBILE_IFNAME, kOtherNat64Prefix.toString()); 6198 networkCallback.expectLinkPropertiesThat(mCellNetworkAgent, 6199 (lp) -> lp.getNat64Prefix().equals(kOtherNat64Prefix)); 6200 clat.interfaceLinkStateChanged(CLAT_PREFIX + MOBILE_IFNAME, true); 6201 networkCallback.expectLinkPropertiesThat(mCellNetworkAgent, 6202 (lp) -> lp.getStackedLinks().size() == 1); 6203 assertRoutesAdded(cellNetId, stackedDefault); 6204 reset(mMockNetd); 6205 6206 // Add ipv4 address, expect that clatd and prefix discovery are stopped and stacked 6207 // linkproperties are cleaned up. 6208 cellLp.addLinkAddress(myIpv4); 6209 cellLp.addRoute(ipv4Subnet); 6210 mCellNetworkAgent.sendLinkProperties(cellLp); 6211 networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent); 6212 assertRoutesAdded(cellNetId, ipv4Subnet); 6213 verify(mMockNetd, times(1)).clatdStop(MOBILE_IFNAME); 6214 verify(mMockDnsResolver, times(1)).stopPrefix64Discovery(cellNetId); 6215 6216 // As soon as stop is called, the linkproperties lose the stacked interface. 6217 networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent); 6218 LinkProperties actualLpAfterIpv4 = mCm.getLinkProperties(mCellNetworkAgent.getNetwork()); 6219 LinkProperties expected = new LinkProperties(cellLp); 6220 expected.setNat64Prefix(kOtherNat64Prefix); 6221 assertEquals(expected, actualLpAfterIpv4); 6222 assertEquals(0, actualLpAfterIpv4.getStackedLinks().size()); 6223 assertRoutesRemoved(cellNetId, stackedDefault); 6224 6225 // The interface removed callback happens but has no effect after stop is called. 6226 clat.interfaceRemoved(CLAT_PREFIX + MOBILE_IFNAME); 6227 networkCallback.assertNoCallback(); 6228 6229 verifyNoMoreInteractions(mMockNetd); 6230 verifyNoMoreInteractions(mMockDnsResolver); 6231 reset(mNetworkManagementService); 6232 reset(mMockNetd); 6233 reset(mMockDnsResolver); 6234 when(mNetworkManagementService.getInterfaceConfig(CLAT_PREFIX + MOBILE_IFNAME)) 6235 .thenReturn(getClatInterfaceConfig(myIpv4)); 6236 6237 // Stopping prefix discovery causes netd to tell us that the NAT64 prefix is gone. 6238 mService.mNetdEventCallback.onNat64PrefixEvent(cellNetId, false /* added */, 6239 kOtherNat64PrefixString, 96); 6240 networkCallback.expectLinkPropertiesThat(mCellNetworkAgent, 6241 (lp) -> lp.getNat64Prefix() == null); 6242 6243 // Remove IPv4 address and expect prefix discovery and clatd to be started again. 6244 cellLp.removeLinkAddress(myIpv4); 6245 cellLp.removeRoute(new RouteInfo(myIpv4, null, MOBILE_IFNAME)); 6246 cellLp.removeDnsServer(InetAddress.getByName("8.8.8.8")); 6247 mCellNetworkAgent.sendLinkProperties(cellLp); 6248 networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent); 6249 assertRoutesRemoved(cellNetId, ipv4Subnet); // Directly-connected routes auto-added. 6250 verify(mMockDnsResolver, times(1)).startPrefix64Discovery(cellNetId); 6251 mService.mNetdEventCallback.onNat64PrefixEvent(cellNetId, true /* added */, 6252 kNat64PrefixString, 96); 6253 networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent); 6254 verify(mMockNetd, times(1)).clatdStart(MOBILE_IFNAME, kNat64Prefix.toString()); 6255 6256 // Clat iface comes up. Expect stacked link to be added. 6257 clat.interfaceLinkStateChanged(CLAT_PREFIX + MOBILE_IFNAME, true); 6258 networkCallback.expectLinkPropertiesThat(mCellNetworkAgent, 6259 (lp) -> lp.getStackedLinks().size() == 1 && lp.getNat64Prefix() != null); 6260 assertRoutesAdded(cellNetId, stackedDefault); 6261 6262 // NAT64 prefix is removed. Expect that clat is stopped. 6263 mService.mNetdEventCallback.onNat64PrefixEvent(cellNetId, false /* added */, 6264 kNat64PrefixString, 96); 6265 networkCallback.expectLinkPropertiesThat(mCellNetworkAgent, 6266 (lp) -> lp.getStackedLinks().size() == 0 && lp.getNat64Prefix() == null); 6267 assertRoutesRemoved(cellNetId, ipv4Subnet, stackedDefault); 6268 6269 // Stop has no effect because clat is already stopped. 6270 verify(mMockNetd, times(1)).clatdStop(MOBILE_IFNAME); 6271 networkCallback.expectLinkPropertiesThat(mCellNetworkAgent, 6272 (lp) -> lp.getStackedLinks().size() == 0); 6273 verifyNoMoreInteractions(mMockNetd); 6274 6275 // Clean up. 6276 mCellNetworkAgent.disconnect(); 6277 networkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 6278 networkCallback.assertNoCallback(); 6279 mCm.unregisterNetworkCallback(networkCallback); 6280 } 6281 expectNat64PrefixChange(TestableNetworkCallback callback, TestNetworkAgentWrapper agent, IpPrefix prefix)6282 private void expectNat64PrefixChange(TestableNetworkCallback callback, 6283 TestNetworkAgentWrapper agent, IpPrefix prefix) { 6284 callback.expectLinkPropertiesThat(agent, x -> Objects.equals(x.getNat64Prefix(), prefix)); 6285 } 6286 6287 @Test testNat64PrefixMultipleSources()6288 public void testNat64PrefixMultipleSources() throws Exception { 6289 final String iface = "wlan0"; 6290 final String pref64FromRaStr = "64:ff9b::"; 6291 final String pref64FromDnsStr = "2001:db8:64::"; 6292 final IpPrefix pref64FromRa = new IpPrefix(InetAddress.getByName(pref64FromRaStr), 96); 6293 final IpPrefix pref64FromDns = new IpPrefix(InetAddress.getByName(pref64FromDnsStr), 96); 6294 final IpPrefix newPref64FromRa = new IpPrefix("2001:db8:64:64:64:64::/96"); 6295 6296 final NetworkRequest request = new NetworkRequest.Builder() 6297 .addCapability(NET_CAPABILITY_INTERNET) 6298 .build(); 6299 final TestNetworkCallback callback = new TestNetworkCallback(); 6300 mCm.registerNetworkCallback(request, callback); 6301 6302 final LinkProperties baseLp = new LinkProperties(); 6303 baseLp.setInterfaceName(iface); 6304 baseLp.addLinkAddress(new LinkAddress("2001:db8:1::1/64")); 6305 baseLp.addDnsServer(InetAddress.getByName("2001:4860:4860::6464")); 6306 6307 reset(mMockNetd, mMockDnsResolver); 6308 InOrder inOrder = inOrder(mMockNetd, mMockDnsResolver); 6309 6310 // If a network already has a NAT64 prefix on connect, clatd is started immediately and 6311 // prefix discovery is never started. 6312 LinkProperties lp = new LinkProperties(baseLp); 6313 lp.setNat64Prefix(pref64FromRa); 6314 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, lp); 6315 mCellNetworkAgent.connect(false); 6316 final Network network = mCellNetworkAgent.getNetwork(); 6317 int netId = network.getNetId(); 6318 callback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent); 6319 inOrder.verify(mMockNetd).clatdStart(iface, pref64FromRa.toString()); 6320 inOrder.verify(mMockDnsResolver).setPrefix64(netId, pref64FromRa.toString()); 6321 inOrder.verify(mMockDnsResolver, never()).startPrefix64Discovery(netId); 6322 callback.assertNoCallback(); 6323 assertEquals(pref64FromRa, mCm.getLinkProperties(network).getNat64Prefix()); 6324 6325 // If the RA prefix is withdrawn, clatd is stopped and prefix discovery is started. 6326 lp.setNat64Prefix(null); 6327 mCellNetworkAgent.sendLinkProperties(lp); 6328 expectNat64PrefixChange(callback, mCellNetworkAgent, null); 6329 inOrder.verify(mMockNetd).clatdStop(iface); 6330 inOrder.verify(mMockDnsResolver).setPrefix64(netId, ""); 6331 inOrder.verify(mMockDnsResolver).startPrefix64Discovery(netId); 6332 6333 // If the RA prefix appears while DNS discovery is in progress, discovery is stopped and 6334 // clatd is started with the prefix from the RA. 6335 lp.setNat64Prefix(pref64FromRa); 6336 mCellNetworkAgent.sendLinkProperties(lp); 6337 expectNat64PrefixChange(callback, mCellNetworkAgent, pref64FromRa); 6338 inOrder.verify(mMockNetd).clatdStart(iface, pref64FromRa.toString()); 6339 inOrder.verify(mMockDnsResolver).stopPrefix64Discovery(netId); 6340 inOrder.verify(mMockDnsResolver).setPrefix64(netId, pref64FromRa.toString()); 6341 6342 // Withdraw the RA prefix so we can test the case where an RA prefix appears after DNS 6343 // discovery has succeeded. 6344 lp.setNat64Prefix(null); 6345 mCellNetworkAgent.sendLinkProperties(lp); 6346 expectNat64PrefixChange(callback, mCellNetworkAgent, null); 6347 inOrder.verify(mMockNetd).clatdStop(iface); 6348 inOrder.verify(mMockDnsResolver).setPrefix64(netId, ""); 6349 inOrder.verify(mMockDnsResolver).startPrefix64Discovery(netId); 6350 6351 mService.mNetdEventCallback.onNat64PrefixEvent(netId, true /* added */, 6352 pref64FromDnsStr, 96); 6353 expectNat64PrefixChange(callback, mCellNetworkAgent, pref64FromDns); 6354 inOrder.verify(mMockNetd).clatdStart(iface, pref64FromDns.toString()); 6355 6356 // If an RA advertises the same prefix that was discovered by DNS, nothing happens: prefix 6357 // discovery is not stopped, and there are no callbacks. 6358 lp.setNat64Prefix(pref64FromDns); 6359 mCellNetworkAgent.sendLinkProperties(lp); 6360 callback.assertNoCallback(); 6361 inOrder.verify(mMockNetd, never()).clatdStop(iface); 6362 inOrder.verify(mMockNetd, never()).clatdStart(eq(iface), anyString()); 6363 inOrder.verify(mMockDnsResolver, never()).stopPrefix64Discovery(netId); 6364 inOrder.verify(mMockDnsResolver, never()).startPrefix64Discovery(netId); 6365 inOrder.verify(mMockDnsResolver, never()).setPrefix64(eq(netId), anyString()); 6366 6367 // If the RA is later withdrawn, nothing happens again. 6368 lp.setNat64Prefix(null); 6369 mCellNetworkAgent.sendLinkProperties(lp); 6370 callback.assertNoCallback(); 6371 inOrder.verify(mMockNetd, never()).clatdStop(iface); 6372 inOrder.verify(mMockNetd, never()).clatdStart(eq(iface), anyString()); 6373 inOrder.verify(mMockDnsResolver, never()).stopPrefix64Discovery(netId); 6374 inOrder.verify(mMockDnsResolver, never()).startPrefix64Discovery(netId); 6375 inOrder.verify(mMockDnsResolver, never()).setPrefix64(eq(netId), anyString()); 6376 6377 // If the RA prefix changes, clatd is restarted and prefix discovery is stopped. 6378 lp.setNat64Prefix(pref64FromRa); 6379 mCellNetworkAgent.sendLinkProperties(lp); 6380 expectNat64PrefixChange(callback, mCellNetworkAgent, pref64FromRa); 6381 inOrder.verify(mMockNetd).clatdStop(iface); 6382 inOrder.verify(mMockDnsResolver).stopPrefix64Discovery(netId); 6383 6384 // Stopping prefix discovery results in a prefix removed notification. 6385 mService.mNetdEventCallback.onNat64PrefixEvent(netId, false /* added */, 6386 pref64FromDnsStr, 96); 6387 6388 inOrder.verify(mMockNetd).clatdStart(iface, pref64FromRa.toString()); 6389 inOrder.verify(mMockDnsResolver).setPrefix64(netId, pref64FromRa.toString()); 6390 inOrder.verify(mMockDnsResolver, never()).startPrefix64Discovery(netId); 6391 6392 // If the RA prefix changes, clatd is restarted and prefix discovery is not started. 6393 lp.setNat64Prefix(newPref64FromRa); 6394 mCellNetworkAgent.sendLinkProperties(lp); 6395 expectNat64PrefixChange(callback, mCellNetworkAgent, newPref64FromRa); 6396 inOrder.verify(mMockNetd).clatdStop(iface); 6397 inOrder.verify(mMockDnsResolver).setPrefix64(netId, ""); 6398 inOrder.verify(mMockNetd).clatdStart(iface, newPref64FromRa.toString()); 6399 inOrder.verify(mMockDnsResolver).setPrefix64(netId, newPref64FromRa.toString()); 6400 inOrder.verify(mMockDnsResolver, never()).stopPrefix64Discovery(netId); 6401 inOrder.verify(mMockDnsResolver, never()).startPrefix64Discovery(netId); 6402 6403 // If the RA prefix changes to the same value, nothing happens. 6404 lp.setNat64Prefix(newPref64FromRa); 6405 mCellNetworkAgent.sendLinkProperties(lp); 6406 callback.assertNoCallback(); 6407 assertEquals(newPref64FromRa, mCm.getLinkProperties(network).getNat64Prefix()); 6408 inOrder.verify(mMockNetd, never()).clatdStop(iface); 6409 inOrder.verify(mMockNetd, never()).clatdStart(eq(iface), anyString()); 6410 inOrder.verify(mMockDnsResolver, never()).stopPrefix64Discovery(netId); 6411 inOrder.verify(mMockDnsResolver, never()).startPrefix64Discovery(netId); 6412 inOrder.verify(mMockDnsResolver, never()).setPrefix64(eq(netId), anyString()); 6413 6414 // The transition between no prefix and DNS prefix is tested in testStackedLinkProperties. 6415 6416 // If the same prefix is learned first by DNS and then by RA, and clat is later stopped, 6417 // (e.g., because the network disconnects) setPrefix64(netid, "") is never called. 6418 lp.setNat64Prefix(null); 6419 mCellNetworkAgent.sendLinkProperties(lp); 6420 expectNat64PrefixChange(callback, mCellNetworkAgent, null); 6421 inOrder.verify(mMockNetd).clatdStop(iface); 6422 inOrder.verify(mMockDnsResolver).setPrefix64(netId, ""); 6423 inOrder.verify(mMockDnsResolver).startPrefix64Discovery(netId); 6424 mService.mNetdEventCallback.onNat64PrefixEvent(netId, true /* added */, 6425 pref64FromDnsStr, 96); 6426 expectNat64PrefixChange(callback, mCellNetworkAgent, pref64FromDns); 6427 inOrder.verify(mMockNetd).clatdStart(iface, pref64FromDns.toString()); 6428 inOrder.verify(mMockDnsResolver, never()).setPrefix64(eq(netId), any()); 6429 6430 lp.setNat64Prefix(pref64FromDns); 6431 mCellNetworkAgent.sendLinkProperties(lp); 6432 callback.assertNoCallback(); 6433 inOrder.verify(mMockNetd, never()).clatdStop(iface); 6434 inOrder.verify(mMockNetd, never()).clatdStart(eq(iface), anyString()); 6435 inOrder.verify(mMockDnsResolver, never()).stopPrefix64Discovery(netId); 6436 inOrder.verify(mMockDnsResolver, never()).startPrefix64Discovery(netId); 6437 inOrder.verify(mMockDnsResolver, never()).setPrefix64(eq(netId), anyString()); 6438 6439 // When tearing down a network, clat state is only updated after CALLBACK_LOST is fired, but 6440 // before CONNECTIVITY_ACTION is sent. Wait for CONNECTIVITY_ACTION before verifying that 6441 // clat has been stopped, or the test will be flaky. 6442 ConditionVariable cv = registerConnectivityBroadcast(1); 6443 mCellNetworkAgent.disconnect(); 6444 callback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 6445 waitFor(cv); 6446 6447 inOrder.verify(mMockNetd).clatdStop(iface); 6448 inOrder.verify(mMockDnsResolver).stopPrefix64Discovery(netId); 6449 inOrder.verify(mMockDnsResolver, never()).setPrefix64(eq(netId), anyString()); 6450 6451 mCm.unregisterNetworkCallback(callback); 6452 } 6453 6454 @Test testDataActivityTracking()6455 public void testDataActivityTracking() throws Exception { 6456 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 6457 final NetworkRequest networkRequest = new NetworkRequest.Builder() 6458 .addCapability(NET_CAPABILITY_INTERNET) 6459 .build(); 6460 mCm.registerNetworkCallback(networkRequest, networkCallback); 6461 6462 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 6463 final LinkProperties cellLp = new LinkProperties(); 6464 cellLp.setInterfaceName(MOBILE_IFNAME); 6465 mCellNetworkAgent.sendLinkProperties(cellLp); 6466 reset(mNetworkManagementService); 6467 mCellNetworkAgent.connect(true); 6468 networkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 6469 verify(mNetworkManagementService, times(1)).addIdleTimer(eq(MOBILE_IFNAME), anyInt(), 6470 eq(ConnectivityManager.TYPE_MOBILE)); 6471 6472 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 6473 final LinkProperties wifiLp = new LinkProperties(); 6474 wifiLp.setInterfaceName(WIFI_IFNAME); 6475 mWiFiNetworkAgent.sendLinkProperties(wifiLp); 6476 6477 // Network switch 6478 reset(mNetworkManagementService); 6479 mWiFiNetworkAgent.connect(true); 6480 networkCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 6481 networkCallback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent); 6482 networkCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent); 6483 verify(mNetworkManagementService, times(1)).addIdleTimer(eq(WIFI_IFNAME), anyInt(), 6484 eq(ConnectivityManager.TYPE_WIFI)); 6485 verify(mNetworkManagementService, times(1)).removeIdleTimer(eq(MOBILE_IFNAME)); 6486 6487 // Disconnect wifi and switch back to cell 6488 reset(mNetworkManagementService); 6489 mWiFiNetworkAgent.disconnect(); 6490 networkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); 6491 assertNoCallbacks(networkCallback); 6492 verify(mNetworkManagementService, times(1)).removeIdleTimer(eq(WIFI_IFNAME)); 6493 verify(mNetworkManagementService, times(1)).addIdleTimer(eq(MOBILE_IFNAME), anyInt(), 6494 eq(ConnectivityManager.TYPE_MOBILE)); 6495 6496 // reconnect wifi 6497 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 6498 wifiLp.setInterfaceName(WIFI_IFNAME); 6499 mWiFiNetworkAgent.sendLinkProperties(wifiLp); 6500 mWiFiNetworkAgent.connect(true); 6501 networkCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); 6502 networkCallback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent); 6503 networkCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent); 6504 6505 // Disconnect cell 6506 reset(mNetworkManagementService); 6507 reset(mMockNetd); 6508 mCellNetworkAgent.disconnect(); 6509 networkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 6510 // LOST callback is triggered earlier than removing idle timer. Broadcast should also be 6511 // sent as network being switched. Ensure rule removal for cell will not be triggered 6512 // unexpectedly before network being removed. 6513 waitForIdle(); 6514 verify(mNetworkManagementService, times(0)).removeIdleTimer(eq(MOBILE_IFNAME)); 6515 verify(mMockNetd, times(1)).networkDestroy(eq(mCellNetworkAgent.getNetwork().netId)); 6516 verify(mMockDnsResolver, times(1)) 6517 .destroyNetworkCache(eq(mCellNetworkAgent.getNetwork().netId)); 6518 6519 // Disconnect wifi 6520 ConditionVariable cv = registerConnectivityBroadcast(1); 6521 reset(mNetworkManagementService); 6522 mWiFiNetworkAgent.disconnect(); 6523 waitFor(cv); 6524 verify(mNetworkManagementService, times(1)).removeIdleTimer(eq(WIFI_IFNAME)); 6525 6526 // Clean up 6527 mCm.unregisterNetworkCallback(networkCallback); 6528 } 6529 verifyTcpBufferSizeChange(String tcpBufferSizes)6530 private void verifyTcpBufferSizeChange(String tcpBufferSizes) throws Exception { 6531 String[] values = tcpBufferSizes.split(","); 6532 String rmemValues = String.join(" ", values[0], values[1], values[2]); 6533 String wmemValues = String.join(" ", values[3], values[4], values[5]); 6534 verify(mMockNetd, atLeastOnce()).setTcpRWmemorySize(rmemValues, wmemValues); 6535 reset(mMockNetd); 6536 } 6537 6538 @Test testTcpBufferReset()6539 public void testTcpBufferReset() throws Exception { 6540 final String testTcpBufferSizes = "1,2,3,4,5,6"; 6541 final NetworkRequest networkRequest = new NetworkRequest.Builder() 6542 .addTransportType(TRANSPORT_CELLULAR) 6543 .addCapability(NET_CAPABILITY_INTERNET) 6544 .build(); 6545 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 6546 mCm.registerNetworkCallback(networkRequest, networkCallback); 6547 6548 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 6549 reset(mMockNetd); 6550 // Switching default network updates TCP buffer sizes. 6551 mCellNetworkAgent.connect(false); 6552 networkCallback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent); 6553 verifyTcpBufferSizeChange(ConnectivityService.DEFAULT_TCP_BUFFER_SIZES); 6554 6555 // Change link Properties should have updated tcp buffer size. 6556 LinkProperties lp = new LinkProperties(); 6557 lp.setTcpBufferSizes(testTcpBufferSizes); 6558 mCellNetworkAgent.sendLinkProperties(lp); 6559 networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent); 6560 verifyTcpBufferSizeChange(testTcpBufferSizes); 6561 6562 // Clean up. 6563 mCellNetworkAgent.disconnect(); 6564 networkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); 6565 networkCallback.assertNoCallback(); 6566 mCm.unregisterNetworkCallback(networkCallback); 6567 } 6568 6569 @Test testGetGlobalProxyForNetwork()6570 public void testGetGlobalProxyForNetwork() throws Exception { 6571 final ProxyInfo testProxyInfo = ProxyInfo.buildDirectProxy("test", 8888); 6572 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 6573 final Network wifiNetwork = mWiFiNetworkAgent.getNetwork(); 6574 when(mService.mProxyTracker.getGlobalProxy()).thenReturn(testProxyInfo); 6575 assertEquals(testProxyInfo, mService.getProxyForNetwork(wifiNetwork)); 6576 } 6577 6578 @Test testGetProxyForActiveNetwork()6579 public void testGetProxyForActiveNetwork() throws Exception { 6580 final ProxyInfo testProxyInfo = ProxyInfo.buildDirectProxy("test", 8888); 6581 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 6582 mWiFiNetworkAgent.connect(true); 6583 waitForIdle(); 6584 assertNull(mService.getProxyForNetwork(null)); 6585 6586 final LinkProperties testLinkProperties = new LinkProperties(); 6587 testLinkProperties.setHttpProxy(testProxyInfo); 6588 6589 mWiFiNetworkAgent.sendLinkProperties(testLinkProperties); 6590 waitForIdle(); 6591 6592 assertEquals(testProxyInfo, mService.getProxyForNetwork(null)); 6593 } 6594 6595 @Test testGetProxyForVPN()6596 public void testGetProxyForVPN() throws Exception { 6597 final ProxyInfo testProxyInfo = ProxyInfo.buildDirectProxy("test", 8888); 6598 6599 // Set up a WiFi network with no proxy 6600 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 6601 mWiFiNetworkAgent.connect(true); 6602 waitForIdle(); 6603 assertNull(mService.getProxyForNetwork(null)); 6604 6605 // Set up a VPN network with a proxy 6606 final int uid = Process.myUid(); 6607 final TestNetworkAgentWrapper 6608 vpnNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_VPN); 6609 final ArraySet<UidRange> ranges = new ArraySet<>(); 6610 ranges.add(new UidRange(uid, uid)); 6611 mMockVpn.setUids(ranges); 6612 LinkProperties testLinkProperties = new LinkProperties(); 6613 testLinkProperties.setHttpProxy(testProxyInfo); 6614 vpnNetworkAgent.sendLinkProperties(testLinkProperties); 6615 waitForIdle(); 6616 6617 // Connect to VPN with proxy 6618 mMockVpn.setNetworkAgent(vpnNetworkAgent); 6619 vpnNetworkAgent.connect(true); 6620 mMockVpn.connect(); 6621 waitForIdle(); 6622 6623 // Test that the VPN network returns a proxy, and the WiFi does not. 6624 assertEquals(testProxyInfo, mService.getProxyForNetwork(vpnNetworkAgent.getNetwork())); 6625 assertEquals(testProxyInfo, mService.getProxyForNetwork(null)); 6626 assertNull(mService.getProxyForNetwork(mWiFiNetworkAgent.getNetwork())); 6627 6628 // Test that the VPN network returns no proxy when it is set to null. 6629 testLinkProperties.setHttpProxy(null); 6630 vpnNetworkAgent.sendLinkProperties(testLinkProperties); 6631 waitForIdle(); 6632 assertNull(mService.getProxyForNetwork(vpnNetworkAgent.getNetwork())); 6633 assertNull(mService.getProxyForNetwork(null)); 6634 6635 // Set WiFi proxy and check that the vpn proxy is still null. 6636 testLinkProperties.setHttpProxy(testProxyInfo); 6637 mWiFiNetworkAgent.sendLinkProperties(testLinkProperties); 6638 waitForIdle(); 6639 assertNull(mService.getProxyForNetwork(null)); 6640 6641 // Disconnect from VPN and check that the active network, which is now the WiFi, has the 6642 // correct proxy setting. 6643 vpnNetworkAgent.disconnect(); 6644 waitForIdle(); 6645 assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); 6646 assertEquals(testProxyInfo, mService.getProxyForNetwork(mWiFiNetworkAgent.getNetwork())); 6647 assertEquals(testProxyInfo, mService.getProxyForNetwork(null)); 6648 } 6649 6650 @Test testFullyRoutedVpnResultsInInterfaceFilteringRules()6651 public void testFullyRoutedVpnResultsInInterfaceFilteringRules() throws Exception { 6652 LinkProperties lp = new LinkProperties(); 6653 lp.setInterfaceName("tun0"); 6654 lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), null)); 6655 lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), RTN_UNREACHABLE)); 6656 // The uid range needs to cover the test app so the network is visible to it. 6657 final Set<UidRange> vpnRange = Collections.singleton(UidRange.createForUser(VPN_USER)); 6658 final TestNetworkAgentWrapper vpnNetworkAgent = establishVpn(lp, VPN_UID, vpnRange); 6659 6660 // Connected VPN should have interface rules set up. There are two expected invocations, 6661 // one during VPN uid update, one during VPN LinkProperties update 6662 ArgumentCaptor<int[]> uidCaptor = ArgumentCaptor.forClass(int[].class); 6663 verify(mMockNetd, times(2)).firewallAddUidInterfaceRules(eq("tun0"), uidCaptor.capture()); 6664 assertContainsExactly(uidCaptor.getAllValues().get(0), APP1_UID, APP2_UID); 6665 assertContainsExactly(uidCaptor.getAllValues().get(1), APP1_UID, APP2_UID); 6666 assertTrue(mService.mPermissionMonitor.getVpnUidRanges("tun0").equals(vpnRange)); 6667 6668 vpnNetworkAgent.disconnect(); 6669 waitForIdle(); 6670 6671 // Disconnected VPN should have interface rules removed 6672 verify(mMockNetd).firewallRemoveUidInterfaceRules(uidCaptor.capture()); 6673 assertContainsExactly(uidCaptor.getValue(), APP1_UID, APP2_UID); 6674 assertNull(mService.mPermissionMonitor.getVpnUidRanges("tun0")); 6675 } 6676 6677 @Test testLegacyVpnDoesNotResultInInterfaceFilteringRule()6678 public void testLegacyVpnDoesNotResultInInterfaceFilteringRule() throws Exception { 6679 LinkProperties lp = new LinkProperties(); 6680 lp.setInterfaceName("tun0"); 6681 lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), null)); 6682 lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), null)); 6683 // The uid range needs to cover the test app so the network is visible to it. 6684 final Set<UidRange> vpnRange = Collections.singleton(UidRange.createForUser(VPN_USER)); 6685 final TestNetworkAgentWrapper vpnNetworkAgent = establishVpn( 6686 lp, Process.SYSTEM_UID, vpnRange); 6687 6688 // Legacy VPN should not have interface rules set up 6689 verify(mMockNetd, never()).firewallAddUidInterfaceRules(any(), any()); 6690 } 6691 6692 @Test testLocalIpv4OnlyVpnDoesNotResultInInterfaceFilteringRule()6693 public void testLocalIpv4OnlyVpnDoesNotResultInInterfaceFilteringRule() 6694 throws Exception { 6695 LinkProperties lp = new LinkProperties(); 6696 lp.setInterfaceName("tun0"); 6697 lp.addRoute(new RouteInfo(new IpPrefix("192.0.2.0/24"), null, "tun0")); 6698 lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), RTN_UNREACHABLE)); 6699 // The uid range needs to cover the test app so the network is visible to it. 6700 final Set<UidRange> vpnRange = Collections.singleton(UidRange.createForUser(VPN_USER)); 6701 final TestNetworkAgentWrapper vpnNetworkAgent = establishVpn( 6702 lp, Process.SYSTEM_UID, vpnRange); 6703 6704 // IPv6 unreachable route should not be misinterpreted as a default route 6705 verify(mMockNetd, never()).firewallAddUidInterfaceRules(any(), any()); 6706 } 6707 6708 @Test testVpnHandoverChangesInterfaceFilteringRule()6709 public void testVpnHandoverChangesInterfaceFilteringRule() throws Exception { 6710 LinkProperties lp = new LinkProperties(); 6711 lp.setInterfaceName("tun0"); 6712 lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), null)); 6713 lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), null)); 6714 // The uid range needs to cover the test app so the network is visible to it. 6715 final Set<UidRange> vpnRange = Collections.singleton(UidRange.createForUser(VPN_USER)); 6716 final TestNetworkAgentWrapper vpnNetworkAgent = establishVpn(lp, VPN_UID, vpnRange); 6717 6718 // Connected VPN should have interface rules set up. There are two expected invocations, 6719 // one during VPN uid update, one during VPN LinkProperties update 6720 ArgumentCaptor<int[]> uidCaptor = ArgumentCaptor.forClass(int[].class); 6721 verify(mMockNetd, times(2)).firewallAddUidInterfaceRules(eq("tun0"), uidCaptor.capture()); 6722 assertContainsExactly(uidCaptor.getAllValues().get(0), APP1_UID, APP2_UID); 6723 assertContainsExactly(uidCaptor.getAllValues().get(1), APP1_UID, APP2_UID); 6724 6725 reset(mMockNetd); 6726 InOrder inOrder = inOrder(mMockNetd); 6727 lp.setInterfaceName("tun1"); 6728 vpnNetworkAgent.sendLinkProperties(lp); 6729 waitForIdle(); 6730 // VPN handover (switch to a new interface) should result in rules being updated (old rules 6731 // removed first, then new rules added) 6732 inOrder.verify(mMockNetd).firewallRemoveUidInterfaceRules(uidCaptor.capture()); 6733 assertContainsExactly(uidCaptor.getValue(), APP1_UID, APP2_UID); 6734 inOrder.verify(mMockNetd).firewallAddUidInterfaceRules(eq("tun1"), uidCaptor.capture()); 6735 assertContainsExactly(uidCaptor.getValue(), APP1_UID, APP2_UID); 6736 6737 reset(mMockNetd); 6738 lp = new LinkProperties(); 6739 lp.setInterfaceName("tun1"); 6740 lp.addRoute(new RouteInfo(new IpPrefix("192.0.2.0/24"), null, "tun1")); 6741 vpnNetworkAgent.sendLinkProperties(lp); 6742 waitForIdle(); 6743 // VPN not routing everything should no longer have interface filtering rules 6744 verify(mMockNetd).firewallRemoveUidInterfaceRules(uidCaptor.capture()); 6745 assertContainsExactly(uidCaptor.getValue(), APP1_UID, APP2_UID); 6746 6747 reset(mMockNetd); 6748 lp = new LinkProperties(); 6749 lp.setInterfaceName("tun1"); 6750 lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), RTN_UNREACHABLE)); 6751 lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), null)); 6752 vpnNetworkAgent.sendLinkProperties(lp); 6753 waitForIdle(); 6754 // Back to routing all IPv6 traffic should have filtering rules 6755 verify(mMockNetd).firewallAddUidInterfaceRules(eq("tun1"), uidCaptor.capture()); 6756 assertContainsExactly(uidCaptor.getValue(), APP1_UID, APP2_UID); 6757 } 6758 6759 @Test testUidUpdateChangesInterfaceFilteringRule()6760 public void testUidUpdateChangesInterfaceFilteringRule() throws Exception { 6761 LinkProperties lp = new LinkProperties(); 6762 lp.setInterfaceName("tun0"); 6763 lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), RTN_UNREACHABLE)); 6764 lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), null)); 6765 // The uid range needs to cover the test app so the network is visible to it. 6766 final UidRange vpnRange = UidRange.createForUser(VPN_USER); 6767 final TestNetworkAgentWrapper vpnNetworkAgent = establishVpn(lp, VPN_UID, 6768 Collections.singleton(vpnRange)); 6769 6770 reset(mMockNetd); 6771 InOrder inOrder = inOrder(mMockNetd); 6772 6773 // Update to new range which is old range minus APP1, i.e. only APP2 6774 final Set<UidRange> newRanges = new HashSet<>(Arrays.asList( 6775 new UidRange(vpnRange.start, APP1_UID - 1), 6776 new UidRange(APP1_UID + 1, vpnRange.stop))); 6777 vpnNetworkAgent.setUids(newRanges); 6778 waitForIdle(); 6779 6780 ArgumentCaptor<int[]> uidCaptor = ArgumentCaptor.forClass(int[].class); 6781 // Verify old rules are removed before new rules are added 6782 inOrder.verify(mMockNetd).firewallRemoveUidInterfaceRules(uidCaptor.capture()); 6783 assertContainsExactly(uidCaptor.getValue(), APP1_UID, APP2_UID); 6784 inOrder.verify(mMockNetd).firewallAddUidInterfaceRules(eq("tun0"), uidCaptor.capture()); 6785 assertContainsExactly(uidCaptor.getValue(), APP2_UID); 6786 } 6787 6788 @Test testLinkPropertiesWithWakeOnLanForActiveNetwork()6789 public void testLinkPropertiesWithWakeOnLanForActiveNetwork() throws Exception { 6790 mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 6791 6792 LinkProperties wifiLp = new LinkProperties(); 6793 wifiLp.setInterfaceName(WIFI_WOL_IFNAME); 6794 wifiLp.setWakeOnLanSupported(false); 6795 6796 // Default network switch should update ifaces. 6797 mWiFiNetworkAgent.connect(false); 6798 mWiFiNetworkAgent.sendLinkProperties(wifiLp); 6799 waitForIdle(); 6800 6801 // ConnectivityService should have changed the WakeOnLanSupported to true 6802 wifiLp.setWakeOnLanSupported(true); 6803 assertEquals(wifiLp, mService.getActiveLinkProperties()); 6804 } 6805 6806 @Test testLegacyExtraInfoSentToNetworkMonitor()6807 public void testLegacyExtraInfoSentToNetworkMonitor() throws Exception { 6808 class TestNetworkAgent extends NetworkAgent { 6809 TestNetworkAgent(Context context, Looper looper, NetworkAgentConfig config) { 6810 super(context, looper, "MockAgent", new NetworkCapabilities(), 6811 new LinkProperties(), 40 , config, null /* provider */); 6812 } 6813 } 6814 final NetworkAgent naNoExtraInfo = new TestNetworkAgent( 6815 mServiceContext, mCsHandlerThread.getLooper(), new NetworkAgentConfig()); 6816 naNoExtraInfo.register(); 6817 verify(mNetworkStack).makeNetworkMonitor(any(), isNull(String.class), any()); 6818 naNoExtraInfo.unregister(); 6819 6820 reset(mNetworkStack); 6821 final NetworkAgentConfig config = 6822 new NetworkAgentConfig.Builder().setLegacyExtraInfo("legacyinfo").build(); 6823 final NetworkAgent naExtraInfo = new TestNetworkAgent( 6824 mServiceContext, mCsHandlerThread.getLooper(), config); 6825 naExtraInfo.register(); 6826 verify(mNetworkStack).makeNetworkMonitor(any(), eq("legacyinfo"), any()); 6827 naExtraInfo.unregister(); 6828 } 6829 setupLocationPermissions( int targetSdk, boolean locationToggle, String op, String perm)6830 private void setupLocationPermissions( 6831 int targetSdk, boolean locationToggle, String op, String perm) throws Exception { 6832 final ApplicationInfo applicationInfo = new ApplicationInfo(); 6833 applicationInfo.targetSdkVersion = targetSdk; 6834 when(mPackageManager.getApplicationInfoAsUser(anyString(), anyInt(), any())) 6835 .thenReturn(applicationInfo); 6836 6837 when(mLocationManager.isLocationEnabledForUser(any())).thenReturn(locationToggle); 6838 6839 if (op != null) { 6840 when(mAppOpsManager.noteOp(eq(op), eq(Process.myUid()), eq(mContext.getPackageName()))) 6841 .thenReturn(AppOpsManager.MODE_ALLOWED); 6842 } 6843 6844 if (perm != null) { 6845 mServiceContext.setPermission(perm, PERMISSION_GRANTED); 6846 } 6847 } 6848 getOwnerUidNetCapsForCallerPermission(int ownerUid, int callerUid)6849 private int getOwnerUidNetCapsForCallerPermission(int ownerUid, int callerUid) { 6850 final NetworkCapabilities netCap = new NetworkCapabilities().setOwnerUid(ownerUid); 6851 6852 return mService 6853 .maybeSanitizeLocationInfoForCaller(netCap, callerUid, mContext.getPackageName()) 6854 .getOwnerUid(); 6855 } 6856 6857 @Test testMaybeSanitizeLocationInfoForCallerWithFineLocationAfterQ()6858 public void testMaybeSanitizeLocationInfoForCallerWithFineLocationAfterQ() throws Exception { 6859 setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION, 6860 Manifest.permission.ACCESS_FINE_LOCATION); 6861 6862 final int myUid = Process.myUid(); 6863 assertEquals(myUid, getOwnerUidNetCapsForCallerPermission(myUid, myUid)); 6864 } 6865 6866 @Test testMaybeSanitizeLocationInfoForCallerWithCoarseLocationPreQ()6867 public void testMaybeSanitizeLocationInfoForCallerWithCoarseLocationPreQ() throws Exception { 6868 setupLocationPermissions(Build.VERSION_CODES.P, true, AppOpsManager.OPSTR_COARSE_LOCATION, 6869 Manifest.permission.ACCESS_COARSE_LOCATION); 6870 6871 final int myUid = Process.myUid(); 6872 assertEquals(myUid, getOwnerUidNetCapsForCallerPermission(myUid, myUid)); 6873 } 6874 6875 @Test testMaybeSanitizeLocationInfoForCallerLocationOff()6876 public void testMaybeSanitizeLocationInfoForCallerLocationOff() throws Exception { 6877 // Test that even with fine location permission, and UIDs matching, the UID is sanitized. 6878 setupLocationPermissions(Build.VERSION_CODES.Q, false, AppOpsManager.OPSTR_FINE_LOCATION, 6879 Manifest.permission.ACCESS_FINE_LOCATION); 6880 6881 final int myUid = Process.myUid(); 6882 assertEquals(Process.INVALID_UID, getOwnerUidNetCapsForCallerPermission(myUid, myUid)); 6883 } 6884 6885 @Test testMaybeSanitizeLocationInfoForCallerWrongUid()6886 public void testMaybeSanitizeLocationInfoForCallerWrongUid() throws Exception { 6887 // Test that even with fine location permission, not being the owner leads to sanitization. 6888 setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION, 6889 Manifest.permission.ACCESS_FINE_LOCATION); 6890 6891 final int myUid = Process.myUid(); 6892 assertEquals(Process.INVALID_UID, getOwnerUidNetCapsForCallerPermission(myUid + 1, myUid)); 6893 } 6894 6895 @Test testMaybeSanitizeLocationInfoForCallerWithCoarseLocationAfterQ()6896 public void testMaybeSanitizeLocationInfoForCallerWithCoarseLocationAfterQ() throws Exception { 6897 // Test that not having fine location permission leads to sanitization. 6898 setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_COARSE_LOCATION, 6899 Manifest.permission.ACCESS_COARSE_LOCATION); 6900 6901 // Test that without the location permission, the owner field is sanitized. 6902 final int myUid = Process.myUid(); 6903 assertEquals(Process.INVALID_UID, getOwnerUidNetCapsForCallerPermission(myUid, myUid)); 6904 } 6905 6906 @Test testMaybeSanitizeLocationInfoForCallerWithoutLocationPermission()6907 public void testMaybeSanitizeLocationInfoForCallerWithoutLocationPermission() throws Exception { 6908 setupLocationPermissions(Build.VERSION_CODES.Q, true, null /* op */, null /* perm */); 6909 6910 // Test that without the location permission, the owner field is sanitized. 6911 final int myUid = Process.myUid(); 6912 assertEquals(Process.INVALID_UID, getOwnerUidNetCapsForCallerPermission(myUid, myUid)); 6913 } 6914 setupConnectionOwnerUid(int vpnOwnerUid, @VpnManager.VpnType int vpnType)6915 private void setupConnectionOwnerUid(int vpnOwnerUid, @VpnManager.VpnType int vpnType) 6916 throws Exception { 6917 final Set<UidRange> vpnRange = Collections.singleton(UidRange.createForUser(VPN_USER)); 6918 establishVpn(new LinkProperties(), vpnOwnerUid, vpnRange); 6919 mMockVpn.setVpnType(vpnType); 6920 6921 final VpnInfo vpnInfo = new VpnInfo(); 6922 vpnInfo.ownerUid = vpnOwnerUid; 6923 mMockVpn.setVpnInfo(vpnInfo); 6924 } 6925 setupConnectionOwnerUidAsVpnApp(int vpnOwnerUid, @VpnManager.VpnType int vpnType)6926 private void setupConnectionOwnerUidAsVpnApp(int vpnOwnerUid, @VpnManager.VpnType int vpnType) 6927 throws Exception { 6928 setupConnectionOwnerUid(vpnOwnerUid, vpnType); 6929 6930 // Test as VPN app 6931 mServiceContext.setPermission(android.Manifest.permission.NETWORK_STACK, PERMISSION_DENIED); 6932 mServiceContext.setPermission( 6933 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, PERMISSION_DENIED); 6934 } 6935 getTestConnectionInfo()6936 private ConnectionInfo getTestConnectionInfo() throws Exception { 6937 return new ConnectionInfo( 6938 IPPROTO_TCP, 6939 new InetSocketAddress(InetAddresses.parseNumericAddress("1.2.3.4"), 1234), 6940 new InetSocketAddress(InetAddresses.parseNumericAddress("2.3.4.5"), 2345)); 6941 } 6942 6943 @Test testGetConnectionOwnerUidPlatformVpn()6944 public void testGetConnectionOwnerUidPlatformVpn() throws Exception { 6945 final int myUid = Process.myUid(); 6946 setupConnectionOwnerUidAsVpnApp(myUid, VpnManager.TYPE_VPN_PLATFORM); 6947 6948 try { 6949 mService.getConnectionOwnerUid(getTestConnectionInfo()); 6950 fail("Expected SecurityException for non-VpnService app"); 6951 } catch (SecurityException expected) { 6952 } 6953 } 6954 6955 @Test testGetConnectionOwnerUidVpnServiceWrongUser()6956 public void testGetConnectionOwnerUidVpnServiceWrongUser() throws Exception { 6957 final int myUid = Process.myUid(); 6958 setupConnectionOwnerUidAsVpnApp(myUid + 1, VpnManager.TYPE_VPN_SERVICE); 6959 6960 try { 6961 mService.getConnectionOwnerUid(getTestConnectionInfo()); 6962 fail("Expected SecurityException for non-VpnService app"); 6963 } catch (SecurityException expected) { 6964 } 6965 } 6966 6967 @Test testGetConnectionOwnerUidVpnServiceDoesNotThrow()6968 public void testGetConnectionOwnerUidVpnServiceDoesNotThrow() throws Exception { 6969 final int myUid = Process.myUid(); 6970 setupConnectionOwnerUidAsVpnApp(myUid, VpnManager.TYPE_VPN_SERVICE); 6971 6972 // TODO: Test the returned UID 6973 mService.getConnectionOwnerUid(getTestConnectionInfo()); 6974 } 6975 6976 @Test testGetConnectionOwnerUidVpnServiceNetworkStackDoesNotThrow()6977 public void testGetConnectionOwnerUidVpnServiceNetworkStackDoesNotThrow() throws Exception { 6978 final int myUid = Process.myUid(); 6979 setupConnectionOwnerUid(myUid, VpnManager.TYPE_VPN_SERVICE); 6980 mServiceContext.setPermission( 6981 android.Manifest.permission.NETWORK_STACK, PERMISSION_GRANTED); 6982 6983 // TODO: Test the returned UID 6984 mService.getConnectionOwnerUid(getTestConnectionInfo()); 6985 } 6986 6987 @Test testGetConnectionOwnerUidVpnServiceMainlineNetworkStackDoesNotThrow()6988 public void testGetConnectionOwnerUidVpnServiceMainlineNetworkStackDoesNotThrow() 6989 throws Exception { 6990 final int myUid = Process.myUid(); 6991 setupConnectionOwnerUid(myUid, VpnManager.TYPE_VPN_SERVICE); 6992 mServiceContext.setPermission( 6993 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, PERMISSION_GRANTED); 6994 6995 // TODO: Test the returned UID 6996 mService.getConnectionOwnerUid(getTestConnectionInfo()); 6997 } 6998 establishVpn( LinkProperties lp, int ownerUid, Set<UidRange> vpnRange)6999 private TestNetworkAgentWrapper establishVpn( 7000 LinkProperties lp, int ownerUid, Set<UidRange> vpnRange) throws Exception { 7001 final TestNetworkAgentWrapper 7002 vpnNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_VPN, lp); 7003 vpnNetworkAgent.getNetworkCapabilities().setOwnerUid(ownerUid); 7004 mMockVpn.setNetworkAgent(vpnNetworkAgent); 7005 mMockVpn.connect(); 7006 mMockVpn.setUids(vpnRange); 7007 vpnNetworkAgent.connect(true); 7008 waitForIdle(); 7009 return vpnNetworkAgent; 7010 } 7011 buildPackageInfo(boolean hasSystemPermission, int uid)7012 private static PackageInfo buildPackageInfo(boolean hasSystemPermission, int uid) { 7013 final PackageInfo packageInfo = new PackageInfo(); 7014 if (hasSystemPermission) { 7015 packageInfo.requestedPermissions = new String[] { 7016 CHANGE_NETWORK_STATE, CONNECTIVITY_USE_RESTRICTED_NETWORKS }; 7017 packageInfo.requestedPermissionsFlags = new int[] { 7018 REQUESTED_PERMISSION_GRANTED, REQUESTED_PERMISSION_GRANTED }; 7019 } else { 7020 packageInfo.requestedPermissions = new String[0]; 7021 } 7022 packageInfo.applicationInfo = new ApplicationInfo(); 7023 packageInfo.applicationInfo.privateFlags = 0; 7024 packageInfo.applicationInfo.uid = UserHandle.getUid(UserHandle.USER_SYSTEM, 7025 UserHandle.getAppId(uid)); 7026 return packageInfo; 7027 } 7028 7029 @Test testRegisterConnectivityDiagnosticsCallbackInvalidRequest()7030 public void testRegisterConnectivityDiagnosticsCallbackInvalidRequest() throws Exception { 7031 final NetworkRequest request = 7032 new NetworkRequest( 7033 new NetworkCapabilities(), TYPE_ETHERNET, 0, NetworkRequest.Type.NONE); 7034 try { 7035 mService.registerConnectivityDiagnosticsCallback( 7036 mConnectivityDiagnosticsCallback, request, mContext.getPackageName()); 7037 fail("registerConnectivityDiagnosticsCallback should throw on invalid NetworkRequest"); 7038 } catch (IllegalArgumentException expected) { 7039 } 7040 } 7041 assertRouteInfoParcelMatches(RouteInfo route, RouteInfoParcel parcel)7042 private void assertRouteInfoParcelMatches(RouteInfo route, RouteInfoParcel parcel) { 7043 assertEquals(route.getDestination().toString(), parcel.destination); 7044 assertEquals(route.getInterface(), parcel.ifName); 7045 assertEquals(route.getMtu(), parcel.mtu); 7046 7047 switch (route.getType()) { 7048 case RouteInfo.RTN_UNICAST: 7049 if (route.hasGateway()) { 7050 assertEquals(route.getGateway().getHostAddress(), parcel.nextHop); 7051 } else { 7052 assertEquals(INetd.NEXTHOP_NONE, parcel.nextHop); 7053 } 7054 break; 7055 case RouteInfo.RTN_UNREACHABLE: 7056 assertEquals(INetd.NEXTHOP_UNREACHABLE, parcel.nextHop); 7057 break; 7058 case RouteInfo.RTN_THROW: 7059 assertEquals(INetd.NEXTHOP_THROW, parcel.nextHop); 7060 break; 7061 default: 7062 assertEquals(INetd.NEXTHOP_NONE, parcel.nextHop); 7063 break; 7064 } 7065 } 7066 assertRoutesAdded(int netId, RouteInfo... routes)7067 private void assertRoutesAdded(int netId, RouteInfo... routes) throws Exception { 7068 ArgumentCaptor<RouteInfoParcel> captor = ArgumentCaptor.forClass(RouteInfoParcel.class); 7069 verify(mMockNetd, times(routes.length)).networkAddRouteParcel(eq(netId), captor.capture()); 7070 for (int i = 0; i < routes.length; i++) { 7071 assertRouteInfoParcelMatches(routes[i], captor.getAllValues().get(i)); 7072 } 7073 } 7074 assertRoutesRemoved(int netId, RouteInfo... routes)7075 private void assertRoutesRemoved(int netId, RouteInfo... routes) throws Exception { 7076 ArgumentCaptor<RouteInfoParcel> captor = ArgumentCaptor.forClass(RouteInfoParcel.class); 7077 verify(mMockNetd, times(routes.length)).networkRemoveRouteParcel(eq(netId), 7078 captor.capture()); 7079 for (int i = 0; i < routes.length; i++) { 7080 assertRouteInfoParcelMatches(routes[i], captor.getAllValues().get(i)); 7081 } 7082 } 7083 7084 @Test testRegisterUnregisterConnectivityDiagnosticsCallback()7085 public void testRegisterUnregisterConnectivityDiagnosticsCallback() throws Exception { 7086 final NetworkRequest wifiRequest = 7087 new NetworkRequest.Builder().addTransportType(TRANSPORT_WIFI).build(); 7088 when(mConnectivityDiagnosticsCallback.asBinder()).thenReturn(mIBinder); 7089 7090 mService.registerConnectivityDiagnosticsCallback( 7091 mConnectivityDiagnosticsCallback, wifiRequest, mContext.getPackageName()); 7092 7093 // Block until all other events are done processing. 7094 HandlerUtilsKt.waitForIdle(mCsHandlerThread, TIMEOUT_MS); 7095 7096 verify(mIBinder).linkToDeath(any(ConnectivityDiagnosticsCallbackInfo.class), anyInt()); 7097 verify(mConnectivityDiagnosticsCallback).asBinder(); 7098 assertTrue(mService.mConnectivityDiagnosticsCallbacks.containsKey(mIBinder)); 7099 7100 mService.unregisterConnectivityDiagnosticsCallback(mConnectivityDiagnosticsCallback); 7101 verify(mIBinder, timeout(TIMEOUT_MS)) 7102 .unlinkToDeath(any(ConnectivityDiagnosticsCallbackInfo.class), anyInt()); 7103 assertFalse(mService.mConnectivityDiagnosticsCallbacks.containsKey(mIBinder)); 7104 verify(mConnectivityDiagnosticsCallback, atLeastOnce()).asBinder(); 7105 } 7106 7107 @Test testRegisterDuplicateConnectivityDiagnosticsCallback()7108 public void testRegisterDuplicateConnectivityDiagnosticsCallback() throws Exception { 7109 final NetworkRequest wifiRequest = 7110 new NetworkRequest.Builder().addTransportType(TRANSPORT_WIFI).build(); 7111 when(mConnectivityDiagnosticsCallback.asBinder()).thenReturn(mIBinder); 7112 7113 mService.registerConnectivityDiagnosticsCallback( 7114 mConnectivityDiagnosticsCallback, wifiRequest, mContext.getPackageName()); 7115 7116 // Block until all other events are done processing. 7117 HandlerUtilsKt.waitForIdle(mCsHandlerThread, TIMEOUT_MS); 7118 7119 verify(mIBinder).linkToDeath(any(ConnectivityDiagnosticsCallbackInfo.class), anyInt()); 7120 verify(mConnectivityDiagnosticsCallback).asBinder(); 7121 assertTrue(mService.mConnectivityDiagnosticsCallbacks.containsKey(mIBinder)); 7122 7123 // Register the same callback again 7124 mService.registerConnectivityDiagnosticsCallback( 7125 mConnectivityDiagnosticsCallback, wifiRequest, mContext.getPackageName()); 7126 7127 // Block until all other events are done processing. 7128 HandlerUtilsKt.waitForIdle(mCsHandlerThread, TIMEOUT_MS); 7129 7130 assertTrue(mService.mConnectivityDiagnosticsCallbacks.containsKey(mIBinder)); 7131 } 7132 7133 @Test testCheckConnectivityDiagnosticsPermissionsNetworkStack()7134 public void testCheckConnectivityDiagnosticsPermissionsNetworkStack() throws Exception { 7135 final NetworkAgentInfo naiWithoutUid = 7136 new NetworkAgentInfo( 7137 null, null, null, null, null, new NetworkCapabilities(), 0, 7138 mServiceContext, null, null, mService, null, null, null, 0, INVALID_UID); 7139 7140 mServiceContext.setPermission( 7141 android.Manifest.permission.NETWORK_STACK, PERMISSION_GRANTED); 7142 assertTrue( 7143 "NetworkStack permission not applied", 7144 mService.checkConnectivityDiagnosticsPermissions( 7145 Process.myPid(), Process.myUid(), naiWithoutUid, 7146 mContext.getOpPackageName())); 7147 } 7148 7149 @Test testCheckConnectivityDiagnosticsPermissionsWrongUidPackageName()7150 public void testCheckConnectivityDiagnosticsPermissionsWrongUidPackageName() throws Exception { 7151 final NetworkAgentInfo naiWithoutUid = 7152 new NetworkAgentInfo( 7153 null, null, null, null, null, new NetworkCapabilities(), 0, 7154 mServiceContext, null, null, mService, null, null, null, 0, INVALID_UID); 7155 7156 mServiceContext.setPermission(android.Manifest.permission.NETWORK_STACK, PERMISSION_DENIED); 7157 7158 assertFalse( 7159 "Mismatched uid/package name should not pass the location permission check", 7160 mService.checkConnectivityDiagnosticsPermissions( 7161 Process.myPid() + 1, Process.myUid() + 1, naiWithoutUid, 7162 mContext.getOpPackageName())); 7163 } 7164 7165 @Test testCheckConnectivityDiagnosticsPermissionsNoLocationPermission()7166 public void testCheckConnectivityDiagnosticsPermissionsNoLocationPermission() throws Exception { 7167 final NetworkAgentInfo naiWithoutUid = 7168 new NetworkAgentInfo( 7169 null, null, null, null, null, new NetworkCapabilities(), 0, 7170 mServiceContext, null, null, mService, null, null, null, 0, INVALID_UID); 7171 7172 mServiceContext.setPermission(android.Manifest.permission.NETWORK_STACK, PERMISSION_DENIED); 7173 7174 assertFalse( 7175 "ACCESS_FINE_LOCATION permission necessary for Connectivity Diagnostics", 7176 mService.checkConnectivityDiagnosticsPermissions( 7177 Process.myPid(), Process.myUid(), naiWithoutUid, 7178 mContext.getOpPackageName())); 7179 } 7180 7181 @Test testCheckConnectivityDiagnosticsPermissionsActiveVpn()7182 public void testCheckConnectivityDiagnosticsPermissionsActiveVpn() throws Exception { 7183 final Network network = new Network(NET_ID); 7184 final NetworkAgentInfo naiWithoutUid = 7185 new NetworkAgentInfo( 7186 null, null, network, null, null, new NetworkCapabilities(), 0, 7187 mServiceContext, null, null, mService, null, null, null, 0, INVALID_UID); 7188 7189 setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION, 7190 Manifest.permission.ACCESS_FINE_LOCATION); 7191 mServiceContext.setPermission(android.Manifest.permission.NETWORK_STACK, PERMISSION_DENIED); 7192 7193 // setUp() calls mockVpn() which adds a VPN with the Test Runner's uid. Configure it to be 7194 // active 7195 final VpnInfo info = new VpnInfo(); 7196 info.ownerUid = Process.myUid(); 7197 info.vpnIface = "interface"; 7198 mMockVpn.setVpnInfo(info); 7199 mMockVpn.overrideUnderlyingNetworks(new Network[] {network}); 7200 assertTrue( 7201 "Active VPN permission not applied", 7202 mService.checkConnectivityDiagnosticsPermissions( 7203 Process.myPid(), Process.myUid(), naiWithoutUid, 7204 mContext.getOpPackageName())); 7205 7206 mMockVpn.overrideUnderlyingNetworks(null); 7207 assertFalse( 7208 "VPN shouldn't receive callback on non-underlying network", 7209 mService.checkConnectivityDiagnosticsPermissions( 7210 Process.myPid(), Process.myUid(), naiWithoutUid, 7211 mContext.getOpPackageName())); 7212 } 7213 7214 @Test testCheckConnectivityDiagnosticsPermissionsNetworkAdministrator()7215 public void testCheckConnectivityDiagnosticsPermissionsNetworkAdministrator() throws Exception { 7216 final NetworkCapabilities nc = new NetworkCapabilities(); 7217 nc.setAdministratorUids(new int[] {Process.myUid()}); 7218 final NetworkAgentInfo naiWithUid = 7219 new NetworkAgentInfo( 7220 null, null, null, null, null, nc, 0, mServiceContext, null, null, 7221 mService, null, null, null, 0, INVALID_UID); 7222 7223 setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION, 7224 Manifest.permission.ACCESS_FINE_LOCATION); 7225 mServiceContext.setPermission(android.Manifest.permission.NETWORK_STACK, PERMISSION_DENIED); 7226 7227 // Disconnect mock vpn so the uid check on NetworkAgentInfo is tested 7228 mMockVpn.disconnect(); 7229 assertTrue( 7230 "NetworkCapabilities administrator uid permission not applied", 7231 mService.checkConnectivityDiagnosticsPermissions( 7232 Process.myPid(), Process.myUid(), naiWithUid, mContext.getOpPackageName())); 7233 } 7234 7235 @Test testCheckConnectivityDiagnosticsPermissionsFails()7236 public void testCheckConnectivityDiagnosticsPermissionsFails() throws Exception { 7237 final NetworkCapabilities nc = new NetworkCapabilities(); 7238 nc.setOwnerUid(Process.myUid()); 7239 nc.setAdministratorUids(new int[] {Process.myUid()}); 7240 final NetworkAgentInfo naiWithUid = 7241 new NetworkAgentInfo( 7242 null, null, null, null, null, nc, 0, mServiceContext, null, null, 7243 mService, null, null, null, 0, INVALID_UID); 7244 7245 setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION, 7246 Manifest.permission.ACCESS_FINE_LOCATION); 7247 mServiceContext.setPermission(android.Manifest.permission.NETWORK_STACK, PERMISSION_DENIED); 7248 7249 // Use wrong pid and uid 7250 assertFalse( 7251 "Permissions allowed when they shouldn't be granted", 7252 mService.checkConnectivityDiagnosticsPermissions( 7253 Process.myPid() + 1, Process.myUid() + 1, naiWithUid, 7254 mContext.getOpPackageName())); 7255 } 7256 7257 @Test testRegisterConnectivityDiagnosticsCallbackCallsOnConnectivityReport()7258 public void testRegisterConnectivityDiagnosticsCallbackCallsOnConnectivityReport() 7259 throws Exception { 7260 // Set up the Network, which leads to a ConnectivityReport being cached for the network. 7261 final TestNetworkCallback callback = new TestNetworkCallback(); 7262 mCm.registerDefaultNetworkCallback(callback); 7263 final LinkProperties linkProperties = new LinkProperties(); 7264 linkProperties.setInterfaceName(INTERFACE_NAME); 7265 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, linkProperties); 7266 mCellNetworkAgent.connect(true); 7267 callback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 7268 callback.assertNoCallback(); 7269 7270 final NetworkRequest request = new NetworkRequest.Builder().build(); 7271 when(mConnectivityDiagnosticsCallback.asBinder()).thenReturn(mIBinder); 7272 7273 mServiceContext.setPermission( 7274 android.Manifest.permission.NETWORK_STACK, PERMISSION_GRANTED); 7275 7276 mService.registerConnectivityDiagnosticsCallback( 7277 mConnectivityDiagnosticsCallback, request, mContext.getPackageName()); 7278 7279 // Block until all other events are done processing. 7280 HandlerUtilsKt.waitForIdle(mCsHandlerThread, TIMEOUT_MS); 7281 7282 verify(mConnectivityDiagnosticsCallback) 7283 .onConnectivityReportAvailable(argThat(report -> { 7284 return INTERFACE_NAME.equals(report.getLinkProperties().getInterfaceName()) 7285 && report.getNetworkCapabilities().hasTransport(TRANSPORT_CELLULAR); 7286 })); 7287 } 7288 setUpConnectivityDiagnosticsCallback()7289 private void setUpConnectivityDiagnosticsCallback() throws Exception { 7290 final NetworkRequest request = new NetworkRequest.Builder().build(); 7291 when(mConnectivityDiagnosticsCallback.asBinder()).thenReturn(mIBinder); 7292 7293 mServiceContext.setPermission( 7294 android.Manifest.permission.NETWORK_STACK, PERMISSION_GRANTED); 7295 7296 mService.registerConnectivityDiagnosticsCallback( 7297 mConnectivityDiagnosticsCallback, request, mContext.getPackageName()); 7298 7299 // Block until all other events are done processing. 7300 HandlerUtilsKt.waitForIdle(mCsHandlerThread, TIMEOUT_MS); 7301 7302 // Connect the cell agent verify that it notifies TestNetworkCallback that it is available 7303 final TestNetworkCallback callback = new TestNetworkCallback(); 7304 mCm.registerDefaultNetworkCallback(callback); 7305 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 7306 mCellNetworkAgent.connect(true); 7307 callback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); 7308 callback.assertNoCallback(); 7309 } 7310 7311 @Test testConnectivityDiagnosticsCallbackOnConnectivityReportAvailable()7312 public void testConnectivityDiagnosticsCallbackOnConnectivityReportAvailable() 7313 throws Exception { 7314 setUpConnectivityDiagnosticsCallback(); 7315 7316 // Block until all other events are done processing. 7317 HandlerUtilsKt.waitForIdle(mCsHandlerThread, TIMEOUT_MS); 7318 7319 // Verify onConnectivityReport fired 7320 verify(mConnectivityDiagnosticsCallback).onConnectivityReportAvailable( 7321 argThat(report -> { 7322 final NetworkCapabilities nc = report.getNetworkCapabilities(); 7323 return nc.getUids() == null 7324 && nc.getAdministratorUids().length == 0 7325 && nc.getOwnerUid() == Process.INVALID_UID; 7326 })); 7327 } 7328 7329 @Test testConnectivityDiagnosticsCallbackOnDataStallSuspected()7330 public void testConnectivityDiagnosticsCallbackOnDataStallSuspected() throws Exception { 7331 setUpConnectivityDiagnosticsCallback(); 7332 7333 // Trigger notifyDataStallSuspected() on the INetworkMonitorCallbacks instance in the 7334 // cellular network agent 7335 mCellNetworkAgent.notifyDataStallSuspected(); 7336 7337 // Block until all other events are done processing. 7338 HandlerUtilsKt.waitForIdle(mCsHandlerThread, TIMEOUT_MS); 7339 7340 // Verify onDataStallSuspected fired 7341 verify(mConnectivityDiagnosticsCallback).onDataStallSuspected( 7342 argThat(report -> { 7343 final NetworkCapabilities nc = report.getNetworkCapabilities(); 7344 return nc.getUids() == null 7345 && nc.getAdministratorUids().length == 0 7346 && nc.getOwnerUid() == Process.INVALID_UID; 7347 })); 7348 } 7349 7350 @Test testConnectivityDiagnosticsCallbackOnConnectivityReported()7351 public void testConnectivityDiagnosticsCallbackOnConnectivityReported() throws Exception { 7352 setUpConnectivityDiagnosticsCallback(); 7353 7354 final Network n = mCellNetworkAgent.getNetwork(); 7355 final boolean hasConnectivity = true; 7356 mService.reportNetworkConnectivity(n, hasConnectivity); 7357 7358 // Block until all other events are done processing. 7359 HandlerUtilsKt.waitForIdle(mCsHandlerThread, TIMEOUT_MS); 7360 7361 // Verify onNetworkConnectivityReported fired 7362 verify(mConnectivityDiagnosticsCallback) 7363 .onNetworkConnectivityReported(eq(n), eq(hasConnectivity)); 7364 7365 final boolean noConnectivity = false; 7366 mService.reportNetworkConnectivity(n, noConnectivity); 7367 7368 // Block until all other events are done processing. 7369 HandlerUtilsKt.waitForIdle(mCsHandlerThread, TIMEOUT_MS); 7370 7371 // Wait for onNetworkConnectivityReported to fire 7372 verify(mConnectivityDiagnosticsCallback) 7373 .onNetworkConnectivityReported(eq(n), eq(noConnectivity)); 7374 } 7375 7376 @Test testRouteAddDeleteUpdate()7377 public void testRouteAddDeleteUpdate() throws Exception { 7378 final NetworkRequest request = new NetworkRequest.Builder().build(); 7379 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 7380 mCm.registerNetworkCallback(request, networkCallback); 7381 mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 7382 reset(mMockNetd); 7383 mCellNetworkAgent.connect(false); 7384 networkCallback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent); 7385 final int netId = mCellNetworkAgent.getNetwork().netId; 7386 7387 final String iface = "rmnet_data0"; 7388 final InetAddress gateway = InetAddress.getByName("fe80::5678"); 7389 RouteInfo direct = RouteInfo.makeHostRoute(gateway, iface); 7390 RouteInfo rio1 = new RouteInfo(new IpPrefix("2001:db8:1::/48"), gateway, iface); 7391 RouteInfo rio2 = new RouteInfo(new IpPrefix("2001:db8:2::/48"), gateway, iface); 7392 RouteInfo defaultRoute = new RouteInfo((IpPrefix) null, gateway, iface); 7393 RouteInfo defaultWithMtu = new RouteInfo(null, gateway, iface, RouteInfo.RTN_UNICAST, 7394 1280 /* mtu */); 7395 7396 // Send LinkProperties and check that we ask netd to add routes. 7397 LinkProperties lp = new LinkProperties(); 7398 lp.setInterfaceName(iface); 7399 lp.addRoute(direct); 7400 lp.addRoute(rio1); 7401 lp.addRoute(defaultRoute); 7402 mCellNetworkAgent.sendLinkProperties(lp); 7403 networkCallback.expectLinkPropertiesThat(mCellNetworkAgent, x -> x.getRoutes().size() == 3); 7404 7405 assertRoutesAdded(netId, direct, rio1, defaultRoute); 7406 reset(mMockNetd); 7407 7408 // Send updated LinkProperties and check that we ask netd to add, remove, update routes. 7409 assertTrue(lp.getRoutes().contains(defaultRoute)); 7410 lp.removeRoute(rio1); 7411 lp.addRoute(rio2); 7412 lp.addRoute(defaultWithMtu); 7413 // Ensure adding the same route with a different MTU replaces the previous route. 7414 assertFalse(lp.getRoutes().contains(defaultRoute)); 7415 assertTrue(lp.getRoutes().contains(defaultWithMtu)); 7416 7417 mCellNetworkAgent.sendLinkProperties(lp); 7418 networkCallback.expectLinkPropertiesThat(mCellNetworkAgent, 7419 x -> x.getRoutes().contains(rio2)); 7420 7421 assertRoutesRemoved(netId, rio1); 7422 assertRoutesAdded(netId, rio2); 7423 7424 ArgumentCaptor<RouteInfoParcel> captor = ArgumentCaptor.forClass(RouteInfoParcel.class); 7425 verify(mMockNetd).networkUpdateRouteParcel(eq(netId), captor.capture()); 7426 assertRouteInfoParcelMatches(defaultWithMtu, captor.getValue()); 7427 7428 7429 mCm.unregisterNetworkCallback(networkCallback); 7430 } 7431 } 7432