1 /* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server; 18 19 import static android.Manifest.permission.ACCESS_NETWORK_STATE; 20 import static android.Manifest.permission.CHANGE_NETWORK_STATE; 21 import static android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS; 22 import static android.Manifest.permission.CONTROL_OEM_PAID_NETWORK_PREFERENCE; 23 import static android.Manifest.permission.CREATE_USERS; 24 import static android.Manifest.permission.DUMP; 25 import static android.Manifest.permission.GET_INTENT_SENDER_INTENT; 26 import static android.Manifest.permission.LOCAL_MAC_ADDRESS; 27 import static android.Manifest.permission.MANAGE_TEST_NETWORKS; 28 import static android.Manifest.permission.NETWORK_FACTORY; 29 import static android.Manifest.permission.NETWORK_SETTINGS; 30 import static android.Manifest.permission.NETWORK_SETUP_WIZARD; 31 import static android.Manifest.permission.NETWORK_STACK; 32 import static android.Manifest.permission.PACKET_KEEPALIVE_OFFLOAD; 33 import static android.Manifest.permission.READ_DEVICE_CONFIG; 34 import static android.Manifest.permission.STATUS_BAR_SERVICE; 35 import static android.app.ActivityManager.UidFrozenStateChangedCallback.UID_FROZEN_STATE_FROZEN; 36 import static android.app.ActivityManager.UidFrozenStateChangedCallback.UID_FROZEN_STATE_UNFROZEN; 37 import static android.app.PendingIntent.FLAG_IMMUTABLE; 38 import static android.content.Intent.ACTION_PACKAGE_ADDED; 39 import static android.content.Intent.ACTION_PACKAGE_REMOVED; 40 import static android.content.Intent.ACTION_PACKAGE_REPLACED; 41 import static android.content.Intent.ACTION_USER_ADDED; 42 import static android.content.Intent.ACTION_USER_REMOVED; 43 import static android.content.pm.PackageInfo.REQUESTED_PERMISSION_GRANTED; 44 import static android.content.pm.PackageManager.FEATURE_ETHERNET; 45 import static android.content.pm.PackageManager.FEATURE_WIFI; 46 import static android.content.pm.PackageManager.FEATURE_WIFI_DIRECT; 47 import static android.content.pm.PackageManager.GET_PERMISSIONS; 48 import static android.content.pm.PackageManager.PERMISSION_DENIED; 49 import static android.content.pm.PackageManager.PERMISSION_GRANTED; 50 import static android.net.ConnectivityManager.ACTION_CAPTIVE_PORTAL_SIGN_IN; 51 import static android.net.ConnectivityManager.ACTION_DATA_ACTIVITY_CHANGE; 52 import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_DATA_SAVER; 53 import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_MASK; 54 import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_USER_RESTRICTED; 55 import static android.net.ConnectivityManager.BLOCKED_REASON_BATTERY_SAVER; 56 import static android.net.ConnectivityManager.BLOCKED_REASON_DOZE; 57 import static android.net.ConnectivityManager.BLOCKED_REASON_NONE; 58 import static android.net.ConnectivityManager.CONNECTIVITY_ACTION; 59 import static android.net.ConnectivityManager.EXTRA_DEVICE_TYPE; 60 import static android.net.ConnectivityManager.EXTRA_IS_ACTIVE; 61 import static android.net.ConnectivityManager.EXTRA_NETWORK_INFO; 62 import static android.net.ConnectivityManager.EXTRA_NETWORK_TYPE; 63 import static android.net.ConnectivityManager.EXTRA_REALTIME_NS; 64 import static android.net.ConnectivityManager.FIREWALL_CHAIN_BACKGROUND; 65 import static android.net.ConnectivityManager.FIREWALL_CHAIN_DOZABLE; 66 import static android.net.ConnectivityManager.FIREWALL_CHAIN_LOW_POWER_STANDBY; 67 import static android.net.ConnectivityManager.FIREWALL_CHAIN_METERED_ALLOW; 68 import static android.net.ConnectivityManager.FIREWALL_CHAIN_METERED_DENY_ADMIN; 69 import static android.net.ConnectivityManager.FIREWALL_CHAIN_METERED_DENY_USER; 70 import static android.net.ConnectivityManager.FIREWALL_CHAIN_OEM_DENY_1; 71 import static android.net.ConnectivityManager.FIREWALL_CHAIN_OEM_DENY_2; 72 import static android.net.ConnectivityManager.FIREWALL_CHAIN_OEM_DENY_3; 73 import static android.net.ConnectivityManager.FIREWALL_CHAIN_POWERSAVE; 74 import static android.net.ConnectivityManager.FIREWALL_CHAIN_RESTRICTED; 75 import static android.net.ConnectivityManager.FIREWALL_CHAIN_STANDBY; 76 import static android.net.ConnectivityManager.FIREWALL_RULE_ALLOW; 77 import static android.net.ConnectivityManager.FIREWALL_RULE_DEFAULT; 78 import static android.net.ConnectivityManager.FIREWALL_RULE_DENY; 79 import static android.net.ConnectivityManager.PROFILE_NETWORK_PREFERENCE_DEFAULT; 80 import static android.net.ConnectivityManager.PROFILE_NETWORK_PREFERENCE_ENTERPRISE; 81 import static android.net.ConnectivityManager.PROFILE_NETWORK_PREFERENCE_ENTERPRISE_BLOCKING; 82 import static android.net.ConnectivityManager.PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK; 83 import static android.net.ConnectivityManager.TYPE_ETHERNET; 84 import static android.net.ConnectivityManager.TYPE_MOBILE; 85 import static android.net.ConnectivityManager.TYPE_MOBILE_SUPL; 86 import static android.net.ConnectivityManager.TYPE_VPN; 87 import static android.net.ConnectivityManager.TYPE_WIFI; 88 import static android.net.ConnectivitySettingsManager.PRIVATE_DNS_MODE_OFF; 89 import static android.net.ConnectivitySettingsManager.PRIVATE_DNS_MODE_OPPORTUNISTIC; 90 import static android.net.ConnectivitySettingsManager.PRIVATE_DNS_MODE_PROVIDER_HOSTNAME; 91 import static android.net.INetd.PERMISSION_INTERNET; 92 import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_DNS; 93 import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_FALLBACK; 94 import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_HTTP; 95 import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_HTTPS; 96 import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_PRIVDNS; 97 import static android.net.INetworkMonitor.NETWORK_VALIDATION_RESULT_PARTIAL; 98 import static android.net.INetworkMonitor.NETWORK_VALIDATION_RESULT_VALID; 99 import static android.net.NetworkCapabilities.NET_CAPABILITY_BIP; 100 import static android.net.NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL; 101 import static android.net.NetworkCapabilities.NET_CAPABILITY_CBS; 102 import static android.net.NetworkCapabilities.NET_CAPABILITY_DUN; 103 import static android.net.NetworkCapabilities.NET_CAPABILITY_EIMS; 104 import static android.net.NetworkCapabilities.NET_CAPABILITY_ENTERPRISE; 105 import static android.net.NetworkCapabilities.NET_CAPABILITY_FOREGROUND; 106 import static android.net.NetworkCapabilities.NET_CAPABILITY_FOTA; 107 import static android.net.NetworkCapabilities.NET_CAPABILITY_IA; 108 import static android.net.NetworkCapabilities.NET_CAPABILITY_IMS; 109 import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET; 110 import static android.net.NetworkCapabilities.NET_CAPABILITY_MMS; 111 import static android.net.NetworkCapabilities.NET_CAPABILITY_MMTEL; 112 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED; 113 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED; 114 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED; 115 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING; 116 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED; 117 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED; 118 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN; 119 import static android.net.NetworkCapabilities.NET_CAPABILITY_OEM_PAID; 120 import static android.net.NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE; 121 import static android.net.NetworkCapabilities.NET_CAPABILITY_PARTIAL_CONNECTIVITY; 122 import static android.net.NetworkCapabilities.NET_CAPABILITY_RCS; 123 import static android.net.NetworkCapabilities.NET_CAPABILITY_SUPL; 124 import static android.net.NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED; 125 import static android.net.NetworkCapabilities.NET_CAPABILITY_TRUSTED; 126 import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED; 127 import static android.net.NetworkCapabilities.NET_CAPABILITY_VSIM; 128 import static android.net.NetworkCapabilities.NET_CAPABILITY_WIFI_P2P; 129 import static android.net.NetworkCapabilities.NET_CAPABILITY_XCAP; 130 import static android.net.NetworkCapabilities.NET_ENTERPRISE_ID_1; 131 import static android.net.NetworkCapabilities.NET_ENTERPRISE_ID_2; 132 import static android.net.NetworkCapabilities.NET_ENTERPRISE_ID_3; 133 import static android.net.NetworkCapabilities.NET_ENTERPRISE_ID_4; 134 import static android.net.NetworkCapabilities.NET_ENTERPRISE_ID_5; 135 import static android.net.NetworkCapabilities.REDACT_FOR_ACCESS_FINE_LOCATION; 136 import static android.net.NetworkCapabilities.REDACT_FOR_LOCAL_MAC_ADDRESS; 137 import static android.net.NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS; 138 import static android.net.NetworkCapabilities.REDACT_NONE; 139 import static android.net.NetworkCapabilities.TRANSPORT_BLUETOOTH; 140 import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; 141 import static android.net.NetworkCapabilities.TRANSPORT_ETHERNET; 142 import static android.net.NetworkCapabilities.TRANSPORT_TEST; 143 import static android.net.NetworkCapabilities.TRANSPORT_VPN; 144 import static android.net.NetworkCapabilities.TRANSPORT_WIFI; 145 import static android.net.NetworkCapabilities.TRANSPORT_WIFI_AWARE; 146 import static android.net.NetworkScore.KEEP_CONNECTED_FOR_HANDOVER; 147 import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID; 148 import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK; 149 import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY; 150 import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY; 151 import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_TEST; 152 import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_TEST_ONLY; 153 import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_UNINITIALIZED; 154 import static android.net.Proxy.PROXY_CHANGE_ACTION; 155 import static android.net.RouteInfo.RTN_UNREACHABLE; 156 import static android.net.connectivity.ConnectivityCompatChanges.NETWORK_BLOCKED_WITHOUT_INTERNET_PERMISSION; 157 import static android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener.PREFIX_OPERATION_ADDED; 158 import static android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener.PREFIX_OPERATION_REMOVED; 159 import static android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener.VALIDATION_RESULT_FAILURE; 160 import static android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener.VALIDATION_RESULT_SUCCESS; 161 import static android.os.Process.INVALID_UID; 162 import static android.system.OsConstants.IPPROTO_TCP; 163 import static android.telephony.DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH; 164 import static android.telephony.DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; 165 166 import static com.android.net.module.util.DeviceConfigUtils.TETHERING_MODULE_NAME; 167 import static com.android.server.ConnectivityService.MAX_NETWORK_REQUESTS_PER_SYSTEM_UID; 168 import static com.android.server.ConnectivityService.PREFERENCE_ORDER_MOBILE_DATA_PREFERERRED; 169 import static com.android.server.ConnectivityService.PREFERENCE_ORDER_OEM; 170 import static com.android.server.ConnectivityService.PREFERENCE_ORDER_PROFILE; 171 import static com.android.server.ConnectivityService.PREFERENCE_ORDER_VPN; 172 import static com.android.server.ConnectivityService.createDeliveryGroupKeyForConnectivityAction; 173 import static com.android.server.ConnectivityService.makeNflogPrefix; 174 import static com.android.server.ConnectivityServiceTestUtils.transportToLegacyType; 175 import static com.android.server.NetworkAgentWrapper.CallbackType.OnQosCallbackRegister; 176 import static com.android.server.NetworkAgentWrapper.CallbackType.OnQosCallbackUnregister; 177 import static com.android.testutils.Cleanup.testAndCleanup; 178 import static com.android.testutils.ConcurrentUtils.await; 179 import static com.android.testutils.ConcurrentUtils.durationOf; 180 import static com.android.testutils.DevSdkIgnoreRule.IgnoreAfter; 181 import static com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo; 182 import static com.android.testutils.DevSdkIgnoreRuleKt.SC_V2; 183 import static com.android.testutils.FunctionalUtils.ignoreExceptions; 184 import static com.android.testutils.HandlerUtils.visibleOnHandlerThread; 185 import static com.android.testutils.HandlerUtils.waitForIdleSerialExecutor; 186 import static com.android.testutils.MiscAsserts.assertContainsAll; 187 import static com.android.testutils.MiscAsserts.assertContainsExactly; 188 import static com.android.testutils.MiscAsserts.assertEmpty; 189 import static com.android.testutils.MiscAsserts.assertLength; 190 import static com.android.testutils.MiscAsserts.assertRunsInAtMost; 191 import static com.android.testutils.MiscAsserts.assertSameElements; 192 import static com.android.testutils.MiscAsserts.assertThrows; 193 import static com.android.testutils.RecorderCallback.CallbackEntry.AVAILABLE; 194 import static com.android.testutils.RecorderCallback.CallbackEntry.BLOCKED_STATUS; 195 import static com.android.testutils.RecorderCallback.CallbackEntry.BLOCKED_STATUS_INT; 196 import static com.android.testutils.RecorderCallback.CallbackEntry.LINK_PROPERTIES_CHANGED; 197 import static com.android.testutils.RecorderCallback.CallbackEntry.LOSING; 198 import static com.android.testutils.RecorderCallback.CallbackEntry.LOST; 199 import static com.android.testutils.RecorderCallback.CallbackEntry.NETWORK_CAPS_UPDATED; 200 import static com.android.testutils.RecorderCallback.CallbackEntry.RESUMED; 201 import static com.android.testutils.RecorderCallback.CallbackEntry.SUSPENDED; 202 import static com.android.testutils.RecorderCallback.CallbackEntry.UNAVAILABLE; 203 import static com.android.testutils.TestPermissionUtil.runAsShell; 204 205 import static org.hamcrest.MatcherAssert.assertThat; 206 import static org.hamcrest.Matchers.containsString; 207 import static org.junit.Assert.assertEquals; 208 import static org.junit.Assert.assertFalse; 209 import static org.junit.Assert.assertNotEquals; 210 import static org.junit.Assert.assertNotNull; 211 import static org.junit.Assert.assertNull; 212 import static org.junit.Assert.assertTrue; 213 import static org.junit.Assert.fail; 214 import static org.junit.Assume.assumeFalse; 215 import static org.junit.Assume.assumeTrue; 216 import static org.mockito.AdditionalMatchers.aryEq; 217 import static org.mockito.ArgumentMatchers.anyBoolean; 218 import static org.mockito.ArgumentMatchers.anyLong; 219 import static org.mockito.ArgumentMatchers.anyString; 220 import static org.mockito.ArgumentMatchers.argThat; 221 import static org.mockito.ArgumentMatchers.eq; 222 import static org.mockito.ArgumentMatchers.isNull; 223 import static org.mockito.ArgumentMatchers.anyInt; 224 import static org.mockito.Mockito.any; 225 import static org.mockito.Mockito.atLeastOnce; 226 import static org.mockito.Mockito.clearInvocations; 227 import static org.mockito.Mockito.doAnswer; 228 import static org.mockito.Mockito.doNothing; 229 import static org.mockito.Mockito.doReturn; 230 import static org.mockito.Mockito.doThrow; 231 import static org.mockito.Mockito.inOrder; 232 import static org.mockito.Mockito.mock; 233 import static org.mockito.Mockito.never; 234 import static org.mockito.Mockito.reset; 235 import static org.mockito.Mockito.spy; 236 import static org.mockito.Mockito.timeout; 237 import static org.mockito.Mockito.times; 238 import static org.mockito.Mockito.verify; 239 import static org.mockito.Mockito.verifyNoMoreInteractions; 240 241 import static java.util.Arrays.asList; 242 243 import android.Manifest; 244 import android.annotation.NonNull; 245 import android.annotation.Nullable; 246 import android.app.ActivityManager; 247 import android.app.ActivityManager.UidFrozenStateChangedCallback; 248 import android.app.AlarmManager; 249 import android.app.AppOpsManager; 250 import android.app.BroadcastOptions; 251 import android.app.NotificationManager; 252 import android.app.PendingIntent; 253 import android.app.admin.DevicePolicyManager; 254 import android.app.usage.NetworkStatsManager; 255 import android.compat.testing.PlatformCompatChangeRule; 256 import android.content.BroadcastReceiver; 257 import android.content.ComponentName; 258 import android.content.ContentProvider; 259 import android.content.ContentResolver; 260 import android.content.Context; 261 import android.content.Intent; 262 import android.content.IntentFilter; 263 import android.content.pm.ApplicationInfo; 264 import android.content.pm.ModuleInfo; 265 import android.content.pm.PackageInfo; 266 import android.content.pm.PackageManager; 267 import android.content.pm.ResolveInfo; 268 import android.content.pm.ServiceInfo; 269 import android.content.pm.UserInfo; 270 import android.content.res.Resources; 271 import android.location.LocationManager; 272 import android.net.CaptivePortal; 273 import android.net.CaptivePortalData; 274 import android.net.ConnectionInfo; 275 import android.net.ConnectivityDiagnosticsManager.DataStallReport; 276 import android.net.ConnectivityManager; 277 import android.net.ConnectivityManager.NetworkCallback; 278 import android.net.ConnectivityManager.PacketKeepalive; 279 import android.net.ConnectivityManager.PacketKeepaliveCallback; 280 import android.net.ConnectivityManager.TooManyRequestsException; 281 import android.net.ConnectivitySettingsManager; 282 import android.net.ConnectivityThread; 283 import android.net.DataStallReportParcelable; 284 import android.net.EthernetManager; 285 import android.net.EthernetNetworkSpecifier; 286 import android.net.IConnectivityDiagnosticsCallback; 287 import android.net.IDnsResolver; 288 import android.net.INetd; 289 import android.net.INetworkMonitor; 290 import android.net.INetworkMonitorCallbacks; 291 import android.net.IOnCompleteListener; 292 import android.net.IQosCallback; 293 import android.net.InetAddresses; 294 import android.net.InterfaceConfigurationParcel; 295 import android.net.IpPrefix; 296 import android.net.IpSecManager; 297 import android.net.IpSecManager.UdpEncapsulationSocket; 298 import android.net.LinkAddress; 299 import android.net.LinkProperties; 300 import android.net.MatchAllNetworkSpecifier; 301 import android.net.NativeNetworkConfig; 302 import android.net.NativeNetworkType; 303 import android.net.Network; 304 import android.net.NetworkAgent; 305 import android.net.NetworkAgentConfig; 306 import android.net.NetworkCapabilities; 307 import android.net.NetworkFactory; 308 import android.net.NetworkInfo; 309 import android.net.NetworkInfo.DetailedState; 310 import android.net.NetworkPolicyManager; 311 import android.net.NetworkPolicyManager.NetworkPolicyCallback; 312 import android.net.NetworkProvider; 313 import android.net.NetworkRequest; 314 import android.net.NetworkScore; 315 import android.net.NetworkSpecifier; 316 import android.net.NetworkStack; 317 import android.net.NetworkStateSnapshot; 318 import android.net.NetworkTestResultParcelable; 319 import android.net.OemNetworkPreferences; 320 import android.net.PacProxyManager; 321 import android.net.ProfileNetworkPreference; 322 import android.net.Proxy; 323 import android.net.ProxyInfo; 324 import android.net.QosCallbackException; 325 import android.net.QosFilter; 326 import android.net.QosSession; 327 import android.net.ResolverParamsParcel; 328 import android.net.RouteInfo; 329 import android.net.RouteInfoParcel; 330 import android.net.SocketKeepalive; 331 import android.net.TelephonyNetworkSpecifier; 332 import android.net.TetheringManager; 333 import android.net.TransportInfo; 334 import android.net.UidRange; 335 import android.net.UidRangeParcel; 336 import android.net.UnderlyingNetworkInfo; 337 import android.net.Uri; 338 import android.net.VpnManager; 339 import android.net.VpnTransportInfo; 340 import android.net.connectivity.ConnectivityCompatChanges; 341 import android.net.metrics.IpConnectivityLog; 342 import android.net.netd.aidl.NativeUidRangeConfig; 343 import android.net.networkstack.NetworkStackClientBase; 344 import android.net.resolv.aidl.Nat64PrefixEventParcel; 345 import android.net.resolv.aidl.PrivateDnsValidationEventParcel; 346 import android.net.shared.PrivateDnsConfig; 347 import android.net.wifi.WifiInfo; 348 import android.os.BadParcelableException; 349 import android.os.BatteryStatsManager; 350 import android.os.Binder; 351 import android.os.Build; 352 import android.os.Bundle; 353 import android.os.ConditionVariable; 354 import android.os.Handler; 355 import android.os.HandlerThread; 356 import android.os.IBinder; 357 import android.os.INetworkManagementService; 358 import android.os.Looper; 359 import android.os.Messenger; 360 import android.os.Parcel; 361 import android.os.ParcelFileDescriptor; 362 import android.os.Parcelable; 363 import android.os.PersistableBundle; 364 import android.os.Process; 365 import android.os.RemoteException; 366 import android.os.ServiceSpecificException; 367 import android.os.SystemClock; 368 import android.os.SystemConfigManager; 369 import android.os.UserHandle; 370 import android.os.UserManager; 371 import android.provider.Settings; 372 import android.system.Os; 373 import android.telephony.SubscriptionManager; 374 import android.telephony.TelephonyManager; 375 import android.telephony.data.EpsBearerQosSessionAttributes; 376 import android.telephony.data.NrQosSessionAttributes; 377 import android.test.mock.MockContentResolver; 378 import android.text.TextUtils; 379 import android.util.ArraySet; 380 import android.util.Log; 381 import android.util.Pair; 382 import android.util.Range; 383 import android.util.SparseArray; 384 385 import androidx.test.InstrumentationRegistry; 386 import androidx.test.filters.SmallTest; 387 388 import com.android.connectivity.resources.R; 389 import com.android.internal.annotations.GuardedBy; 390 import com.android.internal.app.IBatteryStats; 391 import com.android.internal.net.VpnConfig; 392 import com.android.internal.util.WakeupMessage; 393 import com.android.internal.util.test.BroadcastInterceptingContext; 394 import com.android.internal.util.test.FakeSettingsProvider; 395 import com.android.modules.utils.build.SdkLevel; 396 import com.android.net.module.util.ArrayTrackRecord; 397 import com.android.net.module.util.BaseNetdUnsolicitedEventListener; 398 import com.android.net.module.util.CollectionUtils; 399 import com.android.net.module.util.LocationPermissionChecker; 400 import com.android.net.module.util.NetworkMonitorUtils; 401 import com.android.networkstack.apishim.ConstantsShim; 402 import com.android.networkstack.apishim.NetworkAgentConfigShimImpl; 403 import com.android.networkstack.apishim.common.BroadcastOptionsShim; 404 import com.android.networkstack.apishim.common.UnsupportedApiLevelException; 405 import com.android.server.ConnectivityService.ConnectivityDiagnosticsCallbackInfo; 406 import com.android.server.ConnectivityService.NetworkRequestInfo; 407 import com.android.server.ConnectivityServiceTest.ConnectivityServiceDependencies.DestroySocketsWrapper; 408 import com.android.server.ConnectivityServiceTest.ConnectivityServiceDependencies.ReportedInterfaces; 409 import com.android.server.L2capNetworkProvider; 410 import com.android.server.connectivity.ApplicationSelfCertifiedNetworkCapabilities; 411 import com.android.server.connectivity.AutomaticOnOffKeepaliveTracker; 412 import com.android.server.connectivity.CarrierPrivilegeAuthenticator; 413 import com.android.server.connectivity.ClatCoordinator; 414 import com.android.server.connectivity.ConnectivityFlags; 415 import com.android.server.connectivity.ConnectivityResources; 416 import com.android.server.connectivity.InterfaceTracker; 417 import com.android.server.connectivity.KeepaliveTracker; 418 import com.android.server.connectivity.MultinetworkPolicyTracker; 419 import com.android.server.connectivity.MultinetworkPolicyTrackerTestDependencies; 420 import com.android.server.connectivity.Nat464Xlat; 421 import com.android.server.connectivity.NetworkAgentInfo; 422 import com.android.server.connectivity.NetworkNotificationManager; 423 import com.android.server.connectivity.NetworkNotificationManager.NotificationType; 424 import com.android.server.connectivity.PermissionMonitor; 425 import com.android.server.connectivity.ProxyTracker; 426 import com.android.server.connectivity.QosCallbackTracker; 427 import com.android.server.connectivity.SatelliteAccessController; 428 import com.android.server.connectivity.TcpKeepaliveController; 429 import com.android.server.connectivity.UidRangeUtils; 430 import com.android.server.net.NetworkPinner; 431 import com.android.testutils.DevSdkIgnoreRule; 432 import com.android.testutils.DevSdkIgnoreRunner; 433 import com.android.testutils.FunctionalUtils.Function3; 434 import com.android.testutils.FunctionalUtils.ThrowingConsumer; 435 import com.android.testutils.FunctionalUtils.ThrowingRunnable; 436 import com.android.testutils.HandlerUtils; 437 import com.android.testutils.RecorderCallback.CallbackEntry; 438 import com.android.testutils.TestableNetworkCallback; 439 import com.android.testutils.TestableNetworkOfferCallback; 440 441 import libcore.junit.util.compat.CoreCompatChangeRule.DisableCompatChanges; 442 import libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges; 443 444 import org.junit.After; 445 import org.junit.Assert; 446 import org.junit.Before; 447 import org.junit.Ignore; 448 import org.junit.Rule; 449 import org.junit.Test; 450 import org.junit.runner.RunWith; 451 import org.mockito.AdditionalAnswers; 452 import org.mockito.ArgumentCaptor; 453 import org.mockito.InOrder; 454 import org.mockito.Mock; 455 import org.mockito.MockitoAnnotations; 456 import org.mockito.Spy; 457 import org.mockito.stubbing.Answer; 458 459 import java.io.FileDescriptor; 460 import java.io.IOException; 461 import java.io.PrintWriter; 462 import java.io.StringWriter; 463 import java.lang.reflect.Method; 464 import java.net.DatagramSocket; 465 import java.net.Inet4Address; 466 import java.net.Inet6Address; 467 import java.net.InetAddress; 468 import java.net.InetSocketAddress; 469 import java.net.Socket; 470 import java.util.ArrayList; 471 import java.util.Arrays; 472 import java.util.Collection; 473 import java.util.Collections; 474 import java.util.Comparator; 475 import java.util.HashMap; 476 import java.util.HashSet; 477 import java.util.List; 478 import java.util.Map; 479 import java.util.Objects; 480 import java.util.Set; 481 import java.util.UUID; 482 import java.util.concurrent.CompletableFuture; 483 import java.util.concurrent.CountDownLatch; 484 import java.util.concurrent.Executor; 485 import java.util.concurrent.ExecutorService; 486 import java.util.concurrent.Executors; 487 import java.util.concurrent.LinkedBlockingQueue; 488 import java.util.concurrent.TimeUnit; 489 import java.util.concurrent.TimeoutException; 490 import java.util.concurrent.atomic.AtomicBoolean; 491 import java.util.concurrent.atomic.AtomicReference; 492 import java.util.function.BiConsumer; 493 import java.util.function.Consumer; 494 import java.util.function.Predicate; 495 import java.util.function.Supplier; 496 import java.util.regex.Matcher; 497 import java.util.regex.Pattern; 498 import java.util.stream.Collectors; 499 500 /** 501 * Tests for {@link ConnectivityService}. 502 * 503 * Build, install and run with: 504 * runtest frameworks-net -c com.android.server.ConnectivityServiceTest 505 */ 506 // TODO : move methods from this test to smaller tests in the 'connectivityservice' directory 507 // to enable faster testing of smaller groups of functionality. 508 @RunWith(DevSdkIgnoreRunner.class) 509 @SmallTest 510 @DevSdkIgnoreRunner.MonitorThreadLeak 511 @DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.R) 512 public class ConnectivityServiceTest { 513 private static final String TAG = "ConnectivityServiceTest"; 514 515 @Rule 516 public final DevSdkIgnoreRule ignoreRule = new DevSdkIgnoreRule(); 517 518 @Rule 519 public final PlatformCompatChangeRule compatChangeRule = new PlatformCompatChangeRule(); 520 521 private static final int TIMEOUT_MS = 2_000; 522 // Broadcasts can take a long time to be delivered. The test will not wait for that long unless 523 // there is a failure, so use a long timeout. 524 private static final int BROADCAST_TIMEOUT_MS = 30_000; 525 private static final int TEST_LINGER_DELAY_MS = 400; 526 private static final int TEST_NASCENT_DELAY_MS = 300; 527 // Chosen to be less than the linger and nascent timeout. This ensures that we can distinguish 528 // between a LOST callback that arrives immediately and a LOST callback that arrives after 529 // the linger/nascent timeout. For this, our assertions should run fast enough to leave 530 // less than (mService.mLingerDelayMs - TEST_CALLBACK_TIMEOUT_MS) between the time callbacks are 531 // supposedly fired, and the time we call expectCapChanged. 532 private static final int TEST_CALLBACK_TIMEOUT_MS = 250; 533 // Chosen to be less than TEST_CALLBACK_TIMEOUT_MS. This ensures that requests have time to 534 // complete before callbacks are verified. 535 private static final int TEST_REQUEST_TIMEOUT_MS = 150; 536 537 private static final int UNREASONABLY_LONG_ALARM_WAIT_MS = 2_000; 538 539 private static final long TIMESTAMP = 1234L; 540 541 private static final int NET_ID = 110; 542 private static final int OEM_PREF_ANY_NET_ID = -1; 543 // Set a non-zero value to verify the flow to set tcp init rwnd value. 544 private static final int TEST_TCP_INIT_RWND = 60; 545 546 // Used for testing the per-work-profile default network. 547 private static final int TEST_APP_ID = 103; 548 private static final int TEST_WORK_PROFILE_USER_ID = 2; 549 private static final int TEST_WORK_PROFILE_APP_UID = 550 UserHandle.getUid(TEST_WORK_PROFILE_USER_ID, TEST_APP_ID); 551 private static final int TEST_APP_ID_2 = 104; 552 private static final int TEST_WORK_PROFILE_APP_UID_2 = 553 UserHandle.getUid(TEST_WORK_PROFILE_USER_ID, TEST_APP_ID_2); 554 private static final int TEST_APP_ID_3 = 105; 555 private static final int TEST_APP_ID_4 = 106; 556 private static final int TEST_APP_ID_5 = 107; 557 558 private static final String CLAT_PREFIX = "v4-"; 559 private static final String MOBILE_IFNAME = "test_rmnet_data0"; 560 private static final String CLAT_MOBILE_IFNAME = CLAT_PREFIX + MOBILE_IFNAME; 561 private static final String WIFI_IFNAME = "test_wlan0"; 562 private static final String WIFI_WOL_IFNAME = "test_wlan_wol"; 563 private static final String VPN_IFNAME = "tun10042"; 564 private static final String ETHERNET_IFNAME = "eth0"; 565 private static final String TEST_PACKAGE_NAME = "com.android.test.package"; 566 private static final int TEST_PACKAGE_UID = 123; 567 private static final int TEST_PACKAGE_UID2 = 321; 568 private static final int TEST_PACKAGE_UID3 = 456; 569 private static final int NETWORK_ACTIVITY_NO_UID = -1; 570 private static final int TEST_SUBSCRIPTION_ID = 1; 571 572 private static final int PACKET_WAKEUP_MARK_MASK = 0x80000000; 573 574 private static final String ALWAYS_ON_PACKAGE = "com.android.test.alwaysonvpn"; 575 576 private static final String INTERFACE_NAME = "interface"; 577 578 private static final String TEST_VENUE_URL_NA_PASSPOINT = "https://android.com/"; 579 private static final String TEST_VENUE_URL_NA_OTHER = "https://example.com/"; 580 private static final String TEST_TERMS_AND_CONDITIONS_URL_NA_PASSPOINT = 581 "https://android.com/terms/"; 582 private static final String TEST_TERMS_AND_CONDITIONS_URL_NA_OTHER = 583 "https://example.com/terms/"; 584 private static final String TEST_VENUE_URL_CAPPORT = "https://android.com/capport/"; 585 private static final String TEST_USER_PORTAL_API_URL_CAPPORT = 586 "https://android.com/user/api/capport/"; 587 private static final String TEST_FRIENDLY_NAME = "Network friendly name"; 588 private static final String TEST_REDIRECT_URL = "http://example.com/firstPath"; 589 private static final String QUEUE_NETWORK_AGENT_EVENTS_IN_SYSTEM_SERVER = 590 "queue_network_agent_events_in_system_server"; 591 592 private boolean mShouldCreateNetworksImmediately; 593 594 private MockContext mServiceContext; 595 private HandlerThread mCsHandlerThread; 596 private ConnectivityServiceDependencies mDeps; 597 private PermissionMonitorDependencies mPermDeps; 598 private AutomaticOnOffKeepaliveTrackerDependencies mAutoOnOffKeepaliveDependencies; 599 private ConnectivityService mService; 600 private WrappedConnectivityManager mCm; 601 private TestNetworkAgentWrapper mWiFiAgent; 602 private TestNetworkAgentWrapper mCellAgent; 603 private TestNetworkAgentWrapper mEthernetAgent; 604 private final List<TestNetworkAgentWrapper> mCreatedAgents = new ArrayList<>(); 605 private MockVpn mMockVpn; 606 private Context mContext; 607 private NetworkPolicyCallback mPolicyCallback; 608 private WrappedMultinetworkPolicyTracker mPolicyTracker; 609 private ProxyTracker mProxyTracker; 610 private HandlerThread mAlarmManagerThread; 611 private TestNetIdManager mNetIdManager; 612 private QosCallbackMockHelper mQosCallbackMockHelper; 613 private QosCallbackTracker mQosCallbackTracker; 614 private TestNetworkCallback mDefaultNetworkCallback; 615 private TestNetworkCallback mSystemDefaultNetworkCallback; 616 private TestNetworkCallback mProfileDefaultNetworkCallback; 617 private TestNetworkCallback mTestPackageDefaultNetworkCallback; 618 private TestNetworkCallback mProfileDefaultNetworkCallbackAsAppUid2; 619 private TestNetworkCallback mTestPackageDefaultNetworkCallback2; 620 621 // State variables required to emulate NetworkPolicyManagerService behaviour. 622 private int mBlockedReasons = BLOCKED_REASON_NONE; 623 624 @Mock DeviceIdleInternal mDeviceIdleInternal; 625 @Mock INetworkManagementService mNetworkManagementService; 626 @Mock NetworkStatsManager mStatsManager; 627 @Mock IDnsResolver mMockDnsResolver; 628 @Mock INetd mMockNetd; 629 @Mock NetworkStackClientBase mNetworkStack; 630 @Mock PackageManager mPackageManager; 631 @Mock UserManager mUserManager; 632 @Mock NotificationManager mNotificationManager; 633 @Mock AlarmManager mAlarmManager; 634 @Mock IConnectivityDiagnosticsCallback mConnectivityDiagnosticsCallback; 635 @Mock IBinder mIBinder; 636 @Mock LocationManager mLocationManager; 637 @Mock AppOpsManager mAppOpsManager; 638 @Mock TelephonyManager mTelephonyManager; 639 @Mock EthernetManager mEthernetManager; 640 @Mock NetworkPolicyManager mNetworkPolicyManager; 641 @Mock SystemConfigManager mSystemConfigManager; 642 @Mock DevicePolicyManager mDevicePolicyManager; 643 @Mock Resources mResources; 644 @Mock ClatCoordinator mClatCoordinator; 645 @Mock PacProxyManager mPacProxyManager; 646 @Mock BpfNetMaps mBpfNetMaps; 647 @Mock CarrierPrivilegeAuthenticator mCarrierPrivilegeAuthenticator; 648 @Mock TetheringManager mTetheringManager; 649 @Mock BroadcastOptionsShim mBroadcastOptionsShim; 650 @Mock ActivityManager mActivityManager; 651 @Mock DestroySocketsWrapper mDestroySocketsWrapper; 652 @Mock SubscriptionManager mSubscriptionManager; 653 @Mock KeepaliveTracker.Dependencies mMockKeepaliveTrackerDependencies; 654 @Mock SatelliteAccessController mSatelliteAccessController; 655 656 // BatteryStatsManager is final and cannot be mocked with regular mockito, so just mock the 657 // underlying binder calls. 658 final IBatteryStats mIBatteryStats = mock(IBatteryStats.class); 659 final BatteryStatsManager mBatteryStatsManager = new BatteryStatsManager(mIBatteryStats); 660 661 private ArgumentCaptor<ResolverParamsParcel> mResolverParamsParcelCaptor = 662 ArgumentCaptor.forClass(ResolverParamsParcel.class); 663 664 // This class exists to test bindProcessToNetwork and getBoundNetworkForProcess. These methods 665 // do not go through ConnectivityService but talk to netd directly, so they don't automatically 666 // reflect the state of our test ConnectivityService. 667 private class WrappedConnectivityManager extends ConnectivityManager { 668 private Network mFakeBoundNetwork; 669 bindProcessToNetwork(Network network)670 public synchronized boolean bindProcessToNetwork(Network network) { 671 mFakeBoundNetwork = network; 672 return true; 673 } 674 getBoundNetworkForProcess()675 public synchronized Network getBoundNetworkForProcess() { 676 return mFakeBoundNetwork; 677 } 678 WrappedConnectivityManager(Context context, ConnectivityService service)679 public WrappedConnectivityManager(Context context, ConnectivityService service) { 680 super(context, service); 681 } 682 } 683 684 private class MockContext extends BroadcastInterceptingContext { 685 private final MockContentResolver mContentResolver; 686 687 @Spy private Resources mInternalResources; 688 private final LinkedBlockingQueue<Intent> mStartedActivities = new LinkedBlockingQueue<>(); 689 690 // Map of permission name -> PermissionManager.Permission_{GRANTED|DENIED} constant 691 // For permissions granted across the board, the key is only the permission name. 692 // For permissions only granted to a combination of uid/pid, the key 693 // is "<permission name>,<pid>,<uid>". PID+UID permissons have priority over generic ones. 694 private final HashMap<String, Integer> mMockedPermissions = new HashMap<>(); 695 mockStringResource(int resId)696 private void mockStringResource(int resId) { 697 doAnswer((inv) -> { 698 return "Mock string resource ID=" + inv.getArgument(0); 699 }).when(mInternalResources).getString(resId); 700 } 701 MockContext(Context base, ContentProvider settingsProvider)702 MockContext(Context base, ContentProvider settingsProvider) { 703 super(base); 704 705 mInternalResources = spy(base.getResources()); 706 doReturn(new String[] { 707 "wifi,1,1,1,-1,true", 708 "mobile,0,0,0,-1,true", 709 "mobile_mms,2,0,2,60000,true", 710 "mobile_supl,3,0,2,60000,true", 711 }).when(mInternalResources) 712 .getStringArray(com.android.internal.R.array.networkAttributes); 713 714 final int[] stringResourcesToMock = new int[] { 715 com.android.internal.R.string.config_customVpnAlwaysOnDisconnectedDialogComponent, 716 com.android.internal.R.string.vpn_lockdown_config, 717 com.android.internal.R.string.vpn_lockdown_connected, 718 com.android.internal.R.string.vpn_lockdown_connecting, 719 com.android.internal.R.string.vpn_lockdown_disconnected, 720 com.android.internal.R.string.vpn_lockdown_error, 721 }; 722 for (int resId : stringResourcesToMock) { 723 mockStringResource(resId); 724 } 725 726 mContentResolver = new MockContentResolver(); 727 mContentResolver.addProvider(Settings.AUTHORITY, settingsProvider); 728 } 729 730 @Override startActivityAsUser(Intent intent, UserHandle handle)731 public void startActivityAsUser(Intent intent, UserHandle handle) { 732 mStartedActivities.offer(intent); 733 } 734 expectStartActivityIntent(int timeoutMs)735 public Intent expectStartActivityIntent(int timeoutMs) { 736 Intent intent = null; 737 try { 738 intent = mStartedActivities.poll(timeoutMs, TimeUnit.MILLISECONDS); 739 } catch (InterruptedException e) {} 740 assertNotNull("Did not receive sign-in intent after " + timeoutMs + "ms", intent); 741 return intent; 742 } 743 expectNoStartActivityIntent(int timeoutMs)744 public void expectNoStartActivityIntent(int timeoutMs) { 745 try { 746 assertNull("Received unexpected Intent to start activity", 747 mStartedActivities.poll(timeoutMs, TimeUnit.MILLISECONDS)); 748 } catch (InterruptedException e) {} 749 } 750 751 @Override startService(Intent service)752 public ComponentName startService(Intent service) { 753 final String action = service.getAction(); 754 if (!VpnConfig.SERVICE_INTERFACE.equals(action) 755 && !ConstantsShim.ACTION_VPN_MANAGER_EVENT.equals(action)) { 756 fail("Attempt to start unknown service, action=" + action); 757 } 758 return new ComponentName(service.getPackage(), "com.android.test.Service"); 759 } 760 761 @Override getSystemService(String name)762 public Object getSystemService(String name) { 763 if (Context.CONNECTIVITY_SERVICE.equals(name)) return mCm; 764 if (Context.NOTIFICATION_SERVICE.equals(name)) return mNotificationManager; 765 if (Context.USER_SERVICE.equals(name)) return mUserManager; 766 if (Context.ALARM_SERVICE.equals(name)) return mAlarmManager; 767 if (Context.LOCATION_SERVICE.equals(name)) return mLocationManager; 768 if (Context.APP_OPS_SERVICE.equals(name)) return mAppOpsManager; 769 if (Context.TELEPHONY_SERVICE.equals(name)) return mTelephonyManager; 770 if (Context.ETHERNET_SERVICE.equals(name)) return mEthernetManager; 771 if (Context.NETWORK_POLICY_SERVICE.equals(name)) return mNetworkPolicyManager; 772 if (Context.DEVICE_POLICY_SERVICE.equals(name)) return mDevicePolicyManager; 773 if (Context.SYSTEM_CONFIG_SERVICE.equals(name)) return mSystemConfigManager; 774 if (Context.NETWORK_STATS_SERVICE.equals(name)) return mStatsManager; 775 if (Context.BATTERY_STATS_SERVICE.equals(name)) return mBatteryStatsManager; 776 if (Context.PAC_PROXY_SERVICE.equals(name)) return mPacProxyManager; 777 if (Context.TETHERING_SERVICE.equals(name)) return mTetheringManager; 778 if (Context.ACTIVITY_SERVICE.equals(name)) return mActivityManager; 779 if (Context.TELEPHONY_SUBSCRIPTION_SERVICE.equals(name)) return mSubscriptionManager; 780 // StatsManager is final and can't be mocked, and uses static methods for mostly 781 // everything. The simplest fix is to return null and not have metrics in tests. 782 if (Context.STATS_MANAGER.equals(name)) return null; 783 return super.getSystemService(name); 784 } 785 786 final HashMap<UserHandle, UserManager> mUserManagers = new HashMap<>(); 787 @Override createContextAsUser(UserHandle user, int flags)788 public Context createContextAsUser(UserHandle user, int flags) { 789 final Context asUser = mock(Context.class, AdditionalAnswers.delegatesTo(this)); 790 doReturn(user).when(asUser).getUser(); 791 doAnswer((inv) -> { 792 final UserManager um = mUserManagers.computeIfAbsent(user, 793 u -> mock(UserManager.class, AdditionalAnswers.delegatesTo(mUserManager))); 794 return um; 795 }).when(asUser).getSystemService(Context.USER_SERVICE); 796 return asUser; 797 } 798 setWorkProfile(@onNull final UserHandle userHandle, boolean value)799 public void setWorkProfile(@NonNull final UserHandle userHandle, boolean value) { 800 // This relies on all contexts for a given user returning the same UM mock 801 final UserManager umMock = createContextAsUser(userHandle, 0 /* flags */) 802 .getSystemService(UserManager.class); 803 doReturn(value).when(umMock).isManagedProfile(); 804 doReturn(value).when(mUserManager).isManagedProfile(eq(userHandle.getIdentifier())); 805 } 806 setDeviceOwner(@onNull final UserHandle userHandle, String value)807 public void setDeviceOwner(@NonNull final UserHandle userHandle, String value) { 808 // This relies on all contexts for a given user returning the same UM mock 809 final DevicePolicyManager dpmMock = createContextAsUser(userHandle, 0 /* flags */) 810 .getSystemService(DevicePolicyManager.class); 811 ComponentName componentName = value == null 812 ? null : new ComponentName(value, "deviceOwnerClass"); 813 doReturn(componentName).when(dpmMock).getDeviceOwnerComponentOnAnyUser(); 814 doReturn(componentName).when(mDevicePolicyManager).getDeviceOwnerComponentOnAnyUser(); 815 } 816 817 @Override getContentResolver()818 public ContentResolver getContentResolver() { 819 return mContentResolver; 820 } 821 822 @Override getResources()823 public Resources getResources() { 824 return mInternalResources; 825 } 826 827 @Override getPackageManager()828 public PackageManager getPackageManager() { 829 return mPackageManager; 830 } 831 checkMockedPermission(String permission, int pid, int uid, Function3<String, Integer, Integer, Integer> ifAbsent )832 private int checkMockedPermission(String permission, int pid, int uid, 833 Function3<String, Integer, Integer, Integer> ifAbsent /* perm, uid, pid -> int */) { 834 final Integer granted = mMockedPermissions.get(permission + "," + pid + "," + uid); 835 if (null != granted) { 836 return granted; 837 } 838 final Integer allGranted = mMockedPermissions.get(permission); 839 if (null != allGranted) { 840 return allGranted; 841 } 842 return ifAbsent.apply(permission, pid, uid); 843 } 844 845 @Override checkPermission(String permission, int pid, int uid)846 public int checkPermission(String permission, int pid, int uid) { 847 return checkMockedPermission(permission, pid, uid, 848 (perm, p, u) -> super.checkPermission(perm, p, u)); 849 } 850 851 @Override checkCallingOrSelfPermission(String permission)852 public int checkCallingOrSelfPermission(String permission) { 853 return checkMockedPermission(permission, Process.myPid(), Process.myUid(), 854 (perm, p, u) -> super.checkCallingOrSelfPermission(perm)); 855 } 856 857 @Override enforceCallingOrSelfPermission(String permission, String message)858 public void enforceCallingOrSelfPermission(String permission, String message) { 859 final Integer granted = checkMockedPermission(permission, 860 Process.myPid(), Process.myUid(), 861 (perm, p, u) -> { 862 super.enforceCallingOrSelfPermission(perm, message); 863 // enforce will crash if the permission is not granted 864 return PERMISSION_GRANTED; 865 }); 866 867 if (!granted.equals(PERMISSION_GRANTED)) { 868 throw new SecurityException("[Test] permission denied: " + permission); 869 } 870 } 871 872 /** 873 * Mock checks for the specified permission, and have them behave as per {@code granted}. 874 * 875 * This will apply to all calls no matter what the checked UID and PID are. 876 * 877 * <p>Passing null reverts to default behavior, which does a real permission check on the 878 * test package. 879 * @param granted One of {@link PackageManager#PERMISSION_GRANTED} or 880 * {@link PackageManager#PERMISSION_DENIED}. 881 */ setPermission(String permission, Integer granted)882 public void setPermission(String permission, Integer granted) { 883 mMockedPermissions.put(permission, granted); 884 } 885 886 /** 887 * Mock checks for the specified permission, and have them behave as per {@code granted}. 888 * 889 * This will only apply to the passed UID and PID. 890 * 891 * <p>Passing null reverts to default behavior, which does a real permission check on the 892 * test package. 893 * @param granted One of {@link PackageManager#PERMISSION_GRANTED} or 894 * {@link PackageManager#PERMISSION_DENIED}. 895 */ setPermission(String permission, int pid, int uid, Integer granted)896 public void setPermission(String permission, int pid, int uid, Integer granted) { 897 final String key = permission + "," + pid + "," + uid; 898 mMockedPermissions.put(key, granted); 899 } 900 901 @Override registerReceiverForAllUsers(@ullable BroadcastReceiver receiver, @NonNull IntentFilter filter, @Nullable String broadcastPermission, @Nullable Handler scheduler)902 public Intent registerReceiverForAllUsers(@Nullable BroadcastReceiver receiver, 903 @NonNull IntentFilter filter, @Nullable String broadcastPermission, 904 @Nullable Handler scheduler) { 905 // TODO: ensure MultinetworkPolicyTracker's BroadcastReceiver is tested; just returning 906 // null should not pass the test 907 return null; 908 } 909 910 @Override sendStickyBroadcast(Intent intent, Bundle options)911 public void sendStickyBroadcast(Intent intent, Bundle options) { 912 // Verify that delivery group policy APIs were used on U. 913 if (mDeps.isAtLeastU() && CONNECTIVITY_ACTION.equals(intent.getAction())) { 914 final NetworkInfo ni = intent.getParcelableExtra(EXTRA_NETWORK_INFO, 915 NetworkInfo.class); 916 try { 917 verify(mBroadcastOptionsShim).setDeliveryGroupPolicy( 918 eq(ConstantsShim.DELIVERY_GROUP_POLICY_MOST_RECENT)); 919 verify(mBroadcastOptionsShim).setDeliveryGroupMatchingKey( 920 eq(CONNECTIVITY_ACTION), 921 eq(createDeliveryGroupKeyForConnectivityAction(ni))); 922 verify(mBroadcastOptionsShim).setDeferralPolicy( 923 eq(ConstantsShim.DEFERRAL_POLICY_UNTIL_ACTIVE)); 924 } catch (UnsupportedApiLevelException e) { 925 throw new RuntimeException(e); 926 } 927 } 928 super.sendStickyBroadcast(intent, options); 929 } 930 931 private final ArrayTrackRecord<Intent>.ReadHead mOrderedBroadcastAsUserHistory = 932 new ArrayTrackRecord<Intent>().newReadHead(); 933 expectDataActivityBroadcast(int deviceType, boolean isActive, long tsNanos)934 public void expectDataActivityBroadcast(int deviceType, boolean isActive, long tsNanos) { 935 assertNotNull(mOrderedBroadcastAsUserHistory.poll(BROADCAST_TIMEOUT_MS, 936 intent -> intent.getAction().equals(ACTION_DATA_ACTIVITY_CHANGE) 937 && intent.getIntExtra(EXTRA_DEVICE_TYPE, -1) == deviceType 938 && intent.getBooleanExtra(EXTRA_IS_ACTIVE, !isActive) == isActive 939 && intent.getLongExtra(EXTRA_REALTIME_NS, -1) == tsNanos 940 )); 941 } 942 943 @Override sendOrderedBroadcastAsUser(Intent intent, UserHandle user, String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)944 public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user, 945 String receiverPermission, BroadcastReceiver resultReceiver, 946 Handler scheduler, int initialCode, String initialData, Bundle initialExtras) { 947 mOrderedBroadcastAsUserHistory.add(intent); 948 } 949 } 950 951 // This was only added in the T SDK, but this test needs to build against the R+S SDKs, too. toSdkSandboxUid(int appUid)952 private static int toSdkSandboxUid(int appUid) { 953 final int firstSdkSandboxUid = 20000; 954 return appUid + (firstSdkSandboxUid - Process.FIRST_APPLICATION_UID); 955 } 956 957 // Create the list of ranges for the primary user (User 0), excluding excludedUids. intRangesPrimaryExcludingUids(List<Integer> excludedUids)958 private static List<Range<Integer>> intRangesPrimaryExcludingUids(List<Integer> excludedUids) { 959 final List<Integer> excludedUidsList = new ArrayList<>(excludedUids); 960 // Uid 0 is always excluded 961 if (!excludedUidsList.contains(0)) { 962 excludedUidsList.add(0); 963 } 964 return intRangesExcludingUids(PRIMARY_USER, excludedUidsList); 965 } 966 intRangesExcludingUids(int userId, List<Integer> excludedAppIds)967 private static List<Range<Integer>> intRangesExcludingUids(int userId, 968 List<Integer> excludedAppIds) { 969 final List<Integer> excludedUids = CollectionUtils.map(excludedAppIds, 970 appId -> UserHandle.getUid(userId, appId)); 971 final int userBase = userId * UserHandle.PER_USER_RANGE; 972 final int maxUid = userBase + UserHandle.PER_USER_RANGE - 1; 973 974 int start = userBase; 975 Collections.sort(excludedUids); 976 final List<Range<Integer>> ranges = new ArrayList<>(); 977 for (int excludedUid : excludedUids) { 978 if (excludedUid == start) { 979 start++; 980 } else { 981 ranges.add(new Range<>(start, excludedUid - 1)); 982 start = excludedUid + 1; 983 } 984 } 985 if (start <= maxUid) { 986 ranges.add(new Range<>(start, maxUid)); 987 } 988 989 return ranges; 990 } 991 waitForIdle()992 private void waitForIdle() { 993 HandlerUtils.waitForIdle(mCsHandlerThread, TIMEOUT_MS); 994 waitForIdle(mCellAgent, TIMEOUT_MS); 995 waitForIdle(mWiFiAgent, TIMEOUT_MS); 996 waitForIdle(mEthernetAgent, TIMEOUT_MS); 997 HandlerUtils.waitForIdle(mCsHandlerThread, TIMEOUT_MS); 998 HandlerUtils.waitForIdle(ConnectivityThread.get(), TIMEOUT_MS); 999 } 1000 waitForIdle(TestNetworkAgentWrapper agent, long timeoutMs)1001 private void waitForIdle(TestNetworkAgentWrapper agent, long timeoutMs) { 1002 if (agent == null) { 1003 return; 1004 } 1005 agent.waitForIdle(timeoutMs); 1006 } 1007 1008 @Test testWaitForIdle()1009 public void testWaitForIdle() throws Exception { 1010 final int attempts = 50; // Causes the test to take about 200ms on bullhead-eng. 1011 1012 // Tests that waitForIdle returns immediately if the service is already idle. 1013 for (int i = 0; i < attempts; i++) { 1014 waitForIdle(); 1015 } 1016 1017 // Bring up a network that we can use to send messages to ConnectivityService. 1018 ExpectedBroadcast b = expectConnectivityAction(TYPE_WIFI, DetailedState.CONNECTED); 1019 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 1020 mWiFiAgent.connect(false); 1021 b.expectBroadcast(); 1022 Network n = mWiFiAgent.getNetwork(); 1023 assertNotNull(n); 1024 1025 // Tests that calling waitForIdle waits for messages to be processed. 1026 for (int i = 0; i < attempts; i++) { 1027 mWiFiAgent.setSignalStrength(i); 1028 waitForIdle(); 1029 assertEquals(i, mCm.getNetworkCapabilities(n).getSignalStrength()); 1030 } 1031 } 1032 1033 // This test has an inherent race condition in it, and cannot be enabled for continuous testing 1034 // or presubmit tests. It is kept for manual runs and documentation purposes. 1035 @Ignore verifyThatNotWaitingForIdleCausesRaceConditions()1036 public void verifyThatNotWaitingForIdleCausesRaceConditions() throws Exception { 1037 // Bring up a network that we can use to send messages to ConnectivityService. 1038 ExpectedBroadcast b = expectConnectivityAction(TYPE_WIFI, DetailedState.CONNECTED); 1039 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 1040 mWiFiAgent.connect(false); 1041 b.expectBroadcast(); 1042 Network n = mWiFiAgent.getNetwork(); 1043 assertNotNull(n); 1044 1045 // Ensure that not calling waitForIdle causes a race condition. 1046 final int attempts = 50; // Causes the test to take about 200ms on bullhead-eng. 1047 for (int i = 0; i < attempts; i++) { 1048 mWiFiAgent.setSignalStrength(i); 1049 if (i != mCm.getNetworkCapabilities(n).getSignalStrength()) { 1050 // We hit a race condition, as expected. Pass the test. 1051 return; 1052 } 1053 } 1054 1055 // No race? There is a bug in this test. 1056 fail("expected race condition at least once in " + attempts + " attempts"); 1057 } 1058 1059 private class TestNetworkAgentWrapper extends NetworkAgentWrapper { 1060 // Note : Please do not add any new instrumentation here. If you need new instrumentation, 1061 // please add it in CSAgentWrapper and use subclasses of CSTest instead of adding more 1062 // tools in ConnectivityServiceTest. 1063 private static final int VALIDATION_RESULT_INVALID = 0; 1064 1065 private static final long DATA_STALL_TIMESTAMP = 10L; 1066 private static final int DATA_STALL_DETECTION_METHOD = 1; 1067 1068 private INetworkMonitor mNetworkMonitor; 1069 private INetworkMonitorCallbacks mNmCallbacks; 1070 private int mNmValidationResult = VALIDATION_RESULT_INVALID; 1071 private int mProbesCompleted; 1072 private int mProbesSucceeded; 1073 private String mNmValidationRedirectUrl = null; 1074 private boolean mNmProvNotificationRequested = false; 1075 1076 private final ConditionVariable mNetworkStatusReceived = new ConditionVariable(); 1077 // Contains the redirectUrl from networkStatus(). Before reading, wait for 1078 // mNetworkStatusReceived. 1079 private String mRedirectUrl; 1080 TestNetworkAgentWrapper(int transport)1081 TestNetworkAgentWrapper(int transport) throws Exception { 1082 this(transport, new LinkProperties(), null /* ncTemplate */, null /* provider */, null); 1083 } 1084 TestNetworkAgentWrapper(int transport, LinkProperties linkProperties)1085 TestNetworkAgentWrapper(int transport, LinkProperties linkProperties) 1086 throws Exception { 1087 this(transport, linkProperties, null /* ncTemplate */, null /* provider */, null); 1088 } 1089 TestNetworkAgentWrapper(int transport, LinkProperties linkProperties, NetworkCapabilities ncTemplate)1090 private TestNetworkAgentWrapper(int transport, LinkProperties linkProperties, 1091 NetworkCapabilities ncTemplate) throws Exception { 1092 this(transport, linkProperties, ncTemplate, null /* provider */, null); 1093 } 1094 TestNetworkAgentWrapper(int transport, LinkProperties linkProperties, NetworkCapabilities ncTemplate, NetworkProvider provider)1095 private TestNetworkAgentWrapper(int transport, LinkProperties linkProperties, 1096 NetworkCapabilities ncTemplate, NetworkProvider provider) throws Exception { 1097 this(transport, linkProperties, ncTemplate, provider /* provider */, null); 1098 } 1099 TestNetworkAgentWrapper(int transport, NetworkAgentWrapper.Callbacks callbacks)1100 private TestNetworkAgentWrapper(int transport, NetworkAgentWrapper.Callbacks callbacks) 1101 throws Exception { 1102 this(transport, new LinkProperties(), null /* ncTemplate */, null /* provider */, 1103 callbacks); 1104 } 1105 TestNetworkAgentWrapper(int transport, LinkProperties linkProperties, NetworkCapabilities ncTemplate, NetworkProvider provider, NetworkAgentWrapper.Callbacks callbacks)1106 private TestNetworkAgentWrapper(int transport, LinkProperties linkProperties, 1107 NetworkCapabilities ncTemplate, NetworkProvider provider, 1108 NetworkAgentWrapper.Callbacks callbacks) throws Exception { 1109 super(transport, linkProperties, ncTemplate, provider, callbacks, mServiceContext); 1110 mCreatedAgents.add(this); 1111 1112 // Waits for the NetworkAgent to be registered, which includes the creation of the 1113 // NetworkMonitor. 1114 waitForIdle(TIMEOUT_MS); 1115 HandlerUtils.waitForIdle(mCsHandlerThread, TIMEOUT_MS); 1116 HandlerUtils.waitForIdle(ConnectivityThread.get(), TIMEOUT_MS); 1117 } 1118 1119 class TestInstrumentedNetworkAgent extends InstrumentedNetworkAgent { TestInstrumentedNetworkAgent(NetworkAgentWrapper wrapper, LinkProperties lp, NetworkAgentConfig nac, NetworkProvider provider)1120 TestInstrumentedNetworkAgent(NetworkAgentWrapper wrapper, LinkProperties lp, 1121 NetworkAgentConfig nac, NetworkProvider provider) { 1122 super(wrapper, lp, nac, provider); 1123 } 1124 1125 @Override networkStatus(int status, String redirectUrl)1126 public void networkStatus(int status, String redirectUrl) { 1127 mRedirectUrl = redirectUrl; 1128 mNetworkStatusReceived.open(); 1129 } 1130 1131 } 1132 1133 @Override makeNetworkAgent(LinkProperties linkProperties, NetworkAgentConfig nac, NetworkProvider provider)1134 protected InstrumentedNetworkAgent makeNetworkAgent(LinkProperties linkProperties, 1135 NetworkAgentConfig nac, NetworkProvider provider) throws Exception { 1136 mNetworkMonitor = mock(INetworkMonitor.class); 1137 1138 final Answer validateAnswer = inv -> { 1139 new Thread(ignoreExceptions(this::onValidationRequested)).start(); 1140 return null; 1141 }; 1142 1143 doAnswer(validateAnswer).when(mNetworkMonitor).notifyNetworkConnected(any(), any()); 1144 doAnswer(validateAnswer).when(mNetworkMonitor).notifyNetworkConnectedParcel(any()); 1145 doAnswer(validateAnswer).when(mNetworkMonitor).forceReevaluation(anyInt()); 1146 1147 final ArgumentCaptor<Network> nmNetworkCaptor = ArgumentCaptor.forClass(Network.class); 1148 final ArgumentCaptor<INetworkMonitorCallbacks> nmCbCaptor = 1149 ArgumentCaptor.forClass(INetworkMonitorCallbacks.class); 1150 doNothing().when(mNetworkStack).makeNetworkMonitor( 1151 nmNetworkCaptor.capture(), 1152 any() /* name */, 1153 nmCbCaptor.capture()); 1154 1155 final InstrumentedNetworkAgent na = 1156 new TestInstrumentedNetworkAgent(this, linkProperties, nac, provider); 1157 1158 assertEquals(na.getNetwork().netId, nmNetworkCaptor.getValue().netId); 1159 mNmCallbacks = nmCbCaptor.getValue(); 1160 1161 mNmCallbacks.onNetworkMonitorCreated(mNetworkMonitor); 1162 1163 return na; 1164 } 1165 onValidationRequested()1166 private void onValidationRequested() throws Exception { 1167 if (mDeps.isAtLeastT()) { 1168 verify(mNetworkMonitor).notifyNetworkConnectedParcel(any()); 1169 } else { 1170 verify(mNetworkMonitor).notifyNetworkConnected(any(), any()); 1171 } 1172 if (mNmProvNotificationRequested 1173 && ((mNmValidationResult & NETWORK_VALIDATION_RESULT_VALID) != 0)) { 1174 mNmCallbacks.hideProvisioningNotification(); 1175 mNmProvNotificationRequested = false; 1176 } 1177 1178 mNmCallbacks.notifyProbeStatusChanged(mProbesCompleted, mProbesSucceeded); 1179 final NetworkTestResultParcelable p = new NetworkTestResultParcelable(); 1180 p.result = mNmValidationResult; 1181 p.probesAttempted = mProbesCompleted; 1182 p.probesSucceeded = mProbesSucceeded; 1183 p.redirectUrl = mNmValidationRedirectUrl; 1184 p.timestampMillis = TIMESTAMP; 1185 mNmCallbacks.notifyNetworkTestedWithExtras(p); 1186 1187 if (mNmValidationRedirectUrl != null) { 1188 mNmCallbacks.showProvisioningNotification( 1189 "test_provisioning_notif_action", TEST_PACKAGE_NAME); 1190 mNmProvNotificationRequested = true; 1191 } 1192 } 1193 1194 /** 1195 * Connect without adding any internet capability. 1196 */ connectWithoutInternet()1197 public void connectWithoutInternet() { 1198 super.connect(); 1199 } 1200 1201 /** 1202 * Transition this NetworkAgent to CONNECTED state with NET_CAPABILITY_INTERNET. 1203 * @param validated Indicate if network should pretend to be validated. 1204 */ connect(boolean validated)1205 public void connect(boolean validated) { 1206 connect(validated, true, false /* privateDnsProbeSent */); 1207 } 1208 1209 /** 1210 * Transition this NetworkAgent to CONNECTED state. 1211 * 1212 * @param validated Indicate if network should pretend to be validated. 1213 * Note that if this is true, this method will mock the NetworkMonitor 1214 * probes to pretend the network is invalid after it validated once, 1215 * so that subsequent attempts (with mNetworkMonitor.forceReevaluation) 1216 * will fail unless setNetworkValid is called again manually. 1217 * @param hasInternet Indicate if network should pretend to have NET_CAPABILITY_INTERNET. 1218 * @param privateDnsProbeSent whether the private DNS probe should be considered to have 1219 * been sent, assuming |validated| is true. 1220 * If |validated| is false, |privateDnsProbeSent| is not used. 1221 * If |validated| is true and |privateDnsProbeSent| is false, 1222 * the probe has not been sent. 1223 * If |validated| is true and |privateDnsProbeSent| is true, 1224 * the probe has been sent and has succeeded. When the NM probes 1225 * are mocked to be invalid, private DNS is the reason this 1226 * network is invalid ; see @param |validated|. 1227 */ connect(boolean validated, boolean hasInternet, boolean privateDnsProbeSent)1228 public void connect(boolean validated, boolean hasInternet, 1229 boolean privateDnsProbeSent) { 1230 final ConditionVariable validatedCv = new ConditionVariable(); 1231 final ConditionVariable capsChangedCv = new ConditionVariable(); 1232 final NetworkRequest request = new NetworkRequest.Builder() 1233 .addTransportType(getNetworkCapabilities().getTransportTypes()[0]) 1234 .clearCapabilities() 1235 .build(); 1236 if (validated) { 1237 setNetworkValid(privateDnsProbeSent); 1238 } 1239 final NetworkCallback callback = new NetworkCallback() { 1240 public void onCapabilitiesChanged(Network network, 1241 NetworkCapabilities networkCapabilities) { 1242 if (network.equals(getNetwork())) { 1243 capsChangedCv.open(); 1244 if (networkCapabilities.hasCapability(NET_CAPABILITY_VALIDATED)) { 1245 validatedCv.open(); 1246 } 1247 } 1248 } 1249 }; 1250 mCm.registerNetworkCallback(request, callback); 1251 1252 if (hasInternet) { 1253 addCapability(NET_CAPABILITY_INTERNET); 1254 } 1255 1256 connectWithoutInternet(); 1257 waitFor(capsChangedCv); 1258 1259 if (validated) { 1260 // Wait for network to validate. 1261 waitFor(validatedCv); 1262 setNetworkInvalid(privateDnsProbeSent); 1263 } 1264 mCm.unregisterNetworkCallback(callback); 1265 } 1266 connectWithCaptivePortal(String redirectUrl, boolean privateDnsProbeSent)1267 public void connectWithCaptivePortal(String redirectUrl, 1268 boolean privateDnsProbeSent) { 1269 setNetworkPortal(redirectUrl, privateDnsProbeSent); 1270 connect(false, true /* hasInternet */, privateDnsProbeSent); 1271 } 1272 connectWithPartialConnectivity()1273 public void connectWithPartialConnectivity() { 1274 setNetworkPartial(); 1275 connect(false); 1276 } 1277 connectWithPartialValidConnectivity(boolean privateDnsProbeSent)1278 public void connectWithPartialValidConnectivity(boolean privateDnsProbeSent) { 1279 setNetworkPartialValid(privateDnsProbeSent); 1280 connect(false, true /* hasInternet */, privateDnsProbeSent); 1281 } 1282 setNetworkValid(boolean privateDnsProbeSent)1283 void setNetworkValid(boolean privateDnsProbeSent) { 1284 mNmValidationResult = NETWORK_VALIDATION_RESULT_VALID; 1285 mNmValidationRedirectUrl = null; 1286 int probesSucceeded = NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS; 1287 if (privateDnsProbeSent) { 1288 probesSucceeded |= NETWORK_VALIDATION_PROBE_PRIVDNS; 1289 } 1290 // The probesCompleted equals to probesSucceeded for the case of valid network, so put 1291 // the same value into two different parameter of the method. 1292 setProbesStatus(probesSucceeded, probesSucceeded); 1293 } 1294 setNetworkInvalid(boolean invalidBecauseOfPrivateDns)1295 void setNetworkInvalid(boolean invalidBecauseOfPrivateDns) { 1296 mNmValidationResult = VALIDATION_RESULT_INVALID; 1297 mNmValidationRedirectUrl = null; 1298 int probesCompleted = NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS 1299 | NETWORK_VALIDATION_PROBE_HTTP; 1300 int probesSucceeded = 0; 1301 // If |invalidBecauseOfPrivateDns| is true, it means the network is invalid because 1302 // NetworkMonitor tried to validate the private DNS but failed. Therefore it 1303 // didn't get a chance to try the HTTP probe. 1304 if (invalidBecauseOfPrivateDns) { 1305 probesCompleted &= ~NETWORK_VALIDATION_PROBE_HTTP; 1306 probesSucceeded = probesCompleted; 1307 probesCompleted |= NETWORK_VALIDATION_PROBE_PRIVDNS; 1308 } 1309 setProbesStatus(probesCompleted, probesSucceeded); 1310 } 1311 setNetworkPortal(String redirectUrl, boolean privateDnsProbeSent)1312 void setNetworkPortal(String redirectUrl, boolean privateDnsProbeSent) { 1313 setNetworkInvalid(privateDnsProbeSent); 1314 mNmValidationRedirectUrl = redirectUrl; 1315 // Suppose the portal is found when NetworkMonitor probes NETWORK_VALIDATION_PROBE_HTTP 1316 // in the beginning, so the NETWORK_VALIDATION_PROBE_HTTPS hasn't probed yet. 1317 int probesCompleted = NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTP; 1318 int probesSucceeded = VALIDATION_RESULT_INVALID; 1319 if (privateDnsProbeSent) { 1320 probesCompleted |= NETWORK_VALIDATION_PROBE_PRIVDNS; 1321 } 1322 setProbesStatus(probesCompleted, probesSucceeded); 1323 } 1324 setNetworkPartial()1325 void setNetworkPartial() { 1326 mNmValidationResult = NETWORK_VALIDATION_RESULT_PARTIAL; 1327 mNmValidationRedirectUrl = null; 1328 int probesCompleted = NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS 1329 | NETWORK_VALIDATION_PROBE_FALLBACK; 1330 int probesSucceeded = NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_FALLBACK; 1331 setProbesStatus(probesCompleted, probesSucceeded); 1332 } 1333 setNetworkPartialValid(boolean privateDnsProbeSent)1334 void setNetworkPartialValid(boolean privateDnsProbeSent) { 1335 setNetworkPartial(); 1336 mNmValidationResult |= NETWORK_VALIDATION_RESULT_VALID; 1337 mNmValidationRedirectUrl = null; 1338 int probesCompleted = NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS 1339 | NETWORK_VALIDATION_PROBE_HTTP; 1340 int probesSucceeded = NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTP; 1341 // Assume the partial network cannot pass the private DNS validation as well, so only 1342 // add NETWORK_VALIDATION_PROBE_DNS in probesCompleted but not probesSucceeded. 1343 if (privateDnsProbeSent) { 1344 probesCompleted |= NETWORK_VALIDATION_PROBE_PRIVDNS; 1345 } 1346 setProbesStatus(probesCompleted, probesSucceeded); 1347 } 1348 setProbesStatus(int probesCompleted, int probesSucceeded)1349 void setProbesStatus(int probesCompleted, int probesSucceeded) { 1350 mProbesCompleted = probesCompleted; 1351 mProbesSucceeded = probesSucceeded; 1352 } 1353 notifyCapportApiDataChanged(CaptivePortalData data)1354 void notifyCapportApiDataChanged(CaptivePortalData data) { 1355 try { 1356 mNmCallbacks.notifyCaptivePortalDataChanged(data); 1357 } catch (RemoteException e) { 1358 throw new AssertionError("This cannot happen", e); 1359 } 1360 } 1361 waitForRedirectUrl()1362 public String waitForRedirectUrl() { 1363 assertTrue(mNetworkStatusReceived.block(TIMEOUT_MS)); 1364 return mRedirectUrl; 1365 } 1366 expectDisconnected()1367 public void expectDisconnected() { 1368 expectDisconnected(TIMEOUT_MS); 1369 } 1370 expectPreventReconnectReceived()1371 public void expectPreventReconnectReceived() { 1372 expectPreventReconnectReceived(TIMEOUT_MS); 1373 } 1374 notifyDataStallSuspected()1375 void notifyDataStallSuspected() throws Exception { 1376 final DataStallReportParcelable p = new DataStallReportParcelable(); 1377 p.detectionMethod = DATA_STALL_DETECTION_METHOD; 1378 p.timestampMillis = DATA_STALL_TIMESTAMP; 1379 mNmCallbacks.notifyDataStallSuspected(p); 1380 } 1381 } 1382 1383 /** 1384 * A NetworkFactory that allows to wait until any in-flight NetworkRequest add or remove 1385 * operations have been processed and test for them. 1386 */ 1387 private static class MockNetworkFactory extends NetworkFactory { 1388 // Note : Please do not add any new instrumentation here. If you need new instrumentation, 1389 // please add it in CSTest and use subclasses of CSTest instead of adding more 1390 // tools in ConnectivityServiceTest. 1391 private final AtomicBoolean mNetworkStarted = new AtomicBoolean(false); 1392 1393 static class RequestEntry { 1394 @NonNull 1395 public final NetworkRequest request; 1396 RequestEntry(@onNull final NetworkRequest request)1397 RequestEntry(@NonNull final NetworkRequest request) { 1398 this.request = request; 1399 } 1400 1401 static final class Add extends RequestEntry { Add(@onNull final NetworkRequest request)1402 Add(@NonNull final NetworkRequest request) { 1403 super(request); 1404 } 1405 } 1406 1407 static final class Remove extends RequestEntry { Remove(@onNull final NetworkRequest request)1408 Remove(@NonNull final NetworkRequest request) { 1409 super(request); 1410 } 1411 } 1412 1413 @Override toString()1414 public String toString() { 1415 return "RequestEntry [ " + getClass().getName() + " : " + request + " ]"; 1416 } 1417 } 1418 1419 // History of received requests adds and removes. 1420 private final ArrayTrackRecord<RequestEntry>.ReadHead mRequestHistory = 1421 new ArrayTrackRecord<RequestEntry>().newReadHead(); 1422 failIfNull(@ullable final T obj, @Nullable final String message)1423 private static <T> T failIfNull(@Nullable final T obj, @Nullable final String message) { 1424 if (null == obj) fail(null != message ? message : "Must not be null"); 1425 return obj; 1426 } 1427 expectRequestAdd()1428 public RequestEntry.Add expectRequestAdd() { 1429 return failIfNull((RequestEntry.Add) mRequestHistory.poll(TIMEOUT_MS, 1430 it -> it instanceof RequestEntry.Add), "Expected request add"); 1431 } 1432 expectRequestAdds(final int count)1433 public void expectRequestAdds(final int count) { 1434 for (int i = count; i > 0; --i) { 1435 expectRequestAdd(); 1436 } 1437 } 1438 expectRequestRemove()1439 public RequestEntry.Remove expectRequestRemove() { 1440 return failIfNull((RequestEntry.Remove) mRequestHistory.poll(TIMEOUT_MS, 1441 it -> it instanceof RequestEntry.Remove), "Expected request remove"); 1442 } 1443 expectRequestRemoves(final int count)1444 public void expectRequestRemoves(final int count) { 1445 for (int i = count; i > 0; --i) { 1446 expectRequestRemove(); 1447 } 1448 } 1449 1450 // Used to collect the networks requests managed by this factory. This is a duplicate of 1451 // the internal information stored in the NetworkFactory (which is private). 1452 private SparseArray<NetworkRequest> mNetworkRequests = new SparseArray<>(); 1453 private final HandlerThread mHandlerSendingRequests; 1454 MockNetworkFactory(Looper looper, Context context, String logTag, NetworkCapabilities filter, HandlerThread threadSendingRequests)1455 public MockNetworkFactory(Looper looper, Context context, String logTag, 1456 NetworkCapabilities filter, HandlerThread threadSendingRequests) { 1457 super(looper, context, logTag, filter); 1458 mHandlerSendingRequests = threadSendingRequests; 1459 } 1460 getMyRequestCount()1461 public int getMyRequestCount() { 1462 return getRequestCount(); 1463 } 1464 startNetwork()1465 protected void startNetwork() { 1466 mNetworkStarted.set(true); 1467 } 1468 stopNetwork()1469 protected void stopNetwork() { 1470 mNetworkStarted.set(false); 1471 } 1472 getMyStartRequested()1473 public boolean getMyStartRequested() { 1474 return mNetworkStarted.get(); 1475 } 1476 1477 1478 @Override needNetworkFor(NetworkRequest request)1479 protected void needNetworkFor(NetworkRequest request) { 1480 mNetworkRequests.put(request.requestId, request); 1481 super.needNetworkFor(request); 1482 mRequestHistory.add(new RequestEntry.Add(request)); 1483 } 1484 1485 @Override releaseNetworkFor(NetworkRequest request)1486 protected void releaseNetworkFor(NetworkRequest request) { 1487 mNetworkRequests.remove(request.requestId); 1488 super.releaseNetworkFor(request); 1489 mRequestHistory.add(new RequestEntry.Remove(request)); 1490 } 1491 assertRequestCountEquals(final int count)1492 public void assertRequestCountEquals(final int count) { 1493 assertEquals(count, getMyRequestCount()); 1494 } 1495 1496 // Trigger releasing the request as unfulfillable triggerUnfulfillable(NetworkRequest r)1497 public void triggerUnfulfillable(NetworkRequest r) { 1498 super.releaseRequestAsUnfulfillableByAnyFactory(r); 1499 } 1500 assertNoRequestChanged()1501 public void assertNoRequestChanged() { 1502 // Make sure there are no remaining requests unaccounted for. 1503 HandlerUtils.waitForIdle(mHandlerSendingRequests, TIMEOUT_MS); 1504 assertNull(mRequestHistory.poll(0, r -> true)); 1505 } 1506 } 1507 uidRangesForUids(int... uids)1508 private Set<UidRange> uidRangesForUids(int... uids) { 1509 final ArraySet<UidRange> ranges = new ArraySet<>(); 1510 for (final int uid : uids) { 1511 ranges.add(new UidRange(uid, uid)); 1512 } 1513 return ranges; 1514 } 1515 uidRangesForUids(Collection<Integer> uids)1516 private Set<UidRange> uidRangesForUids(Collection<Integer> uids) { 1517 return uidRangesForUids(CollectionUtils.toIntArray(uids)); 1518 } 1519 1520 // Helper class to mock vpn interaction. 1521 private class MockVpn implements TestableNetworkCallback.HasNetwork { 1522 // Note : Please do not add any new instrumentation here. If you need new instrumentation, 1523 // please add it in CSTest and use subclasses of CSTest instead of adding more 1524 // tools in ConnectivityServiceTest. 1525 1526 // Careful ! This is different from mNetworkAgent, because MockNetworkAgent does 1527 // not inherit from NetworkAgent. 1528 private TestNetworkAgentWrapper mMockNetworkAgent; 1529 // Initialize a stored NetworkCapabilities following the defaults of VPN. The TransportInfo 1530 // should at least be updated to a valid VPN type before usage, see registerAgent(...). 1531 private NetworkCapabilities mNetworkCapabilities = new NetworkCapabilities.Builder() 1532 .addTransportType(NetworkCapabilities.TRANSPORT_VPN) 1533 .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN) 1534 .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED) 1535 .setTransportInfo(new VpnTransportInfo( 1536 VpnManager.TYPE_VPN_NONE, 1537 null /* sessionId */, 1538 false /* bypassable */, 1539 false /* longLivedTcpConnectionsExpensive */)) 1540 .build(); 1541 private boolean mAgentRegistered = false; 1542 1543 private int mVpnType = VpnManager.TYPE_VPN_SERVICE; 1544 private String mSessionKey; 1545 setUids(Set<UidRange> uids)1546 public void setUids(Set<UidRange> uids) { 1547 mNetworkCapabilities.setUids(UidRange.toIntRanges(uids)); 1548 if (mAgentRegistered) { 1549 mMockNetworkAgent.setNetworkCapabilities(mNetworkCapabilities, true); 1550 } 1551 } 1552 setVpnType(int vpnType)1553 public void setVpnType(int vpnType) { 1554 mVpnType = vpnType; 1555 } 1556 getNetwork()1557 public Network getNetwork() { 1558 return (mMockNetworkAgent == null) ? null : mMockNetworkAgent.getNetwork(); 1559 } 1560 getNetworkAgentConfig()1561 public NetworkAgentConfig getNetworkAgentConfig() { 1562 return null == mMockNetworkAgent ? null : mMockNetworkAgent.getNetworkAgentConfig(); 1563 } 1564 getActiveVpnType()1565 public int getActiveVpnType() { 1566 return mVpnType; 1567 } 1568 makeLinkProperties()1569 private LinkProperties makeLinkProperties() { 1570 final LinkProperties lp = new LinkProperties(); 1571 lp.setInterfaceName(VPN_IFNAME); 1572 return lp; 1573 } 1574 registerAgent(boolean isAlwaysMetered, Set<UidRange> uids, LinkProperties lp)1575 private void registerAgent(boolean isAlwaysMetered, Set<UidRange> uids, LinkProperties lp) 1576 throws Exception { 1577 if (mAgentRegistered) throw new IllegalStateException("already registered"); 1578 final String session = "MySession12345"; 1579 setUids(uids); 1580 if (!isAlwaysMetered) mNetworkCapabilities.addCapability(NET_CAPABILITY_NOT_METERED); 1581 mNetworkCapabilities.setTransportInfo(new VpnTransportInfo(getActiveVpnType(), 1582 session)); 1583 mMockNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_VPN, lp, 1584 mNetworkCapabilities); 1585 mMockNetworkAgent.waitForIdle(TIMEOUT_MS); 1586 1587 verify(mMockNetd, times(1)).networkAddUidRangesParcel( 1588 new NativeUidRangeConfig(mMockVpn.getNetwork().getNetId(), 1589 toUidRangeStableParcels(uids), PREFERENCE_ORDER_VPN)); 1590 verify(mMockNetd, never()).networkRemoveUidRangesParcel(argThat(config -> 1591 mMockVpn.getNetwork().getNetId() == config.netId 1592 && PREFERENCE_ORDER_VPN == config.subPriority)); 1593 mAgentRegistered = true; 1594 verify(mMockNetd).networkCreate(nativeNetworkConfigVpn(getNetwork().netId, 1595 !mMockNetworkAgent.isBypassableVpn(), mVpnType)); 1596 mNetworkCapabilities.set(mMockNetworkAgent.getNetworkCapabilities()); 1597 } 1598 registerAgent(Set<UidRange> uids)1599 private void registerAgent(Set<UidRange> uids) throws Exception { 1600 registerAgent(false /* isAlwaysMetered */, uids, makeLinkProperties()); 1601 } 1602 connect(boolean validated, boolean hasInternet, boolean privateDnsProbeSent)1603 private void connect(boolean validated, boolean hasInternet, 1604 boolean privateDnsProbeSent) { 1605 mMockNetworkAgent.connect(validated, hasInternet, privateDnsProbeSent); 1606 } 1607 connect(boolean validated)1608 private void connect(boolean validated) { 1609 mMockNetworkAgent.connect(validated); 1610 } 1611 getAgent()1612 private TestNetworkAgentWrapper getAgent() { 1613 return mMockNetworkAgent; 1614 } 1615 setOwnerAndAdminUid(int uid)1616 private void setOwnerAndAdminUid(int uid) throws Exception { 1617 mNetworkCapabilities.setOwnerUid(uid); 1618 mNetworkCapabilities.setAdministratorUids(new int[]{uid}); 1619 } 1620 establish(LinkProperties lp, int uid, Set<UidRange> ranges, boolean validated, boolean hasInternet, boolean privateDnsProbeSent)1621 public void establish(LinkProperties lp, int uid, Set<UidRange> ranges, boolean validated, 1622 boolean hasInternet, boolean privateDnsProbeSent) throws Exception { 1623 setOwnerAndAdminUid(uid); 1624 registerAgent(false, ranges, lp); 1625 connect(validated, hasInternet, privateDnsProbeSent); 1626 waitForIdle(); 1627 } 1628 establish(LinkProperties lp, int uid, Set<UidRange> ranges)1629 public void establish(LinkProperties lp, int uid, Set<UidRange> ranges) throws Exception { 1630 establish(lp, uid, ranges, true, true, false); 1631 } 1632 establishForMyUid(LinkProperties lp)1633 public void establishForMyUid(LinkProperties lp) throws Exception { 1634 final int uid = Process.myUid(); 1635 establish(lp, uid, uidRangesForUids(uid), true, true, false); 1636 } 1637 establishForMyUid(boolean validated, boolean hasInternet, boolean privateDnsProbeSent)1638 public void establishForMyUid(boolean validated, boolean hasInternet, 1639 boolean privateDnsProbeSent) throws Exception { 1640 final int uid = Process.myUid(); 1641 establish(makeLinkProperties(), uid, uidRangesForUids(uid), validated, hasInternet, 1642 privateDnsProbeSent); 1643 } 1644 establishForMyUid()1645 public void establishForMyUid() throws Exception { 1646 establishForMyUid(makeLinkProperties()); 1647 } 1648 sendLinkProperties(LinkProperties lp)1649 public void sendLinkProperties(LinkProperties lp) { 1650 mMockNetworkAgent.sendLinkProperties(lp); 1651 } 1652 disconnect()1653 public void disconnect() { 1654 if (mMockNetworkAgent != null) { 1655 mMockNetworkAgent.disconnect(); 1656 } 1657 mAgentRegistered = false; 1658 setUids(null); 1659 // Remove NET_CAPABILITY_INTERNET or MockNetworkAgent will refuse to connect later on. 1660 mNetworkCapabilities.removeCapability(NET_CAPABILITY_INTERNET); 1661 } 1662 startLegacyVpn()1663 private void startLegacyVpn() { 1664 // Do nothing. 1665 } 1666 1667 // Mock the interaction of IkeV2VpnRunner start. In the context of ConnectivityService, 1668 // setVpnDefaultForUids() is the main interaction and a sessionKey is stored. startPlatformVpn()1669 private void startPlatformVpn() { 1670 mSessionKey = UUID.randomUUID().toString(); 1671 // Assuming no disallowed applications 1672 final Set<Range<Integer>> ranges = UidRange.toIntRanges(Set.of(PRIMARY_UIDRANGE)); 1673 mCm.setVpnDefaultForUids(mSessionKey, ranges); 1674 // Wait for vpn network preference updates. 1675 waitForIdle(); 1676 } 1677 startLegacyVpnPrivileged(boolean isIkev2Vpn)1678 public void startLegacyVpnPrivileged(boolean isIkev2Vpn) { 1679 if (isIkev2Vpn) { 1680 startPlatformVpn(); 1681 } else { 1682 startLegacyVpn(); 1683 } 1684 } 1685 stopVpnRunnerPrivileged()1686 public void stopVpnRunnerPrivileged() { 1687 if (mSessionKey != null) { 1688 // Clear vpn network preference. 1689 mCm.setVpnDefaultForUids(mSessionKey, Collections.EMPTY_LIST); 1690 mSessionKey = null; 1691 } 1692 disconnect(); 1693 } 1694 setUnderlyingNetworks(@ullable Network[] networks)1695 public boolean setUnderlyingNetworks(@Nullable Network[] networks) { 1696 if (!mAgentRegistered) return false; 1697 mMockNetworkAgent.setUnderlyingNetworks( 1698 (networks == null) ? null : Arrays.asList(networks)); 1699 return true; 1700 } 1701 } 1702 toUidRangeStableParcels(final @NonNull Set<UidRange> ranges)1703 private UidRangeParcel[] toUidRangeStableParcels(final @NonNull Set<UidRange> ranges) { 1704 return ranges.stream().map( 1705 r -> new UidRangeParcel(r.start, r.stop)).toArray(UidRangeParcel[]::new); 1706 } 1707 intToUidRangeStableParcels(final @NonNull Set<Integer> ranges)1708 private UidRangeParcel[] intToUidRangeStableParcels(final @NonNull Set<Integer> ranges) { 1709 return ranges.stream().map(r -> new UidRangeParcel(r, r)).toArray(UidRangeParcel[]::new); 1710 } 1711 intToUidRangeStableParcels( final @NonNull List<Range<Integer>> ranges)1712 private static UidRangeParcel[] intToUidRangeStableParcels( 1713 final @NonNull List<Range<Integer>> ranges) { 1714 return ranges.stream().map( 1715 r -> new UidRangeParcel(r.getLower(), r.getUpper())).toArray(UidRangeParcel[]::new); 1716 } 1717 assertVpnTransportInfo(NetworkCapabilities nc, int type)1718 private void assertVpnTransportInfo(NetworkCapabilities nc, int type) { 1719 assertNotNull(nc); 1720 final TransportInfo ti = nc.getTransportInfo(); 1721 assertTrue("VPN TransportInfo is not a VpnTransportInfo: " + ti, 1722 ti instanceof VpnTransportInfo); 1723 assertEquals(type, ((VpnTransportInfo) ti).getType()); 1724 1725 } 1726 processBroadcast(Intent intent)1727 private void processBroadcast(Intent intent) { 1728 mServiceContext.sendBroadcast(intent); 1729 waitForIdle(); 1730 } 1731 mockUidNetworkingBlocked()1732 private void mockUidNetworkingBlocked() { 1733 doAnswer(i -> isUidBlocked(mBlockedReasons, i.getArgument(1)) 1734 ).when(mNetworkPolicyManager).isUidNetworkingBlocked(anyInt(), anyBoolean()); 1735 doAnswer(i -> isUidBlocked(mBlockedReasons, i.getArgument(1)) 1736 ).when(mBpfNetMaps).isUidNetworkingBlocked(anyInt(), anyBoolean()); 1737 } 1738 isUidBlocked(int blockedReasons, boolean meteredNetwork)1739 private boolean isUidBlocked(int blockedReasons, boolean meteredNetwork) { 1740 final int blockedOnAllNetworksReason = (blockedReasons & ~BLOCKED_METERED_REASON_MASK); 1741 if (blockedOnAllNetworksReason != BLOCKED_REASON_NONE) { 1742 return true; 1743 } 1744 if (meteredNetwork) { 1745 return blockedReasons != BLOCKED_REASON_NONE; 1746 } 1747 return false; 1748 } 1749 setBlockedReasonChanged(int blockedReasons)1750 private void setBlockedReasonChanged(int blockedReasons) { 1751 mBlockedReasons = blockedReasons; 1752 if (mDeps.isAtLeastV()) { 1753 visibleOnHandlerThread(mCsHandlerThread.getThreadHandler(), 1754 () -> mService.handleBlockedReasonsChanged( 1755 List.of(new Pair<>(Process.myUid(), blockedReasons)) 1756 1757 )); 1758 } else { 1759 mPolicyCallback.onUidBlockedReasonChanged(Process.myUid(), blockedReasons); 1760 } 1761 } 1762 getNat464Xlat(NetworkAgentWrapper mna)1763 private Nat464Xlat getNat464Xlat(NetworkAgentWrapper mna) { 1764 return mService.getNetworkAgentInfoForNetwork(mna.getNetwork()).clatd; 1765 } 1766 1767 private class WrappedMultinetworkPolicyTracker extends MultinetworkPolicyTracker { 1768 volatile int mConfigMeteredMultipathPreference; 1769 WrappedMultinetworkPolicyTracker(Context c, Handler h, Runnable r)1770 WrappedMultinetworkPolicyTracker(Context c, Handler h, Runnable r) { 1771 super(c, h, r, new MultinetworkPolicyTrackerTestDependencies(mResources)); 1772 } 1773 1774 @Override configMeteredMultipathPreference()1775 public int configMeteredMultipathPreference() { 1776 return mConfigMeteredMultipathPreference; 1777 } 1778 } 1779 1780 /** 1781 * Wait up to TIMEOUT_MS for {@code conditionVariable} to open. 1782 * Fails if TIMEOUT_MS goes by before {@code conditionVariable} opens. 1783 */ waitFor(ConditionVariable conditionVariable)1784 static private void waitFor(ConditionVariable conditionVariable) { 1785 if (conditionVariable.block(TIMEOUT_MS)) { 1786 return; 1787 } 1788 fail("ConditionVariable was blocked for more than " + TIMEOUT_MS + "ms"); 1789 } 1790 doAsUid(final int uid, @NonNull final Supplier<T> what)1791 private <T> T doAsUid(final int uid, @NonNull final Supplier<T> what) { 1792 mDeps.setCallingUid(uid); 1793 try { 1794 return what.get(); 1795 } finally { 1796 mDeps.setCallingUid(null); 1797 } 1798 } 1799 doAsUid(final int uid, @NonNull final Runnable what)1800 private void doAsUid(final int uid, @NonNull final Runnable what) { 1801 doAsUid(uid, () -> { 1802 what.run(); return Void.TYPE; 1803 }); 1804 } 1805 registerNetworkCallbackAsUid(NetworkRequest request, NetworkCallback callback, int uid)1806 private void registerNetworkCallbackAsUid(NetworkRequest request, NetworkCallback callback, 1807 int uid) { 1808 doAsUid(uid, () -> { 1809 mCm.registerNetworkCallback(request, callback); 1810 }); 1811 } 1812 registerDefaultNetworkCallbackAsUid(@onNull final NetworkCallback callback, final int uid)1813 private void registerDefaultNetworkCallbackAsUid(@NonNull final NetworkCallback callback, 1814 final int uid) { 1815 doAsUid(uid, () -> { 1816 mCm.registerDefaultNetworkCallback(callback); 1817 waitForIdle(); 1818 }); 1819 } 1820 withPermission(String permission, ThrowingRunnable r)1821 private void withPermission(String permission, ThrowingRunnable r) throws Exception { 1822 try { 1823 mServiceContext.setPermission(permission, PERMISSION_GRANTED); 1824 r.run(); 1825 } finally { 1826 mServiceContext.setPermission(permission, null); 1827 } 1828 } 1829 withPermission(String permission, int pid, int uid, ThrowingRunnable r)1830 private void withPermission(String permission, int pid, int uid, ThrowingRunnable r) 1831 throws Exception { 1832 try { 1833 mServiceContext.setPermission(permission, pid, uid, PERMISSION_GRANTED); 1834 r.run(); 1835 } finally { 1836 mServiceContext.setPermission(permission, pid, uid, null); 1837 } 1838 } 1839 1840 private static final int PRIMARY_USER = 0; 1841 private static final int SECONDARY_USER = 10; 1842 private static final int TERTIARY_USER = 11; 1843 private static final UidRange PRIMARY_UIDRANGE = 1844 UidRange.createForUser(UserHandle.of(PRIMARY_USER)); 1845 private static final int APP1_UID = UserHandle.getUid(PRIMARY_USER, 10100); 1846 private static final int APP2_UID = UserHandle.getUid(PRIMARY_USER, 10101); 1847 private static final int VPN_UID = UserHandle.getUid(PRIMARY_USER, 10043); 1848 private static final UserInfo PRIMARY_USER_INFO = new UserInfo(PRIMARY_USER, "", 1849 UserInfo.FLAG_PRIMARY); 1850 private static final UserHandle PRIMARY_USER_HANDLE = new UserHandle(PRIMARY_USER); 1851 private static final UserHandle SECONDARY_USER_HANDLE = new UserHandle(SECONDARY_USER); 1852 private static final UserHandle TERTIARY_USER_HANDLE = new UserHandle(TERTIARY_USER); 1853 1854 private static final int RESTRICTED_USER = 1; 1855 private static final UidRange RESTRICTED_USER_UIDRANGE = 1856 UidRange.createForUser(UserHandle.of(RESTRICTED_USER)); 1857 private static final UserInfo RESTRICTED_USER_INFO = new UserInfo(RESTRICTED_USER, "", 1858 UserInfo.FLAG_RESTRICTED); 1859 static { 1860 RESTRICTED_USER_INFO.restrictedProfileParentId = PRIMARY_USER; 1861 } 1862 1863 @Before setUp()1864 public void setUp() throws Exception { 1865 mNetIdManager = new TestNetIdManager(); 1866 1867 mContext = InstrumentationRegistry.getContext(); 1868 1869 MockitoAnnotations.initMocks(this); 1870 1871 // Note : Please do not add any new instrumentation here. If you need new instrumentation, 1872 // please add it in CSTest and use subclasses of CSTest instead of adding more 1873 // tools in ConnectivityServiceTest. 1874 doReturn(asList(PRIMARY_USER_INFO)).when(mUserManager).getAliveUsers(); 1875 doReturn(asList(PRIMARY_USER_HANDLE)).when(mUserManager).getUserHandles(anyBoolean()); 1876 doReturn(PRIMARY_USER_INFO).when(mUserManager).getUserInfo(PRIMARY_USER); 1877 // canHaveRestrictedProfile does not take a userId. It applies to the userId of the context 1878 // it was started from, i.e., PRIMARY_USER. 1879 doReturn(true).when(mUserManager).canHaveRestrictedProfile(); 1880 doReturn(RESTRICTED_USER_INFO).when(mUserManager).getUserInfo(RESTRICTED_USER); 1881 1882 final ApplicationInfo applicationInfo = new ApplicationInfo(); 1883 applicationInfo.targetSdkVersion = Build.VERSION_CODES.Q; 1884 doReturn(applicationInfo).when(mPackageManager) 1885 .getApplicationInfoAsUser(anyString(), anyInt(), any()); 1886 doReturn(applicationInfo.targetSdkVersion).when(mPackageManager) 1887 .getTargetSdkVersion(anyString()); 1888 doReturn(new int[0]).when(mSystemConfigManager).getSystemPermissionUids(anyString()); 1889 1890 // InstrumentationTestRunner prepares a looper, but AndroidJUnitRunner does not. 1891 // http://b/25897652 . 1892 if (Looper.myLooper() == null) { 1893 Looper.prepare(); 1894 } 1895 mockDefaultPackages(); 1896 mockHasSystemFeature(FEATURE_WIFI, true); 1897 mockHasSystemFeature(FEATURE_WIFI_DIRECT, true); 1898 mockHasSystemFeature(FEATURE_ETHERNET, true); 1899 doReturn(true).when(mTelephonyManager).isDataCapable(); 1900 1901 FakeSettingsProvider.clearSettingsProvider(); 1902 mServiceContext = new MockContext(InstrumentationRegistry.getContext(), 1903 new FakeSettingsProvider()); 1904 mServiceContext.setUseRegisteredHandlers(true); 1905 mServiceContext.setPermission(NETWORK_FACTORY, PERMISSION_GRANTED); 1906 mServiceContext.setPermission(NETWORK_STACK, PERMISSION_GRANTED); 1907 mServiceContext.setPermission(CONTROL_OEM_PAID_NETWORK_PREFERENCE, PERMISSION_GRANTED); 1908 mServiceContext.setPermission(PACKET_KEEPALIVE_OFFLOAD, PERMISSION_GRANTED); 1909 mServiceContext.setPermission(CONNECTIVITY_USE_RESTRICTED_NETWORKS, PERMISSION_GRANTED); 1910 mServiceContext.setPermission(READ_DEVICE_CONFIG, PERMISSION_GRANTED); 1911 1912 mAlarmManagerThread = new HandlerThread("TestAlarmManager"); 1913 mAlarmManagerThread.start(); 1914 initAlarmManager(mAlarmManager, mAlarmManagerThread.getThreadHandler()); 1915 1916 mCsHandlerThread = new HandlerThread("TestConnectivityService"); 1917 mProxyTracker = new ProxyTracker(mServiceContext, mock(Handler.class), 1918 16 /* EVENT_PROXY_HAS_CHANGED */); 1919 1920 initMockedResources(); 1921 final Context mockResContext = mock(Context.class); 1922 doReturn(mResources).when(mockResContext).getResources(); 1923 ConnectivityResources.setResourcesContextForTest(mockResContext); 1924 mDeps = new ConnectivityServiceDependencies(mockResContext); 1925 mPermDeps = new PermissionMonitorDependencies(); 1926 doReturn(true).when(mMockKeepaliveTrackerDependencies) 1927 .isAddressTranslationEnabled(mServiceContext); 1928 doReturn(new ConnectivityResources(mockResContext)).when(mMockKeepaliveTrackerDependencies) 1929 .createConnectivityResources(mServiceContext); 1930 doReturn(new int[] {1, 3, 0, 0}).when(mMockKeepaliveTrackerDependencies) 1931 .getSupportedKeepalives(mServiceContext); 1932 mAutoOnOffKeepaliveDependencies = 1933 new AutomaticOnOffKeepaliveTrackerDependencies(mServiceContext); 1934 mService = new ConnectivityService(mServiceContext, 1935 mMockDnsResolver, 1936 mock(IpConnectivityLog.class), 1937 mMockNetd, 1938 mDeps, mPermDeps); 1939 mService.mLingerDelayMs = TEST_LINGER_DELAY_MS; 1940 mService.mNascentDelayMs = TEST_NASCENT_DELAY_MS; 1941 1942 mShouldCreateNetworksImmediately = mService.isConnectivityServiceFeatureEnabledForTesting( 1943 QUEUE_NETWORK_AGENT_EVENTS_IN_SYSTEM_SERVER); 1944 1945 if (mDeps.isAtLeastV()) { 1946 verify(mNetworkPolicyManager, never()).registerNetworkPolicyCallback(any(), any()); 1947 mPolicyCallback = null; 1948 } else { 1949 final ArgumentCaptor<NetworkPolicyCallback> policyCallbackCaptor = 1950 ArgumentCaptor.forClass(NetworkPolicyCallback.class); 1951 verify(mNetworkPolicyManager).registerNetworkPolicyCallback(any(), 1952 policyCallbackCaptor.capture()); 1953 mPolicyCallback = policyCallbackCaptor.getValue(); 1954 } 1955 1956 // Create local CM before sending system ready so that we can answer 1957 // getSystemService() correctly. 1958 mCm = new WrappedConnectivityManager(InstrumentationRegistry.getContext(), mService); 1959 mService.systemReadyInternal(); 1960 verify(mMockDnsResolver).registerUnsolicitedEventListener(any()); 1961 1962 mMockVpn = new MockVpn(); 1963 mCm.bindProcessToNetwork(null); 1964 mQosCallbackTracker = mock(QosCallbackTracker.class); 1965 1966 // Ensure that the default setting for Captive Portals is used for most tests 1967 setCaptivePortalMode(ConnectivitySettingsManager.CAPTIVE_PORTAL_MODE_PROMPT); 1968 setAlwaysOnNetworks(false); 1969 setPrivateDnsSettings(PRIVATE_DNS_MODE_OFF, "ignored.example.com"); 1970 1971 mDeps.setChangeIdEnabled( 1972 true, NETWORK_BLOCKED_WITHOUT_INTERNET_PERMISSION, Process.myUid()); 1973 doReturn(PERMISSION_INTERNET).when(mBpfNetMaps).getNetPermForUid(anyInt()); 1974 // Note : Please do not add any new instrumentation here. If you need new instrumentation, 1975 // please add it in CSTest and use subclasses of CSTest instead of adding more 1976 // tools in ConnectivityServiceTest. 1977 } 1978 initMockedResources()1979 private void initMockedResources() { 1980 doReturn(60000).when(mResources).getInteger(R.integer.config_networkTransitionTimeout); 1981 doReturn("").when(mResources).getString(R.string.config_networkCaptivePortalServerUrl); 1982 doReturn(new String[]{ WIFI_WOL_IFNAME }).when(mResources).getStringArray( 1983 R.array.config_wakeonlan_supported_interfaces); 1984 doReturn(new String[] { "0,1", "1,3" }).when(mResources).getStringArray( 1985 R.array.config_networkSupportedKeepaliveCount); 1986 doReturn(new String[0]).when(mResources).getStringArray( 1987 R.array.config_networkNotifySwitches); 1988 doReturn(new int[]{10, 11, 12, 14, 15}).when(mResources).getIntArray( 1989 R.array.config_protectedNetworks); 1990 // We don't test the actual notification value strings, so just return an empty array. 1991 // It doesn't matter what the values are as long as it's not null. 1992 doReturn(new String[0]).when(mResources) 1993 .getStringArray(R.array.network_switch_type_name); 1994 1995 doReturn(R.array.config_networkSupportedKeepaliveCount).when(mResources) 1996 .getIdentifier(eq("config_networkSupportedKeepaliveCount"), eq("array"), any()); 1997 doReturn(R.array.network_switch_type_name).when(mResources) 1998 .getIdentifier(eq("network_switch_type_name"), eq("array"), any()); 1999 doReturn(1).when(mResources).getInteger(R.integer.config_networkAvoidBadWifi); 2000 doReturn(0).when(mResources).getInteger(R.integer.config_activelyPreferBadWifi); 2001 doReturn(true).when(mResources) 2002 .getBoolean(R.bool.config_cellular_radio_timesharing_capable); 2003 doReturn(PACKET_WAKEUP_MARK_MASK).when(mResources).getInteger( 2004 R.integer.config_networkWakeupPacketMask); 2005 doReturn(PACKET_WAKEUP_MARK_MASK).when(mResources).getInteger( 2006 R.integer.config_networkWakeupPacketMark); 2007 } 2008 2009 class ConnectivityServiceDependencies extends ConnectivityService.Dependencies { 2010 final ConnectivityResources mConnRes; 2011 final ArraySet<Pair<Long, Integer>> mEnabledChangeIds = new ArraySet<>(); 2012 2013 // Note : Please do not add any new instrumentation here. If you need new instrumentation, 2014 // please add it in CSTest and use subclasses of CSTest instead of adding more 2015 // tools in ConnectivityServiceTest. ConnectivityServiceDependencies(final Context mockResContext)2016 ConnectivityServiceDependencies(final Context mockResContext) { 2017 mConnRes = new ConnectivityResources(mockResContext); 2018 } 2019 2020 @Override makeHandlerThread(@onNull final String tag)2021 public HandlerThread makeHandlerThread(@NonNull final String tag) { 2022 return mCsHandlerThread; 2023 } 2024 2025 @Override getNetworkStack()2026 public NetworkStackClientBase getNetworkStack() { 2027 return mNetworkStack; 2028 } 2029 2030 @Override makeProxyTracker(final Context context, final Handler handler)2031 public ProxyTracker makeProxyTracker(final Context context, final Handler handler) { 2032 return mProxyTracker; 2033 } 2034 2035 @Override makeNetIdManager()2036 public NetIdManager makeNetIdManager() { 2037 return mNetIdManager; 2038 } 2039 2040 @Override queryUserAccess(final int uid, final Network network, final ConnectivityService cs)2041 public boolean queryUserAccess(final int uid, final Network network, 2042 final ConnectivityService cs) { 2043 return true; 2044 } 2045 2046 @Override makeMultinetworkPolicyTracker(final Context c, final Handler h, final Runnable r)2047 public MultinetworkPolicyTracker makeMultinetworkPolicyTracker(final Context c, 2048 final Handler h, final Runnable r) { 2049 if (null != mPolicyTracker) { 2050 throw new IllegalStateException("Multinetwork policy tracker already initialized"); 2051 } 2052 mPolicyTracker = new WrappedMultinetworkPolicyTracker(mServiceContext, h, r); 2053 return mPolicyTracker; 2054 } 2055 2056 @Override makeAutomaticOnOffKeepaliveTracker(final Context c, final Handler h)2057 public AutomaticOnOffKeepaliveTracker makeAutomaticOnOffKeepaliveTracker(final Context c, 2058 final Handler h) { 2059 return new AutomaticOnOffKeepaliveTracker(c, h, mAutoOnOffKeepaliveDependencies); 2060 } 2061 2062 @Override getResources(final Context ctx)2063 public ConnectivityResources getResources(final Context ctx) { 2064 return mConnRes; 2065 } 2066 2067 @Override makeLocationPermissionChecker(final Context context)2068 public LocationPermissionChecker makeLocationPermissionChecker(final Context context) { 2069 return new LocationPermissionChecker(context) { 2070 @Override 2071 protected int getCurrentUser() { 2072 return runAsShell(CREATE_USERS, () -> super.getCurrentUser()); 2073 } 2074 }; 2075 } 2076 2077 private BiConsumer<Integer, Integer> mCarrierPrivilegesLostListener; 2078 2079 @Override makeCarrierPrivilegeAuthenticator( @onNull final Context context, @NonNull final TelephonyManager tm, final boolean requestRestrictedWifiEnabled, BiConsumer<Integer, Integer> listener, @NonNull final Handler handler)2080 public CarrierPrivilegeAuthenticator makeCarrierPrivilegeAuthenticator( 2081 @NonNull final Context context, 2082 @NonNull final TelephonyManager tm, 2083 final boolean requestRestrictedWifiEnabled, 2084 BiConsumer<Integer, Integer> listener, 2085 @NonNull final Handler handler) { 2086 mCarrierPrivilegesLostListener = listener; 2087 return mDeps.isAtLeastT() ? mCarrierPrivilegeAuthenticator : null; 2088 } 2089 2090 @Override makeSatelliteAccessController( @onNull final Context context, Consumer<Set<Integer>> updateSatelliteNetworkFallbackUidCallback, @NonNull final Handler connectivityServiceInternalHandler)2091 public SatelliteAccessController makeSatelliteAccessController( 2092 @NonNull final Context context, 2093 Consumer<Set<Integer>> updateSatelliteNetworkFallbackUidCallback, 2094 @NonNull final Handler connectivityServiceInternalHandler) { 2095 return mSatelliteAccessController; 2096 } 2097 2098 @Override intentFilterEquals(final PendingIntent a, final PendingIntent b)2099 public boolean intentFilterEquals(final PendingIntent a, final PendingIntent b) { 2100 return runAsShell(GET_INTENT_SENDER_INTENT, () -> a.intentFilterEquals(b)); 2101 } 2102 2103 @GuardedBy("this") 2104 private Integer mCallingUid = null; 2105 2106 @Override getCallingUid()2107 public int getCallingUid() { 2108 synchronized (this) { 2109 if (null != mCallingUid) return mCallingUid; 2110 return super.getCallingUid(); 2111 } 2112 } 2113 2114 // Pass null for the real calling UID setCallingUid(final Integer uid)2115 public void setCallingUid(final Integer uid) { 2116 synchronized (this) { 2117 mCallingUid = uid; 2118 } 2119 } 2120 2121 @GuardedBy("this") 2122 private boolean mCellular464XlatEnabled = true; 2123 2124 @Override getCellular464XlatEnabled()2125 public boolean getCellular464XlatEnabled() { 2126 synchronized (this) { 2127 return mCellular464XlatEnabled; 2128 } 2129 } 2130 setCellular464XlatEnabled(final boolean enabled)2131 public void setCellular464XlatEnabled(final boolean enabled) { 2132 synchronized (this) { 2133 mCellular464XlatEnabled = enabled; 2134 } 2135 } 2136 2137 @GuardedBy("this") 2138 private Integer mConnectionOwnerUid = null; 2139 2140 @Override getConnectionOwnerUid(final int protocol, final InetSocketAddress local, final InetSocketAddress remote)2141 public int getConnectionOwnerUid(final int protocol, final InetSocketAddress local, 2142 final InetSocketAddress remote) { 2143 synchronized (this) { 2144 if (null != mConnectionOwnerUid) return mConnectionOwnerUid; 2145 return super.getConnectionOwnerUid(protocol, local, remote); 2146 } 2147 } 2148 2149 // Pass null to get the production implementation of getConnectionOwnerUid setConnectionOwnerUid(final Integer uid)2150 public void setConnectionOwnerUid(final Integer uid) { 2151 synchronized (this) { 2152 mConnectionOwnerUid = uid; 2153 } 2154 } 2155 2156 final class ReportedInterfaces { 2157 public final Context context; 2158 public final String iface; 2159 public final int[] transportTypes; ReportedInterfaces(final Context c, final String i, final int[] t)2160 ReportedInterfaces(final Context c, final String i, final int[] t) { 2161 context = c; 2162 iface = i; 2163 transportTypes = t; 2164 } 2165 contentEquals(final Context c, final String i, final int[] t)2166 public boolean contentEquals(final Context c, final String i, final int[] t) { 2167 return Objects.equals(context, c) && Objects.equals(iface, i) 2168 && Arrays.equals(transportTypes, t); 2169 } 2170 } 2171 2172 final ArrayTrackRecord<ReportedInterfaces> mReportedInterfaceHistory = 2173 new ArrayTrackRecord<>(); 2174 2175 @Override reportNetworkInterfaceForTransports(final Context context, final String iface, final int[] transportTypes)2176 public void reportNetworkInterfaceForTransports(final Context context, final String iface, 2177 final int[] transportTypes) { 2178 mReportedInterfaceHistory.add(new ReportedInterfaces(context, iface, transportTypes)); 2179 super.reportNetworkInterfaceForTransports(context, iface, transportTypes); 2180 } 2181 2182 @Override isFeatureEnabled(Context context, String name)2183 public boolean isFeatureEnabled(Context context, String name) { 2184 switch (name) { 2185 case ConnectivityFlags.NO_REMATCH_ALL_REQUESTS_ON_REGISTER: 2186 case ConnectivityFlags.CARRIER_SERVICE_CHANGED_USE_CALLBACK: 2187 case ConnectivityFlags.REQUEST_RESTRICTED_WIFI: 2188 case ConnectivityFlags.USE_DECLARED_METHODS_FOR_CALLBACKS: 2189 case ConnectivityFlags.QUEUE_CALLBACKS_FOR_FROZEN_APPS: 2190 case ConnectivityFlags.BACKGROUND_FIREWALL_CHAIN: 2191 case ConnectivityService.KEY_DESTROY_FROZEN_SOCKETS_VERSION: 2192 return true; 2193 default: 2194 // This is a unit test and must never depend on actual device flag values. 2195 throw new UnsupportedOperationException("Unknown flag " + name 2196 + ", update this test"); 2197 } 2198 } 2199 2200 @Override isFeatureNotChickenedOut(Context context, String name)2201 public boolean isFeatureNotChickenedOut(Context context, String name) { 2202 switch (name) { 2203 case ConnectivityService.ALLOW_SYSUI_CONNECTIVITY_REPORTS: 2204 case ConnectivityService.ALLOW_SATALLITE_NETWORK_FALLBACK: 2205 case ConnectivityFlags.INGRESS_TO_VPN_ADDRESS_FILTERING: 2206 case ConnectivityFlags.BACKGROUND_FIREWALL_CHAIN: 2207 case ConnectivityFlags.DELAY_DESTROY_SOCKETS: 2208 case ConnectivityFlags.USE_DECLARED_METHODS_FOR_CALLBACKS: 2209 case ConnectivityFlags.QUEUE_CALLBACKS_FOR_FROZEN_APPS: 2210 case ConnectivityFlags.QUEUE_NETWORK_AGENT_EVENTS_IN_SYSTEM_SERVER: 2211 return true; 2212 default: 2213 throw new UnsupportedOperationException("Unknown flag " + name 2214 + ", update this test"); 2215 } 2216 } 2217 setChangeIdEnabled(final boolean enabled, final long changeId, final int uid)2218 public void setChangeIdEnabled(final boolean enabled, final long changeId, final int uid) { 2219 final Pair<Long, Integer> data = new Pair<>(changeId, uid); 2220 // mEnabledChangeIds is read on the handler thread and maybe the test thread, so 2221 // make sure both threads see it before continuing. 2222 visibleOnHandlerThread(mCsHandlerThread.getThreadHandler(), () -> { 2223 if (enabled) { 2224 mEnabledChangeIds.add(data); 2225 } else { 2226 mEnabledChangeIds.remove(data); 2227 } 2228 }); 2229 } 2230 2231 @Override isChangeEnabled(final long changeId, final int uid)2232 public boolean isChangeEnabled(final long changeId, final int uid) { 2233 return mEnabledChangeIds.contains(new Pair<>(changeId, uid)); 2234 } 2235 2236 // In AOSP, build version codes are all over the place (e.g. at the time of this writing 2237 // U == V). Define custom ones. 2238 private static final int VERSION_UNMOCKED = -1; 2239 private static final int VERSION_R = 1; 2240 private static final int VERSION_S = 2; 2241 private static final int VERSION_T = 3; 2242 private static final int VERSION_U = 4; 2243 private static final int VERSION_V = 5; 2244 private static final int VERSION_B = 6; 2245 private static final int VERSION_MAX = VERSION_B; 2246 private int mSdkLevel = VERSION_UNMOCKED; 2247 setBuildSdk(final int sdkLevel)2248 private void setBuildSdk(final int sdkLevel) { 2249 if (sdkLevel > VERSION_MAX) { 2250 throw new IllegalArgumentException("setBuildSdk must not be called with" 2251 + " Build.VERSION constants but Dependencies.VERSION_* constants"); 2252 } 2253 visibleOnHandlerThread(mCsHandlerThread.getThreadHandler(), () -> mSdkLevel = sdkLevel); 2254 } 2255 2256 @Override isAtLeastS()2257 public boolean isAtLeastS() { 2258 return mSdkLevel == VERSION_UNMOCKED ? super.isAtLeastS() 2259 : mSdkLevel >= VERSION_S; 2260 } 2261 2262 @Override isAtLeastT()2263 public boolean isAtLeastT() { 2264 return mSdkLevel == VERSION_UNMOCKED ? super.isAtLeastT() 2265 : mSdkLevel >= VERSION_T; 2266 } 2267 2268 @Override isAtLeastU()2269 public boolean isAtLeastU() { 2270 return mSdkLevel == VERSION_UNMOCKED ? super.isAtLeastU() 2271 : mSdkLevel >= VERSION_U; 2272 } 2273 2274 @Override isAtLeastB()2275 public boolean isAtLeastB() { 2276 return mSdkLevel == VERSION_UNMOCKED ? super.isAtLeastB() 2277 : mSdkLevel >= VERSION_B; 2278 } 2279 2280 @Override getBpfNetMaps(Context context, INetd netd, InterfaceTracker interfaceTracker)2281 public BpfNetMaps getBpfNetMaps(Context context, INetd netd, 2282 InterfaceTracker interfaceTracker) { 2283 return mBpfNetMaps; 2284 } 2285 2286 @Override getClatCoordinator(INetd netd)2287 public ClatCoordinator getClatCoordinator(INetd netd) { 2288 return mClatCoordinator; 2289 } 2290 2291 final ArrayTrackRecord<Pair<String, Long>> mRateLimitHistory = new ArrayTrackRecord<>(); 2292 final Map<String, Long> mActiveRateLimit = new HashMap<>(); 2293 2294 @Override enableIngressRateLimit(final String iface, final long rateInBytesPerSecond)2295 public void enableIngressRateLimit(final String iface, final long rateInBytesPerSecond) { 2296 mRateLimitHistory.add(new Pair<>(iface, rateInBytesPerSecond)); 2297 // Due to a TC limitation, the rate limit needs to be removed before it can be 2298 // updated. Check that this happened. 2299 assertEquals(-1L, (long) mActiveRateLimit.getOrDefault(iface, -1L)); 2300 mActiveRateLimit.put(iface, rateInBytesPerSecond); 2301 // verify that clsact qdisc has already been created, otherwise attaching a tc police 2302 // filter will fail. 2303 try { 2304 verify(mMockNetd).networkAddInterface(anyInt(), eq(iface)); 2305 } catch (RemoteException e) { 2306 fail(e.getMessage()); 2307 } 2308 } 2309 2310 @Override disableIngressRateLimit(final String iface)2311 public void disableIngressRateLimit(final String iface) { 2312 mRateLimitHistory.add(new Pair<>(iface, -1L)); 2313 assertNotEquals(-1L, (long) mActiveRateLimit.getOrDefault(iface, -1L)); 2314 mActiveRateLimit.put(iface, -1L); 2315 } 2316 2317 @Override getBpfProgramId(final int attachType)2318 public int getBpfProgramId(final int attachType) { 2319 return 0; 2320 } 2321 2322 @Override makeBroadcastOptionsShim(BroadcastOptions options)2323 public BroadcastOptionsShim makeBroadcastOptionsShim(BroadcastOptions options) { 2324 reset(mBroadcastOptionsShim); 2325 return mBroadcastOptionsShim; 2326 } 2327 2328 @GuardedBy("this") 2329 private boolean mForceDisableCompatChangeCheck = true; 2330 2331 /** 2332 * By default, the {@link #isChangeEnabled(long, String, UserHandle)} will always return 2333 * true as the mForceDisableCompatChangeCheck is true and compat change check logic is 2334 * never executed. The compat change check logic can be turned on by calling this method. 2335 * If this method is called, the 2336 * {@link libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges} or 2337 * {@link libcore.junit.util.compat.CoreCompatChangeRule.DisableCompatChanges} must be 2338 * used to turn on/off the compat change flag. 2339 */ enableCompatChangeCheck()2340 private void enableCompatChangeCheck() { 2341 synchronized (this) { 2342 mForceDisableCompatChangeCheck = false; 2343 } 2344 } 2345 2346 @Override isChangeEnabled(long changeId, @NonNull final String packageName, @NonNull final UserHandle user)2347 public boolean isChangeEnabled(long changeId, 2348 @NonNull final String packageName, 2349 @NonNull final UserHandle user) { 2350 synchronized (this) { 2351 if (mForceDisableCompatChangeCheck) { 2352 return false; 2353 } else { 2354 return super.isChangeEnabled(changeId, packageName, user); 2355 } 2356 } 2357 } 2358 2359 // Class to be mocked and used to verify destroy sockets methods call 2360 public class DestroySocketsWrapper { destroyLiveTcpSockets(final Set<Range<Integer>> ranges, final Set<Integer> exemptUids)2361 public void destroyLiveTcpSockets(final Set<Range<Integer>> ranges, 2362 final Set<Integer> exemptUids){} destroyLiveTcpSocketsByOwnerUids(final Set<Integer> ownerUids)2363 public void destroyLiveTcpSocketsByOwnerUids(final Set<Integer> ownerUids){} 2364 } 2365 2366 @Override @SuppressWarnings("DirectInvocationOnMock") destroyLiveTcpSockets(final Set<Range<Integer>> ranges, final Set<Integer> exemptUids)2367 public void destroyLiveTcpSockets(final Set<Range<Integer>> ranges, 2368 final Set<Integer> exemptUids) { 2369 // Call mocked destroyLiveTcpSockets so that test can verify this method call 2370 mDestroySocketsWrapper.destroyLiveTcpSockets(ranges, exemptUids); 2371 } 2372 2373 @Override @SuppressWarnings("DirectInvocationOnMock") destroyLiveTcpSocketsByOwnerUids(final Set<Integer> ownerUids)2374 public void destroyLiveTcpSocketsByOwnerUids(final Set<Integer> ownerUids) { 2375 // Call mocked destroyLiveTcpSocketsByOwnerUids so that test can verify this method call 2376 // Create copy of ownerUids so that tests can verify the correct value even if the 2377 // ConnectivityService update the ownerUids after this method call. 2378 mDestroySocketsWrapper.destroyLiveTcpSocketsByOwnerUids(new ArraySet<>(ownerUids)); 2379 } 2380 2381 final ArrayTrackRecord<Pair<Integer, Long>>.ReadHead mScheduledEvaluationTimeouts = 2382 new ArrayTrackRecord<Pair<Integer, Long>>().newReadHead(); 2383 @Override scheduleEvaluationTimeout(@onNull Handler handler, @NonNull final Network network, final long delayMs)2384 public void scheduleEvaluationTimeout(@NonNull Handler handler, 2385 @NonNull final Network network, final long delayMs) { 2386 mScheduledEvaluationTimeouts.add(new Pair<>(network.netId, delayMs)); 2387 super.scheduleEvaluationTimeout(handler, network, delayMs); 2388 } 2389 2390 @Override getDefaultCellularDataInactivityTimeout()2391 public int getDefaultCellularDataInactivityTimeout() { 2392 // Needed to mock out the dependency on DeviceConfig 2393 return 10; 2394 } 2395 2396 @Override getDefaultWifiDataInactivityTimeout()2397 public int getDefaultWifiDataInactivityTimeout() { 2398 // Needed to mock out the dependency on DeviceConfig 2399 return 15; 2400 } 2401 2402 @Override makeL2capNetworkProvider(Context context)2403 public L2capNetworkProvider makeL2capNetworkProvider(Context context) { 2404 return null; 2405 } 2406 } 2407 2408 static class PermissionMonitorDependencies extends PermissionMonitor.Dependencies { 2409 @Override 2410 public boolean shouldEnforceLocalNetRestrictions(int uid) { 2411 return false; 2412 } 2413 } 2414 2415 private class AutomaticOnOffKeepaliveTrackerDependencies 2416 extends AutomaticOnOffKeepaliveTracker.Dependencies { 2417 AutomaticOnOffKeepaliveTrackerDependencies(Context context) { 2418 super(context); 2419 } 2420 2421 @Override 2422 public boolean isTetheringFeatureNotChickenedOut(@NonNull final String name) { 2423 // Tests for enabling the feature are verified in AutomaticOnOffKeepaliveTrackerTest. 2424 // Assuming enabled here to focus on ConnectivityService tests. 2425 return true; 2426 } 2427 public KeepaliveTracker newKeepaliveTracker(@NonNull Context context, 2428 @NonNull Handler connectivityserviceHander) { 2429 return new KeepaliveTracker(context, connectivityserviceHander, 2430 new TcpKeepaliveController(connectivityserviceHander), 2431 mMockKeepaliveTrackerDependencies); 2432 } 2433 } 2434 2435 private static void initAlarmManager(final AlarmManager am, final Handler alarmHandler) { 2436 doAnswer(inv -> { 2437 final long when = inv.getArgument(1); 2438 final WakeupMessage wakeupMsg = inv.getArgument(3); 2439 final Handler handler = inv.getArgument(4); 2440 2441 long delayMs = when - SystemClock.elapsedRealtime(); 2442 if (delayMs < 0) delayMs = 0; 2443 if (delayMs > UNREASONABLY_LONG_ALARM_WAIT_MS) { 2444 fail("Attempting to send msg more than " + UNREASONABLY_LONG_ALARM_WAIT_MS 2445 + "ms into the future: " + delayMs); 2446 } 2447 alarmHandler.postDelayed(() -> handler.post(wakeupMsg::onAlarm), wakeupMsg /* token */, 2448 delayMs); 2449 2450 return null; 2451 }).when(am).setExact(eq(AlarmManager.ELAPSED_REALTIME_WAKEUP), anyLong(), anyString(), 2452 any(WakeupMessage.class), any()); 2453 2454 doAnswer(inv -> { 2455 final WakeupMessage wakeupMsg = inv.getArgument(0); 2456 alarmHandler.removeCallbacksAndMessages(wakeupMsg /* token */); 2457 return null; 2458 }).when(am).cancel(any(WakeupMessage.class)); 2459 } 2460 2461 @After 2462 public void tearDown() throws Exception { 2463 // Don't attempt to tear down if setUp didn't even get as far as creating the service. 2464 // Otherwise, exceptions here will mask the actual exception in setUp, making failures 2465 // harder to diagnose. 2466 if (mService == null) return; 2467 unregisterDefaultNetworkCallbacks(); 2468 maybeTearDownEnterpriseNetwork(); 2469 setAlwaysOnNetworks(false); 2470 if (mCellAgent != null) { 2471 mCellAgent.disconnect(); 2472 mCellAgent = null; 2473 } 2474 if (mWiFiAgent != null) { 2475 mWiFiAgent.disconnect(); 2476 mWiFiAgent = null; 2477 } 2478 if (mEthernetAgent != null) { 2479 mEthernetAgent.disconnect(); 2480 mEthernetAgent = null; 2481 } 2482 2483 if (mQosCallbackMockHelper != null) { 2484 mQosCallbackMockHelper.tearDown(); 2485 mQosCallbackMockHelper = null; 2486 } 2487 mMockVpn.disconnect(); 2488 waitForIdle(); 2489 2490 FakeSettingsProvider.clearSettingsProvider(); 2491 ConnectivityResources.setResourcesContextForTest(null); 2492 2493 for (TestNetworkAgentWrapper agent : mCreatedAgents) { 2494 agent.destroy(); 2495 } 2496 mCreatedAgents.clear(); 2497 2498 mCsHandlerThread.quitSafely(); 2499 mCsHandlerThread.join(); 2500 mAlarmManagerThread.quitSafely(); 2501 mAlarmManagerThread.join(); 2502 } 2503 2504 private void mockDefaultPackages() throws Exception { 2505 final String myPackageName = mContext.getPackageName(); 2506 final PackageInfo myPackageInfo = mContext.getPackageManager().getPackageInfo( 2507 myPackageName, PackageManager.GET_PERMISSIONS); 2508 myPackageInfo.setLongVersionCode(9_999_999L); 2509 doReturn(new String[] {myPackageName}).when(mPackageManager) 2510 .getPackagesForUid(Binder.getCallingUid()); 2511 doReturn(myPackageInfo).when(mPackageManager).getPackageInfoAsUser( 2512 eq(myPackageName), anyInt(), eq(UserHandle.getCallingUserId())); 2513 2514 doReturn(asList(new PackageInfo[] { 2515 buildPackageInfo(/* SYSTEM */ false, APP1_UID), 2516 buildPackageInfo(/* SYSTEM */ false, APP2_UID), 2517 buildPackageInfo(/* SYSTEM */ false, VPN_UID) 2518 })).when(mPackageManager).getInstalledPackagesAsUser(eq(GET_PERMISSIONS), anyInt()); 2519 2520 final ModuleInfo moduleInfo = new ModuleInfo(); 2521 moduleInfo.setPackageName(TETHERING_MODULE_NAME); 2522 doReturn(moduleInfo).when(mPackageManager) 2523 .getModuleInfo(TETHERING_MODULE_NAME, PackageManager.MODULE_APEX_NAME); 2524 doReturn(myPackageInfo).when(mPackageManager) 2525 .getPackageInfo(TETHERING_MODULE_NAME, PackageManager.MATCH_APEX); 2526 2527 // Create a fake always-on VPN package. 2528 final int userId = UserHandle.getCallingUserId(); 2529 final ApplicationInfo applicationInfo = new ApplicationInfo(); 2530 applicationInfo.targetSdkVersion = Build.VERSION_CODES.R; // Always-on supported in N+. 2531 doReturn(applicationInfo).when(mPackageManager).getApplicationInfoAsUser( 2532 eq(ALWAYS_ON_PACKAGE), anyInt(), eq(userId)); 2533 2534 // Minimal mocking to keep Vpn#isAlwaysOnPackageSupported happy. 2535 ResolveInfo rInfo = new ResolveInfo(); 2536 rInfo.serviceInfo = new ServiceInfo(); 2537 rInfo.serviceInfo.metaData = new Bundle(); 2538 final List<ResolveInfo> services = asList(new ResolveInfo[]{rInfo}); 2539 doReturn(services).when(mPackageManager).queryIntentServicesAsUser( 2540 any(), eq(PackageManager.GET_META_DATA), eq(userId)); 2541 doReturn(Process.myUid()).when(mPackageManager).getPackageUidAsUser( 2542 TEST_PACKAGE_NAME, userId); 2543 doReturn(VPN_UID).when(mPackageManager).getPackageUidAsUser(ALWAYS_ON_PACKAGE, userId); 2544 } 2545 2546 private void verifyActiveNetwork(int transport) { 2547 // Test getActiveNetworkInfo() 2548 assertNotNull(mCm.getActiveNetworkInfo()); 2549 assertEquals(transportToLegacyType(transport), mCm.getActiveNetworkInfo().getType()); 2550 // Test getActiveNetwork() 2551 assertNotNull(mCm.getActiveNetwork()); 2552 assertEquals(mCm.getActiveNetwork(), mCm.getActiveNetworkForUid(Process.myUid())); 2553 if (!NetworkCapabilities.isValidTransport(transport)) { 2554 throw new IllegalStateException("Unknown transport " + transport); 2555 } 2556 switch (transport) { 2557 case TRANSPORT_WIFI: 2558 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetwork()); 2559 break; 2560 case TRANSPORT_CELLULAR: 2561 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetwork()); 2562 break; 2563 case TRANSPORT_ETHERNET: 2564 assertEquals(mEthernetAgent.getNetwork(), mCm.getActiveNetwork()); 2565 break; 2566 default: 2567 break; 2568 } 2569 // Test getNetworkInfo(Network) 2570 assertNotNull(mCm.getNetworkInfo(mCm.getActiveNetwork())); 2571 assertEquals(transportToLegacyType(transport), 2572 mCm.getNetworkInfo(mCm.getActiveNetwork()).getType()); 2573 assertNotNull(mCm.getActiveNetworkInfoForUid(Process.myUid())); 2574 // Test getNetworkCapabilities(Network) 2575 assertNotNull(mCm.getNetworkCapabilities(mCm.getActiveNetwork())); 2576 assertTrue(mCm.getNetworkCapabilities(mCm.getActiveNetwork()).hasTransport(transport)); 2577 } 2578 2579 private void verifyNoNetwork() { 2580 waitForIdle(); 2581 // Test getActiveNetworkInfo() 2582 assertNull(mCm.getActiveNetworkInfo()); 2583 // Test getActiveNetwork() 2584 assertNull(mCm.getActiveNetwork()); 2585 assertNull(mCm.getActiveNetworkForUid(Process.myUid())); 2586 // Test getAllNetworks() 2587 assertEmpty(mCm.getAllNetworks()); 2588 assertEmpty(mCm.getAllNetworkStateSnapshots()); 2589 } 2590 2591 /** 2592 * Class to simplify expecting broadcasts using BroadcastInterceptingContext. 2593 * Ensures that the receiver is unregistered after the expected broadcast is received. This 2594 * cannot be done in the BroadcastReceiver itself because BroadcastInterceptingContext runs 2595 * the receivers' receive method while iterating over the list of receivers, and unregistering 2596 * the receiver during iteration throws ConcurrentModificationException. 2597 */ 2598 private class ExpectedBroadcast extends CompletableFuture<Intent> { 2599 private final BroadcastReceiver mReceiver; 2600 2601 ExpectedBroadcast(BroadcastReceiver receiver) { 2602 mReceiver = receiver; 2603 } 2604 2605 public Intent expectBroadcast(int timeoutMs) throws Exception { 2606 try { 2607 return get(timeoutMs, TimeUnit.MILLISECONDS); 2608 } catch (TimeoutException e) { 2609 fail("Expected broadcast not received after " + timeoutMs + " ms"); 2610 return null; 2611 } finally { 2612 mServiceContext.unregisterReceiver(mReceiver); 2613 } 2614 } 2615 2616 public Intent expectBroadcast() throws Exception { 2617 return expectBroadcast(BROADCAST_TIMEOUT_MS); 2618 } 2619 2620 public void expectNoBroadcast(int timeoutMs) throws Exception { 2621 waitForIdle(); 2622 try { 2623 final Intent intent = get(timeoutMs, TimeUnit.MILLISECONDS); 2624 fail("Unexpected broadcast: " + intent.getAction() + " " + intent.getExtras()); 2625 } catch (TimeoutException expected) { 2626 } finally { 2627 mServiceContext.unregisterReceiver(mReceiver); 2628 } 2629 } 2630 } 2631 2632 private ExpectedBroadcast registerBroadcastReceiverThat(final String action, final int count, 2633 @NonNull final Predicate<Intent> filter) { 2634 final IntentFilter intentFilter = new IntentFilter(action); 2635 // AtomicReference allows receiver to access expected even though it is constructed later. 2636 final AtomicReference<ExpectedBroadcast> expectedRef = new AtomicReference<>(); 2637 final BroadcastReceiver receiver = new BroadcastReceiver() { 2638 private int mRemaining = count; 2639 public void onReceive(Context context, Intent intent) { 2640 logIntent(intent); 2641 if (!filter.test(intent)) return; 2642 if (--mRemaining == 0) { 2643 expectedRef.get().complete(intent); 2644 } 2645 } 2646 }; 2647 final ExpectedBroadcast expected = new ExpectedBroadcast(receiver); 2648 expectedRef.set(expected); 2649 mServiceContext.registerReceiver(receiver, intentFilter); 2650 return expected; 2651 } 2652 2653 private void logIntent(Intent intent) { 2654 final String action = intent.getAction(); 2655 if (CONNECTIVITY_ACTION.equals(action)) { 2656 final int type = intent.getIntExtra(EXTRA_NETWORK_TYPE, -1); 2657 final NetworkInfo ni = intent.getParcelableExtra(EXTRA_NETWORK_INFO); 2658 Log.d(TAG, "Received " + action + ", type=" + type + " ni=" + ni); 2659 } else if (PROXY_CHANGE_ACTION.equals(action)) { 2660 final ProxyInfo proxy = (ProxyInfo) intent.getExtra( 2661 Proxy.EXTRA_PROXY_INFO, ProxyInfo.buildPacProxy(Uri.EMPTY)); 2662 Log.d(TAG, "Received " + action + ", proxy = " + proxy); 2663 } else { 2664 throw new IllegalArgumentException("Unsupported logging " + action); 2665 } 2666 } 2667 2668 /** Expects that {@code count} CONNECTIVITY_ACTION broadcasts are received. */ 2669 private ExpectedBroadcast expectConnectivityAction(final int count) { 2670 return registerBroadcastReceiverThat(CONNECTIVITY_ACTION, count, intent -> true); 2671 } 2672 2673 private ExpectedBroadcast expectConnectivityAction(int type, NetworkInfo.DetailedState state) { 2674 return registerBroadcastReceiverThat(CONNECTIVITY_ACTION, 1, intent -> { 2675 final int actualType = intent.getIntExtra(EXTRA_NETWORK_TYPE, -1); 2676 final NetworkInfo ni = intent.getParcelableExtra(EXTRA_NETWORK_INFO); 2677 return type == actualType 2678 && state == ni.getDetailedState() 2679 && extraInfoInBroadcastHasExpectedNullness(ni); 2680 }); 2681 } 2682 2683 /** Expects that PROXY_CHANGE_ACTION broadcast is received. */ 2684 private ExpectedBroadcast expectProxyChangeAction() { 2685 return registerBroadcastReceiverThat(PROXY_CHANGE_ACTION, 1, intent -> true); 2686 } 2687 2688 private ExpectedBroadcast expectProxyChangeAction(ProxyInfo proxy) { 2689 return expectProxyChangeAction(actualProxy -> proxy.equals(actualProxy)); 2690 } 2691 2692 private ExpectedBroadcast expectProxyChangeAction(Predicate<ProxyInfo> tester) { 2693 return registerBroadcastReceiverThat(PROXY_CHANGE_ACTION, 1, intent -> { 2694 final ProxyInfo actualProxy = (ProxyInfo) intent.getExtra(Proxy.EXTRA_PROXY_INFO, 2695 ProxyInfo.buildPacProxy(Uri.EMPTY)); 2696 return tester.test(actualProxy); 2697 }); 2698 } 2699 2700 private boolean extraInfoInBroadcastHasExpectedNullness(NetworkInfo ni) { 2701 final DetailedState state = ni.getDetailedState(); 2702 if (state == DetailedState.CONNECTED && ni.getExtraInfo() == null) return false; 2703 // Expect a null extraInfo if the network is CONNECTING, because a CONNECTIVITY_ACTION 2704 // broadcast with a state of CONNECTING only happens due to legacy VPN lockdown, which also 2705 // nulls out extraInfo. 2706 if (state == DetailedState.CONNECTING && ni.getExtraInfo() != null) return false; 2707 // Can't make any assertions about DISCONNECTED broadcasts. When a network actually 2708 // disconnects, disconnectAndDestroyNetwork sets its state to DISCONNECTED and its extraInfo 2709 // to null. But if the DISCONNECTED broadcast is just simulated by LegacyTypeTracker due to 2710 // a network switch, extraInfo will likely be populated. 2711 // This is likely a bug in CS, but likely not one we can fix without impacting apps. 2712 return true; 2713 } 2714 2715 @Test 2716 public void testNetworkFeature() throws Exception { 2717 // Connect the cell agent and wait for the connected broadcast. 2718 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 2719 mCellAgent.addCapability(NET_CAPABILITY_SUPL); 2720 ExpectedBroadcast b = expectConnectivityAction(TYPE_MOBILE, DetailedState.CONNECTED); 2721 mCellAgent.connect(true); 2722 b.expectBroadcast(); 2723 2724 // Build legacy request for SUPL. 2725 final NetworkCapabilities legacyCaps = new NetworkCapabilities(); 2726 legacyCaps.addTransportType(TRANSPORT_CELLULAR); 2727 legacyCaps.addCapability(NET_CAPABILITY_SUPL); 2728 final NetworkRequest legacyRequest = new NetworkRequest(legacyCaps, TYPE_MOBILE_SUPL, 2729 ConnectivityManager.REQUEST_ID_UNSET, NetworkRequest.Type.REQUEST); 2730 2731 // File request, withdraw it and make sure no broadcast is sent 2732 b = expectConnectivityAction(1); 2733 final TestNetworkCallback callback = new TestNetworkCallback(); 2734 mCm.requestNetwork(legacyRequest, callback); 2735 callback.expect(AVAILABLE, mCellAgent); 2736 mCm.unregisterNetworkCallback(callback); 2737 b.expectNoBroadcast(800); // 800ms long enough to at least flake if this is sent 2738 2739 // Disconnect the network and expect mobile disconnected broadcast. 2740 b = expectConnectivityAction(TYPE_MOBILE, DetailedState.DISCONNECTED); 2741 mCellAgent.disconnect(); 2742 b.expectBroadcast(); 2743 } 2744 2745 @Test 2746 public void testLingering() throws Exception { 2747 verifyNoNetwork(); 2748 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 2749 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 2750 assertNull(mCm.getActiveNetworkInfo()); 2751 assertNull(mCm.getActiveNetwork()); 2752 // Test bringing up validated cellular. 2753 ExpectedBroadcast b = expectConnectivityAction(TYPE_MOBILE, DetailedState.CONNECTED); 2754 mCellAgent.connect(true); 2755 b.expectBroadcast(); 2756 verifyActiveNetwork(TRANSPORT_CELLULAR); 2757 assertLength(2, mCm.getAllNetworks()); 2758 assertTrue(mCm.getAllNetworks()[0].equals(mCm.getActiveNetwork()) 2759 || mCm.getAllNetworks()[1].equals(mCm.getActiveNetwork())); 2760 assertTrue(mCm.getAllNetworks()[0].equals(mWiFiAgent.getNetwork()) 2761 || mCm.getAllNetworks()[1].equals(mWiFiAgent.getNetwork())); 2762 // Test bringing up validated WiFi. 2763 b = expectConnectivityAction(2); 2764 mWiFiAgent.connect(true); 2765 b.expectBroadcast(); 2766 verifyActiveNetwork(TRANSPORT_WIFI); 2767 assertLength(2, mCm.getAllNetworks()); 2768 assertTrue(mCm.getAllNetworks()[0].equals(mCm.getActiveNetwork()) 2769 || mCm.getAllNetworks()[1].equals(mCm.getActiveNetwork())); 2770 assertTrue(mCm.getAllNetworks()[0].equals(mCellAgent.getNetwork()) 2771 || mCm.getAllNetworks()[1].equals(mCellAgent.getNetwork())); 2772 // Test cellular linger timeout. 2773 mCellAgent.expectDisconnected(); 2774 waitForIdle(); 2775 assertLength(1, mCm.getAllNetworks()); 2776 verifyActiveNetwork(TRANSPORT_WIFI); 2777 assertLength(1, mCm.getAllNetworks()); 2778 assertEquals(mCm.getAllNetworks()[0], mCm.getActiveNetwork()); 2779 // Test WiFi disconnect. 2780 b = expectConnectivityAction(1); 2781 mWiFiAgent.disconnect(); 2782 b.expectBroadcast(); 2783 verifyNoNetwork(); 2784 } 2785 2786 /** 2787 * Verify a newly created network will be inactive instead of torn down even if no one is 2788 * requesting. 2789 */ 2790 @Test 2791 public void testNewNetworkInactive() throws Exception { 2792 // Create a callback that monitoring the testing network. 2793 final TestNetworkCallback listenCallback = new TestNetworkCallback(); 2794 mCm.registerNetworkCallback(new NetworkRequest.Builder().build(), listenCallback); 2795 2796 // 1. Create a network that is not requested by anyone, and does not satisfy any of the 2797 // default requests. Verify that the network will be inactive instead of torn down. 2798 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 2799 mWiFiAgent.connectWithoutInternet(); 2800 listenCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 2801 listenCallback.assertNoCallback(); 2802 2803 // Verify that the network will be torn down after nascent expiry. A small period of time 2804 // is added in case of flakiness. 2805 final int nascentTimeoutMs = 2806 mService.mNascentDelayMs + mService.mNascentDelayMs / 4; 2807 listenCallback.expect(LOST, mWiFiAgent, nascentTimeoutMs); 2808 2809 // 2. Create a network that is satisfied by a request comes later. 2810 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 2811 mWiFiAgent.connectWithoutInternet(); 2812 listenCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 2813 final NetworkRequest wifiRequest = new NetworkRequest.Builder() 2814 .addTransportType(TRANSPORT_WIFI).build(); 2815 final TestNetworkCallback wifiCallback = new TestNetworkCallback(); 2816 mCm.requestNetwork(wifiRequest, wifiCallback); 2817 wifiCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 2818 2819 // Verify that the network will be kept since the request is still satisfied. And is able 2820 // to get disconnected as usual if the request is released after the nascent timer expires. 2821 listenCallback.assertNoCallback(nascentTimeoutMs); 2822 mCm.unregisterNetworkCallback(wifiCallback); 2823 listenCallback.expect(LOST, mWiFiAgent); 2824 2825 // 3. Create a network that is satisfied by a request comes later. 2826 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 2827 mWiFiAgent.connectWithoutInternet(); 2828 listenCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 2829 mCm.requestNetwork(wifiRequest, wifiCallback); 2830 wifiCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 2831 2832 // Verify that the network will still be torn down after the request gets removed. 2833 mCm.unregisterNetworkCallback(wifiCallback); 2834 listenCallback.expect(LOST, mWiFiAgent); 2835 2836 // There is no need to ensure that LOSING is never sent in the common case that the 2837 // network immediately satisfies a request that was already present, because it is already 2838 // verified anywhere whenever {@code TestNetworkCallback#expectAvailable*} is called. 2839 2840 mCm.unregisterNetworkCallback(listenCallback); 2841 } 2842 2843 /** 2844 * Verify a newly created network will be inactive and switch to background if only background 2845 * request is satisfied. 2846 */ 2847 @Test 2848 public void testNewNetworkInactive_bgNetwork() throws Exception { 2849 // Create a callback that monitoring the wifi network. 2850 final TestNetworkCallback wifiListenCallback = new TestNetworkCallback(); 2851 mCm.registerNetworkCallback(new NetworkRequest.Builder() 2852 .addTransportType(TRANSPORT_WIFI).build(), wifiListenCallback); 2853 2854 // Create callbacks that can monitor background and foreground mobile networks. 2855 // This is done by granting using background networks permission before registration. Thus, 2856 // the service will not add {@code NET_CAPABILITY_FOREGROUND} by default. 2857 grantUsingBackgroundNetworksPermissionForUid(Binder.getCallingUid()); 2858 final TestNetworkCallback bgMobileListenCallback = new TestNetworkCallback(); 2859 final TestNetworkCallback fgMobileListenCallback = new TestNetworkCallback(); 2860 mCm.registerNetworkCallback(new NetworkRequest.Builder() 2861 .addTransportType(TRANSPORT_CELLULAR).build(), bgMobileListenCallback); 2862 mCm.registerNetworkCallback(new NetworkRequest.Builder() 2863 .addTransportType(TRANSPORT_CELLULAR) 2864 .addCapability(NET_CAPABILITY_FOREGROUND).build(), fgMobileListenCallback); 2865 2866 // Connect wifi, which satisfies default request. 2867 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 2868 mWiFiAgent.connect(true); 2869 wifiListenCallback.expectAvailableThenValidatedCallbacks(mWiFiAgent); 2870 2871 // Connect a cellular network, verify that satisfies only the background callback. 2872 setAlwaysOnNetworks(true); 2873 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 2874 mCellAgent.connect(true); 2875 bgMobileListenCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 2876 fgMobileListenCallback.assertNoCallback(); 2877 assertFalse(isForegroundNetwork(mCellAgent)); 2878 2879 mCellAgent.disconnect(); 2880 bgMobileListenCallback.expect(LOST, mCellAgent); 2881 fgMobileListenCallback.assertNoCallback(); 2882 2883 mCm.unregisterNetworkCallback(wifiListenCallback); 2884 mCm.unregisterNetworkCallback(bgMobileListenCallback); 2885 mCm.unregisterNetworkCallback(fgMobileListenCallback); 2886 } 2887 2888 @Test 2889 public void testBinderDeathAfterUnregister() throws Exception { 2890 final NetworkCapabilities caps = new NetworkCapabilities.Builder() 2891 .addTransportType(TRANSPORT_WIFI) 2892 .build(); 2893 final Handler handler = new Handler(ConnectivityThread.getInstanceLooper()); 2894 final Messenger messenger = new Messenger(handler); 2895 final CompletableFuture<Binder.DeathRecipient> deathRecipient = new CompletableFuture<>(); 2896 final Binder binder = new Binder() { 2897 private DeathRecipient mDeathRecipient; 2898 @Override 2899 public void linkToDeath(@NonNull final DeathRecipient recipient, final int flags) { 2900 synchronized (this) { 2901 mDeathRecipient = recipient; 2902 } 2903 super.linkToDeath(recipient, flags); 2904 deathRecipient.complete(recipient); 2905 } 2906 2907 @Override 2908 public boolean unlinkToDeath(@NonNull final DeathRecipient recipient, final int flags) { 2909 synchronized (this) { 2910 if (null == mDeathRecipient) { 2911 throw new IllegalStateException(); 2912 } 2913 mDeathRecipient = null; 2914 } 2915 return super.unlinkToDeath(recipient, flags); 2916 } 2917 }; 2918 final NetworkRequest request = mService.listenForNetwork(caps, messenger, binder, 2919 NetworkCallback.FLAG_NONE, mContext.getOpPackageName(), 2920 mContext.getAttributionTag(), ~0 /* declaredMethodsFlag */); 2921 mService.releaseNetworkRequest(request); 2922 deathRecipient.get().binderDied(); 2923 // Wait for the release message to be processed. 2924 waitForIdle(); 2925 // After waitForIdle(), the message was processed and the service didn't crash. 2926 } 2927 2928 // TODO : migrate to @Parameterized 2929 @Test 2930 public void testValidatedCellularOutscoresUnvalidatedWiFi_CanTimeShare() throws Exception { 2931 // The behavior of this test should be the same whether the radio can time share or not. 2932 doTestValidatedCellularOutscoresUnvalidatedWiFi(true); 2933 } 2934 2935 // TODO : migrate to @Parameterized 2936 @Test 2937 public void testValidatedCellularOutscoresUnvalidatedWiFi_CannotTimeShare() throws Exception { 2938 doTestValidatedCellularOutscoresUnvalidatedWiFi(false); 2939 } 2940 2941 private void doTestValidatedCellularOutscoresUnvalidatedWiFi( 2942 final boolean cellRadioTimesharingCapable) throws Exception { 2943 mService.mCellularRadioTimesharingCapable = cellRadioTimesharingCapable; 2944 // Test bringing up unvalidated WiFi 2945 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 2946 ExpectedBroadcast b = expectConnectivityAction(1); 2947 mWiFiAgent.connect(false); 2948 b.expectBroadcast(); 2949 verifyActiveNetwork(TRANSPORT_WIFI); 2950 // Test bringing up unvalidated cellular 2951 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 2952 mCellAgent.connect(false); 2953 waitForIdle(); 2954 verifyActiveNetwork(TRANSPORT_WIFI); 2955 // Test cellular disconnect. 2956 mCellAgent.disconnect(); 2957 waitForIdle(); 2958 verifyActiveNetwork(TRANSPORT_WIFI); 2959 // Test bringing up validated cellular 2960 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 2961 b = expectConnectivityAction(2); 2962 mCellAgent.connect(true); 2963 b.expectBroadcast(); 2964 verifyActiveNetwork(TRANSPORT_CELLULAR); 2965 // Test cellular disconnect. 2966 b = expectConnectivityAction(2); 2967 mCellAgent.disconnect(); 2968 b.expectBroadcast(); 2969 verifyActiveNetwork(TRANSPORT_WIFI); 2970 // Test WiFi disconnect. 2971 b = expectConnectivityAction(1); 2972 mWiFiAgent.disconnect(); 2973 b.expectBroadcast(); 2974 verifyNoNetwork(); 2975 } 2976 2977 // TODO : migrate to @Parameterized 2978 @Test 2979 public void testUnvalidatedWifiOutscoresUnvalidatedCellular_CanTimeShare() throws Exception { 2980 doTestUnvalidatedWifiOutscoresUnvalidatedCellular(true); 2981 } 2982 2983 // TODO : migrate to @Parameterized 2984 @Test 2985 public void testUnvalidatedWifiOutscoresUnvalidatedCellular_CannotTimeShare() throws Exception { 2986 doTestUnvalidatedWifiOutscoresUnvalidatedCellular(false); 2987 } 2988 2989 private void doTestUnvalidatedWifiOutscoresUnvalidatedCellular( 2990 final boolean cellRadioTimesharingCapable) throws Exception { 2991 mService.mCellularRadioTimesharingCapable = cellRadioTimesharingCapable; 2992 // Test bringing up unvalidated cellular. 2993 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 2994 ExpectedBroadcast b = expectConnectivityAction(1); 2995 mCellAgent.connect(false); 2996 b.expectBroadcast(); 2997 verifyActiveNetwork(TRANSPORT_CELLULAR); 2998 // Test bringing up unvalidated WiFi. 2999 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3000 b = expectConnectivityAction(2); 3001 mWiFiAgent.connect(false); 3002 b.expectBroadcast(); 3003 verifyActiveNetwork(TRANSPORT_WIFI); 3004 // Test WiFi disconnect. 3005 b = expectConnectivityAction(2); 3006 mWiFiAgent.disconnect(); 3007 b.expectBroadcast(); 3008 verifyActiveNetwork(TRANSPORT_CELLULAR); 3009 // Test cellular disconnect. 3010 b = expectConnectivityAction(1); 3011 mCellAgent.disconnect(); 3012 b.expectBroadcast(); 3013 verifyNoNetwork(); 3014 } 3015 3016 // TODO : migrate to @Parameterized 3017 @Test 3018 public void testUnlingeringDoesNotValidate_CanTimeShare() throws Exception { 3019 doTestUnlingeringDoesNotValidate(true); 3020 } 3021 3022 // TODO : migrate to @Parameterized 3023 @Test 3024 public void testUnlingeringDoesNotValidate_CannotTimeShare() throws Exception { 3025 doTestUnlingeringDoesNotValidate(false); 3026 } 3027 3028 private void doTestUnlingeringDoesNotValidate( 3029 final boolean cellRadioTimesharingCapable) throws Exception { 3030 mService.mCellularRadioTimesharingCapable = cellRadioTimesharingCapable; 3031 // Test bringing up unvalidated WiFi. 3032 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3033 ExpectedBroadcast b = expectConnectivityAction(1); 3034 mWiFiAgent.connect(false); 3035 b.expectBroadcast(); 3036 verifyActiveNetwork(TRANSPORT_WIFI); 3037 assertFalse(mCm.getNetworkCapabilities(mWiFiAgent.getNetwork()).hasCapability( 3038 NET_CAPABILITY_VALIDATED)); 3039 // Test bringing up validated cellular. 3040 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 3041 b = expectConnectivityAction(2); 3042 mCellAgent.connect(true); 3043 b.expectBroadcast(); 3044 verifyActiveNetwork(TRANSPORT_CELLULAR); 3045 assertFalse(mCm.getNetworkCapabilities(mWiFiAgent.getNetwork()).hasCapability( 3046 NET_CAPABILITY_VALIDATED)); 3047 // Test cellular disconnect. 3048 b = expectConnectivityAction(2); 3049 mCellAgent.disconnect(); 3050 b.expectBroadcast(); 3051 verifyActiveNetwork(TRANSPORT_WIFI); 3052 // Unlingering a network should not cause it to be marked as validated. 3053 assertFalse(mCm.getNetworkCapabilities(mWiFiAgent.getNetwork()).hasCapability( 3054 NET_CAPABILITY_VALIDATED)); 3055 } 3056 3057 // TODO : migrate to @Parameterized 3058 @Test 3059 public void testRequestMigrationToSameTransport_CanTimeShare() throws Exception { 3060 // Simulate a device where the cell radio is capable of time sharing 3061 mService.mCellularRadioTimesharingCapable = true; 3062 doTestRequestMigrationToSameTransport(TRANSPORT_CELLULAR, true); 3063 doTestRequestMigrationToSameTransport(TRANSPORT_WIFI, true); 3064 doTestRequestMigrationToSameTransport(TRANSPORT_ETHERNET, true); 3065 } 3066 3067 // TODO : migrate to @Parameterized 3068 @Test 3069 public void testRequestMigrationToSameTransport_CannotTimeShare() throws Exception { 3070 // Simulate a device where the cell radio is not capable of time sharing 3071 mService.mCellularRadioTimesharingCapable = false; 3072 doTestRequestMigrationToSameTransport(TRANSPORT_CELLULAR, false); 3073 doTestRequestMigrationToSameTransport(TRANSPORT_WIFI, true); 3074 doTestRequestMigrationToSameTransport(TRANSPORT_ETHERNET, true); 3075 } 3076 3077 private void doTestRequestMigrationToSameTransport(final int transport, 3078 final boolean expectLingering) throws Exception { 3079 // To speed up tests the linger delay is very short by default in tests but this 3080 // test needs to make sure the delay is not incurred so a longer value is safer (it 3081 // reduces the risk that a bug exists but goes undetected). The alarm manager in the test 3082 // throws and crashes CS if this is set to anything more than the below constant though. 3083 mService.mLingerDelayMs = UNREASONABLY_LONG_ALARM_WAIT_MS; 3084 3085 final TestNetworkCallback generalCb = new TestNetworkCallback(); 3086 final TestNetworkCallback defaultCb = new TestNetworkCallback(); 3087 mCm.registerNetworkCallback( 3088 new NetworkRequest.Builder().addTransportType(transport).build(), 3089 generalCb); 3090 mCm.registerDefaultNetworkCallback(defaultCb); 3091 3092 // Bring up net agent 1 3093 final TestNetworkAgentWrapper net1 = new TestNetworkAgentWrapper(transport); 3094 net1.connect(true); 3095 // Make sure the default request is on net 1 3096 generalCb.expectAvailableThenValidatedCallbacks(net1); 3097 defaultCb.expectAvailableThenValidatedCallbacks(net1); 3098 3099 // Bring up net 2 with primary and mms 3100 final TestNetworkAgentWrapper net2 = new TestNetworkAgentWrapper(transport); 3101 net2.addCapability(NET_CAPABILITY_MMS); 3102 net2.setScore(new NetworkScore.Builder().setTransportPrimary(true).build()); 3103 net2.connect(true); 3104 3105 // Make sure the default request goes to net 2 3106 generalCb.expectAvailableCallbacksUnvalidated(net2); 3107 if (expectLingering) { 3108 generalCb.expectLosing(net1); 3109 } 3110 if (mShouldCreateNetworksImmediately) { 3111 if (expectLingering) { 3112 // Make sure cell 1 is unwanted immediately if the radio can't time share, but only 3113 // after some delay if it can. 3114 generalCb.expectCaps(net2, c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 3115 defaultCb.expectAvailableDoubleValidatedCallbacks(net2); 3116 net1.assertNotDisconnected(TEST_CALLBACK_TIMEOUT_MS); // always incurs the timeout 3117 generalCb.assertNoCallback(); 3118 // assertNotDisconnected waited for TEST_CALLBACK_TIMEOUT_MS, so waiting for the 3119 // linger period gives TEST_CALLBACK_TIMEOUT_MS time for the event to process. 3120 net1.expectDisconnected(UNREASONABLY_LONG_ALARM_WAIT_MS); 3121 generalCb.expect(LOST, net1); 3122 } else { 3123 net1.expectDisconnected(TEST_CALLBACK_TIMEOUT_MS); 3124 net1.disconnect(); 3125 generalCb.expect(LOST, net1); 3126 generalCb.expectCaps(net2, c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 3127 defaultCb.expectAvailableDoubleValidatedCallbacks(net2); 3128 } 3129 } else { 3130 generalCb.expectCaps(net2, c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 3131 defaultCb.expectAvailableDoubleValidatedCallbacks(net2); 3132 3133 // Make sure cell 1 is unwanted immediately if the radio can't time share, but only 3134 // after some delay if it can. 3135 if (expectLingering) { 3136 net1.assertNotDisconnected(TEST_CALLBACK_TIMEOUT_MS); // always incurs the timeout 3137 generalCb.assertNoCallback(); 3138 // assertNotDisconnected waited for TEST_CALLBACK_TIMEOUT_MS, so waiting for the 3139 // linger period gives TEST_CALLBACK_TIMEOUT_MS time for the event to process. 3140 net1.expectDisconnected(UNREASONABLY_LONG_ALARM_WAIT_MS); 3141 } else { 3142 net1.expectDisconnected(TEST_CALLBACK_TIMEOUT_MS); 3143 } 3144 net1.disconnect(); 3145 generalCb.expect(LOST, net1); 3146 } 3147 3148 // Remove primary from net 2 3149 net2.setScore(new NetworkScore.Builder().build()); 3150 // Request MMS 3151 final TestNetworkCallback mmsCallback = new TestNetworkCallback(); 3152 mCm.requestNetwork(new NetworkRequest.Builder().addCapability(NET_CAPABILITY_MMS).build(), 3153 mmsCallback); 3154 mmsCallback.expectAvailableCallbacksValidated(net2); 3155 3156 // Bring up net 3 with primary but without MMS 3157 final TestNetworkAgentWrapper net3 = new TestNetworkAgentWrapper(transport); 3158 net3.setScore(new NetworkScore.Builder().setTransportPrimary(true).build()); 3159 net3.connect(true); 3160 3161 // Make sure default goes to net 3, but the MMS request doesn't 3162 generalCb.expectAvailableThenValidatedCallbacks(net3); 3163 defaultCb.expectAvailableDoubleValidatedCallbacks(net3); 3164 mmsCallback.assertNoCallback(); 3165 net2.assertNotDisconnected(TEST_CALLBACK_TIMEOUT_MS); // Always incurs the timeout 3166 3167 // Revoke MMS request and make sure net 2 is torn down with the appropriate delay 3168 mCm.unregisterNetworkCallback(mmsCallback); 3169 if (expectLingering) { 3170 // If the radio can time share, the linger delay hasn't elapsed yet, so apps will 3171 // get LOSING. If the radio can't time share, this is a hard loss, since the last 3172 // request keeping up this network has been removed and the network isn't lingering 3173 // for any other request. 3174 generalCb.expectLosing(net2); 3175 net2.assertNotDisconnected(TEST_CALLBACK_TIMEOUT_MS); 3176 // Timeout 0 because after a while LOST will actually arrive 3177 generalCb.assertNoCallback(0 /* timeoutMs */); 3178 net2.expectDisconnected(UNREASONABLY_LONG_ALARM_WAIT_MS); 3179 } else { 3180 net2.expectDisconnected(TEST_CALLBACK_TIMEOUT_MS); 3181 } 3182 net2.disconnect(); 3183 generalCb.expect(LOST, net2); 3184 defaultCb.assertNoCallback(); 3185 3186 net3.disconnect(); 3187 mCm.unregisterNetworkCallback(defaultCb); 3188 mCm.unregisterNetworkCallback(generalCb); 3189 } 3190 3191 // TODO : migrate to @Parameterized 3192 @Test 3193 public void testCellularOutscoresWeakWifi_CanTimeShare() throws Exception { 3194 // The behavior of this test should be the same whether the radio can time share or not. 3195 doTestCellularOutscoresWeakWifi(true); 3196 } 3197 3198 // TODO : migrate to @Parameterized 3199 @Test 3200 public void testCellularOutscoresWeakWifi_CannotTimeShare() throws Exception { 3201 doTestCellularOutscoresWeakWifi(false); 3202 } 3203 3204 private void doTestCellularOutscoresWeakWifi( 3205 final boolean cellRadioTimesharingCapable) throws Exception { 3206 mService.mCellularRadioTimesharingCapable = cellRadioTimesharingCapable; 3207 // Test bringing up validated cellular. 3208 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 3209 ExpectedBroadcast b = expectConnectivityAction(1); 3210 mCellAgent.connect(true); 3211 b.expectBroadcast(); 3212 verifyActiveNetwork(TRANSPORT_CELLULAR); 3213 // Test bringing up validated WiFi. 3214 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3215 b = expectConnectivityAction(2); 3216 mWiFiAgent.connect(true); 3217 b.expectBroadcast(); 3218 verifyActiveNetwork(TRANSPORT_WIFI); 3219 // Test WiFi getting really weak. 3220 b = expectConnectivityAction(2); 3221 mWiFiAgent.adjustScore(-11); 3222 b.expectBroadcast(); 3223 verifyActiveNetwork(TRANSPORT_CELLULAR); 3224 // Test WiFi restoring signal strength. 3225 b = expectConnectivityAction(2); 3226 mWiFiAgent.adjustScore(11); 3227 b.expectBroadcast(); 3228 verifyActiveNetwork(TRANSPORT_WIFI); 3229 } 3230 3231 // TODO : migrate to @Parameterized 3232 @Test 3233 public void testReapingNetwork_CanTimeShare() throws Exception { 3234 doTestReapingNetwork(true); 3235 } 3236 3237 // TODO : migrate to @Parameterized 3238 @Test 3239 public void testReapingNetwork_CannotTimeShare() throws Exception { 3240 doTestReapingNetwork(false); 3241 } 3242 3243 private void doTestReapingNetwork( 3244 final boolean cellRadioTimesharingCapable) throws Exception { 3245 mService.mCellularRadioTimesharingCapable = cellRadioTimesharingCapable; 3246 // Test bringing up WiFi without NET_CAPABILITY_INTERNET. 3247 // Expect it to be torn down immediately because it satisfies no requests. 3248 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3249 mWiFiAgent.connectWithoutInternet(); 3250 mWiFiAgent.expectDisconnected(); 3251 // Test bringing up cellular without NET_CAPABILITY_INTERNET. 3252 // Expect it to be torn down immediately because it satisfies no requests. 3253 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3254 mCellAgent.connectWithoutInternet(); 3255 mCellAgent.expectDisconnected(); 3256 // Test bringing up validated WiFi. 3257 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3258 final ExpectedBroadcast b = expectConnectivityAction(TYPE_WIFI, DetailedState.CONNECTED); 3259 mWiFiAgent.connect(true); 3260 b.expectBroadcast(); 3261 verifyActiveNetwork(TRANSPORT_WIFI); 3262 // Test bringing up unvalidated cellular. 3263 // Expect it to be torn down because it could never be the highest scoring network 3264 // satisfying the default request even if it validated. 3265 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 3266 mCellAgent.connect(false); 3267 mCellAgent.expectDisconnected(); 3268 verifyActiveNetwork(TRANSPORT_WIFI); 3269 mWiFiAgent.disconnect(); 3270 mWiFiAgent.expectDisconnected(); 3271 } 3272 3273 // TODO : migrate to @Parameterized 3274 @Test 3275 public void testCellularFallback_CanTimeShare() throws Exception { 3276 doTestCellularFallback(true); 3277 } 3278 3279 // TODO : migrate to @Parameterized 3280 @Test 3281 public void testCellularFallback_CannotTimeShare() throws Exception { 3282 doTestCellularFallback(false); 3283 } 3284 3285 private void doTestCellularFallback( 3286 final boolean cellRadioTimesharingCapable) throws Exception { 3287 mService.mCellularRadioTimesharingCapable = cellRadioTimesharingCapable; 3288 // Test bringing up validated cellular. 3289 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 3290 ExpectedBroadcast b = expectConnectivityAction(1); 3291 mCellAgent.connect(true); 3292 b.expectBroadcast(); 3293 verifyActiveNetwork(TRANSPORT_CELLULAR); 3294 // Test bringing up validated WiFi. 3295 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3296 b = expectConnectivityAction(2); 3297 mWiFiAgent.connect(true); 3298 b.expectBroadcast(); 3299 verifyActiveNetwork(TRANSPORT_WIFI); 3300 // Reevaluate WiFi (it'll instantly fail DNS). 3301 b = expectConnectivityAction(2); 3302 assertTrue(mCm.getNetworkCapabilities(mWiFiAgent.getNetwork()).hasCapability( 3303 NET_CAPABILITY_VALIDATED)); 3304 mCm.reportBadNetwork(mWiFiAgent.getNetwork()); 3305 // Should quickly fall back to Cellular. 3306 b.expectBroadcast(); 3307 assertFalse(mCm.getNetworkCapabilities(mWiFiAgent.getNetwork()).hasCapability( 3308 NET_CAPABILITY_VALIDATED)); 3309 verifyActiveNetwork(TRANSPORT_CELLULAR); 3310 // Reevaluate cellular (it'll instantly fail DNS). 3311 b = expectConnectivityAction(2); 3312 assertTrue(mCm.getNetworkCapabilities(mCellAgent.getNetwork()).hasCapability( 3313 NET_CAPABILITY_VALIDATED)); 3314 mCm.reportBadNetwork(mCellAgent.getNetwork()); 3315 // Should quickly fall back to WiFi. 3316 b.expectBroadcast(); 3317 assertFalse(mCm.getNetworkCapabilities(mCellAgent.getNetwork()).hasCapability( 3318 NET_CAPABILITY_VALIDATED)); 3319 assertFalse(mCm.getNetworkCapabilities(mWiFiAgent.getNetwork()).hasCapability( 3320 NET_CAPABILITY_VALIDATED)); 3321 verifyActiveNetwork(TRANSPORT_WIFI); 3322 } 3323 3324 // TODO : migrate to @Parameterized 3325 @Test 3326 public void testWiFiFallback_CanTimeShare() throws Exception { 3327 doTestWiFiFallback(true); 3328 } 3329 3330 // TODO : migrate to @Parameterized 3331 @Test 3332 public void testWiFiFallback_CannotTimeShare() throws Exception { 3333 doTestWiFiFallback(false); 3334 } 3335 3336 private void doTestWiFiFallback( 3337 final boolean cellRadioTimesharingCapable) throws Exception { 3338 mService.mCellularRadioTimesharingCapable = cellRadioTimesharingCapable; 3339 // Test bringing up unvalidated WiFi. 3340 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3341 ExpectedBroadcast b = expectConnectivityAction(1); 3342 mWiFiAgent.connect(false); 3343 b.expectBroadcast(); 3344 verifyActiveNetwork(TRANSPORT_WIFI); 3345 // Test bringing up validated cellular. 3346 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 3347 b = expectConnectivityAction(2); 3348 mCellAgent.connect(true); 3349 b.expectBroadcast(); 3350 verifyActiveNetwork(TRANSPORT_CELLULAR); 3351 // Reevaluate cellular (it'll instantly fail DNS). 3352 b = expectConnectivityAction(2); 3353 assertTrue(mCm.getNetworkCapabilities(mCellAgent.getNetwork()).hasCapability( 3354 NET_CAPABILITY_VALIDATED)); 3355 mCm.reportBadNetwork(mCellAgent.getNetwork()); 3356 // Should quickly fall back to WiFi. 3357 b.expectBroadcast(); 3358 assertFalse(mCm.getNetworkCapabilities(mCellAgent.getNetwork()).hasCapability( 3359 NET_CAPABILITY_VALIDATED)); 3360 verifyActiveNetwork(TRANSPORT_WIFI); 3361 } 3362 3363 @Test 3364 public void testRequiresValidation() { 3365 assertTrue(NetworkMonitorUtils.isValidationRequired(false /* isDunValidationRequired */, 3366 false /* isVpnValidationRequired */, 3367 mCm.getDefaultRequest().networkCapabilities)); 3368 } 3369 3370 /** 3371 * Utility NetworkCallback for testing. The caller must explicitly test for all the callbacks 3372 * this class receives, by calling expect() exactly once each time a callback is 3373 * received. assertNoCallback may be called at any time. 3374 */ 3375 private class TestNetworkCallback extends TestableNetworkCallback { 3376 TestNetworkCallback() { 3377 // In the context of this test, the testable network callbacks should use waitForIdle 3378 // before calling assertNoCallback in an effort to detect issues where a callback is 3379 // not yet sent but a message currently in the queue of a handler will cause it to 3380 // be sent soon. 3381 super(TEST_CALLBACK_TIMEOUT_MS, TEST_CALLBACK_TIMEOUT_MS, 3382 ConnectivityServiceTest.this::waitForIdle); 3383 } 3384 3385 public CallbackEntry.Losing expectLosing(final HasNetwork n, final long timeoutMs) { 3386 final CallbackEntry.Losing losing = expect(LOSING, n, timeoutMs); 3387 final int maxMsToLive = losing.getMaxMsToLive(); 3388 if (maxMsToLive < 0 || maxMsToLive > mService.mLingerDelayMs) { 3389 // maxMsToLive is the value that was received in the onLosing callback. That must 3390 // not be negative, so check that. 3391 // Also, maxMsToLive is the remaining time until the network expires. 3392 // mService.mLingerDelayMs is how long the network takes from when it's first 3393 // detected to be unneeded to when it expires, so maxMsToLive should never 3394 // be greater than that. 3395 fail(String.format("Invalid linger time value %d, must be between %d and %d", 3396 maxMsToLive, 0, mService.mLingerDelayMs)); 3397 } 3398 return losing; 3399 } 3400 3401 public CallbackEntry.Losing expectLosing(final HasNetwork n) { 3402 return expectLosing(n, getDefaultTimeoutMs()); 3403 } 3404 } 3405 3406 // Can't be part of TestNetworkCallback because "cannot be declared static; static methods can 3407 // only be declared in a static or top level type". 3408 static void assertNoCallbacks(final long timeoutMs, TestNetworkCallback ... callbacks) { 3409 for (TestNetworkCallback c : callbacks) { 3410 c.assertNoCallback(timeoutMs); 3411 } 3412 } 3413 3414 static void assertNoCallbacks(TestNetworkCallback ... callbacks) { 3415 for (TestNetworkCallback c : callbacks) { 3416 c.assertNoCallback(); // each callback uses its own timeout 3417 } 3418 } 3419 3420 static void expectOnLost(TestNetworkAgentWrapper network, TestNetworkCallback ... callbacks) { 3421 for (TestNetworkCallback c : callbacks) { 3422 c.expect(LOST, network); 3423 } 3424 } 3425 3426 static void expectAvailableCallbacksUnvalidatedWithSpecifier(TestNetworkAgentWrapper network, 3427 NetworkSpecifier specifier, TestNetworkCallback ... callbacks) { 3428 for (TestNetworkCallback c : callbacks) { 3429 c.expect(AVAILABLE, network); 3430 c.expectCaps(network, cb -> !cb.hasCapability(NET_CAPABILITY_VALIDATED) 3431 && Objects.equals(specifier, cb.getNetworkSpecifier())); 3432 c.expect(LINK_PROPERTIES_CHANGED, network); 3433 c.expect(BLOCKED_STATUS, network); 3434 } 3435 } 3436 3437 @Test 3438 public void testNetworkDoesntMatchRequestsUntilConnected() throws Exception { 3439 final TestNetworkCallback cb = new TestNetworkCallback(); 3440 final NetworkRequest wifiRequest = new NetworkRequest.Builder() 3441 .addTransportType(TRANSPORT_WIFI).build(); 3442 mCm.requestNetwork(wifiRequest, cb); 3443 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3444 // Updating the score triggers a rematch. 3445 mWiFiAgent.setScore(new NetworkScore.Builder().build()); 3446 cb.assertNoCallback(); 3447 mWiFiAgent.connect(false); 3448 cb.expectAvailableCallbacksUnvalidated(mWiFiAgent); 3449 cb.assertNoCallback(); 3450 mCm.unregisterNetworkCallback(cb); 3451 } 3452 3453 @Test 3454 public void testNetworkNotVisibleUntilConnected() throws Exception { 3455 final TestNetworkCallback cb = new TestNetworkCallback(); 3456 final NetworkRequest wifiRequest = new NetworkRequest.Builder() 3457 .addTransportType(TRANSPORT_WIFI).build(); 3458 mCm.registerNetworkCallback(wifiRequest, cb); 3459 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3460 final NetworkCapabilities nc = mWiFiAgent.getNetworkCapabilities(); 3461 nc.addCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED); 3462 mWiFiAgent.setNetworkCapabilities(nc, true /* sendToConnectivityService */); 3463 cb.assertNoCallback(); 3464 mWiFiAgent.connect(false); 3465 cb.expectAvailableCallbacksUnvalidated(mWiFiAgent); 3466 final CallbackEntry found = CollectionUtils.findLast(cb.getHistory(), 3467 it -> it instanceof CallbackEntry.CapabilitiesChanged); 3468 assertTrue(((CallbackEntry.CapabilitiesChanged) found).getCaps() 3469 .hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED)); 3470 cb.assertNoCallback(); 3471 mCm.unregisterNetworkCallback(cb); 3472 } 3473 3474 @Test 3475 public void testStateChangeNetworkCallbacks() throws Exception { 3476 final TestNetworkCallback genericNetworkCallback = new TestNetworkCallback(); 3477 final TestNetworkCallback wifiNetworkCallback = new TestNetworkCallback(); 3478 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback(); 3479 final NetworkRequest genericRequest = new NetworkRequest.Builder() 3480 .clearCapabilities().build(); 3481 final NetworkRequest wifiRequest = new NetworkRequest.Builder() 3482 .addTransportType(TRANSPORT_WIFI).build(); 3483 final NetworkRequest cellRequest = new NetworkRequest.Builder() 3484 .addTransportType(TRANSPORT_CELLULAR).build(); 3485 mCm.registerNetworkCallback(genericRequest, genericNetworkCallback); 3486 mCm.registerNetworkCallback(wifiRequest, wifiNetworkCallback); 3487 mCm.registerNetworkCallback(cellRequest, cellNetworkCallback); 3488 3489 // Test unvalidated networks 3490 ExpectedBroadcast b = expectConnectivityAction(1); 3491 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 3492 mCellAgent.connect(false); 3493 genericNetworkCallback.expectAvailableCallbacksUnvalidated(mCellAgent); 3494 cellNetworkCallback.expectAvailableCallbacksUnvalidated(mCellAgent); 3495 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetwork()); 3496 b.expectBroadcast(); 3497 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback); 3498 3499 // This should not trigger spurious onAvailable() callbacks, b/21762680. 3500 mCellAgent.adjustScore(-1); 3501 waitForIdle(); 3502 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback); 3503 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetwork()); 3504 3505 b = expectConnectivityAction(2); 3506 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3507 mWiFiAgent.connect(false); 3508 genericNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 3509 wifiNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 3510 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetwork()); 3511 b.expectBroadcast(); 3512 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback); 3513 3514 b = expectConnectivityAction(2); 3515 mWiFiAgent.disconnect(); 3516 genericNetworkCallback.expect(CallbackEntry.LOST, mWiFiAgent); 3517 wifiNetworkCallback.expect(CallbackEntry.LOST, mWiFiAgent); 3518 cellNetworkCallback.assertNoCallback(); 3519 b.expectBroadcast(); 3520 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback); 3521 3522 b = expectConnectivityAction(1); 3523 mCellAgent.disconnect(); 3524 genericNetworkCallback.expect(CallbackEntry.LOST, mCellAgent); 3525 cellNetworkCallback.expect(CallbackEntry.LOST, mCellAgent); 3526 b.expectBroadcast(); 3527 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback); 3528 3529 // Test validated networks 3530 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 3531 mCellAgent.connect(true); 3532 genericNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 3533 cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 3534 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetwork()); 3535 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback); 3536 3537 // This should not trigger spurious onAvailable() callbacks, b/21762680. 3538 mCellAgent.adjustScore(-1); 3539 waitForIdle(); 3540 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback); 3541 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetwork()); 3542 3543 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3544 mWiFiAgent.connect(true); 3545 genericNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 3546 genericNetworkCallback.expectLosing(mCellAgent); 3547 genericNetworkCallback.expectCaps(mWiFiAgent, 3548 c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 3549 wifiNetworkCallback.expectAvailableThenValidatedCallbacks(mWiFiAgent); 3550 cellNetworkCallback.expectLosing(mCellAgent); 3551 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetwork()); 3552 // Cell will disconnect after the lingering period. Before that elapses check that 3553 // there have been no callbacks. 3554 assertNoCallbacks(0 /* timeoutMs */, 3555 genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback); 3556 3557 mWiFiAgent.disconnect(); 3558 genericNetworkCallback.expect(LOST, mWiFiAgent); 3559 wifiNetworkCallback.expect(LOST, mWiFiAgent); 3560 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback); 3561 3562 mCellAgent.disconnect(); 3563 genericNetworkCallback.expect(LOST, mCellAgent); 3564 cellNetworkCallback.expect(LOST, mCellAgent); 3565 assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback); 3566 } 3567 3568 private void doNetworkCallbacksSanitizationTest(boolean sanitized) throws Exception { 3569 final TestNetworkCallback callback = new TestNetworkCallback(); 3570 final TestNetworkCallback defaultCallback = new TestNetworkCallback(); 3571 final NetworkRequest wifiRequest = new NetworkRequest.Builder() 3572 .addTransportType(TRANSPORT_WIFI).build(); 3573 mCm.registerNetworkCallback(wifiRequest, callback); 3574 mCm.registerDefaultNetworkCallback(defaultCallback); 3575 3576 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3577 mWiFiAgent.connect(false); 3578 callback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 3579 defaultCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 3580 3581 final LinkProperties newLp = new LinkProperties(); 3582 final Uri capportUrl = Uri.parse("https://capport.example.com/api"); 3583 final CaptivePortalData capportData = new CaptivePortalData.Builder() 3584 .setCaptive(true).build(); 3585 3586 final Uri expectedCapportUrl = sanitized ? null : capportUrl; 3587 newLp.setCaptivePortalApiUrl(capportUrl); 3588 mWiFiAgent.sendLinkProperties(newLp); 3589 callback.expect(LINK_PROPERTIES_CHANGED, mWiFiAgent, cb -> 3590 Objects.equals(expectedCapportUrl, cb.getLp().getCaptivePortalApiUrl())); 3591 defaultCallback.expect(LINK_PROPERTIES_CHANGED, mWiFiAgent, cb -> 3592 Objects.equals(expectedCapportUrl, cb.getLp().getCaptivePortalApiUrl())); 3593 3594 final CaptivePortalData expectedCapportData = sanitized ? null : capportData; 3595 mWiFiAgent.notifyCapportApiDataChanged(capportData); 3596 callback.expect(LINK_PROPERTIES_CHANGED, mWiFiAgent, cb -> 3597 Objects.equals(expectedCapportData, cb.getLp().getCaptivePortalData())); 3598 defaultCallback.expect(LINK_PROPERTIES_CHANGED, mWiFiAgent, cb -> 3599 Objects.equals(expectedCapportData, cb.getLp().getCaptivePortalData())); 3600 3601 final LinkProperties lp = mCm.getLinkProperties(mWiFiAgent.getNetwork()); 3602 assertEquals(expectedCapportUrl, lp.getCaptivePortalApiUrl()); 3603 assertEquals(expectedCapportData, lp.getCaptivePortalData()); 3604 } 3605 3606 @Test 3607 public void networkCallbacksSanitizationTest_Sanitize() throws Exception { 3608 mServiceContext.setPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, 3609 PERMISSION_DENIED); 3610 mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_DENIED); 3611 doNetworkCallbacksSanitizationTest(true /* sanitized */); 3612 } 3613 3614 @Test 3615 public void networkCallbacksSanitizationTest_NoSanitize_NetworkStack() throws Exception { 3616 mServiceContext.setPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, 3617 PERMISSION_GRANTED); 3618 mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_DENIED); 3619 doNetworkCallbacksSanitizationTest(false /* sanitized */); 3620 } 3621 3622 @Test 3623 public void networkCallbacksSanitizationTest_NoSanitize_Settings() throws Exception { 3624 mServiceContext.setPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, 3625 PERMISSION_DENIED); 3626 mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_GRANTED); 3627 doNetworkCallbacksSanitizationTest(false /* sanitized */); 3628 } 3629 3630 @Test 3631 public void testOwnerUidCannotChange() throws Exception { 3632 final NetworkCapabilities ncTemplate = new NetworkCapabilities(); 3633 final int originalOwnerUid = Process.myUid(); 3634 ncTemplate.setOwnerUid(originalOwnerUid); 3635 3636 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, new LinkProperties(), ncTemplate); 3637 mWiFiAgent.connect(false); 3638 waitForIdle(); 3639 3640 // Send ConnectivityService an update to the mWiFiAgent's capabilities that changes 3641 // the owner UID and an unrelated capability. 3642 NetworkCapabilities agentCapabilities = mWiFiAgent.getNetworkCapabilities(); 3643 assertEquals(originalOwnerUid, agentCapabilities.getOwnerUid()); 3644 agentCapabilities.setOwnerUid(42); 3645 assertFalse(agentCapabilities.hasCapability(NET_CAPABILITY_NOT_CONGESTED)); 3646 agentCapabilities.addCapability(NET_CAPABILITY_NOT_CONGESTED); 3647 mWiFiAgent.setNetworkCapabilities(agentCapabilities, true); 3648 waitForIdle(); 3649 3650 // Owner UIDs are not visible without location permission. 3651 setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION, 3652 Manifest.permission.ACCESS_FINE_LOCATION); 3653 3654 // Check that the capability change has been applied but the owner UID is not modified. 3655 NetworkCapabilities nc = mCm.getNetworkCapabilities(mWiFiAgent.getNetwork()); 3656 assertEquals(originalOwnerUid, nc.getOwnerUid()); 3657 assertTrue(nc.hasCapability(NET_CAPABILITY_NOT_CONGESTED)); 3658 } 3659 3660 @Test 3661 public void testMultipleLingering() throws Exception { 3662 // This test would be flaky with the default 120ms timer: that is short enough that 3663 // lingered networks are torn down before assertions can be run. We don't want to mock the 3664 // lingering timer to keep the WakeupMessage logic realistic: this has already proven useful 3665 // in detecting races. Furthermore, sometimes the test is running while Phenotype is running 3666 // so hot that the test doesn't get the CPU for multiple hundreds of milliseconds, so this 3667 // needs to be suitably long. 3668 mService.mLingerDelayMs = 2_000; 3669 3670 NetworkRequest request = new NetworkRequest.Builder() 3671 .clearCapabilities().addCapability(NET_CAPABILITY_NOT_METERED) 3672 .build(); 3673 TestNetworkCallback callback = new TestNetworkCallback(); 3674 mCm.registerNetworkCallback(request, callback); 3675 3676 TestNetworkCallback defaultCallback = new TestNetworkCallback(); 3677 mCm.registerDefaultNetworkCallback(defaultCallback); 3678 3679 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 3680 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3681 mEthernetAgent = new TestNetworkAgentWrapper(TRANSPORT_ETHERNET); 3682 3683 mCellAgent.addCapability(NET_CAPABILITY_NOT_METERED); 3684 mWiFiAgent.addCapability(NET_CAPABILITY_NOT_METERED); 3685 mEthernetAgent.addCapability(NET_CAPABILITY_NOT_METERED); 3686 3687 mCellAgent.connect(true); 3688 callback.expectAvailableThenValidatedCallbacks(mCellAgent); 3689 defaultCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 3690 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetwork()); 3691 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 3692 3693 mWiFiAgent.connect(true); 3694 // We get AVAILABLE on wifi when wifi connects and satisfies our unmetered request. 3695 // We then get LOSING when wifi validates and cell is outscored. 3696 callback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 3697 // TODO: Investigate sending validated before losing. 3698 callback.expectLosing(mCellAgent); 3699 callback.expectCaps(mWiFiAgent, c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 3700 defaultCallback.expectAvailableDoubleValidatedCallbacks(mWiFiAgent); 3701 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetwork()); 3702 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 3703 3704 mEthernetAgent.connect(true); 3705 callback.expectAvailableCallbacksUnvalidated(mEthernetAgent); 3706 // TODO: Investigate sending validated before losing. 3707 callback.expectLosing(mWiFiAgent); 3708 callback.expectCaps(mEthernetAgent, c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 3709 defaultCallback.expectAvailableDoubleValidatedCallbacks(mEthernetAgent); 3710 assertEquals(mEthernetAgent.getNetwork(), mCm.getActiveNetwork()); 3711 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 3712 3713 mEthernetAgent.disconnect(); 3714 callback.expect(LOST, mEthernetAgent); 3715 defaultCallback.expect(LOST, mEthernetAgent); 3716 defaultCallback.expectAvailableCallbacksValidated(mWiFiAgent); 3717 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 3718 3719 for (int i = 0; i < 4; i++) { 3720 TestNetworkAgentWrapper oldNetwork, newNetwork; 3721 if (i % 2 == 0) { 3722 mWiFiAgent.adjustScore(-15); 3723 oldNetwork = mWiFiAgent; 3724 newNetwork = mCellAgent; 3725 } else { 3726 mWiFiAgent.adjustScore(15); 3727 oldNetwork = mCellAgent; 3728 newNetwork = mWiFiAgent; 3729 3730 } 3731 callback.expectLosing(oldNetwork); 3732 // TODO: should we send an AVAILABLE callback to newNetwork, to indicate that it is no 3733 // longer lingering? 3734 defaultCallback.expectAvailableCallbacksValidated(newNetwork); 3735 assertEquals(newNetwork.getNetwork(), mCm.getActiveNetwork()); 3736 } 3737 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetwork()); 3738 3739 // Verify that if a network no longer satisfies a request, we send LOST and not LOSING, even 3740 // if the network is still up. 3741 mWiFiAgent.removeCapability(NET_CAPABILITY_NOT_METERED); 3742 // We expect a notification about the capabilities change, and nothing else. 3743 defaultCallback.expectCaps(mWiFiAgent, c -> !c.hasCapability(NET_CAPABILITY_NOT_METERED)); 3744 defaultCallback.assertNoCallback(); 3745 callback.expect(LOST, mWiFiAgent); 3746 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 3747 3748 // Wifi no longer satisfies our listen, which is for an unmetered network. 3749 // But because its score is 55, it's still up (and the default network). 3750 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetwork()); 3751 3752 // Disconnect our test networks. 3753 mWiFiAgent.disconnect(); 3754 defaultCallback.expect(LOST, mWiFiAgent); 3755 defaultCallback.expectAvailableCallbacksValidated(mCellAgent); 3756 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 3757 mCellAgent.disconnect(); 3758 defaultCallback.expect(LOST, mCellAgent); 3759 waitForIdle(); 3760 assertEquals(null, mCm.getActiveNetwork()); 3761 3762 mCm.unregisterNetworkCallback(callback); 3763 waitForIdle(); 3764 3765 // Check that a network is only lingered or torn down if it would not satisfy a request even 3766 // if it validated. 3767 request = new NetworkRequest.Builder().clearCapabilities().build(); 3768 callback = new TestNetworkCallback(); 3769 3770 mCm.registerNetworkCallback(request, callback); 3771 3772 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 3773 mCellAgent.connect(false); // Score: 10 3774 callback.expectAvailableCallbacksUnvalidated(mCellAgent); 3775 defaultCallback.expectAvailableCallbacksUnvalidated(mCellAgent); 3776 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetwork()); 3777 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 3778 3779 // Bring up wifi with a score of 20. 3780 // Cell stays up because it would satisfy the default request if it validated. 3781 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3782 mWiFiAgent.connect(false); // Score: 20 3783 callback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 3784 defaultCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 3785 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetwork()); 3786 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 3787 3788 mWiFiAgent.disconnect(); 3789 callback.expect(LOST, mWiFiAgent); 3790 defaultCallback.expect(LOST, mWiFiAgent); 3791 defaultCallback.expectAvailableCallbacksUnvalidated(mCellAgent); 3792 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetwork()); 3793 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 3794 3795 // Bring up wifi, then validate it. Previous versions would immediately tear down cell, but 3796 // it's arguably correct to linger it, since it was the default network before it validated. 3797 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3798 mWiFiAgent.connect(true); 3799 callback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 3800 // TODO: Investigate sending validated before losing. 3801 callback.expectLosing(mCellAgent); 3802 callback.expectCaps(mWiFiAgent, c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 3803 defaultCallback.expectAvailableThenValidatedCallbacks(mWiFiAgent); 3804 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetwork()); 3805 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 3806 3807 mWiFiAgent.disconnect(); 3808 callback.expect(LOST, mWiFiAgent); 3809 defaultCallback.expect(LOST, mWiFiAgent); 3810 defaultCallback.expectAvailableCallbacksUnvalidated(mCellAgent); 3811 mCellAgent.disconnect(); 3812 callback.expect(LOST, mCellAgent); 3813 defaultCallback.expect(LOST, mCellAgent); 3814 waitForIdle(); 3815 assertEquals(null, mCm.getActiveNetwork()); 3816 3817 // If a network is lingering, and we add and remove a request from it, resume lingering. 3818 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 3819 mCellAgent.connect(true); 3820 callback.expectAvailableThenValidatedCallbacks(mCellAgent); 3821 defaultCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 3822 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 3823 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3824 mWiFiAgent.connect(true); 3825 defaultCallback.expectAvailableDoubleValidatedCallbacks(mWiFiAgent); 3826 callback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 3827 // TODO: Investigate sending validated before losing. 3828 callback.expectLosing(mCellAgent); 3829 callback.expectCaps(mWiFiAgent, c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 3830 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 3831 3832 NetworkRequest cellRequest = new NetworkRequest.Builder() 3833 .addTransportType(TRANSPORT_CELLULAR).build(); 3834 NetworkCallback noopCallback = new NetworkCallback(); 3835 mCm.requestNetwork(cellRequest, noopCallback); 3836 // TODO: should this cause an AVAILABLE callback, to indicate that the network is no longer 3837 // lingering? 3838 mCm.unregisterNetworkCallback(noopCallback); 3839 callback.expectLosing(mCellAgent); 3840 3841 // Similar to the above: lingering can start even after the lingered request is removed. 3842 // Disconnect wifi and switch to cell. 3843 mWiFiAgent.disconnect(); 3844 callback.expect(LOST, mWiFiAgent); 3845 defaultCallback.expect(LOST, mWiFiAgent); 3846 defaultCallback.expectAvailableCallbacksValidated(mCellAgent); 3847 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 3848 3849 // Cell is now the default network. Pin it with a cell-specific request. 3850 noopCallback = new NetworkCallback(); // Can't reuse NetworkCallbacks. http://b/20701525 3851 mCm.requestNetwork(cellRequest, noopCallback); 3852 3853 // Now connect wifi, and expect it to become the default network. 3854 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3855 mWiFiAgent.connect(true); 3856 callback.expectAvailableThenValidatedCallbacks(mWiFiAgent); 3857 defaultCallback.expectAvailableDoubleValidatedCallbacks(mWiFiAgent); 3858 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 3859 // The default request is lingering on cell, but nothing happens to cell, and we send no 3860 // callbacks for it, because it's kept up by cellRequest. 3861 callback.assertNoCallback(); 3862 // Now unregister cellRequest and expect cell to start lingering. 3863 mCm.unregisterNetworkCallback(noopCallback); 3864 callback.expectLosing(mCellAgent); 3865 3866 // Let linger run its course. 3867 callback.assertNoCallback(0 /* timeoutMs */); 3868 final int lingerTimeoutMs = mService.mLingerDelayMs + mService.mLingerDelayMs / 4; 3869 callback.expect(LOST, mCellAgent, lingerTimeoutMs); 3870 3871 // Register a TRACK_DEFAULT request and check that it does not affect lingering. 3872 TestNetworkCallback trackDefaultCallback = new TestNetworkCallback(); 3873 mCm.registerDefaultNetworkCallback(trackDefaultCallback); 3874 trackDefaultCallback.expectAvailableCallbacksValidated(mWiFiAgent); 3875 mEthernetAgent = new TestNetworkAgentWrapper(TRANSPORT_ETHERNET); 3876 mEthernetAgent.connect(true); 3877 callback.expectAvailableCallbacksUnvalidated(mEthernetAgent); 3878 callback.expectLosing(mWiFiAgent); 3879 callback.expectCaps(mEthernetAgent, c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 3880 trackDefaultCallback.expectAvailableDoubleValidatedCallbacks(mEthernetAgent); 3881 defaultCallback.expectAvailableDoubleValidatedCallbacks(mEthernetAgent); 3882 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 3883 3884 // Let linger run its course. 3885 callback.expect(LOST, mWiFiAgent, lingerTimeoutMs); 3886 3887 // Clean up. 3888 mEthernetAgent.disconnect(); 3889 callback.expect(LOST, mEthernetAgent); 3890 defaultCallback.expect(LOST, mEthernetAgent); 3891 trackDefaultCallback.expect(LOST, mEthernetAgent); 3892 3893 mCm.unregisterNetworkCallback(callback); 3894 mCm.unregisterNetworkCallback(defaultCallback); 3895 mCm.unregisterNetworkCallback(trackDefaultCallback); 3896 } 3897 3898 private void grantUsingBackgroundNetworksPermissionForUid(final int uid) throws Exception { 3899 grantUsingBackgroundNetworksPermissionForUid(uid, mContext.getPackageName()); 3900 } 3901 3902 private void grantUsingBackgroundNetworksPermissionForUid( 3903 final int uid, final String packageName) throws Exception { 3904 doReturn(buildPackageInfo(true /* hasSystemPermission */, uid)).when(mPackageManager) 3905 .getPackageInfo(eq(packageName), eq(GET_PERMISSIONS)); 3906 3907 // Send a broadcast indicating a package was installed. 3908 final Intent addedIntent = new Intent(ACTION_PACKAGE_ADDED); 3909 addedIntent.putExtra(Intent.EXTRA_UID, uid); 3910 addedIntent.setData(Uri.parse("package:" + packageName)); 3911 processBroadcast(addedIntent); 3912 } 3913 3914 @Test 3915 public void testNetworkGoesIntoBackgroundAfterLinger() throws Exception { 3916 setAlwaysOnNetworks(true); 3917 grantUsingBackgroundNetworksPermissionForUid(Binder.getCallingUid()); 3918 NetworkRequest request = new NetworkRequest.Builder() 3919 .clearCapabilities() 3920 .build(); 3921 TestNetworkCallback callback = new TestNetworkCallback(); 3922 mCm.registerNetworkCallback(request, callback); 3923 3924 TestNetworkCallback defaultCallback = new TestNetworkCallback(); 3925 mCm.registerDefaultNetworkCallback(defaultCallback); 3926 3927 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 3928 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 3929 3930 mCellAgent.connect(true); 3931 callback.expectAvailableThenValidatedCallbacks(mCellAgent); 3932 defaultCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 3933 3934 // Wifi comes up and cell lingers. 3935 mWiFiAgent.connect(true); 3936 defaultCallback.expectAvailableDoubleValidatedCallbacks(mWiFiAgent); 3937 callback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 3938 callback.expectLosing(mCellAgent); 3939 callback.expectCaps(mWiFiAgent, c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 3940 3941 // File a request for cellular, then release it. 3942 NetworkRequest cellRequest = new NetworkRequest.Builder() 3943 .addTransportType(TRANSPORT_CELLULAR).build(); 3944 NetworkCallback noopCallback = new NetworkCallback(); 3945 mCm.requestNetwork(cellRequest, noopCallback); 3946 mCm.unregisterNetworkCallback(noopCallback); 3947 callback.expectLosing(mCellAgent); 3948 3949 // Let linger run its course. 3950 callback.assertNoCallback(); 3951 final int lingerTimeoutMs = TEST_LINGER_DELAY_MS + TEST_LINGER_DELAY_MS / 4; 3952 callback.expectCaps(mCellAgent, lingerTimeoutMs, 3953 c -> !c.hasCapability(NET_CAPABILITY_FOREGROUND)); 3954 3955 // Clean up. 3956 mCm.unregisterNetworkCallback(defaultCallback); 3957 mCm.unregisterNetworkCallback(callback); 3958 } 3959 3960 /** Expects the specified notification and returns the notification ID. */ 3961 private int expectNotification(TestNetworkAgentWrapper agent, NotificationType type) { 3962 verify(mNotificationManager, timeout(TIMEOUT_MS)).notify( 3963 eq(NetworkNotificationManager.tagFor(agent.getNetwork().netId)), 3964 eq(type.eventId), any()); 3965 return type.eventId; 3966 } 3967 3968 private void expectNoNotification(@NonNull final TestNetworkAgentWrapper agent) { 3969 verify(mNotificationManager, never()).notifyAsUser(anyString(), anyInt(), any(), any()); 3970 } 3971 3972 /** 3973 * Expects the specified notification happens when the unvalidated prompt message arrives 3974 * 3975 * @return the notification ID. 3976 **/ 3977 private int expectUnvalidationCheckWillNotify(TestNetworkAgentWrapper agent, 3978 NotificationType type) { 3979 mService.scheduleEvaluationTimeout(agent.getNetwork(), 0 /* delayMs */); 3980 waitForIdle(); 3981 return expectNotification(agent, type); 3982 } 3983 3984 /** 3985 * Expects that the notification for the specified network is cleared. 3986 * 3987 * This generally happens when the network disconnects or when the newtwork validates. During 3988 * normal usage the notification is also cleared by the system when the notification is tapped. 3989 */ 3990 private void expectClearNotification(TestNetworkAgentWrapper agent, NotificationType type) { 3991 verify(mNotificationManager, timeout(TIMEOUT_MS)).cancel( 3992 eq(NetworkNotificationManager.tagFor(agent.getNetwork().netId)), eq(type.eventId)); 3993 } 3994 3995 /** 3996 * Expects that no notification happens when the unvalidated prompt message arrives 3997 * 3998 * @return the notification ID. 3999 **/ 4000 private void expectUnvalidationCheckWillNotNotify(TestNetworkAgentWrapper agent) { 4001 mService.scheduleEvaluationTimeout(agent.getNetwork(), 0 /*delayMs */); 4002 waitForIdle(); 4003 expectNoNotification(agent); 4004 } 4005 4006 private void expectDisconnectAndClearNotifications(TestNetworkCallback callback, 4007 TestNetworkAgentWrapper agent, NotificationType type) { 4008 callback.expect(LOST, agent); 4009 expectClearNotification(agent, type); 4010 } 4011 4012 private NativeNetworkConfig nativeNetworkConfigPhysical(int netId, int permission) { 4013 return new NativeNetworkConfig(netId, NativeNetworkType.PHYSICAL, permission, 4014 /*secure=*/ false, VpnManager.TYPE_VPN_NONE, /*excludeLocalRoutes=*/ false); 4015 } 4016 4017 private NativeNetworkConfig nativeNetworkConfigVpn(int netId, boolean secure, int vpnType) { 4018 return new NativeNetworkConfig(netId, NativeNetworkType.VIRTUAL, INetd.PERMISSION_NONE, 4019 secure, vpnType, /*excludeLocalRoutes=*/ false); 4020 } 4021 4022 @Test 4023 public void testNetworkAgentCallbacks() throws Exception { 4024 // Keeps track of the order of events that happen in this test. 4025 final LinkedBlockingQueue<String> eventOrder = new LinkedBlockingQueue<>(); 4026 4027 final NetworkRequest request = new NetworkRequest.Builder() 4028 .addTransportType(TRANSPORT_WIFI).build(); 4029 final TestNetworkCallback callback = new TestNetworkCallback(); 4030 4031 // Expectations for state when various callbacks fire. These expectations run on the handler 4032 // thread and not on the test thread because they need to prevent the handler thread from 4033 // advancing while they examine state. 4034 4035 // 1. When onCreated fires, netd has been told to create the network. 4036 final Consumer<NetworkAgent> onNetworkCreated = (agent) -> { 4037 eventOrder.offer("onNetworkCreated"); 4038 try { 4039 verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( 4040 agent.getNetwork().getNetId(), INetd.PERMISSION_NONE)); 4041 } catch (RemoteException impossible) { 4042 fail(); 4043 } 4044 }; 4045 4046 // 2. onNetworkUnwanted isn't precisely ordered with respect to any particular events. Just 4047 // check that it is fired at some point after disconnect. 4048 final Consumer<NetworkAgent> onNetworkUnwanted = (agent) -> { 4049 eventOrder.offer("onNetworkUnwanted"); 4050 }; 4051 4052 // 3. While the teardown timer is running, connectivity APIs report the network is gone, but 4053 // netd has not yet been told to destroy it. 4054 final Consumer<Network> duringTeardown = (network) -> { 4055 eventOrder.offer("timePasses"); 4056 assertNull(mCm.getLinkProperties(network)); 4057 try { 4058 verify(mMockNetd, never()).networkDestroy(network.getNetId()); 4059 } catch (RemoteException impossible) { 4060 fail(); 4061 } 4062 }; 4063 4064 // 4. After onNetworkDisconnected is called, connectivity APIs report the network is gone, 4065 // and netd has been told to destroy it. 4066 final Consumer<NetworkAgent> onNetworkDisconnected = (agent) -> { 4067 eventOrder.offer("onNetworkDisconnected"); 4068 assertNull(mCm.getLinkProperties(agent.getNetwork())); 4069 try { 4070 verify(mMockNetd).networkDestroy(agent.getNetwork().getNetId()); 4071 } catch (RemoteException impossible) { 4072 fail(); 4073 } 4074 }; 4075 4076 final NetworkAgentWrapper.Callbacks callbacks = new NetworkAgentWrapper.Callbacks( 4077 onNetworkCreated, onNetworkUnwanted, onNetworkDisconnected); 4078 4079 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, callbacks); 4080 4081 if (mService.shouldCreateNetworksImmediately(mWiFiAgent.getNetworkCapabilities())) { 4082 assertEquals("onNetworkCreated", eventOrder.poll(TIMEOUT_MS, TimeUnit.MILLISECONDS)); 4083 } else { 4084 assertNull(eventOrder.poll()); 4085 } 4086 4087 // Connect a network, and file a request for it after it has come up, to ensure the nascent 4088 // timer is cleared and the test does not have to wait for it. Filing the request after the 4089 // network has come up is necessary because ConnectivityService does not appear to clear the 4090 // nascent timer if the first request satisfied by the network was filed before the network 4091 // connected. 4092 // TODO: fix this bug, file the request before connecting, and remove the waitForIdle. 4093 mWiFiAgent.connectWithoutInternet(); 4094 if (!mService.shouldCreateNetworksImmediately(mWiFiAgent.getNetworkCapabilities())) { 4095 assertEquals("onNetworkCreated", eventOrder.poll(TIMEOUT_MS, TimeUnit.MILLISECONDS)); 4096 } else { 4097 waitForIdle(); 4098 assertNull(eventOrder.poll()); 4099 } 4100 mCm.requestNetwork(request, callback); 4101 callback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 4102 4103 // Set teardown delay and make sure CS has processed it. 4104 mWiFiAgent.getNetworkAgent().setTeardownDelayMillis(300); 4105 waitForIdle(); 4106 4107 // Post the duringTeardown lambda to the handler so it fires while teardown is in progress. 4108 // The delay must be long enough it will run after the unregisterNetworkCallback has torn 4109 // down the network and started the teardown timer, and short enough that the lambda is 4110 // scheduled to run before the teardown timer. 4111 final Handler h = new Handler(mCsHandlerThread.getLooper()); 4112 h.postDelayed(() -> duringTeardown.accept(mWiFiAgent.getNetwork()), 150); 4113 4114 // Disconnect the network and check that events happened in the right order. 4115 mCm.unregisterNetworkCallback(callback); 4116 assertEquals("onNetworkUnwanted", eventOrder.poll(TIMEOUT_MS, TimeUnit.MILLISECONDS)); 4117 assertEquals("timePasses", eventOrder.poll(TIMEOUT_MS, TimeUnit.MILLISECONDS)); 4118 assertEquals("onNetworkDisconnected", eventOrder.poll(TIMEOUT_MS, TimeUnit.MILLISECONDS)); 4119 4120 mCm.unregisterNetworkCallback(callback); 4121 } 4122 4123 @Test 4124 public void testExplicitlySelected() throws Exception { 4125 final NetworkRequest request = new NetworkRequest.Builder() 4126 .clearCapabilities().addCapability(NET_CAPABILITY_INTERNET) 4127 .build(); 4128 final TestNetworkCallback callback = new TestNetworkCallback(); 4129 mCm.registerNetworkCallback(request, callback); 4130 4131 // Bring up validated cell 4132 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 4133 mCellAgent.connect(true); 4134 callback.expectAvailableThenValidatedCallbacks(mCellAgent); 4135 4136 // Bring up unvalidated wifi with explicitlySelected=true. 4137 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4138 mWiFiAgent.explicitlySelected(true, false); 4139 mWiFiAgent.connect(false); 4140 callback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 4141 4142 // Cell remains the default. 4143 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetwork()); 4144 4145 // Expect a high-priority NO_INTERNET notification. 4146 expectUnvalidationCheckWillNotify(mWiFiAgent, NotificationType.NO_INTERNET); 4147 4148 // Lower WiFi's score to lower than cell, and check that it doesn't disconnect because 4149 // it's explicitly selected. 4150 mWiFiAgent.adjustScore(-40); 4151 mWiFiAgent.adjustScore(40); 4152 callback.assertNoCallback(); 4153 4154 // If the user chooses yes on the "No Internet access, stay connected?" dialog, we switch to 4155 // wifi even though it's unvalidated. 4156 mCm.setAcceptUnvalidated(mWiFiAgent.getNetwork(), true, false); 4157 callback.expectLosing(mCellAgent); 4158 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetwork()); 4159 4160 // Disconnect wifi, and then reconnect, again with explicitlySelected=true. 4161 mWiFiAgent.disconnect(); 4162 expectDisconnectAndClearNotifications(callback, mWiFiAgent, NotificationType.NO_INTERNET); 4163 4164 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4165 mWiFiAgent.explicitlySelected(true, false); 4166 mWiFiAgent.connect(false); 4167 callback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 4168 4169 // Expect a high-priority NO_INTERNET notification. 4170 expectUnvalidationCheckWillNotify(mWiFiAgent, NotificationType.NO_INTERNET); 4171 4172 // If the user chooses no on the "No Internet access, stay connected?" dialog, we ask the 4173 // network to disconnect. 4174 mCm.setAcceptUnvalidated(mWiFiAgent.getNetwork(), false, false); 4175 expectDisconnectAndClearNotifications(callback, mWiFiAgent, NotificationType.NO_INTERNET); 4176 reset(mNotificationManager); 4177 4178 // Reconnect, again with explicitlySelected=true, but this time validate. 4179 // Expect no notifications. 4180 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4181 mWiFiAgent.explicitlySelected(true, false); 4182 mWiFiAgent.connect(true); 4183 callback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 4184 callback.expectLosing(mCellAgent); 4185 callback.expectCaps(mWiFiAgent, c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 4186 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetwork()); 4187 expectUnvalidationCheckWillNotNotify(mWiFiAgent); 4188 4189 // Now request cell so it doesn't disconnect during the test 4190 final NetworkRequest cellRequest = new NetworkRequest.Builder() 4191 .clearCapabilities().addTransportType(TRANSPORT_CELLULAR).build(); 4192 final TestNetworkCallback cellCallback = new TestNetworkCallback(); 4193 mCm.requestNetwork(cellRequest, cellCallback); 4194 4195 mEthernetAgent = new TestNetworkAgentWrapper(TRANSPORT_ETHERNET); 4196 mEthernetAgent.connect(true); 4197 callback.expectAvailableCallbacksUnvalidated(mEthernetAgent); 4198 callback.expectLosing(mWiFiAgent); 4199 callback.expectCaps(mEthernetAgent, c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 4200 assertEquals(mEthernetAgent.getNetwork(), mCm.getActiveNetwork()); 4201 callback.assertNoCallback(); 4202 4203 // Disconnect wifi, and then reconnect as if the user had selected "yes, don't ask again" 4204 // (i.e., with explicitlySelected=true and acceptUnvalidated=true). Expect to switch to 4205 // wifi immediately. 4206 mWiFiAgent.disconnect(); 4207 callback.expect(LOST, mWiFiAgent); 4208 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4209 mWiFiAgent.explicitlySelected(true, true); 4210 mWiFiAgent.connect(false); 4211 callback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 4212 callback.expectLosing(mEthernetAgent); 4213 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetwork()); 4214 mEthernetAgent.disconnect(); 4215 callback.expect(LOST, mEthernetAgent); 4216 expectUnvalidationCheckWillNotNotify(mWiFiAgent); 4217 4218 // Disconnect and reconnect with explicitlySelected=false and acceptUnvalidated=true. 4219 // Check that the network is not scored specially and that the device prefers cell data. 4220 mWiFiAgent.disconnect(); 4221 callback.expect(LOST, mWiFiAgent); 4222 4223 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4224 mWiFiAgent.explicitlySelected(false, true); 4225 mWiFiAgent.connect(false); 4226 callback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 4227 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetwork()); 4228 expectUnvalidationCheckWillNotNotify(mWiFiAgent); 4229 4230 // Clean up. 4231 mWiFiAgent.disconnect(); 4232 mCellAgent.disconnect(); 4233 4234 callback.expect(LOST, mWiFiAgent); 4235 callback.expect(LOST, mCellAgent); 4236 mCm.unregisterNetworkCallback(cellCallback); 4237 } 4238 4239 private void doTestFirstEvaluation( 4240 @NonNull final Consumer<TestNetworkAgentWrapper> doConnect, 4241 final boolean waitForSecondCaps, 4242 final boolean evaluatedByValidation) 4243 throws Exception { 4244 final NetworkRequest request = new NetworkRequest.Builder() 4245 .addTransportType(TRANSPORT_WIFI) 4246 .build(); 4247 TestNetworkCallback callback = new TestNetworkCallback(); 4248 mCm.registerNetworkCallback(request, callback); 4249 4250 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4251 doConnect.accept(mWiFiAgent); 4252 // Expect the available callbacks, but don't require specific values for their arguments 4253 // since this method doesn't know how the network was connected. 4254 callback.expect(AVAILABLE, mWiFiAgent); 4255 callback.expect(NETWORK_CAPS_UPDATED, mWiFiAgent); 4256 callback.expect(LINK_PROPERTIES_CHANGED, mWiFiAgent); 4257 callback.expect(BLOCKED_STATUS, mWiFiAgent); 4258 if (waitForSecondCaps) { 4259 // This is necessary because of b/245893397, the same bug that happens where we use 4260 // expectAvailableDoubleValidatedCallbacks. 4261 callback.expect(NETWORK_CAPS_UPDATED, mWiFiAgent); 4262 } 4263 final NetworkAgentInfo nai = 4264 mService.getNetworkAgentInfoForNetwork(mWiFiAgent.getNetwork()); 4265 final long firstEvaluation = nai.getFirstEvaluationConcludedTime(); 4266 if (evaluatedByValidation) { 4267 assertNotEquals(0L, firstEvaluation); 4268 } else { 4269 assertEquals(0L, firstEvaluation); 4270 } 4271 mService.scheduleEvaluationTimeout(mWiFiAgent.getNetwork(), 0L /* timeout */); 4272 waitForIdle(); 4273 if (evaluatedByValidation) { 4274 assertEquals(firstEvaluation, nai.getFirstEvaluationConcludedTime()); 4275 } else { 4276 assertNotEquals(0L, nai.getFirstEvaluationConcludedTime()); 4277 } 4278 mWiFiAgent.disconnect(); 4279 callback.expect(LOST, mWiFiAgent); 4280 4281 mCm.unregisterNetworkCallback(callback); 4282 } 4283 4284 @Test 4285 public void testEverEvaluated() throws Exception { 4286 doTestFirstEvaluation(naw -> naw.connect(true /* validated */), 4287 true /* waitForSecondCaps */, true /* immediatelyEvaluated */); 4288 doTestFirstEvaluation(naw -> naw.connectWithPartialConnectivity(), 4289 true /* waitForSecondCaps */, true /* immediatelyEvaluated */); 4290 doTestFirstEvaluation(naw -> naw.connectWithCaptivePortal(TEST_REDIRECT_URL, false), 4291 true /* waitForSecondCaps */, true /* immediatelyEvaluated */); 4292 doTestFirstEvaluation(naw -> naw.connect(false /* validated */), 4293 false /* waitForSecondCaps */, false /* immediatelyEvaluated */); 4294 } 4295 4296 private void tryNetworkFactoryRequests(int capability) throws Exception { 4297 // Verify NOT_RESTRICTED is set appropriately 4298 final NetworkCapabilities nc = new NetworkRequest.Builder().addCapability(capability) 4299 .build().networkCapabilities; 4300 if (capability == NET_CAPABILITY_CBS || capability == NET_CAPABILITY_DUN 4301 || capability == NET_CAPABILITY_EIMS || capability == NET_CAPABILITY_FOTA 4302 || capability == NET_CAPABILITY_IA || capability == NET_CAPABILITY_IMS 4303 || capability == NET_CAPABILITY_RCS || capability == NET_CAPABILITY_XCAP 4304 || capability == NET_CAPABILITY_VSIM || capability == NET_CAPABILITY_BIP 4305 || capability == NET_CAPABILITY_ENTERPRISE || capability == NET_CAPABILITY_MMTEL) { 4306 assertFalse(nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)); 4307 } else { 4308 assertTrue(nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)); 4309 } 4310 4311 NetworkCapabilities filter = new NetworkCapabilities(); 4312 filter.addTransportType(TRANSPORT_CELLULAR); 4313 filter.addCapability(capability); 4314 // Add NOT_VCN_MANAGED capability into filter unconditionally since some requests will add 4315 // NOT_VCN_MANAGED automatically but not for NetworkCapabilities, 4316 // see {@code NetworkCapabilities#deduceNotVcnManagedCapability} for more details. 4317 filter.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED); 4318 final HandlerThread handlerThread = new HandlerThread("testNetworkFactoryRequests"); 4319 handlerThread.start(); 4320 final MockNetworkFactory testFactory = new MockNetworkFactory(handlerThread.getLooper(), 4321 mServiceContext, "testFactory", filter, mCsHandlerThread); 4322 testFactory.setScoreFilter(45); 4323 testFactory.register(); 4324 4325 final NetworkCallback networkCallback; 4326 if (capability != NET_CAPABILITY_INTERNET) { 4327 // If the capability passed in argument is part of the default request, then the 4328 // factory will see the default request. Otherwise the filter will prevent the 4329 // factory from seeing it. In that case, add a request so it can be tested. 4330 assertFalse(testFactory.getMyStartRequested()); 4331 NetworkRequest request = new NetworkRequest.Builder().addCapability(capability).build(); 4332 networkCallback = new NetworkCallback(); 4333 mCm.requestNetwork(request, networkCallback); 4334 } else { 4335 networkCallback = null; 4336 } 4337 testFactory.expectRequestAdd(); 4338 testFactory.assertRequestCountEquals(1); 4339 assertTrue(testFactory.getMyStartRequested()); 4340 4341 // Now bring in a higher scored network. 4342 TestNetworkAgentWrapper testAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 4343 // When testAgent connects, because of its score (50 legacy int / cell transport) 4344 // it will beat or equal the testFactory's offer, so the request will be removed. 4345 // Note the agent as validated only if the capability is INTERNET, as it's the only case 4346 // where it makes sense. 4347 testAgent.connect(NET_CAPABILITY_INTERNET == capability /* validated */); 4348 testAgent.addCapability(capability); 4349 testFactory.expectRequestRemove(); 4350 testFactory.assertRequestCountEquals(0); 4351 assertFalse(testFactory.getMyStartRequested()); 4352 4353 // Add a request and make sure it's not sent to the factory, because the agent 4354 // is satisfying it better. 4355 final NetworkCallback cb = new ConnectivityManager.NetworkCallback(); 4356 mCm.requestNetwork(new NetworkRequest.Builder().addCapability(capability).build(), cb); 4357 expectNoRequestChanged(testFactory); 4358 testFactory.assertRequestCountEquals(0); 4359 assertFalse(testFactory.getMyStartRequested()); 4360 4361 // If using legacy scores, make the test agent weak enough to have the exact same score as 4362 // the factory (50 for cell - 5 adjustment). Make sure the factory doesn't see the request. 4363 // If not using legacy score, this is a no-op and the "same score removes request" behavior 4364 // has already been tested above. 4365 testAgent.adjustScore(-5); 4366 expectNoRequestChanged(testFactory); 4367 assertFalse(testFactory.getMyStartRequested()); 4368 4369 // Make the test agent weak enough that the factory will see the two requests (the one that 4370 // was just sent, and either the default one or the one sent at the top of this test if 4371 // the default won't be seen). 4372 testAgent.setScore(new NetworkScore.Builder().setLegacyInt(2).setExiting(true).build()); 4373 testFactory.expectRequestAdds(2); 4374 testFactory.assertRequestCountEquals(2); 4375 assertTrue(testFactory.getMyStartRequested()); 4376 4377 // Now unregister and make sure the request is removed. 4378 mCm.unregisterNetworkCallback(cb); 4379 testFactory.expectRequestRemove(); 4380 4381 // Bring in a bunch of requests. 4382 assertEquals(1, testFactory.getMyRequestCount()); 4383 ConnectivityManager.NetworkCallback[] networkCallbacks = 4384 new ConnectivityManager.NetworkCallback[10]; 4385 for (int i = 0; i< networkCallbacks.length; i++) { 4386 networkCallbacks[i] = new ConnectivityManager.NetworkCallback(); 4387 NetworkRequest.Builder builder = new NetworkRequest.Builder(); 4388 builder.addCapability(capability); 4389 mCm.requestNetwork(builder.build(), networkCallbacks[i]); 4390 } 4391 testFactory.expectRequestAdds(10); 4392 testFactory.assertRequestCountEquals(11); // +1 for the default/test specific request 4393 assertTrue(testFactory.getMyStartRequested()); 4394 4395 // Remove the requests. 4396 for (int i = 0; i < networkCallbacks.length; i++) { 4397 mCm.unregisterNetworkCallback(networkCallbacks[i]); 4398 } 4399 testFactory.expectRequestRemoves(10); 4400 testFactory.assertRequestCountEquals(1); 4401 assertTrue(testFactory.getMyStartRequested()); 4402 4403 // Adjust the agent score up again. Expect the request to be withdrawn. 4404 testAgent.setScore(new NetworkScore.Builder().setLegacyInt(50).build()); 4405 testFactory.expectRequestRemove(); 4406 testFactory.assertRequestCountEquals(0); 4407 assertFalse(testFactory.getMyStartRequested()); 4408 4409 // Drop the higher scored network. 4410 testAgent.disconnect(); 4411 testFactory.expectRequestAdd(); 4412 testFactory.assertRequestCountEquals(1); 4413 assertEquals(1, testFactory.getMyRequestCount()); 4414 assertTrue(testFactory.getMyStartRequested()); 4415 4416 testFactory.terminate(); 4417 testFactory.assertNoRequestChanged(); 4418 if (networkCallback != null) mCm.unregisterNetworkCallback(networkCallback); 4419 4420 handlerThread.quitSafely(); 4421 handlerThread.join(); 4422 } 4423 4424 @Test 4425 public void testNetworkFactoryRequests() throws Exception { 4426 tryNetworkFactoryRequests(NET_CAPABILITY_MMS); 4427 tryNetworkFactoryRequests(NET_CAPABILITY_SUPL); 4428 tryNetworkFactoryRequests(NET_CAPABILITY_DUN); 4429 tryNetworkFactoryRequests(NET_CAPABILITY_FOTA); 4430 tryNetworkFactoryRequests(NET_CAPABILITY_IMS); 4431 tryNetworkFactoryRequests(NET_CAPABILITY_CBS); 4432 tryNetworkFactoryRequests(NET_CAPABILITY_WIFI_P2P); 4433 tryNetworkFactoryRequests(NET_CAPABILITY_IA); 4434 tryNetworkFactoryRequests(NET_CAPABILITY_RCS); 4435 tryNetworkFactoryRequests(NET_CAPABILITY_MMTEL); 4436 tryNetworkFactoryRequests(NET_CAPABILITY_XCAP); 4437 tryNetworkFactoryRequests(NET_CAPABILITY_ENTERPRISE); 4438 tryNetworkFactoryRequests(NET_CAPABILITY_EIMS); 4439 tryNetworkFactoryRequests(NET_CAPABILITY_NOT_METERED); 4440 tryNetworkFactoryRequests(NET_CAPABILITY_INTERNET); 4441 tryNetworkFactoryRequests(NET_CAPABILITY_TRUSTED); 4442 tryNetworkFactoryRequests(NET_CAPABILITY_NOT_VPN); 4443 tryNetworkFactoryRequests(NET_CAPABILITY_VSIM); 4444 tryNetworkFactoryRequests(NET_CAPABILITY_BIP); 4445 // Skipping VALIDATED and CAPTIVE_PORTAL as they're disallowed. 4446 } 4447 4448 @Test 4449 public void testRegisterIgnoringScore() throws Exception { 4450 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4451 mWiFiAgent.setScore(new NetworkScore.Builder().setLegacyInt(90).build()); 4452 mWiFiAgent.connect(true /* validated */); 4453 4454 // Make sure the factory sees the default network 4455 final NetworkCapabilities filter = new NetworkCapabilities(); 4456 filter.addTransportType(TRANSPORT_CELLULAR); 4457 filter.addCapability(NET_CAPABILITY_INTERNET); 4458 filter.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED); 4459 final HandlerThread handlerThread = new HandlerThread("testNetworkFactoryRequests"); 4460 handlerThread.start(); 4461 final MockNetworkFactory testFactory = new MockNetworkFactory(handlerThread.getLooper(), 4462 mServiceContext, "testFactory", filter, mCsHandlerThread); 4463 testFactory.register(); 4464 4465 final MockNetworkFactory testFactoryAll = new MockNetworkFactory(handlerThread.getLooper(), 4466 mServiceContext, "testFactoryAll", filter, mCsHandlerThread); 4467 testFactoryAll.registerIgnoringScore(); 4468 4469 // The regular test factory should not see the request, because WiFi is stronger than cell. 4470 expectNoRequestChanged(testFactory); 4471 // With ignoringScore though the request is seen. 4472 testFactoryAll.expectRequestAdd(); 4473 4474 // The legacy int will be ignored anyway, set the only other knob to true 4475 mWiFiAgent.setScore(new NetworkScore.Builder().setLegacyInt(110) 4476 .setTransportPrimary(true).build()); 4477 4478 expectNoRequestChanged(testFactory); // still not seeing the request 4479 expectNoRequestChanged(testFactoryAll); // still seeing the request 4480 4481 mWiFiAgent.disconnect(); 4482 handlerThread.quitSafely(); 4483 handlerThread.join(); 4484 } 4485 4486 @Test 4487 public void testNetworkFactoryUnregister() throws Exception { 4488 // Make sure the factory sees the default network 4489 final NetworkCapabilities filter = new NetworkCapabilities(); 4490 filter.addCapability(NET_CAPABILITY_INTERNET); 4491 filter.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED); 4492 4493 final HandlerThread handlerThread = new HandlerThread("testNetworkFactoryRequests"); 4494 handlerThread.start(); 4495 4496 // Checks that calling setScoreFilter on a NetworkFactory immediately before closing it 4497 // does not crash. 4498 for (int i = 0; i < 100; i++) { 4499 final MockNetworkFactory testFactory = new MockNetworkFactory(handlerThread.getLooper(), 4500 mServiceContext, "testFactory", filter, mCsHandlerThread); 4501 // Register the factory and don't be surprised when the default request arrives. 4502 testFactory.register(); 4503 testFactory.expectRequestAdd(); 4504 4505 testFactory.setScoreFilter(42); 4506 testFactory.terminate(); 4507 testFactory.assertNoRequestChanged(); 4508 4509 if (i % 2 == 0) { 4510 try { 4511 testFactory.register(); 4512 fail("Re-registering terminated NetworkFactory should throw"); 4513 } catch (IllegalStateException expected) { 4514 } 4515 } 4516 } 4517 handlerThread.quitSafely(); 4518 handlerThread.join(); 4519 } 4520 4521 @Test 4522 public void testNoMutableNetworkRequests() throws Exception { 4523 final PendingIntent pendingIntent = PendingIntent.getBroadcast( 4524 mContext, 0 /* requestCode */, new Intent("a"), FLAG_IMMUTABLE); 4525 final NetworkRequest request1 = new NetworkRequest.Builder() 4526 .addCapability(NET_CAPABILITY_VALIDATED) 4527 .build(); 4528 final NetworkRequest request2 = new NetworkRequest.Builder() 4529 .addCapability(NET_CAPABILITY_CAPTIVE_PORTAL) 4530 .build(); 4531 4532 final Class<IllegalArgumentException> expected = IllegalArgumentException.class; 4533 assertThrows(expected, () -> mCm.requestNetwork(request1, new NetworkCallback())); 4534 assertThrows(expected, () -> mCm.requestNetwork(request1, pendingIntent)); 4535 assertThrows(expected, () -> mCm.requestNetwork(request2, new NetworkCallback())); 4536 assertThrows(expected, () -> mCm.requestNetwork(request2, pendingIntent)); 4537 } 4538 4539 @Test 4540 public void testNoAllowedUidsInNetworkRequests() throws Exception { 4541 final PendingIntent pendingIntent = PendingIntent.getBroadcast( 4542 mContext, 0 /* requestCode */, new Intent("a"), FLAG_IMMUTABLE); 4543 final NetworkRequest r = new NetworkRequest.Builder().build(); 4544 final ArraySet<Integer> allowedUids = new ArraySet<>(); 4545 allowedUids.add(6); 4546 allowedUids.add(9); 4547 r.networkCapabilities.setAllowedUids(allowedUids); 4548 4549 final Handler handler = new Handler(ConnectivityThread.getInstanceLooper()); 4550 final NetworkCallback cb = new NetworkCallback(); 4551 4552 final Class<IllegalArgumentException> expected = IllegalArgumentException.class; 4553 assertThrows(expected, () -> mCm.requestNetwork(r, cb)); 4554 assertThrows(expected, () -> mCm.requestNetwork(r, pendingIntent)); 4555 assertThrows(expected, () -> mCm.registerNetworkCallback(r, cb)); 4556 assertThrows(expected, () -> mCm.registerNetworkCallback(r, cb, handler)); 4557 assertThrows(expected, () -> mCm.registerNetworkCallback(r, pendingIntent)); 4558 assertThrows(expected, () -> mCm.registerBestMatchingNetworkCallback(r, cb, handler)); 4559 4560 // Make sure that resetting the access UIDs to the empty set will allow calling 4561 // requestNetwork and registerNetworkCallback. 4562 r.networkCapabilities.setAllowedUids(Collections.emptySet()); 4563 mCm.requestNetwork(r, cb); 4564 mCm.unregisterNetworkCallback(cb); 4565 mCm.registerNetworkCallback(r, cb); 4566 mCm.unregisterNetworkCallback(cb); 4567 } 4568 4569 @Test 4570 public void testMMSonWiFi() throws Exception { 4571 // Test bringing up cellular without MMS NetworkRequest gets reaped 4572 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 4573 mCellAgent.addCapability(NET_CAPABILITY_MMS); 4574 mCellAgent.connectWithoutInternet(); 4575 mCellAgent.expectDisconnected(); 4576 waitForIdle(); 4577 assertEmpty(mCm.getAllNetworks()); 4578 verifyNoNetwork(); 4579 4580 // Test bringing up validated WiFi. 4581 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4582 final ExpectedBroadcast b = expectConnectivityAction(TYPE_WIFI, DetailedState.CONNECTED); 4583 mWiFiAgent.connect(true); 4584 b.expectBroadcast(); 4585 verifyActiveNetwork(TRANSPORT_WIFI); 4586 4587 // Register MMS NetworkRequest 4588 NetworkRequest.Builder builder = new NetworkRequest.Builder(); 4589 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_MMS); 4590 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 4591 mCm.requestNetwork(builder.build(), networkCallback); 4592 4593 // Test bringing up unvalidated cellular with MMS 4594 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 4595 mCellAgent.addCapability(NET_CAPABILITY_MMS); 4596 mCellAgent.connectWithoutInternet(); 4597 networkCallback.expectAvailableCallbacksUnvalidated(mCellAgent); 4598 verifyActiveNetwork(TRANSPORT_WIFI); 4599 4600 // Test releasing NetworkRequest disconnects cellular with MMS 4601 mCm.unregisterNetworkCallback(networkCallback); 4602 mCellAgent.expectDisconnected(); 4603 verifyActiveNetwork(TRANSPORT_WIFI); 4604 } 4605 4606 @Test 4607 public void testMMSonCell() throws Exception { 4608 // Test bringing up cellular without MMS 4609 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 4610 ExpectedBroadcast b = expectConnectivityAction(TYPE_MOBILE, DetailedState.CONNECTED); 4611 mCellAgent.connect(false); 4612 b.expectBroadcast(); 4613 verifyActiveNetwork(TRANSPORT_CELLULAR); 4614 4615 // Register MMS NetworkRequest 4616 NetworkRequest.Builder builder = new NetworkRequest.Builder(); 4617 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_MMS); 4618 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 4619 mCm.requestNetwork(builder.build(), networkCallback); 4620 4621 // Test bringing up MMS cellular network 4622 TestNetworkAgentWrapper 4623 mmsNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 4624 mmsNetworkAgent.addCapability(NET_CAPABILITY_MMS); 4625 mmsNetworkAgent.connectWithoutInternet(); 4626 networkCallback.expectAvailableCallbacksUnvalidated(mmsNetworkAgent); 4627 verifyActiveNetwork(TRANSPORT_CELLULAR); 4628 4629 // Test releasing MMS NetworkRequest does not disconnect main cellular NetworkAgent 4630 mCm.unregisterNetworkCallback(networkCallback); 4631 mmsNetworkAgent.expectDisconnected(); 4632 verifyActiveNetwork(TRANSPORT_CELLULAR); 4633 } 4634 4635 @Test 4636 public void testPartialConnectivity() throws Exception { 4637 // Register network callback. 4638 NetworkRequest request = new NetworkRequest.Builder() 4639 .clearCapabilities().addCapability(NET_CAPABILITY_INTERNET) 4640 .build(); 4641 TestNetworkCallback callback = new TestNetworkCallback(); 4642 mCm.registerNetworkCallback(request, callback); 4643 4644 // Bring up validated mobile data. 4645 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 4646 mCellAgent.connect(true); 4647 callback.expectAvailableThenValidatedCallbacks(mCellAgent); 4648 4649 // Bring up wifi with partial connectivity. 4650 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4651 mWiFiAgent.connectWithPartialConnectivity(); 4652 callback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 4653 callback.expectCaps(mWiFiAgent, c -> c.hasCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY)); 4654 4655 // Mobile data should be the default network. 4656 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetwork()); 4657 callback.assertNoCallback(); 4658 4659 // Expect a PARTIAL_CONNECTIVITY notification. The notification appears as soon as partial 4660 // connectivity is detected, and is low priority because the network was not explicitly 4661 // selected by the user. This happens if we reconnect to a network where the user previously 4662 // accepted partial connectivity without checking "always". 4663 expectNotification(mWiFiAgent, NotificationType.PARTIAL_CONNECTIVITY); 4664 4665 // With HTTPS probe disabled, NetworkMonitor should pass the network validation with http 4666 // probe. 4667 mWiFiAgent.setNetworkPartialValid(false /* privateDnsProbeSent */); 4668 // If the user chooses yes to use this partial connectivity wifi, switch the default 4669 // network to wifi and check if wifi becomes valid or not. 4670 mCm.setAcceptPartialConnectivity(mWiFiAgent.getNetwork(), true /* accept */, 4671 false /* always */); 4672 // If user accepts partial connectivity network, 4673 // NetworkMonitor#setAcceptPartialConnectivity() should be called too. 4674 waitForIdle(); 4675 verify(mWiFiAgent.mNetworkMonitor, times(1)).setAcceptPartialConnectivity(); 4676 4677 // Need a trigger point to let NetworkMonitor tell ConnectivityService that the network is 4678 // validated. 4679 mCm.reportNetworkConnectivity(mWiFiAgent.getNetwork(), true); 4680 callback.expectLosing(mCellAgent); 4681 NetworkCapabilities nc = 4682 callback.expectCaps(mWiFiAgent, c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 4683 assertTrue(nc.hasCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY)); 4684 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetwork()); 4685 4686 // Once the network validates, the notification disappears. 4687 expectClearNotification(mWiFiAgent, NotificationType.PARTIAL_CONNECTIVITY); 4688 4689 // Disconnect and reconnect wifi with partial connectivity again. 4690 mWiFiAgent.disconnect(); 4691 callback.expect(LOST, mWiFiAgent); 4692 4693 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4694 mWiFiAgent.connectWithPartialConnectivity(); 4695 callback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 4696 callback.expectCaps(mWiFiAgent, c -> c.hasCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY)); 4697 4698 // Mobile data should be the default network. 4699 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetwork()); 4700 waitForIdle(); 4701 4702 // Expect a low-priority PARTIAL_CONNECTIVITY notification as soon as partial connectivity 4703 // is detected. 4704 expectNotification(mWiFiAgent, NotificationType.PARTIAL_CONNECTIVITY); 4705 4706 // If the user chooses no, disconnect wifi immediately. 4707 mCm.setAcceptPartialConnectivity(mWiFiAgent.getNetwork(), false /* accept */, 4708 false /* always */); 4709 callback.expect(LOST, mWiFiAgent); 4710 expectClearNotification(mWiFiAgent, NotificationType.PARTIAL_CONNECTIVITY); 4711 reset(mNotificationManager); 4712 4713 // If the user accepted partial connectivity before, and the device connects to that network 4714 // again, but now the network has full connectivity, then the network shouldn't contain 4715 // NET_CAPABILITY_PARTIAL_CONNECTIVITY. 4716 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4717 // acceptUnvalidated is also used as setting for accepting partial networks. 4718 mWiFiAgent.explicitlySelected(true /* explicitlySelected */, true /* acceptUnvalidated */); 4719 mWiFiAgent.connect(true); 4720 expectUnvalidationCheckWillNotNotify(mWiFiAgent); 4721 4722 // If user accepted partial connectivity network before, 4723 // NetworkMonitor#setAcceptPartialConnectivity() will be called in 4724 // ConnectivityService#updateNetworkInfo(). 4725 callback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 4726 verify(mWiFiAgent.mNetworkMonitor, times(1)).setAcceptPartialConnectivity(); 4727 callback.expectLosing(mCellAgent); 4728 nc = callback.expectCaps(mWiFiAgent, c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 4729 assertFalse(nc.hasCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY)); 4730 4731 // Wifi should be the default network. 4732 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetwork()); 4733 mWiFiAgent.disconnect(); 4734 callback.expect(LOST, mWiFiAgent); 4735 4736 // The user accepted partial connectivity and selected "don't ask again". Now the user 4737 // reconnects to the partial connectivity network. Switch to wifi as soon as partial 4738 // connectivity is detected. 4739 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4740 mWiFiAgent.explicitlySelected(true /* explicitlySelected */, true /* acceptUnvalidated */); 4741 mWiFiAgent.connectWithPartialConnectivity(); 4742 // If user accepted partial connectivity network before, 4743 // NetworkMonitor#setAcceptPartialConnectivity() will be called in 4744 // ConnectivityService#updateNetworkInfo(). 4745 callback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 4746 verify(mWiFiAgent.mNetworkMonitor, times(1)).setAcceptPartialConnectivity(); 4747 callback.expectLosing(mCellAgent); 4748 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetwork()); 4749 callback.expectCaps(mWiFiAgent, c -> c.hasCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY)); 4750 expectUnvalidationCheckWillNotNotify(mWiFiAgent); 4751 4752 mWiFiAgent.setNetworkValid(false /* privateDnsProbeSent */); 4753 4754 // Need a trigger point to let NetworkMonitor tell ConnectivityService that the network is 4755 // validated. 4756 mCm.reportNetworkConnectivity(mWiFiAgent.getNetwork(), true); 4757 callback.expectCaps(mWiFiAgent, c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 4758 mWiFiAgent.disconnect(); 4759 callback.expect(LOST, mWiFiAgent); 4760 4761 // If the user accepted partial connectivity, and the device auto-reconnects to the partial 4762 // connectivity network, it should contain both PARTIAL_CONNECTIVITY and VALIDATED. 4763 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4764 mWiFiAgent.explicitlySelected(false /* explicitlySelected */, true /* acceptUnvalidated */); 4765 4766 // NetworkMonitor will immediately (once the HTTPS probe fails...) report the network as 4767 // valid, because ConnectivityService calls setAcceptPartialConnectivity before it calls 4768 // notifyNetworkConnected. 4769 mWiFiAgent.connectWithPartialValidConnectivity(false /* privateDnsProbeSent */); 4770 callback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 4771 verify(mWiFiAgent.mNetworkMonitor, times(1)).setAcceptPartialConnectivity(); 4772 callback.expectLosing(mCellAgent); 4773 callback.expectCaps(mWiFiAgent, c -> c.hasCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY) 4774 && c.hasCapability(NET_CAPABILITY_VALIDATED)); 4775 expectUnvalidationCheckWillNotNotify(mWiFiAgent); 4776 mWiFiAgent.disconnect(); 4777 callback.expect(LOST, mWiFiAgent); 4778 verifyNoMoreInteractions(mNotificationManager); 4779 } 4780 4781 @Test 4782 public void testCaptivePortalOnPartialConnectivity() throws Exception { 4783 final TestNetworkCallback wifiCallback = new TestNetworkCallback(); 4784 final NetworkRequest wifiRequest = new NetworkRequest.Builder() 4785 .addTransportType(TRANSPORT_WIFI) 4786 .build(); 4787 mCm.registerNetworkCallback(wifiRequest, wifiCallback); 4788 4789 final TestNetworkCallback validatedCallback = new TestNetworkCallback(); 4790 final NetworkRequest validatedRequest = new NetworkRequest.Builder() 4791 .addCapability(NET_CAPABILITY_VALIDATED).build(); 4792 mCm.registerNetworkCallback(validatedRequest, validatedCallback); 4793 4794 // Bring up a network with a captive portal. 4795 // Expect onAvailable callback of listen for NET_CAPABILITY_CAPTIVE_PORTAL. 4796 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4797 String redirectUrl = "http://android.com/path"; 4798 mWiFiAgent.connectWithCaptivePortal(redirectUrl, false /* privateDnsProbeSent */); 4799 wifiCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 4800 assertEquals(mWiFiAgent.waitForRedirectUrl(), redirectUrl); 4801 4802 // This is necessary because of b/245893397, the same bug that happens where we use 4803 // expectAvailableDoubleValidatedCallbacks. 4804 // TODO : fix b/245893397 and remove this. 4805 wifiCallback.expectCaps(mWiFiAgent, c -> c.hasCapability(NET_CAPABILITY_CAPTIVE_PORTAL)); 4806 4807 // Check that startCaptivePortalApp sends the expected command to NetworkMonitor. 4808 mCm.startCaptivePortalApp(mWiFiAgent.getNetwork()); 4809 verify(mWiFiAgent.mNetworkMonitor, timeout(TIMEOUT_MS).times(1)).launchCaptivePortalApp(); 4810 4811 // Report that the captive portal is dismissed with partial connectivity, and check that 4812 // callbacks are fired with PARTIAL and without CAPTIVE_PORTAL. 4813 mWiFiAgent.setNetworkPartial(); 4814 mCm.reportNetworkConnectivity(mWiFiAgent.getNetwork(), true); 4815 waitForIdle(); 4816 wifiCallback.expectCaps(mWiFiAgent, 4817 c -> c.hasCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY) 4818 && !c.hasCapability(NET_CAPABILITY_CAPTIVE_PORTAL)); 4819 4820 // Report partial connectivity is accepted. 4821 mWiFiAgent.setNetworkPartialValid(false /* privateDnsProbeSent */); 4822 mCm.setAcceptPartialConnectivity(mWiFiAgent.getNetwork(), true /* accept */, 4823 false /* always */); 4824 waitForIdle(); 4825 mCm.reportNetworkConnectivity(mWiFiAgent.getNetwork(), true); 4826 wifiCallback.expectCaps(mWiFiAgent, c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 4827 validatedCallback.expectAvailableCallbacksValidated(mWiFiAgent); 4828 validatedCallback.expectCaps(mWiFiAgent, 4829 c -> c.hasCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY)); 4830 4831 mCm.unregisterNetworkCallback(wifiCallback); 4832 mCm.unregisterNetworkCallback(validatedCallback); 4833 } 4834 4835 @Test 4836 public void testCaptivePortal() throws Exception { 4837 final TestNetworkCallback captivePortalCallback = new TestNetworkCallback(); 4838 final NetworkRequest captivePortalRequest = new NetworkRequest.Builder() 4839 .addCapability(NET_CAPABILITY_CAPTIVE_PORTAL).build(); 4840 mCm.registerNetworkCallback(captivePortalRequest, captivePortalCallback); 4841 4842 final TestNetworkCallback validatedCallback = new TestNetworkCallback(); 4843 final NetworkRequest validatedRequest = new NetworkRequest.Builder() 4844 .addCapability(NET_CAPABILITY_VALIDATED).build(); 4845 mCm.registerNetworkCallback(validatedRequest, validatedCallback); 4846 4847 // Bring up a network with a captive portal. 4848 // Expect onAvailable callback of listen for NET_CAPABILITY_CAPTIVE_PORTAL. 4849 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4850 String firstRedirectUrl = "http://example.com/firstPath"; 4851 mWiFiAgent.connectWithCaptivePortal(firstRedirectUrl, false /* privateDnsProbeSent */); 4852 captivePortalCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 4853 assertEquals(mWiFiAgent.waitForRedirectUrl(), firstRedirectUrl); 4854 4855 // Take down network. 4856 // Expect onLost callback. 4857 mWiFiAgent.disconnect(); 4858 captivePortalCallback.expect(LOST, mWiFiAgent); 4859 4860 // Bring up a network with a captive portal. 4861 // Expect onAvailable callback of listen for NET_CAPABILITY_CAPTIVE_PORTAL. 4862 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4863 String secondRedirectUrl = "http://example.com/secondPath"; 4864 mWiFiAgent.connectWithCaptivePortal(secondRedirectUrl, false /* privateDnsProbeSent */); 4865 captivePortalCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 4866 assertEquals(mWiFiAgent.waitForRedirectUrl(), secondRedirectUrl); 4867 4868 // Make captive portal disappear then revalidate. 4869 // Expect onLost callback because network no longer provides NET_CAPABILITY_CAPTIVE_PORTAL. 4870 mWiFiAgent.setNetworkValid(false /* privateDnsProbeSent */); 4871 mCm.reportNetworkConnectivity(mWiFiAgent.getNetwork(), true); 4872 captivePortalCallback.expect(LOST, mWiFiAgent); 4873 4874 // Expect NET_CAPABILITY_VALIDATED onAvailable callback. 4875 validatedCallback.expectAvailableDoubleValidatedCallbacks(mWiFiAgent); 4876 4877 // Break network connectivity. 4878 // Expect NET_CAPABILITY_VALIDATED onLost callback. 4879 mWiFiAgent.setNetworkInvalid(false /* invalidBecauseOfPrivateDns */); 4880 mCm.reportNetworkConnectivity(mWiFiAgent.getNetwork(), false); 4881 validatedCallback.expect(LOST, mWiFiAgent); 4882 } 4883 4884 private Intent startCaptivePortalApp(TestNetworkAgentWrapper networkAgent) throws Exception { 4885 Network network = networkAgent.getNetwork(); 4886 // Check that startCaptivePortalApp sends the expected command to NetworkMonitor. 4887 mCm.startCaptivePortalApp(network); 4888 waitForIdle(); 4889 verify(networkAgent.mNetworkMonitor).launchCaptivePortalApp(); 4890 4891 // NetworkMonitor uses startCaptivePortal(Network, Bundle) (startCaptivePortalAppInternal) 4892 final Bundle testBundle = new Bundle(); 4893 final String testKey = "testkey"; 4894 final String testValue = "testvalue"; 4895 testBundle.putString(testKey, testValue); 4896 mServiceContext.setPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, 4897 PERMISSION_GRANTED); 4898 mCm.startCaptivePortalApp(network, testBundle); 4899 final Intent signInIntent = mServiceContext.expectStartActivityIntent(TIMEOUT_MS); 4900 assertEquals(ACTION_CAPTIVE_PORTAL_SIGN_IN, signInIntent.getAction()); 4901 assertEquals(testValue, signInIntent.getStringExtra(testKey)); 4902 return signInIntent; 4903 } 4904 4905 @Test 4906 public void testCaptivePortalApp() throws Exception { 4907 final TestNetworkCallback captivePortalCallback = new TestNetworkCallback(); 4908 final NetworkRequest captivePortalRequest = new NetworkRequest.Builder() 4909 .addCapability(NET_CAPABILITY_CAPTIVE_PORTAL).build(); 4910 mCm.registerNetworkCallback(captivePortalRequest, captivePortalCallback); 4911 4912 final TestNetworkCallback validatedCallback = new TestNetworkCallback(); 4913 final NetworkRequest validatedRequest = new NetworkRequest.Builder() 4914 .addCapability(NET_CAPABILITY_VALIDATED).build(); 4915 mCm.registerNetworkCallback(validatedRequest, validatedCallback); 4916 4917 // Bring up wifi. 4918 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4919 mWiFiAgent.connect(true); 4920 validatedCallback.expectAvailableDoubleValidatedCallbacks(mWiFiAgent); 4921 Network wifiNetwork = mWiFiAgent.getNetwork(); 4922 4923 // Check that calling startCaptivePortalApp does nothing. 4924 final int fastTimeoutMs = 100; 4925 mCm.startCaptivePortalApp(wifiNetwork); 4926 waitForIdle(); 4927 verify(mWiFiAgent.mNetworkMonitor, never()).launchCaptivePortalApp(); 4928 mServiceContext.expectNoStartActivityIntent(fastTimeoutMs); 4929 4930 // Turn into a captive portal. 4931 mWiFiAgent.setNetworkPortal("http://example.com", false /* privateDnsProbeSent */); 4932 mCm.reportNetworkConnectivity(wifiNetwork, false); 4933 captivePortalCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 4934 validatedCallback.expect(LOST, mWiFiAgent); 4935 // This is necessary because of b/245893397, the same bug that happens where we use 4936 // expectAvailableDoubleValidatedCallbacks. 4937 // TODO : fix b/245893397 and remove this. 4938 captivePortalCallback.expectCaps(mWiFiAgent); 4939 4940 startCaptivePortalApp(mWiFiAgent); 4941 4942 // Report that the captive portal is dismissed, and check that callbacks are fired 4943 mWiFiAgent.setNetworkValid(false /* privateDnsProbeSent */); 4944 mWiFiAgent.mNetworkMonitor.forceReevaluation(Process.myUid()); 4945 validatedCallback.expectAvailableCallbacksValidated(mWiFiAgent); 4946 captivePortalCallback.expect(LOST, mWiFiAgent); 4947 4948 mCm.unregisterNetworkCallback(validatedCallback); 4949 mCm.unregisterNetworkCallback(captivePortalCallback); 4950 } 4951 4952 @Test 4953 public void testCaptivePortalApp_IgnoreNetwork() throws Exception { 4954 final TestNetworkCallback captivePortalCallback = new TestNetworkCallback(); 4955 final NetworkRequest captivePortalRequest = new NetworkRequest.Builder() 4956 .addCapability(NET_CAPABILITY_CAPTIVE_PORTAL).build(); 4957 mCm.registerNetworkCallback(captivePortalRequest, captivePortalCallback); 4958 4959 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4960 mWiFiAgent.connectWithCaptivePortal(TEST_REDIRECT_URL, false); 4961 captivePortalCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 4962 4963 final Intent signInIntent = startCaptivePortalApp(mWiFiAgent); 4964 final CaptivePortal captivePortal = signInIntent 4965 .getParcelableExtra(ConnectivityManager.EXTRA_CAPTIVE_PORTAL); 4966 4967 captivePortal.ignoreNetwork(); 4968 waitForIdle(); 4969 4970 // Since network will disconnect, ensure no notification of response to NetworkMonitor 4971 verify(mWiFiAgent.mNetworkMonitor, never()) 4972 .notifyCaptivePortalAppFinished(CaptivePortal.APP_RETURN_UNWANTED); 4973 4974 // Report that the network is disconnected 4975 mWiFiAgent.expectDisconnected(); 4976 mWiFiAgent.expectPreventReconnectReceived(); 4977 verify(mWiFiAgent.mNetworkMonitor).notifyNetworkDisconnected(); 4978 captivePortalCallback.expect(LOST, mWiFiAgent); 4979 4980 mCm.unregisterNetworkCallback(captivePortalCallback); 4981 } 4982 4983 @Test 4984 public void testAvoidOrIgnoreCaptivePortals() throws Exception { 4985 final TestNetworkCallback captivePortalCallback = new TestNetworkCallback(); 4986 final NetworkRequest captivePortalRequest = new NetworkRequest.Builder() 4987 .addCapability(NET_CAPABILITY_CAPTIVE_PORTAL).build(); 4988 mCm.registerNetworkCallback(captivePortalRequest, captivePortalCallback); 4989 4990 final TestNetworkCallback validatedCallback = new TestNetworkCallback(); 4991 final NetworkRequest validatedRequest = new NetworkRequest.Builder() 4992 .addCapability(NET_CAPABILITY_VALIDATED).build(); 4993 mCm.registerNetworkCallback(validatedRequest, validatedCallback); 4994 4995 setCaptivePortalMode(ConnectivitySettingsManager.CAPTIVE_PORTAL_MODE_AVOID); 4996 // Bring up a network with a captive portal. 4997 // Expect it to fail to connect and not result in any callbacks. 4998 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 4999 final String firstRedirectUrl = "http://example.com/firstPath"; 5000 5001 mWiFiAgent.connectWithCaptivePortal(firstRedirectUrl, false /* privateDnsProbeSent */); 5002 mWiFiAgent.expectDisconnected(); 5003 mWiFiAgent.expectPreventReconnectReceived(); 5004 5005 assertNoCallbacks(captivePortalCallback, validatedCallback); 5006 } 5007 5008 @Test 5009 public void testNoAvoidCaptivePortalOnWearProxy() throws Exception { 5010 // Bring up a BLUETOOTH network which is companion proxy on wear 5011 // then set captive portal. 5012 mockHasSystemFeature(PackageManager.FEATURE_WATCH, true); 5013 setCaptivePortalMode(ConnectivitySettingsManager.CAPTIVE_PORTAL_MODE_AVOID); 5014 TestNetworkAgentWrapper btAgent = new TestNetworkAgentWrapper(TRANSPORT_BLUETOOTH); 5015 final String firstRedirectUrl = "http://example.com/firstPath"; 5016 5017 btAgent.connectWithCaptivePortal(firstRedirectUrl, false /* privateDnsProbeSent */); 5018 btAgent.assertNotDisconnected(TIMEOUT_MS); 5019 } 5020 5021 @Test 5022 public void testAvoidCaptivePortalOnBluetooth() throws Exception { 5023 // When not on Wear, BLUETOOTH is just regular network, 5024 // then set captive portal. 5025 mockHasSystemFeature(PackageManager.FEATURE_WATCH, false); 5026 setCaptivePortalMode(ConnectivitySettingsManager.CAPTIVE_PORTAL_MODE_AVOID); 5027 TestNetworkAgentWrapper btAgent = new TestNetworkAgentWrapper(TRANSPORT_BLUETOOTH); 5028 final String firstRedirectUrl = "http://example.com/firstPath"; 5029 5030 btAgent.connectWithCaptivePortal(firstRedirectUrl, false /* privateDnsProbeSent */); 5031 5032 btAgent.expectDisconnected(); 5033 btAgent.expectPreventReconnectReceived(); 5034 } 5035 5036 @Test 5037 public void testCaptivePortalApi() throws Exception { 5038 mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_GRANTED); 5039 5040 final TestNetworkCallback captivePortalCallback = new TestNetworkCallback(); 5041 final NetworkRequest captivePortalRequest = new NetworkRequest.Builder() 5042 .addCapability(NET_CAPABILITY_CAPTIVE_PORTAL).build(); 5043 mCm.registerNetworkCallback(captivePortalRequest, captivePortalCallback); 5044 5045 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 5046 final String redirectUrl = "http://example.com/firstPath"; 5047 5048 mWiFiAgent.connectWithCaptivePortal(redirectUrl, 5049 false /* privateDnsProbeSent */); 5050 captivePortalCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 5051 5052 final CaptivePortalData testData = new CaptivePortalData.Builder() 5053 .setUserPortalUrl(Uri.parse(redirectUrl)) 5054 .setBytesRemaining(12345L) 5055 .build(); 5056 5057 mWiFiAgent.notifyCapportApiDataChanged(testData); 5058 5059 captivePortalCallback.expect(LINK_PROPERTIES_CHANGED, mWiFiAgent, 5060 cb -> testData.equals(cb.getLp().getCaptivePortalData())); 5061 5062 final LinkProperties newLps = new LinkProperties(); 5063 newLps.setMtu(1234); 5064 mWiFiAgent.sendLinkProperties(newLps); 5065 // CaptivePortalData is not lost and unchanged when LPs are received from the NetworkAgent 5066 captivePortalCallback.expect(LINK_PROPERTIES_CHANGED, mWiFiAgent, 5067 cb -> testData.equals(cb.getLp().getCaptivePortalData()) 5068 && cb.getLp().getMtu() == 1234); 5069 } 5070 5071 private TestNetworkCallback setupNetworkCallbackAndConnectToWifi() throws Exception { 5072 // Grant NETWORK_SETTINGS permission to be able to receive LinkProperties change callbacks 5073 // with sensitive (captive portal) data 5074 mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_GRANTED); 5075 5076 final TestNetworkCallback captivePortalCallback = new TestNetworkCallback(); 5077 final NetworkRequest captivePortalRequest = new NetworkRequest.Builder() 5078 .addCapability(NET_CAPABILITY_CAPTIVE_PORTAL).build(); 5079 mCm.registerNetworkCallback(captivePortalRequest, captivePortalCallback); 5080 5081 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 5082 5083 mWiFiAgent.connectWithCaptivePortal(TEST_REDIRECT_URL, 5084 false /* privateDnsProbeSent */); 5085 captivePortalCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 5086 return captivePortalCallback; 5087 } 5088 5089 private class CaptivePortalTestData { 5090 CaptivePortalTestData(CaptivePortalData naPasspointData, CaptivePortalData capportData, 5091 CaptivePortalData naOtherData, CaptivePortalData expectedMergedPasspointData, 5092 CaptivePortalData expectedMergedOtherData) { 5093 mNaPasspointData = naPasspointData; 5094 mCapportData = capportData; 5095 mNaOtherData = naOtherData; 5096 mExpectedMergedPasspointData = expectedMergedPasspointData; 5097 mExpectedMergedOtherData = expectedMergedOtherData; 5098 } 5099 5100 public final CaptivePortalData mNaPasspointData; 5101 public final CaptivePortalData mCapportData; 5102 public final CaptivePortalData mNaOtherData; 5103 public final CaptivePortalData mExpectedMergedPasspointData; 5104 public final CaptivePortalData mExpectedMergedOtherData; 5105 5106 } 5107 5108 private CaptivePortalTestData setupCaptivePortalData() { 5109 final CaptivePortalData capportData = new CaptivePortalData.Builder() 5110 .setUserPortalUrl(Uri.parse(TEST_REDIRECT_URL)) 5111 .setVenueInfoUrl(Uri.parse(TEST_VENUE_URL_CAPPORT)) 5112 .setUserPortalUrl(Uri.parse(TEST_USER_PORTAL_API_URL_CAPPORT)) 5113 .setExpiryTime(1000000L) 5114 .setBytesRemaining(12345L) 5115 .build(); 5116 5117 final CaptivePortalData naPasspointData = new CaptivePortalData.Builder() 5118 .setBytesRemaining(80802L) 5119 .setVenueInfoUrl(Uri.parse(TEST_VENUE_URL_NA_PASSPOINT), 5120 CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT) 5121 .setUserPortalUrl(Uri.parse(TEST_TERMS_AND_CONDITIONS_URL_NA_PASSPOINT), 5122 CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT) 5123 .setVenueFriendlyName(TEST_FRIENDLY_NAME).build(); 5124 5125 final CaptivePortalData naOtherData = new CaptivePortalData.Builder() 5126 .setBytesRemaining(80802L) 5127 .setVenueInfoUrl(Uri.parse(TEST_VENUE_URL_NA_OTHER), 5128 CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_OTHER) 5129 .setUserPortalUrl(Uri.parse(TEST_TERMS_AND_CONDITIONS_URL_NA_OTHER), 5130 CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_OTHER) 5131 .setVenueFriendlyName(TEST_FRIENDLY_NAME).build(); 5132 5133 final CaptivePortalData expectedMergedPasspointData = new CaptivePortalData.Builder() 5134 .setUserPortalUrl(Uri.parse(TEST_REDIRECT_URL)) 5135 .setBytesRemaining(12345L) 5136 .setExpiryTime(1000000L) 5137 .setVenueInfoUrl(Uri.parse(TEST_VENUE_URL_NA_PASSPOINT), 5138 CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT) 5139 .setUserPortalUrl(Uri.parse(TEST_TERMS_AND_CONDITIONS_URL_NA_PASSPOINT), 5140 CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT) 5141 .setVenueFriendlyName(TEST_FRIENDLY_NAME).build(); 5142 5143 final CaptivePortalData expectedMergedOtherData = new CaptivePortalData.Builder() 5144 .setUserPortalUrl(Uri.parse(TEST_REDIRECT_URL)) 5145 .setBytesRemaining(12345L) 5146 .setExpiryTime(1000000L) 5147 .setVenueInfoUrl(Uri.parse(TEST_VENUE_URL_CAPPORT)) 5148 .setUserPortalUrl(Uri.parse(TEST_USER_PORTAL_API_URL_CAPPORT)) 5149 .setVenueFriendlyName(TEST_FRIENDLY_NAME).build(); 5150 return new CaptivePortalTestData(naPasspointData, capportData, naOtherData, 5151 expectedMergedPasspointData, expectedMergedOtherData); 5152 } 5153 5154 @Test 5155 public void testMergeCaptivePortalApiWithFriendlyNameAndVenueUrl() throws Exception { 5156 final TestNetworkCallback captivePortalCallback = setupNetworkCallbackAndConnectToWifi(); 5157 final CaptivePortalTestData captivePortalTestData = setupCaptivePortalData(); 5158 5159 // Baseline capport data 5160 mWiFiAgent.notifyCapportApiDataChanged(captivePortalTestData.mCapportData); 5161 5162 captivePortalCallback.expect(LINK_PROPERTIES_CHANGED, mWiFiAgent, 5163 cb -> captivePortalTestData.mCapportData.equals(cb.getLp().getCaptivePortalData())); 5164 5165 // Venue URL, T&C URL and friendly name from Network agent with Passpoint source, confirm 5166 // that API data gets precedence on the bytes remaining. 5167 final LinkProperties linkProperties = new LinkProperties(); 5168 linkProperties.setCaptivePortalData(captivePortalTestData.mNaPasspointData); 5169 mWiFiAgent.sendLinkProperties(linkProperties); 5170 5171 // Make sure that the capport data is merged 5172 captivePortalCallback.expect(LINK_PROPERTIES_CHANGED, mWiFiAgent, 5173 cb -> captivePortalTestData.mExpectedMergedPasspointData.equals( 5174 cb.getLp().getCaptivePortalData())); 5175 5176 // Now send this information from non-Passpoint source, confirm that Capport data takes 5177 // precedence 5178 linkProperties.setCaptivePortalData(captivePortalTestData.mNaOtherData); 5179 mWiFiAgent.sendLinkProperties(linkProperties); 5180 5181 // Make sure that the capport data is merged 5182 captivePortalCallback.expect(LINK_PROPERTIES_CHANGED, mWiFiAgent, 5183 cb -> captivePortalTestData.mExpectedMergedOtherData.equals( 5184 cb.getLp().getCaptivePortalData())); 5185 5186 // Create a new LP with no Network agent capport data 5187 final LinkProperties newLps = new LinkProperties(); 5188 newLps.setMtu(1234); 5189 mWiFiAgent.sendLinkProperties(newLps); 5190 // CaptivePortalData is not lost and has the original values when LPs are received from the 5191 // NetworkAgent 5192 captivePortalCallback.expect(LINK_PROPERTIES_CHANGED, mWiFiAgent, 5193 cb -> captivePortalTestData.mCapportData.equals(cb.getLp().getCaptivePortalData()) 5194 && cb.getLp().getMtu() == 1234); 5195 5196 // Now send capport data only from the Network agent 5197 mWiFiAgent.notifyCapportApiDataChanged(null); 5198 captivePortalCallback.expect(LINK_PROPERTIES_CHANGED, mWiFiAgent, 5199 cb -> cb.getLp().getCaptivePortalData() == null); 5200 5201 newLps.setCaptivePortalData(captivePortalTestData.mNaPasspointData); 5202 mWiFiAgent.sendLinkProperties(newLps); 5203 5204 // Make sure that only the network agent capport data is available 5205 captivePortalCallback.expect(LINK_PROPERTIES_CHANGED, mWiFiAgent, 5206 cb -> captivePortalTestData.mNaPasspointData.equals( 5207 cb.getLp().getCaptivePortalData())); 5208 } 5209 5210 @Test 5211 public void testMergeCaptivePortalDataFromNetworkAgentFirstThenCapport() throws Exception { 5212 final TestNetworkCallback captivePortalCallback = setupNetworkCallbackAndConnectToWifi(); 5213 final CaptivePortalTestData captivePortalTestData = setupCaptivePortalData(); 5214 5215 // Venue URL and friendly name from Network agent, confirm that API data gets precedence 5216 // on the bytes remaining. 5217 final LinkProperties linkProperties = new LinkProperties(); 5218 linkProperties.setCaptivePortalData(captivePortalTestData.mNaPasspointData); 5219 mWiFiAgent.sendLinkProperties(linkProperties); 5220 5221 // Make sure that the data is saved correctly 5222 captivePortalCallback.expect(LINK_PROPERTIES_CHANGED, mWiFiAgent, 5223 cb -> captivePortalTestData.mNaPasspointData.equals( 5224 cb.getLp().getCaptivePortalData())); 5225 5226 // Expected merged data: Network agent data is preferred, and values that are not used by 5227 // it are merged from capport data 5228 mWiFiAgent.notifyCapportApiDataChanged(captivePortalTestData.mCapportData); 5229 5230 // Make sure that the Capport data is merged correctly 5231 captivePortalCallback.expect(LINK_PROPERTIES_CHANGED, mWiFiAgent, 5232 cb -> captivePortalTestData.mExpectedMergedPasspointData.equals( 5233 cb.getLp().getCaptivePortalData())); 5234 5235 // Now set the naData to null 5236 linkProperties.setCaptivePortalData(null); 5237 mWiFiAgent.sendLinkProperties(linkProperties); 5238 5239 // Make sure that the Capport data is retained correctly 5240 captivePortalCallback.expect(LINK_PROPERTIES_CHANGED, mWiFiAgent, 5241 cb -> captivePortalTestData.mCapportData.equals(cb.getLp().getCaptivePortalData())); 5242 } 5243 5244 @Test 5245 public void testMergeCaptivePortalDataFromNetworkAgentOtherSourceFirstThenCapport() 5246 throws Exception { 5247 final TestNetworkCallback captivePortalCallback = setupNetworkCallbackAndConnectToWifi(); 5248 final CaptivePortalTestData captivePortalTestData = setupCaptivePortalData(); 5249 5250 // Venue URL and friendly name from Network agent, confirm that API data gets precedence 5251 // on the bytes remaining. 5252 final LinkProperties linkProperties = new LinkProperties(); 5253 linkProperties.setCaptivePortalData(captivePortalTestData.mNaOtherData); 5254 mWiFiAgent.sendLinkProperties(linkProperties); 5255 5256 // Make sure that the data is saved correctly 5257 captivePortalCallback.expect(LINK_PROPERTIES_CHANGED, mWiFiAgent, 5258 cb -> captivePortalTestData.mNaOtherData.equals(cb.getLp().getCaptivePortalData())); 5259 5260 // Expected merged data: Network agent data is preferred, and values that are not used by 5261 // it are merged from capport data 5262 mWiFiAgent.notifyCapportApiDataChanged(captivePortalTestData.mCapportData); 5263 5264 // Make sure that the Capport data is merged correctly 5265 captivePortalCallback.expect(LINK_PROPERTIES_CHANGED, mWiFiAgent, 5266 cb -> captivePortalTestData.mExpectedMergedOtherData.equals( 5267 cb.getLp().getCaptivePortalData())); 5268 } 5269 5270 private NetworkRequest.Builder newWifiRequestBuilder() { 5271 return new NetworkRequest.Builder().addTransportType(TRANSPORT_WIFI); 5272 } 5273 5274 // A NetworkSpecifier subclass that matches all networks but must not be visible to apps. 5275 static class ConfidentialMatchAllNetworkSpecifier extends NetworkSpecifier implements 5276 Parcelable { 5277 public static final Parcelable.Creator<ConfidentialMatchAllNetworkSpecifier> CREATOR = 5278 new Parcelable.Creator<ConfidentialMatchAllNetworkSpecifier>() { 5279 public ConfidentialMatchAllNetworkSpecifier createFromParcel(Parcel in) { 5280 return new ConfidentialMatchAllNetworkSpecifier(); 5281 } 5282 5283 public ConfidentialMatchAllNetworkSpecifier[] newArray(int size) { 5284 return new ConfidentialMatchAllNetworkSpecifier[size]; 5285 } 5286 }; 5287 @Override 5288 public boolean canBeSatisfiedBy(NetworkSpecifier other) { 5289 return true; 5290 } 5291 5292 @Override 5293 public int describeContents() { 5294 return 0; 5295 } 5296 5297 @Override 5298 public void writeToParcel(Parcel dest, int flags) {} 5299 5300 @Override 5301 public NetworkSpecifier redact() { 5302 return null; 5303 } 5304 } 5305 5306 // A network specifier that matches either another LocalNetworkSpecifier with the same 5307 // string or a ConfidentialMatchAllNetworkSpecifier, and can be passed to apps as is. 5308 static class LocalStringNetworkSpecifier extends NetworkSpecifier implements Parcelable { 5309 public static final Parcelable.Creator<LocalStringNetworkSpecifier> CREATOR = 5310 new Parcelable.Creator<LocalStringNetworkSpecifier>() { 5311 public LocalStringNetworkSpecifier createFromParcel(Parcel in) { 5312 return new LocalStringNetworkSpecifier(in); 5313 } 5314 5315 public LocalStringNetworkSpecifier[] newArray(int size) { 5316 return new LocalStringNetworkSpecifier[size]; 5317 } 5318 }; 5319 private String mString; 5320 5321 LocalStringNetworkSpecifier(String string) { 5322 mString = string; 5323 } 5324 5325 LocalStringNetworkSpecifier(Parcel in) { 5326 mString = in.readString(); 5327 } 5328 5329 @Override 5330 public boolean canBeSatisfiedBy(NetworkSpecifier other) { 5331 if (other instanceof LocalStringNetworkSpecifier) { 5332 return TextUtils.equals(mString, 5333 ((LocalStringNetworkSpecifier) other).mString); 5334 } 5335 if (other instanceof ConfidentialMatchAllNetworkSpecifier) return true; 5336 return false; 5337 } 5338 5339 @Override 5340 public int describeContents() { 5341 return 0; 5342 } 5343 @Override 5344 public void writeToParcel(Parcel dest, int flags) { 5345 dest.writeString(mString); 5346 } 5347 } 5348 5349 /** 5350 * Verify request matching behavior with network specifiers. 5351 * 5352 * This test does not check updating the specifier on a live network because the specifier is 5353 * immutable and this triggers a WTF in 5354 * {@link ConnectivityService#mixInCapabilities(NetworkAgentInfo, NetworkCapabilities)}. 5355 */ 5356 @Test 5357 public void testNetworkSpecifier() throws Exception { 5358 NetworkRequest rEmpty1 = newWifiRequestBuilder().build(); 5359 NetworkRequest rEmpty2 = newWifiRequestBuilder().setNetworkSpecifier((String) null).build(); 5360 NetworkRequest rEmpty3 = newWifiRequestBuilder().setNetworkSpecifier("").build(); 5361 NetworkRequest rEmpty4 = newWifiRequestBuilder().setNetworkSpecifier( 5362 (NetworkSpecifier) null).build(); 5363 NetworkRequest rFoo = newWifiRequestBuilder().setNetworkSpecifier( 5364 new LocalStringNetworkSpecifier("foo")).build(); 5365 NetworkRequest rBar = newWifiRequestBuilder().setNetworkSpecifier( 5366 new LocalStringNetworkSpecifier("bar")).build(); 5367 5368 TestNetworkCallback cEmpty1 = new TestNetworkCallback(); 5369 TestNetworkCallback cEmpty2 = new TestNetworkCallback(); 5370 TestNetworkCallback cEmpty3 = new TestNetworkCallback(); 5371 TestNetworkCallback cEmpty4 = new TestNetworkCallback(); 5372 TestNetworkCallback cFoo = new TestNetworkCallback(); 5373 TestNetworkCallback cBar = new TestNetworkCallback(); 5374 TestNetworkCallback[] emptyCallbacks = new TestNetworkCallback[] { 5375 cEmpty1, cEmpty2, cEmpty3, cEmpty4 }; 5376 5377 mCm.registerNetworkCallback(rEmpty1, cEmpty1); 5378 mCm.registerNetworkCallback(rEmpty2, cEmpty2); 5379 mCm.registerNetworkCallback(rEmpty3, cEmpty3); 5380 mCm.registerNetworkCallback(rEmpty4, cEmpty4); 5381 mCm.registerNetworkCallback(rFoo, cFoo); 5382 mCm.registerNetworkCallback(rBar, cBar); 5383 5384 LocalStringNetworkSpecifier nsFoo = new LocalStringNetworkSpecifier("foo"); 5385 LocalStringNetworkSpecifier nsBar = new LocalStringNetworkSpecifier("bar"); 5386 5387 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 5388 mWiFiAgent.connect(false); 5389 expectAvailableCallbacksUnvalidatedWithSpecifier(mWiFiAgent, null /* specifier */, 5390 cEmpty1, cEmpty2, cEmpty3, cEmpty4); 5391 assertNoCallbacks(cFoo, cBar); 5392 5393 mWiFiAgent.disconnect(); 5394 expectOnLost(mWiFiAgent, cEmpty1, cEmpty2, cEmpty3, cEmpty4); 5395 5396 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 5397 mWiFiAgent.setNetworkSpecifier(nsFoo); 5398 mWiFiAgent.connect(false); 5399 expectAvailableCallbacksUnvalidatedWithSpecifier(mWiFiAgent, nsFoo, 5400 cEmpty1, cEmpty2, cEmpty3, cEmpty4, cFoo); 5401 cBar.assertNoCallback(); 5402 assertEquals(nsFoo, 5403 mCm.getNetworkCapabilities(mWiFiAgent.getNetwork()).getNetworkSpecifier()); 5404 assertNoCallbacks(cEmpty1, cEmpty2, cEmpty3, cEmpty4, cFoo); 5405 5406 mWiFiAgent.disconnect(); 5407 expectOnLost(mWiFiAgent, cEmpty1, cEmpty2, cEmpty3, cEmpty4, cFoo); 5408 5409 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 5410 mWiFiAgent.setNetworkSpecifier(nsBar); 5411 mWiFiAgent.connect(false); 5412 expectAvailableCallbacksUnvalidatedWithSpecifier(mWiFiAgent, nsBar, 5413 cEmpty1, cEmpty2, cEmpty3, cEmpty4, cBar); 5414 cFoo.assertNoCallback(); 5415 assertEquals(nsBar, 5416 mCm.getNetworkCapabilities(mWiFiAgent.getNetwork()).getNetworkSpecifier()); 5417 5418 mWiFiAgent.disconnect(); 5419 expectOnLost(mWiFiAgent, cEmpty1, cEmpty2, cEmpty3, cEmpty4, cBar); 5420 cFoo.assertNoCallback(); 5421 5422 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 5423 mWiFiAgent.setNetworkSpecifier(new ConfidentialMatchAllNetworkSpecifier()); 5424 mWiFiAgent.connect(false); 5425 expectAvailableCallbacksUnvalidatedWithSpecifier(mWiFiAgent, null /* specifier */, 5426 cEmpty1, cEmpty2, cEmpty3, cEmpty4, cFoo, cBar); 5427 assertNull(mCm.getNetworkCapabilities(mWiFiAgent.getNetwork()).getNetworkSpecifier()); 5428 5429 mWiFiAgent.disconnect(); 5430 expectOnLost(mWiFiAgent, cEmpty1, cEmpty2, cEmpty3, cEmpty4, cFoo, cBar); 5431 } 5432 5433 /** 5434 * @return the context's attribution tag 5435 */ 5436 private String getAttributionTag() { 5437 return mContext.getAttributionTag(); 5438 } 5439 5440 static class NonParcelableSpecifier extends NetworkSpecifier { 5441 @Override 5442 public boolean canBeSatisfiedBy(NetworkSpecifier other) { 5443 return false; 5444 } 5445 } 5446 static class ParcelableSpecifier extends NonParcelableSpecifier implements Parcelable { 5447 public static final Parcelable.Creator<NonParcelableSpecifier> CREATOR = 5448 new Parcelable.Creator<NonParcelableSpecifier>() { 5449 public NonParcelableSpecifier createFromParcel(Parcel in) { 5450 return new NonParcelableSpecifier(); 5451 } 5452 5453 public NonParcelableSpecifier[] newArray(int size) { 5454 return new NonParcelableSpecifier[size]; 5455 } 5456 }; 5457 @Override public int describeContents() { 5458 return 0; 5459 } 5460 @Override public void writeToParcel(Parcel p, int flags) {} 5461 } 5462 5463 @Test 5464 public void testInvalidNetworkSpecifier() { 5465 assertThrows(IllegalArgumentException.class, () -> { 5466 NetworkRequest.Builder builder = new NetworkRequest.Builder(); 5467 builder.setNetworkSpecifier(new MatchAllNetworkSpecifier()); 5468 }); 5469 5470 assertThrows(IllegalArgumentException.class, () -> { 5471 NetworkCapabilities networkCapabilities = new NetworkCapabilities(); 5472 networkCapabilities.addTransportType(TRANSPORT_WIFI) 5473 .setNetworkSpecifier(new MatchAllNetworkSpecifier()); 5474 mService.requestNetwork(Process.INVALID_UID, networkCapabilities, 5475 NetworkRequest.Type.REQUEST.ordinal(), null, 0, null, 5476 ConnectivityManager.TYPE_WIFI, NetworkCallback.FLAG_NONE, 5477 mContext.getPackageName(), getAttributionTag(), ~0 /* declaredMethodsFlag */); 5478 }); 5479 5480 final NetworkRequest.Builder builder = 5481 new NetworkRequest.Builder().addTransportType(TRANSPORT_ETHERNET); 5482 assertThrows(ClassCastException.class, () -> { 5483 builder.setNetworkSpecifier(new NonParcelableSpecifier()); 5484 Parcel parcelW = Parcel.obtain(); 5485 builder.build().writeToParcel(parcelW, 0); 5486 }); 5487 5488 final NetworkRequest nr = 5489 new NetworkRequest.Builder().addTransportType(TRANSPORT_ETHERNET) 5490 .setNetworkSpecifier(new ParcelableSpecifier()) 5491 .build(); 5492 assertNotNull(nr); 5493 5494 assertThrows(BadParcelableException.class, () -> { 5495 Parcel parcelW = Parcel.obtain(); 5496 nr.writeToParcel(parcelW, 0); 5497 byte[] bytes = parcelW.marshall(); 5498 parcelW.recycle(); 5499 5500 Parcel parcelR = Parcel.obtain(); 5501 parcelR.unmarshall(bytes, 0, bytes.length); 5502 parcelR.setDataPosition(0); 5503 NetworkRequest rereadNr = NetworkRequest.CREATOR.createFromParcel(parcelR); 5504 }); 5505 } 5506 5507 @Test 5508 public void testNetworkRequestUidSpoofSecurityException() throws Exception { 5509 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 5510 mWiFiAgent.connect(false); 5511 NetworkRequest networkRequest = newWifiRequestBuilder().build(); 5512 TestNetworkCallback networkCallback = new TestNetworkCallback(); 5513 doThrow(new SecurityException()).when(mAppOpsManager).checkPackage(anyInt(), anyString()); 5514 assertThrows(SecurityException.class, () -> { 5515 mCm.requestNetwork(networkRequest, networkCallback); 5516 }); 5517 } 5518 5519 @Test 5520 public void testInvalidSignalStrength() { 5521 NetworkRequest r = new NetworkRequest.Builder() 5522 .addCapability(NET_CAPABILITY_INTERNET) 5523 .addTransportType(TRANSPORT_WIFI) 5524 .setSignalStrength(-75) 5525 .build(); 5526 // Registering a NetworkCallback with signal strength but w/o NETWORK_SIGNAL_STRENGTH_WAKEUP 5527 // permission should get SecurityException. 5528 assertThrows(SecurityException.class, () -> 5529 mCm.registerNetworkCallback(r, new NetworkCallback())); 5530 5531 assertThrows(SecurityException.class, () -> 5532 mCm.registerNetworkCallback(r, PendingIntent.getService( 5533 mServiceContext, 0 /* requestCode */, new Intent(), FLAG_IMMUTABLE))); 5534 5535 // Requesting a Network with signal strength should get IllegalArgumentException. 5536 assertThrows(IllegalArgumentException.class, () -> 5537 mCm.requestNetwork(r, new NetworkCallback())); 5538 5539 assertThrows(IllegalArgumentException.class, () -> 5540 mCm.requestNetwork(r, PendingIntent.getService( 5541 mServiceContext, 0 /* requestCode */, new Intent(), FLAG_IMMUTABLE))); 5542 } 5543 5544 @Test 5545 public void testRegisterDefaultNetworkCallback() throws Exception { 5546 final TestNetworkCallback defaultNetworkCallback = new TestNetworkCallback(); 5547 mCm.registerDefaultNetworkCallback(defaultNetworkCallback); 5548 defaultNetworkCallback.assertNoCallback(); 5549 5550 final Handler handler = new Handler(ConnectivityThread.getInstanceLooper()); 5551 final TestNetworkCallback systemDefaultCallback = new TestNetworkCallback(); 5552 mCm.registerSystemDefaultNetworkCallback(systemDefaultCallback, handler); 5553 systemDefaultCallback.assertNoCallback(); 5554 5555 // Create a TRANSPORT_CELLULAR request to keep the mobile interface up 5556 // whenever Wi-Fi is up. Without this, the mobile network agent is 5557 // reaped before any other activity can take place. 5558 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback(); 5559 final NetworkRequest cellRequest = new NetworkRequest.Builder() 5560 .addTransportType(TRANSPORT_CELLULAR).build(); 5561 mCm.requestNetwork(cellRequest, cellNetworkCallback); 5562 cellNetworkCallback.assertNoCallback(); 5563 5564 // Bring up cell and expect CALLBACK_AVAILABLE. 5565 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 5566 mCellAgent.connect(true); 5567 cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 5568 defaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 5569 systemDefaultCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 5570 assertEquals(defaultNetworkCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 5571 assertEquals(systemDefaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 5572 5573 // Bring up wifi and expect CALLBACK_AVAILABLE. 5574 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 5575 mWiFiAgent.connect(true); 5576 cellNetworkCallback.assertNoCallback(); 5577 defaultNetworkCallback.expectAvailableDoubleValidatedCallbacks(mWiFiAgent); 5578 systemDefaultCallback.expectAvailableDoubleValidatedCallbacks(mWiFiAgent); 5579 assertEquals(defaultNetworkCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 5580 assertEquals(systemDefaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 5581 5582 // Bring down cell. Expect no default network callback, since it wasn't the default. 5583 mCellAgent.disconnect(); 5584 cellNetworkCallback.expect(LOST, mCellAgent); 5585 defaultNetworkCallback.assertNoCallback(); 5586 systemDefaultCallback.assertNoCallback(); 5587 assertEquals(defaultNetworkCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 5588 assertEquals(systemDefaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 5589 5590 // Bring up cell. Expect no default network callback, since it won't be the default. 5591 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 5592 mCellAgent.connect(true); 5593 cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 5594 defaultNetworkCallback.assertNoCallback(); 5595 systemDefaultCallback.assertNoCallback(); 5596 assertEquals(defaultNetworkCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 5597 assertEquals(systemDefaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 5598 5599 // Bring down wifi. Expect the default network callback to notified of LOST wifi 5600 // followed by AVAILABLE cell. 5601 mWiFiAgent.disconnect(); 5602 cellNetworkCallback.assertNoCallback(); 5603 defaultNetworkCallback.expect(LOST, mWiFiAgent); 5604 defaultNetworkCallback.expectAvailableCallbacksValidated(mCellAgent); 5605 systemDefaultCallback.expect(LOST, mWiFiAgent); 5606 systemDefaultCallback.expectAvailableCallbacksValidated(mCellAgent); 5607 mCellAgent.disconnect(); 5608 cellNetworkCallback.expect(LOST, mCellAgent); 5609 defaultNetworkCallback.expect(LOST, mCellAgent); 5610 systemDefaultCallback.expect(LOST, mCellAgent); 5611 waitForIdle(); 5612 assertEquals(null, mCm.getActiveNetwork()); 5613 5614 mMockVpn.establishForMyUid(); 5615 assertUidRangesUpdatedForMyUid(true); 5616 defaultNetworkCallback.expectAvailableThenValidatedCallbacks(mMockVpn); 5617 systemDefaultCallback.assertNoCallback(); 5618 assertEquals(defaultNetworkCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 5619 assertEquals(null, systemDefaultCallback.getLastAvailableNetwork()); 5620 5621 mMockVpn.disconnect(); 5622 defaultNetworkCallback.expect(LOST, mMockVpn); 5623 systemDefaultCallback.assertNoCallback(); 5624 waitForIdle(); 5625 assertEquals(null, mCm.getActiveNetwork()); 5626 } 5627 5628 @Test 5629 public void testAdditionalStateCallbacks() throws Exception { 5630 // File a network request for mobile. 5631 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback(); 5632 final NetworkRequest cellRequest = new NetworkRequest.Builder() 5633 .addTransportType(TRANSPORT_CELLULAR).build(); 5634 mCm.requestNetwork(cellRequest, cellNetworkCallback); 5635 5636 // Bring up the mobile network. 5637 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 5638 mCellAgent.connect(true); 5639 5640 // We should get onAvailable(), onCapabilitiesChanged(), and 5641 // onLinkPropertiesChanged() in rapid succession. Additionally, we 5642 // should get onCapabilitiesChanged() when the mobile network validates. 5643 cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 5644 cellNetworkCallback.assertNoCallback(); 5645 5646 // Update LinkProperties. 5647 final LinkProperties lp = new LinkProperties(); 5648 lp.setInterfaceName("foonet_data0"); 5649 mCellAgent.sendLinkProperties(lp); 5650 // We should get onLinkPropertiesChanged(). 5651 cellNetworkCallback.expect(LINK_PROPERTIES_CHANGED, mCellAgent); 5652 cellNetworkCallback.assertNoCallback(); 5653 5654 // Suspend the network. 5655 mCellAgent.suspend(); 5656 cellNetworkCallback.expectCaps(mCellAgent, 5657 c -> !c.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 5658 cellNetworkCallback.expect(SUSPENDED, mCellAgent); 5659 cellNetworkCallback.assertNoCallback(); 5660 assertEquals(NetworkInfo.State.SUSPENDED, mCm.getActiveNetworkInfo().getState()); 5661 5662 // Register a garden variety default network request. 5663 TestNetworkCallback dfltNetworkCallback = new TestNetworkCallback(); 5664 mCm.registerDefaultNetworkCallback(dfltNetworkCallback); 5665 // We should get onAvailable(), onCapabilitiesChanged(), onLinkPropertiesChanged(), 5666 // as well as onNetworkSuspended() in rapid succession. 5667 dfltNetworkCallback.expectAvailableAndSuspendedCallbacks(mCellAgent, true); 5668 dfltNetworkCallback.assertNoCallback(); 5669 mCm.unregisterNetworkCallback(dfltNetworkCallback); 5670 5671 mCellAgent.resume(); 5672 cellNetworkCallback.expectCaps(mCellAgent, 5673 c -> c.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 5674 cellNetworkCallback.expect(RESUMED, mCellAgent); 5675 cellNetworkCallback.assertNoCallback(); 5676 assertEquals(NetworkInfo.State.CONNECTED, mCm.getActiveNetworkInfo().getState()); 5677 5678 dfltNetworkCallback = new TestNetworkCallback(); 5679 mCm.registerDefaultNetworkCallback(dfltNetworkCallback); 5680 // This time onNetworkSuspended should not be called. 5681 dfltNetworkCallback.expectAvailableCallbacksValidated(mCellAgent); 5682 dfltNetworkCallback.assertNoCallback(); 5683 5684 mCm.unregisterNetworkCallback(dfltNetworkCallback); 5685 mCm.unregisterNetworkCallback(cellNetworkCallback); 5686 } 5687 5688 @Test 5689 public void testRegisterPrivilegedDefaultCallbacksRequirePermissions() throws Exception { 5690 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 5691 mCellAgent.connect(false /* validated */); 5692 mServiceContext.setPermission(CONNECTIVITY_USE_RESTRICTED_NETWORKS, PERMISSION_DENIED); 5693 5694 final Handler handler = new Handler(ConnectivityThread.getInstanceLooper()); 5695 final TestNetworkCallback callback = new TestNetworkCallback(); 5696 assertThrows(SecurityException.class, 5697 () -> mCm.registerSystemDefaultNetworkCallback(callback, handler)); 5698 callback.assertNoCallback(); 5699 assertThrows(SecurityException.class, 5700 () -> mCm.registerDefaultNetworkCallbackForUid(APP1_UID, callback, handler)); 5701 callback.assertNoCallback(); 5702 5703 mServiceContext.setPermission(CONNECTIVITY_USE_RESTRICTED_NETWORKS, PERMISSION_GRANTED); 5704 mCm.registerSystemDefaultNetworkCallback(callback, handler); 5705 mServiceContext.setPermission(CONNECTIVITY_USE_RESTRICTED_NETWORKS, PERMISSION_DENIED); 5706 callback.expectAvailableCallbacksUnvalidated(mCellAgent); 5707 mCm.unregisterNetworkCallback(callback); 5708 5709 mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_GRANTED); 5710 mCm.registerSystemDefaultNetworkCallback(callback, handler); 5711 callback.expectAvailableCallbacksUnvalidated(mCellAgent); 5712 mCm.unregisterNetworkCallback(callback); 5713 5714 mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_DENIED); 5715 mServiceContext.setPermission(NETWORK_SETUP_WIZARD, PERMISSION_GRANTED); 5716 mCm.registerSystemDefaultNetworkCallback(callback, handler); 5717 callback.expectAvailableCallbacksUnvalidated(mCellAgent); 5718 mCm.unregisterNetworkCallback(callback); 5719 5720 mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_GRANTED); 5721 mCm.registerDefaultNetworkCallbackForUid(APP1_UID, callback, handler); 5722 callback.expectAvailableCallbacksUnvalidated(mCellAgent); 5723 mCm.unregisterNetworkCallback(callback); 5724 } 5725 5726 @Test 5727 public void testNetworkCallbackWithNullUids() throws Exception { 5728 final NetworkRequest request = new NetworkRequest.Builder() 5729 .removeCapability(NET_CAPABILITY_NOT_VPN) 5730 .build(); 5731 final TestNetworkCallback callback = new TestNetworkCallback(); 5732 mCm.registerNetworkCallback(request, callback); 5733 5734 // Attempt to file a callback for networks applying to another UID. This does not actually 5735 // work, because this code does not currently have permission to do so. The callback behaves 5736 // exactly the same as the one registered just above. 5737 final int otherUid = UserHandle.getUid(RESTRICTED_USER, VPN_UID); 5738 final NetworkRequest otherUidRequest = new NetworkRequest.Builder() 5739 .removeCapability(NET_CAPABILITY_NOT_VPN) 5740 .setUids(UidRange.toIntRanges(uidRangesForUids(otherUid))) 5741 .build(); 5742 final TestNetworkCallback otherUidCallback = new TestNetworkCallback(); 5743 mCm.registerNetworkCallback(otherUidRequest, otherUidCallback); 5744 5745 final NetworkRequest includeOtherUidsRequest = new NetworkRequest.Builder() 5746 .removeCapability(NET_CAPABILITY_NOT_VPN) 5747 .setIncludeOtherUidNetworks(true) 5748 .build(); 5749 final TestNetworkCallback includeOtherUidsCallback = new TestNetworkCallback(); 5750 mCm.registerNetworkCallback(includeOtherUidsRequest, includeOtherUidsCallback); 5751 5752 // Both callbacks see a network with no specifier that applies to their UID. 5753 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 5754 mWiFiAgent.connect(false /* validated */); 5755 callback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 5756 otherUidCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 5757 includeOtherUidsCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 5758 mWiFiAgent.disconnect(); 5759 callback.expect(LOST, mWiFiAgent); 5760 otherUidCallback.expect(LOST, mWiFiAgent); 5761 includeOtherUidsCallback.expect(LOST, mWiFiAgent); 5762 5763 // Only the includeOtherUidsCallback sees a VPN that does not apply to its UID. 5764 final UidRange range = UidRange.createForUser(UserHandle.of(RESTRICTED_USER)); 5765 final Set<UidRange> vpnRanges = Collections.singleton(range); 5766 mMockVpn.establish(new LinkProperties(), VPN_UID, vpnRanges); 5767 includeOtherUidsCallback.expectAvailableThenValidatedCallbacks(mMockVpn); 5768 callback.assertNoCallback(); 5769 otherUidCallback.assertNoCallback(); 5770 5771 mMockVpn.disconnect(); 5772 includeOtherUidsCallback.expect(LOST, mMockVpn); 5773 callback.assertNoCallback(); 5774 otherUidCallback.assertNoCallback(); 5775 } 5776 5777 private static class RedactableNetworkSpecifier extends NetworkSpecifier { 5778 public static final int ID_INVALID = -1; 5779 5780 public final int networkId; 5781 5782 RedactableNetworkSpecifier(int networkId) { 5783 this.networkId = networkId; 5784 } 5785 5786 @Override 5787 public boolean canBeSatisfiedBy(NetworkSpecifier other) { 5788 return other instanceof RedactableNetworkSpecifier 5789 && this.networkId == ((RedactableNetworkSpecifier) other).networkId; 5790 } 5791 5792 @Override 5793 public NetworkSpecifier redact() { 5794 return new RedactableNetworkSpecifier(ID_INVALID); 5795 } 5796 } 5797 5798 @Test 5799 public void testNetworkCallbackWithNullUidsRedactsSpecifier() throws Exception { 5800 final RedactableNetworkSpecifier specifier = new RedactableNetworkSpecifier(42); 5801 final NetworkRequest request = new NetworkRequest.Builder() 5802 .addCapability(NET_CAPABILITY_INTERNET) 5803 .addTransportType(TRANSPORT_WIFI) 5804 .setNetworkSpecifier(specifier) 5805 .build(); 5806 final TestNetworkCallback callback = new TestNetworkCallback(); 5807 mCm.registerNetworkCallback(request, callback); 5808 5809 // Attempt to file a callback for networks applying to another UID. This does not actually 5810 // work, because this code does not currently have permission to do so. The callback behaves 5811 // exactly the same as the one registered just above. 5812 final int otherUid = UserHandle.getUid(RESTRICTED_USER, VPN_UID); 5813 final NetworkRequest otherUidRequest = new NetworkRequest.Builder() 5814 .addCapability(NET_CAPABILITY_INTERNET) 5815 .addTransportType(TRANSPORT_WIFI) 5816 .setNetworkSpecifier(specifier) 5817 .setUids(UidRange.toIntRanges(uidRangesForUids(otherUid))) 5818 .build(); 5819 final TestNetworkCallback otherUidCallback = new TestNetworkCallback(); 5820 mCm.registerNetworkCallback(otherUidRequest, otherUidCallback); 5821 5822 final NetworkRequest includeOtherUidsRequest = new NetworkRequest.Builder() 5823 .addCapability(NET_CAPABILITY_INTERNET) 5824 .addTransportType(TRANSPORT_WIFI) 5825 .setNetworkSpecifier(specifier) 5826 .setIncludeOtherUidNetworks(true) 5827 .build(); 5828 final TestNetworkCallback includeOtherUidsCallback = new TestNetworkCallback(); 5829 mCm.registerNetworkCallback(includeOtherUidsRequest, callback); 5830 5831 // Only the regular callback sees the network, because callbacks filed with no UID have 5832 // their specifiers redacted. 5833 final LinkProperties emptyLp = new LinkProperties(); 5834 final NetworkCapabilities ncTemplate = new NetworkCapabilities() 5835 .addTransportType(TRANSPORT_WIFI) 5836 .setNetworkSpecifier(specifier); 5837 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, emptyLp, ncTemplate); 5838 mWiFiAgent.connect(false /* validated */); 5839 callback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 5840 otherUidCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 5841 includeOtherUidsCallback.assertNoCallback(); 5842 } 5843 5844 private void setCaptivePortalMode(int mode) { 5845 ContentResolver cr = mServiceContext.getContentResolver(); 5846 Settings.Global.putInt(cr, ConnectivitySettingsManager.CAPTIVE_PORTAL_MODE, mode); 5847 } 5848 5849 private void setAlwaysOnNetworks(boolean enable) { 5850 ContentResolver cr = mServiceContext.getContentResolver(); 5851 Settings.Global.putInt(cr, ConnectivitySettingsManager.MOBILE_DATA_ALWAYS_ON, 5852 enable ? 1 : 0); 5853 mService.updateAlwaysOnNetworks(); 5854 waitForIdle(); 5855 } 5856 5857 private void setPrivateDnsSettings(int mode, String specifier) { 5858 ConnectivitySettingsManager.setPrivateDnsMode(mServiceContext, mode); 5859 ConnectivitySettingsManager.setPrivateDnsHostname(mServiceContext, specifier); 5860 mService.updatePrivateDnsSettings(); 5861 waitForIdle(); 5862 } 5863 5864 private void setIngressRateLimit(int rateLimitInBytesPerSec) { 5865 ConnectivitySettingsManager.setIngressRateLimitInBytesPerSecond(mServiceContext, 5866 rateLimitInBytesPerSec); 5867 mService.updateIngressRateLimit(); 5868 waitForIdle(); 5869 } 5870 5871 private boolean isForegroundNetwork(TestNetworkAgentWrapper network) { 5872 NetworkCapabilities nc = mCm.getNetworkCapabilities(network.getNetwork()); 5873 assertNotNull(nc); 5874 return nc.hasCapability(NET_CAPABILITY_FOREGROUND); 5875 } 5876 5877 @Test 5878 public void testBackgroundNetworks() throws Exception { 5879 // Create a cellular background request. 5880 grantUsingBackgroundNetworksPermissionForUid(Binder.getCallingUid()); 5881 final TestNetworkCallback cellBgCallback = new TestNetworkCallback(); 5882 mCm.requestBackgroundNetwork(new NetworkRequest.Builder() 5883 .addTransportType(TRANSPORT_CELLULAR).build(), 5884 cellBgCallback, mCsHandlerThread.getThreadHandler()); 5885 5886 // Make callbacks for monitoring. 5887 final NetworkRequest request = new NetworkRequest.Builder().build(); 5888 final NetworkRequest fgRequest = new NetworkRequest.Builder() 5889 .addCapability(NET_CAPABILITY_FOREGROUND).build(); 5890 final TestNetworkCallback callback = new TestNetworkCallback(); 5891 final TestNetworkCallback fgCallback = new TestNetworkCallback(); 5892 mCm.registerNetworkCallback(request, callback); 5893 mCm.registerNetworkCallback(fgRequest, fgCallback); 5894 5895 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 5896 mCellAgent.connect(true); 5897 callback.expectAvailableThenValidatedCallbacks(mCellAgent); 5898 fgCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 5899 assertTrue(isForegroundNetwork(mCellAgent)); 5900 5901 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 5902 mWiFiAgent.connect(true); 5903 5904 // When wifi connects, cell lingers. 5905 callback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 5906 callback.expectLosing(mCellAgent); 5907 callback.expectCaps(mWiFiAgent, c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 5908 fgCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 5909 fgCallback.expectLosing(mCellAgent); 5910 fgCallback.expectCaps(mWiFiAgent, c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 5911 assertTrue(isForegroundNetwork(mCellAgent)); 5912 assertTrue(isForegroundNetwork(mWiFiAgent)); 5913 5914 // When lingering is complete, cell is still there but is now in the background. 5915 waitForIdle(); 5916 int timeoutMs = TEST_LINGER_DELAY_MS + TEST_LINGER_DELAY_MS / 4; 5917 fgCallback.expect(LOST, mCellAgent, timeoutMs); 5918 // Expect a network capabilities update sans FOREGROUND. 5919 callback.expectCaps(mCellAgent, c -> !c.hasCapability(NET_CAPABILITY_FOREGROUND)); 5920 assertFalse(isForegroundNetwork(mCellAgent)); 5921 assertTrue(isForegroundNetwork(mWiFiAgent)); 5922 5923 // File a cell request and check that cell comes into the foreground. 5924 final NetworkRequest cellRequest = new NetworkRequest.Builder() 5925 .addTransportType(TRANSPORT_CELLULAR).build(); 5926 final TestNetworkCallback cellCallback = new TestNetworkCallback(); 5927 mCm.requestNetwork(cellRequest, cellCallback); 5928 cellCallback.expectAvailableCallbacksValidated(mCellAgent); 5929 fgCallback.expectAvailableCallbacksValidated(mCellAgent); 5930 // Expect a network capabilities update with FOREGROUND, because the most recent 5931 // request causes its state to change. 5932 cellCallback.expectCaps(mCellAgent, c -> c.hasCapability(NET_CAPABILITY_FOREGROUND)); 5933 callback.expectCaps(mCellAgent, c -> c.hasCapability(NET_CAPABILITY_FOREGROUND)); 5934 assertTrue(isForegroundNetwork(mCellAgent)); 5935 assertTrue(isForegroundNetwork(mWiFiAgent)); 5936 5937 // Release the request. The network immediately goes into the background, since it was not 5938 // lingering. 5939 mCm.unregisterNetworkCallback(cellCallback); 5940 fgCallback.expect(LOST, mCellAgent); 5941 // Expect a network capabilities update sans FOREGROUND. 5942 callback.expectCaps(mCellAgent, c -> !c.hasCapability(NET_CAPABILITY_FOREGROUND)); 5943 assertFalse(isForegroundNetwork(mCellAgent)); 5944 assertTrue(isForegroundNetwork(mWiFiAgent)); 5945 5946 // Disconnect wifi and check that cell is foreground again. 5947 mWiFiAgent.disconnect(); 5948 callback.expect(LOST, mWiFiAgent); 5949 fgCallback.expect(LOST, mWiFiAgent); 5950 fgCallback.expectAvailableCallbacksValidated(mCellAgent); 5951 assertTrue(isForegroundNetwork(mCellAgent)); 5952 5953 mCm.unregisterNetworkCallback(callback); 5954 mCm.unregisterNetworkCallback(fgCallback); 5955 mCm.unregisterNetworkCallback(cellBgCallback); 5956 } 5957 5958 @Ignore // This test has instrinsic chances of spurious failures: ignore for continuous testing. 5959 public void benchmarkRequestRegistrationAndCallbackDispatch() throws Exception { 5960 // TODO: turn this unit test into a real benchmarking test. 5961 // Benchmarks connecting and switching performance in the presence of a large number of 5962 // NetworkRequests. 5963 // 1. File NUM_REQUESTS requests. 5964 // 2. Have a network connect. Wait for NUM_REQUESTS onAvailable callbacks to fire. 5965 // 3. Have a new network connect and outscore the previous. Wait for NUM_REQUESTS onLosing 5966 // and NUM_REQUESTS onAvailable callbacks to fire. 5967 // See how long it took. 5968 final int NUM_REQUESTS = 90; 5969 final int REGISTER_TIME_LIMIT_MS = 200; 5970 final int CONNECT_TIME_LIMIT_MS = 60; 5971 final int SWITCH_TIME_LIMIT_MS = 60; 5972 final int UNREGISTER_TIME_LIMIT_MS = 20; 5973 5974 final NetworkRequest request = new NetworkRequest.Builder().clearCapabilities().build(); 5975 final NetworkCallback[] callbacks = new NetworkCallback[NUM_REQUESTS]; 5976 final CountDownLatch availableLatch = new CountDownLatch(NUM_REQUESTS); 5977 final CountDownLatch losingLatch = new CountDownLatch(NUM_REQUESTS); 5978 5979 for (int i = 0; i < NUM_REQUESTS; i++) { 5980 callbacks[i] = new NetworkCallback() { 5981 @Override public void onAvailable(Network n) { availableLatch.countDown(); } 5982 @Override public void onLosing(Network n, int t) { losingLatch.countDown(); } 5983 }; 5984 } 5985 5986 assertRunsInAtMost("Registering callbacks", REGISTER_TIME_LIMIT_MS, () -> { 5987 for (NetworkCallback cb : callbacks) { 5988 mCm.registerNetworkCallback(request, cb); 5989 } 5990 }); 5991 5992 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 5993 // Don't request that the network validate, because otherwise connect() will block until 5994 // the network gets NET_CAPABILITY_VALIDATED, after all the callbacks below have fired, 5995 // and we won't actually measure anything. 5996 mCellAgent.connect(false); 5997 5998 long onAvailableDispatchingDuration = durationOf(() -> { 5999 await(availableLatch, 10 * CONNECT_TIME_LIMIT_MS); 6000 }); 6001 Log.d(TAG, String.format("Dispatched %d of %d onAvailable callbacks in %dms", 6002 NUM_REQUESTS - availableLatch.getCount(), NUM_REQUESTS, 6003 onAvailableDispatchingDuration)); 6004 assertTrue(String.format("Dispatching %d onAvailable callbacks in %dms, expected %dms", 6005 NUM_REQUESTS, onAvailableDispatchingDuration, CONNECT_TIME_LIMIT_MS), 6006 onAvailableDispatchingDuration <= CONNECT_TIME_LIMIT_MS); 6007 6008 // Give wifi a high enough score that we'll linger cell when wifi comes up. 6009 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 6010 mWiFiAgent.adjustScore(40); 6011 mWiFiAgent.connect(false); 6012 6013 long onLostDispatchingDuration = durationOf(() -> { 6014 await(losingLatch, 10 * SWITCH_TIME_LIMIT_MS); 6015 }); 6016 Log.d(TAG, String.format("Dispatched %d of %d onLosing callbacks in %dms", 6017 NUM_REQUESTS - losingLatch.getCount(), NUM_REQUESTS, onLostDispatchingDuration)); 6018 assertTrue(String.format("Dispatching %d onLosing callbacks in %dms, expected %dms", 6019 NUM_REQUESTS, onLostDispatchingDuration, SWITCH_TIME_LIMIT_MS), 6020 onLostDispatchingDuration <= SWITCH_TIME_LIMIT_MS); 6021 6022 assertRunsInAtMost("Unregistering callbacks", UNREGISTER_TIME_LIMIT_MS, () -> { 6023 for (NetworkCallback cb : callbacks) { 6024 mCm.unregisterNetworkCallback(cb); 6025 } 6026 }); 6027 } 6028 6029 @Test 6030 public void testMobileDataAlwaysOn() throws Exception { 6031 grantUsingBackgroundNetworksPermissionForUid(Binder.getCallingUid()); 6032 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback(); 6033 final NetworkRequest cellRequest = new NetworkRequest.Builder() 6034 .addTransportType(TRANSPORT_CELLULAR).build(); 6035 mCm.registerNetworkCallback(cellRequest, cellNetworkCallback); 6036 6037 final HandlerThread handlerThread = new HandlerThread("MobileDataAlwaysOnFactory"); 6038 handlerThread.start(); 6039 NetworkCapabilities filter = new NetworkCapabilities() 6040 .addTransportType(TRANSPORT_CELLULAR) 6041 .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED) 6042 .addCapability(NET_CAPABILITY_INTERNET); 6043 final MockNetworkFactory testFactory = new MockNetworkFactory(handlerThread.getLooper(), 6044 mServiceContext, "testFactory", filter, mCsHandlerThread); 6045 testFactory.setScoreFilter(40); 6046 6047 // Register the factory and expect it to start looking for a network. 6048 testFactory.register(); 6049 6050 try { 6051 // Expect the factory to receive the default network request. 6052 testFactory.expectRequestAdd(); 6053 testFactory.assertRequestCountEquals(1); 6054 assertTrue(testFactory.getMyStartRequested()); 6055 6056 // Bring up wifi. The factory stops looking for a network. 6057 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 6058 // Score 60 - 40 penalty for not validated yet, then 60 when it validates 6059 mWiFiAgent.connect(true); 6060 // The network connects with a low score, so the offer can still beat it and 6061 // nothing happens. Then the network validates, and the offer with its filter score 6062 // of 40 can no longer beat it and the request is removed. 6063 testFactory.expectRequestRemove(); 6064 testFactory.assertRequestCountEquals(0); 6065 6066 assertFalse(testFactory.getMyStartRequested()); 6067 6068 // Turn on mobile data always on. This request will not match the wifi request, so 6069 // it will be sent to the test factory whose filters allow to see it. 6070 setAlwaysOnNetworks(true); 6071 testFactory.expectRequestAdd(); 6072 testFactory.assertRequestCountEquals(1); 6073 6074 assertTrue(testFactory.getMyStartRequested()); 6075 6076 // Bring up cell data and check that the factory stops looking. 6077 assertLength(1, mCm.getAllNetworks()); 6078 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 6079 mCellAgent.connect(false); 6080 cellNetworkCallback.expectAvailableCallbacks(mCellAgent, false, false, false, 6081 TEST_CALLBACK_TIMEOUT_MS); 6082 // When cell connects, it will satisfy the "mobile always on request" right away 6083 // by virtue of being the only network that can satisfy the request. However, its 6084 // score is low (50 - 40 = 10) so the test factory can still hope to beat it. 6085 expectNoRequestChanged(testFactory); 6086 6087 // Next, cell validates. This gives it a score of 50 and the test factory can't 6088 // hope to beat that according to its filters. It will see the message that its 6089 // offer is now unnecessary. 6090 mCellAgent.setNetworkValid(true); 6091 // Need a trigger point to let NetworkMonitor tell ConnectivityService that network is 6092 // validated – see testPartialConnectivity. 6093 mCm.reportNetworkConnectivity(mCellAgent.getNetwork(), true); 6094 cellNetworkCallback.expectCaps(mCellAgent, 6095 c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 6096 testFactory.expectRequestRemove(); 6097 testFactory.assertRequestCountEquals(0); 6098 // Accordingly, the factory shouldn't be started. 6099 assertFalse(testFactory.getMyStartRequested()); 6100 6101 // Check that cell data stays up. 6102 waitForIdle(); 6103 verifyActiveNetwork(TRANSPORT_WIFI); 6104 assertLength(2, mCm.getAllNetworks()); 6105 6106 // Cell disconnects. There is still the "mobile data always on" request outstanding, 6107 // and the test factory should see it now that it isn't hopelessly outscored. 6108 mCellAgent.disconnect(); 6109 cellNetworkCallback.expect(LOST, mCellAgent); 6110 // Wait for the network to be removed from internal structures before 6111 // calling synchronous getter 6112 waitForIdle(); 6113 assertLength(1, mCm.getAllNetworks()); 6114 testFactory.expectRequestAdd(); 6115 testFactory.assertRequestCountEquals(1); 6116 6117 // Reconnect cell validated, see the request disappear again. Then withdraw the 6118 // mobile always on request. This will tear down cell, and there shouldn't be a 6119 // blip where the test factory briefly sees the request or anything. 6120 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 6121 mCellAgent.connect(true); 6122 cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 6123 waitForIdle(); 6124 assertLength(2, mCm.getAllNetworks()); 6125 testFactory.expectRequestRemove(); 6126 testFactory.assertRequestCountEquals(0); 6127 setAlwaysOnNetworks(false); 6128 expectNoRequestChanged(testFactory); 6129 testFactory.assertRequestCountEquals(0); 6130 assertFalse(testFactory.getMyStartRequested()); 6131 // ... and cell data to be torn down immediately since it is no longer nascent. 6132 cellNetworkCallback.expect(LOST, mCellAgent); 6133 waitForIdle(); 6134 assertLength(1, mCm.getAllNetworks()); 6135 testFactory.terminate(); 6136 testFactory.assertNoRequestChanged(); 6137 } finally { 6138 mCm.unregisterNetworkCallback(cellNetworkCallback); 6139 handlerThread.quitSafely(); 6140 handlerThread.join(); 6141 } 6142 } 6143 6144 @Test 6145 public void testSetAllowBadWifiUntil() throws Exception { 6146 runAsShell(NETWORK_SETTINGS, 6147 () -> mService.setTestAllowBadWifiUntil(System.currentTimeMillis() + 5_000L)); 6148 waitForIdle(); 6149 testAvoidBadWifiConfig_controlledBySettings(); 6150 6151 runAsShell(NETWORK_SETTINGS, 6152 () -> mService.setTestAllowBadWifiUntil(System.currentTimeMillis() - 5_000L)); 6153 waitForIdle(); 6154 testAvoidBadWifiConfig_ignoreSettings(); 6155 } 6156 6157 private void testAvoidBadWifiConfig_controlledBySettings() { 6158 final ContentResolver cr = mServiceContext.getContentResolver(); 6159 final String settingName = ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI; 6160 6161 Settings.Global.putString(cr, settingName, "0"); 6162 mPolicyTracker.reevaluate(); 6163 waitForIdle(); 6164 assertFalse(mService.avoidBadWifi()); 6165 assertFalse(mPolicyTracker.shouldNotifyWifiUnvalidated()); 6166 6167 Settings.Global.putString(cr, settingName, "1"); 6168 mPolicyTracker.reevaluate(); 6169 waitForIdle(); 6170 assertTrue(mService.avoidBadWifi()); 6171 assertFalse(mPolicyTracker.shouldNotifyWifiUnvalidated()); 6172 6173 Settings.Global.putString(cr, settingName, null); 6174 mPolicyTracker.reevaluate(); 6175 waitForIdle(); 6176 assertFalse(mService.avoidBadWifi()); 6177 assertTrue(mPolicyTracker.shouldNotifyWifiUnvalidated()); 6178 } 6179 6180 private void testAvoidBadWifiConfig_ignoreSettings() { 6181 final ContentResolver cr = mServiceContext.getContentResolver(); 6182 final String settingName = ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI; 6183 6184 String[] values = new String[] {null, "0", "1"}; 6185 for (int i = 0; i < values.length; i++) { 6186 Settings.Global.putString(cr, settingName, values[i]); 6187 mPolicyTracker.reevaluate(); 6188 waitForIdle(); 6189 String msg = String.format("config=false, setting=%s", values[i]); 6190 assertTrue(mService.avoidBadWifi()); 6191 assertFalse(msg, mPolicyTracker.shouldNotifyWifiUnvalidated()); 6192 } 6193 } 6194 6195 @Test 6196 public void testAvoidBadWifiSetting() throws Exception { 6197 doReturn(1).when(mResources).getInteger(R.integer.config_networkAvoidBadWifi); 6198 testAvoidBadWifiConfig_ignoreSettings(); 6199 6200 doReturn(0).when(mResources).getInteger(R.integer.config_networkAvoidBadWifi); 6201 testAvoidBadWifiConfig_controlledBySettings(); 6202 } 6203 6204 @Test 6205 public void testActivelyPreferBadWifiSetting() throws Exception { 6206 doReturn(1).when(mResources).getInteger(R.integer.config_activelyPreferBadWifi); 6207 mPolicyTracker.reevaluate(); 6208 waitForIdle(); 6209 assertTrue(mService.mNetworkRanker.getConfiguration().activelyPreferBadWifi()); 6210 6211 doReturn(0).when(mResources).getInteger(R.integer.config_activelyPreferBadWifi); 6212 mPolicyTracker.reevaluate(); 6213 waitForIdle(); 6214 if (mDeps.isAtLeastU()) { 6215 // U+ ignore the setting and always actively prefers bad wifi 6216 assertTrue(mService.mNetworkRanker.getConfiguration().activelyPreferBadWifi()); 6217 } else { 6218 assertFalse(mService.mNetworkRanker.getConfiguration().activelyPreferBadWifi()); 6219 } 6220 } 6221 6222 @Test 6223 public void testOffersAvoidsBadWifi() throws Exception { 6224 // Normal mode : the carrier doesn't restrict moving away from bad wifi. 6225 // This has getAvoidBadWifi return true. 6226 doReturn(1).when(mResources).getInteger(R.integer.config_networkAvoidBadWifi); 6227 // Don't request cell separately for the purposes of this test. 6228 setAlwaysOnNetworks(false); 6229 6230 final NetworkProvider cellProvider = new NetworkProvider(mServiceContext, 6231 mCsHandlerThread.getLooper(), "Cell provider"); 6232 final NetworkProvider wifiProvider = new NetworkProvider(mServiceContext, 6233 mCsHandlerThread.getLooper(), "Wifi provider"); 6234 6235 mCm.registerNetworkProvider(cellProvider); 6236 mCm.registerNetworkProvider(wifiProvider); 6237 6238 final NetworkScore cellScore = new NetworkScore.Builder().build(); 6239 final NetworkScore wifiScore = new NetworkScore.Builder().build(); 6240 final NetworkCapabilities defaultCaps = new NetworkCapabilities.Builder() 6241 .addCapability(NET_CAPABILITY_INTERNET) 6242 .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED) 6243 .build(); 6244 final NetworkCapabilities cellCaps = new NetworkCapabilities.Builder() 6245 .addTransportType(TRANSPORT_CELLULAR) 6246 .addCapability(NET_CAPABILITY_INTERNET) 6247 .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED) 6248 .build(); 6249 final NetworkCapabilities wifiCaps = new NetworkCapabilities.Builder() 6250 .addTransportType(TRANSPORT_WIFI) 6251 .addCapability(NET_CAPABILITY_INTERNET) 6252 .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED) 6253 .build(); 6254 final TestableNetworkOfferCallback cellCallback = new TestableNetworkOfferCallback( 6255 TIMEOUT_MS /* timeout */, TEST_CALLBACK_TIMEOUT_MS /* noCallbackTimeout */); 6256 final TestableNetworkOfferCallback wifiCallback = new TestableNetworkOfferCallback( 6257 TIMEOUT_MS /* timeout */, TEST_CALLBACK_TIMEOUT_MS /* noCallbackTimeout */); 6258 6259 // Offer callbacks will run on the CS handler thread in this test. 6260 cellProvider.registerNetworkOffer(cellScore, cellCaps, r -> r.run(), cellCallback); 6261 wifiProvider.registerNetworkOffer(wifiScore, wifiCaps, r -> r.run(), wifiCallback); 6262 6263 // Both providers see the default request. 6264 cellCallback.expectOnNetworkNeeded(defaultCaps); 6265 wifiCallback.expectOnNetworkNeeded(defaultCaps); 6266 6267 // Listen to cell and wifi to know when agents are finished processing 6268 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback(); 6269 final NetworkRequest cellRequest = new NetworkRequest.Builder() 6270 .addTransportType(TRANSPORT_CELLULAR).build(); 6271 mCm.registerNetworkCallback(cellRequest, cellNetworkCallback); 6272 final TestNetworkCallback wifiNetworkCallback = new TestNetworkCallback(); 6273 final NetworkRequest wifiRequest = new NetworkRequest.Builder() 6274 .addTransportType(TRANSPORT_WIFI).build(); 6275 mCm.registerNetworkCallback(wifiRequest, wifiNetworkCallback); 6276 6277 // Cell connects and validates. 6278 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, 6279 new LinkProperties(), null /* ncTemplate */, cellProvider); 6280 mCellAgent.connect(true); 6281 cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 6282 cellCallback.assertNoCallback(); 6283 wifiCallback.assertNoCallback(); 6284 6285 // Bring up wifi. At first it's invalidated, so cell is still needed. 6286 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, 6287 new LinkProperties(), null /* ncTemplate */, wifiProvider); 6288 mWiFiAgent.connect(false); 6289 wifiNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 6290 cellCallback.assertNoCallback(); 6291 wifiCallback.assertNoCallback(); 6292 6293 // Wifi validates. Cell is no longer needed, because it's outscored. 6294 mWiFiAgent.setNetworkValid(true /* privateDnsProbeSent */); 6295 // Have CS reconsider the network (see testPartialConnectivity) 6296 mCm.reportNetworkConnectivity(mWiFiAgent.getNetwork(), true); 6297 wifiNetworkCallback.expectCaps(mWiFiAgent, c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 6298 cellCallback.expectOnNetworkUnneeded(defaultCaps); 6299 wifiCallback.assertNoCallback(); 6300 6301 // Wifi is no longer validated. Cell is needed again. 6302 mWiFiAgent.setNetworkInvalid(true /* invalidBecauseOfPrivateDns */); 6303 mCm.reportNetworkConnectivity(mWiFiAgent.getNetwork(), false); 6304 wifiNetworkCallback.expectCaps(mWiFiAgent, 6305 c -> !c.hasCapability(NET_CAPABILITY_VALIDATED)); 6306 cellCallback.expectOnNetworkNeeded(defaultCaps); 6307 wifiCallback.assertNoCallback(); 6308 6309 // Disconnect wifi and pretend the carrier restricts moving away from bad wifi. 6310 mWiFiAgent.disconnect(); 6311 wifiNetworkCallback.expect(LOST, mWiFiAgent); 6312 // This has getAvoidBadWifi return false. This test doesn't change the value of the 6313 // associated setting. 6314 doReturn(0).when(mResources).getInteger(R.integer.config_networkAvoidBadWifi); 6315 mPolicyTracker.reevaluate(); 6316 waitForIdle(); 6317 6318 // Connect wifi again, cell is needed until wifi validates. 6319 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, 6320 new LinkProperties(), null /* ncTemplate */, wifiProvider); 6321 mWiFiAgent.connect(false); 6322 wifiNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 6323 cellCallback.assertNoCallback(); 6324 wifiCallback.assertNoCallback(); 6325 mWiFiAgent.setNetworkValid(true /* privateDnsProbeSent */); 6326 mCm.reportNetworkConnectivity(mWiFiAgent.getNetwork(), true); 6327 wifiNetworkCallback.expectCaps(mWiFiAgent, 6328 c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 6329 cellCallback.expectOnNetworkUnneeded(defaultCaps); 6330 wifiCallback.assertNoCallback(); 6331 6332 // Wifi loses validation. Because the device doesn't avoid bad wifis, cell is 6333 // not needed. 6334 mWiFiAgent.setNetworkInvalid(true /* invalidBecauseOfPrivateDns */); 6335 mCm.reportNetworkConnectivity(mWiFiAgent.getNetwork(), false); 6336 wifiNetworkCallback.expectCaps(mWiFiAgent, 6337 c -> !c.hasCapability(NET_CAPABILITY_VALIDATED)); 6338 cellCallback.assertNoCallback(); 6339 wifiCallback.assertNoCallback(); 6340 } 6341 6342 public void doTestPreferBadWifi(final boolean avoidBadWifi, 6343 final boolean preferBadWifi, final boolean explicitlySelected, 6344 @NonNull Predicate<Long> checkUnvalidationTimeout) throws Exception { 6345 // Pretend we're on a carrier that restricts switching away from bad wifi, and 6346 // depending on the parameter one that may indeed prefer bad wifi. 6347 doReturn(avoidBadWifi ? 1 : 0).when(mResources) 6348 .getInteger(R.integer.config_networkAvoidBadWifi); 6349 doReturn(preferBadWifi ? 1 : 0).when(mResources) 6350 .getInteger(R.integer.config_activelyPreferBadWifi); 6351 mPolicyTracker.reevaluate(); 6352 6353 registerDefaultNetworkCallbacks(); 6354 final NetworkRequest wifiRequest = new NetworkRequest.Builder() 6355 .clearCapabilities() 6356 .addTransportType(TRANSPORT_WIFI) 6357 .build(); 6358 final TestNetworkCallback wifiCallback = new TestNetworkCallback(); 6359 mCm.registerNetworkCallback(wifiRequest, wifiCallback); 6360 6361 // Bring up validated cell and unvalidated wifi. 6362 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 6363 mCellAgent.connect(true); 6364 mDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 6365 6366 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 6367 mWiFiAgent.explicitlySelected(explicitlySelected, false /* acceptUnvalidated */); 6368 mWiFiAgent.connect(false); 6369 wifiCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 6370 6371 assertNotNull(mDeps.mScheduledEvaluationTimeouts.poll(TIMEOUT_MS, 6372 t -> t.first == mWiFiAgent.getNetwork().netId 6373 && checkUnvalidationTimeout.test(t.second))); 6374 6375 if (!avoidBadWifi && preferBadWifi) { 6376 expectUnvalidationCheckWillNotify(mWiFiAgent, NotificationType.LOST_INTERNET); 6377 mDefaultNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 6378 } else { 6379 expectUnvalidationCheckWillNotNotify(mWiFiAgent); 6380 mDefaultNetworkCallback.assertNoCallback(); 6381 } 6382 } 6383 6384 @Test 6385 public void testPreferBadWifi_doNotAvoid_doNotPrefer() throws Exception { 6386 // Starting with U this mode is no longer supported and can't actually be tested 6387 assumeFalse(mDeps.isAtLeastU()); 6388 doTestPreferBadWifi(false /* avoidBadWifi */, false /* preferBadWifi */, 6389 false /* explicitlySelected */, timeout -> timeout < 14_000); 6390 } 6391 6392 @Test 6393 public void testPreferBadWifi_doNotAvoid_doPrefer_notExplicit() throws Exception { 6394 doTestPreferBadWifi(false /* avoidBadWifi */, true /* preferBadWifi */, 6395 false /* explicitlySelected */, timeout -> timeout > 14_000); 6396 } 6397 6398 @Test 6399 public void testPreferBadWifi_doNotAvoid_doPrefer_explicitlySelected() throws Exception { 6400 doTestPreferBadWifi(false /* avoidBadWifi */, true /* preferBadWifi */, 6401 true /* explicitlySelected */, timeout -> timeout < 14_000); 6402 } 6403 6404 @Test 6405 public void testPreferBadWifi_doAvoid_doNotPrefer() throws Exception { 6406 // If avoidBadWifi=true, then preferBadWifi should be irrelevant. Test anyway. 6407 doTestPreferBadWifi(true /* avoidBadWifi */, false /* preferBadWifi */, 6408 false /* explicitlySelected */, timeout -> timeout < 14_000); 6409 } 6410 6411 @Test 6412 public void testPreferBadWifi_doAvoid_doPrefer() throws Exception { 6413 // If avoidBadWifi=true, then preferBadWifi should be irrelevant. Test anyway. 6414 doTestPreferBadWifi(true /* avoidBadWifi */, true /* preferBadWifi */, 6415 false /* explicitlySelected */, timeout -> timeout < 14_000); 6416 } 6417 6418 @Test 6419 public void testAvoidBadWifi() throws Exception { 6420 final ContentResolver cr = mServiceContext.getContentResolver(); 6421 6422 // Pretend we're on a carrier that restricts switching away from bad wifi. 6423 doReturn(0).when(mResources).getInteger(R.integer.config_networkAvoidBadWifi); 6424 6425 // File a request for cell to ensure it doesn't go down. 6426 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback(); 6427 final NetworkRequest cellRequest = new NetworkRequest.Builder() 6428 .addTransportType(TRANSPORT_CELLULAR).build(); 6429 mCm.requestNetwork(cellRequest, cellNetworkCallback); 6430 6431 TestNetworkCallback defaultCallback = new TestNetworkCallback(); 6432 mCm.registerDefaultNetworkCallback(defaultCallback); 6433 6434 NetworkRequest validatedWifiRequest = new NetworkRequest.Builder() 6435 .addTransportType(TRANSPORT_WIFI) 6436 .addCapability(NET_CAPABILITY_VALIDATED) 6437 .build(); 6438 TestNetworkCallback validatedWifiCallback = new TestNetworkCallback(); 6439 mCm.registerNetworkCallback(validatedWifiRequest, validatedWifiCallback); 6440 6441 // Prompt mode, so notifications can be tested 6442 Settings.Global.putString(cr, ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI, null); 6443 mPolicyTracker.reevaluate(); 6444 6445 // Bring up validated cell. 6446 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 6447 mCellAgent.connect(true); 6448 cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 6449 defaultCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 6450 Network cellNetwork = mCellAgent.getNetwork(); 6451 6452 // Bring up validated wifi. 6453 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 6454 mWiFiAgent.connect(true); 6455 defaultCallback.expectAvailableDoubleValidatedCallbacks(mWiFiAgent); 6456 validatedWifiCallback.expectAvailableDoubleValidatedCallbacks(mWiFiAgent); 6457 Network wifiNetwork = mWiFiAgent.getNetwork(); 6458 6459 // Fail validation on wifi. 6460 mWiFiAgent.setNetworkInvalid(false /* invalidBecauseOfPrivateDns */); 6461 mCm.reportNetworkConnectivity(wifiNetwork, false); 6462 defaultCallback.expectCaps(mWiFiAgent, c -> !c.hasCapability(NET_CAPABILITY_VALIDATED)); 6463 validatedWifiCallback.expect(LOST, mWiFiAgent); 6464 expectNotification(mWiFiAgent, NotificationType.LOST_INTERNET); 6465 6466 // Because avoid bad wifi is off, we don't switch to cellular. 6467 defaultCallback.assertNoCallback(); 6468 assertFalse(mCm.getNetworkCapabilities(wifiNetwork).hasCapability( 6469 NET_CAPABILITY_VALIDATED)); 6470 assertTrue(mCm.getNetworkCapabilities(cellNetwork).hasCapability( 6471 NET_CAPABILITY_VALIDATED)); 6472 assertEquals(mCm.getActiveNetwork(), wifiNetwork); 6473 6474 // Simulate switching to a carrier that does not restrict avoiding bad wifi, and expect 6475 // that we switch back to cell. 6476 doReturn(1).when(mResources).getInteger(R.integer.config_networkAvoidBadWifi); 6477 mPolicyTracker.reevaluate(); 6478 defaultCallback.expectAvailableCallbacksValidated(mCellAgent); 6479 assertEquals(mCm.getActiveNetwork(), cellNetwork); 6480 expectClearNotification(mWiFiAgent, NotificationType.LOST_INTERNET); 6481 6482 // Switch back to a restrictive carrier. 6483 doReturn(0).when(mResources).getInteger(R.integer.config_networkAvoidBadWifi); 6484 mPolicyTracker.reevaluate(); 6485 defaultCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 6486 assertEquals(mCm.getActiveNetwork(), wifiNetwork); 6487 // A notification was already shown for this very network. 6488 expectNoNotification(mWiFiAgent); 6489 6490 // Simulate the user selecting "switch" on the dialog, and check that we switch to cell. 6491 // In principle this is a little bit unrealistic because the switch to a less restrictive 6492 // carrier above should have remove the notification but this doesn't matter for the 6493 // purposes of this test. 6494 mCm.setAvoidUnvalidated(wifiNetwork); 6495 defaultCallback.expectAvailableCallbacksValidated(mCellAgent); 6496 assertFalse(mCm.getNetworkCapabilities(wifiNetwork).hasCapability( 6497 NET_CAPABILITY_VALIDATED)); 6498 assertTrue(mCm.getNetworkCapabilities(cellNetwork).hasCapability( 6499 NET_CAPABILITY_VALIDATED)); 6500 assertEquals(mCm.getActiveNetwork(), cellNetwork); 6501 6502 // Disconnect and reconnect wifi to clear the one-time switch above. 6503 mWiFiAgent.disconnect(); 6504 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 6505 mWiFiAgent.connect(true); 6506 defaultCallback.expectAvailableDoubleValidatedCallbacks(mWiFiAgent); 6507 validatedWifiCallback.expectAvailableDoubleValidatedCallbacks(mWiFiAgent); 6508 wifiNetwork = mWiFiAgent.getNetwork(); 6509 6510 // Fail validation on wifi and expect the dialog to appear. 6511 mWiFiAgent.setNetworkInvalid(false /* invalidBecauseOfPrivateDns */); 6512 mCm.reportNetworkConnectivity(wifiNetwork, false); 6513 defaultCallback.expectCaps(mWiFiAgent, c -> !c.hasCapability(NET_CAPABILITY_VALIDATED)); 6514 validatedWifiCallback.expect(LOST, mWiFiAgent); 6515 expectNotification(mWiFiAgent, NotificationType.LOST_INTERNET); 6516 6517 // Simulate the user selecting "switch" and checking the don't ask again checkbox. 6518 Settings.Global.putInt(cr, ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI, 1); 6519 mPolicyTracker.reevaluate(); 6520 6521 // We now switch to cell. 6522 defaultCallback.expectAvailableCallbacksValidated(mCellAgent); 6523 assertFalse(mCm.getNetworkCapabilities(wifiNetwork).hasCapability( 6524 NET_CAPABILITY_VALIDATED)); 6525 assertTrue(mCm.getNetworkCapabilities(cellNetwork).hasCapability( 6526 NET_CAPABILITY_VALIDATED)); 6527 assertEquals(mCm.getActiveNetwork(), cellNetwork); 6528 expectClearNotification(mWiFiAgent, NotificationType.LOST_INTERNET); 6529 6530 // Simulate the user turning the cellular fallback setting off and then on. 6531 // We switch to wifi and then to cell. 6532 Settings.Global.putString(cr, ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI, null); 6533 mPolicyTracker.reevaluate(); 6534 defaultCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 6535 assertEquals(mCm.getActiveNetwork(), wifiNetwork); 6536 // Notification is cleared again because CS doesn't particularly remember that it has 6537 // cleared it before, and if it hasn't cleared it before then it should do so now. 6538 expectClearNotification(mWiFiAgent, NotificationType.LOST_INTERNET); 6539 Settings.Global.putInt(cr, ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI, 1); 6540 mPolicyTracker.reevaluate(); 6541 defaultCallback.expectAvailableCallbacksValidated(mCellAgent); 6542 assertEquals(mCm.getActiveNetwork(), cellNetwork); 6543 6544 // If cell goes down, we switch to wifi. 6545 mCellAgent.disconnect(); 6546 defaultCallback.expect(LOST, mCellAgent); 6547 defaultCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 6548 validatedWifiCallback.assertNoCallback(); 6549 // Notification is cleared yet again because the device switched to wifi. 6550 expectClearNotification(mWiFiAgent, NotificationType.LOST_INTERNET); 6551 6552 mCm.unregisterNetworkCallback(cellNetworkCallback); 6553 mCm.unregisterNetworkCallback(validatedWifiCallback); 6554 mCm.unregisterNetworkCallback(defaultCallback); 6555 } 6556 6557 @Test 6558 public void testMeteredMultipathPreferenceSetting() throws Exception { 6559 final ContentResolver cr = mServiceContext.getContentResolver(); 6560 final String settingName = ConnectivitySettingsManager.NETWORK_METERED_MULTIPATH_PREFERENCE; 6561 6562 for (int config : asList(0, 3, 2)) { 6563 for (String setting: asList(null, "0", "2", "1")) { 6564 mPolicyTracker.mConfigMeteredMultipathPreference = config; 6565 Settings.Global.putString(cr, settingName, setting); 6566 mPolicyTracker.reevaluate(); 6567 waitForIdle(); 6568 6569 final int expected = (setting != null) ? Integer.parseInt(setting) : config; 6570 String msg = String.format("config=%d, setting=%s", config, setting); 6571 assertEquals(msg, expected, mCm.getMultipathPreference(null)); 6572 } 6573 } 6574 } 6575 6576 /** 6577 * Validate that a satisfied network request does not trigger onUnavailable() once the 6578 * time-out period expires. 6579 */ 6580 @Test 6581 public void testSatisfiedNetworkRequestDoesNotTriggerOnUnavailable() throws Exception { 6582 NetworkRequest nr = new NetworkRequest.Builder().addTransportType( 6583 NetworkCapabilities.TRANSPORT_WIFI).build(); 6584 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 6585 mCm.requestNetwork(nr, networkCallback, TEST_REQUEST_TIMEOUT_MS); 6586 6587 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 6588 mWiFiAgent.connect(false); 6589 networkCallback.expectAvailableCallbacks(mWiFiAgent, false, false, false, 6590 TEST_CALLBACK_TIMEOUT_MS); 6591 6592 // pass timeout and validate that UNAVAILABLE is not called 6593 networkCallback.assertNoCallback(); 6594 } 6595 6596 /** 6597 * Validate that a satisfied network request followed by a disconnected (lost) network does 6598 * not trigger onUnavailable() once the time-out period expires. 6599 */ 6600 @Test 6601 public void testSatisfiedThenLostNetworkRequestDoesNotTriggerOnUnavailable() throws Exception { 6602 NetworkRequest nr = new NetworkRequest.Builder().addTransportType( 6603 NetworkCapabilities.TRANSPORT_WIFI).build(); 6604 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 6605 mCm.requestNetwork(nr, networkCallback, TEST_REQUEST_TIMEOUT_MS); 6606 6607 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 6608 mWiFiAgent.connect(false); 6609 networkCallback.expectAvailableCallbacks(mWiFiAgent, false, false, false, 6610 TEST_CALLBACK_TIMEOUT_MS); 6611 mWiFiAgent.disconnect(); 6612 networkCallback.expect(LOST, mWiFiAgent); 6613 6614 // Validate that UNAVAILABLE is not called 6615 networkCallback.assertNoCallback(); 6616 } 6617 6618 /** 6619 * Validate that when a time-out is specified for a network request the onUnavailable() 6620 * callback is called when time-out expires. Then validate that if network request is 6621 * (somehow) satisfied - the callback isn't called later. 6622 */ 6623 @Test 6624 public void testTimedoutNetworkRequest() throws Exception { 6625 NetworkRequest nr = new NetworkRequest.Builder().addTransportType( 6626 NetworkCapabilities.TRANSPORT_WIFI).build(); 6627 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 6628 final int timeoutMs = 10; 6629 mCm.requestNetwork(nr, networkCallback, timeoutMs); 6630 6631 // pass timeout and validate that UNAVAILABLE is called 6632 networkCallback.expect(UNAVAILABLE); 6633 6634 // create a network satisfying request - validate that request not triggered 6635 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 6636 mWiFiAgent.connect(false); 6637 networkCallback.assertNoCallback(); 6638 } 6639 6640 /** 6641 * Validate that when a network request is unregistered (cancelled), no posterior event can 6642 * trigger the callback. 6643 */ 6644 @Test 6645 public void testNoCallbackAfterUnregisteredNetworkRequest() throws Exception { 6646 NetworkRequest nr = new NetworkRequest.Builder().addTransportType( 6647 NetworkCapabilities.TRANSPORT_WIFI).build(); 6648 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 6649 final int timeoutMs = 10; 6650 6651 mCm.requestNetwork(nr, networkCallback, timeoutMs); 6652 mCm.unregisterNetworkCallback(networkCallback); 6653 // Regardless of the timeout, unregistering the callback in ConnectivityManager ensures 6654 // that this callback will not be called. 6655 networkCallback.assertNoCallback(); 6656 6657 // create a network satisfying request - validate that request not triggered 6658 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 6659 mWiFiAgent.connect(false); 6660 networkCallback.assertNoCallback(); 6661 } 6662 6663 @Test 6664 public void testUnfulfillableNetworkRequest() throws Exception { 6665 runUnfulfillableNetworkRequest(false); 6666 } 6667 6668 @Test 6669 public void testUnfulfillableNetworkRequestAfterUnregister() throws Exception { 6670 runUnfulfillableNetworkRequest(true); 6671 } 6672 6673 /** 6674 * Validate the callback flow for a factory releasing a request as unfulfillable. 6675 */ 6676 private void runUnfulfillableNetworkRequest(boolean preUnregister) throws Exception { 6677 NetworkRequest nr = new NetworkRequest.Builder().addTransportType( 6678 NetworkCapabilities.TRANSPORT_WIFI).build(); 6679 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 6680 6681 final HandlerThread handlerThread = new HandlerThread("testUnfulfillableNetworkRequest"); 6682 handlerThread.start(); 6683 NetworkCapabilities filter = new NetworkCapabilities() 6684 .addTransportType(TRANSPORT_WIFI) 6685 .addCapability(NET_CAPABILITY_INTERNET) 6686 .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED); 6687 final MockNetworkFactory testFactory = new MockNetworkFactory(handlerThread.getLooper(), 6688 mServiceContext, "testFactory", filter, mCsHandlerThread); 6689 testFactory.setScoreFilter(40); 6690 6691 // Register the factory and expect it to receive the default request. 6692 testFactory.register(); 6693 testFactory.expectRequestAdd(); 6694 6695 try { 6696 // Now file the test request and expect it. 6697 mCm.requestNetwork(nr, networkCallback); 6698 final NetworkRequest newRequest = testFactory.expectRequestAdd().request; 6699 6700 if (preUnregister) { 6701 mCm.unregisterNetworkCallback(networkCallback); 6702 6703 // The request has been released : the factory should see it removed 6704 // immediately. 6705 testFactory.expectRequestRemove(); 6706 6707 // Simulate the factory releasing the request as unfulfillable: no-op since 6708 // the callback has already been unregistered (but a test that no exceptions are 6709 // thrown). 6710 testFactory.triggerUnfulfillable(newRequest); 6711 } else { 6712 // Simulate the factory releasing the request as unfulfillable and expect 6713 // onUnavailable! 6714 testFactory.triggerUnfulfillable(newRequest); 6715 6716 networkCallback.expect(UNAVAILABLE); 6717 6718 // Declaring a request unfulfillable releases it automatically. 6719 testFactory.expectRequestRemove(); 6720 6721 // unregister network callback - a no-op (since already freed by the 6722 // on-unavailable), but should not fail or throw exceptions. 6723 mCm.unregisterNetworkCallback(networkCallback); 6724 6725 // The factory should not see any further removal, as this request has 6726 // already been removed. 6727 } 6728 } finally { 6729 testFactory.terminate(); 6730 handlerThread.quitSafely(); 6731 handlerThread.join(); 6732 } 6733 } 6734 6735 @Test 6736 @IgnoreUpTo(Build.VERSION_CODES.TIRAMISU) 6737 @DisableCompatChanges(ConnectivityCompatChanges.ENABLE_SELF_CERTIFIED_CAPABILITIES_DECLARATION) 6738 public void testSelfCertifiedCapabilitiesDisabled() 6739 throws Exception { 6740 mDeps.enableCompatChangeCheck(); 6741 final NetworkRequest networkRequest = new NetworkRequest.Builder() 6742 .addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_LATENCY) 6743 .addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_BANDWIDTH) 6744 .build(); 6745 final TestNetworkCallback cb = new TestNetworkCallback(); 6746 mCm.requestNetwork(networkRequest, cb); 6747 mCm.unregisterNetworkCallback(cb); 6748 } 6749 6750 /** Set the networkSliceResourceId to 0 will result in NameNotFoundException be thrown. */ 6751 private void setupMockForNetworkCapabilitiesResources(int networkSliceResourceId) 6752 throws PackageManager.NameNotFoundException { 6753 if (networkSliceResourceId == 0) { 6754 doThrow(new PackageManager.NameNotFoundException()).when(mPackageManager).getProperty( 6755 ConstantsShim.PROPERTY_SELF_CERTIFIED_NETWORK_CAPABILITIES, 6756 mContext.getPackageName()); 6757 } else { 6758 final PackageManager.Property property = new PackageManager.Property( 6759 ConstantsShim.PROPERTY_SELF_CERTIFIED_NETWORK_CAPABILITIES, 6760 networkSliceResourceId, 6761 true /* isResource */, 6762 mContext.getPackageName(), 6763 "dummyClass" 6764 ); 6765 doReturn(property).when(mPackageManager).getProperty( 6766 ConstantsShim.PROPERTY_SELF_CERTIFIED_NETWORK_CAPABILITIES, 6767 mContext.getPackageName()); 6768 doReturn(mContext.getResources()).when(mPackageManager).getResourcesForApplication( 6769 mContext.getPackageName()); 6770 } 6771 } 6772 6773 @Test 6774 @IgnoreUpTo(Build.VERSION_CODES.TIRAMISU) 6775 @EnableCompatChanges(ConnectivityCompatChanges.ENABLE_SELF_CERTIFIED_CAPABILITIES_DECLARATION) 6776 public void requestNetwork_withoutPrioritizeBandwidthDeclaration_shouldThrowException() 6777 throws Exception { 6778 mDeps.enableCompatChangeCheck(); 6779 setupMockForNetworkCapabilitiesResources( 6780 com.android.frameworks.tests.net.R.xml.self_certified_capabilities_latency); 6781 final NetworkRequest networkRequest = new NetworkRequest.Builder() 6782 .addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_BANDWIDTH) 6783 .build(); 6784 final TestNetworkCallback cb = new TestNetworkCallback(); 6785 final Exception e = assertThrows(SecurityException.class, 6786 () -> mCm.requestNetwork(networkRequest, cb)); 6787 assertThat(e.getMessage(), 6788 containsString(ApplicationSelfCertifiedNetworkCapabilities.PRIORITIZE_BANDWIDTH)); 6789 } 6790 6791 @Test 6792 @IgnoreUpTo(Build.VERSION_CODES.TIRAMISU) 6793 @EnableCompatChanges(ConnectivityCompatChanges.ENABLE_SELF_CERTIFIED_CAPABILITIES_DECLARATION) 6794 public void requestNetwork_withoutPrioritizeLatencyDeclaration_shouldThrowException() 6795 throws Exception { 6796 mDeps.enableCompatChangeCheck(); 6797 setupMockForNetworkCapabilitiesResources( 6798 com.android.frameworks.tests.net.R.xml.self_certified_capabilities_bandwidth); 6799 final NetworkRequest networkRequest = new NetworkRequest.Builder() 6800 .addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_LATENCY) 6801 .build(); 6802 final TestNetworkCallback cb = new TestNetworkCallback(); 6803 final Exception e = assertThrows(SecurityException.class, 6804 () -> mCm.requestNetwork(networkRequest, cb)); 6805 assertThat(e.getMessage(), 6806 containsString(ApplicationSelfCertifiedNetworkCapabilities.PRIORITIZE_LATENCY)); 6807 } 6808 6809 @Test 6810 @IgnoreUpTo(Build.VERSION_CODES.TIRAMISU) 6811 @EnableCompatChanges(ConnectivityCompatChanges.ENABLE_SELF_CERTIFIED_CAPABILITIES_DECLARATION) 6812 public void requestNetwork_withoutNetworkSliceProperty_shouldThrowException() throws Exception { 6813 mDeps.enableCompatChangeCheck(); 6814 setupMockForNetworkCapabilitiesResources(0 /* networkSliceResourceId */); 6815 final NetworkRequest networkRequest = new NetworkRequest.Builder() 6816 .addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_LATENCY) 6817 .addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_BANDWIDTH) 6818 .build(); 6819 final TestNetworkCallback cb = new TestNetworkCallback(); 6820 final Exception e = assertThrows(SecurityException.class, 6821 () -> mCm.requestNetwork(networkRequest, cb)); 6822 assertThat(e.getMessage(), 6823 containsString(ConstantsShim.PROPERTY_SELF_CERTIFIED_NETWORK_CAPABILITIES)); 6824 } 6825 6826 @Test 6827 @IgnoreUpTo(Build.VERSION_CODES.TIRAMISU) 6828 @EnableCompatChanges(ConnectivityCompatChanges.ENABLE_SELF_CERTIFIED_CAPABILITIES_DECLARATION) 6829 public void requestNetwork_withNetworkSliceDeclaration_shouldSucceed() throws Exception { 6830 mDeps.enableCompatChangeCheck(); 6831 setupMockForNetworkCapabilitiesResources( 6832 com.android.frameworks.tests.net.R.xml.self_certified_capabilities_both); 6833 6834 final NetworkRequest networkRequest = new NetworkRequest.Builder() 6835 .addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_LATENCY) 6836 .addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_BANDWIDTH) 6837 .build(); 6838 final TestNetworkCallback cb = new TestNetworkCallback(); 6839 mCm.requestNetwork(networkRequest, cb); 6840 mCm.unregisterNetworkCallback(cb); 6841 } 6842 6843 @Test 6844 @IgnoreUpTo(Build.VERSION_CODES.TIRAMISU) 6845 @EnableCompatChanges(ConnectivityCompatChanges.ENABLE_SELF_CERTIFIED_CAPABILITIES_DECLARATION) 6846 public void requestNetwork_withNetworkSliceDeclaration_shouldUseCache() throws Exception { 6847 mDeps.enableCompatChangeCheck(); 6848 setupMockForNetworkCapabilitiesResources( 6849 com.android.frameworks.tests.net.R.xml.self_certified_capabilities_both); 6850 6851 final NetworkRequest networkRequest = new NetworkRequest.Builder() 6852 .addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_LATENCY) 6853 .addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_BANDWIDTH) 6854 .build(); 6855 final TestNetworkCallback cb = new TestNetworkCallback(); 6856 mCm.requestNetwork(networkRequest, cb); 6857 mCm.unregisterNetworkCallback(cb); 6858 6859 // Second call should use caches 6860 mCm.requestNetwork(networkRequest, cb); 6861 mCm.unregisterNetworkCallback(cb); 6862 6863 // PackageManager's API only called once because the second call is using cache. 6864 verify(mPackageManager, times(1)).getProperty( 6865 ConstantsShim.PROPERTY_SELF_CERTIFIED_NETWORK_CAPABILITIES, 6866 mContext.getPackageName()); 6867 verify(mPackageManager, times(1)).getResourcesForApplication( 6868 mContext.getPackageName()); 6869 } 6870 6871 /** 6872 * Validate the service throws if request with CBS but without carrier privilege. 6873 */ 6874 @Test 6875 public void testCBSRequestWithoutCarrierPrivilege() throws Exception { 6876 final NetworkRequest nr = new NetworkRequest.Builder().addTransportType( 6877 TRANSPORT_CELLULAR).addCapability(NET_CAPABILITY_CBS).build(); 6878 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 6879 6880 mServiceContext.setPermission(CONNECTIVITY_USE_RESTRICTED_NETWORKS, PERMISSION_DENIED); 6881 // Now file the test request and expect the service throws. 6882 assertThrows(SecurityException.class, () -> mCm.requestNetwork(nr, networkCallback)); 6883 } 6884 6885 private static class TestKeepaliveCallback extends PacketKeepaliveCallback { 6886 6887 public enum CallbackType { ON_STARTED, ON_STOPPED, ON_ERROR } 6888 6889 private class CallbackValue { 6890 public CallbackType callbackType; 6891 public int error; 6892 6893 public CallbackValue(CallbackType type) { 6894 this.callbackType = type; 6895 this.error = PacketKeepalive.SUCCESS; 6896 assertTrue("onError callback must have error", type != CallbackType.ON_ERROR); 6897 } 6898 6899 public CallbackValue(CallbackType type, int error) { 6900 this.callbackType = type; 6901 this.error = error; 6902 assertEquals("error can only be set for onError", type, CallbackType.ON_ERROR); 6903 } 6904 6905 @Override 6906 public boolean equals(Object o) { 6907 return o instanceof CallbackValue && 6908 this.callbackType == ((CallbackValue) o).callbackType && 6909 this.error == ((CallbackValue) o).error; 6910 } 6911 6912 @Override 6913 public String toString() { 6914 return String.format("%s(%s, %d)", getClass().getSimpleName(), callbackType, error); 6915 } 6916 } 6917 6918 private final LinkedBlockingQueue<CallbackValue> mCallbacks = new LinkedBlockingQueue<>(); 6919 6920 @Override 6921 public void onStarted() { 6922 mCallbacks.add(new CallbackValue(CallbackType.ON_STARTED)); 6923 } 6924 6925 @Override 6926 public void onStopped() { 6927 mCallbacks.add(new CallbackValue(CallbackType.ON_STOPPED)); 6928 } 6929 6930 @Override 6931 public void onError(int error) { 6932 mCallbacks.add(new CallbackValue(CallbackType.ON_ERROR, error)); 6933 } 6934 6935 private void expect(CallbackValue callbackValue) throws InterruptedException { 6936 assertEquals(callbackValue, mCallbacks.poll(TIMEOUT_MS, TimeUnit.MILLISECONDS)); 6937 } 6938 6939 public void expectStarted() throws Exception { 6940 expect(new CallbackValue(CallbackType.ON_STARTED)); 6941 } 6942 6943 public void expectStopped() throws Exception { 6944 expect(new CallbackValue(CallbackType.ON_STOPPED)); 6945 } 6946 6947 public void expectError(int error) throws Exception { 6948 expect(new CallbackValue(CallbackType.ON_ERROR, error)); 6949 } 6950 } 6951 6952 private static class TestSocketKeepaliveCallback extends SocketKeepalive.Callback { 6953 6954 public enum CallbackType { ON_STARTED, ON_STOPPED, ON_ERROR }; 6955 6956 private class CallbackValue { 6957 public CallbackType callbackType; 6958 public int error; 6959 6960 CallbackValue(CallbackType type) { 6961 this.callbackType = type; 6962 this.error = SocketKeepalive.SUCCESS; 6963 assertTrue("onError callback must have error", type != CallbackType.ON_ERROR); 6964 } 6965 6966 CallbackValue(CallbackType type, int error) { 6967 this.callbackType = type; 6968 this.error = error; 6969 assertEquals("error can only be set for onError", type, CallbackType.ON_ERROR); 6970 } 6971 6972 @Override 6973 public boolean equals(Object o) { 6974 return o instanceof CallbackValue 6975 && this.callbackType == ((CallbackValue) o).callbackType 6976 && this.error == ((CallbackValue) o).error; 6977 } 6978 6979 @Override 6980 public String toString() { 6981 return String.format("%s(%s, %d)", getClass().getSimpleName(), callbackType, 6982 error); 6983 } 6984 } 6985 6986 private LinkedBlockingQueue<CallbackValue> mCallbacks = new LinkedBlockingQueue<>(); 6987 private final Executor mExecutor; 6988 6989 TestSocketKeepaliveCallback(@NonNull Executor executor) { 6990 mExecutor = executor; 6991 } 6992 6993 @Override 6994 public void onStarted() { 6995 mCallbacks.add(new CallbackValue(CallbackType.ON_STARTED)); 6996 } 6997 6998 @Override 6999 public void onStopped() { 7000 mCallbacks.add(new CallbackValue(CallbackType.ON_STOPPED)); 7001 } 7002 7003 @Override 7004 public void onError(int error) { 7005 mCallbacks.add(new CallbackValue(CallbackType.ON_ERROR, error)); 7006 } 7007 7008 private void expect(CallbackValue callbackValue) throws InterruptedException { 7009 assertEquals(callbackValue, mCallbacks.poll(TIMEOUT_MS, TimeUnit.MILLISECONDS)); 7010 7011 } 7012 7013 public void expectStarted() throws InterruptedException { 7014 expect(new CallbackValue(CallbackType.ON_STARTED)); 7015 } 7016 7017 public void expectStopped() throws InterruptedException { 7018 expect(new CallbackValue(CallbackType.ON_STOPPED)); 7019 } 7020 7021 public void expectError(int error) throws InterruptedException { 7022 expect(new CallbackValue(CallbackType.ON_ERROR, error)); 7023 } 7024 7025 public void assertNoCallback() { 7026 waitForIdleSerialExecutor(mExecutor, TIMEOUT_MS); 7027 CallbackValue cv = mCallbacks.peek(); 7028 assertNull("Unexpected callback: " + cv, cv); 7029 } 7030 } 7031 7032 private Network connectKeepaliveNetwork(LinkProperties lp) throws Exception { 7033 // Ensure the network is disconnected before anything else occurs 7034 if (mWiFiAgent != null) { 7035 assertNull(mCm.getNetworkCapabilities(mWiFiAgent.getNetwork())); 7036 } 7037 7038 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 7039 ExpectedBroadcast b = expectConnectivityAction(TYPE_WIFI, DetailedState.CONNECTED); 7040 mWiFiAgent.connect(true); 7041 b.expectBroadcast(); 7042 verifyActiveNetwork(TRANSPORT_WIFI); 7043 mWiFiAgent.sendLinkProperties(lp); 7044 waitForIdle(); 7045 return mWiFiAgent.getNetwork(); 7046 } 7047 7048 @Test 7049 public void testPacketKeepalives() throws Exception { 7050 final LinkAddress v4Addr = new LinkAddress("192.0.2.129/24"); 7051 final InetAddress myIPv4 = v4Addr.getAddress(); 7052 InetAddress notMyIPv4 = InetAddress.getByName("192.0.2.35"); 7053 InetAddress myIPv6 = InetAddress.getByName("2001:db8::1"); 7054 InetAddress dstIPv4 = InetAddress.getByName("8.8.8.8"); 7055 InetAddress dstIPv6 = InetAddress.getByName("2001:4860:4860::8888"); 7056 doReturn(getClatInterfaceConfigParcel(v4Addr)).when(mMockNetd) 7057 .interfaceGetCfg(CLAT_MOBILE_IFNAME); 7058 final int validKaInterval = 15; 7059 final int invalidKaInterval = 9; 7060 7061 LinkProperties lp = new LinkProperties(); 7062 lp.setInterfaceName(MOBILE_IFNAME); 7063 lp.addLinkAddress(new LinkAddress(myIPv6, 64)); 7064 lp.addLinkAddress(new LinkAddress(myIPv4, 25)); 7065 lp.addRoute(new RouteInfo(InetAddress.getByName("fe80::1234"))); 7066 lp.addRoute(new RouteInfo(InetAddress.getByName("192.0.2.254"))); 7067 7068 Network notMyNet = new Network(61234); 7069 Network myNet = connectKeepaliveNetwork(lp); 7070 7071 TestKeepaliveCallback callback = new TestKeepaliveCallback(); 7072 PacketKeepalive ka; 7073 7074 // Attempt to start keepalives with invalid parameters and check for errors. 7075 ka = mCm.startNattKeepalive(notMyNet, validKaInterval, callback, myIPv4, 1234, dstIPv4); 7076 callback.expectError(PacketKeepalive.ERROR_INVALID_NETWORK); 7077 7078 ka = mCm.startNattKeepalive(myNet, invalidKaInterval, callback, myIPv4, 1234, dstIPv4); 7079 callback.expectError(PacketKeepalive.ERROR_INVALID_INTERVAL); 7080 7081 ka = mCm.startNattKeepalive(myNet, validKaInterval, callback, myIPv4, 1234, dstIPv6); 7082 callback.expectError(PacketKeepalive.ERROR_INVALID_IP_ADDRESS); 7083 7084 ka = mCm.startNattKeepalive(myNet, validKaInterval, callback, myIPv6, 1234, dstIPv4); 7085 callback.expectError(PacketKeepalive.ERROR_INVALID_IP_ADDRESS); 7086 7087 ka = mCm.startNattKeepalive(myNet, validKaInterval, callback, myIPv4, 123456, dstIPv4); 7088 callback.expectError(PacketKeepalive.ERROR_INVALID_PORT); 7089 7090 ka = mCm.startNattKeepalive(myNet, validKaInterval, callback, myIPv4, 123456, dstIPv4); 7091 callback.expectError(PacketKeepalive.ERROR_INVALID_PORT); 7092 7093 ka = mCm.startNattKeepalive(myNet, validKaInterval, callback, myIPv4, 12345, dstIPv4); 7094 callback.expectError(PacketKeepalive.ERROR_HARDWARE_UNSUPPORTED); 7095 7096 ka = mCm.startNattKeepalive(myNet, validKaInterval, callback, myIPv4, 12345, dstIPv4); 7097 callback.expectError(PacketKeepalive.ERROR_HARDWARE_UNSUPPORTED); 7098 7099 // Check that a started keepalive can be stopped. 7100 mWiFiAgent.setStartKeepaliveEvent(PacketKeepalive.SUCCESS); 7101 ka = mCm.startNattKeepalive(myNet, validKaInterval, callback, myIPv4, 12345, dstIPv4); 7102 callback.expectStarted(); 7103 mWiFiAgent.setStopKeepaliveEvent(PacketKeepalive.SUCCESS); 7104 ka.stop(); 7105 callback.expectStopped(); 7106 7107 // Check that deleting the IP address stops the keepalive. 7108 LinkProperties bogusLp = new LinkProperties(lp); 7109 ka = mCm.startNattKeepalive(myNet, validKaInterval, callback, myIPv4, 12345, dstIPv4); 7110 callback.expectStarted(); 7111 bogusLp.removeLinkAddress(new LinkAddress(myIPv4, 25)); 7112 bogusLp.addLinkAddress(new LinkAddress(notMyIPv4, 25)); 7113 mWiFiAgent.sendLinkProperties(bogusLp); 7114 callback.expectError(PacketKeepalive.ERROR_INVALID_IP_ADDRESS); 7115 mWiFiAgent.sendLinkProperties(lp); 7116 7117 // Check that a started keepalive is stopped correctly when the network disconnects. 7118 ka = mCm.startNattKeepalive(myNet, validKaInterval, callback, myIPv4, 12345, dstIPv4); 7119 callback.expectStarted(); 7120 mWiFiAgent.disconnect(); 7121 mWiFiAgent.expectDisconnected(); 7122 callback.expectError(PacketKeepalive.ERROR_INVALID_NETWORK); 7123 7124 // ... and that stopping it after that has no adverse effects. 7125 waitForIdle(); 7126 final Network myNetAlias = myNet; 7127 assertNull(mCm.getNetworkCapabilities(myNetAlias)); 7128 ka.stop(); 7129 7130 // Reconnect. 7131 myNet = connectKeepaliveNetwork(lp); 7132 mWiFiAgent.setStartKeepaliveEvent(PacketKeepalive.SUCCESS); 7133 7134 // Check that keepalive slots start from 1 and increment. The first one gets slot 1. 7135 mWiFiAgent.setExpectedKeepaliveSlot(1); 7136 ka = mCm.startNattKeepalive(myNet, validKaInterval, callback, myIPv4, 12345, dstIPv4); 7137 callback.expectStarted(); 7138 7139 // The second one gets slot 2. 7140 mWiFiAgent.setExpectedKeepaliveSlot(2); 7141 TestKeepaliveCallback callback2 = new TestKeepaliveCallback(); 7142 PacketKeepalive ka2 = mCm.startNattKeepalive( 7143 myNet, validKaInterval, callback2, myIPv4, 6789, dstIPv4); 7144 callback2.expectStarted(); 7145 7146 // Now stop the first one and create a third. This also gets slot 1. 7147 ka.stop(); 7148 callback.expectStopped(); 7149 7150 mWiFiAgent.setExpectedKeepaliveSlot(1); 7151 TestKeepaliveCallback callback3 = new TestKeepaliveCallback(); 7152 PacketKeepalive ka3 = mCm.startNattKeepalive( 7153 myNet, validKaInterval, callback3, myIPv4, 9876, dstIPv4); 7154 callback3.expectStarted(); 7155 7156 ka2.stop(); 7157 callback2.expectStopped(); 7158 7159 ka3.stop(); 7160 callback3.expectStopped(); 7161 } 7162 7163 // Helper method to prepare the executor and run test 7164 private void runTestWithSerialExecutors(ThrowingConsumer<Executor> functor) 7165 throws Exception { 7166 final ExecutorService executorSingleThread = Executors.newSingleThreadExecutor(); 7167 final Executor executorInline = (Runnable r) -> r.run(); 7168 functor.accept(executorSingleThread); 7169 executorSingleThread.shutdown(); 7170 functor.accept(executorInline); 7171 } 7172 7173 @Test 7174 public void testNattSocketKeepalives() throws Exception { 7175 runTestWithSerialExecutors(executor -> doTestNattSocketKeepalivesWithExecutor(executor)); 7176 runTestWithSerialExecutors(executor -> doTestNattSocketKeepalivesFdWithExecutor(executor)); 7177 } 7178 7179 private void doTestNattSocketKeepalivesWithExecutor(Executor executor) throws Exception { 7180 // TODO: 1. Move this outside of ConnectivityServiceTest. 7181 // 2. Make test to verify that Nat-T keepalive socket is created by IpSecService. 7182 // 3. Mock ipsec service. 7183 final InetAddress myIPv4 = InetAddress.getByName("192.0.2.129"); 7184 final InetAddress notMyIPv4 = InetAddress.getByName("192.0.2.35"); 7185 final InetAddress myIPv6 = InetAddress.getByName("2001:db8::1"); 7186 final InetAddress dstIPv4 = InetAddress.getByName("8.8.8.8"); 7187 final InetAddress dstIPv6 = InetAddress.getByName("2001:4860:4860::8888"); 7188 7189 final int validKaInterval = 15; 7190 final int invalidKaInterval = 9; 7191 7192 final IpSecManager mIpSec = (IpSecManager) mContext.getSystemService(Context.IPSEC_SERVICE); 7193 final UdpEncapsulationSocket testSocket = mIpSec.openUdpEncapsulationSocket(); 7194 final int srcPort = testSocket.getPort(); 7195 7196 LinkProperties lp = new LinkProperties(); 7197 lp.setInterfaceName("wlan12"); 7198 lp.addLinkAddress(new LinkAddress(myIPv6, 64)); 7199 lp.addLinkAddress(new LinkAddress(myIPv4, 25)); 7200 lp.addRoute(new RouteInfo(InetAddress.getByName("fe80::1234"))); 7201 lp.addRoute(new RouteInfo(InetAddress.getByName("192.0.2.254"))); 7202 7203 Network notMyNet = new Network(61234); 7204 Network myNet = connectKeepaliveNetwork(lp); 7205 7206 TestSocketKeepaliveCallback callback = new TestSocketKeepaliveCallback(executor); 7207 7208 // Attempt to start keepalives with invalid parameters and check for errors. 7209 // Invalid network. 7210 try (SocketKeepalive ka = mCm.createSocketKeepalive( 7211 notMyNet, testSocket, myIPv4, dstIPv4, executor, callback)) { 7212 ka.start(validKaInterval); 7213 callback.expectError(SocketKeepalive.ERROR_INVALID_NETWORK); 7214 } 7215 7216 // Invalid interval. 7217 try (SocketKeepalive ka = mCm.createSocketKeepalive( 7218 myNet, testSocket, myIPv4, dstIPv4, executor, callback)) { 7219 ka.start(invalidKaInterval); 7220 callback.expectError(SocketKeepalive.ERROR_INVALID_INTERVAL); 7221 } 7222 7223 // Invalid destination. 7224 try (SocketKeepalive ka = mCm.createSocketKeepalive( 7225 myNet, testSocket, myIPv4, dstIPv6, executor, callback)) { 7226 ka.start(validKaInterval); 7227 callback.expectError(SocketKeepalive.ERROR_INVALID_IP_ADDRESS); 7228 } 7229 7230 // Invalid source; 7231 try (SocketKeepalive ka = mCm.createSocketKeepalive( 7232 myNet, testSocket, myIPv6, dstIPv4, executor, callback)) { 7233 ka.start(validKaInterval); 7234 callback.expectError(SocketKeepalive.ERROR_INVALID_IP_ADDRESS); 7235 } 7236 7237 // Basic check before testing started keepalive. 7238 try (SocketKeepalive ka = mCm.createSocketKeepalive( 7239 myNet, testSocket, myIPv4, dstIPv4, executor, callback)) { 7240 ka.start(validKaInterval); 7241 callback.expectError(SocketKeepalive.ERROR_UNSUPPORTED); 7242 } 7243 7244 // Check that a started keepalive can be stopped. 7245 mWiFiAgent.setStartKeepaliveEvent(SocketKeepalive.SUCCESS); 7246 try (SocketKeepalive ka = mCm.createSocketKeepalive( 7247 myNet, testSocket, myIPv4, dstIPv4, executor, callback)) { 7248 ka.start(validKaInterval); 7249 callback.expectStarted(); 7250 mWiFiAgent.setStopKeepaliveEvent(SocketKeepalive.SUCCESS); 7251 ka.stop(); 7252 callback.expectStopped(); 7253 7254 // Check that keepalive could be restarted. 7255 ka.start(validKaInterval); 7256 callback.expectStarted(); 7257 ka.stop(); 7258 callback.expectStopped(); 7259 7260 // Check that keepalive can be restarted without waiting for callback. 7261 ka.start(validKaInterval); 7262 callback.expectStarted(); 7263 ka.stop(); 7264 ka.start(validKaInterval); 7265 callback.expectStopped(); 7266 callback.expectStarted(); 7267 ka.stop(); 7268 callback.expectStopped(); 7269 } 7270 7271 // Check that deleting the IP address stops the keepalive. 7272 LinkProperties bogusLp = new LinkProperties(lp); 7273 try (SocketKeepalive ka = mCm.createSocketKeepalive( 7274 myNet, testSocket, myIPv4, dstIPv4, executor, callback)) { 7275 ka.start(validKaInterval); 7276 callback.expectStarted(); 7277 bogusLp.removeLinkAddress(new LinkAddress(myIPv4, 25)); 7278 bogusLp.addLinkAddress(new LinkAddress(notMyIPv4, 25)); 7279 mWiFiAgent.sendLinkProperties(bogusLp); 7280 callback.expectError(SocketKeepalive.ERROR_INVALID_IP_ADDRESS); 7281 mWiFiAgent.sendLinkProperties(lp); 7282 } 7283 7284 // Check that a started keepalive is stopped correctly when the network disconnects. 7285 try (SocketKeepalive ka = mCm.createSocketKeepalive( 7286 myNet, testSocket, myIPv4, dstIPv4, executor, callback)) { 7287 ka.start(validKaInterval); 7288 callback.expectStarted(); 7289 mWiFiAgent.disconnect(); 7290 mWiFiAgent.expectDisconnected(); 7291 callback.expectError(SocketKeepalive.ERROR_INVALID_NETWORK); 7292 7293 // ... and that stopping it after that has no adverse effects. 7294 waitForIdle(); 7295 assertNull(mCm.getNetworkCapabilities(myNet)); 7296 ka.stop(); 7297 callback.assertNoCallback(); 7298 } 7299 7300 // Reconnect. 7301 myNet = connectKeepaliveNetwork(lp); 7302 mWiFiAgent.setStartKeepaliveEvent(SocketKeepalive.SUCCESS); 7303 7304 // Check that a stop followed by network disconnects does not result in crash. 7305 try (SocketKeepalive ka = mCm.createSocketKeepalive( 7306 myNet, testSocket, myIPv4, dstIPv4, executor, callback)) { 7307 ka.start(validKaInterval); 7308 callback.expectStarted(); 7309 // Delay the response of keepalive events in networkAgent long enough to make sure 7310 // the follow-up network disconnection will be processed first. 7311 mWiFiAgent.setKeepaliveResponseDelay(3 * TIMEOUT_MS); 7312 ka.stop(); 7313 // Call stop() twice shouldn't result in crash, b/182586681. 7314 ka.stop(); 7315 7316 // Make sure the stop has been processed. Wait for executor idle is needed to prevent 7317 // flaky since the actual stop call to the service is delegated to executor thread. 7318 waitForIdleSerialExecutor(executor, TIMEOUT_MS); 7319 waitForIdle(); 7320 7321 mWiFiAgent.disconnect(); 7322 mWiFiAgent.expectDisconnected(); 7323 callback.expectStopped(); 7324 callback.assertNoCallback(); 7325 } 7326 7327 // Reconnect. 7328 waitForIdle(); 7329 myNet = connectKeepaliveNetwork(lp); 7330 mWiFiAgent.setStartKeepaliveEvent(SocketKeepalive.SUCCESS); 7331 7332 // Check that keepalive slots start from 1 and increment. The first one gets slot 1. 7333 mWiFiAgent.setExpectedKeepaliveSlot(1); 7334 try (SocketKeepalive ka = mCm.createSocketKeepalive( 7335 myNet, testSocket, myIPv4, dstIPv4, executor, callback)) { 7336 ka.start(validKaInterval); 7337 callback.expectStarted(); 7338 7339 // The second one gets slot 2. 7340 mWiFiAgent.setExpectedKeepaliveSlot(2); 7341 final UdpEncapsulationSocket testSocket2 = mIpSec.openUdpEncapsulationSocket(); 7342 TestSocketKeepaliveCallback callback2 = new TestSocketKeepaliveCallback(executor); 7343 try (SocketKeepalive ka2 = mCm.createSocketKeepalive( 7344 myNet, testSocket2, myIPv4, dstIPv4, executor, callback2)) { 7345 ka2.start(validKaInterval); 7346 callback2.expectStarted(); 7347 7348 ka.stop(); 7349 callback.expectStopped(); 7350 7351 ka2.stop(); 7352 callback2.expectStopped(); 7353 7354 testSocket.close(); 7355 testSocket2.close(); 7356 } 7357 } 7358 7359 // Check that there is no port leaked after all keepalives and sockets are closed. 7360 // TODO: enable this check after ensuring a valid free port. See b/129512753#comment7. 7361 // assertFalse(isUdpPortInUse(srcPort)); 7362 // assertFalse(isUdpPortInUse(srcPort2)); 7363 7364 mWiFiAgent.disconnect(); 7365 mWiFiAgent.expectDisconnected(); 7366 mWiFiAgent = null; 7367 } 7368 7369 @Test 7370 public void testTcpSocketKeepalives() throws Exception { 7371 runTestWithSerialExecutors(executor -> doTestTcpSocketKeepalivesWithExecutor(executor)); 7372 } 7373 7374 private void doTestTcpSocketKeepalivesWithExecutor(Executor executor) throws Exception { 7375 final int srcPortV4 = 12345; 7376 final int srcPortV6 = 23456; 7377 final InetAddress myIPv4 = InetAddress.getByName("127.0.0.1"); 7378 final InetAddress myIPv6 = InetAddress.getByName("::1"); 7379 7380 final int validKaInterval = 15; 7381 7382 final LinkProperties lp = new LinkProperties(); 7383 lp.setInterfaceName("wlan12"); 7384 lp.addLinkAddress(new LinkAddress(myIPv6, 64)); 7385 lp.addLinkAddress(new LinkAddress(myIPv4, 25)); 7386 lp.addRoute(new RouteInfo(InetAddress.getByName("fe80::1234"))); 7387 lp.addRoute(new RouteInfo(InetAddress.getByName("127.0.0.254"))); 7388 7389 final Network notMyNet = new Network(61234); 7390 final Network myNet = connectKeepaliveNetwork(lp); 7391 7392 final Socket testSocketV4 = new Socket(); 7393 final Socket testSocketV6 = new Socket(); 7394 7395 TestSocketKeepaliveCallback callback = new TestSocketKeepaliveCallback(executor); 7396 7397 // Attempt to start Tcp keepalives with invalid parameters and check for errors. 7398 // Invalid network. 7399 try (SocketKeepalive ka = mCm.createSocketKeepalive( 7400 notMyNet, testSocketV4, executor, callback)) { 7401 ka.start(validKaInterval); 7402 callback.expectError(SocketKeepalive.ERROR_INVALID_NETWORK); 7403 } 7404 7405 // Invalid Socket (socket is not bound with IPv4 address). 7406 try (SocketKeepalive ka = mCm.createSocketKeepalive( 7407 myNet, testSocketV4, executor, callback)) { 7408 ka.start(validKaInterval); 7409 callback.expectError(SocketKeepalive.ERROR_INVALID_SOCKET); 7410 } 7411 7412 // Invalid Socket (socket is not bound with IPv6 address). 7413 try (SocketKeepalive ka = mCm.createSocketKeepalive( 7414 myNet, testSocketV6, executor, callback)) { 7415 ka.start(validKaInterval); 7416 callback.expectError(SocketKeepalive.ERROR_INVALID_SOCKET); 7417 } 7418 7419 // Bind the socket address 7420 testSocketV4.bind(new InetSocketAddress(myIPv4, srcPortV4)); 7421 testSocketV6.bind(new InetSocketAddress(myIPv6, srcPortV6)); 7422 7423 // Invalid Socket (socket is bound with IPv4 address). 7424 try (SocketKeepalive ka = mCm.createSocketKeepalive( 7425 myNet, testSocketV4, executor, callback)) { 7426 ka.start(validKaInterval); 7427 callback.expectError(SocketKeepalive.ERROR_INVALID_SOCKET); 7428 } 7429 7430 // Invalid Socket (socket is bound with IPv6 address). 7431 try (SocketKeepalive ka = mCm.createSocketKeepalive( 7432 myNet, testSocketV6, executor, callback)) { 7433 ka.start(validKaInterval); 7434 callback.expectError(SocketKeepalive.ERROR_INVALID_SOCKET); 7435 } 7436 7437 testSocketV4.close(); 7438 testSocketV6.close(); 7439 7440 mWiFiAgent.disconnect(); 7441 mWiFiAgent.expectDisconnected(); 7442 mWiFiAgent = null; 7443 } 7444 7445 private void doTestNattSocketKeepalivesFdWithExecutor(Executor executor) throws Exception { 7446 final InetAddress myIPv4 = InetAddress.getByName("192.0.2.129"); 7447 final InetAddress anyIPv4 = InetAddress.getByName("0.0.0.0"); 7448 final InetAddress dstIPv4 = InetAddress.getByName("8.8.8.8"); 7449 final int validKaInterval = 15; 7450 7451 // Prepare the target network. 7452 LinkProperties lp = new LinkProperties(); 7453 lp.setInterfaceName("wlan12"); 7454 lp.addLinkAddress(new LinkAddress(myIPv4, 25)); 7455 lp.addRoute(new RouteInfo(InetAddress.getByName("192.0.2.254"))); 7456 Network myNet = connectKeepaliveNetwork(lp); 7457 mWiFiAgent.setStartKeepaliveEvent(SocketKeepalive.SUCCESS); 7458 mWiFiAgent.setStopKeepaliveEvent(SocketKeepalive.SUCCESS); 7459 7460 TestSocketKeepaliveCallback callback = new TestSocketKeepaliveCallback(executor); 7461 7462 // Prepare the target file descriptor, keep only one instance. 7463 final IpSecManager mIpSec = (IpSecManager) mContext.getSystemService(Context.IPSEC_SERVICE); 7464 final UdpEncapsulationSocket testSocket = mIpSec.openUdpEncapsulationSocket(); 7465 final int srcPort = testSocket.getPort(); 7466 final ParcelFileDescriptor testPfd = 7467 ParcelFileDescriptor.dup(testSocket.getFileDescriptor()); 7468 testSocket.close(); 7469 assertTrue(isUdpPortInUse(srcPort)); 7470 7471 // Start keepalive and explicit make the variable goes out of scope with try-with-resources 7472 // block. 7473 try (SocketKeepalive ka = mCm.createNattKeepalive( 7474 myNet, testPfd, myIPv4, dstIPv4, executor, callback)) { 7475 ka.start(validKaInterval); 7476 callback.expectStarted(); 7477 ka.stop(); 7478 callback.expectStopped(); 7479 } 7480 7481 // Check that the ParcelFileDescriptor is still valid after keepalive stopped, 7482 // ErrnoException with EBADF will be thrown if the socket is closed when checking local 7483 // address. 7484 assertTrue(isUdpPortInUse(srcPort)); 7485 final InetSocketAddress sa = 7486 (InetSocketAddress) Os.getsockname(testPfd.getFileDescriptor()); 7487 assertEquals(anyIPv4, sa.getAddress()); 7488 7489 testPfd.close(); 7490 // TODO: enable this check after ensuring a valid free port. See b/129512753#comment7. 7491 // assertFalse(isUdpPortInUse(srcPort)); 7492 7493 mWiFiAgent.disconnect(); 7494 mWiFiAgent.expectDisconnected(); 7495 mWiFiAgent = null; 7496 } 7497 7498 private static boolean isUdpPortInUse(int port) { 7499 try (DatagramSocket ignored = new DatagramSocket(port)) { 7500 return false; 7501 } catch (IOException alreadyInUse) { 7502 return true; 7503 } 7504 } 7505 7506 @Test 7507 public void testGetCaptivePortalServerUrl() throws Exception { 7508 String url = mCm.getCaptivePortalServerUrl(); 7509 assertEquals("http://connectivitycheck.gstatic.com/generate_204", url); 7510 } 7511 7512 private static class TestNetworkPinner extends NetworkPinner { 7513 public static boolean awaitPin(int timeoutMs) throws InterruptedException { 7514 synchronized(sLock) { 7515 if (sNetwork == null) { 7516 sLock.wait(timeoutMs); 7517 } 7518 return sNetwork != null; 7519 } 7520 } 7521 7522 public static boolean awaitUnpin(int timeoutMs) throws InterruptedException { 7523 synchronized(sLock) { 7524 if (sNetwork != null) { 7525 sLock.wait(timeoutMs); 7526 } 7527 return sNetwork == null; 7528 } 7529 } 7530 } 7531 7532 private void assertPinnedToWifiWithCellDefault() { 7533 assertEquals(mWiFiAgent.getNetwork(), mCm.getBoundNetworkForProcess()); 7534 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetwork()); 7535 } 7536 7537 private void assertPinnedToWifiWithWifiDefault() { 7538 assertEquals(mWiFiAgent.getNetwork(), mCm.getBoundNetworkForProcess()); 7539 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetwork()); 7540 } 7541 7542 private void assertNotPinnedToWifi() { 7543 assertNull(mCm.getBoundNetworkForProcess()); 7544 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetwork()); 7545 } 7546 7547 @Test 7548 public void testNetworkPinner() throws Exception { 7549 NetworkRequest wifiRequest = new NetworkRequest.Builder() 7550 .addTransportType(TRANSPORT_WIFI) 7551 .build(); 7552 assertNull(mCm.getBoundNetworkForProcess()); 7553 7554 TestNetworkPinner.pin(mServiceContext, wifiRequest); 7555 assertNull(mCm.getBoundNetworkForProcess()); 7556 7557 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 7558 mCellAgent.connect(true); 7559 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 7560 mWiFiAgent.connect(false); 7561 7562 // When wi-fi connects, expect to be pinned. 7563 assertTrue(TestNetworkPinner.awaitPin(100)); 7564 assertPinnedToWifiWithCellDefault(); 7565 7566 // Disconnect and expect the pin to drop. 7567 mWiFiAgent.disconnect(); 7568 assertTrue(TestNetworkPinner.awaitUnpin(100)); 7569 assertNotPinnedToWifi(); 7570 7571 // Reconnecting does not cause the pin to come back. 7572 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 7573 mWiFiAgent.connect(false); 7574 assertFalse(TestNetworkPinner.awaitPin(100)); 7575 assertNotPinnedToWifi(); 7576 7577 // Pinning while connected causes the pin to take effect immediately. 7578 TestNetworkPinner.pin(mServiceContext, wifiRequest); 7579 assertTrue(TestNetworkPinner.awaitPin(100)); 7580 assertPinnedToWifiWithCellDefault(); 7581 7582 // Explicitly unpin and expect to use the default network again. 7583 TestNetworkPinner.unpin(); 7584 assertNotPinnedToWifi(); 7585 7586 // Disconnect cell and wifi. 7587 ExpectedBroadcast b = expectConnectivityAction(3); // cell down, wifi up, wifi down. 7588 mCellAgent.disconnect(); 7589 mWiFiAgent.disconnect(); 7590 b.expectBroadcast(); 7591 7592 // Pinning takes effect even if the pinned network is the default when the pin is set... 7593 TestNetworkPinner.pin(mServiceContext, wifiRequest); 7594 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 7595 mWiFiAgent.connect(false); 7596 assertTrue(TestNetworkPinner.awaitPin(100)); 7597 assertPinnedToWifiWithWifiDefault(); 7598 7599 // ... and is maintained even when that network is no longer the default. 7600 b = expectConnectivityAction(1); 7601 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 7602 mCellAgent.connect(true); 7603 b.expectBroadcast(); 7604 assertPinnedToWifiWithCellDefault(); 7605 } 7606 7607 @Test 7608 public void testNetworkCallbackMaximum() throws Exception { 7609 final int MAX_REQUESTS = 100; 7610 final int CALLBACKS = 88; 7611 final int DIFF_INTENTS = 10; 7612 final int SAME_INTENTS = 10; 7613 final int SYSTEM_ONLY_MAX_REQUESTS = 250; 7614 // CALLBACKS + DIFF_INTENTS + 1 (same intent) 7615 // = MAX_REQUESTS - 1, since the capacity is MAX_REQUEST - 1. 7616 assertEquals(MAX_REQUESTS - 1, CALLBACKS + DIFF_INTENTS + 1); 7617 7618 NetworkRequest networkRequest = new NetworkRequest.Builder().build(); 7619 ArrayList<Object> registered = new ArrayList<>(); 7620 7621 for (int j = 0; j < CALLBACKS; j++) { 7622 final NetworkCallback cb = new NetworkCallback(); 7623 if (j < CALLBACKS / 2) { 7624 mCm.requestNetwork(networkRequest, cb); 7625 } else { 7626 mCm.registerNetworkCallback(networkRequest, cb); 7627 } 7628 registered.add(cb); 7629 } 7630 7631 // Since ConnectivityService will de-duplicate the request with the same intent, 7632 // register multiple times does not really increase multiple requests. 7633 final PendingIntent same_pi = PendingIntent.getBroadcast(mContext, 0 /* requestCode */, 7634 new Intent("same"), FLAG_IMMUTABLE); 7635 for (int j = 0; j < SAME_INTENTS; j++) { 7636 mCm.registerNetworkCallback(networkRequest, same_pi); 7637 // Wait for the requests with the same intent to be de-duplicated. Because 7638 // ConnectivityService side incrementCountOrThrow in binder, decrementCount in handler 7639 // thread, waitForIdle is needed to ensure decrementCount being invoked for same intent 7640 // requests before doing further tests. 7641 waitForIdle(); 7642 } 7643 for (int j = 0; j < SAME_INTENTS; j++) { 7644 mCm.requestNetwork(networkRequest, same_pi); 7645 // Wait for the requests with the same intent to be de-duplicated. 7646 // Refer to the reason above. 7647 waitForIdle(); 7648 } 7649 registered.add(same_pi); 7650 7651 for (int j = 0; j < DIFF_INTENTS; j++) { 7652 if (j < DIFF_INTENTS / 2) { 7653 final PendingIntent pi = PendingIntent.getBroadcast(mContext, 0 /* requestCode */, 7654 new Intent("a" + j), FLAG_IMMUTABLE); 7655 mCm.requestNetwork(networkRequest, pi); 7656 registered.add(pi); 7657 } else { 7658 final PendingIntent pi = PendingIntent.getBroadcast(mContext, 0 /* requestCode */, 7659 new Intent("b" + j), FLAG_IMMUTABLE); 7660 mCm.registerNetworkCallback(networkRequest, pi); 7661 registered.add(pi); 7662 } 7663 } 7664 7665 // Test that the limit is enforced when MAX_REQUESTS simultaneous requests are added. 7666 assertThrows(TooManyRequestsException.class, () -> 7667 mCm.requestNetwork(networkRequest, new NetworkCallback()) 7668 ); 7669 assertThrows(TooManyRequestsException.class, () -> 7670 mCm.registerNetworkCallback(networkRequest, new NetworkCallback()) 7671 ); 7672 assertThrows(TooManyRequestsException.class, () -> 7673 mCm.requestNetwork(networkRequest, 7674 PendingIntent.getBroadcast(mContext, 0 /* requestCode */, 7675 new Intent("c"), FLAG_IMMUTABLE)) 7676 ); 7677 assertThrows(TooManyRequestsException.class, () -> 7678 mCm.registerNetworkCallback(networkRequest, 7679 PendingIntent.getBroadcast(mContext, 0 /* requestCode */, 7680 new Intent("d"), FLAG_IMMUTABLE)) 7681 ); 7682 7683 // The system gets another SYSTEM_ONLY_MAX_REQUESTS slots. 7684 final Handler handler = new Handler(ConnectivityThread.getInstanceLooper()); 7685 withPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, () -> { 7686 ArrayList<NetworkCallback> systemRegistered = new ArrayList<>(); 7687 for (int i = 0; i < SYSTEM_ONLY_MAX_REQUESTS - 1; i++) { 7688 NetworkCallback cb = new NetworkCallback(); 7689 if (i % 2 == 0) { 7690 mCm.registerDefaultNetworkCallbackForUid(1000000 + i, cb, handler); 7691 } else { 7692 mCm.registerNetworkCallback(networkRequest, cb); 7693 } 7694 systemRegistered.add(cb); 7695 } 7696 waitForIdle(); 7697 7698 assertThrows(TooManyRequestsException.class, () -> 7699 mCm.registerDefaultNetworkCallbackForUid(1001042, new NetworkCallback(), 7700 handler)); 7701 assertThrows(TooManyRequestsException.class, () -> 7702 mCm.registerNetworkCallback(networkRequest, new NetworkCallback())); 7703 7704 for (NetworkCallback callback : systemRegistered) { 7705 mCm.unregisterNetworkCallback(callback); 7706 } 7707 waitForIdle(); // Wait for requests to be unregistered before giving up the permission. 7708 }); 7709 7710 for (Object o : registered) { 7711 if (o instanceof NetworkCallback) { 7712 mCm.unregisterNetworkCallback((NetworkCallback) o); 7713 } 7714 if (o instanceof PendingIntent) { 7715 mCm.unregisterNetworkCallback((PendingIntent) o); 7716 } 7717 } 7718 waitForIdle(); 7719 7720 // Test that the limit is not hit when MAX_REQUESTS requests are added and removed. 7721 for (int i = 0; i < MAX_REQUESTS; i++) { 7722 NetworkCallback networkCallback = new NetworkCallback(); 7723 mCm.requestNetwork(networkRequest, networkCallback); 7724 mCm.unregisterNetworkCallback(networkCallback); 7725 // While requestNetwork increases the count synchronously, unregister decreases it 7726 // asynchronously on a handler, so unregistering doesn't immediately free up 7727 // a slot : calling unregister-register when max requests are registered throws. 7728 // Potential fix : ConnectivityService catches TooManyRequestsException once when 7729 // creating NetworkRequestInfo and waits for handler thread (see 7730 // https://r.android.com/2707373 for impl). However, this complexity is not equal to 7731 // the issue ; the purpose of having "max requests" is only to help apps detect leaks. 7732 // Apps relying on exact enforcement or rapid request registration should reconsider. 7733 // 7734 // In this test, test thread registering all before handler thread decrements can cause 7735 // flakes. A single waitForIdle at (e.g.) MAX_REQUESTS / 2 processes decrements up to 7736 // that point, fixing the flake. 7737 if (MAX_REQUESTS / 2 == i) waitForIdle(); 7738 } 7739 waitForIdle(); 7740 7741 for (int i = 0; i < MAX_REQUESTS; i++) { 7742 NetworkCallback networkCallback = new NetworkCallback(); 7743 mCm.registerNetworkCallback(networkRequest, networkCallback); 7744 mCm.unregisterNetworkCallback(networkCallback); 7745 // See comment above for the reasons for this wait. 7746 if (MAX_REQUESTS / 2 == i) waitForIdle(); 7747 } 7748 waitForIdle(); 7749 7750 for (int i = 0; i < MAX_REQUESTS; i++) { 7751 NetworkCallback networkCallback = new NetworkCallback(); 7752 mCm.registerDefaultNetworkCallback(networkCallback); 7753 mCm.unregisterNetworkCallback(networkCallback); 7754 // See comment above for the reasons for this wait. 7755 if (MAX_REQUESTS / 2 == i) waitForIdle(); 7756 } 7757 waitForIdle(); 7758 7759 for (int i = 0; i < MAX_REQUESTS; i++) { 7760 NetworkCallback networkCallback = new NetworkCallback(); 7761 mCm.registerDefaultNetworkCallback(networkCallback); 7762 mCm.unregisterNetworkCallback(networkCallback); 7763 // See comment above for the reasons for this wait. 7764 if (MAX_REQUESTS / 2 == i) waitForIdle(); 7765 } 7766 waitForIdle(); 7767 7768 withPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, () -> { 7769 for (int i = 0; i < MAX_REQUESTS; i++) { 7770 NetworkCallback networkCallback = new NetworkCallback(); 7771 mCm.registerDefaultNetworkCallbackForUid(1000000 + i, networkCallback, 7772 new Handler(ConnectivityThread.getInstanceLooper())); 7773 mCm.unregisterNetworkCallback(networkCallback); 7774 // See comment above for the reasons for this wait. 7775 if (MAX_REQUESTS / 2 == i) waitForIdle(); 7776 } 7777 }); 7778 waitForIdle(); 7779 7780 for (int i = 0; i < MAX_REQUESTS; i++) { 7781 final PendingIntent pendingIntent = PendingIntent.getBroadcast( 7782 mContext, 0 /* requestCode */, new Intent("e" + i), FLAG_IMMUTABLE); 7783 mCm.requestNetwork(networkRequest, pendingIntent); 7784 mCm.unregisterNetworkCallback(pendingIntent); 7785 // See comment above for the reasons for this wait. 7786 if (MAX_REQUESTS / 2 == i) waitForIdle(); 7787 } 7788 waitForIdle(); 7789 7790 for (int i = 0; i < MAX_REQUESTS; i++) { 7791 final PendingIntent pendingIntent = PendingIntent.getBroadcast( 7792 mContext, 0 /* requestCode */, new Intent("f" + i), FLAG_IMMUTABLE); 7793 mCm.registerNetworkCallback(networkRequest, pendingIntent); 7794 mCm.unregisterNetworkCallback(pendingIntent); 7795 // See comment above for the reasons for this wait. 7796 if (MAX_REQUESTS / 2 == i) waitForIdle(); 7797 } 7798 } 7799 7800 @Test 7801 public void testNetworkInfoOfTypeNone() throws Exception { 7802 ExpectedBroadcast b = expectConnectivityAction(1); 7803 7804 verifyNoNetwork(); 7805 TestNetworkAgentWrapper wifiAware = new TestNetworkAgentWrapper(TRANSPORT_WIFI_AWARE); 7806 assertNull(mCm.getActiveNetworkInfo()); 7807 7808 Network[] allNetworks = mCm.getAllNetworks(); 7809 assertLength(1, allNetworks); 7810 Network network = allNetworks[0]; 7811 NetworkCapabilities capabilities = mCm.getNetworkCapabilities(network); 7812 assertTrue(capabilities.hasTransport(TRANSPORT_WIFI_AWARE)); 7813 7814 final NetworkRequest request = 7815 new NetworkRequest.Builder().addTransportType(TRANSPORT_WIFI_AWARE).build(); 7816 final TestNetworkCallback callback = new TestNetworkCallback(); 7817 mCm.registerNetworkCallback(request, callback); 7818 7819 // Bring up wifi aware network. 7820 wifiAware.connect(false, false, false /* privateDnsProbeSent */); 7821 callback.expectAvailableCallbacksUnvalidated(wifiAware); 7822 7823 assertNull(mCm.getActiveNetworkInfo()); 7824 assertNull(mCm.getActiveNetwork()); 7825 // TODO: getAllNetworkInfo is dirty and returns a non-empty array right from the start 7826 // of this test. Fix it and uncomment the assert below. 7827 //assertEmpty(mCm.getAllNetworkInfo()); 7828 7829 // Disconnect wifi aware network. 7830 wifiAware.disconnect(); 7831 callback.expect(LOST, TIMEOUT_MS); 7832 mCm.unregisterNetworkCallback(callback); 7833 7834 verifyNoNetwork(); 7835 b.expectNoBroadcast(10); 7836 } 7837 7838 @Test 7839 public void testDeprecatedAndUnsupportedOperations() throws Exception { 7840 final int TYPE_NONE = ConnectivityManager.TYPE_NONE; 7841 assertNull(mCm.getNetworkInfo(TYPE_NONE)); 7842 assertNull(mCm.getNetworkForType(TYPE_NONE)); 7843 assertNull(mCm.getLinkProperties(TYPE_NONE)); 7844 assertFalse(mCm.isNetworkSupported(TYPE_NONE)); 7845 7846 assertThrows(IllegalArgumentException.class, 7847 () -> mCm.networkCapabilitiesForType(TYPE_NONE)); 7848 7849 Class<UnsupportedOperationException> unsupported = UnsupportedOperationException.class; 7850 assertThrows(unsupported, () -> mCm.startUsingNetworkFeature(TYPE_WIFI, "")); 7851 assertThrows(unsupported, () -> mCm.stopUsingNetworkFeature(TYPE_WIFI, "")); 7852 // TODO: let test context have configuration application target sdk version 7853 // and test that pre-M requesting for TYPE_NONE sends back APN_REQUEST_FAILED 7854 assertThrows(unsupported, () -> mCm.startUsingNetworkFeature(TYPE_NONE, "")); 7855 assertThrows(unsupported, () -> mCm.stopUsingNetworkFeature(TYPE_NONE, "")); 7856 assertThrows(unsupported, () -> mCm.requestRouteToHostAddress(TYPE_NONE, null)); 7857 } 7858 7859 @Test 7860 public void testLinkPropertiesEnsuresDirectlyConnectedRoutes() throws Exception { 7861 final NetworkRequest networkRequest = new NetworkRequest.Builder() 7862 .addTransportType(TRANSPORT_WIFI).build(); 7863 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 7864 mCm.registerNetworkCallback(networkRequest, networkCallback); 7865 7866 LinkProperties lp = new LinkProperties(); 7867 lp.setInterfaceName(WIFI_IFNAME); 7868 LinkAddress myIpv4Address = new LinkAddress("192.168.12.3/24"); 7869 RouteInfo myIpv4DefaultRoute = new RouteInfo((IpPrefix) null, 7870 InetAddresses.parseNumericAddress("192.168.12.1"), lp.getInterfaceName()); 7871 lp.addLinkAddress(myIpv4Address); 7872 lp.addRoute(myIpv4DefaultRoute); 7873 7874 // Verify direct routes are added when network agent is first registered in 7875 // ConnectivityService. 7876 TestNetworkAgentWrapper networkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, lp); 7877 networkAgent.connect(true); 7878 networkCallback.expect(AVAILABLE, networkAgent); 7879 networkCallback.expect(NETWORK_CAPS_UPDATED, networkAgent); 7880 CallbackEntry.LinkPropertiesChanged cbi = 7881 networkCallback.expect(LINK_PROPERTIES_CHANGED, networkAgent); 7882 networkCallback.expect(BLOCKED_STATUS, networkAgent); 7883 networkCallback.expectCaps(networkAgent, c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 7884 networkCallback.assertNoCallback(); 7885 checkDirectlyConnectedRoutes(cbi.getLp(), asList(myIpv4Address), 7886 asList(myIpv4DefaultRoute)); 7887 checkDirectlyConnectedRoutes(mCm.getLinkProperties(networkAgent.getNetwork()), 7888 asList(myIpv4Address), asList(myIpv4DefaultRoute)); 7889 7890 // Verify direct routes are added during subsequent link properties updates. 7891 LinkProperties newLp = new LinkProperties(lp); 7892 LinkAddress myIpv6Address1 = new LinkAddress("fe80::cafe/64"); 7893 LinkAddress myIpv6Address2 = new LinkAddress("2001:db8::2/64"); 7894 newLp.addLinkAddress(myIpv6Address1); 7895 newLp.addLinkAddress(myIpv6Address2); 7896 networkAgent.sendLinkProperties(newLp); 7897 cbi = networkCallback.expect(LINK_PROPERTIES_CHANGED, networkAgent); 7898 networkCallback.assertNoCallback(); 7899 checkDirectlyConnectedRoutes(cbi.getLp(), 7900 asList(myIpv4Address, myIpv6Address1, myIpv6Address2), 7901 asList(myIpv4DefaultRoute)); 7902 mCm.unregisterNetworkCallback(networkCallback); 7903 } 7904 7905 private void expectNotifyNetworkStatus(List<Network> allNetworks, List<Network> defaultNetworks, 7906 String defaultIface, Integer vpnUid, String vpnIfname, List<String> underlyingIfaces) 7907 throws Exception { 7908 ArgumentCaptor<List<Network>> defaultNetworksCaptor = ArgumentCaptor.forClass(List.class); 7909 ArgumentCaptor<List<UnderlyingNetworkInfo>> vpnInfosCaptor = 7910 ArgumentCaptor.forClass(List.class); 7911 ArgumentCaptor<List<NetworkStateSnapshot>> snapshotsCaptor = 7912 ArgumentCaptor.forClass(List.class); 7913 7914 verify(mStatsManager, atLeastOnce()).notifyNetworkStatus(defaultNetworksCaptor.capture(), 7915 snapshotsCaptor.capture(), eq(defaultIface), vpnInfosCaptor.capture()); 7916 7917 assertSameElements(defaultNetworks, defaultNetworksCaptor.getValue()); 7918 7919 List<Network> snapshotNetworks = new ArrayList<Network>(); 7920 for (NetworkStateSnapshot ns : snapshotsCaptor.getValue()) { 7921 snapshotNetworks.add(ns.getNetwork()); 7922 } 7923 assertSameElements(allNetworks, snapshotNetworks); 7924 7925 if (defaultIface != null) { 7926 assertNotNull( 7927 "Did not find interface " + defaultIface + " in call to notifyNetworkStatus", 7928 CollectionUtils.findFirst(snapshotsCaptor.getValue(), (ns) -> { 7929 final LinkProperties lp = ns.getLinkProperties(); 7930 if (lp != null && TextUtils.equals(defaultIface, lp.getInterfaceName())) { 7931 return true; 7932 } 7933 return false; 7934 })); 7935 } 7936 7937 List<UnderlyingNetworkInfo> infos = vpnInfosCaptor.getValue(); 7938 if (vpnUid != null) { 7939 assertEquals("Should have exactly one VPN:", 1, infos.size()); 7940 UnderlyingNetworkInfo info = infos.get(0); 7941 assertEquals("Unexpected VPN owner:", (int) vpnUid, info.getOwnerUid()); 7942 assertEquals("Unexpected VPN interface:", vpnIfname, info.getInterface()); 7943 assertSameElements(underlyingIfaces, info.getUnderlyingInterfaces()); 7944 } else { 7945 assertEquals(0, infos.size()); 7946 return; 7947 } 7948 } 7949 7950 private void expectNotifyNetworkStatus( 7951 List<Network> allNetworks, List<Network> defaultNetworks, String defaultIface) 7952 throws Exception { 7953 expectNotifyNetworkStatus(allNetworks, defaultNetworks, defaultIface, null, null, 7954 List.of()); 7955 } 7956 7957 private List<Network> onlyCell() { 7958 return List.of(mCellAgent.getNetwork()); 7959 } 7960 7961 private List<Network> onlyWifi() { 7962 return List.of(mWiFiAgent.getNetwork()); 7963 } 7964 7965 private List<Network> cellAndWifi() { 7966 return List.of(mCellAgent.getNetwork(), mWiFiAgent.getNetwork()); 7967 } 7968 7969 @Test 7970 public void testStatsIfacesChanged() throws Exception { 7971 LinkProperties cellLp = new LinkProperties(); 7972 cellLp.setInterfaceName(MOBILE_IFNAME); 7973 LinkProperties wifiLp = new LinkProperties(); 7974 wifiLp.setInterfaceName(WIFI_IFNAME); 7975 7976 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp); 7977 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 7978 7979 // Simple connection with initial LP should have updated ifaces. 7980 mCellAgent.connect(false); 7981 waitForIdle(); 7982 List<Network> allNetworks = mService.shouldCreateNetworksImmediately( 7983 mCellAgent.getNetworkCapabilities()) ? cellAndWifi() : onlyCell(); 7984 expectNotifyNetworkStatus(allNetworks, onlyCell(), MOBILE_IFNAME); 7985 reset(mStatsManager); 7986 7987 // Verify change fields other than interfaces does not trigger a notification to NSS. 7988 cellLp.addLinkAddress(new LinkAddress("192.0.2.4/24")); 7989 cellLp.addRoute(new RouteInfo((IpPrefix) null, InetAddress.getByName("192.0.2.4"), 7990 MOBILE_IFNAME)); 7991 cellLp.setDnsServers(List.of(InetAddress.getAllByName("8.8.8.8"))); 7992 mCellAgent.sendLinkProperties(cellLp); 7993 verifyNoMoreInteractions(mStatsManager); 7994 reset(mStatsManager); 7995 7996 // Default network switch should update ifaces. 7997 mWiFiAgent.connect(false); 7998 mWiFiAgent.sendLinkProperties(wifiLp); 7999 waitForIdle(); 8000 assertEquals(wifiLp, mService.getActiveLinkProperties()); 8001 expectNotifyNetworkStatus(cellAndWifi(), onlyWifi(), WIFI_IFNAME); 8002 reset(mStatsManager); 8003 8004 // Disconnecting a network updates ifaces again. The soon-to-be disconnected interface is 8005 // still in the list to ensure that stats are counted on that interface. 8006 // TODO: this means that if anything else uses that interface for any other reason before 8007 // notifyNetworkStatus is called again, traffic on that interface will be accounted to the 8008 // disconnected network. This is likely a bug in ConnectivityService; it should probably 8009 // call notifyNetworkStatus again without the disconnected network. 8010 mCellAgent.disconnect(); 8011 waitForIdle(); 8012 expectNotifyNetworkStatus(cellAndWifi(), onlyWifi(), WIFI_IFNAME); 8013 verifyNoMoreInteractions(mStatsManager); 8014 reset(mStatsManager); 8015 8016 // Connecting a network updates ifaces even if the network doesn't become default. 8017 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp); 8018 mCellAgent.connect(false); 8019 waitForIdle(); 8020 expectNotifyNetworkStatus(cellAndWifi(), onlyWifi(), WIFI_IFNAME); 8021 reset(mStatsManager); 8022 8023 // Disconnect should update ifaces. 8024 mWiFiAgent.disconnect(); 8025 waitForIdle(); 8026 expectNotifyNetworkStatus(onlyCell(), onlyCell(), MOBILE_IFNAME); 8027 reset(mStatsManager); 8028 8029 // Metered change should update ifaces 8030 mCellAgent.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED); 8031 waitForIdle(); 8032 expectNotifyNetworkStatus(onlyCell(), onlyCell(), MOBILE_IFNAME); 8033 reset(mStatsManager); 8034 8035 mCellAgent.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED); 8036 waitForIdle(); 8037 expectNotifyNetworkStatus(onlyCell(), onlyCell(), MOBILE_IFNAME); 8038 reset(mStatsManager); 8039 8040 // Temp metered change shouldn't update ifaces 8041 mCellAgent.addCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED); 8042 waitForIdle(); 8043 verify(mStatsManager, never()).notifyNetworkStatus(eq(onlyCell()), 8044 any(List.class), eq(MOBILE_IFNAME), any(List.class)); 8045 reset(mStatsManager); 8046 8047 // Congested change shouldn't update ifaces 8048 mCellAgent.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED); 8049 waitForIdle(); 8050 verify(mStatsManager, never()).notifyNetworkStatus(eq(onlyCell()), 8051 any(List.class), eq(MOBILE_IFNAME), any(List.class)); 8052 reset(mStatsManager); 8053 8054 // Roaming change should update ifaces 8055 mCellAgent.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING); 8056 waitForIdle(); 8057 expectNotifyNetworkStatus(onlyCell(), onlyCell(), MOBILE_IFNAME); 8058 reset(mStatsManager); 8059 8060 // Test VPNs. 8061 final LinkProperties lp = new LinkProperties(); 8062 lp.setInterfaceName(VPN_IFNAME); 8063 8064 mMockVpn.establishForMyUid(lp); 8065 assertUidRangesUpdatedForMyUid(true); 8066 8067 final List<Network> cellAndVpn = List.of(mCellAgent.getNetwork(), mMockVpn.getNetwork()); 8068 8069 // A VPN with default (null) underlying networks sets the underlying network's interfaces... 8070 expectNotifyNetworkStatus(cellAndVpn, cellAndVpn, MOBILE_IFNAME, Process.myUid(), 8071 VPN_IFNAME, List.of(MOBILE_IFNAME)); 8072 8073 // ...and updates them as the default network switches. 8074 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 8075 mWiFiAgent.connect(false); 8076 mWiFiAgent.sendLinkProperties(wifiLp); 8077 final Network[] onlyNull = new Network[]{null}; 8078 final List<Network> wifiAndVpn = List.of(mWiFiAgent.getNetwork(), mMockVpn.getNetwork()); 8079 final List<Network> cellWifiAndVpn = List.of(mCellAgent.getNetwork(), 8080 mWiFiAgent.getNetwork(), mMockVpn.getNetwork()); 8081 final Network[] cellNullAndWifi = 8082 new Network[] { mCellAgent.getNetwork(), null, mWiFiAgent.getNetwork() }; 8083 8084 waitForIdle(); 8085 assertEquals(wifiLp, mService.getActiveLinkProperties()); 8086 expectNotifyNetworkStatus(cellWifiAndVpn, wifiAndVpn, WIFI_IFNAME, Process.myUid(), 8087 VPN_IFNAME, List.of(WIFI_IFNAME)); 8088 reset(mStatsManager); 8089 8090 // A VPN that sets its underlying networks passes the underlying interfaces, and influences 8091 // the default interface sent to NetworkStatsService by virtue of applying to the system 8092 // server UID (or, in this test, to the test's UID). This is the reason for sending 8093 // MOBILE_IFNAME even though the default network is wifi. 8094 // TODO: fix this to pass in the actual default network interface. Whether or not the VPN 8095 // applies to the system server UID should not have any bearing on network stats. 8096 mMockVpn.setUnderlyingNetworks(onlyCell().toArray(new Network[0])); 8097 waitForIdle(); 8098 expectNotifyNetworkStatus(cellWifiAndVpn, wifiAndVpn, MOBILE_IFNAME, Process.myUid(), 8099 VPN_IFNAME, List.of(MOBILE_IFNAME)); 8100 reset(mStatsManager); 8101 8102 mMockVpn.setUnderlyingNetworks(cellAndWifi().toArray(new Network[0])); 8103 waitForIdle(); 8104 expectNotifyNetworkStatus(cellWifiAndVpn, wifiAndVpn, MOBILE_IFNAME, Process.myUid(), 8105 VPN_IFNAME, List.of(MOBILE_IFNAME, WIFI_IFNAME)); 8106 reset(mStatsManager); 8107 8108 // Null underlying networks are ignored. 8109 mMockVpn.setUnderlyingNetworks(cellNullAndWifi); 8110 waitForIdle(); 8111 expectNotifyNetworkStatus(cellWifiAndVpn, wifiAndVpn, MOBILE_IFNAME, Process.myUid(), 8112 VPN_IFNAME, List.of(MOBILE_IFNAME, WIFI_IFNAME)); 8113 reset(mStatsManager); 8114 8115 // If an underlying network disconnects, that interface should no longer be underlying. 8116 // This doesn't actually work because disconnectAndDestroyNetwork only notifies 8117 // NetworkStatsService before the underlying network is actually removed. So the underlying 8118 // network will only be removed if notifyIfacesChangedForNetworkStats is called again. This 8119 // could result in incorrect data usage measurements if the interface used by the 8120 // disconnected network is reused by a system component that does not register an agent for 8121 // it (e.g., tethering). 8122 mCellAgent.disconnect(); 8123 waitForIdle(); 8124 assertNull(mService.getLinkProperties(mCellAgent.getNetwork())); 8125 expectNotifyNetworkStatus(cellWifiAndVpn, wifiAndVpn, MOBILE_IFNAME, Process.myUid(), 8126 VPN_IFNAME, List.of(MOBILE_IFNAME, WIFI_IFNAME)); 8127 8128 // Confirm that we never tell NetworkStatsService that cell is no longer the underlying 8129 // network for the VPN... 8130 verify(mStatsManager, never()).notifyNetworkStatus(any(List.class), 8131 any(List.class), any() /* anyString() doesn't match null */, 8132 argThat(infos -> infos.get(0).getUnderlyingInterfaces().size() == 1 8133 && WIFI_IFNAME.equals(infos.get(0).getUnderlyingInterfaces().get(0)))); 8134 verifyNoMoreInteractions(mStatsManager); 8135 reset(mStatsManager); 8136 8137 // ... but if something else happens that causes notifyIfacesChangedForNetworkStats to be 8138 // called again, it does. For example, connect Ethernet, but with a low score, such that it 8139 // does not become the default network. 8140 mEthernetAgent = new TestNetworkAgentWrapper(TRANSPORT_ETHERNET); 8141 mEthernetAgent.setScore( 8142 new NetworkScore.Builder().setLegacyInt(30).setExiting(true).build()); 8143 mEthernetAgent.connect(false); 8144 waitForIdle(); 8145 verify(mStatsManager).notifyNetworkStatus(any(List.class), 8146 any(List.class), any() /* anyString() doesn't match null */, 8147 argThat(vpnInfos -> vpnInfos.get(0).getUnderlyingInterfaces().size() == 1 8148 && WIFI_IFNAME.equals(vpnInfos.get(0).getUnderlyingInterfaces().get(0)))); 8149 mEthernetAgent.disconnect(); 8150 waitForIdle(); 8151 reset(mStatsManager); 8152 8153 // When a VPN declares no underlying networks (i.e., no connectivity), getAllVpnInfo 8154 // does not return the VPN, so CS does not pass it to NetworkStatsService. This causes 8155 // NetworkStatsFactory#adjustForTunAnd464Xlat not to attempt any VPN data migration, which 8156 // is probably a performance improvement (though it's very unlikely that a VPN would declare 8157 // no underlying networks). 8158 // Also, for the same reason as above, the active interface passed in is null. 8159 mMockVpn.setUnderlyingNetworks(new Network[0]); 8160 waitForIdle(); 8161 expectNotifyNetworkStatus(wifiAndVpn, wifiAndVpn, null); 8162 reset(mStatsManager); 8163 8164 // Specifying only a null underlying network is the same as no networks. 8165 mMockVpn.setUnderlyingNetworks(onlyNull); 8166 waitForIdle(); 8167 expectNotifyNetworkStatus(wifiAndVpn, wifiAndVpn, null); 8168 reset(mStatsManager); 8169 8170 // Specifying networks that are all disconnected is the same as specifying no networks. 8171 mMockVpn.setUnderlyingNetworks(onlyCell().toArray(new Network[0])); 8172 waitForIdle(); 8173 expectNotifyNetworkStatus(wifiAndVpn, wifiAndVpn, null); 8174 reset(mStatsManager); 8175 8176 // Passing in null again means follow the default network again. 8177 mMockVpn.setUnderlyingNetworks(null); 8178 waitForIdle(); 8179 expectNotifyNetworkStatus(wifiAndVpn, wifiAndVpn, WIFI_IFNAME, Process.myUid(), VPN_IFNAME, 8180 List.of(WIFI_IFNAME)); 8181 reset(mStatsManager); 8182 } 8183 8184 @Test 8185 public void testAdminUidsRedacted() throws Exception { 8186 final int[] adminUids = new int[] {Process.myUid() + 1}; 8187 final NetworkCapabilities ncTemplate = new NetworkCapabilities(); 8188 ncTemplate.setAdministratorUids(adminUids); 8189 mCellAgent = 8190 new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, new LinkProperties(), ncTemplate); 8191 mCellAgent.connect(false /* validated */); 8192 8193 // Verify case where caller has permission 8194 mServiceContext.setPermission( 8195 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, PERMISSION_GRANTED); 8196 TestNetworkCallback callback = new TestNetworkCallback(); 8197 mCm.registerDefaultNetworkCallback(callback); 8198 callback.expect(AVAILABLE, mCellAgent); 8199 callback.expectCaps(mCellAgent, c -> Arrays.equals(adminUids, c.getAdministratorUids())); 8200 mCm.unregisterNetworkCallback(callback); 8201 8202 // Verify case where caller does NOT have permission 8203 mServiceContext.setPermission( 8204 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, PERMISSION_DENIED); 8205 mServiceContext.setPermission(NETWORK_STACK, PERMISSION_DENIED); 8206 callback = new TestNetworkCallback(); 8207 mCm.registerDefaultNetworkCallback(callback); 8208 callback.expect(AVAILABLE, mCellAgent); 8209 callback.expectCaps(mCellAgent, c -> c.getAdministratorUids().length == 0); 8210 } 8211 8212 @Test 8213 public void testNonVpnUnderlyingNetworks() throws Exception { 8214 // Ensure wifi and cellular are not torn down. 8215 for (int transport : new int[]{TRANSPORT_CELLULAR, TRANSPORT_WIFI}) { 8216 final NetworkRequest request = new NetworkRequest.Builder() 8217 .addTransportType(transport) 8218 .removeCapability(NET_CAPABILITY_NOT_VCN_MANAGED) 8219 .build(); 8220 mCm.requestNetwork(request, new NetworkCallback()); 8221 } 8222 8223 // Connect a VCN-managed wifi network. 8224 final LinkProperties wifiLp = new LinkProperties(); 8225 wifiLp.setInterfaceName(WIFI_IFNAME); 8226 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, wifiLp); 8227 mWiFiAgent.removeCapability(NET_CAPABILITY_NOT_VCN_MANAGED); 8228 mWiFiAgent.addCapability(NET_CAPABILITY_NOT_METERED); 8229 mWiFiAgent.connect(true /* validated */); 8230 8231 final List<Network> none = List.of(); 8232 expectNotifyNetworkStatus(onlyWifi(), none, null); // Wifi is not the default network 8233 8234 // Create a virtual network based on the wifi network. 8235 final int ownerUid = 10042; 8236 NetworkCapabilities nc = new NetworkCapabilities.Builder() 8237 .setOwnerUid(ownerUid) 8238 .setAdministratorUids(new int[]{ownerUid}) 8239 .build(); 8240 final String vcnIface = "ipsec42"; 8241 final LinkProperties lp = new LinkProperties(); 8242 lp.setInterfaceName(vcnIface); 8243 final TestNetworkAgentWrapper vcn = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, lp, nc); 8244 vcn.setUnderlyingNetworks(List.of(mWiFiAgent.getNetwork())); 8245 vcn.connect(false /* validated */); 8246 8247 final TestNetworkCallback callback = new TestNetworkCallback(); 8248 mCm.registerDefaultNetworkCallback(callback); 8249 callback.expectAvailableCallbacksUnvalidated(vcn); 8250 8251 // The underlying wifi network's capabilities are not propagated to the virtual network, 8252 // but NetworkStatsService is informed of the underlying interface. 8253 nc = mCm.getNetworkCapabilities(vcn.getNetwork()); 8254 assertFalse(nc.hasTransport(TRANSPORT_WIFI)); 8255 assertFalse(nc.hasCapability(NET_CAPABILITY_NOT_METERED)); 8256 final List<Network> onlyVcn = List.of(vcn.getNetwork()); 8257 final List<Network> vcnAndWifi = List.of(vcn.getNetwork(), mWiFiAgent.getNetwork()); 8258 expectNotifyNetworkStatus(vcnAndWifi, onlyVcn, vcnIface, ownerUid, vcnIface, 8259 List.of(WIFI_IFNAME)); 8260 8261 // Add NOT_METERED to the underlying network, check that it is not propagated. 8262 mWiFiAgent.addCapability(NET_CAPABILITY_NOT_METERED); 8263 callback.assertNoCallback(); 8264 nc = mCm.getNetworkCapabilities(vcn.getNetwork()); 8265 assertFalse(nc.hasCapability(NET_CAPABILITY_NOT_METERED)); 8266 8267 // Switch underlying networks. 8268 final LinkProperties cellLp = new LinkProperties(); 8269 cellLp.setInterfaceName(MOBILE_IFNAME); 8270 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp); 8271 mCellAgent.removeCapability(NET_CAPABILITY_NOT_VCN_MANAGED); 8272 mCellAgent.addCapability(NET_CAPABILITY_NOT_ROAMING); 8273 mCellAgent.connect(false /* validated */); 8274 vcn.setUnderlyingNetworks(List.of(mCellAgent.getNetwork())); 8275 8276 // The underlying capability changes do not propagate to the virtual network, but 8277 // NetworkStatsService is informed of the new underlying interface. 8278 callback.assertNoCallback(); 8279 nc = mCm.getNetworkCapabilities(vcn.getNetwork()); 8280 assertFalse(nc.hasTransport(TRANSPORT_WIFI)); 8281 assertFalse(nc.hasCapability(NET_CAPABILITY_NOT_ROAMING)); 8282 final List<Network> vcnWifiAndCell = List.of(vcn.getNetwork(), 8283 mWiFiAgent.getNetwork(), mCellAgent.getNetwork()); 8284 expectNotifyNetworkStatus(vcnWifiAndCell, onlyVcn, vcnIface, ownerUid, vcnIface, 8285 List.of(MOBILE_IFNAME)); 8286 } 8287 8288 @Test 8289 public void testBasicDnsConfigurationPushed() throws Exception { 8290 setPrivateDnsSettings(PRIVATE_DNS_MODE_OPPORTUNISTIC, "ignored.example.com"); 8291 8292 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 8293 final int netId = mCellAgent.getNetwork().netId; 8294 waitForIdle(); 8295 if (mService.shouldCreateNetworksImmediately(mCellAgent.getNetworkCapabilities())) { 8296 verify(mMockDnsResolver, times(1)).createNetworkCache(netId); 8297 } else { 8298 verify(mMockDnsResolver, never()).setResolverConfiguration(any()); 8299 } 8300 8301 final LinkProperties cellLp = new LinkProperties(); 8302 cellLp.setInterfaceName(MOBILE_IFNAME); 8303 // Add IPv4 and IPv6 default routes, because DNS-over-TLS code does 8304 // "is-reachable" testing in order to not program netd with unreachable 8305 // nameservers that it might try repeated to validate. 8306 cellLp.addLinkAddress(new LinkAddress("192.0.2.4/24")); 8307 cellLp.addRoute(new RouteInfo((IpPrefix) null, InetAddress.getByName("192.0.2.4"), 8308 MOBILE_IFNAME)); 8309 cellLp.addLinkAddress(new LinkAddress("2001:db8:1::1/64")); 8310 cellLp.addRoute(new RouteInfo((IpPrefix) null, InetAddress.getByName("2001:db8:1::1"), 8311 MOBILE_IFNAME)); 8312 mCellAgent.sendLinkProperties(cellLp); 8313 mCellAgent.connect(false); 8314 waitForIdle(); 8315 if (!mService.shouldCreateNetworksImmediately(mCellAgent.getNetworkCapabilities())) { 8316 // CS tells dnsresolver about the empty DNS config for this network. 8317 verify(mMockDnsResolver, times(1)).createNetworkCache(netId); 8318 } 8319 verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration(any()); 8320 8321 verifyNoMoreInteractions(mMockDnsResolver); 8322 reset(mMockDnsResolver); 8323 8324 cellLp.addDnsServer(InetAddress.getByName("2001:db8::1")); 8325 mCellAgent.sendLinkProperties(cellLp); 8326 waitForIdle(); 8327 verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration( 8328 mResolverParamsParcelCaptor.capture()); 8329 ResolverParamsParcel resolvrParams = mResolverParamsParcelCaptor.getValue(); 8330 assertEquals(1, resolvrParams.servers.length); 8331 assertTrue(CollectionUtils.contains(resolvrParams.servers, "2001:db8::1")); 8332 // Opportunistic mode. 8333 assertTrue(CollectionUtils.contains(resolvrParams.tlsServers, "2001:db8::1")); 8334 reset(mMockDnsResolver); 8335 8336 cellLp.addDnsServer(InetAddress.getByName("192.0.2.1")); 8337 mCellAgent.sendLinkProperties(cellLp); 8338 waitForIdle(); 8339 verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration( 8340 mResolverParamsParcelCaptor.capture()); 8341 resolvrParams = mResolverParamsParcelCaptor.getValue(); 8342 assertEquals(2, resolvrParams.servers.length); 8343 assertTrue(new ArraySet<>(resolvrParams.servers).containsAll( 8344 asList("2001:db8::1", "192.0.2.1"))); 8345 // Opportunistic mode. 8346 assertEquals(2, resolvrParams.tlsServers.length); 8347 assertTrue(new ArraySet<>(resolvrParams.tlsServers).containsAll( 8348 asList("2001:db8::1", "192.0.2.1"))); 8349 reset(mMockDnsResolver); 8350 8351 final String TLS_SPECIFIER = "tls.example.com"; 8352 final String TLS_SERVER6 = "2001:db8:53::53"; 8353 final InetAddress[] TLS_IPS = new InetAddress[]{ InetAddress.getByName(TLS_SERVER6) }; 8354 final String[] TLS_SERVERS = new String[]{ TLS_SERVER6 }; 8355 mCellAgent.mNmCallbacks.notifyPrivateDnsConfigResolved( 8356 new PrivateDnsConfig(TLS_SPECIFIER, TLS_IPS).toParcel()); 8357 8358 waitForIdle(); 8359 verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration( 8360 mResolverParamsParcelCaptor.capture()); 8361 resolvrParams = mResolverParamsParcelCaptor.getValue(); 8362 assertEquals(2, resolvrParams.servers.length); 8363 assertTrue(new ArraySet<>(resolvrParams.servers).containsAll( 8364 asList("2001:db8::1", "192.0.2.1"))); 8365 reset(mMockDnsResolver); 8366 } 8367 8368 @Test 8369 public void testDnsConfigurationTransTypesPushed() throws Exception { 8370 final NetworkRequest request = new NetworkRequest.Builder() 8371 .clearCapabilities().addCapability(NET_CAPABILITY_INTERNET) 8372 .build(); 8373 final TestNetworkCallback callback = new TestNetworkCallback(); 8374 mCm.registerNetworkCallback(request, callback); 8375 8376 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 8377 mWiFiAgent.connect(false); 8378 callback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 8379 verify(mMockDnsResolver, times(1)).createNetworkCache(eq(mWiFiAgent.getNetwork().netId)); 8380 verify(mMockDnsResolver, times(2)).setResolverConfiguration( 8381 mResolverParamsParcelCaptor.capture()); 8382 final ResolverParamsParcel resolverParams = mResolverParamsParcelCaptor.getValue(); 8383 assertContainsExactly(resolverParams.transportTypes, TRANSPORT_WIFI); 8384 reset(mMockDnsResolver); 8385 } 8386 8387 @Test 8388 public void testPrivateDnsNotification() throws Exception { 8389 NetworkRequest request = new NetworkRequest.Builder() 8390 .clearCapabilities().addCapability(NET_CAPABILITY_INTERNET) 8391 .build(); 8392 TestNetworkCallback callback = new TestNetworkCallback(); 8393 mCm.registerNetworkCallback(request, callback); 8394 // Bring up wifi. 8395 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 8396 mWiFiAgent.connect(false); 8397 callback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 8398 // Private DNS resolution failed, checking if the notification will be shown or not. 8399 mWiFiAgent.setNetworkInvalid(true /* invalidBecauseOfPrivateDns */); 8400 mWiFiAgent.mNetworkMonitor.forceReevaluation(Process.myUid()); 8401 waitForIdle(); 8402 // If network validation failed, NetworkMonitor will re-evaluate the network. 8403 // ConnectivityService should filter the redundant notification. This part is trying to 8404 // simulate that situation and check if ConnectivityService could filter that case. 8405 mWiFiAgent.mNetworkMonitor.forceReevaluation(Process.myUid()); 8406 waitForIdle(); 8407 verify(mNotificationManager, timeout(TIMEOUT_MS).times(1)).notify(anyString(), 8408 eq(NotificationType.PRIVATE_DNS_BROKEN.eventId), any()); 8409 // If private DNS resolution successful, the PRIVATE_DNS_BROKEN notification shouldn't be 8410 // shown. 8411 mWiFiAgent.setNetworkValid(true /* privateDnsProbeSent */); 8412 mWiFiAgent.mNetworkMonitor.forceReevaluation(Process.myUid()); 8413 waitForIdle(); 8414 verify(mNotificationManager, timeout(TIMEOUT_MS).times(1)).cancel(anyString(), 8415 eq(NotificationType.PRIVATE_DNS_BROKEN.eventId)); 8416 // If private DNS resolution failed again, the PRIVATE_DNS_BROKEN notification should be 8417 // shown again. 8418 mWiFiAgent.setNetworkInvalid(true /* invalidBecauseOfPrivateDns */); 8419 mWiFiAgent.mNetworkMonitor.forceReevaluation(Process.myUid()); 8420 waitForIdle(); 8421 verify(mNotificationManager, timeout(TIMEOUT_MS).times(2)).notify(anyString(), 8422 eq(NotificationType.PRIVATE_DNS_BROKEN.eventId), any()); 8423 } 8424 8425 @Test 8426 public void testPrivateDnsSettingsChange() throws Exception { 8427 // The default on Android is opportunistic mode ("Automatic"). 8428 setPrivateDnsSettings(PRIVATE_DNS_MODE_OPPORTUNISTIC, "ignored.example.com"); 8429 8430 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback(); 8431 final NetworkRequest cellRequest = new NetworkRequest.Builder() 8432 .addTransportType(TRANSPORT_CELLULAR).build(); 8433 mCm.requestNetwork(cellRequest, cellNetworkCallback); 8434 8435 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 8436 final int netId = mCellAgent.getNetwork().netId; 8437 waitForIdle(); 8438 if (mService.shouldCreateNetworksImmediately(mCellAgent.getNetworkCapabilities())) { 8439 verify(mMockDnsResolver, times(1)).createNetworkCache(netId); 8440 } else { 8441 verify(mMockDnsResolver, never()).setResolverConfiguration(any()); 8442 } 8443 8444 final LinkProperties cellLp = new LinkProperties(); 8445 cellLp.setInterfaceName(MOBILE_IFNAME); 8446 // Add IPv4 and IPv6 default routes, because DNS-over-TLS code does 8447 // "is-reachable" testing in order to not program netd with unreachable 8448 // nameservers that it might try repeated to validate. 8449 cellLp.addLinkAddress(new LinkAddress("192.0.2.4/24")); 8450 cellLp.addRoute(new RouteInfo((IpPrefix) null, InetAddress.getByName("192.0.2.4"), 8451 MOBILE_IFNAME)); 8452 cellLp.addLinkAddress(new LinkAddress("2001:db8:1::1/64")); 8453 cellLp.addRoute(new RouteInfo((IpPrefix) null, InetAddress.getByName("2001:db8:1::1"), 8454 MOBILE_IFNAME)); 8455 cellLp.addDnsServer(InetAddress.getByName("2001:db8::1")); 8456 cellLp.addDnsServer(InetAddress.getByName("192.0.2.1")); 8457 8458 mCellAgent.sendLinkProperties(cellLp); 8459 mCellAgent.connect(false); 8460 waitForIdle(); 8461 if (!mService.shouldCreateNetworksImmediately(mCellAgent.getNetworkCapabilities())) { 8462 verify(mMockDnsResolver, times(1)).createNetworkCache(netId); 8463 } 8464 verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration( 8465 mResolverParamsParcelCaptor.capture()); 8466 ResolverParamsParcel resolvrParams = mResolverParamsParcelCaptor.getValue(); 8467 assertEquals(2, resolvrParams.tlsServers.length); 8468 assertTrue(new ArraySet<>(resolvrParams.tlsServers).containsAll( 8469 asList("2001:db8::1", "192.0.2.1"))); 8470 // Opportunistic mode. 8471 assertEquals(2, resolvrParams.tlsServers.length); 8472 assertTrue(new ArraySet<>(resolvrParams.tlsServers).containsAll( 8473 asList("2001:db8::1", "192.0.2.1"))); 8474 verifyNoMoreInteractions(mMockDnsResolver); 8475 reset(mMockDnsResolver); 8476 cellNetworkCallback.expect(AVAILABLE, mCellAgent); 8477 cellNetworkCallback.expect(NETWORK_CAPS_UPDATED, mCellAgent); 8478 CallbackEntry.LinkPropertiesChanged cbi = cellNetworkCallback.expect( 8479 LINK_PROPERTIES_CHANGED, mCellAgent); 8480 cellNetworkCallback.expect(BLOCKED_STATUS, mCellAgent); 8481 cellNetworkCallback.assertNoCallback(); 8482 assertFalse(cbi.getLp().isPrivateDnsActive()); 8483 assertNull(cbi.getLp().getPrivateDnsServerName()); 8484 8485 setPrivateDnsSettings(PRIVATE_DNS_MODE_OFF, "ignored.example.com"); 8486 verify(mMockDnsResolver, times(1)).setResolverConfiguration( 8487 mResolverParamsParcelCaptor.capture()); 8488 resolvrParams = mResolverParamsParcelCaptor.getValue(); 8489 assertEquals(2, resolvrParams.servers.length); 8490 assertTrue(new ArraySet<>(resolvrParams.servers).containsAll( 8491 asList("2001:db8::1", "192.0.2.1"))); 8492 reset(mMockDnsResolver); 8493 cellNetworkCallback.assertNoCallback(); 8494 8495 setPrivateDnsSettings(PRIVATE_DNS_MODE_OPPORTUNISTIC, "ignored.example.com"); 8496 verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration( 8497 mResolverParamsParcelCaptor.capture()); 8498 resolvrParams = mResolverParamsParcelCaptor.getValue(); 8499 assertEquals(2, resolvrParams.servers.length); 8500 assertTrue(new ArraySet<>(resolvrParams.servers).containsAll( 8501 asList("2001:db8::1", "192.0.2.1"))); 8502 assertEquals(2, resolvrParams.tlsServers.length); 8503 assertTrue(new ArraySet<>(resolvrParams.tlsServers).containsAll( 8504 asList("2001:db8::1", "192.0.2.1"))); 8505 reset(mMockDnsResolver); 8506 cellNetworkCallback.assertNoCallback(); 8507 8508 setPrivateDnsSettings(PRIVATE_DNS_MODE_PROVIDER_HOSTNAME, "strict.example.com"); 8509 // Can't test dns configuration for strict mode without properly mocking 8510 // out the DNS lookups, but can test that LinkProperties is updated. 8511 cbi = cellNetworkCallback.expect(LINK_PROPERTIES_CHANGED, mCellAgent); 8512 cellNetworkCallback.assertNoCallback(); 8513 assertTrue(cbi.getLp().isPrivateDnsActive()); 8514 assertEquals("strict.example.com", cbi.getLp().getPrivateDnsServerName()); 8515 } 8516 8517 private PrivateDnsValidationEventParcel makePrivateDnsValidationEvent( 8518 final int netId, final String ipAddress, final String hostname, final int validation) { 8519 final PrivateDnsValidationEventParcel event = new PrivateDnsValidationEventParcel(); 8520 event.netId = netId; 8521 event.ipAddress = ipAddress; 8522 event.hostname = hostname; 8523 event.validation = validation; 8524 return event; 8525 } 8526 8527 @Test 8528 public void testLinkPropertiesWithPrivateDnsValidationEvents() throws Exception { 8529 // The default on Android is opportunistic mode ("Automatic"). 8530 setPrivateDnsSettings(PRIVATE_DNS_MODE_OPPORTUNISTIC, "ignored.example.com"); 8531 8532 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback(); 8533 final NetworkRequest cellRequest = new NetworkRequest.Builder() 8534 .addTransportType(TRANSPORT_CELLULAR).build(); 8535 mCm.requestNetwork(cellRequest, cellNetworkCallback); 8536 8537 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 8538 waitForIdle(); 8539 LinkProperties lp = new LinkProperties(); 8540 mCellAgent.sendLinkProperties(lp); 8541 mCellAgent.connect(false); 8542 waitForIdle(); 8543 cellNetworkCallback.expect(AVAILABLE, mCellAgent); 8544 cellNetworkCallback.expect(NETWORK_CAPS_UPDATED, mCellAgent); 8545 CallbackEntry.LinkPropertiesChanged cbi = cellNetworkCallback.expect( 8546 LINK_PROPERTIES_CHANGED, mCellAgent); 8547 cellNetworkCallback.expect(BLOCKED_STATUS, mCellAgent); 8548 cellNetworkCallback.assertNoCallback(); 8549 assertFalse(cbi.getLp().isPrivateDnsActive()); 8550 assertNull(cbi.getLp().getPrivateDnsServerName()); 8551 Set<InetAddress> dnsServers = new HashSet<>(); 8552 checkDnsServers(cbi.getLp(), dnsServers); 8553 8554 // Send a validation event for a server that is not part of the current 8555 // resolver config. The validation event should be ignored. 8556 mService.mResolverUnsolEventCallback.onPrivateDnsValidationEvent( 8557 makePrivateDnsValidationEvent(mCellAgent.getNetwork().netId, "", 8558 "145.100.185.18", VALIDATION_RESULT_SUCCESS)); 8559 cellNetworkCallback.assertNoCallback(); 8560 8561 // Add a dns server to the LinkProperties. 8562 LinkProperties lp2 = new LinkProperties(lp); 8563 lp2.addDnsServer(InetAddress.getByName("145.100.185.16")); 8564 mCellAgent.sendLinkProperties(lp2); 8565 cbi = cellNetworkCallback.expect(LINK_PROPERTIES_CHANGED, mCellAgent); 8566 cellNetworkCallback.assertNoCallback(); 8567 assertFalse(cbi.getLp().isPrivateDnsActive()); 8568 assertNull(cbi.getLp().getPrivateDnsServerName()); 8569 dnsServers.add(InetAddress.getByName("145.100.185.16")); 8570 checkDnsServers(cbi.getLp(), dnsServers); 8571 8572 // Send a validation event containing a hostname that is not part of 8573 // the current resolver config. The validation event should be ignored. 8574 mService.mResolverUnsolEventCallback.onPrivateDnsValidationEvent( 8575 makePrivateDnsValidationEvent(mCellAgent.getNetwork().netId, 8576 "145.100.185.16", "hostname", VALIDATION_RESULT_SUCCESS)); 8577 cellNetworkCallback.assertNoCallback(); 8578 8579 // Send a validation event where validation failed. 8580 mService.mResolverUnsolEventCallback.onPrivateDnsValidationEvent( 8581 makePrivateDnsValidationEvent(mCellAgent.getNetwork().netId, 8582 "145.100.185.16", "", VALIDATION_RESULT_FAILURE)); 8583 cellNetworkCallback.assertNoCallback(); 8584 8585 // Send a validation event where validation succeeded for a server in 8586 // the current resolver config. A LinkProperties callback with updated 8587 // private dns fields should be sent. 8588 mService.mResolverUnsolEventCallback.onPrivateDnsValidationEvent( 8589 makePrivateDnsValidationEvent(mCellAgent.getNetwork().netId, 8590 "145.100.185.16", "", VALIDATION_RESULT_SUCCESS)); 8591 cbi = cellNetworkCallback.expect(LINK_PROPERTIES_CHANGED, mCellAgent); 8592 cellNetworkCallback.assertNoCallback(); 8593 assertTrue(cbi.getLp().isPrivateDnsActive()); 8594 assertNull(cbi.getLp().getPrivateDnsServerName()); 8595 checkDnsServers(cbi.getLp(), dnsServers); 8596 8597 // The private dns fields in LinkProperties should be preserved when 8598 // the network agent sends unrelated changes. 8599 LinkProperties lp3 = new LinkProperties(lp2); 8600 lp3.setMtu(1300); 8601 mCellAgent.sendLinkProperties(lp3); 8602 cbi = cellNetworkCallback.expect(LINK_PROPERTIES_CHANGED, mCellAgent); 8603 cellNetworkCallback.assertNoCallback(); 8604 assertTrue(cbi.getLp().isPrivateDnsActive()); 8605 assertNull(cbi.getLp().getPrivateDnsServerName()); 8606 checkDnsServers(cbi.getLp(), dnsServers); 8607 assertEquals(1300, cbi.getLp().getMtu()); 8608 8609 // Removing the only validated server should affect the private dns 8610 // fields in LinkProperties. 8611 LinkProperties lp4 = new LinkProperties(lp3); 8612 lp4.removeDnsServer(InetAddress.getByName("145.100.185.16")); 8613 mCellAgent.sendLinkProperties(lp4); 8614 cbi = cellNetworkCallback.expect(LINK_PROPERTIES_CHANGED, mCellAgent); 8615 cellNetworkCallback.assertNoCallback(); 8616 assertFalse(cbi.getLp().isPrivateDnsActive()); 8617 assertNull(cbi.getLp().getPrivateDnsServerName()); 8618 dnsServers.remove(InetAddress.getByName("145.100.185.16")); 8619 checkDnsServers(cbi.getLp(), dnsServers); 8620 assertEquals(1300, cbi.getLp().getMtu()); 8621 } 8622 8623 private void checkDirectlyConnectedRoutes(Object callbackObj, 8624 Collection<LinkAddress> linkAddresses, Collection<RouteInfo> otherRoutes) { 8625 assertTrue(callbackObj instanceof LinkProperties); 8626 LinkProperties lp = (LinkProperties) callbackObj; 8627 8628 Set<RouteInfo> expectedRoutes = new ArraySet<>(); 8629 expectedRoutes.addAll(otherRoutes); 8630 for (LinkAddress address : linkAddresses) { 8631 RouteInfo localRoute = new RouteInfo(address, null, lp.getInterfaceName()); 8632 // Duplicates in linkAddresses are considered failures 8633 assertTrue(expectedRoutes.add(localRoute)); 8634 } 8635 List<RouteInfo> observedRoutes = lp.getRoutes(); 8636 assertEquals(expectedRoutes.size(), observedRoutes.size()); 8637 assertTrue(observedRoutes.containsAll(expectedRoutes)); 8638 } 8639 8640 private static void checkDnsServers(Object callbackObj, Set<InetAddress> dnsServers) { 8641 assertTrue(callbackObj instanceof LinkProperties); 8642 LinkProperties lp = (LinkProperties) callbackObj; 8643 assertEquals(dnsServers.size(), lp.getDnsServers().size()); 8644 assertTrue(lp.getDnsServers().containsAll(dnsServers)); 8645 } 8646 8647 @Test 8648 public void testApplyUnderlyingCapabilities() throws Exception { 8649 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 8650 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 8651 mCellAgent.connect(false /* validated */); 8652 mWiFiAgent.connect(false /* validated */); 8653 8654 final NetworkCapabilities cellNc = new NetworkCapabilities() 8655 .addTransportType(TRANSPORT_CELLULAR) 8656 .addCapability(NET_CAPABILITY_INTERNET) 8657 .addCapability(NET_CAPABILITY_NOT_CONGESTED) 8658 .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED) 8659 .setLinkDownstreamBandwidthKbps(10); 8660 final NetworkCapabilities wifiNc = new NetworkCapabilities() 8661 .addTransportType(TRANSPORT_WIFI) 8662 .addCapability(NET_CAPABILITY_INTERNET) 8663 .addCapability(NET_CAPABILITY_NOT_METERED) 8664 .addCapability(NET_CAPABILITY_NOT_ROAMING) 8665 .addCapability(NET_CAPABILITY_NOT_CONGESTED) 8666 .addCapability(NET_CAPABILITY_NOT_SUSPENDED) 8667 .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED) 8668 .setLinkUpstreamBandwidthKbps(20); 8669 mCellAgent.setNetworkCapabilities(cellNc, true /* sendToConnectivityService */); 8670 mWiFiAgent.setNetworkCapabilities(wifiNc, true /* sendToConnectivityService */); 8671 waitForIdle(); 8672 8673 final Network mobile = mCellAgent.getNetwork(); 8674 final Network wifi = mWiFiAgent.getNetwork(); 8675 8676 final NetworkCapabilities initialCaps = new NetworkCapabilities(); 8677 initialCaps.addTransportType(TRANSPORT_VPN); 8678 initialCaps.addCapability(NET_CAPABILITY_INTERNET); 8679 initialCaps.removeCapability(NET_CAPABILITY_NOT_VPN); 8680 final ArrayList<Network> emptyUnderlyingNetworks = new ArrayList<Network>(); 8681 final ArrayList<Network> underlyingNetworksContainMobile = new ArrayList<Network>(); 8682 underlyingNetworksContainMobile.add(mobile); 8683 final ArrayList<Network> underlyingNetworksContainWifi = new ArrayList<Network>(); 8684 underlyingNetworksContainWifi.add(wifi); 8685 final ArrayList<Network> underlyingNetworksContainMobileAndMobile = 8686 new ArrayList<Network>(); 8687 underlyingNetworksContainMobileAndMobile.add(mobile); 8688 underlyingNetworksContainMobileAndMobile.add(wifi); 8689 8690 final NetworkCapabilities withNoUnderlying = new NetworkCapabilities(); 8691 withNoUnderlying.addCapability(NET_CAPABILITY_INTERNET); 8692 withNoUnderlying.addCapability(NET_CAPABILITY_NOT_CONGESTED); 8693 withNoUnderlying.addCapability(NET_CAPABILITY_NOT_ROAMING); 8694 withNoUnderlying.addCapability(NET_CAPABILITY_NOT_SUSPENDED); 8695 withNoUnderlying.addTransportType(TRANSPORT_VPN); 8696 withNoUnderlying.removeCapability(NET_CAPABILITY_NOT_VPN); 8697 withNoUnderlying.setUnderlyingNetworks(emptyUnderlyingNetworks); 8698 8699 final NetworkCapabilities withMobileUnderlying = new NetworkCapabilities(withNoUnderlying); 8700 withMobileUnderlying.addTransportType(TRANSPORT_CELLULAR); 8701 withMobileUnderlying.removeCapability(NET_CAPABILITY_NOT_ROAMING); 8702 withMobileUnderlying.removeCapability(NET_CAPABILITY_NOT_SUSPENDED); 8703 withMobileUnderlying.setLinkDownstreamBandwidthKbps(10); 8704 withMobileUnderlying.setUnderlyingNetworks(underlyingNetworksContainMobile); 8705 8706 final NetworkCapabilities withWifiUnderlying = new NetworkCapabilities(withNoUnderlying); 8707 withWifiUnderlying.addTransportType(TRANSPORT_WIFI); 8708 withWifiUnderlying.addCapability(NET_CAPABILITY_NOT_METERED); 8709 withWifiUnderlying.setLinkUpstreamBandwidthKbps(20); 8710 withWifiUnderlying.setUnderlyingNetworks(underlyingNetworksContainWifi); 8711 8712 final NetworkCapabilities withWifiAndMobileUnderlying = 8713 new NetworkCapabilities(withNoUnderlying); 8714 withWifiAndMobileUnderlying.addTransportType(TRANSPORT_CELLULAR); 8715 withWifiAndMobileUnderlying.addTransportType(TRANSPORT_WIFI); 8716 withWifiAndMobileUnderlying.removeCapability(NET_CAPABILITY_NOT_METERED); 8717 withWifiAndMobileUnderlying.removeCapability(NET_CAPABILITY_NOT_ROAMING); 8718 withWifiAndMobileUnderlying.setLinkDownstreamBandwidthKbps(10); 8719 withWifiAndMobileUnderlying.setLinkUpstreamBandwidthKbps(20); 8720 withWifiAndMobileUnderlying.setUnderlyingNetworks(underlyingNetworksContainMobileAndMobile); 8721 8722 final NetworkCapabilities initialCapsNotMetered = new NetworkCapabilities(initialCaps); 8723 initialCapsNotMetered.addCapability(NET_CAPABILITY_NOT_METERED); 8724 8725 NetworkCapabilities caps = new NetworkCapabilities(initialCaps); 8726 mService.applyUnderlyingCapabilities(new Network[]{}, initialCapsNotMetered, caps); 8727 assertEquals(withNoUnderlying, caps); 8728 assertEquals(0, new ArrayList<>(caps.getUnderlyingNetworks()).size()); 8729 8730 caps = new NetworkCapabilities(initialCaps); 8731 mService.applyUnderlyingCapabilities(new Network[]{null}, initialCapsNotMetered, caps); 8732 assertEquals(withNoUnderlying, caps); 8733 assertEquals(0, new ArrayList<>(caps.getUnderlyingNetworks()).size()); 8734 8735 caps = new NetworkCapabilities(initialCaps); 8736 mService.applyUnderlyingCapabilities(new Network[]{mobile}, initialCapsNotMetered, caps); 8737 assertEquals(withMobileUnderlying, caps); 8738 assertEquals(1, new ArrayList<>(caps.getUnderlyingNetworks()).size()); 8739 assertEquals(mobile, new ArrayList<>(caps.getUnderlyingNetworks()).get(0)); 8740 8741 caps = new NetworkCapabilities(initialCaps); 8742 mService.applyUnderlyingCapabilities(new Network[]{wifi}, initialCapsNotMetered, caps); 8743 assertEquals(withWifiUnderlying, caps); 8744 assertEquals(1, new ArrayList<>(caps.getUnderlyingNetworks()).size()); 8745 assertEquals(wifi, new ArrayList<>(caps.getUnderlyingNetworks()).get(0)); 8746 8747 withWifiUnderlying.removeCapability(NET_CAPABILITY_NOT_METERED); 8748 caps = new NetworkCapabilities(initialCaps); 8749 mService.applyUnderlyingCapabilities(new Network[]{wifi}, initialCaps, caps); 8750 assertEquals(withWifiUnderlying, caps); 8751 assertEquals(1, new ArrayList<>(caps.getUnderlyingNetworks()).size()); 8752 assertEquals(wifi, new ArrayList<>(caps.getUnderlyingNetworks()).get(0)); 8753 8754 caps = new NetworkCapabilities(initialCaps); 8755 mService.applyUnderlyingCapabilities(new Network[]{mobile, wifi}, initialCaps, caps); 8756 assertEquals(withWifiAndMobileUnderlying, caps); 8757 assertEquals(2, new ArrayList<>(caps.getUnderlyingNetworks()).size()); 8758 assertEquals(mobile, new ArrayList<>(caps.getUnderlyingNetworks()).get(0)); 8759 assertEquals(wifi, new ArrayList<>(caps.getUnderlyingNetworks()).get(1)); 8760 8761 withWifiUnderlying.addCapability(NET_CAPABILITY_NOT_METERED); 8762 caps = new NetworkCapabilities(initialCaps); 8763 mService.applyUnderlyingCapabilities(new Network[]{null, mobile, null, wifi}, 8764 initialCapsNotMetered, caps); 8765 assertEquals(withWifiAndMobileUnderlying, caps); 8766 assertEquals(2, new ArrayList<>(caps.getUnderlyingNetworks()).size()); 8767 assertEquals(mobile, new ArrayList<>(caps.getUnderlyingNetworks()).get(0)); 8768 assertEquals(wifi, new ArrayList<>(caps.getUnderlyingNetworks()).get(1)); 8769 8770 caps = new NetworkCapabilities(initialCaps); 8771 mService.applyUnderlyingCapabilities(new Network[]{null, mobile, null, wifi}, 8772 initialCapsNotMetered, caps); 8773 assertEquals(withWifiAndMobileUnderlying, caps); 8774 assertEquals(2, new ArrayList<>(caps.getUnderlyingNetworks()).size()); 8775 assertEquals(mobile, new ArrayList<>(caps.getUnderlyingNetworks()).get(0)); 8776 assertEquals(wifi, new ArrayList<>(caps.getUnderlyingNetworks()).get(1)); 8777 8778 caps = new NetworkCapabilities(initialCaps); 8779 mService.applyUnderlyingCapabilities(null, initialCapsNotMetered, caps); 8780 assertEquals(withWifiUnderlying, caps); 8781 assertEquals(1, new ArrayList<>(caps.getUnderlyingNetworks()).size()); 8782 assertEquals(wifi, new ArrayList<>(caps.getUnderlyingNetworks()).get(0)); 8783 } 8784 8785 @Test 8786 public void testVpnConnectDisconnectUnderlyingNetwork() throws Exception { 8787 final TestNetworkCallback callback = new TestNetworkCallback(); 8788 final NetworkRequest request = new NetworkRequest.Builder() 8789 .removeCapability(NET_CAPABILITY_NOT_VPN).build(); 8790 8791 runAsShell(NETWORK_SETTINGS, () -> { 8792 mCm.registerNetworkCallback(request, callback); 8793 8794 // Bring up a VPN that specifies an underlying network that does not exist yet. 8795 // Note: it's sort of meaningless for a VPN app to declare a network that doesn't exist 8796 // yet, (and doing so is difficult without using reflection) but it's good to test that 8797 // the code behaves approximately correctly. 8798 mMockVpn.establishForMyUid(false, true, false); 8799 callback.expectAvailableCallbacksUnvalidated(mMockVpn); 8800 assertUidRangesUpdatedForMyUid(true); 8801 final Network wifiNetwork = new Network(mNetIdManager.peekNextNetId()); 8802 mMockVpn.setUnderlyingNetworks(new Network[]{wifiNetwork}); 8803 // onCapabilitiesChanged() should be called because 8804 // NetworkCapabilities#mUnderlyingNetworks is updated. 8805 final NetworkCapabilities vpnNc1 = callback.expectCaps(mMockVpn); 8806 // Since the wifi network hasn't brought up, 8807 // ConnectivityService#applyUnderlyingCapabilities cannot find it. Update 8808 // NetworkCapabilities#mUnderlyingNetworks to an empty array, and it will be updated to 8809 // the correct underlying networks once the wifi network brings up. But this case 8810 // shouldn't happen in reality since no one could get the network which hasn't brought 8811 // up. For the empty array of underlying networks, it should be happened for 2 cases, 8812 // the first one is that the VPN app declares an empty array for its underlying 8813 // networks, the second one is that the underlying networks are torn down. 8814 // 8815 // It shouldn't be null since the null value means the underlying networks of this 8816 // network should follow the default network. 8817 final ArrayList<Network> underlyingNetwork = new ArrayList<>(); 8818 assertEquals(underlyingNetwork, vpnNc1.getUnderlyingNetworks()); 8819 // Since the wifi network isn't exist, applyUnderlyingCapabilities() 8820 assertTrue(mCm.getNetworkCapabilities(mMockVpn.getNetwork()) 8821 .hasTransport(TRANSPORT_VPN)); 8822 assertFalse(mCm.getNetworkCapabilities(mMockVpn.getNetwork()) 8823 .hasTransport(TRANSPORT_WIFI)); 8824 8825 // Make that underlying network connect, and expect to see its capabilities immediately 8826 // reflected in the VPN's capabilities. 8827 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 8828 assertEquals(wifiNetwork, mWiFiAgent.getNetwork()); 8829 mWiFiAgent.connect(false); 8830 // TODO: the callback for the VPN happens before any callbacks are called for the wifi 8831 // network that has just connected. There appear to be two issues here: 8832 // 1. The VPN code will accept an underlying network as soon as getNetworkCapabilities() 8833 // for it returns non-null (which happens very early, during 8834 // handleRegisterNetworkAgent). 8835 // This is not correct because that that point the network is not connected and 8836 // cannot pass any traffic. 8837 // 2. When a network connects, updateNetworkInfo propagates underlying network 8838 // capabilities before rematching networks. 8839 // Given that this scenario can't really happen, this is probably fine for now. 8840 final NetworkCapabilities vpnNc2 = callback.expectCaps(mMockVpn); 8841 // The wifi network is brought up, NetworkCapabilities#mUnderlyingNetworks is updated to 8842 // it. 8843 underlyingNetwork.add(wifiNetwork); 8844 assertEquals(underlyingNetwork, vpnNc2.getUnderlyingNetworks()); 8845 callback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 8846 assertTrue(mCm.getNetworkCapabilities(mMockVpn.getNetwork()) 8847 .hasTransport(TRANSPORT_VPN)); 8848 assertTrue(mCm.getNetworkCapabilities(mMockVpn.getNetwork()) 8849 .hasTransport(TRANSPORT_WIFI)); 8850 8851 // Disconnect the network, and expect to see the VPN capabilities change accordingly. 8852 mWiFiAgent.disconnect(); 8853 callback.expect(LOST, mWiFiAgent); 8854 callback.expectCaps(mMockVpn, c -> c.getTransportTypes().length == 1 8855 && c.hasTransport(TRANSPORT_VPN)); 8856 8857 mMockVpn.disconnect(); 8858 mCm.unregisterNetworkCallback(callback); 8859 }); 8860 } 8861 8862 private void assertGetNetworkInfoOfGetActiveNetworkIsConnected(boolean expectedConnectivity) { 8863 // What Chromium used to do before https://chromium-review.googlesource.com/2605304 8864 assertEquals("Unexpected result for getActiveNetworkInfo(getActiveNetwork())", 8865 expectedConnectivity, mCm.getNetworkInfo(mCm.getActiveNetwork()).isConnected()); 8866 } 8867 8868 @Test 8869 public void testVpnUnderlyingNetworkSuspended() throws Exception { 8870 final TestNetworkCallback callback = new TestNetworkCallback(); 8871 mCm.registerDefaultNetworkCallback(callback); 8872 8873 // Connect a VPN. 8874 mMockVpn.establishForMyUid(false /* validated */, true /* hasInternet */, 8875 false /* privateDnsProbeSent */); 8876 callback.expectAvailableCallbacksUnvalidated(mMockVpn); 8877 8878 // Connect cellular data. 8879 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 8880 mCellAgent.connect(false /* validated */); 8881 callback.expectCaps(mMockVpn, c -> c.hasCapability(NET_CAPABILITY_NOT_SUSPENDED) 8882 && c.hasTransport(TRANSPORT_CELLULAR)); 8883 callback.assertNoCallback(); 8884 8885 assertTrue(mCm.getNetworkCapabilities(mMockVpn.getNetwork()) 8886 .hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 8887 assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 8888 assertNetworkInfo(TYPE_WIFI, DetailedState.DISCONNECTED); 8889 assertNetworkInfo(TYPE_VPN, DetailedState.CONNECTED); 8890 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 8891 assertGetNetworkInfoOfGetActiveNetworkIsConnected(true); 8892 8893 // Suspend the cellular network and expect the VPN to be suspended. 8894 mCellAgent.suspend(); 8895 callback.expectCaps(mMockVpn, c -> !c.hasCapability(NET_CAPABILITY_NOT_SUSPENDED) 8896 && c.hasTransport(TRANSPORT_CELLULAR)); 8897 callback.expect(SUSPENDED, mMockVpn); 8898 callback.assertNoCallback(); 8899 8900 assertFalse(mCm.getNetworkCapabilities(mMockVpn.getNetwork()) 8901 .hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 8902 assertNetworkInfo(TYPE_MOBILE, DetailedState.SUSPENDED); 8903 assertNetworkInfo(TYPE_WIFI, DetailedState.DISCONNECTED); 8904 assertNetworkInfo(TYPE_VPN, DetailedState.SUSPENDED); 8905 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.SUSPENDED); 8906 // VPN's main underlying network is suspended, so no connectivity. 8907 assertGetNetworkInfoOfGetActiveNetworkIsConnected(false); 8908 8909 // Switch to another network. The VPN should no longer be suspended. 8910 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 8911 mWiFiAgent.connect(false /* validated */); 8912 callback.expectCaps(mMockVpn, c -> c.hasCapability(NET_CAPABILITY_NOT_SUSPENDED) 8913 && c.hasTransport(TRANSPORT_WIFI)); 8914 callback.expect(RESUMED, mMockVpn); 8915 callback.assertNoCallback(); 8916 8917 assertTrue(mCm.getNetworkCapabilities(mMockVpn.getNetwork()) 8918 .hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 8919 assertNetworkInfo(TYPE_MOBILE, DetailedState.DISCONNECTED); 8920 assertNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 8921 assertNetworkInfo(TYPE_VPN, DetailedState.CONNECTED); 8922 assertActiveNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 8923 assertGetNetworkInfoOfGetActiveNetworkIsConnected(true); 8924 8925 // Unsuspend cellular and then switch back to it. The VPN remains not suspended. 8926 mCellAgent.resume(); 8927 callback.assertNoCallback(); 8928 mWiFiAgent.disconnect(); 8929 callback.expectCaps(mMockVpn, c -> c.hasCapability(NET_CAPABILITY_NOT_SUSPENDED) 8930 && c.hasTransport(TRANSPORT_CELLULAR)); 8931 // Spurious double callback? 8932 callback.expectCaps(mMockVpn, c -> c.hasCapability(NET_CAPABILITY_NOT_SUSPENDED) 8933 && c.hasTransport(TRANSPORT_CELLULAR)); 8934 callback.assertNoCallback(); 8935 8936 assertTrue(mCm.getNetworkCapabilities(mMockVpn.getNetwork()) 8937 .hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 8938 assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 8939 assertNetworkInfo(TYPE_WIFI, DetailedState.DISCONNECTED); 8940 assertNetworkInfo(TYPE_VPN, DetailedState.CONNECTED); 8941 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 8942 assertGetNetworkInfoOfGetActiveNetworkIsConnected(true); 8943 8944 // Suspend cellular and expect no connectivity. 8945 mCellAgent.suspend(); 8946 callback.expectCaps(mMockVpn, c -> !c.hasCapability(NET_CAPABILITY_NOT_SUSPENDED) 8947 && c.hasTransport(TRANSPORT_CELLULAR)); 8948 callback.expect(SUSPENDED, mMockVpn); 8949 callback.assertNoCallback(); 8950 8951 assertFalse(mCm.getNetworkCapabilities(mMockVpn.getNetwork()) 8952 .hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 8953 assertNetworkInfo(TYPE_MOBILE, DetailedState.SUSPENDED); 8954 assertNetworkInfo(TYPE_WIFI, DetailedState.DISCONNECTED); 8955 assertNetworkInfo(TYPE_VPN, DetailedState.SUSPENDED); 8956 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.SUSPENDED); 8957 assertGetNetworkInfoOfGetActiveNetworkIsConnected(false); 8958 8959 // Resume cellular and expect that connectivity comes back. 8960 mCellAgent.resume(); 8961 callback.expectCaps(mMockVpn, c -> c.hasCapability(NET_CAPABILITY_NOT_SUSPENDED) 8962 && c.hasTransport(TRANSPORT_CELLULAR)); 8963 callback.expect(RESUMED, mMockVpn); 8964 callback.assertNoCallback(); 8965 8966 assertTrue(mCm.getNetworkCapabilities(mMockVpn.getNetwork()) 8967 .hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 8968 assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 8969 assertNetworkInfo(TYPE_WIFI, DetailedState.DISCONNECTED); 8970 assertNetworkInfo(TYPE_VPN, DetailedState.CONNECTED); 8971 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 8972 assertGetNetworkInfoOfGetActiveNetworkIsConnected(true); 8973 } 8974 8975 @Test 8976 public void testVpnNetworkActive() throws Exception { 8977 final int uid = Process.myUid(); 8978 8979 final TestNetworkCallback genericNetworkCallback = new TestNetworkCallback(); 8980 final TestNetworkCallback genericNotVpnNetworkCallback = new TestNetworkCallback(); 8981 final TestNetworkCallback wifiNetworkCallback = new TestNetworkCallback(); 8982 final TestNetworkCallback vpnNetworkCallback = new TestNetworkCallback(); 8983 final TestNetworkCallback defaultCallback = new TestNetworkCallback(); 8984 final TestNetworkCallback systemDefaultCallback = new TestNetworkCallback(); 8985 final NetworkRequest genericNotVpnRequest = new NetworkRequest.Builder().build(); 8986 final NetworkRequest genericRequest = new NetworkRequest.Builder() 8987 .removeCapability(NET_CAPABILITY_NOT_VPN).build(); 8988 final NetworkRequest wifiRequest = new NetworkRequest.Builder() 8989 .addTransportType(TRANSPORT_WIFI).build(); 8990 final NetworkRequest vpnNetworkRequest = new NetworkRequest.Builder() 8991 .removeCapability(NET_CAPABILITY_NOT_VPN) 8992 .addTransportType(TRANSPORT_VPN).build(); 8993 mCm.registerNetworkCallback(genericRequest, genericNetworkCallback); 8994 mCm.registerNetworkCallback(genericNotVpnRequest, genericNotVpnNetworkCallback); 8995 mCm.registerNetworkCallback(wifiRequest, wifiNetworkCallback); 8996 mCm.registerNetworkCallback(vpnNetworkRequest, vpnNetworkCallback); 8997 mCm.registerDefaultNetworkCallback(defaultCallback); 8998 mCm.registerSystemDefaultNetworkCallback(systemDefaultCallback, 8999 new Handler(ConnectivityThread.getInstanceLooper())); 9000 defaultCallback.assertNoCallback(); 9001 9002 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 9003 mWiFiAgent.connect(false); 9004 9005 genericNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 9006 genericNotVpnNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 9007 wifiNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 9008 defaultCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 9009 systemDefaultCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 9010 vpnNetworkCallback.assertNoCallback(); 9011 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 9012 9013 final Set<UidRange> ranges = uidRangesForUids(uid); 9014 mMockVpn.registerAgent(ranges); 9015 mMockVpn.setUnderlyingNetworks(new Network[0]); 9016 9017 // VPN networks do not satisfy the default request and are automatically validated 9018 // by NetworkMonitor 9019 assertFalse(NetworkMonitorUtils.isValidationRequired( 9020 false /* isDunValidationRequired */, 9021 NetworkAgentConfigShimImpl.newInstance(mMockVpn.getNetworkAgentConfig()) 9022 .isVpnValidationRequired(), 9023 mMockVpn.getAgent().getNetworkCapabilities())); 9024 mMockVpn.getAgent().setNetworkValid(false /* privateDnsProbeSent */); 9025 9026 mMockVpn.connect(false); 9027 9028 genericNetworkCallback.expectAvailableThenValidatedCallbacks(mMockVpn); 9029 genericNotVpnNetworkCallback.assertNoCallback(); 9030 wifiNetworkCallback.assertNoCallback(); 9031 vpnNetworkCallback.expectAvailableThenValidatedCallbacks(mMockVpn); 9032 defaultCallback.expectAvailableThenValidatedCallbacks(mMockVpn); 9033 systemDefaultCallback.assertNoCallback(); 9034 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 9035 assertEquals(mWiFiAgent.getNetwork(), systemDefaultCallback.getLastAvailableNetwork()); 9036 9037 ranges.clear(); 9038 mMockVpn.setUids(ranges); 9039 9040 genericNetworkCallback.expect(LOST, mMockVpn); 9041 genericNotVpnNetworkCallback.assertNoCallback(); 9042 wifiNetworkCallback.assertNoCallback(); 9043 vpnNetworkCallback.expect(LOST, mMockVpn); 9044 9045 // TODO : The default network callback should actually get a LOST call here (also see the 9046 // comment below for AVAILABLE). This is because ConnectivityService does not look at UID 9047 // ranges at all when determining whether a network should be rematched. In practice, VPNs 9048 // can't currently update their UIDs without disconnecting, so this does not matter too 9049 // much, but that is the reason the test here has to check for an update to the 9050 // capabilities instead of the expected LOST then AVAILABLE. 9051 defaultCallback.expectCaps(mMockVpn); 9052 systemDefaultCallback.assertNoCallback(); 9053 9054 ranges.add(new UidRange(uid, uid)); 9055 mMockVpn.setUids(ranges); 9056 9057 genericNetworkCallback.expectAvailableCallbacksValidated(mMockVpn); 9058 genericNotVpnNetworkCallback.assertNoCallback(); 9059 wifiNetworkCallback.assertNoCallback(); 9060 vpnNetworkCallback.expectAvailableCallbacksValidated(mMockVpn); 9061 // TODO : Here like above, AVAILABLE would be correct, but because this can't actually 9062 // happen outside of the test, ConnectivityService does not rematch callbacks. 9063 defaultCallback.expectCaps(mMockVpn); 9064 systemDefaultCallback.assertNoCallback(); 9065 9066 mWiFiAgent.disconnect(); 9067 9068 genericNetworkCallback.expect(LOST, mWiFiAgent); 9069 genericNotVpnNetworkCallback.expect(LOST, mWiFiAgent); 9070 wifiNetworkCallback.expect(LOST, mWiFiAgent); 9071 vpnNetworkCallback.assertNoCallback(); 9072 defaultCallback.assertNoCallback(); 9073 systemDefaultCallback.expect(LOST, mWiFiAgent); 9074 9075 mMockVpn.disconnect(); 9076 9077 genericNetworkCallback.expect(LOST, mMockVpn); 9078 genericNotVpnNetworkCallback.assertNoCallback(); 9079 wifiNetworkCallback.assertNoCallback(); 9080 vpnNetworkCallback.expect(LOST, mMockVpn); 9081 defaultCallback.expect(LOST, mMockVpn); 9082 systemDefaultCallback.assertNoCallback(); 9083 assertEquals(null, mCm.getActiveNetwork()); 9084 9085 mCm.unregisterNetworkCallback(genericNetworkCallback); 9086 mCm.unregisterNetworkCallback(wifiNetworkCallback); 9087 mCm.unregisterNetworkCallback(vpnNetworkCallback); 9088 mCm.unregisterNetworkCallback(defaultCallback); 9089 mCm.unregisterNetworkCallback(systemDefaultCallback); 9090 } 9091 9092 @Test 9093 public void testVpnWithoutInternet() throws Exception { 9094 final int uid = Process.myUid(); 9095 9096 final TestNetworkCallback defaultCallback = new TestNetworkCallback(); 9097 mCm.registerDefaultNetworkCallback(defaultCallback); 9098 9099 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 9100 mWiFiAgent.connect(true); 9101 9102 defaultCallback.expectAvailableThenValidatedCallbacks(mWiFiAgent); 9103 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 9104 9105 mMockVpn.establishForMyUid(true /* validated */, false /* hasInternet */, 9106 false /* privateDnsProbeSent */); 9107 assertUidRangesUpdatedForMyUid(true); 9108 9109 defaultCallback.assertNoCallback(); 9110 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 9111 9112 mMockVpn.disconnect(); 9113 defaultCallback.assertNoCallback(); 9114 9115 mCm.unregisterNetworkCallback(defaultCallback); 9116 } 9117 9118 @Test 9119 public void testVpnWithInternet() throws Exception { 9120 final int uid = Process.myUid(); 9121 9122 final TestNetworkCallback defaultCallback = new TestNetworkCallback(); 9123 mCm.registerDefaultNetworkCallback(defaultCallback); 9124 9125 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 9126 mWiFiAgent.connect(true); 9127 9128 defaultCallback.expectAvailableThenValidatedCallbacks(mWiFiAgent); 9129 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 9130 9131 mMockVpn.establishForMyUid(true /* validated */, true /* hasInternet */, 9132 false /* privateDnsProbeSent */); 9133 assertUidRangesUpdatedForMyUid(true); 9134 9135 defaultCallback.expectAvailableThenValidatedCallbacks(mMockVpn); 9136 assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); 9137 9138 mMockVpn.disconnect(); 9139 defaultCallback.expect(LOST, mMockVpn); 9140 defaultCallback.expectAvailableCallbacksValidated(mWiFiAgent); 9141 9142 mCm.unregisterNetworkCallback(defaultCallback); 9143 } 9144 9145 @Test 9146 public void testVpnUnvalidated() throws Exception { 9147 final TestNetworkCallback callback = new TestNetworkCallback(); 9148 mCm.registerDefaultNetworkCallback(callback); 9149 9150 // Bring up Ethernet. 9151 mEthernetAgent = new TestNetworkAgentWrapper(TRANSPORT_ETHERNET); 9152 mEthernetAgent.connect(true); 9153 callback.expectAvailableThenValidatedCallbacks(mEthernetAgent); 9154 callback.assertNoCallback(); 9155 9156 // Bring up a VPN that has the INTERNET capability, initially unvalidated. 9157 mMockVpn.establishForMyUid(false /* validated */, true /* hasInternet */, 9158 false /* privateDnsProbeSent */); 9159 assertUidRangesUpdatedForMyUid(true); 9160 9161 // Even though the VPN is unvalidated, it becomes the default network for our app. 9162 callback.expectAvailableCallbacksUnvalidated(mMockVpn); 9163 callback.assertNoCallback(); 9164 9165 assertEquals(mMockVpn.getNetwork(), mCm.getActiveNetwork()); 9166 9167 NetworkCapabilities nc = mCm.getNetworkCapabilities(mMockVpn.getNetwork()); 9168 assertFalse(nc.hasCapability(NET_CAPABILITY_VALIDATED)); 9169 assertTrue(nc.hasCapability(NET_CAPABILITY_INTERNET)); 9170 9171 assertFalse(NetworkMonitorUtils.isValidationRequired( 9172 false /* isDunValidationRequired */, 9173 NetworkAgentConfigShimImpl.newInstance(mMockVpn.getNetworkAgentConfig()) 9174 .isVpnValidationRequired(), 9175 mMockVpn.getAgent().getNetworkCapabilities())); 9176 assertTrue(NetworkMonitorUtils.isPrivateDnsValidationRequired( 9177 mMockVpn.getAgent().getNetworkCapabilities())); 9178 9179 // Pretend that the VPN network validates. 9180 mMockVpn.getAgent().setNetworkValid(false /* privateDnsProbeSent */); 9181 mMockVpn.getAgent().mNetworkMonitor.forceReevaluation(Process.myUid()); 9182 // Expect to see the validated capability, but no other changes, because the VPN is already 9183 // the default network for the app. 9184 callback.expectCaps(mMockVpn, c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 9185 callback.assertNoCallback(); 9186 9187 mMockVpn.disconnect(); 9188 callback.expect(LOST, mMockVpn); 9189 callback.expectAvailableCallbacksValidated(mEthernetAgent); 9190 } 9191 9192 @Test 9193 public void testVpnStartsWithUnderlyingCaps() throws Exception { 9194 final int uid = Process.myUid(); 9195 9196 final TestNetworkCallback vpnNetworkCallback = new TestNetworkCallback(); 9197 final NetworkRequest vpnNetworkRequest = new NetworkRequest.Builder() 9198 .removeCapability(NET_CAPABILITY_NOT_VPN) 9199 .addTransportType(TRANSPORT_VPN) 9200 .build(); 9201 mCm.registerNetworkCallback(vpnNetworkRequest, vpnNetworkCallback); 9202 vpnNetworkCallback.assertNoCallback(); 9203 9204 // Connect cell. It will become the default network, and in the absence of setting 9205 // underlying networks explicitly it will become the sole underlying network for the vpn. 9206 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 9207 mCellAgent.addCapability(NET_CAPABILITY_NOT_SUSPENDED); 9208 mCellAgent.connect(true); 9209 9210 mMockVpn.establishForMyUid(true /* validated */, false /* hasInternet */, 9211 false /* privateDnsProbeSent */); 9212 assertUidRangesUpdatedForMyUid(true); 9213 9214 vpnNetworkCallback.expectAvailableCallbacks(mMockVpn.getNetwork(), 9215 false /* suspended */, false /* validated */, false /* blocked */, TIMEOUT_MS); 9216 vpnNetworkCallback.expectCaps(mMockVpn.getNetwork(), TIMEOUT_MS, 9217 c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 9218 9219 final NetworkCapabilities nc = mCm.getNetworkCapabilities(mMockVpn.getNetwork()); 9220 assertTrue(nc.hasTransport(TRANSPORT_VPN)); 9221 assertTrue(nc.hasTransport(TRANSPORT_CELLULAR)); 9222 assertFalse(nc.hasTransport(TRANSPORT_WIFI)); 9223 assertTrue(nc.hasCapability(NET_CAPABILITY_VALIDATED)); 9224 assertFalse(nc.hasCapability(NET_CAPABILITY_NOT_METERED)); 9225 assertTrue(nc.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 9226 9227 assertVpnTransportInfo(nc, VpnManager.TYPE_VPN_SERVICE); 9228 } 9229 9230 private void assertDefaultNetworkCapabilities(int userId, NetworkAgentWrapper... networks) { 9231 final NetworkCapabilities[] defaultCaps = mService.getDefaultNetworkCapabilitiesForUser( 9232 userId, "com.android.calling.package", "com.test"); 9233 final String defaultCapsString = Arrays.toString(defaultCaps); 9234 assertEquals(defaultCapsString, defaultCaps.length, networks.length); 9235 final Set<NetworkCapabilities> defaultCapsSet = new ArraySet<>(defaultCaps); 9236 for (NetworkAgentWrapper network : networks) { 9237 final NetworkCapabilities nc = mCm.getNetworkCapabilities(network.getNetwork()); 9238 final String msg = "Did not find " + nc + " in " + Arrays.toString(defaultCaps); 9239 assertTrue(msg, defaultCapsSet.contains(nc)); 9240 } 9241 } 9242 9243 @Test 9244 public void testVpnSetUnderlyingNetworks() throws Exception { 9245 final TestNetworkCallback vpnNetworkCallback = new TestNetworkCallback(); 9246 final NetworkRequest vpnNetworkRequest = new NetworkRequest.Builder() 9247 .removeCapability(NET_CAPABILITY_NOT_VPN) 9248 .addTransportType(TRANSPORT_VPN) 9249 .build(); 9250 NetworkCapabilities nc; 9251 mCm.registerNetworkCallback(vpnNetworkRequest, vpnNetworkCallback); 9252 vpnNetworkCallback.assertNoCallback(); 9253 9254 // Lingering timer is short and cell might be disconnected if the device is particularly 9255 // slow running the test, unless it's requested. Make sure the networks the test needs 9256 // are all requested. 9257 final NetworkCallback cellCallback = new NetworkCallback() {}; 9258 final NetworkCallback wifiCallback = new NetworkCallback() {}; 9259 mCm.requestNetwork( 9260 new NetworkRequest.Builder().addTransportType(TRANSPORT_CELLULAR).build(), 9261 cellCallback); 9262 mCm.requestNetwork( 9263 new NetworkRequest.Builder().addTransportType(TRANSPORT_WIFI).build(), 9264 wifiCallback); 9265 9266 mMockVpn.establishForMyUid(true /* validated */, false /* hasInternet */, 9267 false /* privateDnsProbeSent */); 9268 assertUidRangesUpdatedForMyUid(true); 9269 9270 vpnNetworkCallback.expectAvailableThenValidatedCallbacks(mMockVpn); 9271 nc = mCm.getNetworkCapabilities(mMockVpn.getNetwork()); 9272 assertTrue(nc.hasTransport(TRANSPORT_VPN)); 9273 assertFalse(nc.hasTransport(TRANSPORT_CELLULAR)); 9274 assertFalse(nc.hasTransport(TRANSPORT_WIFI)); 9275 // For safety reasons a VPN without underlying networks is considered metered. 9276 assertFalse(nc.hasCapability(NET_CAPABILITY_NOT_METERED)); 9277 // A VPN without underlying networks is not suspended. 9278 assertTrue(nc.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 9279 assertVpnTransportInfo(nc, VpnManager.TYPE_VPN_SERVICE); 9280 9281 final int userId = UserHandle.getUserId(Process.myUid()); 9282 assertDefaultNetworkCapabilities(userId /* no networks */); 9283 9284 // Connect cell and use it as an underlying network. 9285 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 9286 mCellAgent.addCapability(NET_CAPABILITY_NOT_SUSPENDED); 9287 mCellAgent.connect(true); 9288 9289 mMockVpn.setUnderlyingNetworks(new Network[] { mCellAgent.getNetwork() }); 9290 9291 vpnNetworkCallback.expectCaps(mMockVpn, 9292 c -> c.hasTransport(TRANSPORT_VPN) 9293 && c.hasTransport(TRANSPORT_CELLULAR) 9294 && !c.hasTransport(TRANSPORT_WIFI) 9295 && !c.hasCapability(NET_CAPABILITY_NOT_METERED) 9296 && c.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 9297 assertDefaultNetworkCapabilities(userId, mCellAgent); 9298 9299 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 9300 mWiFiAgent.addCapability(NET_CAPABILITY_NOT_METERED); 9301 mWiFiAgent.addCapability(NET_CAPABILITY_NOT_SUSPENDED); 9302 mWiFiAgent.connect(true); 9303 9304 mMockVpn.setUnderlyingNetworks( 9305 new Network[] { mCellAgent.getNetwork(), mWiFiAgent.getNetwork() }); 9306 9307 vpnNetworkCallback.expectCaps(mMockVpn, 9308 c -> c.hasTransport(TRANSPORT_VPN) 9309 && c.hasTransport(TRANSPORT_CELLULAR) 9310 && c.hasTransport(TRANSPORT_WIFI) 9311 && !c.hasCapability(NET_CAPABILITY_NOT_METERED) 9312 && c.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 9313 assertDefaultNetworkCapabilities(userId, mCellAgent, mWiFiAgent); 9314 9315 // Don't disconnect, but note the VPN is not using wifi any more. 9316 mMockVpn.setUnderlyingNetworks(new Network[] { mCellAgent.getNetwork() }); 9317 9318 vpnNetworkCallback.expectCaps(mMockVpn, 9319 c -> c.hasTransport(TRANSPORT_VPN) 9320 && c.hasTransport(TRANSPORT_CELLULAR) 9321 && !c.hasTransport(TRANSPORT_WIFI) 9322 && !c.hasCapability(NET_CAPABILITY_NOT_METERED) 9323 && c.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 9324 // The return value of getDefaultNetworkCapabilitiesForUser always includes the default 9325 // network (wifi) as well as the underlying networks (cell). 9326 assertDefaultNetworkCapabilities(userId, mCellAgent, mWiFiAgent); 9327 9328 // Remove NOT_SUSPENDED from the only network and observe VPN is now suspended. 9329 mCellAgent.removeCapability(NET_CAPABILITY_NOT_SUSPENDED); 9330 vpnNetworkCallback.expectCaps(mMockVpn, 9331 c -> c.hasTransport(TRANSPORT_VPN) 9332 && c.hasTransport(TRANSPORT_CELLULAR) 9333 && !c.hasTransport(TRANSPORT_WIFI) 9334 && !c.hasCapability(NET_CAPABILITY_NOT_METERED) 9335 && !c.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 9336 vpnNetworkCallback.expect(SUSPENDED, mMockVpn); 9337 9338 // Add NOT_SUSPENDED again and observe VPN is no longer suspended. 9339 mCellAgent.addCapability(NET_CAPABILITY_NOT_SUSPENDED); 9340 vpnNetworkCallback.expectCaps(mMockVpn, 9341 c -> c.hasTransport(TRANSPORT_VPN) 9342 && c.hasTransport(TRANSPORT_CELLULAR) 9343 && !c.hasTransport(TRANSPORT_WIFI) 9344 && !c.hasCapability(NET_CAPABILITY_NOT_METERED) 9345 && c.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 9346 vpnNetworkCallback.expect(RESUMED, mMockVpn); 9347 9348 // Use Wifi but not cell. Note the VPN is now unmetered and not suspended. 9349 mMockVpn.setUnderlyingNetworks(new Network[] { mWiFiAgent.getNetwork() }); 9350 9351 vpnNetworkCallback.expectCaps(mMockVpn, 9352 c -> c.hasTransport(TRANSPORT_VPN) 9353 && !c.hasTransport(TRANSPORT_CELLULAR) 9354 && c.hasTransport(TRANSPORT_WIFI) 9355 && c.hasCapability(NET_CAPABILITY_NOT_METERED) 9356 && c.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 9357 assertDefaultNetworkCapabilities(userId, mWiFiAgent); 9358 9359 // Use both again. 9360 mMockVpn.setUnderlyingNetworks( 9361 new Network[] { mCellAgent.getNetwork(), mWiFiAgent.getNetwork() }); 9362 9363 vpnNetworkCallback.expectCaps(mMockVpn, 9364 c -> c.hasTransport(TRANSPORT_VPN) 9365 && c.hasTransport(TRANSPORT_CELLULAR) 9366 && c.hasTransport(TRANSPORT_WIFI) 9367 && !c.hasCapability(NET_CAPABILITY_NOT_METERED) 9368 && c.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 9369 assertDefaultNetworkCapabilities(userId, mCellAgent, mWiFiAgent); 9370 9371 // Cell is suspended again. As WiFi is not, this should not cause a callback. 9372 mCellAgent.removeCapability(NET_CAPABILITY_NOT_SUSPENDED); 9373 vpnNetworkCallback.assertNoCallback(); 9374 9375 // Stop using WiFi. The VPN is suspended again. 9376 mMockVpn.setUnderlyingNetworks(new Network[] { mCellAgent.getNetwork() }); 9377 vpnNetworkCallback.expectCaps(mMockVpn, 9378 c -> c.hasTransport(TRANSPORT_VPN) 9379 && c.hasTransport(TRANSPORT_CELLULAR) 9380 && !c.hasCapability(NET_CAPABILITY_NOT_METERED) 9381 && !c.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 9382 vpnNetworkCallback.expect(SUSPENDED, mMockVpn); 9383 assertDefaultNetworkCapabilities(userId, mCellAgent, mWiFiAgent); 9384 9385 // Use both again. 9386 mMockVpn.setUnderlyingNetworks( 9387 new Network[] { mCellAgent.getNetwork(), mWiFiAgent.getNetwork() }); 9388 9389 vpnNetworkCallback.expectCaps(mMockVpn, 9390 c -> c.hasTransport(TRANSPORT_VPN) 9391 && c.hasTransport(TRANSPORT_CELLULAR) 9392 && c.hasTransport(TRANSPORT_WIFI) 9393 && !c.hasCapability(NET_CAPABILITY_NOT_METERED) 9394 && c.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 9395 vpnNetworkCallback.expect(RESUMED, mMockVpn); 9396 assertDefaultNetworkCapabilities(userId, mCellAgent, mWiFiAgent); 9397 9398 // Disconnect cell. Receive update without even removing the dead network from the 9399 // underlying networks – it's dead anyway. Not metered any more. 9400 mCellAgent.disconnect(); 9401 vpnNetworkCallback.expectCaps(mMockVpn, 9402 c -> c.hasTransport(TRANSPORT_VPN) 9403 && !c.hasTransport(TRANSPORT_CELLULAR) 9404 && c.hasTransport(TRANSPORT_WIFI) 9405 && c.hasCapability(NET_CAPABILITY_NOT_METERED)); 9406 assertDefaultNetworkCapabilities(userId, mWiFiAgent); 9407 9408 // Disconnect wifi too. No underlying networks means this is now metered. 9409 mWiFiAgent.disconnect(); 9410 vpnNetworkCallback.expectCaps(mMockVpn, 9411 c -> c.hasTransport(TRANSPORT_VPN) 9412 && !c.hasTransport(TRANSPORT_CELLULAR) 9413 && !c.hasTransport(TRANSPORT_WIFI) 9414 && !c.hasCapability(NET_CAPABILITY_NOT_METERED)); 9415 // When a network disconnects, the callbacks are fired before all state is updated, so for a 9416 // short time, synchronous calls will behave as if the network is still connected. Wait for 9417 // things to settle. 9418 waitForIdle(); 9419 assertDefaultNetworkCapabilities(userId /* no networks */); 9420 9421 mMockVpn.disconnect(); 9422 mCm.unregisterNetworkCallback(cellCallback); 9423 mCm.unregisterNetworkCallback(wifiCallback); 9424 } 9425 9426 @Test 9427 public void testNullUnderlyingNetworks() throws Exception { 9428 final int uid = Process.myUid(); 9429 9430 final TestNetworkCallback vpnNetworkCallback = new TestNetworkCallback(); 9431 final NetworkRequest vpnNetworkRequest = new NetworkRequest.Builder() 9432 .removeCapability(NET_CAPABILITY_NOT_VPN) 9433 .addTransportType(TRANSPORT_VPN) 9434 .build(); 9435 NetworkCapabilities nc; 9436 mCm.registerNetworkCallback(vpnNetworkRequest, vpnNetworkCallback); 9437 vpnNetworkCallback.assertNoCallback(); 9438 9439 mMockVpn.establishForMyUid(true /* validated */, false /* hasInternet */, 9440 false /* privateDnsProbeSent */); 9441 assertUidRangesUpdatedForMyUid(true); 9442 9443 vpnNetworkCallback.expectAvailableThenValidatedCallbacks(mMockVpn); 9444 nc = mCm.getNetworkCapabilities(mMockVpn.getNetwork()); 9445 assertTrue(nc.hasTransport(TRANSPORT_VPN)); 9446 assertFalse(nc.hasTransport(TRANSPORT_CELLULAR)); 9447 assertFalse(nc.hasTransport(TRANSPORT_WIFI)); 9448 // By default, VPN is set to track default network (i.e. its underlying networks is null). 9449 // In case of no default network, VPN is considered metered. 9450 assertFalse(nc.hasCapability(NET_CAPABILITY_NOT_METERED)); 9451 assertVpnTransportInfo(nc, VpnManager.TYPE_VPN_SERVICE); 9452 9453 // Connect to Cell; Cell is the default network. 9454 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 9455 mCellAgent.connect(true); 9456 9457 vpnNetworkCallback.expectCaps(mMockVpn, 9458 c -> c.hasTransport(TRANSPORT_VPN) 9459 && c.hasTransport(TRANSPORT_CELLULAR) 9460 && !c.hasTransport(TRANSPORT_WIFI) 9461 && !c.hasCapability(NET_CAPABILITY_NOT_METERED)); 9462 9463 // Connect to WiFi; WiFi is the new default. 9464 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 9465 mWiFiAgent.addCapability(NET_CAPABILITY_NOT_METERED); 9466 mWiFiAgent.connect(true); 9467 9468 vpnNetworkCallback.expectCaps(mMockVpn, 9469 c -> c.hasTransport(TRANSPORT_VPN) 9470 && !c.hasTransport(TRANSPORT_CELLULAR) 9471 && c.hasTransport(TRANSPORT_WIFI) 9472 && c.hasCapability(NET_CAPABILITY_NOT_METERED)); 9473 9474 // Disconnect Cell. The default network did not change, so there shouldn't be any changes in 9475 // the capabilities. 9476 mCellAgent.disconnect(); 9477 9478 // Disconnect wifi too. Now we have no default network. 9479 mWiFiAgent.disconnect(); 9480 9481 vpnNetworkCallback.expectCaps(mMockVpn, 9482 c -> c.hasTransport(TRANSPORT_VPN) 9483 && !c.hasTransport(TRANSPORT_CELLULAR) 9484 && !c.hasTransport(TRANSPORT_WIFI) 9485 && !c.hasCapability(NET_CAPABILITY_NOT_METERED)); 9486 9487 mMockVpn.disconnect(); 9488 } 9489 9490 @Test 9491 public void testRestrictedProfileAffectsVpnUidRanges() throws Exception { 9492 // NETWORK_SETTINGS is necessary to see the UID ranges in NetworkCapabilities. 9493 mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_GRANTED); 9494 9495 final NetworkRequest request = new NetworkRequest.Builder() 9496 .removeCapability(NET_CAPABILITY_NOT_VPN) 9497 .build(); 9498 final TestNetworkCallback callback = new TestNetworkCallback(); 9499 mCm.registerNetworkCallback(request, callback); 9500 9501 // File a VPN request to prevent VPN network being lingered. 9502 final NetworkRequest vpnRequest = new NetworkRequest.Builder() 9503 .addTransportType(TRANSPORT_VPN) 9504 .removeCapability(NET_CAPABILITY_NOT_VPN) 9505 .build(); 9506 final TestNetworkCallback vpnCallback = new TestNetworkCallback(); 9507 mCm.requestNetwork(vpnRequest, vpnCallback); 9508 9509 // Bring up a VPN 9510 mMockVpn.establishForMyUid(); 9511 assertUidRangesUpdatedForMyUid(true); 9512 callback.expectAvailableThenValidatedCallbacks(mMockVpn); 9513 callback.assertNoCallback(); 9514 9515 final int uid = Process.myUid(); 9516 NetworkCapabilities nc = mCm.getNetworkCapabilities(mMockVpn.getNetwork()); 9517 assertNotNull("nc=" + nc, nc.getUids()); 9518 assertEquals(nc.getUids(), UidRange.toIntRanges(uidRangesForUids(uid))); 9519 assertVpnTransportInfo(nc, VpnManager.TYPE_VPN_SERVICE); 9520 9521 // Set an underlying network and expect to see the VPN transports change. 9522 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 9523 mWiFiAgent.connect(true); 9524 callback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 9525 callback.expectCaps(mMockVpn, c -> c.hasTransport(TRANSPORT_VPN) 9526 && c.hasTransport(TRANSPORT_WIFI)); 9527 callback.expectCaps(mWiFiAgent, c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 9528 9529 // New user added, this updates the Vpn uids, coverage in VpnTest. 9530 // This is equivalent to `mMockVpn.onUserAdded(RESTRICTED_USER);` 9531 final Set<UidRange> ranges = uidRangesForUids(uid); 9532 ranges.add(RESTRICTED_USER_UIDRANGE); 9533 mMockVpn.setUids(ranges); 9534 9535 // Expect that the VPN UID ranges contain both |uid| and the UID range for the newly-added 9536 // restricted user. 9537 final UidRange rRange = UidRange.createForUser(UserHandle.of(RESTRICTED_USER)); 9538 final Range<Integer> restrictUidRange = new Range<>(rRange.start, rRange.stop); 9539 final Range<Integer> singleUidRange = new Range<>(uid, uid); 9540 callback.expectCaps(mMockVpn, c -> 9541 c.getUids().size() == 2 9542 && c.getUids().contains(singleUidRange) 9543 && c.getUids().contains(restrictUidRange) 9544 && c.hasTransport(TRANSPORT_VPN) 9545 && c.hasTransport(TRANSPORT_WIFI)); 9546 9547 // Change the VPN's capabilities somehow (specifically, disconnect wifi). 9548 mWiFiAgent.disconnect(); 9549 callback.expect(LOST, mWiFiAgent); 9550 callback.expectCaps(mMockVpn, c -> 9551 c.getUids().size() == 2 9552 && c.getUids().contains(singleUidRange) 9553 && c.getUids().contains(restrictUidRange) 9554 && c.hasTransport(TRANSPORT_VPN) 9555 && !c.hasTransport(TRANSPORT_WIFI)); 9556 9557 // User removed and expect to lose the UID range for the restricted user. 9558 // This updates the Vpn uids, coverage in VpnTest. 9559 // This is equivalent to `mMockVpn.onUserRemoved(RESTRICTED_USER);` 9560 mMockVpn.setUids(uidRangesForUids(uid)); 9561 9562 // Expect that the VPN gains the UID range for the restricted user, and that the capability 9563 // change made just before that (i.e., loss of TRANSPORT_WIFI) is preserved. 9564 callback.expectCaps(mMockVpn, c -> 9565 c.getUids().size() == 1 9566 && c.getUids().contains(singleUidRange) 9567 && c.hasTransport(TRANSPORT_VPN) 9568 && !c.hasTransport(TRANSPORT_WIFI)); 9569 9570 mCm.unregisterNetworkCallback(callback); 9571 mCm.unregisterNetworkCallback(vpnCallback); 9572 } 9573 9574 @Test 9575 public void testLockdownVpnWithRestrictedProfiles() throws Exception { 9576 // For ConnectivityService#setAlwaysOnVpnPackage. 9577 mServiceContext.setPermission( 9578 Manifest.permission.CONTROL_ALWAYS_ON_VPN, PERMISSION_GRANTED); 9579 // For call Vpn#setAlwaysOnPackage. 9580 mServiceContext.setPermission( 9581 Manifest.permission.CONTROL_VPN, PERMISSION_GRANTED); 9582 // Necessary to see the UID ranges in NetworkCapabilities. 9583 mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_GRANTED); 9584 9585 final NetworkRequest request = new NetworkRequest.Builder() 9586 .removeCapability(NET_CAPABILITY_NOT_VPN) 9587 .build(); 9588 final TestNetworkCallback callback = new TestNetworkCallback(); 9589 mCm.registerNetworkCallback(request, callback); 9590 9591 final int uid = Process.myUid(); 9592 9593 // Connect wifi and check that UIDs in the main and restricted profiles have network access. 9594 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 9595 mWiFiAgent.connect(true /* validated */); 9596 final int restrictedUid = UserHandle.getUid(RESTRICTED_USER, 42 /* appId */); 9597 assertNotNull(mCm.getActiveNetworkForUid(uid)); 9598 assertNotNull(mCm.getActiveNetworkForUid(restrictedUid)); 9599 9600 // Enable always-on VPN lockdown. The main user loses network access because no VPN is up. 9601 // Coverage in VpnTest. 9602 final List<Integer> excludedUids = new ArrayList<>(); 9603 excludedUids.add(VPN_UID); 9604 if (mDeps.isAtLeastT()) { 9605 // On T onwards, the corresponding SDK sandbox UID should also be excluded 9606 excludedUids.add(toSdkSandboxUid(VPN_UID)); 9607 } 9608 final List<Range<Integer>> primaryRanges = intRangesPrimaryExcludingUids(excludedUids); 9609 mCm.setRequireVpnForUids(true, primaryRanges); 9610 9611 waitForIdle(); 9612 assertNull(mCm.getActiveNetworkForUid(uid)); 9613 // This is arguably overspecified: a UID that is not running doesn't have an active network. 9614 // But it's useful to check that non-default users do not lose network access, and to prove 9615 // that the loss of connectivity below is indeed due to the restricted profile coming up. 9616 assertNotNull(mCm.getActiveNetworkForUid(restrictedUid)); 9617 9618 // Start the restricted profile, and check that the UID within it loses network access. 9619 // TODO: check that VPN app within restricted profile still has access, etc. 9620 // Add a restricted user. 9621 // This is equivalent to `mMockVpn.onUserAdded(RESTRICTED_USER);`, coverage in VpnTest. 9622 final List<Range<Integer>> restrictedRanges = 9623 intRangesExcludingUids(RESTRICTED_USER, excludedUids); 9624 mCm.setRequireVpnForUids(true, restrictedRanges); 9625 waitForIdle(); 9626 9627 assertNull(mCm.getActiveNetworkForUid(uid)); 9628 assertNull(mCm.getActiveNetworkForUid(restrictedUid)); 9629 9630 // Stop the restricted profile, and check that the UID within it has network access again. 9631 // Remove the restricted user. 9632 // This is equivalent to `mMockVpn.onUserRemoved(RESTRICTED_USER);`, coverage in VpnTest. 9633 mCm.setRequireVpnForUids(false, restrictedRanges); 9634 waitForIdle(); 9635 9636 assertNull(mCm.getActiveNetworkForUid(uid)); 9637 assertNotNull(mCm.getActiveNetworkForUid(restrictedUid)); 9638 9639 mCm.setRequireVpnForUids(false, primaryRanges); 9640 9641 waitForIdle(); 9642 } 9643 9644 @Test 9645 public void testIsActiveNetworkMeteredOverWifi() throws Exception { 9646 // Returns true by default when no network is available. 9647 assertTrue(mCm.isActiveNetworkMetered()); 9648 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 9649 mWiFiAgent.addCapability(NET_CAPABILITY_NOT_METERED); 9650 mWiFiAgent.connect(true); 9651 waitForIdle(); 9652 9653 assertFalse(mCm.isActiveNetworkMetered()); 9654 } 9655 9656 @Test 9657 public void testIsActiveNetworkMeteredOverCell() throws Exception { 9658 // Returns true by default when no network is available. 9659 assertTrue(mCm.isActiveNetworkMetered()); 9660 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 9661 mCellAgent.removeCapability(NET_CAPABILITY_NOT_METERED); 9662 mCellAgent.connect(true); 9663 waitForIdle(); 9664 9665 assertTrue(mCm.isActiveNetworkMetered()); 9666 } 9667 9668 @Test 9669 public void testIsActiveNetworkMeteredOverVpnTrackingPlatformDefault() throws Exception { 9670 // Returns true by default when no network is available. 9671 assertTrue(mCm.isActiveNetworkMetered()); 9672 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 9673 mCellAgent.removeCapability(NET_CAPABILITY_NOT_METERED); 9674 mCellAgent.connect(true); 9675 waitForIdle(); 9676 assertTrue(mCm.isActiveNetworkMetered()); 9677 9678 // Connect VPN network. By default it is using current default network (Cell). 9679 mMockVpn.establishForMyUid(); 9680 assertUidRangesUpdatedForMyUid(true); 9681 9682 // Ensure VPN is now the active network. 9683 assertEquals(mMockVpn.getNetwork(), mCm.getActiveNetwork()); 9684 9685 // Expect VPN to be metered. 9686 assertTrue(mCm.isActiveNetworkMetered()); 9687 9688 // Connect WiFi. 9689 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 9690 mWiFiAgent.addCapability(NET_CAPABILITY_NOT_METERED); 9691 mWiFiAgent.connect(true); 9692 waitForIdle(); 9693 // VPN should still be the active network. 9694 assertEquals(mMockVpn.getNetwork(), mCm.getActiveNetwork()); 9695 9696 // Expect VPN to be unmetered as it should now be using WiFi (new default). 9697 assertFalse(mCm.isActiveNetworkMetered()); 9698 9699 // Disconnecting Cell should not affect VPN's meteredness. 9700 mCellAgent.disconnect(); 9701 waitForIdle(); 9702 9703 assertFalse(mCm.isActiveNetworkMetered()); 9704 9705 // Disconnect WiFi; Now there is no platform default network. 9706 mWiFiAgent.disconnect(); 9707 waitForIdle(); 9708 9709 // VPN without any underlying networks is treated as metered. 9710 assertTrue(mCm.isActiveNetworkMetered()); 9711 9712 mMockVpn.disconnect(); 9713 } 9714 9715 @Test 9716 public void testIsActiveNetworkMeteredOverVpnSpecifyingUnderlyingNetworks() throws Exception { 9717 // Returns true by default when no network is available. 9718 assertTrue(mCm.isActiveNetworkMetered()); 9719 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 9720 mCellAgent.removeCapability(NET_CAPABILITY_NOT_METERED); 9721 mCellAgent.connect(true); 9722 waitForIdle(); 9723 assertTrue(mCm.isActiveNetworkMetered()); 9724 9725 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 9726 mWiFiAgent.addCapability(NET_CAPABILITY_NOT_METERED); 9727 mWiFiAgent.connect(true); 9728 waitForIdle(); 9729 assertFalse(mCm.isActiveNetworkMetered()); 9730 9731 // Connect VPN network. 9732 mMockVpn.establishForMyUid(); 9733 assertUidRangesUpdatedForMyUid(true); 9734 9735 // Ensure VPN is now the active network. 9736 assertEquals(mMockVpn.getNetwork(), mCm.getActiveNetwork()); 9737 // VPN is using Cell 9738 mMockVpn.setUnderlyingNetworks(new Network[] { mCellAgent.getNetwork() }); 9739 waitForIdle(); 9740 9741 // Expect VPN to be metered. 9742 assertTrue(mCm.isActiveNetworkMetered()); 9743 9744 // VPN is now using WiFi 9745 mMockVpn.setUnderlyingNetworks(new Network[] { mWiFiAgent.getNetwork() }); 9746 waitForIdle(); 9747 9748 // Expect VPN to be unmetered 9749 assertFalse(mCm.isActiveNetworkMetered()); 9750 9751 // VPN is using Cell | WiFi. 9752 mMockVpn.setUnderlyingNetworks( 9753 new Network[] { mCellAgent.getNetwork(), mWiFiAgent.getNetwork() }); 9754 waitForIdle(); 9755 9756 // Expect VPN to be metered. 9757 assertTrue(mCm.isActiveNetworkMetered()); 9758 9759 // VPN is using WiFi | Cell. 9760 mMockVpn.setUnderlyingNetworks( 9761 new Network[] { mWiFiAgent.getNetwork(), mCellAgent.getNetwork() }); 9762 waitForIdle(); 9763 9764 // Order should not matter and VPN should still be metered. 9765 assertTrue(mCm.isActiveNetworkMetered()); 9766 9767 // VPN is not using any underlying networks. 9768 mMockVpn.setUnderlyingNetworks(new Network[0]); 9769 waitForIdle(); 9770 9771 // VPN without underlying networks is treated as metered. 9772 assertTrue(mCm.isActiveNetworkMetered()); 9773 9774 mMockVpn.disconnect(); 9775 } 9776 9777 @Test 9778 public void testIsActiveNetworkMeteredOverAlwaysMeteredVpn() throws Exception { 9779 // Returns true by default when no network is available. 9780 assertTrue(mCm.isActiveNetworkMetered()); 9781 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 9782 mWiFiAgent.addCapability(NET_CAPABILITY_NOT_METERED); 9783 mWiFiAgent.connect(true); 9784 waitForIdle(); 9785 assertFalse(mCm.isActiveNetworkMetered()); 9786 9787 // Connect VPN network. 9788 mMockVpn.registerAgent(true /* isAlwaysMetered */, uidRangesForUids(Process.myUid()), 9789 new LinkProperties()); 9790 mMockVpn.connect(true); 9791 waitForIdle(); 9792 assertEquals(mMockVpn.getNetwork(), mCm.getActiveNetwork()); 9793 9794 // VPN is tracking current platform default (WiFi). 9795 mMockVpn.setUnderlyingNetworks(null); 9796 waitForIdle(); 9797 9798 // Despite VPN using WiFi (which is unmetered), VPN itself is marked as always metered. 9799 assertTrue(mCm.isActiveNetworkMetered()); 9800 9801 9802 // VPN explicitly declares WiFi as its underlying network. 9803 mMockVpn.setUnderlyingNetworks(new Network[] { mWiFiAgent.getNetwork() }); 9804 waitForIdle(); 9805 9806 // Doesn't really matter whether VPN declares its underlying networks explicitly. 9807 assertTrue(mCm.isActiveNetworkMetered()); 9808 9809 // With WiFi lost, VPN is basically without any underlying networks. And in that case it is 9810 // anyways suppose to be metered. 9811 mWiFiAgent.disconnect(); 9812 waitForIdle(); 9813 9814 assertTrue(mCm.isActiveNetworkMetered()); 9815 9816 mMockVpn.disconnect(); 9817 } 9818 9819 private class DetailedBlockedStatusCallback extends TestNetworkCallback { 9820 public void expectAvailableThenValidatedCallbacks(HasNetwork n, int blockedStatus) { 9821 super.expectAvailableThenValidatedCallbacks(n.getNetwork(), blockedStatus, TIMEOUT_MS); 9822 } 9823 public void onBlockedStatusChanged(Network network, int blockedReasons) { 9824 getHistory().add(new CallbackEntry.BlockedStatusInt(network, blockedReasons)); 9825 } 9826 } 9827 9828 @Test 9829 public void testNetworkBlockedStatus() throws Exception { 9830 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback(); 9831 final NetworkRequest cellRequest = new NetworkRequest.Builder() 9832 .addTransportType(TRANSPORT_CELLULAR) 9833 .build(); 9834 mCm.registerNetworkCallback(cellRequest, cellNetworkCallback); 9835 final DetailedBlockedStatusCallback detailedCallback = new DetailedBlockedStatusCallback(); 9836 mCm.registerNetworkCallback(cellRequest, detailedCallback); 9837 9838 mockUidNetworkingBlocked(); 9839 9840 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 9841 mCellAgent.connect(true); 9842 cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 9843 detailedCallback.expectAvailableThenValidatedCallbacks(mCellAgent, BLOCKED_REASON_NONE); 9844 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetwork()); 9845 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 9846 assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 9847 assertExtraInfoFromCmPresent(mCellAgent); 9848 9849 setBlockedReasonChanged(BLOCKED_REASON_BATTERY_SAVER); 9850 cellNetworkCallback.expect(BLOCKED_STATUS, mCellAgent, cb -> cb.getBlocked()); 9851 detailedCallback.expect(BLOCKED_STATUS_INT, mCellAgent, 9852 cb -> cb.getReason() == BLOCKED_REASON_BATTERY_SAVER); 9853 assertNull(mCm.getActiveNetwork()); 9854 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); 9855 assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); 9856 assertExtraInfoFromCmBlocked(mCellAgent); 9857 9858 // If blocked state does not change but blocked reason does, the boolean callback is called. 9859 // TODO: investigate de-duplicating. 9860 setBlockedReasonChanged(BLOCKED_METERED_REASON_USER_RESTRICTED); 9861 cellNetworkCallback.expect(BLOCKED_STATUS, mCellAgent, cb -> cb.getBlocked()); 9862 detailedCallback.expect(BLOCKED_STATUS_INT, mCellAgent, 9863 cb -> cb.getReason() == BLOCKED_METERED_REASON_USER_RESTRICTED); 9864 9865 setBlockedReasonChanged(BLOCKED_REASON_NONE); 9866 cellNetworkCallback.expect(BLOCKED_STATUS, mCellAgent, cb -> !cb.getBlocked()); 9867 detailedCallback.expect(BLOCKED_STATUS_INT, mCellAgent, 9868 cb -> cb.getReason() == BLOCKED_REASON_NONE); 9869 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetwork()); 9870 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 9871 assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 9872 assertExtraInfoFromCmPresent(mCellAgent); 9873 9874 setBlockedReasonChanged(BLOCKED_METERED_REASON_DATA_SAVER); 9875 cellNetworkCallback.expect(BLOCKED_STATUS, mCellAgent, cb -> cb.getBlocked()); 9876 detailedCallback.expect(BLOCKED_STATUS_INT, mCellAgent, 9877 cb -> cb.getReason() == BLOCKED_METERED_REASON_DATA_SAVER); 9878 assertNull(mCm.getActiveNetwork()); 9879 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); 9880 assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); 9881 assertExtraInfoFromCmBlocked(mCellAgent); 9882 9883 // Restrict the network based on UID rule and NOT_METERED capability change. 9884 mCellAgent.addCapability(NET_CAPABILITY_NOT_METERED); 9885 cellNetworkCallback.expectCaps(mCellAgent, 9886 c -> c.hasCapability(NET_CAPABILITY_NOT_METERED)); 9887 cellNetworkCallback.expect(BLOCKED_STATUS, mCellAgent, cb -> !cb.getBlocked()); 9888 detailedCallback.expectCaps(mCellAgent, c -> c.hasCapability(NET_CAPABILITY_NOT_METERED)); 9889 detailedCallback.expect(BLOCKED_STATUS_INT, mCellAgent, 9890 cb -> cb.getReason() == BLOCKED_REASON_NONE); 9891 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetwork()); 9892 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 9893 assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 9894 assertExtraInfoFromCmPresent(mCellAgent); 9895 9896 mCellAgent.removeCapability(NET_CAPABILITY_NOT_METERED); 9897 cellNetworkCallback.expectCaps(mCellAgent, 9898 c -> !c.hasCapability(NET_CAPABILITY_NOT_METERED)); 9899 cellNetworkCallback.expect(BLOCKED_STATUS, mCellAgent, cb -> cb.getBlocked()); 9900 detailedCallback.expectCaps(mCellAgent, 9901 c -> !c.hasCapability(NET_CAPABILITY_NOT_METERED)); 9902 detailedCallback.expect(BLOCKED_STATUS_INT, mCellAgent, 9903 cb -> cb.getReason() == BLOCKED_METERED_REASON_DATA_SAVER); 9904 assertNull(mCm.getActiveNetwork()); 9905 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); 9906 assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); 9907 assertExtraInfoFromCmBlocked(mCellAgent); 9908 9909 setBlockedReasonChanged(BLOCKED_REASON_NONE); 9910 cellNetworkCallback.expect(BLOCKED_STATUS, mCellAgent, cb -> !cb.getBlocked()); 9911 detailedCallback.expect(BLOCKED_STATUS_INT, mCellAgent, 9912 cb -> cb.getReason() == BLOCKED_REASON_NONE); 9913 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetwork()); 9914 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 9915 assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 9916 assertExtraInfoFromCmPresent(mCellAgent); 9917 9918 setBlockedReasonChanged(BLOCKED_REASON_NONE); 9919 cellNetworkCallback.assertNoCallback(); 9920 detailedCallback.assertNoCallback(); 9921 9922 // Restrict background data. Networking is not blocked because the network is unmetered. 9923 setBlockedReasonChanged(BLOCKED_METERED_REASON_DATA_SAVER); 9924 cellNetworkCallback.expect(BLOCKED_STATUS, mCellAgent, cb -> cb.getBlocked()); 9925 detailedCallback.expect(BLOCKED_STATUS_INT, mCellAgent, 9926 cb -> cb.getReason() == BLOCKED_METERED_REASON_DATA_SAVER); 9927 assertNull(mCm.getActiveNetwork()); 9928 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); 9929 assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); 9930 assertExtraInfoFromCmBlocked(mCellAgent); 9931 setBlockedReasonChanged(BLOCKED_METERED_REASON_DATA_SAVER); 9932 cellNetworkCallback.assertNoCallback(); 9933 9934 setBlockedReasonChanged(BLOCKED_REASON_NONE); 9935 cellNetworkCallback.expect(BLOCKED_STATUS, mCellAgent, cb -> !cb.getBlocked()); 9936 detailedCallback.expect(BLOCKED_STATUS_INT, mCellAgent, 9937 cb -> cb.getReason() == BLOCKED_REASON_NONE); 9938 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 9939 assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 9940 assertExtraInfoFromCmPresent(mCellAgent); 9941 9942 setBlockedReasonChanged(BLOCKED_REASON_NONE); 9943 cellNetworkCallback.assertNoCallback(); 9944 detailedCallback.assertNoCallback(); 9945 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetwork()); 9946 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 9947 assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 9948 assertExtraInfoFromCmPresent(mCellAgent); 9949 9950 // Remove PERMISSION_INTERNET and disable NETWORK_BLOCKED_WITHOUT_INTERNET_PERMISSION 9951 doReturn(INetd.PERMISSION_NONE).when(mBpfNetMaps).getNetPermForUid(Process.myUid()); 9952 mDeps.setChangeIdEnabled(false, 9953 NETWORK_BLOCKED_WITHOUT_INTERNET_PERMISSION, Process.myUid()); 9954 9955 setBlockedReasonChanged(BLOCKED_REASON_DOZE); 9956 if (mDeps.isAtLeastV()) { 9957 // On V+, network access from app that does not have INTERNET permission is considered 9958 // not blocked if NETWORK_BLOCKED_WITHOUT_INTERNET_PERMISSION is disabled. 9959 // So blocked status does not change from BLOCKED_REASON_NONE 9960 cellNetworkCallback.assertNoCallback(); 9961 detailedCallback.assertNoCallback(); 9962 } else { 9963 // On U-, onBlockedStatusChanged callback is called with blocked reasons CS receives 9964 // from NPMS callback regardless of permission app has. 9965 // Note that this cannot actually happen because on U-, NPMS will never notify any 9966 // blocked reasons for apps that don't have the INTERNET permission. 9967 cellNetworkCallback.expect(BLOCKED_STATUS, mCellAgent, cb -> cb.getBlocked()); 9968 detailedCallback.expect(BLOCKED_STATUS_INT, mCellAgent, 9969 cb -> cb.getReason() == BLOCKED_REASON_DOZE); 9970 } 9971 9972 mCm.unregisterNetworkCallback(cellNetworkCallback); 9973 } 9974 9975 @Test 9976 public void testNetworkBlockedStatusBeforeAndAfterConnect() throws Exception { 9977 final TestNetworkCallback defaultCallback = new TestNetworkCallback(); 9978 mCm.registerDefaultNetworkCallback(defaultCallback); 9979 mockUidNetworkingBlocked(); 9980 9981 // No Networkcallbacks invoked before any network is active. 9982 setBlockedReasonChanged(BLOCKED_REASON_BATTERY_SAVER); 9983 setBlockedReasonChanged(BLOCKED_REASON_NONE); 9984 setBlockedReasonChanged(BLOCKED_METERED_REASON_DATA_SAVER); 9985 defaultCallback.assertNoCallback(); 9986 9987 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 9988 mCellAgent.connect(true); 9989 defaultCallback.expectAvailableCallbacksUnvalidatedAndBlocked(mCellAgent); 9990 defaultCallback.expectCaps(mCellAgent, c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 9991 9992 // Allow to use the network after switching to NOT_METERED network. 9993 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 9994 mWiFiAgent.addCapability(NET_CAPABILITY_NOT_METERED); 9995 mWiFiAgent.connect(true); 9996 defaultCallback.expectAvailableDoubleValidatedCallbacks(mWiFiAgent); 9997 9998 // Switch to METERED network. Restrict the use of the network. 9999 mWiFiAgent.disconnect(); 10000 defaultCallback.expect(LOST, mWiFiAgent); 10001 defaultCallback.expectAvailableCallbacksValidatedAndBlocked(mCellAgent); 10002 10003 // Network becomes NOT_METERED. 10004 mCellAgent.addCapability(NET_CAPABILITY_NOT_METERED); 10005 defaultCallback.expectCaps(mCellAgent, c -> c.hasCapability(NET_CAPABILITY_NOT_METERED)); 10006 defaultCallback.expect(BLOCKED_STATUS, mCellAgent, cb -> !cb.getBlocked()); 10007 10008 // Verify there's no Networkcallbacks invoked after data saver on/off. 10009 setBlockedReasonChanged(BLOCKED_METERED_REASON_DATA_SAVER); 10010 setBlockedReasonChanged(BLOCKED_REASON_NONE); 10011 defaultCallback.assertNoCallback(); 10012 10013 mCellAgent.disconnect(); 10014 defaultCallback.expect(LOST, mCellAgent); 10015 defaultCallback.assertNoCallback(); 10016 10017 mCm.unregisterNetworkCallback(defaultCallback); 10018 } 10019 10020 private void expectNetworkRejectNonSecureVpn(InOrder inOrder, boolean add, 10021 UidRangeParcel... expected) throws Exception { 10022 inOrder.verify(mMockNetd).networkRejectNonSecureVpn(eq(add), aryEq(expected)); 10023 } 10024 10025 private void checkNetworkInfo(NetworkInfo ni, int type, DetailedState state) { 10026 assertNotNull(ni); 10027 assertEquals(type, ni.getType()); 10028 assertEquals(ConnectivityManager.getNetworkTypeName(type), state, ni.getDetailedState()); 10029 if (state == DetailedState.CONNECTED || state == DetailedState.SUSPENDED) { 10030 assertNotNull(ni.getExtraInfo()); 10031 } else { 10032 // Technically speaking, a network that's in CONNECTING state will generally have a 10033 // non-null extraInfo. This doesn't actually happen in this test because it never calls 10034 // a legacy API while a network is connecting. When a network is in CONNECTING state 10035 // because of legacy lockdown VPN, its extraInfo is always null. 10036 assertNull(ni.getExtraInfo()); 10037 } 10038 } 10039 10040 private void assertActiveNetworkInfo(int type, DetailedState state) { 10041 checkNetworkInfo(mCm.getActiveNetworkInfo(), type, state); 10042 } 10043 private void assertNetworkInfo(int type, DetailedState state) { 10044 checkNetworkInfo(mCm.getNetworkInfo(type), type, state); 10045 } 10046 10047 private void assertExtraInfoFromCm(TestNetworkAgentWrapper network, boolean present) { 10048 final NetworkInfo niForNetwork = mCm.getNetworkInfo(network.getNetwork()); 10049 final NetworkInfo niForType = mCm.getNetworkInfo(network.getLegacyType()); 10050 if (present) { 10051 assertEquals(network.getExtraInfo(), niForNetwork.getExtraInfo()); 10052 assertEquals(network.getExtraInfo(), niForType.getExtraInfo()); 10053 } else { 10054 assertNull(niForNetwork.getExtraInfo()); 10055 assertNull(niForType.getExtraInfo()); 10056 } 10057 } 10058 10059 private void assertExtraInfoFromCmBlocked(TestNetworkAgentWrapper network) { 10060 assertExtraInfoFromCm(network, false); 10061 } 10062 10063 private void assertExtraInfoFromCmPresent(TestNetworkAgentWrapper network) { 10064 assertExtraInfoFromCm(network, true); 10065 } 10066 10067 // Checks that each of the |agents| receive a blocked status change callback with the specified 10068 // |blocked| value, in any order. This is needed because when an event affects multiple 10069 // networks, ConnectivityService does not guarantee the order in which callbacks are fired. 10070 private void assertBlockedCallbackInAnyOrder(TestNetworkCallback callback, boolean blocked, 10071 TestNetworkAgentWrapper... agents) { 10072 final List<Network> expectedNetworks = asList(agents).stream() 10073 .map((agent) -> agent.getNetwork()) 10074 .collect(Collectors.toList()); 10075 10076 // Expect exactly one blocked callback for each agent. 10077 for (int i = 0; i < agents.length; i++) { 10078 final CallbackEntry e = callback.expect(BLOCKED_STATUS, TIMEOUT_MS, 10079 c -> c.getBlocked() == blocked); 10080 final Network network = e.getNetwork(); 10081 assertTrue("Received unexpected blocked callback for network " + network, 10082 expectedNetworks.remove(network)); 10083 } 10084 } 10085 10086 @Test 10087 public void testNetworkBlockedStatusAlwaysOnVpn() throws Exception { 10088 mServiceContext.setPermission( 10089 Manifest.permission.CONTROL_ALWAYS_ON_VPN, PERMISSION_GRANTED); 10090 mServiceContext.setPermission( 10091 Manifest.permission.CONTROL_VPN, PERMISSION_GRANTED); 10092 mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_GRANTED); 10093 10094 final TestNetworkCallback callback = new TestNetworkCallback(); 10095 final NetworkRequest request = new NetworkRequest.Builder() 10096 .removeCapability(NET_CAPABILITY_NOT_VPN) 10097 .build(); 10098 mCm.registerNetworkCallback(request, callback); 10099 10100 final TestNetworkCallback defaultCallback = new TestNetworkCallback(); 10101 mCm.registerDefaultNetworkCallback(defaultCallback); 10102 10103 final TestNetworkCallback vpnUidCallback = new TestNetworkCallback(); 10104 final NetworkRequest vpnUidRequest = new NetworkRequest.Builder().build(); 10105 registerNetworkCallbackAsUid(vpnUidRequest, vpnUidCallback, VPN_UID); 10106 10107 final TestNetworkCallback vpnUidDefaultCallback = new TestNetworkCallback(); 10108 registerDefaultNetworkCallbackAsUid(vpnUidDefaultCallback, VPN_UID); 10109 10110 final TestNetworkCallback vpnDefaultCallbackAsUid = new TestNetworkCallback(); 10111 mCm.registerDefaultNetworkCallbackForUid(VPN_UID, vpnDefaultCallbackAsUid, 10112 new Handler(ConnectivityThread.getInstanceLooper())); 10113 10114 final int uid = Process.myUid(); 10115 10116 // Enable always-on VPN lockdown, coverage in VpnTest. 10117 final List<Integer> excludedUids = new ArrayList<Integer>(); 10118 excludedUids.add(VPN_UID); 10119 if (mDeps.isAtLeastT()) { 10120 // On T onwards, the corresponding SDK sandbox UID should also be excluded 10121 excludedUids.add(toSdkSandboxUid(VPN_UID)); 10122 } 10123 10124 final List<Range<Integer>> primaryRanges = intRangesPrimaryExcludingUids(excludedUids); 10125 mCm.setRequireVpnForUids(true, primaryRanges); 10126 waitForIdle(); 10127 10128 final UidRangeParcel[] uidRangeParcels = intToUidRangeStableParcels(primaryRanges); 10129 InOrder inOrder = inOrder(mMockNetd); 10130 expectNetworkRejectNonSecureVpn(inOrder, true, uidRangeParcels); 10131 10132 // Connect a network when lockdown is active, expect to see it blocked. 10133 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 10134 mWiFiAgent.connect(false /* validated */); 10135 callback.expectAvailableCallbacksUnvalidatedAndBlocked(mWiFiAgent); 10136 defaultCallback.expectAvailableCallbacksUnvalidatedAndBlocked(mWiFiAgent); 10137 vpnUidCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 10138 vpnUidDefaultCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 10139 vpnDefaultCallbackAsUid.expectAvailableCallbacksUnvalidated(mWiFiAgent); 10140 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetworkForUid(VPN_UID)); 10141 assertNull(mCm.getActiveNetwork()); 10142 assertActiveNetworkInfo(TYPE_WIFI, DetailedState.BLOCKED); 10143 // Mobile is BLOCKED even though it's not actually connected. 10144 assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); 10145 assertNetworkInfo(TYPE_WIFI, DetailedState.BLOCKED); 10146 10147 // Disable lockdown, expect to see the network unblocked. 10148 mCm.setRequireVpnForUids(false, primaryRanges); 10149 waitForIdle(); 10150 callback.expect(BLOCKED_STATUS, mWiFiAgent, cb -> !cb.getBlocked()); 10151 defaultCallback.expect(BLOCKED_STATUS, mWiFiAgent, cb -> !cb.getBlocked()); 10152 vpnUidCallback.assertNoCallback(); 10153 vpnUidDefaultCallback.assertNoCallback(); 10154 vpnDefaultCallbackAsUid.assertNoCallback(); 10155 expectNetworkRejectNonSecureVpn(inOrder, false, uidRangeParcels); 10156 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetworkForUid(VPN_UID)); 10157 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetwork()); 10158 assertActiveNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 10159 assertNetworkInfo(TYPE_MOBILE, DetailedState.DISCONNECTED); 10160 assertNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 10161 10162 // Add our UID to the allowlist, expect network is not blocked. Coverage in VpnTest. 10163 excludedUids.add(uid); 10164 if (mDeps.isAtLeastT()) { 10165 // On T onwards, the corresponding SDK sandbox UID should also be excluded 10166 excludedUids.add(toSdkSandboxUid(uid)); 10167 } 10168 final List<Range<Integer>> primaryRangesExcludingUid = 10169 intRangesPrimaryExcludingUids(excludedUids); 10170 mCm.setRequireVpnForUids(true, primaryRangesExcludingUid); 10171 waitForIdle(); 10172 10173 callback.assertNoCallback(); 10174 defaultCallback.assertNoCallback(); 10175 vpnUidCallback.assertNoCallback(); 10176 vpnUidDefaultCallback.assertNoCallback(); 10177 vpnDefaultCallbackAsUid.assertNoCallback(); 10178 10179 final UidRangeParcel[] uidRangeParcelsAlsoExcludingUs = 10180 intToUidRangeStableParcels(primaryRangesExcludingUid); 10181 expectNetworkRejectNonSecureVpn(inOrder, true, uidRangeParcelsAlsoExcludingUs); 10182 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetworkForUid(VPN_UID)); 10183 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetwork()); 10184 assertActiveNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 10185 assertNetworkInfo(TYPE_MOBILE, DetailedState.DISCONNECTED); 10186 assertNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 10187 10188 // Connect a new network, expect it to be unblocked. 10189 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 10190 mCellAgent.connect(false /* validated */); 10191 callback.expectAvailableCallbacksUnvalidated(mCellAgent); 10192 defaultCallback.assertNoCallback(); 10193 vpnUidCallback.expectAvailableCallbacksUnvalidated(mCellAgent); 10194 vpnUidDefaultCallback.assertNoCallback(); 10195 vpnDefaultCallbackAsUid.assertNoCallback(); 10196 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetworkForUid(VPN_UID)); 10197 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetwork()); 10198 assertActiveNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 10199 // Cellular is DISCONNECTED because it's not the default and there are no requests for it. 10200 assertNetworkInfo(TYPE_MOBILE, DetailedState.DISCONNECTED); 10201 assertNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 10202 10203 // Disable lockdown 10204 mCm.setRequireVpnForUids(false, primaryRangesExcludingUid); 10205 waitForIdle(); 10206 expectNetworkRejectNonSecureVpn(inOrder, false, uidRangeParcelsAlsoExcludingUs); 10207 // Remove our UID from the allowlist, and re-enable lockdown. 10208 mCm.setRequireVpnForUids(true, primaryRanges); 10209 waitForIdle(); 10210 expectNetworkRejectNonSecureVpn(inOrder, true, uidRangeParcels); 10211 // Everything should now be blocked. 10212 defaultCallback.expect(BLOCKED_STATUS, mWiFiAgent, cb -> cb.getBlocked()); 10213 assertBlockedCallbackInAnyOrder(callback, true, mWiFiAgent, mCellAgent); 10214 vpnUidCallback.assertNoCallback(); 10215 vpnUidDefaultCallback.assertNoCallback(); 10216 vpnDefaultCallbackAsUid.assertNoCallback(); 10217 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetworkForUid(VPN_UID)); 10218 assertNull(mCm.getActiveNetwork()); 10219 assertActiveNetworkInfo(TYPE_WIFI, DetailedState.BLOCKED); 10220 assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); 10221 assertNetworkInfo(TYPE_WIFI, DetailedState.BLOCKED); 10222 10223 // Disable lockdown. Everything is unblocked. 10224 mCm.setRequireVpnForUids(false, primaryRanges); 10225 defaultCallback.expect(BLOCKED_STATUS, mWiFiAgent, cb -> !cb.getBlocked()); 10226 assertBlockedCallbackInAnyOrder(callback, false, mWiFiAgent, mCellAgent); 10227 vpnUidCallback.assertNoCallback(); 10228 vpnUidDefaultCallback.assertNoCallback(); 10229 vpnDefaultCallbackAsUid.assertNoCallback(); 10230 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetworkForUid(VPN_UID)); 10231 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetwork()); 10232 assertActiveNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 10233 assertNetworkInfo(TYPE_MOBILE, DetailedState.DISCONNECTED); 10234 assertNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 10235 10236 // Enable lockdown and connect a VPN. The VPN is not blocked. 10237 mCm.setRequireVpnForUids(true, primaryRanges); 10238 defaultCallback.expect(BLOCKED_STATUS, mWiFiAgent, cb -> cb.getBlocked()); 10239 assertBlockedCallbackInAnyOrder(callback, true, mWiFiAgent, mCellAgent); 10240 vpnUidCallback.assertNoCallback(); 10241 vpnUidDefaultCallback.assertNoCallback(); 10242 vpnDefaultCallbackAsUid.assertNoCallback(); 10243 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetworkForUid(VPN_UID)); 10244 assertNull(mCm.getActiveNetwork()); 10245 assertActiveNetworkInfo(TYPE_WIFI, DetailedState.BLOCKED); 10246 assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); 10247 assertNetworkInfo(TYPE_WIFI, DetailedState.BLOCKED); 10248 10249 mMockVpn.establishForMyUid(); 10250 assertUidRangesUpdatedForMyUid(true); 10251 defaultCallback.expectAvailableThenValidatedCallbacks(mMockVpn); 10252 vpnUidCallback.assertNoCallback(); // vpnUidCallback has NOT_VPN capability. 10253 vpnUidDefaultCallback.assertNoCallback(); // VPN does not apply to VPN_UID 10254 vpnDefaultCallbackAsUid.assertNoCallback(); 10255 assertEquals(mMockVpn.getNetwork(), mCm.getActiveNetwork()); 10256 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetworkForUid(VPN_UID)); 10257 assertActiveNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 10258 assertNetworkInfo(TYPE_MOBILE, DetailedState.DISCONNECTED); 10259 assertNetworkInfo(TYPE_VPN, DetailedState.CONNECTED); 10260 assertNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 10261 10262 mMockVpn.disconnect(); 10263 defaultCallback.expect(LOST, mMockVpn); 10264 defaultCallback.expectAvailableCallbacksUnvalidatedAndBlocked(mWiFiAgent); 10265 vpnUidCallback.assertNoCallback(); 10266 vpnUidDefaultCallback.assertNoCallback(); 10267 vpnDefaultCallbackAsUid.assertNoCallback(); 10268 assertNull(mCm.getActiveNetwork()); 10269 10270 mCm.unregisterNetworkCallback(callback); 10271 mCm.unregisterNetworkCallback(defaultCallback); 10272 mCm.unregisterNetworkCallback(vpnUidCallback); 10273 mCm.unregisterNetworkCallback(vpnUidDefaultCallback); 10274 mCm.unregisterNetworkCallback(vpnDefaultCallbackAsUid); 10275 } 10276 10277 @Test 10278 public void testVpnExcludesOwnUid() throws Exception { 10279 // required for registerDefaultNetworkCallbackForUid. 10280 mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_GRANTED); 10281 10282 // Connect Wi-Fi. 10283 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 10284 mWiFiAgent.connect(true /* validated */); 10285 10286 // Connect a VPN that excludes its UID from its UID ranges. 10287 final LinkProperties lp = new LinkProperties(); 10288 lp.setInterfaceName(VPN_IFNAME); 10289 final int myUid = Process.myUid(); 10290 final Set<UidRange> ranges = new ArraySet<>(); 10291 ranges.add(new UidRange(0, myUid - 1)); 10292 ranges.add(new UidRange(myUid + 1, UserHandle.PER_USER_RANGE - 1)); 10293 mMockVpn.setUnderlyingNetworks(new Network[] { mWiFiAgent.getNetwork() }); 10294 mMockVpn.establish(lp, myUid, ranges); 10295 10296 // Wait for validation before registering callbacks. 10297 waitForIdle(); 10298 10299 final int otherUid = myUid + 1; 10300 final Handler h = new Handler(ConnectivityThread.getInstanceLooper()); 10301 final TestNetworkCallback otherUidCb = new TestNetworkCallback(); 10302 final TestNetworkCallback defaultCb = new TestNetworkCallback(); 10303 final TestNetworkCallback perUidCb = new TestNetworkCallback(); 10304 registerDefaultNetworkCallbackAsUid(otherUidCb, otherUid); 10305 mCm.registerDefaultNetworkCallback(defaultCb, h); 10306 doAsUid(Process.SYSTEM_UID, 10307 () -> mCm.registerDefaultNetworkCallbackForUid(myUid, perUidCb, h)); 10308 10309 otherUidCb.expectAvailableCallbacksValidated(mMockVpn); 10310 // BUG (b/195265065): the default network for the VPN app is actually Wi-Fi, not the VPN. 10311 defaultCb.expectAvailableCallbacksValidated(mMockVpn); 10312 perUidCb.expectAvailableCallbacksValidated(mMockVpn); 10313 // getActiveNetwork is not affected by this bug. 10314 assertEquals(mMockVpn.getNetwork(), mCm.getActiveNetworkForUid(myUid + 1)); 10315 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetwork()); 10316 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetworkForUid(myUid)); 10317 10318 doAsUid(otherUid, () -> mCm.unregisterNetworkCallback(otherUidCb)); 10319 mCm.unregisterNetworkCallback(defaultCb); 10320 doAsUid(Process.SYSTEM_UID, () -> mCm.unregisterNetworkCallback(perUidCb)); 10321 } 10322 10323 private void establishLegacyLockdownVpn(Network underlying) throws Exception { 10324 // The legacy lockdown VPN only supports userId 0, and must have an underlying network. 10325 assertNotNull(underlying); 10326 mMockVpn.setVpnType(VpnManager.TYPE_VPN_LEGACY); 10327 // The legacy lockdown VPN only supports userId 0. 10328 final Set<UidRange> ranges = Collections.singleton(PRIMARY_UIDRANGE); 10329 mMockVpn.registerAgent(ranges); 10330 mMockVpn.setUnderlyingNetworks(new Network[]{underlying}); 10331 mMockVpn.connect(true); 10332 } 10333 10334 private void doTestLockdownVpn(boolean isIkev2Vpn) 10335 throws Exception { 10336 mServiceContext.setPermission( 10337 Manifest.permission.CONTROL_VPN, PERMISSION_GRANTED); 10338 10339 final NetworkRequest request = new NetworkRequest.Builder().clearCapabilities().build(); 10340 final TestNetworkCallback callback = new TestNetworkCallback(); 10341 mCm.registerNetworkCallback(request, callback); 10342 10343 final TestNetworkCallback defaultCallback = new TestNetworkCallback(); 10344 mCm.registerDefaultNetworkCallback(defaultCallback); 10345 10346 final TestNetworkCallback systemDefaultCallback = new TestNetworkCallback(); 10347 mCm.registerSystemDefaultNetworkCallback(systemDefaultCallback, 10348 new Handler(ConnectivityThread.getInstanceLooper())); 10349 10350 // Init lockdown state to simulate LockdownVpnTracker behavior. 10351 mCm.setLegacyLockdownVpnEnabled(true); 10352 final List<Range<Integer>> ranges = 10353 intRangesPrimaryExcludingUids(Collections.EMPTY_LIST /* excludedeUids */); 10354 mCm.setRequireVpnForUids(true /* requireVpn */, ranges); 10355 10356 // Bring up a network. 10357 final LinkProperties cellLp = new LinkProperties(); 10358 cellLp.setInterfaceName("rmnet0"); 10359 cellLp.addLinkAddress(new LinkAddress("192.0.2.2/25")); 10360 cellLp.addRoute(new RouteInfo(new IpPrefix("0.0.0.0/0"), null, "rmnet0")); 10361 // When lockdown VPN is active, the NetworkInfo state in CONNECTIVITY_ACTION is overwritten 10362 // with the state of the VPN network. So expect a CONNECTING broadcast. 10363 final ExpectedBroadcast b = expectConnectivityAction(TYPE_MOBILE, DetailedState.CONNECTING); 10364 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp); 10365 mCellAgent.connect(false /* validated */); 10366 callback.expectAvailableCallbacksUnvalidatedAndBlocked(mCellAgent); 10367 defaultCallback.expectAvailableCallbacksUnvalidatedAndBlocked(mCellAgent); 10368 systemDefaultCallback.expectAvailableCallbacksUnvalidatedAndBlocked(mCellAgent); 10369 b.expectBroadcast(); 10370 // Simulate LockdownVpnTracker attempting to start the VPN since it received the 10371 // systemDefault callback. 10372 mMockVpn.startLegacyVpnPrivileged(isIkev2Vpn); 10373 if (isIkev2Vpn) { 10374 // setVpnDefaultForUids() releases the original network request and creates a VPN 10375 // request so LOST callback is received. 10376 defaultCallback.expect(LOST, mCellAgent); 10377 // Due to the VPN default request, getActiveNetworkInfo() gets the mNoServiceNetwork 10378 // as the network satisfier. 10379 assertNull(mCm.getActiveNetworkInfo()); 10380 } else { 10381 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); 10382 } 10383 assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); 10384 assertNetworkInfo(TYPE_WIFI, DetailedState.BLOCKED); 10385 assertNetworkInfo(TYPE_VPN, DetailedState.BLOCKED); 10386 assertExtraInfoFromCmBlocked(mCellAgent); 10387 10388 final ExpectedBroadcast b2 = expectConnectivityAction(TYPE_VPN, DetailedState.CONNECTED); 10389 final ExpectedBroadcast b3 = expectConnectivityAction(TYPE_MOBILE, DetailedState.CONNECTED); 10390 establishLegacyLockdownVpn(mCellAgent.getNetwork()); 10391 callback.expectAvailableThenValidatedCallbacks(mMockVpn); 10392 defaultCallback.expectAvailableThenValidatedCallbacks(mMockVpn); 10393 systemDefaultCallback.assertNoCallback(); 10394 final NetworkCapabilities vpnNc = mCm.getNetworkCapabilities(mMockVpn.getNetwork()); 10395 b2.expectBroadcast(); 10396 b3.expectBroadcast(); 10397 if (isIkev2Vpn) { 10398 // Due to the VPN default request, getActiveNetworkInfo() gets the VPN network as the 10399 // network satisfier which has TYPE_VPN. 10400 assertActiveNetworkInfo(TYPE_VPN, DetailedState.CONNECTED); 10401 } else { 10402 // LegacyVpnRunner does not call setVpnDefaultsForUids(), which means 10403 // getActiveNetworkInfo() can only return the info for the system-wide default instead. 10404 // This should be fixed, but LegacyVpnRunner will be removed soon anyway. 10405 assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 10406 } 10407 assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); 10408 assertNetworkInfo(TYPE_WIFI, DetailedState.DISCONNECTED); 10409 assertNetworkInfo(TYPE_VPN, DetailedState.CONNECTED); 10410 assertExtraInfoFromCmPresent(mCellAgent); 10411 assertTrue(vpnNc.hasTransport(TRANSPORT_VPN)); 10412 assertTrue(vpnNc.hasTransport(TRANSPORT_CELLULAR)); 10413 assertFalse(vpnNc.hasTransport(TRANSPORT_WIFI)); 10414 assertFalse(vpnNc.hasCapability(NET_CAPABILITY_NOT_METERED)); 10415 assertVpnTransportInfo(vpnNc, VpnManager.TYPE_VPN_LEGACY); 10416 10417 // Switch default network from cell to wifi. Expect VPN to disconnect and reconnect. 10418 final LinkProperties wifiLp = new LinkProperties(); 10419 wifiLp.setInterfaceName("wlan0"); 10420 wifiLp.addLinkAddress(new LinkAddress("192.0.2.163/25")); 10421 wifiLp.addRoute(new RouteInfo(new IpPrefix("0.0.0.0/0"), null, "wlan0")); 10422 final NetworkCapabilities wifiNc = new NetworkCapabilities(); 10423 wifiNc.addTransportType(TRANSPORT_WIFI); 10424 wifiNc.addCapability(NET_CAPABILITY_NOT_METERED); 10425 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, wifiLp, wifiNc); 10426 10427 final ExpectedBroadcast b4 = 10428 expectConnectivityAction(TYPE_MOBILE, DetailedState.DISCONNECTED); 10429 // Wifi is CONNECTING because the VPN isn't up yet. 10430 final ExpectedBroadcast b5 = expectConnectivityAction(TYPE_WIFI, DetailedState.CONNECTING); 10431 mWiFiAgent.connect(false /* validated */); 10432 // Wifi is not blocked since VPN network is still connected. 10433 callback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 10434 defaultCallback.assertNoCallback(); 10435 systemDefaultCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 10436 b4.expectBroadcast(); 10437 b5.expectBroadcast(); 10438 10439 // Simulate LockdownVpnTracker restarting the VPN since it received the systemDefault 10440 // callback with different network. 10441 final ExpectedBroadcast b6 = expectConnectivityAction(TYPE_VPN, DetailedState.DISCONNECTED); 10442 mMockVpn.stopVpnRunnerPrivileged(); 10443 10444 mMockVpn.startLegacyVpnPrivileged(isIkev2Vpn); 10445 // VPN network is disconnected (to restart) 10446 callback.expect(LOST, mMockVpn); 10447 defaultCallback.expect(LOST, mMockVpn); 10448 // The network preference is cleared when VPN is disconnected so it receives callbacks for 10449 // the system-wide default. 10450 defaultCallback.expectAvailableCallbacksUnvalidatedAndBlocked(mWiFiAgent); 10451 if (isIkev2Vpn) { 10452 // setVpnDefaultForUids() releases the original network request and creates a VPN 10453 // request so LOST callback is received. 10454 defaultCallback.expect(LOST, mWiFiAgent); 10455 } 10456 systemDefaultCallback.assertNoCallback(); 10457 b6.expectBroadcast(); 10458 10459 // While the VPN is reconnecting on the new network, everything is blocked. 10460 if (isIkev2Vpn) { 10461 // Due to the VPN default request, getActiveNetworkInfo() gets the mNoServiceNetwork 10462 // as the network satisfier. 10463 assertNull(mCm.getActiveNetworkInfo()); 10464 } else { 10465 assertActiveNetworkInfo(TYPE_WIFI, DetailedState.BLOCKED); 10466 } 10467 assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); 10468 assertNetworkInfo(TYPE_WIFI, DetailedState.BLOCKED); 10469 assertNetworkInfo(TYPE_VPN, DetailedState.BLOCKED); 10470 assertExtraInfoFromCmBlocked(mWiFiAgent); 10471 10472 // The VPN comes up again on wifi. 10473 final ExpectedBroadcast b7 = expectConnectivityAction(TYPE_VPN, DetailedState.CONNECTED); 10474 final ExpectedBroadcast b8 = expectConnectivityAction(TYPE_WIFI, DetailedState.CONNECTED); 10475 establishLegacyLockdownVpn(mWiFiAgent.getNetwork()); 10476 callback.expectAvailableThenValidatedCallbacks(mMockVpn); 10477 defaultCallback.expectAvailableThenValidatedCallbacks(mMockVpn); 10478 systemDefaultCallback.assertNoCallback(); 10479 b7.expectBroadcast(); 10480 b8.expectBroadcast(); 10481 if (isIkev2Vpn) { 10482 // Due to the VPN default request, getActiveNetworkInfo() gets the VPN network as the 10483 // network satisfier which has TYPE_VPN. 10484 assertActiveNetworkInfo(TYPE_VPN, DetailedState.CONNECTED); 10485 } else { 10486 // LegacyVpnRunner does not call setVpnDefaultsForUids(), which means 10487 // getActiveNetworkInfo() can only return the info for the system-wide default instead. 10488 // This should be fixed, but LegacyVpnRunner will be removed soon anyway. 10489 assertActiveNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 10490 } 10491 assertNetworkInfo(TYPE_MOBILE, DetailedState.DISCONNECTED); 10492 assertNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 10493 assertNetworkInfo(TYPE_VPN, DetailedState.CONNECTED); 10494 assertExtraInfoFromCmPresent(mWiFiAgent); 10495 final NetworkCapabilities vpnNc2 = mCm.getNetworkCapabilities(mMockVpn.getNetwork()); 10496 assertTrue(vpnNc2.hasTransport(TRANSPORT_VPN)); 10497 assertTrue(vpnNc2.hasTransport(TRANSPORT_WIFI)); 10498 assertFalse(vpnNc2.hasTransport(TRANSPORT_CELLULAR)); 10499 assertTrue(vpnNc2.hasCapability(NET_CAPABILITY_NOT_METERED)); 10500 10501 // Disconnect cell. Nothing much happens since it's not the default network. 10502 mCellAgent.disconnect(); 10503 callback.expect(LOST, mCellAgent); 10504 defaultCallback.assertNoCallback(); 10505 systemDefaultCallback.assertNoCallback(); 10506 10507 if (isIkev2Vpn) { 10508 // Due to the VPN default request, getActiveNetworkInfo() gets the VPN network as the 10509 // network satisfier which has TYPE_VPN. 10510 assertActiveNetworkInfo(TYPE_VPN, DetailedState.CONNECTED); 10511 } else { 10512 // LegacyVpnRunner does not call setVpnDefaultsForUids(), which means 10513 // getActiveNetworkInfo() can only return the info for the system-wide default instead. 10514 // This should be fixed, but LegacyVpnRunner will be removed soon anyway. 10515 assertActiveNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 10516 } 10517 assertNetworkInfo(TYPE_MOBILE, DetailedState.DISCONNECTED); 10518 assertNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); 10519 assertNetworkInfo(TYPE_VPN, DetailedState.CONNECTED); 10520 assertExtraInfoFromCmPresent(mWiFiAgent); 10521 10522 final ExpectedBroadcast b9 = 10523 expectConnectivityAction(TYPE_WIFI, DetailedState.DISCONNECTED); 10524 final ExpectedBroadcast b10 = 10525 expectConnectivityAction(TYPE_VPN, DetailedState.DISCONNECTED); 10526 mWiFiAgent.disconnect(); 10527 callback.expect(LOST, mWiFiAgent); 10528 callback.expectCaps(mMockVpn, c -> !c.hasTransport(TRANSPORT_WIFI)); 10529 defaultCallback.expectCaps(mMockVpn, c -> !c.hasTransport(TRANSPORT_WIFI)); 10530 systemDefaultCallback.expect(LOST, mWiFiAgent); 10531 // TODO: There should only be one LOST callback. Since the WIFI network is underlying a VPN 10532 // network, ConnectivityService#propagateUnderlyingNetworkCapabilities() causes a rematch to 10533 // occur. Notably, this happens before setting the satisfiers of its network requests to 10534 // null. Since the satisfiers are set to null in the rematch, an extra LOST callback is 10535 // called. 10536 systemDefaultCallback.expect(LOST, mWiFiAgent); 10537 b9.expectBroadcast(); 10538 mMockVpn.stopVpnRunnerPrivileged(); 10539 callback.expect(LOST, mMockVpn); 10540 defaultCallback.expect(LOST, mMockVpn); 10541 b10.expectBroadcast(); 10542 10543 assertNoCallbacks(callback, defaultCallback, systemDefaultCallback); 10544 } 10545 10546 @Test 10547 public void testLockdownVpn_LegacyVpnRunner() throws Exception { 10548 doTestLockdownVpn(false /* isIkev2Vpn */); 10549 } 10550 10551 @Test 10552 public void testLockdownVpn_Ikev2VpnRunner() throws Exception { 10553 doTestLockdownVpn(true /* isIkev2Vpn */); 10554 } 10555 10556 @Test @IgnoreUpTo(Build.VERSION_CODES.S_V2) 10557 public void testLockdownSetFirewallUidRule() throws Exception { 10558 final List<Range<Integer>> lockdownRange = 10559 intRangesPrimaryExcludingUids(Collections.EMPTY_LIST /* excludedeUids */); 10560 // Enable Lockdown 10561 mCm.setRequireVpnForUids(true /* requireVpn */, lockdownRange); 10562 waitForIdle(); 10563 10564 // Lockdown rule is set to apps uids 10565 verify(mBpfNetMaps, times(3)).updateUidLockdownRule(anyInt(), eq(true) /* add */); 10566 verify(mBpfNetMaps).updateUidLockdownRule(APP1_UID, true /* add */); 10567 verify(mBpfNetMaps).updateUidLockdownRule(APP2_UID, true /* add */); 10568 verify(mBpfNetMaps).updateUidLockdownRule(VPN_UID, true /* add */); 10569 10570 reset(mBpfNetMaps); 10571 10572 // Disable lockdown 10573 mCm.setRequireVpnForUids(false /* requireVPN */, lockdownRange); 10574 waitForIdle(); 10575 10576 // Lockdown rule is removed from apps uids 10577 verify(mBpfNetMaps, times(3)).updateUidLockdownRule(anyInt(), eq(false) /* add */); 10578 verify(mBpfNetMaps).updateUidLockdownRule(APP1_UID, false /* add */); 10579 verify(mBpfNetMaps).updateUidLockdownRule(APP2_UID, false /* add */); 10580 verify(mBpfNetMaps).updateUidLockdownRule(VPN_UID, false /* add */); 10581 10582 // Interface rules are not changed by Lockdown mode enable/disable 10583 verify(mBpfNetMaps, never()).addUidInterfaceRules(any(), any()); 10584 verify(mBpfNetMaps, never()).removeUidInterfaceRules(any()); 10585 } 10586 10587 private void doTestSetUidFirewallRule(final int chain, final int defaultRule) { 10588 final int uid = 1001; 10589 mCm.setUidFirewallRule(chain, uid, FIREWALL_RULE_ALLOW); 10590 verify(mBpfNetMaps).setUidRule(chain, uid, FIREWALL_RULE_ALLOW); 10591 reset(mBpfNetMaps); 10592 10593 mCm.setUidFirewallRule(chain, uid, FIREWALL_RULE_DENY); 10594 verify(mBpfNetMaps).setUidRule(chain, uid, FIREWALL_RULE_DENY); 10595 reset(mBpfNetMaps); 10596 10597 mCm.setUidFirewallRule(chain, uid, FIREWALL_RULE_DEFAULT); 10598 verify(mBpfNetMaps).setUidRule(chain, uid, defaultRule); 10599 reset(mBpfNetMaps); 10600 } 10601 10602 @Test @IgnoreUpTo(SC_V2) 10603 public void testSetUidFirewallRule() throws Exception { 10604 doTestSetUidFirewallRule(FIREWALL_CHAIN_DOZABLE, FIREWALL_RULE_DENY); 10605 doTestSetUidFirewallRule(FIREWALL_CHAIN_STANDBY, FIREWALL_RULE_ALLOW); 10606 doTestSetUidFirewallRule(FIREWALL_CHAIN_POWERSAVE, FIREWALL_RULE_DENY); 10607 doTestSetUidFirewallRule(FIREWALL_CHAIN_RESTRICTED, FIREWALL_RULE_DENY); 10608 doTestSetUidFirewallRule(FIREWALL_CHAIN_LOW_POWER_STANDBY, FIREWALL_RULE_DENY); 10609 if (SdkLevel.isAtLeastV()) { 10610 // FIREWALL_CHAIN_BACKGROUND is only available on V+. 10611 doTestSetUidFirewallRule(FIREWALL_CHAIN_BACKGROUND, FIREWALL_RULE_DENY); 10612 } 10613 doTestSetUidFirewallRule(FIREWALL_CHAIN_OEM_DENY_1, FIREWALL_RULE_ALLOW); 10614 doTestSetUidFirewallRule(FIREWALL_CHAIN_OEM_DENY_2, FIREWALL_RULE_ALLOW); 10615 doTestSetUidFirewallRule(FIREWALL_CHAIN_OEM_DENY_3, FIREWALL_RULE_ALLOW); 10616 doTestSetUidFirewallRule(FIREWALL_CHAIN_METERED_ALLOW, FIREWALL_RULE_DENY); 10617 doTestSetUidFirewallRule(FIREWALL_CHAIN_METERED_DENY_USER, FIREWALL_RULE_ALLOW); 10618 doTestSetUidFirewallRule(FIREWALL_CHAIN_METERED_DENY_ADMIN, FIREWALL_RULE_ALLOW); 10619 } 10620 10621 @Test @IgnoreUpTo(SC_V2) 10622 public void testSetFirewallChainEnabled() throws Exception { 10623 final List<Integer> firewallChains = new ArrayList<>(Arrays.asList( 10624 FIREWALL_CHAIN_DOZABLE, 10625 FIREWALL_CHAIN_STANDBY, 10626 FIREWALL_CHAIN_POWERSAVE, 10627 FIREWALL_CHAIN_RESTRICTED, 10628 FIREWALL_CHAIN_LOW_POWER_STANDBY, 10629 FIREWALL_CHAIN_OEM_DENY_1, 10630 FIREWALL_CHAIN_OEM_DENY_2, 10631 FIREWALL_CHAIN_OEM_DENY_3)); 10632 if (SdkLevel.isAtLeastV()) { 10633 // FIREWALL_CHAIN_BACKGROUND is only available on V+. 10634 firewallChains.add(FIREWALL_CHAIN_BACKGROUND); 10635 } 10636 for (final int chain: firewallChains) { 10637 mCm.setFirewallChainEnabled(chain, true /* enabled */); 10638 verify(mBpfNetMaps).setChildChain(chain, true /* enable */); 10639 reset(mBpfNetMaps); 10640 10641 mCm.setFirewallChainEnabled(chain, false /* enabled */); 10642 verify(mBpfNetMaps).setChildChain(chain, false /* enable */); 10643 reset(mBpfNetMaps); 10644 } 10645 } 10646 10647 private void doTestSetFirewallChainEnabledCloseSocket(final int chain, 10648 final boolean isAllowList) throws Exception { 10649 reset(mDestroySocketsWrapper); 10650 10651 mCm.setFirewallChainEnabled(chain, true /* enabled */); 10652 final Set<Integer> uids = 10653 new ArraySet<>(List.of(TEST_PACKAGE_UID, TEST_PACKAGE_UID2)); 10654 if (isAllowList) { 10655 final Set<Range<Integer>> range = new ArraySet<>( 10656 List.of(new Range<>(Process.FIRST_APPLICATION_UID, Integer.MAX_VALUE))); 10657 verify(mDestroySocketsWrapper).destroyLiveTcpSockets(range, uids); 10658 } else { 10659 verify(mDestroySocketsWrapper).destroyLiveTcpSocketsByOwnerUids(uids); 10660 } 10661 10662 mCm.setFirewallChainEnabled(chain, false /* enabled */); 10663 verifyNoMoreInteractions(mDestroySocketsWrapper); 10664 } 10665 10666 @Test @IgnoreUpTo(Build.VERSION_CODES.TIRAMISU) 10667 public void testSetFirewallChainEnabledCloseSocket() throws Exception { 10668 doReturn(new ArraySet<>(Arrays.asList(TEST_PACKAGE_UID, TEST_PACKAGE_UID2))) 10669 .when(mBpfNetMaps) 10670 .getUidsWithDenyRuleOnDenyListChain(anyInt()); 10671 doReturn(new ArraySet<>(Arrays.asList(TEST_PACKAGE_UID, TEST_PACKAGE_UID2))) 10672 .when(mBpfNetMaps) 10673 .getUidsWithAllowRuleOnAllowListChain(anyInt()); 10674 10675 final boolean allowlist = true; 10676 final boolean denylist = false; 10677 10678 doTestSetFirewallChainEnabledCloseSocket(FIREWALL_CHAIN_DOZABLE, allowlist); 10679 doTestSetFirewallChainEnabledCloseSocket(FIREWALL_CHAIN_POWERSAVE, allowlist); 10680 doTestSetFirewallChainEnabledCloseSocket(FIREWALL_CHAIN_RESTRICTED, allowlist); 10681 doTestSetFirewallChainEnabledCloseSocket(FIREWALL_CHAIN_LOW_POWER_STANDBY, allowlist); 10682 if (SdkLevel.isAtLeastV()) { 10683 // FIREWALL_CHAIN_BACKGROUND is only available on V+. 10684 doTestSetFirewallChainEnabledCloseSocket(FIREWALL_CHAIN_BACKGROUND, allowlist); 10685 } 10686 10687 doTestSetFirewallChainEnabledCloseSocket(FIREWALL_CHAIN_STANDBY, denylist); 10688 doTestSetFirewallChainEnabledCloseSocket(FIREWALL_CHAIN_OEM_DENY_1, denylist); 10689 doTestSetFirewallChainEnabledCloseSocket(FIREWALL_CHAIN_OEM_DENY_2, denylist); 10690 doTestSetFirewallChainEnabledCloseSocket(FIREWALL_CHAIN_OEM_DENY_3, denylist); 10691 } 10692 10693 private void doTestReplaceFirewallChain(final int chain) { 10694 final int[] uids = new int[] {1001, 1002}; 10695 mCm.replaceFirewallChain(chain, uids); 10696 verify(mBpfNetMaps).replaceUidChain(chain, uids); 10697 reset(mBpfNetMaps); 10698 } 10699 10700 @Test @IgnoreUpTo(SC_V2) 10701 public void testReplaceFirewallChain() { 10702 doTestReplaceFirewallChain(FIREWALL_CHAIN_DOZABLE); 10703 doTestReplaceFirewallChain(FIREWALL_CHAIN_STANDBY); 10704 doTestReplaceFirewallChain(FIREWALL_CHAIN_POWERSAVE); 10705 doTestReplaceFirewallChain(FIREWALL_CHAIN_RESTRICTED); 10706 doTestReplaceFirewallChain(FIREWALL_CHAIN_LOW_POWER_STANDBY); 10707 if (SdkLevel.isAtLeastV()) { 10708 // FIREWALL_CHAIN_BACKGROUND is only available on V+. 10709 doTestReplaceFirewallChain(FIREWALL_CHAIN_BACKGROUND); 10710 } 10711 doTestReplaceFirewallChain(FIREWALL_CHAIN_OEM_DENY_1); 10712 doTestReplaceFirewallChain(FIREWALL_CHAIN_OEM_DENY_2); 10713 doTestReplaceFirewallChain(FIREWALL_CHAIN_OEM_DENY_3); 10714 } 10715 10716 @Test @IgnoreUpTo(SC_V2) 10717 public void testInvalidFirewallChain() throws Exception { 10718 final int uid = 1001; 10719 final Class<IllegalArgumentException> expected = IllegalArgumentException.class; 10720 assertThrows(expected, 10721 () -> mCm.setUidFirewallRule(-1 /* chain */, uid, FIREWALL_RULE_ALLOW)); 10722 assertThrows(expected, 10723 () -> mCm.setUidFirewallRule(100 /* chain */, uid, FIREWALL_RULE_ALLOW)); 10724 } 10725 10726 @Test @IgnoreUpTo(SC_V2) 10727 public void testInvalidFirewallRule() throws Exception { 10728 final Class<IllegalArgumentException> expected = IllegalArgumentException.class; 10729 assertThrows(expected, 10730 () -> mCm.setUidFirewallRule(FIREWALL_CHAIN_DOZABLE, 10731 1001 /* uid */, -1 /* rule */)); 10732 assertThrows(expected, 10733 () -> mCm.setUidFirewallRule(FIREWALL_CHAIN_DOZABLE, 10734 1001 /* uid */, 100 /* rule */)); 10735 } 10736 10737 /** 10738 * Test mutable and requestable network capabilities such as 10739 * {@link NetworkCapabilities#NET_CAPABILITY_TRUSTED} and 10740 * {@link NetworkCapabilities#NET_CAPABILITY_NOT_VCN_MANAGED}. Verify that the 10741 * {@code ConnectivityService} re-assign the networks accordingly. 10742 */ 10743 @Test 10744 public final void testLoseMutableAndRequestableCaps() throws Exception { 10745 final int[] testCaps = new int [] { 10746 NET_CAPABILITY_TRUSTED, 10747 NET_CAPABILITY_NOT_VCN_MANAGED 10748 }; 10749 for (final int testCap : testCaps) { 10750 // Create requests with and without the testing capability. 10751 final TestNetworkCallback callbackWithCap = new TestNetworkCallback(); 10752 final TestNetworkCallback callbackWithoutCap = new TestNetworkCallback(); 10753 mCm.requestNetwork(new NetworkRequest.Builder().addCapability(testCap).build(), 10754 callbackWithCap); 10755 mCm.requestNetwork(new NetworkRequest.Builder().removeCapability(testCap).build(), 10756 callbackWithoutCap); 10757 10758 // Setup networks with testing capability and verify the default network changes. 10759 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 10760 mCellAgent.addCapability(testCap); 10761 mCellAgent.connect(true); 10762 callbackWithCap.expectAvailableThenValidatedCallbacks(mCellAgent); 10763 callbackWithoutCap.expectAvailableThenValidatedCallbacks(mCellAgent); 10764 verify(mMockNetd).networkSetDefault(eq(mCellAgent.getNetwork().netId)); 10765 reset(mMockNetd); 10766 10767 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 10768 mWiFiAgent.addCapability(testCap); 10769 mWiFiAgent.connect(true); 10770 callbackWithCap.expectAvailableDoubleValidatedCallbacks(mWiFiAgent); 10771 callbackWithoutCap.expectAvailableDoubleValidatedCallbacks(mWiFiAgent); 10772 verify(mMockNetd).networkSetDefault(eq(mWiFiAgent.getNetwork().netId)); 10773 reset(mMockNetd); 10774 10775 // Remove the testing capability on wifi, verify the callback and default network 10776 // changes back to cellular. 10777 mWiFiAgent.removeCapability(testCap); 10778 callbackWithCap.expectAvailableCallbacksValidated(mCellAgent); 10779 callbackWithoutCap.expectCaps(mWiFiAgent, c -> !c.hasCapability(testCap)); 10780 verify(mMockNetd).networkSetDefault(eq(mCellAgent.getNetwork().netId)); 10781 reset(mMockNetd); 10782 10783 mCellAgent.removeCapability(testCap); 10784 callbackWithCap.expect(LOST, mCellAgent); 10785 callbackWithoutCap.assertNoCallback(); 10786 verify(mMockNetd).networkClearDefault(); 10787 10788 mCm.unregisterNetworkCallback(callbackWithCap); 10789 mCm.unregisterNetworkCallback(callbackWithoutCap); 10790 } 10791 } 10792 10793 @Test 10794 public final void testBatteryStatsNetworkType() throws Exception { 10795 final LinkProperties cellLp = new LinkProperties(); 10796 cellLp.setInterfaceName("cell0"); 10797 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp); 10798 mCellAgent.connect(true); 10799 waitForIdle(); 10800 final ArrayTrackRecord<ReportedInterfaces>.ReadHead readHead = 10801 mDeps.mReportedInterfaceHistory.newReadHead(); 10802 assertNotNull(readHead.poll(TIMEOUT_MS, ri -> ri.contentEquals(mServiceContext, 10803 cellLp.getInterfaceName(), 10804 new int[] { TRANSPORT_CELLULAR }))); 10805 10806 final LinkProperties wifiLp = new LinkProperties(); 10807 wifiLp.setInterfaceName("wifi0"); 10808 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, wifiLp); 10809 mWiFiAgent.connect(true); 10810 waitForIdle(); 10811 assertNotNull(readHead.poll(TIMEOUT_MS, ri -> ri.contentEquals(mServiceContext, 10812 wifiLp.getInterfaceName(), 10813 new int[] { TRANSPORT_WIFI }))); 10814 10815 mCellAgent.disconnect(); 10816 mWiFiAgent.disconnect(); 10817 10818 cellLp.setInterfaceName("wifi0"); 10819 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp); 10820 mCellAgent.connect(true); 10821 waitForIdle(); 10822 assertNotNull(readHead.poll(TIMEOUT_MS, ri -> ri.contentEquals(mServiceContext, 10823 cellLp.getInterfaceName(), 10824 new int[] { TRANSPORT_CELLULAR }))); 10825 mCellAgent.disconnect(); 10826 } 10827 10828 /** 10829 * Make simulated InterfaceConfigParcel for Nat464Xlat to query clat lower layer info. 10830 */ 10831 private InterfaceConfigurationParcel getClatInterfaceConfigParcel(LinkAddress la) { 10832 final InterfaceConfigurationParcel cfg = new InterfaceConfigurationParcel(); 10833 cfg.hwAddr = "11:22:33:44:55:66"; 10834 cfg.ipv4Addr = la.getAddress().getHostAddress(); 10835 cfg.prefixLength = la.getPrefixLength(); 10836 return cfg; 10837 } 10838 10839 /** 10840 * Make expected stack link properties, copied from Nat464Xlat. 10841 */ 10842 private LinkProperties makeClatLinkProperties(LinkAddress la) { 10843 LinkAddress clatAddress = la; 10844 LinkProperties stacked = new LinkProperties(); 10845 stacked.setInterfaceName(CLAT_MOBILE_IFNAME); 10846 RouteInfo ipv4Default = new RouteInfo( 10847 new LinkAddress(Inet4Address.ANY, 0), 10848 clatAddress.getAddress(), CLAT_MOBILE_IFNAME); 10849 stacked.addRoute(ipv4Default); 10850 stacked.addLinkAddress(clatAddress); 10851 return stacked; 10852 } 10853 10854 private Nat64PrefixEventParcel makeNat64PrefixEvent(final int netId, final int prefixOperation, 10855 final String prefixAddress, final int prefixLength) { 10856 final Nat64PrefixEventParcel event = new Nat64PrefixEventParcel(); 10857 event.netId = netId; 10858 event.prefixOperation = prefixOperation; 10859 event.prefixAddress = prefixAddress; 10860 event.prefixLength = prefixLength; 10861 return event; 10862 } 10863 10864 private void verifyWakeupModifyInterface(String iface, boolean add) throws RemoteException { 10865 if (add) { 10866 verify(mMockNetd).wakeupAddInterface(eq(iface), anyString(), anyInt(), 10867 anyInt()); 10868 } else { 10869 verify(mMockNetd).wakeupDelInterface(eq(iface), anyString(), anyInt(), 10870 anyInt()); 10871 } 10872 } 10873 10874 private <T> T verifyWithOrder(@Nullable InOrder inOrder, @NonNull T t) { 10875 if (inOrder != null) { 10876 return inOrder.verify(t); 10877 } else { 10878 // times(1) for consistency with the above. InOrder#verify always implies times(1). 10879 return verify(t, times(1)); 10880 } 10881 } 10882 10883 private <T> T verifyNeverWithOrder(@Nullable InOrder inOrder, @NonNull T t) { 10884 if (inOrder != null) { 10885 return inOrder.verify(t, never()); 10886 } else { 10887 return verify(t, never()); 10888 } 10889 } 10890 10891 private void verifyClatdStart(@Nullable InOrder inOrder, @NonNull String iface, int netId, 10892 @NonNull String nat64Prefix) throws Exception { 10893 if (mDeps.isAtLeastT()) { 10894 verifyWithOrder(inOrder, mClatCoordinator) 10895 .clatStart(eq(iface), eq(netId), eq(new IpPrefix(nat64Prefix))); 10896 } else { 10897 verifyWithOrder(inOrder, mMockNetd).clatdStart(eq(iface), eq(nat64Prefix)); 10898 } 10899 } 10900 10901 private void verifyNeverClatdStart(@Nullable InOrder inOrder, @NonNull String iface) 10902 throws Exception { 10903 if (mDeps.isAtLeastT()) { 10904 verifyNeverWithOrder(inOrder, mClatCoordinator).clatStart(eq(iface), anyInt(), any()); 10905 } else { 10906 verifyNeverWithOrder(inOrder, mMockNetd).clatdStart(eq(iface), anyString()); 10907 } 10908 } 10909 10910 private void verifyClatdStop(@Nullable InOrder inOrder, @NonNull String iface) 10911 throws Exception { 10912 if (mDeps.isAtLeastT()) { 10913 verifyWithOrder(inOrder, mClatCoordinator).clatStop(); 10914 } else { 10915 verifyWithOrder(inOrder, mMockNetd).clatdStop(eq(iface)); 10916 } 10917 } 10918 10919 private void verifyNeverClatdStop(@Nullable InOrder inOrder, @NonNull String iface) 10920 throws Exception { 10921 if (mDeps.isAtLeastT()) { 10922 verifyNeverWithOrder(inOrder, mClatCoordinator).clatStop(); 10923 } else { 10924 verifyNeverWithOrder(inOrder, mMockNetd).clatdStop(eq(iface)); 10925 } 10926 } 10927 10928 private void expectNativeNetworkCreated(int netId, int permission, String iface, 10929 InOrder inOrder) throws Exception { 10930 verifyWithOrder(inOrder, mMockNetd).networkCreate(nativeNetworkConfigPhysical(netId, 10931 permission)); 10932 verifyWithOrder(inOrder, mMockDnsResolver).createNetworkCache(eq(netId)); 10933 if (iface != null) { 10934 verifyWithOrder(inOrder, mMockNetd).networkAddInterface(netId, iface); 10935 } 10936 } 10937 10938 private void expectNativeNetworkCreated(int netId, int permission, String iface) 10939 throws Exception { 10940 expectNativeNetworkCreated(netId, permission, iface, null /* inOrder */); 10941 } 10942 10943 private int getIdleTimerLabel(int netId, int transportType) { 10944 return ConnectivityService.LegacyNetworkActivityTracker.getIdleTimerLabel( 10945 mDeps.isAtLeastV(), netId, transportType); 10946 } 10947 10948 @Test 10949 public void testStackedLinkProperties() throws Exception { 10950 final LinkAddress myIpv4 = new LinkAddress("1.2.3.4/24"); 10951 final LinkAddress myIpv6 = new LinkAddress("2001:db8:1::1/64"); 10952 final String kNat64PrefixString = "2001:db8:64:64:64:64::"; 10953 final IpPrefix kNat64Prefix = new IpPrefix(InetAddress.getByName(kNat64PrefixString), 96); 10954 final String kOtherNat64PrefixString = "64:ff9b::"; 10955 final IpPrefix kOtherNat64Prefix = new IpPrefix( 10956 InetAddress.getByName(kOtherNat64PrefixString), 96); 10957 final RouteInfo ipv6Default = 10958 new RouteInfo((IpPrefix) null, myIpv6.getAddress(), MOBILE_IFNAME); 10959 final RouteInfo ipv6Subnet = new RouteInfo(myIpv6, null, MOBILE_IFNAME); 10960 final RouteInfo ipv4Subnet = new RouteInfo(myIpv4, null, MOBILE_IFNAME); 10961 final RouteInfo stackedDefault = 10962 new RouteInfo((IpPrefix) null, myIpv4.getAddress(), CLAT_MOBILE_IFNAME); 10963 final BaseNetdUnsolicitedEventListener netdUnsolicitedListener = 10964 getRegisteredNetdUnsolicitedEventListener(); 10965 10966 final NetworkRequest networkRequest = new NetworkRequest.Builder() 10967 .addTransportType(TRANSPORT_CELLULAR) 10968 .addCapability(NET_CAPABILITY_INTERNET) 10969 .build(); 10970 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 10971 mCm.registerNetworkCallback(networkRequest, networkCallback); 10972 10973 // Prepare ipv6 only link properties. 10974 final LinkProperties cellLp = new LinkProperties(); 10975 cellLp.setInterfaceName(MOBILE_IFNAME); 10976 cellLp.addLinkAddress(myIpv6); 10977 cellLp.addRoute(ipv6Default); 10978 cellLp.addRoute(ipv6Subnet); 10979 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp); 10980 reset(mClatCoordinator); 10981 10982 // Connect with ipv6 link properties. Expect prefix discovery to be started. 10983 mCellAgent.connect(true); 10984 int cellNetId = mCellAgent.getNetwork().netId; 10985 waitForIdle(); 10986 10987 expectNativeNetworkCreated(cellNetId, INetd.PERMISSION_NONE, MOBILE_IFNAME); 10988 assertRoutesAdded(cellNetId, ipv6Subnet, ipv6Default); 10989 final ArrayTrackRecord<ReportedInterfaces>.ReadHead readHead = 10990 mDeps.mReportedInterfaceHistory.newReadHead(); 10991 assertNotNull(readHead.poll(TIMEOUT_MS, ri -> ri.contentEquals(mServiceContext, 10992 cellLp.getInterfaceName(), 10993 new int[] { TRANSPORT_CELLULAR }))); 10994 10995 networkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 10996 verify(mMockDnsResolver, times(1)).startPrefix64Discovery(cellNetId); 10997 10998 // Switching default network updates TCP buffer sizes. 10999 verifyTcpBufferSizeChange(ConnectivityService.DEFAULT_TCP_BUFFER_SIZES); 11000 // Add an IPv4 address. Expect prefix discovery to be stopped. Netd doesn't tell us that 11001 // the NAT64 prefix was removed because one was never discovered. 11002 cellLp.addLinkAddress(myIpv4); 11003 mCellAgent.sendLinkProperties(cellLp); 11004 networkCallback.expect(LINK_PROPERTIES_CHANGED, mCellAgent); 11005 assertRoutesAdded(cellNetId, ipv4Subnet); 11006 verify(mMockDnsResolver, times(1)).stopPrefix64Discovery(cellNetId); 11007 verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration(any()); 11008 11009 // Make sure BatteryStats was not told about any v4- interfaces, as none should have 11010 // come online yet. 11011 waitForIdle(); 11012 assertNull(readHead.poll(0 /* timeout */, ri -> mServiceContext.equals(ri.context) 11013 && ri.iface != null && ri.iface.startsWith("v4-"))); 11014 11015 verifyNoMoreInteractions(mMockNetd); 11016 verifyNoMoreInteractions(mClatCoordinator); 11017 verifyNoMoreInteractions(mMockDnsResolver); 11018 reset(mMockNetd); 11019 reset(mClatCoordinator); 11020 reset(mMockDnsResolver); 11021 doReturn(getClatInterfaceConfigParcel(myIpv4)).when(mMockNetd) 11022 .interfaceGetCfg(CLAT_MOBILE_IFNAME); 11023 11024 // Remove IPv4 address. Expect prefix discovery to be started again. 11025 cellLp.removeLinkAddress(myIpv4); 11026 mCellAgent.sendLinkProperties(cellLp); 11027 networkCallback.expect(LINK_PROPERTIES_CHANGED, mCellAgent); 11028 verify(mMockDnsResolver, times(1)).startPrefix64Discovery(cellNetId); 11029 assertRoutesRemoved(cellNetId, ipv4Subnet); 11030 11031 // When NAT64 prefix discovery succeeds, LinkProperties are updated and clatd is started. 11032 assertNull(mCm.getLinkProperties(mCellAgent.getNetwork()).getNat64Prefix()); 11033 mService.mResolverUnsolEventCallback.onNat64PrefixEvent( 11034 makeNat64PrefixEvent(cellNetId, PREFIX_OPERATION_ADDED, kNat64PrefixString, 96)); 11035 LinkProperties lpBeforeClat = networkCallback.expect( 11036 LINK_PROPERTIES_CHANGED, mCellAgent).getLp(); 11037 assertEquals(0, lpBeforeClat.getStackedLinks().size()); 11038 assertEquals(kNat64Prefix, lpBeforeClat.getNat64Prefix()); 11039 verifyClatdStart(null /* inOrder */, MOBILE_IFNAME, cellNetId, kNat64Prefix.toString()); 11040 11041 // Clat iface comes up. Expect stacked link to be added. 11042 netdUnsolicitedListener.onInterfaceLinkStateChanged( 11043 CLAT_MOBILE_IFNAME, true); 11044 networkCallback.expect(LINK_PROPERTIES_CHANGED, mCellAgent); 11045 List<LinkProperties> stackedLps = mCm.getLinkProperties(mCellAgent.getNetwork()) 11046 .getStackedLinks(); 11047 assertEquals(makeClatLinkProperties(myIpv4), stackedLps.get(0)); 11048 assertRoutesAdded(cellNetId, stackedDefault); 11049 verify(mMockNetd, times(1)).networkAddInterface(cellNetId, CLAT_MOBILE_IFNAME); 11050 // Change trivial linkproperties and see if stacked link is preserved. 11051 cellLp.addDnsServer(InetAddress.getByName("8.8.8.8")); 11052 mCellAgent.sendLinkProperties(cellLp); 11053 networkCallback.expect(LINK_PROPERTIES_CHANGED, mCellAgent); 11054 11055 List<LinkProperties> stackedLpsAfterChange = 11056 mCm.getLinkProperties(mCellAgent.getNetwork()).getStackedLinks(); 11057 assertNotEquals(stackedLpsAfterChange, Collections.EMPTY_LIST); 11058 assertEquals(makeClatLinkProperties(myIpv4), stackedLpsAfterChange.get(0)); 11059 11060 verify(mMockDnsResolver, times(1)).setResolverConfiguration( 11061 mResolverParamsParcelCaptor.capture()); 11062 ResolverParamsParcel resolvrParams = mResolverParamsParcelCaptor.getValue(); 11063 assertEquals(1, resolvrParams.servers.length); 11064 assertTrue(CollectionUtils.contains(resolvrParams.servers, "8.8.8.8")); 11065 11066 for (final LinkProperties stackedLp : stackedLpsAfterChange) { 11067 assertNotNull(readHead.poll(TIMEOUT_MS, ri -> ri.contentEquals(mServiceContext, 11068 stackedLp.getInterfaceName(), 11069 new int[] { TRANSPORT_CELLULAR }))); 11070 } 11071 reset(mMockNetd); 11072 reset(mClatCoordinator); 11073 doReturn(getClatInterfaceConfigParcel(myIpv4)).when(mMockNetd) 11074 .interfaceGetCfg(CLAT_MOBILE_IFNAME); 11075 // Change the NAT64 prefix without first removing it. 11076 // Expect clatd to be stopped and started with the new prefix. 11077 mService.mResolverUnsolEventCallback.onNat64PrefixEvent(makeNat64PrefixEvent( 11078 cellNetId, PREFIX_OPERATION_ADDED, kOtherNat64PrefixString, 96)); 11079 networkCallback.expect(LINK_PROPERTIES_CHANGED, mCellAgent, 11080 cb -> cb.getLp().getStackedLinks().size() == 0); 11081 verifyClatdStop(null /* inOrder */, MOBILE_IFNAME); 11082 assertRoutesRemoved(cellNetId, stackedDefault); 11083 verify(mMockNetd, times(1)).networkRemoveInterface(cellNetId, CLAT_MOBILE_IFNAME); 11084 11085 verifyClatdStart(null /* inOrder */, MOBILE_IFNAME, cellNetId, 11086 kOtherNat64Prefix.toString()); 11087 networkCallback.expect(LINK_PROPERTIES_CHANGED, mCellAgent, 11088 cb -> cb.getLp().getNat64Prefix().equals(kOtherNat64Prefix)); 11089 netdUnsolicitedListener.onInterfaceLinkStateChanged(CLAT_MOBILE_IFNAME, true); 11090 networkCallback.expect(LINK_PROPERTIES_CHANGED, mCellAgent, 11091 cb -> cb.getLp().getStackedLinks().size() == 1); 11092 assertRoutesAdded(cellNetId, stackedDefault); 11093 verify(mMockNetd, times(1)).networkAddInterface(cellNetId, CLAT_MOBILE_IFNAME); 11094 reset(mMockNetd); 11095 reset(mClatCoordinator); 11096 11097 // Add ipv4 address, expect that clatd and prefix discovery are stopped and stacked 11098 // linkproperties are cleaned up. 11099 cellLp.addLinkAddress(myIpv4); 11100 cellLp.addRoute(ipv4Subnet); 11101 mCellAgent.sendLinkProperties(cellLp); 11102 networkCallback.expect(LINK_PROPERTIES_CHANGED, mCellAgent); 11103 assertRoutesAdded(cellNetId, ipv4Subnet); 11104 verifyClatdStop(null /* inOrder */, MOBILE_IFNAME); 11105 verify(mMockDnsResolver, times(1)).stopPrefix64Discovery(cellNetId); 11106 11107 // As soon as stop is called, the linkproperties lose the stacked interface. 11108 networkCallback.expect(LINK_PROPERTIES_CHANGED, mCellAgent); 11109 LinkProperties actualLpAfterIpv4 = mCm.getLinkProperties(mCellAgent.getNetwork()); 11110 LinkProperties expected = new LinkProperties(cellLp); 11111 expected.setNat64Prefix(kOtherNat64Prefix); 11112 assertEquals(expected, actualLpAfterIpv4); 11113 assertEquals(0, actualLpAfterIpv4.getStackedLinks().size()); 11114 assertRoutesRemoved(cellNetId, stackedDefault); 11115 11116 // The interface removed callback happens but has no effect after stop is called. 11117 netdUnsolicitedListener.onInterfaceRemoved(CLAT_MOBILE_IFNAME); 11118 networkCallback.assertNoCallback(); 11119 verify(mMockNetd, times(1)).networkRemoveInterface(cellNetId, CLAT_MOBILE_IFNAME); 11120 11121 if (mDeps.isAtLeastU()) { 11122 verifyWakeupModifyInterface(CLAT_MOBILE_IFNAME, false); 11123 } 11124 11125 verifyNoMoreInteractions(mMockNetd); 11126 verifyNoMoreInteractions(mClatCoordinator); 11127 verifyNoMoreInteractions(mMockDnsResolver); 11128 reset(mMockNetd); 11129 reset(mClatCoordinator); 11130 reset(mMockDnsResolver); 11131 doReturn(getClatInterfaceConfigParcel(myIpv4)).when(mMockNetd) 11132 .interfaceGetCfg(CLAT_MOBILE_IFNAME); 11133 11134 // Stopping prefix discovery causes netd to tell us that the NAT64 prefix is gone. 11135 mService.mResolverUnsolEventCallback.onNat64PrefixEvent(makeNat64PrefixEvent( 11136 cellNetId, PREFIX_OPERATION_REMOVED, kOtherNat64PrefixString, 96)); 11137 networkCallback.expect(LINK_PROPERTIES_CHANGED, mCellAgent, 11138 cb -> cb.getLp().getNat64Prefix() == null); 11139 11140 // Remove IPv4 address and expect prefix discovery and clatd to be started again. 11141 cellLp.removeLinkAddress(myIpv4); 11142 cellLp.removeRoute(new RouteInfo(myIpv4, null, MOBILE_IFNAME)); 11143 cellLp.removeDnsServer(InetAddress.getByName("8.8.8.8")); 11144 mCellAgent.sendLinkProperties(cellLp); 11145 networkCallback.expect(LINK_PROPERTIES_CHANGED, mCellAgent); 11146 assertRoutesRemoved(cellNetId, ipv4Subnet); // Directly-connected routes auto-added. 11147 verify(mMockDnsResolver, times(1)).startPrefix64Discovery(cellNetId); 11148 mService.mResolverUnsolEventCallback.onNat64PrefixEvent(makeNat64PrefixEvent( 11149 cellNetId, PREFIX_OPERATION_ADDED, kNat64PrefixString, 96)); 11150 networkCallback.expect(LINK_PROPERTIES_CHANGED, mCellAgent); 11151 verifyClatdStart(null /* inOrder */, MOBILE_IFNAME, cellNetId, kNat64Prefix.toString()); 11152 11153 // Clat iface comes up. Expect stacked link to be added. 11154 netdUnsolicitedListener.onInterfaceLinkStateChanged(CLAT_MOBILE_IFNAME, true); 11155 networkCallback.expect(LINK_PROPERTIES_CHANGED, mCellAgent, 11156 cb -> cb.getLp().getStackedLinks().size() == 1 11157 && cb.getLp().getNat64Prefix() != null); 11158 assertRoutesAdded(cellNetId, stackedDefault); 11159 verify(mMockNetd, times(1)).networkAddInterface(cellNetId, CLAT_MOBILE_IFNAME); 11160 11161 if (mDeps.isAtLeastU()) { 11162 verifyWakeupModifyInterface(CLAT_MOBILE_IFNAME, true); 11163 } 11164 11165 // NAT64 prefix is removed. Expect that clat is stopped. 11166 mService.mResolverUnsolEventCallback.onNat64PrefixEvent(makeNat64PrefixEvent( 11167 cellNetId, PREFIX_OPERATION_REMOVED, kNat64PrefixString, 96)); 11168 networkCallback.expect(LINK_PROPERTIES_CHANGED, mCellAgent, 11169 cb -> cb.getLp().getStackedLinks().size() == 0 11170 && cb.getLp().getNat64Prefix() == null); 11171 assertRoutesRemoved(cellNetId, ipv4Subnet, stackedDefault); 11172 11173 // Stop has no effect because clat is already stopped. 11174 verifyClatdStop(null /* inOrder */, MOBILE_IFNAME); 11175 networkCallback.expect(LINK_PROPERTIES_CHANGED, mCellAgent, 11176 cb -> cb.getLp().getStackedLinks().size() == 0); 11177 verify(mMockNetd, times(1)).networkRemoveInterface(cellNetId, CLAT_MOBILE_IFNAME); 11178 verify(mMockNetd, times(1)).interfaceGetCfg(CLAT_MOBILE_IFNAME); 11179 11180 if (mDeps.isAtLeastU()) { 11181 verifyWakeupModifyInterface(CLAT_MOBILE_IFNAME, false); 11182 } 11183 11184 // Clean up. 11185 mCellAgent.disconnect(); 11186 networkCallback.expect(LOST, mCellAgent); 11187 networkCallback.assertNoCallback(); 11188 verify(mMockNetd, times(1)).idletimerRemoveInterface(eq(MOBILE_IFNAME), anyInt(), 11189 eq(Integer.toString(getIdleTimerLabel(cellNetId, TRANSPORT_CELLULAR)))); 11190 verify(mMockNetd).networkDestroy(cellNetId); 11191 if (mDeps.isAtLeastU()) { 11192 verify(mMockNetd).setNetworkAllowlist(any()); 11193 } else { 11194 verify(mMockNetd, never()).setNetworkAllowlist(any()); 11195 } 11196 11197 if (mDeps.isAtLeastU()) { 11198 verifyWakeupModifyInterface(MOBILE_IFNAME, false); 11199 } 11200 11201 verifyNoMoreInteractions(mMockNetd); 11202 verifyNoMoreInteractions(mClatCoordinator); 11203 reset(mMockNetd); 11204 reset(mClatCoordinator); 11205 11206 // Test disconnecting a network that is running 464xlat. 11207 11208 // Connect a network with a NAT64 prefix. 11209 doReturn(getClatInterfaceConfigParcel(myIpv4)).when(mMockNetd) 11210 .interfaceGetCfg(CLAT_MOBILE_IFNAME); 11211 cellLp.setNat64Prefix(kNat64Prefix); 11212 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp); 11213 mCellAgent.connect(false /* validated */); 11214 networkCallback.expectAvailableCallbacksUnvalidated(mCellAgent); 11215 cellNetId = mCellAgent.getNetwork().netId; 11216 verify(mMockNetd, times(1)).networkCreate(nativeNetworkConfigPhysical(cellNetId, 11217 INetd.PERMISSION_NONE)); 11218 assertRoutesAdded(cellNetId, ipv6Subnet, ipv6Default); 11219 11220 // Clatd is started and clat iface comes up. Expect stacked link to be added. 11221 verifyClatdStart(null /* inOrder */, MOBILE_IFNAME, cellNetId, kNat64Prefix.toString()); 11222 netdUnsolicitedListener.onInterfaceLinkStateChanged(CLAT_MOBILE_IFNAME, true /* up */); 11223 networkCallback.expect(LINK_PROPERTIES_CHANGED, mCellAgent, 11224 cb -> cb.getLp().getStackedLinks().size() == 1 11225 && cb.getLp().getNat64Prefix().equals(kNat64Prefix)); 11226 verify(mMockNetd).networkAddInterface(cellNetId, CLAT_MOBILE_IFNAME); 11227 // assertRoutesAdded sees all calls since last mMockNetd reset, so expect IPv6 routes again. 11228 assertRoutesAdded(cellNetId, ipv6Subnet, ipv6Default, stackedDefault); 11229 11230 if (mDeps.isAtLeastU()) { 11231 verifyWakeupModifyInterface(MOBILE_IFNAME, true); 11232 } 11233 11234 reset(mMockNetd); 11235 reset(mClatCoordinator); 11236 11237 // Disconnect the network. clat is stopped and the network is destroyed. 11238 mCellAgent.disconnect(); 11239 networkCallback.expect(LOST, mCellAgent); 11240 networkCallback.assertNoCallback(); 11241 verifyClatdStop(null /* inOrder */, MOBILE_IFNAME); 11242 11243 if (mDeps.isAtLeastU()) { 11244 verifyWakeupModifyInterface(CLAT_MOBILE_IFNAME, false); 11245 } 11246 11247 verify(mMockNetd).idletimerRemoveInterface(eq(MOBILE_IFNAME), anyInt(), 11248 eq(Integer.toString(getIdleTimerLabel(cellNetId, TRANSPORT_CELLULAR)))); 11249 verify(mMockNetd).networkDestroy(cellNetId); 11250 if (mDeps.isAtLeastU()) { 11251 verify(mMockNetd).setNetworkAllowlist(any()); 11252 } else { 11253 verify(mMockNetd, never()).setNetworkAllowlist(any()); 11254 } 11255 11256 if (mDeps.isAtLeastU()) { 11257 verifyWakeupModifyInterface(MOBILE_IFNAME, false); 11258 } 11259 11260 verifyNoMoreInteractions(mMockNetd); 11261 verifyNoMoreInteractions(mClatCoordinator); 11262 11263 mCm.unregisterNetworkCallback(networkCallback); 11264 } 11265 11266 private void expectNat64PrefixChange(TestNetworkCallback callback, 11267 TestNetworkAgentWrapper agent, IpPrefix prefix) { 11268 callback.expect(LINK_PROPERTIES_CHANGED, agent, 11269 x -> Objects.equals(x.getLp().getNat64Prefix(), prefix)); 11270 } 11271 11272 @Test 11273 public void testNat64PrefixMultipleSources() throws Exception { 11274 final String iface = "wlan0"; 11275 final String pref64FromRaStr = "64:ff9b::"; 11276 final String pref64FromDnsStr = "2001:db8:64::"; 11277 final IpPrefix pref64FromRa = new IpPrefix(InetAddress.getByName(pref64FromRaStr), 96); 11278 final IpPrefix pref64FromDns = new IpPrefix(InetAddress.getByName(pref64FromDnsStr), 96); 11279 final IpPrefix newPref64FromRa = new IpPrefix("2001:db8:64:64:64:64::/96"); 11280 11281 final NetworkRequest request = new NetworkRequest.Builder() 11282 .addCapability(NET_CAPABILITY_INTERNET) 11283 .build(); 11284 final TestNetworkCallback callback = new TestNetworkCallback(); 11285 mCm.registerNetworkCallback(request, callback); 11286 11287 final LinkProperties baseLp = new LinkProperties(); 11288 baseLp.setInterfaceName(iface); 11289 baseLp.addLinkAddress(new LinkAddress("2001:db8:1::1/64")); 11290 baseLp.addDnsServer(InetAddress.getByName("2001:4860:4860::6464")); 11291 11292 reset(mMockNetd, mMockDnsResolver); 11293 InOrder inOrder = inOrder(mMockNetd, mMockDnsResolver, mClatCoordinator); 11294 11295 // If a network already has a NAT64 prefix on connect, clatd is started immediately and 11296 // prefix discovery is never started. 11297 LinkProperties lp = new LinkProperties(baseLp); 11298 lp.setNat64Prefix(pref64FromRa); 11299 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, lp); 11300 mWiFiAgent.connect(false); 11301 final Network network = mWiFiAgent.getNetwork(); 11302 int netId = network.getNetId(); 11303 callback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 11304 verifyClatdStart(inOrder, iface, netId, pref64FromRa.toString()); 11305 inOrder.verify(mMockDnsResolver).setPrefix64(netId, pref64FromRa.toString()); 11306 inOrder.verify(mMockDnsResolver, never()).startPrefix64Discovery(netId); 11307 callback.assertNoCallback(); 11308 assertEquals(pref64FromRa, mCm.getLinkProperties(network).getNat64Prefix()); 11309 11310 // If the RA prefix is withdrawn, clatd is stopped and prefix discovery is started. 11311 lp.setNat64Prefix(null); 11312 mWiFiAgent.sendLinkProperties(lp); 11313 expectNat64PrefixChange(callback, mWiFiAgent, null); 11314 verifyClatdStop(inOrder, iface); 11315 inOrder.verify(mMockDnsResolver).setPrefix64(netId, ""); 11316 inOrder.verify(mMockDnsResolver).startPrefix64Discovery(netId); 11317 11318 // If the RA prefix appears while DNS discovery is in progress, discovery is stopped and 11319 // clatd is started with the prefix from the RA. 11320 lp.setNat64Prefix(pref64FromRa); 11321 mWiFiAgent.sendLinkProperties(lp); 11322 expectNat64PrefixChange(callback, mWiFiAgent, pref64FromRa); 11323 verifyClatdStart(inOrder, iface, netId, pref64FromRa.toString()); 11324 inOrder.verify(mMockDnsResolver).stopPrefix64Discovery(netId); 11325 inOrder.verify(mMockDnsResolver).setPrefix64(netId, pref64FromRa.toString()); 11326 11327 // Withdraw the RA prefix so we can test the case where an RA prefix appears after DNS 11328 // discovery has succeeded. 11329 lp.setNat64Prefix(null); 11330 mWiFiAgent.sendLinkProperties(lp); 11331 expectNat64PrefixChange(callback, mWiFiAgent, null); 11332 verifyClatdStop(inOrder, iface); 11333 inOrder.verify(mMockDnsResolver).setPrefix64(netId, ""); 11334 inOrder.verify(mMockDnsResolver).startPrefix64Discovery(netId); 11335 11336 mService.mResolverUnsolEventCallback.onNat64PrefixEvent( 11337 makeNat64PrefixEvent(netId, PREFIX_OPERATION_ADDED, pref64FromDnsStr, 96)); 11338 expectNat64PrefixChange(callback, mWiFiAgent, pref64FromDns); 11339 verifyClatdStart(inOrder, iface, netId, pref64FromDns.toString()); 11340 11341 // If an RA advertises the same prefix that was discovered by DNS, nothing happens: prefix 11342 // discovery is not stopped, and there are no callbacks. 11343 lp.setNat64Prefix(pref64FromDns); 11344 mWiFiAgent.sendLinkProperties(lp); 11345 callback.assertNoCallback(); 11346 verifyNeverClatdStop(inOrder, iface); 11347 verifyNeverClatdStart(inOrder, iface); 11348 inOrder.verify(mMockDnsResolver, never()).stopPrefix64Discovery(netId); 11349 inOrder.verify(mMockDnsResolver, never()).startPrefix64Discovery(netId); 11350 inOrder.verify(mMockDnsResolver, never()).setPrefix64(eq(netId), anyString()); 11351 11352 // If the RA is later withdrawn, nothing happens again. 11353 lp.setNat64Prefix(null); 11354 mWiFiAgent.sendLinkProperties(lp); 11355 callback.assertNoCallback(); 11356 verifyNeverClatdStop(inOrder, iface); 11357 verifyNeverClatdStart(inOrder, iface); 11358 inOrder.verify(mMockDnsResolver, never()).stopPrefix64Discovery(netId); 11359 inOrder.verify(mMockDnsResolver, never()).startPrefix64Discovery(netId); 11360 inOrder.verify(mMockDnsResolver, never()).setPrefix64(eq(netId), anyString()); 11361 11362 // If the RA prefix changes, clatd is restarted and prefix discovery is stopped. 11363 lp.setNat64Prefix(pref64FromRa); 11364 mWiFiAgent.sendLinkProperties(lp); 11365 expectNat64PrefixChange(callback, mWiFiAgent, pref64FromRa); 11366 verifyClatdStop(inOrder, iface); 11367 inOrder.verify(mMockDnsResolver).stopPrefix64Discovery(netId); 11368 11369 // Stopping prefix discovery results in a prefix removed notification. 11370 mService.mResolverUnsolEventCallback.onNat64PrefixEvent( 11371 makeNat64PrefixEvent(netId, PREFIX_OPERATION_REMOVED, pref64FromDnsStr, 96)); 11372 11373 verifyClatdStart(inOrder, iface, netId, pref64FromRa.toString()); 11374 inOrder.verify(mMockDnsResolver).setPrefix64(netId, pref64FromRa.toString()); 11375 inOrder.verify(mMockDnsResolver, never()).startPrefix64Discovery(netId); 11376 11377 // If the RA prefix changes, clatd is restarted and prefix discovery is not started. 11378 lp.setNat64Prefix(newPref64FromRa); 11379 mWiFiAgent.sendLinkProperties(lp); 11380 expectNat64PrefixChange(callback, mWiFiAgent, newPref64FromRa); 11381 verifyClatdStop(inOrder, iface); 11382 inOrder.verify(mMockDnsResolver).setPrefix64(netId, ""); 11383 verifyClatdStart(inOrder, iface, netId, newPref64FromRa.toString()); 11384 inOrder.verify(mMockDnsResolver).setPrefix64(netId, newPref64FromRa.toString()); 11385 inOrder.verify(mMockDnsResolver, never()).stopPrefix64Discovery(netId); 11386 inOrder.verify(mMockDnsResolver, never()).startPrefix64Discovery(netId); 11387 11388 // If the RA prefix changes to the same value, nothing happens. 11389 lp.setNat64Prefix(newPref64FromRa); 11390 mWiFiAgent.sendLinkProperties(lp); 11391 callback.assertNoCallback(); 11392 assertEquals(newPref64FromRa, mCm.getLinkProperties(network).getNat64Prefix()); 11393 verifyNeverClatdStop(inOrder, iface); 11394 verifyNeverClatdStart(inOrder, iface); 11395 inOrder.verify(mMockDnsResolver, never()).stopPrefix64Discovery(netId); 11396 inOrder.verify(mMockDnsResolver, never()).startPrefix64Discovery(netId); 11397 inOrder.verify(mMockDnsResolver, never()).setPrefix64(eq(netId), anyString()); 11398 11399 // The transition between no prefix and DNS prefix is tested in testStackedLinkProperties. 11400 11401 // If the same prefix is learned first by DNS and then by RA, and clat is later stopped, 11402 // (e.g., because the network disconnects) setPrefix64(netid, "") is never called. 11403 lp.setNat64Prefix(null); 11404 mWiFiAgent.sendLinkProperties(lp); 11405 expectNat64PrefixChange(callback, mWiFiAgent, null); 11406 verifyClatdStop(inOrder, iface); 11407 inOrder.verify(mMockDnsResolver).setPrefix64(netId, ""); 11408 inOrder.verify(mMockDnsResolver).startPrefix64Discovery(netId); 11409 mService.mResolverUnsolEventCallback.onNat64PrefixEvent( 11410 makeNat64PrefixEvent(netId, PREFIX_OPERATION_ADDED, pref64FromDnsStr, 96)); 11411 expectNat64PrefixChange(callback, mWiFiAgent, pref64FromDns); 11412 verifyClatdStart(inOrder, iface, netId, pref64FromDns.toString()); 11413 inOrder.verify(mMockDnsResolver, never()).setPrefix64(eq(netId), any()); 11414 11415 lp.setNat64Prefix(pref64FromDns); 11416 mWiFiAgent.sendLinkProperties(lp); 11417 callback.assertNoCallback(); 11418 verifyNeverClatdStop(inOrder, iface); 11419 verifyNeverClatdStart(inOrder, iface); 11420 inOrder.verify(mMockDnsResolver, never()).stopPrefix64Discovery(netId); 11421 inOrder.verify(mMockDnsResolver, never()).startPrefix64Discovery(netId); 11422 inOrder.verify(mMockDnsResolver, never()).setPrefix64(eq(netId), anyString()); 11423 11424 // When tearing down a network, clat state is only updated after CALLBACK_LOST is fired, but 11425 // before CONNECTIVITY_ACTION is sent. Wait for CONNECTIVITY_ACTION before verifying that 11426 // clat has been stopped, or the test will be flaky. 11427 ExpectedBroadcast b = expectConnectivityAction(TYPE_WIFI, DetailedState.DISCONNECTED); 11428 mWiFiAgent.disconnect(); 11429 callback.expect(LOST, mWiFiAgent); 11430 b.expectBroadcast(); 11431 11432 verifyClatdStop(inOrder, iface); 11433 inOrder.verify(mMockDnsResolver).stopPrefix64Discovery(netId); 11434 inOrder.verify(mMockDnsResolver, never()).setPrefix64(eq(netId), anyString()); 11435 11436 mCm.unregisterNetworkCallback(callback); 11437 } 11438 11439 @Test 11440 public void testWith464XlatDisable() throws Exception { 11441 mDeps.setCellular464XlatEnabled(false); 11442 11443 final TestNetworkCallback callback = new TestNetworkCallback(); 11444 final TestNetworkCallback defaultCallback = new TestNetworkCallback(); 11445 final NetworkRequest networkRequest = new NetworkRequest.Builder() 11446 .addCapability(NET_CAPABILITY_INTERNET) 11447 .build(); 11448 mCm.registerNetworkCallback(networkRequest, callback); 11449 mCm.registerDefaultNetworkCallback(defaultCallback); 11450 11451 // Bring up validated cell. 11452 final LinkProperties cellLp = new LinkProperties(); 11453 cellLp.setInterfaceName(MOBILE_IFNAME); 11454 cellLp.addLinkAddress(new LinkAddress("2001:db8:1::1/64")); 11455 cellLp.addRoute(new RouteInfo(new IpPrefix("::/0"), null, MOBILE_IFNAME)); 11456 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 11457 11458 mCellAgent.sendLinkProperties(cellLp); 11459 mCellAgent.connect(true); 11460 callback.expectAvailableThenValidatedCallbacks(mCellAgent); 11461 defaultCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 11462 final int cellNetId = mCellAgent.getNetwork().netId; 11463 waitForIdle(); 11464 11465 verify(mMockDnsResolver, never()).startPrefix64Discovery(cellNetId); 11466 Nat464Xlat clat = getNat464Xlat(mCellAgent); 11467 assertTrue("Nat464Xlat was not IDLE", !clat.isStarted()); 11468 11469 // This cannot happen because prefix discovery cannot succeed if it is never started. 11470 mService.mResolverUnsolEventCallback.onNat64PrefixEvent( 11471 makeNat64PrefixEvent(cellNetId, PREFIX_OPERATION_ADDED, "64:ff9b::", 96)); 11472 11473 // ... but still, check that even if it did, clatd would not be started. 11474 verify(mMockNetd, never()).clatdStart(anyString(), anyString()); 11475 assertTrue("Nat464Xlat was not IDLE", !clat.isStarted()); 11476 } 11477 11478 final String transportToTestIfaceName(int transport) { 11479 switch (transport) { 11480 case TRANSPORT_WIFI: 11481 return WIFI_IFNAME; 11482 case TRANSPORT_CELLULAR: 11483 return MOBILE_IFNAME; 11484 case TRANSPORT_ETHERNET: 11485 return ETHERNET_IFNAME; 11486 default: 11487 throw new AssertionError("Unsupported transport type"); 11488 } 11489 } 11490 11491 private void doTestInterfaceClassActivityChanged(final int transportType) throws Exception { 11492 final BaseNetdUnsolicitedEventListener netdUnsolicitedEventListener = 11493 getRegisteredNetdUnsolicitedEventListener(); 11494 11495 final int legacyType = transportToLegacyType(transportType); 11496 final LinkProperties lp = new LinkProperties(); 11497 lp.setInterfaceName(transportToTestIfaceName(transportType)); 11498 final TestNetworkAgentWrapper agent = new TestNetworkAgentWrapper(transportType, lp); 11499 11500 final ConditionVariable onNetworkActiveCv = new ConditionVariable(); 11501 final ConnectivityManager.OnNetworkActiveListener listener = onNetworkActiveCv::open; 11502 11503 TestNetworkCallback defaultCallback = new TestNetworkCallback(); 11504 11505 testAndCleanup(() -> { 11506 mCm.registerDefaultNetworkCallback(defaultCallback); 11507 agent.connect(true); 11508 defaultCallback.expectAvailableThenValidatedCallbacks(agent); 11509 if (transportType == TRANSPORT_CELLULAR) { 11510 verify(mIBatteryStats).noteMobileRadioPowerState(eq(DC_POWER_STATE_HIGH), 11511 anyLong() /* timestampNs */, eq(NETWORK_ACTIVITY_NO_UID)); 11512 } else if (transportType == TRANSPORT_WIFI) { 11513 verify(mIBatteryStats).noteWifiRadioPowerState(eq(DC_POWER_STATE_HIGH), 11514 anyLong() /* timestampNs */, eq(NETWORK_ACTIVITY_NO_UID)); 11515 } 11516 clearInvocations(mIBatteryStats); 11517 final int idleTimerLabel = getIdleTimerLabel(agent.getNetwork().netId, transportType); 11518 11519 // Network is considered active when the network becomes the default network. 11520 assertTrue(mCm.isDefaultNetworkActive()); 11521 11522 mCm.addDefaultNetworkActiveListener(listener); 11523 11524 // Interface goes to inactive state 11525 netdUnsolicitedEventListener.onInterfaceClassActivityChanged(false /* isActive */, 11526 idleTimerLabel, TIMESTAMP, NETWORK_ACTIVITY_NO_UID); 11527 mServiceContext.expectDataActivityBroadcast(legacyType, false /* isActive */, 11528 TIMESTAMP); 11529 assertFalse(onNetworkActiveCv.block(TEST_CALLBACK_TIMEOUT_MS)); 11530 assertFalse(mCm.isDefaultNetworkActive()); 11531 if (mDeps.isAtLeastV()) { 11532 if (transportType == TRANSPORT_CELLULAR) { 11533 verify(mIBatteryStats).noteMobileRadioPowerState(eq(DC_POWER_STATE_LOW), 11534 anyLong() /* timestampNs */, eq(NETWORK_ACTIVITY_NO_UID)); 11535 } else if (transportType == TRANSPORT_WIFI) { 11536 verify(mIBatteryStats).noteWifiRadioPowerState(eq(DC_POWER_STATE_LOW), 11537 anyLong() /* timestampNs */, eq(NETWORK_ACTIVITY_NO_UID)); 11538 } 11539 } else { 11540 // If TrackMultiNetworks is disabled, LegacyNetworkActivityTracker does not call 11541 // BatteryStats API by the netd activity change callback since BatteryStatsService 11542 // listen to netd callback via NetworkManagementService and update battery stats by 11543 // itself. 11544 verify(mIBatteryStats, never()) 11545 .noteMobileRadioPowerState(anyInt(), anyLong(), anyInt()); 11546 verify(mIBatteryStats, never()) 11547 .noteWifiRadioPowerState(anyInt(), anyLong(), anyInt()); 11548 } 11549 11550 // Interface goes to active state 11551 netdUnsolicitedEventListener.onInterfaceClassActivityChanged(true /* isActive */, 11552 idleTimerLabel, TIMESTAMP, TEST_PACKAGE_UID); 11553 mServiceContext.expectDataActivityBroadcast(legacyType, true /* isActive */, TIMESTAMP); 11554 assertTrue(onNetworkActiveCv.block(TEST_CALLBACK_TIMEOUT_MS)); 11555 assertTrue(mCm.isDefaultNetworkActive()); 11556 if (mDeps.isAtLeastV()) { 11557 if (transportType == TRANSPORT_CELLULAR) { 11558 verify(mIBatteryStats).noteMobileRadioPowerState(eq(DC_POWER_STATE_HIGH), 11559 anyLong() /* timestampNs */, eq(TEST_PACKAGE_UID)); 11560 } else if (transportType == TRANSPORT_WIFI) { 11561 verify(mIBatteryStats).noteWifiRadioPowerState(eq(DC_POWER_STATE_HIGH), 11562 anyLong() /* timestampNs */, eq(TEST_PACKAGE_UID)); 11563 } 11564 } else { 11565 // If TrackMultiNetworks is disabled, LegacyNetworkActivityTracker does not call 11566 // BatteryStats API by the netd activity change callback since BatteryStatsService 11567 // listen to netd callback via NetworkManagementService and update battery stats by 11568 // itself. 11569 verify(mIBatteryStats, never()) 11570 .noteMobileRadioPowerState(anyInt(), anyLong(), anyInt()); 11571 verify(mIBatteryStats, never()) 11572 .noteWifiRadioPowerState(anyInt(), anyLong(), anyInt()); 11573 } 11574 }, () -> { // Cleanup 11575 mCm.unregisterNetworkCallback(defaultCallback); 11576 }, () -> { // Cleanup 11577 mCm.removeDefaultNetworkActiveListener(listener); 11578 }, () -> { // Cleanup 11579 agent.disconnect(); 11580 }); 11581 } 11582 11583 @Test 11584 public void testInterfaceClassActivityChangedWifi() throws Exception { 11585 doTestInterfaceClassActivityChanged(TRANSPORT_WIFI); 11586 } 11587 11588 @Test 11589 public void testInterfaceClassActivityChangedCellular() throws Exception { 11590 doTestInterfaceClassActivityChanged(TRANSPORT_CELLULAR); 11591 } 11592 11593 private void doTestOnNetworkActive_NewNetworkConnects(int transportType, boolean expectCapChanged) 11594 throws Exception { 11595 final ConditionVariable onNetworkActiveCv = new ConditionVariable(); 11596 final ConnectivityManager.OnNetworkActiveListener listener = onNetworkActiveCv::open; 11597 11598 final LinkProperties lp = new LinkProperties(); 11599 lp.setInterfaceName(transportToTestIfaceName(transportType)); 11600 final TestNetworkAgentWrapper agent = new TestNetworkAgentWrapper(transportType, lp); 11601 11602 testAndCleanup(() -> { 11603 mCm.addDefaultNetworkActiveListener(listener); 11604 agent.connect(true); 11605 if (expectCapChanged) { 11606 assertTrue(onNetworkActiveCv.block(TEST_CALLBACK_TIMEOUT_MS)); 11607 } else { 11608 assertFalse(onNetworkActiveCv.block(TEST_CALLBACK_TIMEOUT_MS)); 11609 } 11610 assertTrue(mCm.isDefaultNetworkActive()); 11611 }, () -> { // Cleanup 11612 mCm.removeDefaultNetworkActiveListener(listener); 11613 }, () -> { // Cleanup 11614 agent.disconnect(); 11615 }); 11616 } 11617 11618 @Test 11619 public void testOnNetworkActive_NewCellConnects_CallbackCalled() throws Exception { 11620 doTestOnNetworkActive_NewNetworkConnects(TRANSPORT_CELLULAR, true /* expectCapChanged */); 11621 } 11622 11623 @Test 11624 public void testOnNetworkActive_NewEthernetConnects_Callback() throws Exception { 11625 // On pre-V devices, LegacyNetworkActivityTracker calls onNetworkActive callback only for 11626 // networks that tracker adds the idle timer to. And the tracker does not set the idle timer 11627 // for the ethernet network. 11628 // So onNetworkActive is not called when the ethernet becomes the default network 11629 final boolean expectCapChanged = mDeps.isAtLeastV(); 11630 doTestOnNetworkActive_NewNetworkConnects(TRANSPORT_ETHERNET, expectCapChanged); 11631 } 11632 11633 @Test 11634 public void testIsDefaultNetworkActiveNoDefaultNetwork() throws Exception { 11635 // isDefaultNetworkActive returns true if there is no default network, which is known issue. 11636 assertTrue(mCm.isDefaultNetworkActive()); 11637 11638 final LinkProperties cellLp = new LinkProperties(); 11639 cellLp.setInterfaceName(MOBILE_IFNAME); 11640 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp); 11641 mCellAgent.connect(true); 11642 // Network is considered active when the network becomes the default network. 11643 assertTrue(mCm.isDefaultNetworkActive()); 11644 11645 mCellAgent.disconnect(); 11646 waitForIdle(); 11647 11648 assertTrue(mCm.isDefaultNetworkActive()); 11649 } 11650 11651 @Test 11652 public void testDataActivityTracking() throws Exception { 11653 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 11654 final NetworkRequest networkRequest = new NetworkRequest.Builder() 11655 .addCapability(NET_CAPABILITY_INTERNET) 11656 .build(); 11657 mCm.registerNetworkCallback(networkRequest, networkCallback); 11658 11659 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 11660 final String cellIdleTimerLabel = Integer.toString(getIdleTimerLabel( 11661 mCellAgent.getNetwork().netId, TRANSPORT_CELLULAR)); 11662 final LinkProperties cellLp = new LinkProperties(); 11663 cellLp.setInterfaceName(MOBILE_IFNAME); 11664 mCellAgent.sendLinkProperties(cellLp); 11665 mCellAgent.connect(true); 11666 networkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 11667 verify(mMockNetd, times(1)).idletimerAddInterface(eq(MOBILE_IFNAME), anyInt(), 11668 eq(cellIdleTimerLabel)); 11669 11670 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 11671 String wifiIdleTimerLabel = Integer.toString(getIdleTimerLabel( 11672 mWiFiAgent.getNetwork().netId, TRANSPORT_WIFI)); 11673 final LinkProperties wifiLp = new LinkProperties(); 11674 wifiLp.setInterfaceName(WIFI_IFNAME); 11675 mWiFiAgent.sendLinkProperties(wifiLp); 11676 11677 // Network switch 11678 mWiFiAgent.connect(true); 11679 networkCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 11680 networkCallback.expectLosing(mCellAgent); 11681 networkCallback.expectCaps(mWiFiAgent, c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 11682 verify(mMockNetd, times(1)).idletimerAddInterface(eq(WIFI_IFNAME), anyInt(), 11683 eq(wifiIdleTimerLabel)); 11684 if (mDeps.isAtLeastV()) { 11685 // V+ devices add idleTimer when the network is first connected and remove when the 11686 // network is disconnected. 11687 verify(mMockNetd, never()).idletimerRemoveInterface(eq(MOBILE_IFNAME), anyInt(), 11688 eq(Integer.toString(mCellAgent.getNetwork().netId))); 11689 } else { 11690 // pre V devices add idleTimer when the network becomes the default network and remove 11691 // when the network becomes no longer the default network. 11692 verify(mMockNetd, times(1)).idletimerRemoveInterface(eq(MOBILE_IFNAME), anyInt(), 11693 eq(Integer.toString(TRANSPORT_CELLULAR))); 11694 } 11695 11696 // Disconnect wifi and switch back to cell 11697 reset(mMockNetd); 11698 mWiFiAgent.disconnect(); 11699 networkCallback.expect(LOST, mWiFiAgent); 11700 assertNoCallbacks(networkCallback); 11701 verify(mMockNetd, times(1)).idletimerRemoveInterface(eq(WIFI_IFNAME), anyInt(), 11702 eq(wifiIdleTimerLabel)); 11703 if (mDeps.isAtLeastV()) { 11704 verify(mMockNetd, never()).idletimerAddInterface(eq(MOBILE_IFNAME), anyInt(), 11705 eq(Integer.toString(mCellAgent.getNetwork().netId))); 11706 } else { 11707 verify(mMockNetd, times(1)).idletimerAddInterface(eq(MOBILE_IFNAME), anyInt(), 11708 eq(Integer.toString(TRANSPORT_CELLULAR))); 11709 } 11710 11711 // reconnect wifi 11712 reset(mMockNetd); 11713 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 11714 wifiIdleTimerLabel = Integer.toString(getIdleTimerLabel( 11715 mWiFiAgent.getNetwork().netId, TRANSPORT_WIFI)); 11716 wifiLp.setInterfaceName(WIFI_IFNAME); 11717 mWiFiAgent.sendLinkProperties(wifiLp); 11718 mWiFiAgent.connect(true); 11719 networkCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 11720 networkCallback.expectLosing(mCellAgent); 11721 networkCallback.expectCaps(mWiFiAgent, c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 11722 verify(mMockNetd, times(1)).idletimerAddInterface(eq(WIFI_IFNAME), anyInt(), 11723 eq(wifiIdleTimerLabel)); 11724 if (mDeps.isAtLeastV()) { 11725 verify(mMockNetd, never()).idletimerRemoveInterface(eq(MOBILE_IFNAME), anyInt(), 11726 eq(Integer.toString(mCellAgent.getNetwork().netId))); 11727 } else { 11728 verify(mMockNetd, times(1)).idletimerRemoveInterface(eq(MOBILE_IFNAME), anyInt(), 11729 eq(Integer.toString(TRANSPORT_CELLULAR))); 11730 } 11731 11732 // Disconnect cell 11733 reset(mMockNetd); 11734 mCellAgent.disconnect(); 11735 networkCallback.expect(LOST, mCellAgent); 11736 waitForIdle(); 11737 if (mDeps.isAtLeastV()) { 11738 verify(mMockNetd, times(1)).idletimerRemoveInterface(eq(MOBILE_IFNAME), anyInt(), 11739 eq(Integer.toString(mCellAgent.getNetwork().netId))); 11740 } else { 11741 // LOST callback is triggered earlier than removing idle timer. Broadcast should also be 11742 // sent as network being switched. Ensure rule removal for cell will not be triggered 11743 // unexpectedly before network being removed. 11744 verify(mMockNetd, times(0)).idletimerRemoveInterface(eq(MOBILE_IFNAME), anyInt(), 11745 eq(Integer.toString(TRANSPORT_CELLULAR))); 11746 } 11747 verify(mMockNetd, times(1)).networkDestroy(eq(mCellAgent.getNetwork().netId)); 11748 verify(mMockDnsResolver, times(1)).destroyNetworkCache(eq(mCellAgent.getNetwork().netId)); 11749 11750 // Disconnect wifi 11751 ExpectedBroadcast b = expectConnectivityAction(TYPE_WIFI, DetailedState.DISCONNECTED); 11752 mWiFiAgent.disconnect(); 11753 b.expectBroadcast(); 11754 verify(mMockNetd, times(1)).idletimerRemoveInterface(eq(WIFI_IFNAME), anyInt(), 11755 eq(wifiIdleTimerLabel)); 11756 11757 // Clean up 11758 mCm.unregisterNetworkCallback(networkCallback); 11759 } 11760 11761 @Test 11762 public void testDataActivityTracking_VpnNetwork() throws Exception { 11763 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 11764 mWiFiAgent.connect(true /* validated */); 11765 mMockVpn.setUnderlyingNetworks(new Network[] { mWiFiAgent.getNetwork() }); 11766 11767 final LinkProperties lp = new LinkProperties(); 11768 lp.setInterfaceName(VPN_IFNAME); 11769 mMockVpn.establishForMyUid(lp); 11770 11771 // NetworkActivityTracker should not track the VPN network since VPN can change the 11772 // underlying network without disconnect. 11773 verify(mMockNetd, never()).idletimerAddInterface(eq(VPN_IFNAME), anyInt(), any()); 11774 } 11775 11776 private void verifyTcpBufferSizeChange(String tcpBufferSizes) throws Exception { 11777 String[] values = tcpBufferSizes.split(","); 11778 String rmemValues = String.join(" ", values[0], values[1], values[2]); 11779 String wmemValues = String.join(" ", values[3], values[4], values[5]); 11780 verify(mMockNetd, atLeastOnce()).setTcpRWmemorySize(rmemValues, wmemValues); 11781 reset(mMockNetd); 11782 } 11783 11784 @Test 11785 public void testTcpBufferReset() throws Exception { 11786 final String testTcpBufferSizes = "1,2,3,4,5,6"; 11787 final NetworkRequest networkRequest = new NetworkRequest.Builder() 11788 .addTransportType(TRANSPORT_CELLULAR) 11789 .addCapability(NET_CAPABILITY_INTERNET) 11790 .build(); 11791 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 11792 mCm.registerNetworkCallback(networkRequest, networkCallback); 11793 11794 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 11795 reset(mMockNetd); 11796 // Switching default network updates TCP buffer sizes. 11797 mCellAgent.connect(false); 11798 networkCallback.expectAvailableCallbacksUnvalidated(mCellAgent); 11799 verifyTcpBufferSizeChange(ConnectivityService.DEFAULT_TCP_BUFFER_SIZES); 11800 // Change link Properties should have updated tcp buffer size. 11801 LinkProperties lp = new LinkProperties(); 11802 lp.setTcpBufferSizes(testTcpBufferSizes); 11803 mCellAgent.sendLinkProperties(lp); 11804 networkCallback.expect(LINK_PROPERTIES_CHANGED, mCellAgent); 11805 verifyTcpBufferSizeChange(testTcpBufferSizes); 11806 // Clean up. 11807 mCellAgent.disconnect(); 11808 networkCallback.expect(LOST, mCellAgent); 11809 networkCallback.assertNoCallback(); 11810 mCm.unregisterNetworkCallback(networkCallback); 11811 } 11812 11813 @Test 11814 public void testGetGlobalProxyForNetwork() throws Exception { 11815 final ProxyInfo testProxyInfo = ProxyInfo.buildDirectProxy("test", 8888); 11816 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 11817 final Network wifiNetwork = mWiFiAgent.getNetwork(); 11818 mProxyTracker.setGlobalProxy(testProxyInfo); 11819 assertEquals(testProxyInfo, mService.getProxyForNetwork(wifiNetwork)); 11820 } 11821 11822 @Test 11823 public void testGetProxyForActiveNetwork() throws Exception { 11824 final ProxyInfo testProxyInfo = ProxyInfo.buildDirectProxy("test", 8888); 11825 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 11826 mWiFiAgent.connect(true); 11827 waitForIdle(); 11828 assertNull(mService.getProxyForNetwork(null)); 11829 11830 final LinkProperties testLinkProperties = new LinkProperties(); 11831 testLinkProperties.setHttpProxy(testProxyInfo); 11832 11833 mWiFiAgent.sendLinkProperties(testLinkProperties); 11834 waitForIdle(); 11835 11836 assertEquals(testProxyInfo, mService.getProxyForNetwork(null)); 11837 } 11838 11839 /* 11840 * Note for maintainers about how PAC proxies are implemented in Android. 11841 * 11842 * Generally, a proxy is just a hostname and a port to which requests are sent, instead of 11843 * sending them directly. Most HTTP libraries know to use this protocol, and the Java 11844 * language has properties to help handling these : 11845 * https://docs.oracle.com/javase/8/docs/technotes/guides/net/proxies.html 11846 * Unfortunately these properties are very old and do not take multi-networking into account. 11847 * 11848 * A PAC proxy consists of a javascript file stored on a server, and the client is expected to 11849 * download the file and interpret the javascript for each HTTP request to know where to direct 11850 * it. The device must therefore run code (namely, a javascript interpreter) to interpret the 11851 * PAC file correctly. Most HTTP libraries do not know how to do this, since they do not 11852 * embark a javascript interpreter (and it would be generally unreasonable for them to do 11853 * so). Some apps, notably browsers, do know how to do this, but they are the exception rather 11854 * than the rule. 11855 * So to support most apps, Android embarks the javascript interpreter. When a network is 11856 * configured to have a PAC proxy, Android will first set the ProxyInfo object to an object 11857 * that contains the PAC URL (to communicate that to apps that know how to use it), then 11858 * download the PAC file and start a native process which will open a server on localhost, 11859 * and uses the interpreter inside WebView to interpret the PAC file. This server takes 11860 * a little bit of time to start and will listen on a random port. When the port is known, 11861 * the framework receives a notification and it updates the ProxyInfo in LinkProperties 11862 * as well as send a broadcast to inform apps. This new ProxyInfo still contains the PAC URL, 11863 * but it also contains "localhost" as the host and the port that the server listens to as 11864 * the port. This will let HTTP libraries that don't have a javascript interpreter work, 11865 * because they'll send the requests to this server running on localhost on the correct port, 11866 * and this server will do what is appropriate with each request according to the PAC file. 11867 * 11868 * Note that at the time of this writing, Android does not support starting multiple local 11869 * PAC servers, though this would be possible in theory by just starting multiple instances 11870 * of this process running their server on different ports. As a stopgap measure, Android 11871 * keeps one local server which is always the one for the default network. If a non-default 11872 * network has a PAC proxy, it will have a LinkProperties with a port of -1, which means it 11873 * could still be used by apps that know how to use the PAC URL directly, but not by HTTP 11874 * libs that don't know how to do that. When a network with a PAC proxy becomes the default, 11875 * the local server is started. When a network without a PAC proxy becomes the default, the 11876 * local server is stopped if it is running (and the LP for the old default network should 11877 * be reset to have a port of -1). 11878 * 11879 * In principle, each network can be configured with a different proxy (typically in the 11880 * network settings for a Wi-Fi network). These end up exposed in the LinkProperties of the 11881 * relevant network. 11882 * Android also exposes ConnectivityManager#getDefaultProxy, which is simply the proxy for 11883 * the default network. This was retrofitted from a time where Android did not support multiple 11884 * concurrent networks, hence the difficult architecture. 11885 * Note that there is also a "global" proxy that can be set by the DPM. When this is set, 11886 * it overrides the proxy settings for every single network at the same time – that is, the 11887 * system behaves as if the global proxy is the configured proxy for each network. 11888 * 11889 * Generally there are four ways for apps to look up the proxy. 11890 * - Looking up the ProxyInfo in the LinkProperties for a network. 11891 * - Listening to the PROXY_CHANGED_ACTION broadcast 11892 * - Calling ConnectivityManager#getDefaultProxy, or ConnectivityManager#getProxyForNetwork 11893 * which can be used to retrieve the proxy for any given network or the default network by 11894 * passing null. 11895 * - Reading the standard JVM properties (http{s,}.proxy{Host,Port}). See the Java 11896 * distribution documentation for details on how these are supposed to work : 11897 * https://docs.oracle.com/javase/8/docs/technotes/guides/net/proxies.html 11898 * In Android, these are set by ActivityThread in each process in response to the broadcast. 11899 * Many apps actually use these, and it's important they work because it's part of the 11900 * Java standard, meaning they need to be set for existing Java libs to work on Android. 11901 */ 11902 @Test 11903 public void testPacProxy() throws Exception { 11904 final Uri pacUrl = Uri.parse("https://pac-url"); 11905 11906 final TestNetworkCallback cellCallback = new TestNetworkCallback(); 11907 final NetworkRequest cellRequest = new NetworkRequest.Builder() 11908 .addTransportType(TRANSPORT_CELLULAR).build(); 11909 // Request cell to make sure it doesn't disconnect at an arbitrary point in the test, 11910 // which would make testing the callbacks on it difficult. 11911 mCm.requestNetwork(cellRequest, cellCallback); 11912 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 11913 mCellAgent.connect(true); 11914 cellCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 11915 11916 final TestNetworkCallback wifiCallback = new TestNetworkCallback(); 11917 final NetworkRequest wifiRequest = new NetworkRequest.Builder() 11918 .addTransportType(TRANSPORT_WIFI).build(); 11919 mCm.registerNetworkCallback(wifiRequest, wifiCallback); 11920 11921 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 11922 mWiFiAgent.connect(true); 11923 wifiCallback.expectAvailableThenValidatedCallbacks(mWiFiAgent); 11924 cellCallback.assertNoCallback(); 11925 11926 final ProxyInfo initialProxyInfo = ProxyInfo.buildPacProxy(pacUrl); 11927 final LinkProperties testLinkProperties = new LinkProperties(); 11928 testLinkProperties.setHttpProxy(initialProxyInfo); 11929 mWiFiAgent.sendLinkProperties(testLinkProperties); 11930 wifiCallback.expect(CallbackEntry.LINK_PROPERTIES_CHANGED, mWiFiAgent); 11931 cellCallback.assertNoCallback(); 11932 11933 // At first the local PAC proxy server is unstarted (see the description of what the local 11934 // server is in the comment at the top of this method). It will contain the PAC URL and a 11935 // port of -1 because it is unstarted. Check that all ways of getting that proxy info 11936 // returns the same object that was initially created. 11937 final ProxyInfo unstartedDefaultProxyInfo = mService.getProxyForNetwork(null); 11938 final ProxyInfo unstartedWifiProxyInfo = mService.getProxyForNetwork( 11939 mWiFiAgent.getNetwork()); 11940 final LinkProperties unstartedLp = 11941 mService.getLinkProperties(mWiFiAgent.getNetwork()); 11942 11943 assertEquals(initialProxyInfo, unstartedDefaultProxyInfo); 11944 assertEquals(initialProxyInfo, unstartedWifiProxyInfo); 11945 assertEquals(initialProxyInfo, unstartedLp.getHttpProxy()); 11946 11947 // Make sure the cell network is unaffected. The LP are per-network and each network has 11948 // its own configuration. The default proxy and broadcast are system-wide, and the JVM 11949 // properties are per-process, and therefore can have only one value at any given time, 11950 // so the code sets them to the proxy of the default network (TODO : really, since the 11951 // default process is per-network, the JVM properties (http.proxyHost family – see 11952 // the comment at the top of the method for details about these) also should be per-network 11953 // and even the broadcast contents should be but none of this is implemented). The LP are 11954 // still per-network, and a process that wants to use a non-default network is supposed to 11955 // look up the proxy in its LP and it has to be correct. 11956 assertNull(mService.getLinkProperties(mCellAgent.getNetwork()).getHttpProxy()); 11957 assertNull(mService.getProxyForNetwork(mCellAgent.getNetwork())); 11958 11959 // Simulate PacManager sending the notification that the local server has started 11960 final ProxyInfo servingProxyInfo = new ProxyInfo(pacUrl, 2097); 11961 final ExpectedBroadcast servingProxyBroadcast = expectProxyChangeAction(servingProxyInfo); 11962 mService.simulateUpdateProxyInfo(mWiFiAgent.getNetwork(), servingProxyInfo); 11963 wifiCallback.expect(CallbackEntry.LINK_PROPERTIES_CHANGED, mWiFiAgent); 11964 cellCallback.assertNoCallback(); 11965 servingProxyBroadcast.expectBroadcast(); 11966 11967 final ProxyInfo startedDefaultProxyInfo = mService.getProxyForNetwork(null); 11968 final ProxyInfo startedWifiProxyInfo = mService.getProxyForNetwork( 11969 mWiFiAgent.getNetwork()); 11970 final LinkProperties startedLp = mService.getLinkProperties(mWiFiAgent.getNetwork()); 11971 assertEquals(servingProxyInfo, startedDefaultProxyInfo); 11972 assertEquals(servingProxyInfo, startedWifiProxyInfo); 11973 assertEquals(servingProxyInfo, startedLp.getHttpProxy()); 11974 // Make sure the cell network is still unaffected 11975 assertNull(mService.getLinkProperties(mCellAgent.getNetwork()).getHttpProxy()); 11976 assertNull(mService.getProxyForNetwork(mCellAgent.getNetwork())); 11977 11978 // Start an ethernet network which will become the default, in order to test what happens 11979 // to the proxy of wifi while manipulating the proxy of ethernet. 11980 final Uri ethPacUrl = Uri.parse("https://ethernet-pac-url"); 11981 final TestableNetworkCallback ethernetCallback = new TestableNetworkCallback(); 11982 final NetworkRequest ethernetRequest = new NetworkRequest.Builder() 11983 .addTransportType(TRANSPORT_ETHERNET).build(); 11984 mEthernetAgent = new TestNetworkAgentWrapper(TRANSPORT_ETHERNET); 11985 mCm.registerNetworkCallback(ethernetRequest, ethernetCallback); 11986 mEthernetAgent.connect(true); 11987 ethernetCallback.expectAvailableThenValidatedCallbacks(mEthernetAgent); 11988 11989 // Wifi is no longer the default, so it should get a callback to LP changed with a PAC 11990 // proxy but a port of -1 (since the local proxy doesn't serve wifi now) 11991 wifiCallback.expect(LINK_PROPERTIES_CHANGED, mWiFiAgent, 11992 lp -> lp.getLp().getHttpProxy().getPort() == -1 11993 && lp.getLp().getHttpProxy().isPacProxy()); 11994 // Wifi is lingered as it was the default but is no longer serving any request. 11995 wifiCallback.expect(CallbackEntry.LOSING, mWiFiAgent); 11996 11997 // Now arrange for Ethernet to have a PAC proxy. 11998 final ProxyInfo ethProxy = ProxyInfo.buildPacProxy(ethPacUrl); 11999 final LinkProperties ethLinkProperties = new LinkProperties(); 12000 ethLinkProperties.setHttpProxy(ethProxy); 12001 mEthernetAgent.sendLinkProperties(ethLinkProperties); 12002 ethernetCallback.expect(CallbackEntry.LINK_PROPERTIES_CHANGED, mEthernetAgent); 12003 // Default network is Ethernet 12004 assertEquals(ethProxy, mService.getProxyForNetwork(null)); 12005 assertEquals(ethProxy, mService.getProxyForNetwork(mEthernetAgent.getNetwork())); 12006 // Proxy info for WiFi ideally should be the old one with the old server still running, 12007 // but as the PAC code only handles one server at any given time, this can't work. Wifi 12008 // having null as a proxy also won't work (apps using WiFi will try to access the network 12009 // without proxy) but is not as bad as having the new proxy (that would send requests 12010 // over the default network). 12011 assertEquals(initialProxyInfo, mService.getProxyForNetwork(mWiFiAgent.getNetwork())); 12012 assertNull(mService.getProxyForNetwork(mCellAgent.getNetwork())); 12013 12014 // Expect the local PAC proxy server starts to serve the proxy on Ethernet. Use 12015 // simulateUpdateProxyInfo to simulate this, and check that the callback is called to 12016 // inform apps of the port and that the various networks have the expected proxies in 12017 // their link properties. 12018 final ProxyInfo servingEthProxy = new ProxyInfo(ethPacUrl, 2099); 12019 final ExpectedBroadcast servingEthProxyBroadcast = expectProxyChangeAction(servingEthProxy); 12020 final ExpectedBroadcast servingProxyBroadcast2 = expectProxyChangeAction(servingProxyInfo); 12021 mService.simulateUpdateProxyInfo(mEthernetAgent.getNetwork(), servingEthProxy); 12022 ethernetCallback.expect(CallbackEntry.LINK_PROPERTIES_CHANGED, mEthernetAgent); 12023 assertEquals(servingEthProxy, mService.getProxyForNetwork(null)); 12024 assertEquals(servingEthProxy, mService.getProxyForNetwork(mEthernetAgent.getNetwork())); 12025 assertEquals(initialProxyInfo, mService.getProxyForNetwork(mWiFiAgent.getNetwork())); 12026 assertNull(mService.getProxyForNetwork(mCellAgent.getNetwork())); 12027 servingEthProxyBroadcast.expectBroadcast(); 12028 12029 // Ethernet disconnects, back to WiFi 12030 mEthernetAgent.disconnect(); 12031 ethernetCallback.expect(CallbackEntry.LOST, mEthernetAgent); 12032 12033 // WiFi is now the default network again. However, the local proxy server does not serve 12034 // WiFi at this time, so at this time a proxy with port -1 is still the correct value. 12035 // In time, the local proxy server for ethernet will be downed and the local proxy server 12036 // for WiFi will be restarted, and WiFi will see an update to its LP with the new port, 12037 // but in this test this won't happen until the test simulates the local proxy starting 12038 // up for WiFi (which is done just a few lines below). This is therefore the perfect place 12039 // to check that WiFi is unaffected until the new local proxy starts up. 12040 wifiCallback.assertNoCallback(); 12041 assertEquals(initialProxyInfo, mService.getProxyForNetwork(null)); 12042 assertEquals(initialProxyInfo, mService.getProxyForNetwork(mWiFiAgent.getNetwork())); 12043 assertNull(mService.getProxyForNetwork(mCellAgent.getNetwork())); 12044 // Note : strictly speaking, for correctness here apps should expect a broadcast with a 12045 // port of -1, since that's the current default proxy. The code does not send this 12046 // broadcast. In practice though, not sending it is more useful since the new proxy will 12047 // start momentarily, so broadcasting and getting all apps to update and retry once now 12048 // and again in 250ms is kind of counter-productive, so don't fix this bug. 12049 12050 // After a while the PAC file for wifi is resolved again and the local proxy server 12051 // starts up. This should cause a LP event to inform clients of the port to access the 12052 // proxy server for wifi. 12053 mService.simulateUpdateProxyInfo(mWiFiAgent.getNetwork(), servingProxyInfo); 12054 wifiCallback.expect(CallbackEntry.LINK_PROPERTIES_CHANGED, mWiFiAgent); 12055 assertEquals(servingProxyInfo, mService.getProxyForNetwork(null)); 12056 assertEquals(servingProxyInfo, mService.getProxyForNetwork(mWiFiAgent.getNetwork())); 12057 assertNull(mService.getProxyForNetwork(mCellAgent.getNetwork())); 12058 servingProxyBroadcast2.expectBroadcast(); 12059 12060 // Expect a broadcast for an empty proxy after wifi disconnected, because cell is now 12061 // the default network and it doesn't have a proxy. Whether "no proxy" is a null pointer 12062 // or a ProxyInfo with an empty host doesn't matter because both are correct, so this test 12063 // accepts both. 12064 final ExpectedBroadcast emptyProxyBroadcast = expectProxyChangeAction( 12065 proxy -> proxy == null || TextUtils.isEmpty(proxy.getHost())); 12066 mWiFiAgent.disconnect(); 12067 emptyProxyBroadcast.expectBroadcast(); 12068 wifiCallback.expect(CallbackEntry.LOST, mWiFiAgent); 12069 assertNull(mService.getProxyForNetwork(null)); 12070 assertNull(mService.getLinkProperties(mCellAgent.getNetwork()).getHttpProxy()); 12071 assertNull(mService.getGlobalProxy()); 12072 12073 mCm.unregisterNetworkCallback(cellCallback); 12074 } 12075 12076 @Test 12077 public void testPacProxy_NetworkDisconnects_BroadcastSent() throws Exception { 12078 // Make a WiFi network with a PAC URI. 12079 final Uri pacUrl = Uri.parse("https://pac-url"); 12080 final ProxyInfo initialProxyInfo = ProxyInfo.buildPacProxy(pacUrl); 12081 final LinkProperties testLinkProperties = new LinkProperties(); 12082 testLinkProperties.setHttpProxy(initialProxyInfo); 12083 12084 final TestNetworkCallback wifiCallback = new TestNetworkCallback(); 12085 final NetworkRequest wifiRequest = new NetworkRequest.Builder() 12086 .addTransportType(TRANSPORT_WIFI).build(); 12087 mCm.registerNetworkCallback(wifiRequest, wifiCallback); 12088 12089 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, testLinkProperties); 12090 mWiFiAgent.connect(true); 12091 // Wifi is up, but the local proxy server hasn't started yet. 12092 wifiCallback.expectAvailableThenValidatedCallbacks(mWiFiAgent); 12093 12094 // Simulate PacManager sending the notification that the local server has started 12095 final ProxyInfo servingProxyInfo = new ProxyInfo(pacUrl, 2097); 12096 final ExpectedBroadcast servingProxyBroadcast = expectProxyChangeAction(servingProxyInfo); 12097 mService.simulateUpdateProxyInfo(mWiFiAgent.getNetwork(), servingProxyInfo); 12098 wifiCallback.expect(CallbackEntry.LINK_PROPERTIES_CHANGED, mWiFiAgent); 12099 servingProxyBroadcast.expectBroadcast(); 12100 12101 // Now disconnect Wi-Fi and make sure there is a broadcast for some empty proxy. Whether 12102 // the "empty" proxy is a null pointer or a ProxyInfo with an empty host doesn't matter 12103 // because both are correct, so this test accepts both. 12104 final ExpectedBroadcast emptyProxyBroadcast = expectProxyChangeAction( 12105 proxy -> proxy == null || TextUtils.isEmpty(proxy.getHost())); 12106 mWiFiAgent.disconnect(); 12107 wifiCallback.expect(CallbackEntry.LOST, mWiFiAgent); 12108 emptyProxyBroadcast.expectBroadcast(); 12109 } 12110 12111 @Test 12112 public void testGetProxyForVPN() throws Exception { 12113 final ProxyInfo testProxyInfo = ProxyInfo.buildDirectProxy("test", 8888); 12114 12115 // Set up a WiFi network with no proxy 12116 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 12117 mWiFiAgent.connect(true); 12118 waitForIdle(); 12119 assertNull(mService.getProxyForNetwork(null)); 12120 12121 // Connect a VPN network with a proxy. 12122 LinkProperties testLinkProperties = new LinkProperties(); 12123 testLinkProperties.setHttpProxy(testProxyInfo); 12124 mMockVpn.establishForMyUid(testLinkProperties); 12125 assertUidRangesUpdatedForMyUid(true); 12126 12127 // Test that the VPN network returns a proxy, and the WiFi does not. 12128 assertEquals(testProxyInfo, mService.getProxyForNetwork(mMockVpn.getNetwork())); 12129 assertEquals(testProxyInfo, mService.getProxyForNetwork(null)); 12130 assertNull(mService.getProxyForNetwork(mWiFiAgent.getNetwork())); 12131 12132 // Test that the VPN network returns no proxy when it is set to null. 12133 testLinkProperties.setHttpProxy(null); 12134 mMockVpn.sendLinkProperties(testLinkProperties); 12135 waitForIdle(); 12136 assertNull(mService.getProxyForNetwork(mMockVpn.getNetwork())); 12137 assertNull(mService.getProxyForNetwork(null)); 12138 12139 // Set WiFi proxy and check that the vpn proxy is still null. 12140 testLinkProperties.setHttpProxy(testProxyInfo); 12141 mWiFiAgent.sendLinkProperties(testLinkProperties); 12142 waitForIdle(); 12143 assertNull(mService.getProxyForNetwork(null)); 12144 12145 // Disconnect from VPN and check that the active network, which is now the WiFi, has the 12146 // correct proxy setting. 12147 mMockVpn.disconnect(); 12148 waitForIdle(); 12149 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetwork()); 12150 assertEquals(testProxyInfo, mService.getProxyForNetwork(mWiFiAgent.getNetwork())); 12151 assertEquals(testProxyInfo, mService.getProxyForNetwork(null)); 12152 } 12153 12154 @Test 12155 public void testFullyRoutedVpnResultsInInterfaceFilteringRules() throws Exception { 12156 LinkProperties lp = new LinkProperties(); 12157 lp.setInterfaceName("tun0"); 12158 lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), null)); 12159 lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), RTN_UNREACHABLE)); 12160 // The uid range needs to cover the test app so the network is visible to it. 12161 final Set<UidRange> vpnRange = Collections.singleton(PRIMARY_UIDRANGE); 12162 mMockVpn.establish(lp, VPN_UID, vpnRange); 12163 assertVpnUidRangesUpdated(true, vpnRange, VPN_UID); 12164 12165 // A connected VPN should have interface rules set up. There are two expected invocations, 12166 // one during the VPN initial connection, one during the VPN LinkProperties update. 12167 ArgumentCaptor<int[]> uidCaptor = ArgumentCaptor.forClass(int[].class); 12168 verify(mBpfNetMaps, times(2)).addUidInterfaceRules(eq("tun0"), uidCaptor.capture()); 12169 assertContainsExactly(uidCaptor.getAllValues().get(0), APP1_UID, APP2_UID); 12170 assertContainsExactly(uidCaptor.getAllValues().get(1), APP1_UID, APP2_UID); 12171 12172 mMockVpn.disconnect(); 12173 waitForIdle(); 12174 12175 // Disconnected VPN should have interface rules removed 12176 verify(mBpfNetMaps).removeUidInterfaceRules(uidCaptor.capture()); 12177 assertContainsExactly(uidCaptor.getValue(), APP1_UID, APP2_UID); 12178 } 12179 12180 private void checkInterfaceFilteringRuleWithNullInterface(final LinkProperties lp, 12181 final int uid) throws Exception { 12182 // The uid range needs to cover the test app so the network is visible to it. 12183 final Set<UidRange> vpnRange = Collections.singleton(PRIMARY_UIDRANGE); 12184 mMockVpn.establish(lp, uid, vpnRange); 12185 assertVpnUidRangesUpdated(true, vpnRange, uid); 12186 12187 if (mDeps.isAtLeastT()) { 12188 // On T and above, VPN should have rules for null interface. Null Interface is a 12189 // wildcard and this accepts traffic from all the interfaces. 12190 // There are two expected invocations, one during the VPN initial 12191 // connection, one during the VPN LinkProperties update. 12192 ArgumentCaptor<int[]> uidCaptor = ArgumentCaptor.forClass(int[].class); 12193 verify(mBpfNetMaps, times(2)).addUidInterfaceRules( 12194 eq(null) /* iface */, uidCaptor.capture()); 12195 if (uid == VPN_UID) { 12196 assertContainsExactly(uidCaptor.getAllValues().get(0), APP1_UID, APP2_UID); 12197 assertContainsExactly(uidCaptor.getAllValues().get(1), APP1_UID, APP2_UID); 12198 } else { 12199 assertContainsExactly(uidCaptor.getAllValues().get(0), APP1_UID, APP2_UID, VPN_UID); 12200 assertContainsExactly(uidCaptor.getAllValues().get(1), APP1_UID, APP2_UID, VPN_UID); 12201 } 12202 12203 mMockVpn.disconnect(); 12204 waitForIdle(); 12205 12206 // Disconnected VPN should have interface rules removed 12207 verify(mBpfNetMaps).removeUidInterfaceRules(uidCaptor.capture()); 12208 if (uid == VPN_UID) { 12209 assertContainsExactly(uidCaptor.getValue(), APP1_UID, APP2_UID); 12210 } else { 12211 assertContainsExactly(uidCaptor.getValue(), APP1_UID, APP2_UID, VPN_UID); 12212 } 12213 } else { 12214 // Before T, rules are not configured for null interface. 12215 verify(mBpfNetMaps, never()).addUidInterfaceRules(any(), any()); 12216 } 12217 } 12218 12219 @Test 12220 public void testLegacyVpnInterfaceFilteringRule() throws Exception { 12221 LinkProperties lp = new LinkProperties(); 12222 lp.setInterfaceName("tun0"); 12223 lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), null)); 12224 lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), null)); 12225 // Legacy VPN should have interface filtering with null interface. 12226 checkInterfaceFilteringRuleWithNullInterface(lp, Process.SYSTEM_UID); 12227 } 12228 12229 @Test 12230 public void testLocalIpv4OnlyVpnInterfaceFilteringRule() throws Exception { 12231 LinkProperties lp = new LinkProperties(); 12232 lp.setInterfaceName("tun0"); 12233 lp.addRoute(new RouteInfo(new IpPrefix("192.0.2.0/24"), null, "tun0")); 12234 lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), RTN_UNREACHABLE)); 12235 // VPN that does not provide a default route should have interface filtering with null 12236 // interface. 12237 checkInterfaceFilteringRuleWithNullInterface(lp, VPN_UID); 12238 } 12239 12240 @Test 12241 public void testVpnHandoverChangesInterfaceFilteringRule() throws Exception { 12242 LinkProperties lp = new LinkProperties(); 12243 lp.setInterfaceName("tun0"); 12244 lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), null)); 12245 lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), null)); 12246 // The uid range needs to cover the test app so the network is visible to it. 12247 final Set<UidRange> vpnRange = Collections.singleton(PRIMARY_UIDRANGE); 12248 mMockVpn.establish(lp, VPN_UID, vpnRange); 12249 assertVpnUidRangesUpdated(true, vpnRange, VPN_UID); 12250 12251 // Connected VPN should have interface rules set up. There are two expected invocations, 12252 // one during VPN uid update, one during VPN LinkProperties update 12253 ArgumentCaptor<int[]> uidCaptor = ArgumentCaptor.forClass(int[].class); 12254 verify(mBpfNetMaps, times(2)).addUidInterfaceRules(eq("tun0"), uidCaptor.capture()); 12255 assertContainsExactly(uidCaptor.getAllValues().get(0), APP1_UID, APP2_UID); 12256 assertContainsExactly(uidCaptor.getAllValues().get(1), APP1_UID, APP2_UID); 12257 12258 reset(mBpfNetMaps); 12259 InOrder inOrder = inOrder(mBpfNetMaps); 12260 lp.setInterfaceName("tun1"); 12261 mMockVpn.sendLinkProperties(lp); 12262 waitForIdle(); 12263 // VPN handover (switch to a new interface) should result in rules being updated (old rules 12264 // removed first, then new rules added) 12265 inOrder.verify(mBpfNetMaps).removeUidInterfaceRules(uidCaptor.capture()); 12266 assertContainsExactly(uidCaptor.getValue(), APP1_UID, APP2_UID); 12267 inOrder.verify(mBpfNetMaps).addUidInterfaceRules(eq("tun1"), uidCaptor.capture()); 12268 assertContainsExactly(uidCaptor.getValue(), APP1_UID, APP2_UID); 12269 12270 reset(mBpfNetMaps); 12271 lp = new LinkProperties(); 12272 lp.setInterfaceName("tun1"); 12273 lp.addRoute(new RouteInfo(new IpPrefix("192.0.2.0/24"), null, "tun1")); 12274 mMockVpn.sendLinkProperties(lp); 12275 waitForIdle(); 12276 // VPN not routing everything should no longer have interface filtering rules 12277 verify(mBpfNetMaps).removeUidInterfaceRules(uidCaptor.capture()); 12278 assertContainsExactly(uidCaptor.getValue(), APP1_UID, APP2_UID); 12279 12280 reset(mBpfNetMaps); 12281 lp = new LinkProperties(); 12282 lp.setInterfaceName("tun1"); 12283 lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), RTN_UNREACHABLE)); 12284 lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), null)); 12285 mMockVpn.sendLinkProperties(lp); 12286 waitForIdle(); 12287 // Back to routing all IPv6 traffic should have filtering rules 12288 verify(mBpfNetMaps).addUidInterfaceRules(eq("tun1"), uidCaptor.capture()); 12289 assertContainsExactly(uidCaptor.getValue(), APP1_UID, APP2_UID); 12290 } 12291 12292 @Test 12293 public void testUidUpdateChangesInterfaceFilteringRule() throws Exception { 12294 LinkProperties lp = new LinkProperties(); 12295 lp.setInterfaceName("tun0"); 12296 lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), RTN_UNREACHABLE)); 12297 lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), null)); 12298 // The uid range needs to cover the test app so the network is visible to it. 12299 final UidRange vpnRange = PRIMARY_UIDRANGE; 12300 final Set<UidRange> vpnRanges = Collections.singleton(vpnRange); 12301 mMockVpn.establish(lp, VPN_UID, vpnRanges); 12302 assertVpnUidRangesUpdated(true, vpnRanges, VPN_UID); 12303 12304 reset(mBpfNetMaps); 12305 InOrder inOrder = inOrder(mBpfNetMaps); 12306 12307 // Update to new range which is old range minus APP1, i.e. only APP2 12308 final Set<UidRange> newRanges = new HashSet<>(asList( 12309 new UidRange(vpnRange.start, APP1_UID - 1), 12310 new UidRange(APP1_UID + 1, vpnRange.stop))); 12311 mMockVpn.setUids(newRanges); 12312 waitForIdle(); 12313 12314 ArgumentCaptor<int[]> uidCaptor = ArgumentCaptor.forClass(int[].class); 12315 // Verify old rules are removed before new rules are added 12316 inOrder.verify(mBpfNetMaps).removeUidInterfaceRules(uidCaptor.capture()); 12317 assertContainsExactly(uidCaptor.getValue(), APP1_UID, APP2_UID); 12318 inOrder.verify(mBpfNetMaps).addUidInterfaceRules(eq("tun0"), uidCaptor.capture()); 12319 assertContainsExactly(uidCaptor.getValue(), APP2_UID); 12320 } 12321 12322 @Test 12323 public void testLinkPropertiesWithWakeOnLanForActiveNetwork() throws Exception { 12324 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 12325 12326 LinkProperties wifiLp = new LinkProperties(); 12327 wifiLp.setInterfaceName(WIFI_WOL_IFNAME); 12328 wifiLp.setWakeOnLanSupported(false); 12329 12330 // Default network switch should update ifaces. 12331 mWiFiAgent.connect(false); 12332 mWiFiAgent.sendLinkProperties(wifiLp); 12333 waitForIdle(); 12334 12335 // ConnectivityService should have changed the WakeOnLanSupported to true 12336 wifiLp.setWakeOnLanSupported(true); 12337 assertEquals(wifiLp, mService.getActiveLinkProperties()); 12338 } 12339 12340 @Test 12341 public void testLegacyExtraInfoSentToNetworkMonitor() throws Exception { 12342 class TestNetworkAgent extends NetworkAgent { 12343 TestNetworkAgent(Context context, Looper looper, NetworkAgentConfig config) { 12344 super(context, looper, "MockAgent", new NetworkCapabilities(), 12345 new LinkProperties(), 40 , config, null /* provider */); 12346 } 12347 } 12348 final NetworkAgent naNoExtraInfo = new TestNetworkAgent( 12349 mServiceContext, mCsHandlerThread.getLooper(), new NetworkAgentConfig()); 12350 naNoExtraInfo.register(); 12351 verify(mNetworkStack).makeNetworkMonitor(any(), isNull(), any()); 12352 naNoExtraInfo.unregister(); 12353 12354 reset(mNetworkStack); 12355 final NetworkAgentConfig config = 12356 new NetworkAgentConfig.Builder().setLegacyExtraInfo("legacyinfo").build(); 12357 final NetworkAgent naExtraInfo = new TestNetworkAgent( 12358 mServiceContext, mCsHandlerThread.getLooper(), config); 12359 naExtraInfo.register(); 12360 verify(mNetworkStack).makeNetworkMonitor(any(), eq("legacyinfo"), any()); 12361 naExtraInfo.unregister(); 12362 } 12363 12364 // To avoid granting location permission bypass. 12365 private void denyAllLocationPrivilegedPermissions() { 12366 mServiceContext.setPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, 12367 PERMISSION_DENIED); 12368 mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_DENIED); 12369 mServiceContext.setPermission(NETWORK_STACK, PERMISSION_DENIED); 12370 mServiceContext.setPermission(Manifest.permission.NETWORK_SETUP_WIZARD, 12371 PERMISSION_DENIED); 12372 } 12373 12374 private void setupLocationPermissions( 12375 int targetSdk, boolean locationToggle, String op, String perm) throws Exception { 12376 denyAllLocationPrivilegedPermissions(); 12377 12378 final ApplicationInfo applicationInfo = new ApplicationInfo(); 12379 applicationInfo.targetSdkVersion = targetSdk; 12380 doReturn(applicationInfo).when(mPackageManager) 12381 .getApplicationInfoAsUser(anyString(), anyInt(), any()); 12382 doReturn(targetSdk).when(mPackageManager).getTargetSdkVersion(any()); 12383 12384 doReturn(locationToggle).when(mLocationManager).isLocationEnabledForUser(any()); 12385 12386 if (op != null) { 12387 doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager).noteOp( 12388 eq(op), eq(Process.myUid()), eq(mContext.getPackageName()), 12389 eq(getAttributionTag()), anyString()); 12390 } 12391 12392 if (perm != null) { 12393 mServiceContext.setPermission(perm, PERMISSION_GRANTED); 12394 } 12395 } 12396 12397 private int getOwnerUidNetCapsPermission(int ownerUid, int callerUid, 12398 boolean includeLocationSensitiveInfo) { 12399 final NetworkCapabilities netCap = new NetworkCapabilities().setOwnerUid(ownerUid); 12400 12401 return mService.createWithLocationInfoSanitizedIfNecessaryWhenParceled( 12402 netCap, includeLocationSensitiveInfo, Process.myUid(), callerUid, 12403 mContext.getPackageName(), getAttributionTag()) 12404 .getOwnerUid(); 12405 } 12406 12407 private void verifyTransportInfoCopyNetCapsPermission( 12408 int callerUid, boolean includeLocationSensitiveInfo, 12409 boolean shouldMakeCopyWithLocationSensitiveFieldsParcelable) { 12410 final TransportInfo transportInfo = mock(TransportInfo.class); 12411 doReturn(REDACT_FOR_ACCESS_FINE_LOCATION).when(transportInfo).getApplicableRedactions(); 12412 final NetworkCapabilities netCap = 12413 new NetworkCapabilities().setTransportInfo(transportInfo); 12414 12415 mService.createWithLocationInfoSanitizedIfNecessaryWhenParceled( 12416 netCap, includeLocationSensitiveInfo, Process.myPid(), callerUid, 12417 mContext.getPackageName(), getAttributionTag()); 12418 if (shouldMakeCopyWithLocationSensitiveFieldsParcelable) { 12419 verify(transportInfo).makeCopy(REDACT_NONE); 12420 } else { 12421 verify(transportInfo).makeCopy(REDACT_FOR_ACCESS_FINE_LOCATION); 12422 } 12423 } 12424 12425 private void verifyOwnerUidAndTransportInfoNetCapsPermission( 12426 boolean shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag, 12427 boolean shouldInclLocationSensitiveOwnerUidWithIncludeFlag, 12428 boolean shouldInclLocationSensitiveTransportInfoWithoutIncludeFlag, 12429 boolean shouldInclLocationSensitiveTransportInfoWithIncludeFlag) { 12430 final int myUid = Process.myUid(); 12431 12432 final int expectedOwnerUidWithoutIncludeFlag = 12433 shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag 12434 ? myUid : INVALID_UID; 12435 assertEquals(expectedOwnerUidWithoutIncludeFlag, getOwnerUidNetCapsPermission( 12436 myUid, myUid, false /* includeLocationSensitiveInfo */)); 12437 12438 final int expectedOwnerUidWithIncludeFlag = 12439 shouldInclLocationSensitiveOwnerUidWithIncludeFlag ? myUid : INVALID_UID; 12440 assertEquals(expectedOwnerUidWithIncludeFlag, getOwnerUidNetCapsPermission( 12441 myUid, myUid, true /* includeLocationSensitiveInfo */)); 12442 12443 verifyTransportInfoCopyNetCapsPermission(myUid, 12444 false, /* includeLocationSensitiveInfo */ 12445 shouldInclLocationSensitiveTransportInfoWithoutIncludeFlag); 12446 12447 verifyTransportInfoCopyNetCapsPermission(myUid, 12448 true, /* includeLocationSensitiveInfo */ 12449 shouldInclLocationSensitiveTransportInfoWithIncludeFlag); 12450 12451 } 12452 12453 private void verifyOwnerUidAndTransportInfoNetCapsPermissionPreS() { 12454 verifyOwnerUidAndTransportInfoNetCapsPermission( 12455 // Ensure that owner uid is included even if the request asks to remove it (which is 12456 // the default) since the app has necessary permissions and targetSdk < S. 12457 true, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */ 12458 true, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */ 12459 // Ensure that location info is removed if the request asks to remove it even if the 12460 // app has necessary permissions. 12461 false, /* shouldInclLocationSensitiveTransportInfoWithoutIncludeFlag */ 12462 true /* shouldInclLocationSensitiveTransportInfoWithIncludeFlag */ 12463 ); 12464 } 12465 12466 @Test 12467 public void testCreateWithLocationInfoSanitizedWithFineLocationAfterQPreS() 12468 throws Exception { 12469 setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION, 12470 Manifest.permission.ACCESS_FINE_LOCATION); 12471 12472 verifyOwnerUidAndTransportInfoNetCapsPermissionPreS(); 12473 } 12474 12475 @Test 12476 public void testCreateWithLocationInfoSanitizedWithFineLocationPreSWithAndWithoutCallbackFlag() 12477 throws Exception { 12478 setupLocationPermissions(Build.VERSION_CODES.R, true, AppOpsManager.OPSTR_FINE_LOCATION, 12479 Manifest.permission.ACCESS_FINE_LOCATION); 12480 12481 verifyOwnerUidAndTransportInfoNetCapsPermissionPreS(); 12482 } 12483 12484 @Test 12485 public void 12486 testCreateWithLocationInfoSanitizedWithFineLocationAfterSWithAndWithoutCallbackFlag() 12487 throws Exception { 12488 setupLocationPermissions(Build.VERSION_CODES.S, true, AppOpsManager.OPSTR_FINE_LOCATION, 12489 Manifest.permission.ACCESS_FINE_LOCATION); 12490 12491 verifyOwnerUidAndTransportInfoNetCapsPermission( 12492 // Ensure that the owner UID is removed if the request asks us to remove it even 12493 // if the app has necessary permissions since targetSdk >= S. 12494 false, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */ 12495 true, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */ 12496 // Ensure that location info is removed if the request asks to remove it even if the 12497 // app has necessary permissions. 12498 false, /* shouldInclLocationSensitiveTransportInfoWithoutIncludeFlag */ 12499 true /* shouldInclLocationSensitiveTransportInfoWithIncludeFlag */ 12500 ); 12501 } 12502 12503 @Test 12504 public void testCreateWithLocationInfoSanitizedWithCoarseLocationPreQ() 12505 throws Exception { 12506 setupLocationPermissions(Build.VERSION_CODES.P, true, AppOpsManager.OPSTR_COARSE_LOCATION, 12507 Manifest.permission.ACCESS_COARSE_LOCATION); 12508 12509 verifyOwnerUidAndTransportInfoNetCapsPermissionPreS(); 12510 } 12511 12512 private void verifyOwnerUidAndTransportInfoNetCapsNotIncluded() { 12513 verifyOwnerUidAndTransportInfoNetCapsPermission( 12514 false, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */ 12515 false, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */ 12516 false, /* shouldInclLocationSensitiveTransportInfoWithoutIncludeFlag */ 12517 false /* shouldInclLocationSensitiveTransportInfoWithIncludeFlag */ 12518 ); 12519 } 12520 12521 @Test 12522 public void testCreateWithLocationInfoSanitizedLocationOff() throws Exception { 12523 // Test that even with fine location permission, and UIDs matching, the UID is sanitized. 12524 setupLocationPermissions(Build.VERSION_CODES.Q, false, AppOpsManager.OPSTR_FINE_LOCATION, 12525 Manifest.permission.ACCESS_FINE_LOCATION); 12526 12527 verifyOwnerUidAndTransportInfoNetCapsNotIncluded(); 12528 } 12529 12530 @Test 12531 public void testCreateWithLocationInfoSanitizedWrongUid() throws Exception { 12532 // Test that even with fine location permission, not being the owner leads to sanitization. 12533 setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION, 12534 Manifest.permission.ACCESS_FINE_LOCATION); 12535 12536 final int myUid = Process.myUid(); 12537 assertEquals(Process.INVALID_UID, 12538 getOwnerUidNetCapsPermission(myUid + 1, myUid, 12539 true /* includeLocationSensitiveInfo */)); 12540 } 12541 12542 @Test 12543 public void testCreateWithLocationInfoSanitizedWithCoarseLocationAfterQ() 12544 throws Exception { 12545 // Test that not having fine location permission leads to sanitization. 12546 setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_COARSE_LOCATION, 12547 Manifest.permission.ACCESS_COARSE_LOCATION); 12548 12549 verifyOwnerUidAndTransportInfoNetCapsNotIncluded(); 12550 } 12551 12552 @Test 12553 public void testCreateWithLocationInfoSanitizedWithCoarseLocationAfterS() 12554 throws Exception { 12555 // Test that not having fine location permission leads to sanitization. 12556 setupLocationPermissions(Build.VERSION_CODES.S, true, AppOpsManager.OPSTR_COARSE_LOCATION, 12557 Manifest.permission.ACCESS_COARSE_LOCATION); 12558 12559 verifyOwnerUidAndTransportInfoNetCapsNotIncluded(); 12560 } 12561 12562 @Test 12563 public void testCreateForCallerWithLocalMacAddressSanitizedWithLocalMacAddressPermission() 12564 throws Exception { 12565 mServiceContext.setPermission(Manifest.permission.LOCAL_MAC_ADDRESS, PERMISSION_GRANTED); 12566 12567 final TransportInfo transportInfo = mock(TransportInfo.class); 12568 doReturn(REDACT_FOR_ACCESS_FINE_LOCATION | REDACT_FOR_LOCAL_MAC_ADDRESS) 12569 .when(transportInfo).getApplicableRedactions(); 12570 final NetworkCapabilities netCap = 12571 new NetworkCapabilities().setTransportInfo(transportInfo); 12572 12573 mService.createWithLocationInfoSanitizedIfNecessaryWhenParceled( 12574 netCap, false /* includeLocationSensitiveInfoInTransportInfo */, 12575 Process.myPid(), Process.myUid(), 12576 mContext.getPackageName(), getAttributionTag()); 12577 // don't redact MAC_ADDRESS fields, only location sensitive fields. 12578 verify(transportInfo).makeCopy(REDACT_FOR_ACCESS_FINE_LOCATION); 12579 } 12580 12581 @Test 12582 public void testCreateForCallerWithLocalMacAddressSanitizedWithoutLocalMacAddressPermission() 12583 throws Exception { 12584 mServiceContext.setPermission(Manifest.permission.LOCAL_MAC_ADDRESS, PERMISSION_DENIED); 12585 12586 final TransportInfo transportInfo = mock(TransportInfo.class); 12587 doReturn(REDACT_FOR_ACCESS_FINE_LOCATION | REDACT_FOR_LOCAL_MAC_ADDRESS) 12588 .when(transportInfo).getApplicableRedactions(); 12589 final NetworkCapabilities netCap = 12590 new NetworkCapabilities().setTransportInfo(transportInfo); 12591 12592 mService.createWithLocationInfoSanitizedIfNecessaryWhenParceled( 12593 netCap, false /* includeLocationSensitiveInfoInTransportInfo */, 12594 Process.myPid(), Process.myUid(), 12595 mContext.getPackageName(), getAttributionTag()); 12596 // redact both MAC_ADDRESS & location sensitive fields. 12597 verify(transportInfo).makeCopy(REDACT_FOR_ACCESS_FINE_LOCATION 12598 | REDACT_FOR_LOCAL_MAC_ADDRESS); 12599 } 12600 12601 @Test 12602 public void testCreateForCallerWithLocalMacAddressSanitizedWithSettingsPermission() 12603 throws Exception { 12604 mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_GRANTED); 12605 12606 final TransportInfo transportInfo = mock(TransportInfo.class); 12607 doReturn(REDACT_FOR_ACCESS_FINE_LOCATION | REDACT_FOR_NETWORK_SETTINGS) 12608 .when(transportInfo).getApplicableRedactions(); 12609 final NetworkCapabilities netCap = 12610 new NetworkCapabilities().setTransportInfo(transportInfo); 12611 12612 mService.createWithLocationInfoSanitizedIfNecessaryWhenParceled( 12613 netCap, false /* includeLocationSensitiveInfoInTransportInfo */, 12614 Process.myPid(), Process.myUid(), 12615 mContext.getPackageName(), getAttributionTag()); 12616 // don't redact NETWORK_SETTINGS fields, only location sensitive fields. 12617 verify(transportInfo).makeCopy(REDACT_FOR_ACCESS_FINE_LOCATION); 12618 } 12619 12620 @Test 12621 public void testCreateForCallerWithLocalMacAddressSanitizedWithoutSettingsPermission() 12622 throws Exception { 12623 mServiceContext.setPermission(Manifest.permission.LOCAL_MAC_ADDRESS, PERMISSION_DENIED); 12624 12625 final TransportInfo transportInfo = mock(TransportInfo.class); 12626 doReturn(REDACT_FOR_ACCESS_FINE_LOCATION | REDACT_FOR_NETWORK_SETTINGS) 12627 .when(transportInfo).getApplicableRedactions(); 12628 final NetworkCapabilities netCap = 12629 new NetworkCapabilities().setTransportInfo(transportInfo); 12630 12631 mService.createWithLocationInfoSanitizedIfNecessaryWhenParceled( 12632 netCap, false /* includeLocationSensitiveInfoInTransportInfo */, 12633 Process.myPid(), Process.myUid(), 12634 mContext.getPackageName(), getAttributionTag()); 12635 // redact both NETWORK_SETTINGS & location sensitive fields. 12636 verify(transportInfo).makeCopy( 12637 REDACT_FOR_ACCESS_FINE_LOCATION | REDACT_FOR_NETWORK_SETTINGS); 12638 } 12639 12640 /** 12641 * Test TransportInfo to verify redaction mechanism. 12642 */ 12643 private static class TestTransportInfo implements TransportInfo { 12644 public final boolean locationRedacted; 12645 public final boolean localMacAddressRedacted; 12646 public final boolean settingsRedacted; 12647 12648 TestTransportInfo() { 12649 locationRedacted = false; 12650 localMacAddressRedacted = false; 12651 settingsRedacted = false; 12652 } 12653 12654 TestTransportInfo(boolean locationRedacted, boolean localMacAddressRedacted, 12655 boolean settingsRedacted) { 12656 this.locationRedacted = locationRedacted; 12657 this.localMacAddressRedacted = 12658 localMacAddressRedacted; 12659 this.settingsRedacted = settingsRedacted; 12660 } 12661 12662 @Override 12663 public TransportInfo makeCopy(@NetworkCapabilities.RedactionType long redactions) { 12664 return new TestTransportInfo( 12665 locationRedacted | (redactions & REDACT_FOR_ACCESS_FINE_LOCATION) != 0, 12666 localMacAddressRedacted | (redactions & REDACT_FOR_LOCAL_MAC_ADDRESS) != 0, 12667 settingsRedacted | (redactions & REDACT_FOR_NETWORK_SETTINGS) != 0 12668 ); 12669 } 12670 12671 @Override 12672 public @NetworkCapabilities.RedactionType long getApplicableRedactions() { 12673 return REDACT_FOR_ACCESS_FINE_LOCATION | REDACT_FOR_LOCAL_MAC_ADDRESS 12674 | REDACT_FOR_NETWORK_SETTINGS; 12675 } 12676 12677 @Override 12678 public boolean equals(Object other) { 12679 if (!(other instanceof TestTransportInfo)) return false; 12680 TestTransportInfo that = (TestTransportInfo) other; 12681 return that.locationRedacted == this.locationRedacted 12682 && that.localMacAddressRedacted == this.localMacAddressRedacted 12683 && that.settingsRedacted == this.settingsRedacted; 12684 } 12685 12686 @Override 12687 public int hashCode() { 12688 return Objects.hash(locationRedacted, localMacAddressRedacted, settingsRedacted); 12689 } 12690 12691 @Override 12692 public String toString() { 12693 return String.format( 12694 "TestTransportInfo{locationRedacted=%s macRedacted=%s settingsRedacted=%s}", 12695 locationRedacted, localMacAddressRedacted, settingsRedacted); 12696 } 12697 } 12698 12699 private TestTransportInfo getTestTransportInfo(NetworkCapabilities nc) { 12700 return (TestTransportInfo) nc.getTransportInfo(); 12701 } 12702 12703 private TestTransportInfo getTestTransportInfo(TestNetworkAgentWrapper n) { 12704 final NetworkCapabilities nc = mCm.getNetworkCapabilities(n.getNetwork()); 12705 assertNotNull(nc); 12706 return getTestTransportInfo(nc); 12707 } 12708 12709 12710 private void verifyNetworkCallbackLocationDataInclusionUsingTransportInfoAndOwnerUidInNetCaps( 12711 @NonNull TestNetworkCallback wifiNetworkCallback, int actualOwnerUid, 12712 @NonNull TransportInfo actualTransportInfo, int expectedOwnerUid, 12713 @NonNull TransportInfo expectedTransportInfo) throws Exception { 12714 doReturn(Build.VERSION_CODES.S).when(mPackageManager).getTargetSdkVersion(anyString()); 12715 final NetworkCapabilities ncTemplate = 12716 new NetworkCapabilities() 12717 .addTransportType(TRANSPORT_WIFI) 12718 .setOwnerUid(actualOwnerUid); 12719 12720 final NetworkRequest wifiRequest = new NetworkRequest.Builder() 12721 .addTransportType(TRANSPORT_WIFI).build(); 12722 mCm.registerNetworkCallback(wifiRequest, wifiNetworkCallback); 12723 12724 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, new LinkProperties(), 12725 ncTemplate); 12726 mWiFiAgent.connect(false); 12727 12728 wifiNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 12729 12730 // Send network capabilities update with TransportInfo to trigger capabilities changed 12731 // callback. 12732 mWiFiAgent.setNetworkCapabilities(ncTemplate.setTransportInfo(actualTransportInfo), true); 12733 12734 wifiNetworkCallback.expectCaps(mWiFiAgent, 12735 c -> Objects.equals(expectedOwnerUid, c.getOwnerUid()) 12736 && Objects.equals(expectedTransportInfo, c.getTransportInfo())); 12737 } 12738 12739 @Test 12740 public void testVerifyLocationDataIsNotIncludedWhenInclFlagNotSet() throws Exception { 12741 final TestNetworkCallback wifiNetworkCallack = new TestNetworkCallback(); 12742 final int ownerUid = Process.myUid(); 12743 final TransportInfo transportInfo = new TestTransportInfo(); 12744 // Even though the test uid holds privileged permissions, mask location fields since 12745 // the callback did not explicitly opt-in to get location data. 12746 final TransportInfo sanitizedTransportInfo = new TestTransportInfo( 12747 true, /* locationRedacted */ 12748 true, /* localMacAddressRedacted */ 12749 true /* settingsRedacted */ 12750 ); 12751 // Should not expect location data since the callback does not set the flag for including 12752 // location data. 12753 verifyNetworkCallbackLocationDataInclusionUsingTransportInfoAndOwnerUidInNetCaps( 12754 wifiNetworkCallack, ownerUid, transportInfo, INVALID_UID, sanitizedTransportInfo); 12755 } 12756 12757 @Test 12758 public void testTransportInfoRedactionInSynchronousCalls() throws Exception { 12759 final NetworkCapabilities ncTemplate = new NetworkCapabilities() 12760 .addTransportType(TRANSPORT_WIFI) 12761 .setTransportInfo(new TestTransportInfo()); 12762 12763 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, new LinkProperties(), ncTemplate); 12764 mWiFiAgent.connect(true /* validated; waits for callback */); 12765 12766 // NETWORK_SETTINGS redaction is controlled by the NETWORK_SETTINGS permission 12767 assertTrue(getTestTransportInfo(mWiFiAgent).settingsRedacted); 12768 withPermission(NETWORK_SETTINGS, () -> { 12769 assertFalse(getTestTransportInfo(mWiFiAgent).settingsRedacted); 12770 }); 12771 assertTrue(getTestTransportInfo(mWiFiAgent).settingsRedacted); 12772 12773 // LOCAL_MAC_ADDRESS redaction is controlled by the LOCAL_MAC_ADDRESS permission 12774 assertTrue(getTestTransportInfo(mWiFiAgent).localMacAddressRedacted); 12775 withPermission(LOCAL_MAC_ADDRESS, () -> { 12776 assertFalse(getTestTransportInfo(mWiFiAgent).localMacAddressRedacted); 12777 }); 12778 assertTrue(getTestTransportInfo(mWiFiAgent).localMacAddressRedacted); 12779 12780 // Synchronous getNetworkCapabilities calls never return unredacted location-sensitive 12781 // information. 12782 assertTrue(getTestTransportInfo(mWiFiAgent).locationRedacted); 12783 setupLocationPermissions(Build.VERSION_CODES.S, true, AppOpsManager.OPSTR_FINE_LOCATION, 12784 Manifest.permission.ACCESS_FINE_LOCATION); 12785 assertTrue(getTestTransportInfo(mWiFiAgent).locationRedacted); 12786 denyAllLocationPrivilegedPermissions(); 12787 assertTrue(getTestTransportInfo(mWiFiAgent).locationRedacted); 12788 } 12789 12790 private void setupConnectionOwnerUid(int vpnOwnerUid, @VpnManager.VpnType int vpnType) 12791 throws Exception { 12792 final Set<UidRange> vpnRange = Collections.singleton(PRIMARY_UIDRANGE); 12793 mMockVpn.setVpnType(vpnType); 12794 mMockVpn.establish(new LinkProperties(), vpnOwnerUid, vpnRange); 12795 assertVpnUidRangesUpdated(true, vpnRange, vpnOwnerUid); 12796 12797 mDeps.setConnectionOwnerUid(42); 12798 } 12799 12800 private void setupConnectionOwnerUidAsVpnApp(int vpnOwnerUid, @VpnManager.VpnType int vpnType) 12801 throws Exception { 12802 setupConnectionOwnerUid(vpnOwnerUid, vpnType); 12803 12804 // Test as VPN app 12805 mServiceContext.setPermission(NETWORK_STACK, PERMISSION_DENIED); 12806 mServiceContext.setPermission( 12807 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, PERMISSION_DENIED); 12808 } 12809 12810 private ConnectionInfo getTestConnectionInfo() throws Exception { 12811 return new ConnectionInfo( 12812 IPPROTO_TCP, 12813 new InetSocketAddress(InetAddresses.parseNumericAddress("1.2.3.4"), 1234), 12814 new InetSocketAddress(InetAddresses.parseNumericAddress("2.3.4.5"), 2345)); 12815 } 12816 12817 @Test 12818 public void testGetConnectionOwnerUidPlatformVpn() throws Exception { 12819 final int myUid = Process.myUid(); 12820 setupConnectionOwnerUidAsVpnApp(myUid, VpnManager.TYPE_VPN_PLATFORM); 12821 12822 assertEquals(INVALID_UID, mService.getConnectionOwnerUid(getTestConnectionInfo())); 12823 } 12824 12825 @Test 12826 public void testGetConnectionOwnerUidVpnServiceWrongUser() throws Exception { 12827 final int myUid = Process.myUid(); 12828 setupConnectionOwnerUidAsVpnApp(myUid + 1, VpnManager.TYPE_VPN_SERVICE); 12829 12830 assertEquals(INVALID_UID, mService.getConnectionOwnerUid(getTestConnectionInfo())); 12831 } 12832 12833 @Test 12834 public void testGetConnectionOwnerUidVpnServiceDoesNotThrow() throws Exception { 12835 final int myUid = Process.myUid(); 12836 setupConnectionOwnerUidAsVpnApp(myUid, VpnManager.TYPE_VPN_SERVICE); 12837 12838 assertEquals(42, mService.getConnectionOwnerUid(getTestConnectionInfo())); 12839 } 12840 12841 @Test 12842 public void testGetConnectionOwnerUidVpnServiceNetworkStackDoesNotThrow() throws Exception { 12843 final int myUid = Process.myUid(); 12844 setupConnectionOwnerUid(myUid, VpnManager.TYPE_VPN_SERVICE); 12845 mServiceContext.setPermission(NETWORK_STACK, PERMISSION_GRANTED); 12846 12847 assertEquals(42, mService.getConnectionOwnerUid(getTestConnectionInfo())); 12848 } 12849 12850 @Test 12851 public void testGetConnectionOwnerUidVpnServiceMainlineNetworkStackDoesNotThrow() 12852 throws Exception { 12853 final int myUid = Process.myUid(); 12854 setupConnectionOwnerUid(myUid, VpnManager.TYPE_VPN_SERVICE); 12855 mServiceContext.setPermission( 12856 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, PERMISSION_GRANTED); 12857 12858 assertEquals(42, mService.getConnectionOwnerUid(getTestConnectionInfo())); 12859 } 12860 12861 private static PackageInfo buildPackageInfo(boolean hasSystemPermission, int uid) { 12862 final PackageInfo packageInfo = new PackageInfo(); 12863 if (hasSystemPermission) { 12864 packageInfo.requestedPermissions = new String[] { 12865 CHANGE_NETWORK_STATE, CONNECTIVITY_USE_RESTRICTED_NETWORKS }; 12866 packageInfo.requestedPermissionsFlags = new int[] { 12867 REQUESTED_PERMISSION_GRANTED, REQUESTED_PERMISSION_GRANTED }; 12868 } else { 12869 packageInfo.requestedPermissions = new String[0]; 12870 } 12871 packageInfo.applicationInfo = new ApplicationInfo(); 12872 packageInfo.applicationInfo.privateFlags = 0; 12873 packageInfo.applicationInfo.uid = UserHandle.getUid(UserHandle.USER_SYSTEM, 12874 UserHandle.getAppId(uid)); 12875 return packageInfo; 12876 } 12877 12878 @Test 12879 public void testRegisterConnectivityDiagnosticsCallbackInvalidRequest() throws Exception { 12880 final NetworkRequest request = 12881 new NetworkRequest( 12882 new NetworkCapabilities(), TYPE_ETHERNET, 0, NetworkRequest.Type.NONE); 12883 try { 12884 mService.registerConnectivityDiagnosticsCallback( 12885 mConnectivityDiagnosticsCallback, request, mContext.getPackageName()); 12886 fail("registerConnectivityDiagnosticsCallback should throw on invalid NetworkRequest"); 12887 } catch (IllegalArgumentException expected) { 12888 } 12889 } 12890 12891 private void assertRouteInfoParcelMatches(RouteInfo route, RouteInfoParcel parcel) { 12892 assertEquals(route.getDestination().toString(), parcel.destination); 12893 assertEquals(route.getInterface(), parcel.ifName); 12894 assertEquals(route.getMtu(), parcel.mtu); 12895 12896 switch (route.getType()) { 12897 case RouteInfo.RTN_UNICAST: 12898 if (route.hasGateway()) { 12899 assertEquals(route.getGateway().getHostAddress(), parcel.nextHop); 12900 } else { 12901 assertEquals(INetd.NEXTHOP_NONE, parcel.nextHop); 12902 } 12903 break; 12904 case RouteInfo.RTN_UNREACHABLE: 12905 assertEquals(INetd.NEXTHOP_UNREACHABLE, parcel.nextHop); 12906 break; 12907 case RouteInfo.RTN_THROW: 12908 assertEquals(INetd.NEXTHOP_THROW, parcel.nextHop); 12909 break; 12910 default: 12911 assertEquals(INetd.NEXTHOP_NONE, parcel.nextHop); 12912 break; 12913 } 12914 } 12915 12916 private void assertRoutesAdded(int netId, RouteInfo... routes) throws Exception { 12917 // TODO: add @JavaDerive(equals=true) to RouteInfoParcel, use eq() directly, and delete 12918 // assertRouteInfoParcelMatches above. 12919 ArgumentCaptor<RouteInfoParcel> captor = ArgumentCaptor.forClass(RouteInfoParcel.class); 12920 verify(mMockNetd, times(routes.length)).networkAddRouteParcel(eq(netId), captor.capture()); 12921 for (int i = 0; i < routes.length; i++) { 12922 assertRouteInfoParcelMatches(routes[i], captor.getAllValues().get(i)); 12923 } 12924 } 12925 12926 private void assertRoutesRemoved(int netId, RouteInfo... routes) throws Exception { 12927 ArgumentCaptor<RouteInfoParcel> captor = ArgumentCaptor.forClass(RouteInfoParcel.class); 12928 verify(mMockNetd, times(routes.length)).networkRemoveRouteParcel(eq(netId), 12929 captor.capture()); 12930 for (int i = 0; i < routes.length; i++) { 12931 assertRouteInfoParcelMatches(routes[i], captor.getAllValues().get(i)); 12932 } 12933 } 12934 12935 @Test 12936 public void testRegisterUnregisterConnectivityDiagnosticsCallback() throws Exception { 12937 final NetworkRequest wifiRequest = 12938 new NetworkRequest.Builder().addTransportType(TRANSPORT_WIFI).build(); 12939 doReturn(mIBinder).when(mConnectivityDiagnosticsCallback).asBinder(); 12940 12941 mService.registerConnectivityDiagnosticsCallback( 12942 mConnectivityDiagnosticsCallback, wifiRequest, mContext.getPackageName()); 12943 12944 // Block until all other events are done processing. 12945 HandlerUtils.waitForIdle(mCsHandlerThread, TIMEOUT_MS); 12946 12947 verify(mIBinder).linkToDeath(any(ConnectivityDiagnosticsCallbackInfo.class), anyInt()); 12948 verify(mConnectivityDiagnosticsCallback).asBinder(); 12949 assertTrue(mService.mConnectivityDiagnosticsCallbacks.containsKey(mIBinder)); 12950 12951 mService.unregisterConnectivityDiagnosticsCallback(mConnectivityDiagnosticsCallback); 12952 verify(mIBinder, timeout(TIMEOUT_MS)) 12953 .unlinkToDeath(any(ConnectivityDiagnosticsCallbackInfo.class), anyInt()); 12954 assertFalse(mService.mConnectivityDiagnosticsCallbacks.containsKey(mIBinder)); 12955 verify(mConnectivityDiagnosticsCallback, atLeastOnce()).asBinder(); 12956 } 12957 12958 @Test 12959 public void testRegisterDuplicateConnectivityDiagnosticsCallback() throws Exception { 12960 final NetworkRequest wifiRequest = 12961 new NetworkRequest.Builder().addTransportType(TRANSPORT_WIFI).build(); 12962 doReturn(mIBinder).when(mConnectivityDiagnosticsCallback).asBinder(); 12963 12964 mService.registerConnectivityDiagnosticsCallback( 12965 mConnectivityDiagnosticsCallback, wifiRequest, mContext.getPackageName()); 12966 12967 // Block until all other events are done processing. 12968 HandlerUtils.waitForIdle(mCsHandlerThread, TIMEOUT_MS); 12969 12970 verify(mIBinder).linkToDeath(any(ConnectivityDiagnosticsCallbackInfo.class), anyInt()); 12971 verify(mConnectivityDiagnosticsCallback).asBinder(); 12972 assertTrue(mService.mConnectivityDiagnosticsCallbacks.containsKey(mIBinder)); 12973 12974 // Register the same callback again 12975 mService.registerConnectivityDiagnosticsCallback( 12976 mConnectivityDiagnosticsCallback, wifiRequest, mContext.getPackageName()); 12977 12978 // Block until all other events are done processing. 12979 HandlerUtils.waitForIdle(mCsHandlerThread, TIMEOUT_MS); 12980 12981 assertTrue(mService.mConnectivityDiagnosticsCallbacks.containsKey(mIBinder)); 12982 } 12983 12984 @Test(expected = NullPointerException.class) 12985 public void testRegisterConnectivityDiagnosticsCallbackNullCallback() { 12986 mService.registerConnectivityDiagnosticsCallback( 12987 null /* callback */, 12988 new NetworkRequest.Builder().build(), 12989 mContext.getPackageName()); 12990 } 12991 12992 @Test(expected = NullPointerException.class) 12993 public void testRegisterConnectivityDiagnosticsCallbackNullNetworkRequest() { 12994 mService.registerConnectivityDiagnosticsCallback( 12995 mConnectivityDiagnosticsCallback, 12996 null /* request */, 12997 mContext.getPackageName()); 12998 } 12999 13000 @Test(expected = NullPointerException.class) 13001 public void testRegisterConnectivityDiagnosticsCallbackNullPackageName() { 13002 mService.registerConnectivityDiagnosticsCallback( 13003 mConnectivityDiagnosticsCallback, 13004 new NetworkRequest.Builder().build(), 13005 null /* callingPackageName */); 13006 } 13007 13008 @Test(expected = NullPointerException.class) 13009 public void testUnregisterConnectivityDiagnosticsCallbackNullPackageName() { 13010 mService.unregisterConnectivityDiagnosticsCallback(null /* callback */); 13011 } 13012 13013 public NetworkAgentInfo fakeMobileNai(NetworkCapabilities nc) { 13014 final NetworkCapabilities cellNc = new NetworkCapabilities.Builder(nc) 13015 .addTransportType(TRANSPORT_CELLULAR).build(); 13016 final NetworkInfo info = new NetworkInfo(TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_LTE, 13017 ConnectivityManager.getNetworkTypeName(TYPE_MOBILE), 13018 TelephonyManager.getNetworkTypeName(TelephonyManager.NETWORK_TYPE_LTE)); 13019 return fakeNai(cellNc, info); 13020 } 13021 13022 private NetworkAgentInfo fakeWifiNai(NetworkCapabilities nc) { 13023 final NetworkCapabilities wifiNc = new NetworkCapabilities.Builder(nc) 13024 .addTransportType(TRANSPORT_WIFI).build(); 13025 final NetworkInfo info = new NetworkInfo(TYPE_WIFI, 0 /* subtype */, 13026 ConnectivityManager.getNetworkTypeName(TYPE_WIFI), "" /* subtypeName */); 13027 return fakeNai(wifiNc, info); 13028 } 13029 13030 private NetworkAgentInfo fakeVpnNai(NetworkCapabilities nc) { 13031 final NetworkCapabilities vpnNc = new NetworkCapabilities.Builder(nc) 13032 .addTransportType(TRANSPORT_VPN).build(); 13033 final NetworkInfo info = new NetworkInfo(TYPE_VPN, 0 /* subtype */, 13034 ConnectivityManager.getNetworkTypeName(TYPE_VPN), "" /* subtypeName */); 13035 return fakeNai(vpnNc, info); 13036 } 13037 13038 private NetworkAgentInfo fakeNai(NetworkCapabilities nc, NetworkInfo networkInfo) { 13039 return new NetworkAgentInfo(null, new Network(NET_ID), networkInfo, new LinkProperties(), 13040 nc, null /* localNetworkConfig */, 13041 new NetworkScore.Builder().setLegacyInt(0).build(), 13042 mServiceContext, null, new NetworkAgentConfig(), mService, null, null, 0, 13043 INVALID_UID, TEST_LINGER_DELAY_MS, mQosCallbackTracker, 13044 new ConnectivityService.Dependencies()); 13045 } 13046 13047 @Test 13048 public void testCheckConnectivityDiagnosticsPermissionsNetworkStack() throws Exception { 13049 final NetworkAgentInfo naiWithoutUid = fakeMobileNai(new NetworkCapabilities()); 13050 13051 mServiceContext.setPermission(NETWORK_STACK, PERMISSION_GRANTED); 13052 assertTrue( 13053 "NetworkStack permission not applied", 13054 mService.hasConnectivityDiagnosticsPermissions( 13055 Process.myPid(), Process.myUid(), naiWithoutUid, 13056 mContext.getOpPackageName())); 13057 } 13058 13059 @Test 13060 public void testCheckConnectivityDiagnosticsPermissionsSysUi() throws Exception { 13061 final NetworkAgentInfo naiWithoutUid = fakeMobileNai(new NetworkCapabilities()); 13062 13063 mServiceContext.setPermission(STATUS_BAR_SERVICE, PERMISSION_GRANTED); 13064 assertTrue( 13065 "SysUi permission (STATUS_BAR_SERVICE) not applied", 13066 mService.hasConnectivityDiagnosticsPermissions( 13067 Process.myPid(), Process.myUid(), naiWithoutUid, 13068 mContext.getOpPackageName())); 13069 } 13070 13071 @Test 13072 public void testCheckConnectivityDiagnosticsPermissionsWrongUidPackageName() throws Exception { 13073 final int wrongUid = Process.myUid() + 1; 13074 13075 final NetworkCapabilities nc = new NetworkCapabilities(); 13076 nc.setAdministratorUids(new int[] {wrongUid}); 13077 final NetworkAgentInfo naiWithUid = fakeWifiNai(nc); 13078 13079 mServiceContext.setPermission(NETWORK_STACK, PERMISSION_DENIED); 13080 13081 assertFalse( 13082 "Mismatched uid/package name should not pass the location permission check", 13083 mService.hasConnectivityDiagnosticsPermissions( 13084 Process.myPid() + 1, wrongUid, naiWithUid, mContext.getOpPackageName())); 13085 } 13086 13087 private void verifyConnectivityDiagnosticsPermissionsWithNetworkAgentInfo( 13088 NetworkAgentInfo info, boolean expectPermission) { 13089 mServiceContext.setPermission(NETWORK_STACK, PERMISSION_DENIED); 13090 13091 assertEquals( 13092 "Unexpected ConnDiags permission", 13093 expectPermission, 13094 mService.hasConnectivityDiagnosticsPermissions( 13095 Process.myPid(), Process.myUid(), info, mContext.getOpPackageName())); 13096 } 13097 13098 @Test 13099 public void testCheckConnectivityDiagnosticsPermissionsCellularNoLocationPermission() 13100 throws Exception { 13101 final NetworkCapabilities nc = new NetworkCapabilities(); 13102 nc.setAdministratorUids(new int[] {Process.myUid()}); 13103 final NetworkAgentInfo naiWithUid = fakeMobileNai(nc); 13104 13105 verifyConnectivityDiagnosticsPermissionsWithNetworkAgentInfo(naiWithUid, 13106 true /* expectPermission */); 13107 } 13108 13109 @Test 13110 public void testCheckConnectivityDiagnosticsPermissionsWifiNoLocationPermission() 13111 throws Exception { 13112 final NetworkCapabilities nc = new NetworkCapabilities(); 13113 nc.setAdministratorUids(new int[] {Process.myUid()}); 13114 final NetworkAgentInfo naiWithUid = fakeWifiNai(nc); 13115 13116 verifyConnectivityDiagnosticsPermissionsWithNetworkAgentInfo(naiWithUid, 13117 false /* expectPermission */); 13118 } 13119 13120 @Test 13121 public void testCheckConnectivityDiagnosticsPermissionsActiveVpn() throws Exception { 13122 final NetworkAgentInfo naiWithoutUid = fakeMobileNai(new NetworkCapabilities()); 13123 13124 mMockVpn.establishForMyUid(); 13125 assertUidRangesUpdatedForMyUid(true); 13126 13127 // Wait for networks to connect and broadcasts to be sent before removing permissions. 13128 waitForIdle(); 13129 setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION, 13130 Manifest.permission.ACCESS_FINE_LOCATION); 13131 13132 assertTrue(mMockVpn.setUnderlyingNetworks(new Network[] {naiWithoutUid.network})); 13133 waitForIdle(); 13134 assertTrue( 13135 "Active VPN permission not applied", 13136 mService.hasConnectivityDiagnosticsPermissions( 13137 Process.myPid(), Process.myUid(), naiWithoutUid, 13138 mContext.getOpPackageName())); 13139 13140 assertTrue(mMockVpn.setUnderlyingNetworks(null)); 13141 waitForIdle(); 13142 assertFalse( 13143 "VPN shouldn't receive callback on non-underlying network", 13144 mService.hasConnectivityDiagnosticsPermissions( 13145 Process.myPid(), Process.myUid(), naiWithoutUid, 13146 mContext.getOpPackageName())); 13147 } 13148 13149 @Test 13150 public void testCheckConnectivityDiagnosticsPermissionsNetworkAdministrator() throws Exception { 13151 final NetworkCapabilities nc = new NetworkCapabilities(); 13152 nc.setAdministratorUids(new int[] {Process.myUid()}); 13153 final NetworkAgentInfo naiWithUid = fakeMobileNai(nc); 13154 13155 setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION, 13156 Manifest.permission.ACCESS_FINE_LOCATION); 13157 mServiceContext.setPermission(NETWORK_STACK, PERMISSION_DENIED); 13158 13159 assertTrue( 13160 "NetworkCapabilities administrator uid permission not applied", 13161 mService.hasConnectivityDiagnosticsPermissions( 13162 Process.myPid(), Process.myUid(), naiWithUid, mContext.getOpPackageName())); 13163 } 13164 13165 @Test 13166 public void testCheckConnectivityDiagnosticsPermissionsFails() throws Exception { 13167 final NetworkCapabilities nc = new NetworkCapabilities(); 13168 nc.setOwnerUid(Process.myUid()); 13169 nc.setAdministratorUids(new int[] {Process.myUid()}); 13170 final NetworkAgentInfo naiWithUid = fakeMobileNai(nc); 13171 13172 setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION, 13173 Manifest.permission.ACCESS_FINE_LOCATION); 13174 mServiceContext.setPermission(NETWORK_STACK, PERMISSION_DENIED); 13175 13176 // Use wrong pid and uid 13177 assertFalse( 13178 "Permissions allowed when they shouldn't be granted", 13179 mService.hasConnectivityDiagnosticsPermissions( 13180 Process.myPid() + 1, Process.myUid() + 1, naiWithUid, 13181 mContext.getOpPackageName())); 13182 } 13183 13184 @Test 13185 public void testUnderlyingNetworksWillBeSetInNetworkAgentInfoConstructor() throws Exception { 13186 assumeTrue(mDeps.isAtLeastT()); 13187 final Network network1 = new Network(100); 13188 final Network network2 = new Network(101); 13189 final List<Network> underlyingNetworks = new ArrayList<>(); 13190 final NetworkCapabilities ncWithEmptyUnderlyingNetworks = new NetworkCapabilities.Builder() 13191 .setUnderlyingNetworks(underlyingNetworks) 13192 .build(); 13193 final NetworkAgentInfo vpnNaiWithEmptyUnderlyingNetworks = 13194 fakeVpnNai(ncWithEmptyUnderlyingNetworks); 13195 assertEquals(underlyingNetworks, 13196 Arrays.asList(vpnNaiWithEmptyUnderlyingNetworks.declaredUnderlyingNetworks)); 13197 13198 underlyingNetworks.add(network1); 13199 underlyingNetworks.add(network2); 13200 final NetworkCapabilities ncWithUnderlyingNetworks = new NetworkCapabilities.Builder() 13201 .setUnderlyingNetworks(underlyingNetworks) 13202 .build(); 13203 final NetworkAgentInfo vpnNaiWithUnderlyingNetwokrs = fakeVpnNai(ncWithUnderlyingNetworks); 13204 assertEquals(underlyingNetworks, 13205 Arrays.asList(vpnNaiWithUnderlyingNetwokrs.declaredUnderlyingNetworks)); 13206 13207 final NetworkCapabilities ncWithoutUnderlyingNetworks = new NetworkCapabilities.Builder() 13208 .build(); 13209 final NetworkAgentInfo vpnNaiWithoutUnderlyingNetwokrs = 13210 fakeVpnNai(ncWithoutUnderlyingNetworks); 13211 assertNull(vpnNaiWithoutUnderlyingNetwokrs.declaredUnderlyingNetworks); 13212 } 13213 13214 @Test 13215 public void testRegisterConnectivityDiagnosticsCallbackCallsOnConnectivityReport() 13216 throws Exception { 13217 // Set up the Network, which leads to a ConnectivityReport being cached for the network. 13218 final TestNetworkCallback callback = new TestNetworkCallback(); 13219 mCm.registerDefaultNetworkCallback(callback); 13220 final LinkProperties linkProperties = new LinkProperties(); 13221 linkProperties.setInterfaceName(INTERFACE_NAME); 13222 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, linkProperties); 13223 mCellAgent.connect(true); 13224 callback.expectAvailableThenValidatedCallbacks(mCellAgent); 13225 callback.assertNoCallback(); 13226 13227 final NetworkRequest request = new NetworkRequest.Builder().build(); 13228 doReturn(mIBinder).when(mConnectivityDiagnosticsCallback).asBinder(); 13229 13230 mServiceContext.setPermission(NETWORK_STACK, PERMISSION_GRANTED); 13231 13232 mService.registerConnectivityDiagnosticsCallback( 13233 mConnectivityDiagnosticsCallback, request, mContext.getPackageName()); 13234 13235 verify(mConnectivityDiagnosticsCallback, timeout(TIMEOUT_MS)) 13236 .onConnectivityReportAvailable(argThat(report -> { 13237 return INTERFACE_NAME.equals(report.getLinkProperties().getInterfaceName()) 13238 && report.getNetworkCapabilities().hasTransport(TRANSPORT_CELLULAR); 13239 })); 13240 } 13241 13242 private void setUpConnectivityDiagnosticsCallback() throws Exception { 13243 final NetworkRequest request = new NetworkRequest.Builder().build(); 13244 doReturn(mIBinder).when(mConnectivityDiagnosticsCallback).asBinder(); 13245 13246 mServiceContext.setPermission(NETWORK_STACK, PERMISSION_GRANTED); 13247 13248 mService.registerConnectivityDiagnosticsCallback( 13249 mConnectivityDiagnosticsCallback, request, mContext.getPackageName()); 13250 13251 // Block until all other events are done processing. 13252 HandlerUtils.waitForIdle(mCsHandlerThread, TIMEOUT_MS); 13253 13254 // Connect the cell agent verify that it notifies TestNetworkCallback that it is available 13255 final TestNetworkCallback callback = new TestNetworkCallback(); 13256 mCm.registerDefaultNetworkCallback(callback); 13257 13258 final NetworkCapabilities ncTemplate = new NetworkCapabilities() 13259 .addTransportType(TRANSPORT_CELLULAR) 13260 .setTransportInfo(new TestTransportInfo()); 13261 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, new LinkProperties(), 13262 ncTemplate); 13263 mCellAgent.connect(true); 13264 callback.expectAvailableThenValidatedCallbacks(mCellAgent); 13265 callback.assertNoCallback(); 13266 13267 // Make sure a report is sent and that the caps are suitably redacted. 13268 verify(mConnectivityDiagnosticsCallback, timeout(TIMEOUT_MS)) 13269 .onConnectivityReportAvailable(argThat(report -> 13270 areConnDiagCapsRedacted(report.getNetworkCapabilities()))); 13271 reset(mConnectivityDiagnosticsCallback); 13272 } 13273 13274 private boolean areConnDiagCapsRedacted(NetworkCapabilities nc) { 13275 TestTransportInfo ti = getTestTransportInfo(nc); 13276 return nc.getUids() == null 13277 && nc.getAdministratorUids().length == 0 13278 && nc.getOwnerUid() == Process.INVALID_UID 13279 && ti.locationRedacted 13280 && ti.localMacAddressRedacted 13281 && ti.settingsRedacted; 13282 } 13283 13284 @Test 13285 public void testConnectivityDiagnosticsCallbackOnDataStallSuspected() throws Exception { 13286 setUpConnectivityDiagnosticsCallback(); 13287 13288 // Trigger notifyDataStallSuspected() on the INetworkMonitorCallbacks instance in the 13289 // cellular network agent 13290 mCellAgent.notifyDataStallSuspected(); 13291 13292 // Verify onDataStallSuspected fired 13293 verify(mConnectivityDiagnosticsCallback, timeout(TIMEOUT_MS)).onDataStallSuspected( 13294 argThat(report -> areConnDiagCapsRedacted(report.getNetworkCapabilities()))); 13295 } 13296 13297 @Test 13298 public void testConnectivityDiagnosticsCallbackOnConnectivityReported() throws Exception { 13299 setUpConnectivityDiagnosticsCallback(); 13300 13301 final Network n = mCellAgent.getNetwork(); 13302 final boolean hasConnectivity = true; 13303 mService.reportNetworkConnectivity(n, hasConnectivity); 13304 13305 // Verify onNetworkConnectivityReported fired 13306 verify(mConnectivityDiagnosticsCallback, timeout(TIMEOUT_MS)) 13307 .onNetworkConnectivityReported(eq(n), eq(hasConnectivity)); 13308 verify(mConnectivityDiagnosticsCallback, timeout(TIMEOUT_MS)) 13309 .onConnectivityReportAvailable( 13310 argThat(report -> 13311 areConnDiagCapsRedacted(report.getNetworkCapabilities()))); 13312 13313 final boolean noConnectivity = false; 13314 mService.reportNetworkConnectivity(n, noConnectivity); 13315 13316 // Wait for onNetworkConnectivityReported to fire 13317 verify(mConnectivityDiagnosticsCallback, timeout(TIMEOUT_MS)) 13318 .onNetworkConnectivityReported(eq(n), eq(noConnectivity)); 13319 13320 // Also expect a ConnectivityReport after NetworkMonitor asynchronously re-validates 13321 verify(mConnectivityDiagnosticsCallback, timeout(TIMEOUT_MS).times(2)) 13322 .onConnectivityReportAvailable( 13323 argThat(report -> 13324 areConnDiagCapsRedacted(report.getNetworkCapabilities()))); 13325 } 13326 13327 @Test 13328 public void testConnectivityDiagnosticsCallbackOnConnectivityReportedSeparateUid() 13329 throws Exception { 13330 setUpConnectivityDiagnosticsCallback(); 13331 13332 // report known Connectivity from a different uid. Verify that network is not re-validated 13333 // and this callback is not notified. 13334 final Network n = mCellAgent.getNetwork(); 13335 final boolean hasConnectivity = true; 13336 doAsUid(Process.myUid() + 1, () -> mService.reportNetworkConnectivity(n, hasConnectivity)); 13337 13338 // Block until all other events are done processing. 13339 HandlerUtils.waitForIdle(mCsHandlerThread, TIMEOUT_MS); 13340 13341 // Verify onNetworkConnectivityReported did not fire 13342 verify(mConnectivityDiagnosticsCallback, never()) 13343 .onNetworkConnectivityReported(any(), anyBoolean()); 13344 verify(mConnectivityDiagnosticsCallback, never()) 13345 .onConnectivityReportAvailable(any()); 13346 13347 // report different Connectivity from a different uid. Verify that network is re-validated 13348 // and that this callback is notified. 13349 final boolean noConnectivity = false; 13350 doAsUid(Process.myUid() + 1, () -> mService.reportNetworkConnectivity(n, noConnectivity)); 13351 13352 // Wait for onNetworkConnectivityReported to fire 13353 verify(mConnectivityDiagnosticsCallback, timeout(TIMEOUT_MS)) 13354 .onNetworkConnectivityReported(eq(n), eq(noConnectivity)); 13355 13356 // Also expect a ConnectivityReport after NetworkMonitor asynchronously re-validates 13357 verify(mConnectivityDiagnosticsCallback, timeout(TIMEOUT_MS)) 13358 .onConnectivityReportAvailable( 13359 argThat(report -> 13360 areConnDiagCapsRedacted(report.getNetworkCapabilities()))); 13361 } 13362 13363 @Test(expected = NullPointerException.class) 13364 public void testSimulateDataStallNullNetwork() { 13365 mService.simulateDataStall( 13366 DataStallReport.DETECTION_METHOD_DNS_EVENTS, 13367 0L /* timestampMillis */, 13368 null /* network */, 13369 new PersistableBundle()); 13370 } 13371 13372 @Test(expected = NullPointerException.class) 13373 public void testSimulateDataStallNullPersistableBundle() { 13374 mService.simulateDataStall( 13375 DataStallReport.DETECTION_METHOD_DNS_EVENTS, 13376 0L /* timestampMillis */, 13377 mock(Network.class), 13378 null /* extras */); 13379 } 13380 13381 @Test 13382 public void testRouteAddDeleteUpdate() throws Exception { 13383 final NetworkRequest request = new NetworkRequest.Builder().build(); 13384 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 13385 mCm.registerNetworkCallback(request, networkCallback); 13386 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 13387 reset(mMockNetd); 13388 mCellAgent.connect(false); 13389 networkCallback.expectAvailableCallbacksUnvalidated(mCellAgent); 13390 final int netId = mCellAgent.getNetwork().netId; 13391 13392 final String iface = "rmnet_data0"; 13393 final InetAddress gateway = InetAddress.getByName("fe80::5678"); 13394 RouteInfo direct = RouteInfo.makeHostRoute(gateway, iface); 13395 RouteInfo rio1 = new RouteInfo(new IpPrefix("2001:db8:1::/48"), gateway, iface); 13396 RouteInfo rio2 = new RouteInfo(new IpPrefix("2001:db8:2::/48"), gateway, iface); 13397 RouteInfo defaultRoute = new RouteInfo((IpPrefix) null, gateway, iface); 13398 RouteInfo defaultWithMtu = new RouteInfo(null, gateway, iface, RouteInfo.RTN_UNICAST, 13399 1280 /* mtu */); 13400 13401 // Send LinkProperties and check that we ask netd to add routes. 13402 LinkProperties lp = new LinkProperties(); 13403 lp.setInterfaceName(iface); 13404 lp.addRoute(direct); 13405 lp.addRoute(rio1); 13406 lp.addRoute(defaultRoute); 13407 mCellAgent.sendLinkProperties(lp); 13408 networkCallback.expect(LINK_PROPERTIES_CHANGED, mCellAgent, 13409 x -> x.getLp().getRoutes().size() == 3); 13410 13411 assertRoutesAdded(netId, direct, rio1, defaultRoute); 13412 reset(mMockNetd); 13413 13414 // Send updated LinkProperties and check that we ask netd to add, remove, update routes. 13415 assertTrue(lp.getRoutes().contains(defaultRoute)); 13416 lp.removeRoute(rio1); 13417 lp.addRoute(rio2); 13418 lp.addRoute(defaultWithMtu); 13419 // Ensure adding the same route with a different MTU replaces the previous route. 13420 assertFalse(lp.getRoutes().contains(defaultRoute)); 13421 assertTrue(lp.getRoutes().contains(defaultWithMtu)); 13422 13423 mCellAgent.sendLinkProperties(lp); 13424 networkCallback.expect(LINK_PROPERTIES_CHANGED, mCellAgent, 13425 x -> x.getLp().getRoutes().contains(rio2)); 13426 13427 assertRoutesRemoved(netId, rio1); 13428 assertRoutesAdded(netId, rio2); 13429 13430 ArgumentCaptor<RouteInfoParcel> captor = ArgumentCaptor.forClass(RouteInfoParcel.class); 13431 verify(mMockNetd).networkUpdateRouteParcel(eq(netId), captor.capture()); 13432 assertRouteInfoParcelMatches(defaultWithMtu, captor.getValue()); 13433 13434 13435 mCm.unregisterNetworkCallback(networkCallback); 13436 } 13437 13438 private void verifyDump(String[] args) { 13439 final StringWriter stringWriter = new StringWriter(); 13440 mService.dump(new FileDescriptor(), new PrintWriter(stringWriter), args); 13441 assertFalse(stringWriter.toString().isEmpty()); 13442 } 13443 13444 @Test 13445 public void testDumpDoesNotCrash() throws Exception { 13446 mServiceContext.setPermission(DUMP, PERMISSION_GRANTED); 13447 // Filing a couple requests prior to testing the dump. 13448 final TestNetworkCallback genericNetworkCallback = new TestNetworkCallback(); 13449 final TestNetworkCallback wifiNetworkCallback = new TestNetworkCallback(); 13450 final NetworkRequest genericRequest = new NetworkRequest.Builder() 13451 .clearCapabilities().build(); 13452 final NetworkRequest wifiRequest = new NetworkRequest.Builder() 13453 .addTransportType(TRANSPORT_WIFI).build(); 13454 mCm.registerNetworkCallback(genericRequest, genericNetworkCallback); 13455 mCm.registerNetworkCallback(wifiRequest, wifiNetworkCallback); 13456 13457 // NetworkProvider 13458 final NetworkProvider wifiProvider = new NetworkProvider(mServiceContext, 13459 mCsHandlerThread.getLooper(), "Wifi provider"); 13460 mCm.registerNetworkProvider(wifiProvider); 13461 13462 // NetworkAgent 13463 final LinkProperties wifiLp = new LinkProperties(); 13464 wifiLp.setInterfaceName(WIFI_IFNAME); 13465 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, wifiLp); 13466 mWiFiAgent.connect(true); 13467 13468 // NetworkOffer 13469 final NetworkScore wifiScore = new NetworkScore.Builder().build(); 13470 final NetworkCapabilities wifiCaps = new NetworkCapabilities.Builder() 13471 .addTransportType(TRANSPORT_WIFI) 13472 .addCapability(NET_CAPABILITY_INTERNET) 13473 .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED) 13474 .build(); 13475 final TestableNetworkOfferCallback wifiCallback = new TestableNetworkOfferCallback( 13476 TIMEOUT_MS /* timeout */, TEST_CALLBACK_TIMEOUT_MS /* noCallbackTimeout */); 13477 wifiProvider.registerNetworkOffer(wifiScore, wifiCaps, r -> r.run(), wifiCallback); 13478 13479 // Profile preferences 13480 final UserHandle testHandle = setupEnterpriseNetwork(); 13481 final TestNetworkAgentWrapper workAgent = makeEnterpriseNetworkAgent(); 13482 workAgent.connect(true); 13483 mCm.setProfileNetworkPreference(testHandle, PROFILE_NETWORK_PREFERENCE_ENTERPRISE, 13484 null /* executor */, null /* listener */); 13485 13486 // OEM preferences 13487 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 13488 OEM_NETWORK_PREFERENCE_OEM_PAID; 13489 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); 13490 setOemNetworkPreference(networkPref, TEST_PACKAGE_NAME); 13491 13492 // Mobile data preferred UIDs 13493 setAndUpdateMobileDataPreferredUids(Set.of(TEST_PACKAGE_UID)); 13494 13495 verifyDump(new String[0]); 13496 13497 // Verify dump with arguments. 13498 final String dumpPrio = "--dump-priority"; 13499 final String[] dumpArgs = {dumpPrio}; 13500 verifyDump(dumpArgs); 13501 13502 final String[] highDumpArgs = {dumpPrio, "HIGH"}; 13503 verifyDump(highDumpArgs); 13504 13505 final String[] normalDumpArgs = {dumpPrio, "NORMAL"}; 13506 verifyDump(normalDumpArgs); 13507 13508 // Invalid args should do dumpNormal w/o exception 13509 final String[] unknownDumpArgs = {dumpPrio, "UNKNOWN"}; 13510 verifyDump(unknownDumpArgs); 13511 13512 final String[] invalidDumpArgs = {"UNKNOWN"}; 13513 verifyDump(invalidDumpArgs); 13514 } 13515 13516 @Test 13517 public void testRequestsSortedByIdSortsCorrectly() { 13518 final TestNetworkCallback genericNetworkCallback = new TestNetworkCallback(); 13519 final TestNetworkCallback wifiNetworkCallback = new TestNetworkCallback(); 13520 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback(); 13521 final NetworkRequest genericRequest = new NetworkRequest.Builder() 13522 .clearCapabilities().build(); 13523 final NetworkRequest wifiRequest = new NetworkRequest.Builder() 13524 .addTransportType(TRANSPORT_WIFI).build(); 13525 final NetworkRequest cellRequest = new NetworkRequest.Builder() 13526 .addTransportType(TRANSPORT_CELLULAR).build(); 13527 mCm.registerNetworkCallback(genericRequest, genericNetworkCallback); 13528 mCm.registerNetworkCallback(wifiRequest, wifiNetworkCallback); 13529 mCm.registerNetworkCallback(cellRequest, cellNetworkCallback); 13530 waitForIdle(); 13531 13532 final NetworkRequestInfo[] nriOutput = mService.requestsSortedById(); 13533 13534 assertTrue(nriOutput.length > 1); 13535 for (int i = 0; i < nriOutput.length - 1; i++) { 13536 final boolean isRequestIdInOrder = 13537 nriOutput[i].mRequests.get(0).requestId 13538 < nriOutput[i + 1].mRequests.get(0).requestId; 13539 assertTrue(isRequestIdInOrder); 13540 } 13541 } 13542 13543 private void assertUidRangesUpdatedForMyUid(boolean add) throws Exception { 13544 final int uid = Process.myUid(); 13545 assertVpnUidRangesUpdated(add, uidRangesForUids(uid), uid); 13546 } 13547 13548 private void assertVpnUidRangesUpdated(boolean add, Set<UidRange> vpnRanges, int exemptUid) 13549 throws Exception { 13550 InOrder inOrder = inOrder(mMockNetd, mDestroySocketsWrapper); 13551 final Set<Integer> exemptUidSet = new ArraySet<>(List.of(exemptUid, Process.VPN_UID)); 13552 ArgumentCaptor<int[]> exemptUidCaptor = ArgumentCaptor.forClass(int[].class); 13553 13554 if (mDeps.isAtLeastU()) { 13555 inOrder.verify(mDestroySocketsWrapper).destroyLiveTcpSockets( 13556 UidRange.toIntRanges(vpnRanges), exemptUidSet); 13557 } else { 13558 inOrder.verify(mMockNetd).socketDestroy(eq(toUidRangeStableParcels(vpnRanges)), 13559 exemptUidCaptor.capture()); 13560 assertContainsExactly(exemptUidCaptor.getValue(), Process.VPN_UID, exemptUid); 13561 } 13562 13563 if (add) { 13564 inOrder.verify(mMockNetd, times(1)).networkAddUidRangesParcel( 13565 new NativeUidRangeConfig(mMockVpn.getNetwork().getNetId(), 13566 toUidRangeStableParcels(vpnRanges), PREFERENCE_ORDER_VPN)); 13567 } else { 13568 inOrder.verify(mMockNetd, times(1)).networkRemoveUidRangesParcel( 13569 new NativeUidRangeConfig(mMockVpn.getNetwork().getNetId(), 13570 toUidRangeStableParcels(vpnRanges), PREFERENCE_ORDER_VPN)); 13571 } 13572 13573 if (mDeps.isAtLeastU()) { 13574 inOrder.verify(mDestroySocketsWrapper).destroyLiveTcpSockets( 13575 UidRange.toIntRanges(vpnRanges), exemptUidSet); 13576 } else { 13577 inOrder.verify(mMockNetd).socketDestroy(eq(toUidRangeStableParcels(vpnRanges)), 13578 exemptUidCaptor.capture()); 13579 assertContainsExactly(exemptUidCaptor.getValue(), Process.VPN_UID, exemptUid); 13580 } 13581 } 13582 13583 @Test 13584 public void testVpnUidRangesUpdate() throws Exception { 13585 // Set up a WiFi network without proxy. 13586 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 13587 mWiFiAgent.connect(true); 13588 assertNull(mService.getProxyForNetwork(null)); 13589 assertNull(mCm.getDefaultProxy()); 13590 13591 final ExpectedBroadcast b1 = expectProxyChangeAction(); 13592 final LinkProperties lp = new LinkProperties(); 13593 lp.setInterfaceName("tun0"); 13594 lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), null)); 13595 lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), null)); 13596 final UidRange vpnRange = PRIMARY_UIDRANGE; 13597 final Set<UidRange> vpnRanges = Collections.singleton(vpnRange); 13598 mMockVpn.establish(lp, VPN_UID, vpnRanges); 13599 assertVpnUidRangesUpdated(true, vpnRanges, VPN_UID); 13600 // VPN is connected but proxy is not set, so there is no need to send proxy broadcast. 13601 b1.expectNoBroadcast(500); 13602 13603 // Update to new range which is old range minus APP1, i.e. only APP2 13604 final ExpectedBroadcast b2 = expectProxyChangeAction(); 13605 final Set<UidRange> newRanges = new HashSet<>(asList( 13606 new UidRange(vpnRange.start, APP1_UID - 1), 13607 new UidRange(APP1_UID + 1, vpnRange.stop))); 13608 mMockVpn.setUids(newRanges); 13609 waitForIdle(); 13610 13611 assertVpnUidRangesUpdated(true, newRanges, VPN_UID); 13612 assertVpnUidRangesUpdated(false, vpnRanges, VPN_UID); 13613 13614 // Uid has changed but proxy is not set, so there is no need to send proxy broadcast. 13615 b2.expectNoBroadcast(500); 13616 13617 final ProxyInfo testProxyInfo = ProxyInfo.buildDirectProxy("test", 8888); 13618 final ExpectedBroadcast b3 = expectProxyChangeAction(); 13619 lp.setHttpProxy(testProxyInfo); 13620 mMockVpn.sendLinkProperties(lp); 13621 waitForIdle(); 13622 // Proxy is set, so send a proxy broadcast. 13623 b3.expectBroadcast(); 13624 13625 final ExpectedBroadcast b4 = expectProxyChangeAction(); 13626 mMockVpn.setUids(vpnRanges); 13627 waitForIdle(); 13628 // Uid has changed and proxy is already set, so send a proxy broadcast. 13629 b4.expectBroadcast(); 13630 13631 final ExpectedBroadcast b5 = expectProxyChangeAction(); 13632 // Proxy is removed, send a proxy broadcast. 13633 lp.setHttpProxy(null); 13634 mMockVpn.sendLinkProperties(lp); 13635 waitForIdle(); 13636 b5.expectBroadcast(); 13637 13638 // Proxy is added in WiFi(default network), setDefaultProxy will be called. 13639 final LinkProperties wifiLp = mCm.getLinkProperties(mWiFiAgent.getNetwork()); 13640 assertNotNull(wifiLp); 13641 final ExpectedBroadcast b6 = expectProxyChangeAction(testProxyInfo); 13642 wifiLp.setHttpProxy(testProxyInfo); 13643 mWiFiAgent.sendLinkProperties(wifiLp); 13644 waitForIdle(); 13645 b6.expectBroadcast(); 13646 } 13647 13648 @Test 13649 public void testProxyBroadcastWillBeSentWhenVpnHasProxyAndConnects() throws Exception { 13650 // Set up a WiFi network without proxy. 13651 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 13652 mWiFiAgent.connect(true); 13653 assertNull(mService.getProxyForNetwork(null)); 13654 assertNull(mCm.getDefaultProxy()); 13655 13656 final LinkProperties lp = new LinkProperties(); 13657 lp.setInterfaceName("tun0"); 13658 lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), null)); 13659 lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), null)); 13660 final ProxyInfo testProxyInfo = ProxyInfo.buildDirectProxy("test", 8888); 13661 lp.setHttpProxy(testProxyInfo); 13662 final UidRange vpnRange = PRIMARY_UIDRANGE; 13663 final Set<UidRange> vpnRanges = Collections.singleton(vpnRange); 13664 final ExpectedBroadcast b1 = expectProxyChangeAction(); 13665 mMockVpn.setOwnerAndAdminUid(VPN_UID); 13666 mMockVpn.registerAgent(false, vpnRanges, lp); 13667 // In any case, the proxy broadcast won't be sent before VPN goes into CONNECTED state. 13668 // Otherwise, the app that calls ConnectivityManager#getDefaultProxy() when it receives the 13669 // proxy broadcast will get null. 13670 b1.expectNoBroadcast(500); 13671 13672 final ExpectedBroadcast b2 = expectProxyChangeAction(); 13673 mMockVpn.connect(true /* validated */, true /* hasInternet */, 13674 false /* privateDnsProbeSent */); 13675 waitForIdle(); 13676 assertVpnUidRangesUpdated(true, vpnRanges, VPN_UID); 13677 // Vpn is connected with proxy, so the proxy broadcast will be sent to inform the apps to 13678 // update their proxy data. 13679 b2.expectBroadcast(); 13680 } 13681 13682 @Test 13683 public void testProxyBroadcastWillBeSentWhenTheProxyOfNonDefaultNetworkHasChanged() 13684 throws Exception { 13685 // Set up a CELLULAR network without proxy. 13686 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 13687 mCellAgent.connect(true); 13688 assertNull(mService.getProxyForNetwork(null)); 13689 assertNull(mCm.getDefaultProxy()); 13690 // CELLULAR network should be the default network. 13691 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetwork()); 13692 13693 // Set up a WiFi network without proxy. 13694 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 13695 mWiFiAgent.connect(true); 13696 assertNull(mService.getProxyForNetwork(null)); 13697 assertNull(mCm.getDefaultProxy()); 13698 // WiFi network should be the default network. 13699 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetwork()); 13700 // CELLULAR network is not the default network. 13701 assertNotEquals(mCellAgent.getNetwork(), mCm.getActiveNetwork()); 13702 13703 // CELLULAR network is not the system default network, but it might be a per-app default 13704 // network. The proxy broadcast should be sent once its proxy has changed. 13705 final LinkProperties cellularLp = new LinkProperties(); 13706 cellularLp.setInterfaceName(MOBILE_IFNAME); 13707 final ProxyInfo testProxyInfo = ProxyInfo.buildDirectProxy("test", 8888); 13708 final ExpectedBroadcast b = expectProxyChangeAction(); 13709 cellularLp.setHttpProxy(testProxyInfo); 13710 mCellAgent.sendLinkProperties(cellularLp); 13711 b.expectBroadcast(); 13712 } 13713 13714 @Test 13715 public void testInvalidRequestTypes() { 13716 final int[] invalidReqTypeInts = new int[]{-1, NetworkRequest.Type.NONE.ordinal(), 13717 NetworkRequest.Type.LISTEN.ordinal(), NetworkRequest.Type.values().length}; 13718 final NetworkCapabilities nc = new NetworkCapabilities().addTransportType(TRANSPORT_WIFI); 13719 13720 for (int reqTypeInt : invalidReqTypeInts) { 13721 assertThrows("Expect throws for invalid request type " + reqTypeInt, 13722 IllegalArgumentException.class, 13723 () -> mService.requestNetwork(Process.INVALID_UID, nc, reqTypeInt, null, 0, 13724 null, ConnectivityManager.TYPE_NONE, NetworkCallback.FLAG_NONE, 13725 mContext.getPackageName(), getAttributionTag(), 13726 ~0 /* declaredMethodsFlag */) 13727 ); 13728 } 13729 } 13730 13731 @Test 13732 public void testKeepConnected() throws Exception { 13733 setAlwaysOnNetworks(false); 13734 registerDefaultNetworkCallbacks(); 13735 final TestNetworkCallback allNetworksCb = new TestNetworkCallback(); 13736 final NetworkRequest allNetworksRequest = new NetworkRequest.Builder().clearCapabilities() 13737 .build(); 13738 mCm.registerNetworkCallback(allNetworksRequest, allNetworksCb); 13739 13740 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 13741 mCellAgent.connect(true /* validated */); 13742 13743 mDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 13744 allNetworksCb.expectAvailableThenValidatedCallbacks(mCellAgent); 13745 13746 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 13747 mWiFiAgent.connect(true /* validated */); 13748 13749 mDefaultNetworkCallback.expectAvailableDoubleValidatedCallbacks(mWiFiAgent); 13750 // While the default callback doesn't see the network before it's validated, the listen 13751 // sees the network come up and validate later 13752 allNetworksCb.expectAvailableCallbacksUnvalidated(mWiFiAgent); 13753 allNetworksCb.expectLosing(mCellAgent); 13754 allNetworksCb.expectCaps(mWiFiAgent, c -> c.hasCapability(NET_CAPABILITY_VALIDATED)); 13755 allNetworksCb.expect(LOST, mCellAgent, TEST_LINGER_DELAY_MS * 2); 13756 13757 // The cell network has disconnected (see LOST above) because it was outscored and 13758 // had no requests (see setAlwaysOnNetworks(false) above) 13759 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 13760 final NetworkScore score = new NetworkScore.Builder().setLegacyInt(30).build(); 13761 mCellAgent.setScore(score); 13762 mCellAgent.connect(false /* validated */); 13763 13764 // The cell network gets torn down right away. 13765 allNetworksCb.expectAvailableCallbacksUnvalidated(mCellAgent); 13766 allNetworksCb.expect(LOST, mCellAgent, TEST_NASCENT_DELAY_MS * 2); 13767 allNetworksCb.assertNoCallback(); 13768 13769 // Now create a cell network with KEEP_CONNECTED_FOR_HANDOVER and make sure it's 13770 // not disconnected immediately when outscored. 13771 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 13772 final NetworkScore scoreKeepup = new NetworkScore.Builder().setLegacyInt(30) 13773 .setKeepConnectedReason(KEEP_CONNECTED_FOR_HANDOVER).build(); 13774 mCellAgent.setScore(scoreKeepup); 13775 mCellAgent.connect(true /* validated */); 13776 13777 allNetworksCb.expectAvailableThenValidatedCallbacks(mCellAgent); 13778 mDefaultNetworkCallback.assertNoCallback(); 13779 13780 mWiFiAgent.disconnect(); 13781 13782 allNetworksCb.expect(LOST, mWiFiAgent); 13783 mDefaultNetworkCallback.expect(LOST, mWiFiAgent); 13784 mDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellAgent); 13785 13786 // Reconnect a WiFi network and make sure the cell network is still not torn down. 13787 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 13788 mWiFiAgent.connect(true /* validated */); 13789 13790 allNetworksCb.expectAvailableThenValidatedCallbacks(mWiFiAgent); 13791 mDefaultNetworkCallback.expectAvailableDoubleValidatedCallbacks(mWiFiAgent); 13792 13793 // Now remove the reason to keep connected and make sure the network lingers and is 13794 // torn down. 13795 mCellAgent.setScore(new NetworkScore.Builder().setLegacyInt(30).build()); 13796 allNetworksCb.expectLosing(mCellAgent, TEST_NASCENT_DELAY_MS * 2); 13797 allNetworksCb.expect(LOST, mCellAgent, TEST_LINGER_DELAY_MS * 2); 13798 mDefaultNetworkCallback.assertNoCallback(); 13799 13800 mCm.unregisterNetworkCallback(allNetworksCb); 13801 // mDefaultNetworkCallback will be unregistered by tearDown() 13802 } 13803 13804 private class QosCallbackMockHelper { 13805 @NonNull public final QosFilter mFilter; 13806 @NonNull public final IQosCallback mCallback; 13807 @NonNull public final TestNetworkAgentWrapper mAgentWrapper; 13808 @NonNull private final List<IQosCallback> mCallbacks = new ArrayList(); 13809 13810 QosCallbackMockHelper() throws Exception { 13811 Log.d(TAG, "QosCallbackMockHelper: "); 13812 mFilter = mock(QosFilter.class); 13813 13814 // Ensure the network is disconnected before anything else occurs 13815 assertNull(mCellAgent); 13816 13817 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 13818 mCellAgent.connect(true); 13819 13820 verifyActiveNetwork(TRANSPORT_CELLULAR); 13821 waitForIdle(); 13822 final Network network = mCellAgent.getNetwork(); 13823 13824 final Pair<IQosCallback, IBinder> pair = createQosCallback(); 13825 mCallback = pair.first; 13826 13827 doReturn(network).when(mFilter).getNetwork(); 13828 doReturn(QosCallbackException.EX_TYPE_FILTER_NONE).when(mFilter).validate(); 13829 mAgentWrapper = mCellAgent; 13830 } 13831 13832 void registerQosCallback(@NonNull final QosFilter filter, 13833 @NonNull final IQosCallback callback) { 13834 mCallbacks.add(callback); 13835 final NetworkAgentInfo nai = 13836 mService.getNetworkAgentInfoForNetwork(filter.getNetwork()); 13837 mService.registerQosCallbackInternal(filter, callback, nai); 13838 } 13839 13840 void tearDown() { 13841 for (int i = 0; i < mCallbacks.size(); i++) { 13842 mService.unregisterQosCallback(mCallbacks.get(i)); 13843 } 13844 } 13845 } 13846 13847 private Pair<IQosCallback, IBinder> createQosCallback() { 13848 final IQosCallback callback = mock(IQosCallback.class); 13849 final IBinder binder = mock(Binder.class); 13850 doReturn(binder).when(callback).asBinder(); 13851 doReturn(true).when(binder).isBinderAlive(); 13852 return new Pair<>(callback, binder); 13853 } 13854 13855 13856 @Test 13857 public void testQosCallbackRegistration() throws Exception { 13858 mQosCallbackMockHelper = new QosCallbackMockHelper(); 13859 final NetworkAgentWrapper wrapper = mQosCallbackMockHelper.mAgentWrapper; 13860 13861 doReturn(QosCallbackException.EX_TYPE_FILTER_NONE) 13862 .when(mQosCallbackMockHelper.mFilter).validate(); 13863 mQosCallbackMockHelper.registerQosCallback( 13864 mQosCallbackMockHelper.mFilter, mQosCallbackMockHelper.mCallback); 13865 13866 final OnQosCallbackRegister cbRegister1 = 13867 (OnQosCallbackRegister) wrapper.getCallbackHistory().poll(1000, x -> true); 13868 assertNotNull(cbRegister1); 13869 13870 final int registerCallbackId = cbRegister1.mQosCallbackId; 13871 mService.unregisterQosCallback(mQosCallbackMockHelper.mCallback); 13872 final OnQosCallbackUnregister cbUnregister = 13873 (OnQosCallbackUnregister) wrapper.getCallbackHistory().poll(1000, x -> true); 13874 assertNotNull(cbUnregister); 13875 assertEquals(registerCallbackId, cbUnregister.mQosCallbackId); 13876 assertNull(wrapper.getCallbackHistory().poll(200, x -> true)); 13877 } 13878 13879 @Test 13880 public void testQosCallbackNoRegistrationOnValidationError() throws Exception { 13881 mQosCallbackMockHelper = new QosCallbackMockHelper(); 13882 13883 doReturn(QosCallbackException.EX_TYPE_FILTER_NETWORK_RELEASED) 13884 .when(mQosCallbackMockHelper.mFilter).validate(); 13885 mQosCallbackMockHelper.registerQosCallback( 13886 mQosCallbackMockHelper.mFilter, mQosCallbackMockHelper.mCallback); 13887 waitForIdle(); 13888 verify(mQosCallbackMockHelper.mCallback) 13889 .onError(eq(QosCallbackException.EX_TYPE_FILTER_NETWORK_RELEASED)); 13890 } 13891 13892 @Test 13893 public void testQosCallbackAvailableAndLost() throws Exception { 13894 mQosCallbackMockHelper = new QosCallbackMockHelper(); 13895 final int sessionId = 10; 13896 final int qosCallbackId = 1; 13897 13898 doReturn(QosCallbackException.EX_TYPE_FILTER_NONE) 13899 .when(mQosCallbackMockHelper.mFilter).validate(); 13900 mQosCallbackMockHelper.registerQosCallback( 13901 mQosCallbackMockHelper.mFilter, mQosCallbackMockHelper.mCallback); 13902 waitForIdle(); 13903 13904 final EpsBearerQosSessionAttributes attributes = new EpsBearerQosSessionAttributes( 13905 1, 2, 3, 4, 5, new ArrayList<>()); 13906 mQosCallbackMockHelper.mAgentWrapper.getNetworkAgent() 13907 .sendQosSessionAvailable(qosCallbackId, sessionId, attributes); 13908 waitForIdle(); 13909 13910 verify(mQosCallbackMockHelper.mCallback).onQosEpsBearerSessionAvailable(argThat(session -> 13911 session.getSessionId() == sessionId 13912 && session.getSessionType() == QosSession.TYPE_EPS_BEARER), eq(attributes)); 13913 13914 mQosCallbackMockHelper.mAgentWrapper.getNetworkAgent() 13915 .sendQosSessionLost(qosCallbackId, sessionId, QosSession.TYPE_EPS_BEARER); 13916 waitForIdle(); 13917 verify(mQosCallbackMockHelper.mCallback).onQosSessionLost(argThat(session -> 13918 session.getSessionId() == sessionId 13919 && session.getSessionType() == QosSession.TYPE_EPS_BEARER)); 13920 } 13921 13922 @Test 13923 public void testNrQosCallbackAvailableAndLost() throws Exception { 13924 mQosCallbackMockHelper = new QosCallbackMockHelper(); 13925 final int sessionId = 10; 13926 final int qosCallbackId = 1; 13927 13928 doReturn(QosCallbackException.EX_TYPE_FILTER_NONE) 13929 .when(mQosCallbackMockHelper.mFilter).validate(); 13930 mQosCallbackMockHelper.registerQosCallback( 13931 mQosCallbackMockHelper.mFilter, mQosCallbackMockHelper.mCallback); 13932 waitForIdle(); 13933 13934 final NrQosSessionAttributes attributes = new NrQosSessionAttributes( 13935 1, 2, 3, 4, 5, 6, 7, new ArrayList<>()); 13936 mQosCallbackMockHelper.mAgentWrapper.getNetworkAgent() 13937 .sendQosSessionAvailable(qosCallbackId, sessionId, attributes); 13938 waitForIdle(); 13939 13940 verify(mQosCallbackMockHelper.mCallback).onNrQosSessionAvailable(argThat(session -> 13941 session.getSessionId() == sessionId 13942 && session.getSessionType() == QosSession.TYPE_NR_BEARER), eq(attributes)); 13943 13944 mQosCallbackMockHelper.mAgentWrapper.getNetworkAgent() 13945 .sendQosSessionLost(qosCallbackId, sessionId, QosSession.TYPE_NR_BEARER); 13946 waitForIdle(); 13947 verify(mQosCallbackMockHelper.mCallback).onQosSessionLost(argThat(session -> 13948 session.getSessionId() == sessionId 13949 && session.getSessionType() == QosSession.TYPE_NR_BEARER)); 13950 } 13951 13952 @Test @IgnoreUpTo(SC_V2) 13953 public void testQosCallbackAvailableOnValidationError() throws Exception { 13954 mQosCallbackMockHelper = new QosCallbackMockHelper(); 13955 final NetworkAgentWrapper wrapper = mQosCallbackMockHelper.mAgentWrapper; 13956 final int sessionId = 10; 13957 final int qosCallbackId = 1; 13958 13959 doReturn(QosCallbackException.EX_TYPE_FILTER_NONE) 13960 .when(mQosCallbackMockHelper.mFilter).validate(); 13961 mQosCallbackMockHelper.registerQosCallback( 13962 mQosCallbackMockHelper.mFilter, mQosCallbackMockHelper.mCallback); 13963 OnQosCallbackRegister cbRegister1 = 13964 (OnQosCallbackRegister) wrapper.getCallbackHistory().poll(1000, x -> true); 13965 assertNotNull(cbRegister1); 13966 final int registerCallbackId = cbRegister1.mQosCallbackId; 13967 13968 waitForIdle(); 13969 13970 doReturn(QosCallbackException.EX_TYPE_FILTER_SOCKET_REMOTE_ADDRESS_CHANGED) 13971 .when(mQosCallbackMockHelper.mFilter).validate(); 13972 final EpsBearerQosSessionAttributes attributes = new EpsBearerQosSessionAttributes( 13973 1, 2, 3, 4, 5, new ArrayList<>()); 13974 mQosCallbackMockHelper.mAgentWrapper.getNetworkAgent() 13975 .sendQosSessionAvailable(qosCallbackId, sessionId, attributes); 13976 waitForIdle(); 13977 13978 final NetworkAgentWrapper.CallbackType.OnQosCallbackUnregister cbUnregister; 13979 cbUnregister = (NetworkAgentWrapper.CallbackType.OnQosCallbackUnregister) 13980 wrapper.getCallbackHistory().poll(1000, x -> true); 13981 assertNotNull(cbUnregister); 13982 assertEquals(registerCallbackId, cbUnregister.mQosCallbackId); 13983 waitForIdle(); 13984 verify(mQosCallbackMockHelper.mCallback) 13985 .onError(eq(QosCallbackException.EX_TYPE_FILTER_SOCKET_REMOTE_ADDRESS_CHANGED)); 13986 } 13987 13988 @Test @IgnoreUpTo(SC_V2) 13989 public void testQosCallbackLostOnValidationError() throws Exception { 13990 mQosCallbackMockHelper = new QosCallbackMockHelper(); 13991 final int sessionId = 10; 13992 final int qosCallbackId = 1; 13993 13994 doReturn(QosCallbackException.EX_TYPE_FILTER_NONE) 13995 .when(mQosCallbackMockHelper.mFilter).validate(); 13996 mQosCallbackMockHelper.registerQosCallback( 13997 mQosCallbackMockHelper.mFilter, mQosCallbackMockHelper.mCallback); 13998 waitForIdle(); 13999 EpsBearerQosSessionAttributes attributes = 14000 sendQosSessionEvent(qosCallbackId, sessionId, true); 14001 waitForIdle(); 14002 14003 verify(mQosCallbackMockHelper.mCallback).onQosEpsBearerSessionAvailable(argThat(session -> 14004 session.getSessionId() == sessionId 14005 && session.getSessionType() == QosSession.TYPE_EPS_BEARER), eq(attributes)); 14006 14007 doReturn(QosCallbackException.EX_TYPE_FILTER_SOCKET_REMOTE_ADDRESS_CHANGED) 14008 .when(mQosCallbackMockHelper.mFilter).validate(); 14009 14010 sendQosSessionEvent(qosCallbackId, sessionId, false); 14011 waitForIdle(); 14012 verify(mQosCallbackMockHelper.mCallback) 14013 .onError(eq(QosCallbackException.EX_TYPE_FILTER_SOCKET_REMOTE_ADDRESS_CHANGED)); 14014 } 14015 14016 private EpsBearerQosSessionAttributes sendQosSessionEvent( 14017 int qosCallbackId, int sessionId, boolean available) { 14018 if (available) { 14019 final EpsBearerQosSessionAttributes attributes = new EpsBearerQosSessionAttributes( 14020 1, 2, 3, 4, 5, new ArrayList<>()); 14021 mQosCallbackMockHelper.mAgentWrapper.getNetworkAgent() 14022 .sendQosSessionAvailable(qosCallbackId, sessionId, attributes); 14023 return attributes; 14024 } else { 14025 mQosCallbackMockHelper.mAgentWrapper.getNetworkAgent() 14026 .sendQosSessionLost(qosCallbackId, sessionId, QosSession.TYPE_EPS_BEARER); 14027 return null; 14028 } 14029 14030 } 14031 14032 @Test 14033 public void testQosCallbackTooManyRequests() throws Exception { 14034 mQosCallbackMockHelper = new QosCallbackMockHelper(); 14035 14036 doReturn(QosCallbackException.EX_TYPE_FILTER_NONE) 14037 .when(mQosCallbackMockHelper.mFilter).validate(); 14038 for (int i = 0; i < 100; i++) { 14039 final Pair<IQosCallback, IBinder> pair = createQosCallback(); 14040 14041 try { 14042 mQosCallbackMockHelper.registerQosCallback( 14043 mQosCallbackMockHelper.mFilter, pair.first); 14044 } catch (ServiceSpecificException e) { 14045 assertEquals(e.errorCode, ConnectivityManager.Errors.TOO_MANY_REQUESTS); 14046 if (i < 50) { 14047 fail("TOO_MANY_REQUESTS thrown too early, the count is " + i); 14048 } 14049 14050 // As long as there is at least 50 requests, it is safe to assume it works. 14051 // Note: The count isn't being tested precisely against 100 because the counter 14052 // is shared with request network. 14053 return; 14054 } 14055 } 14056 fail("TOO_MANY_REQUESTS never thrown"); 14057 } 14058 14059 private void mockGetApplicationInfo(@NonNull final String packageName, final int uid) { 14060 mockGetApplicationInfo(packageName, uid, PRIMARY_USER_HANDLE); 14061 } 14062 14063 private void mockGetApplicationInfo(@NonNull final String packageName, final int uid, 14064 @NonNull final UserHandle user) { 14065 final ApplicationInfo applicationInfo = new ApplicationInfo(); 14066 applicationInfo.uid = uid; 14067 try { 14068 doReturn(applicationInfo).when(mPackageManager).getApplicationInfoAsUser( 14069 eq(packageName), anyInt(), eq(user)); 14070 } catch (Exception e) { 14071 fail(e.getMessage()); 14072 } 14073 } 14074 14075 private void mockGetApplicationInfoThrowsNameNotFound(@NonNull final String packageName, 14076 @NonNull final UserHandle user) 14077 throws Exception { 14078 doThrow(new PackageManager.NameNotFoundException(packageName)).when( 14079 mPackageManager).getApplicationInfoAsUser(eq(packageName), anyInt(), eq(user)); 14080 } 14081 14082 private void mockHasSystemFeature(@NonNull final String featureName, final boolean hasFeature) { 14083 doReturn(hasFeature).when(mPackageManager).hasSystemFeature(eq(featureName)); 14084 } 14085 14086 private Range<Integer> getNriFirstUidRange(@NonNull final NetworkRequestInfo nri) { 14087 return nri.mRequests.get(0).networkCapabilities.getUids().iterator().next(); 14088 } 14089 14090 private OemNetworkPreferences createDefaultOemNetworkPreferences( 14091 @OemNetworkPreferences.OemNetworkPreference final int preference) { 14092 // Arrange PackageManager mocks 14093 mockGetApplicationInfo(TEST_PACKAGE_NAME, TEST_PACKAGE_UID); 14094 14095 // Build OemNetworkPreferences object 14096 return new OemNetworkPreferences.Builder() 14097 .addNetworkPreference(TEST_PACKAGE_NAME, preference) 14098 .build(); 14099 } 14100 14101 @Test 14102 public void testOemNetworkRequestFactoryPreferenceUninitializedThrowsError() { 14103 @OemNetworkPreferences.OemNetworkPreference final int prefToTest = 14104 OEM_NETWORK_PREFERENCE_UNINITIALIZED; 14105 14106 // Act on OemNetworkRequestFactory.createNrisFromOemNetworkPreferences() 14107 assertThrows(IllegalArgumentException.class, 14108 () -> mService.new OemNetworkRequestFactory() 14109 .createNrisFromOemNetworkPreferences( 14110 createDefaultOemNetworkPreferences(prefToTest))); 14111 } 14112 14113 @Test 14114 public void testOemNetworkRequestFactoryPreferenceOemPaid() 14115 throws Exception { 14116 // Expectations 14117 final int expectedNumOfNris = 1; 14118 final int expectedNumOfRequests = 3; 14119 14120 @OemNetworkPreferences.OemNetworkPreference final int prefToTest = 14121 OEM_NETWORK_PREFERENCE_OEM_PAID; 14122 14123 // Act on OemNetworkRequestFactory.createNrisFromOemNetworkPreferences() 14124 final ArraySet<NetworkRequestInfo> nris = 14125 mService.new OemNetworkRequestFactory() 14126 .createNrisFromOemNetworkPreferences( 14127 createDefaultOemNetworkPreferences(prefToTest)); 14128 final NetworkRequestInfo nri = nris.iterator().next(); 14129 assertEquals(PREFERENCE_ORDER_OEM, nri.mPreferenceOrder); 14130 final List<NetworkRequest> mRequests = nri.mRequests; 14131 assertEquals(expectedNumOfNris, nris.size()); 14132 assertEquals(expectedNumOfRequests, mRequests.size()); 14133 assertTrue(mRequests.get(0).isListen()); 14134 assertTrue(mRequests.get(0).hasCapability(NET_CAPABILITY_NOT_METERED)); 14135 assertTrue(mRequests.get(0).hasCapability(NET_CAPABILITY_VALIDATED)); 14136 assertTrue(mRequests.get(1).isRequest()); 14137 assertTrue(mRequests.get(1).hasCapability(NET_CAPABILITY_OEM_PAID)); 14138 assertEquals(NetworkRequest.Type.TRACK_DEFAULT, mRequests.get(2).type); 14139 assertTrue(mService.getDefaultRequest().networkCapabilities.equalsNetCapabilities( 14140 mRequests.get(2).networkCapabilities)); 14141 } 14142 14143 @Test 14144 public void testOemNetworkRequestFactoryPreferenceOemPaidNoFallback() 14145 throws Exception { 14146 // Expectations 14147 final int expectedNumOfNris = 1; 14148 final int expectedNumOfRequests = 2; 14149 14150 @OemNetworkPreferences.OemNetworkPreference final int prefToTest = 14151 OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK; 14152 14153 // Act on OemNetworkRequestFactory.createNrisFromOemNetworkPreferences() 14154 final ArraySet<NetworkRequestInfo> nris = 14155 mService.new OemNetworkRequestFactory() 14156 .createNrisFromOemNetworkPreferences( 14157 createDefaultOemNetworkPreferences(prefToTest)); 14158 final NetworkRequestInfo nri = nris.iterator().next(); 14159 assertEquals(PREFERENCE_ORDER_OEM, nri.mPreferenceOrder); 14160 final List<NetworkRequest> mRequests = nri.mRequests; 14161 assertEquals(expectedNumOfNris, nris.size()); 14162 assertEquals(expectedNumOfRequests, mRequests.size()); 14163 assertTrue(mRequests.get(0).isListen()); 14164 assertTrue(mRequests.get(0).hasCapability(NET_CAPABILITY_NOT_METERED)); 14165 assertTrue(mRequests.get(0).hasCapability(NET_CAPABILITY_VALIDATED)); 14166 assertTrue(mRequests.get(1).isRequest()); 14167 assertTrue(mRequests.get(1).hasCapability(NET_CAPABILITY_OEM_PAID)); 14168 } 14169 14170 @Test 14171 public void testOemNetworkRequestFactoryPreferenceOemPaidOnly() 14172 throws Exception { 14173 // Expectations 14174 final int expectedNumOfNris = 1; 14175 final int expectedNumOfRequests = 1; 14176 14177 @OemNetworkPreferences.OemNetworkPreference final int prefToTest = 14178 OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY; 14179 14180 // Act on OemNetworkRequestFactory.createNrisFromOemNetworkPreferences() 14181 final ArraySet<NetworkRequestInfo> nris = 14182 mService.new OemNetworkRequestFactory() 14183 .createNrisFromOemNetworkPreferences( 14184 createDefaultOemNetworkPreferences(prefToTest)); 14185 final NetworkRequestInfo nri = nris.iterator().next(); 14186 assertEquals(PREFERENCE_ORDER_OEM, nri.mPreferenceOrder); 14187 final List<NetworkRequest> mRequests = nri.mRequests; 14188 assertEquals(expectedNumOfNris, nris.size()); 14189 assertEquals(expectedNumOfRequests, mRequests.size()); 14190 assertTrue(mRequests.get(0).isRequest()); 14191 assertTrue(mRequests.get(0).hasCapability(NET_CAPABILITY_OEM_PAID)); 14192 } 14193 14194 @Test 14195 public void testOemNetworkRequestFactoryPreferenceOemPrivateOnly() 14196 throws Exception { 14197 // Expectations 14198 final int expectedNumOfNris = 1; 14199 final int expectedNumOfRequests = 1; 14200 14201 @OemNetworkPreferences.OemNetworkPreference final int prefToTest = 14202 OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY; 14203 14204 // Act on OemNetworkRequestFactory.createNrisFromOemNetworkPreferences() 14205 final ArraySet<NetworkRequestInfo> nris = 14206 mService.new OemNetworkRequestFactory() 14207 .createNrisFromOemNetworkPreferences( 14208 createDefaultOemNetworkPreferences(prefToTest)); 14209 final NetworkRequestInfo nri = nris.iterator().next(); 14210 assertEquals(PREFERENCE_ORDER_OEM, nri.mPreferenceOrder); 14211 final List<NetworkRequest> mRequests = nri.mRequests; 14212 assertEquals(expectedNumOfNris, nris.size()); 14213 assertEquals(expectedNumOfRequests, mRequests.size()); 14214 assertTrue(mRequests.get(0).isRequest()); 14215 assertTrue(mRequests.get(0).hasCapability(NET_CAPABILITY_OEM_PRIVATE)); 14216 assertFalse(mRequests.get(0).hasCapability(NET_CAPABILITY_OEM_PAID)); 14217 } 14218 14219 @Test 14220 public void testOemNetworkRequestFactoryCreatesCorrectNumOfNris() 14221 throws Exception { 14222 // Expectations 14223 final int expectedNumOfNris = 2; 14224 14225 // Arrange PackageManager mocks 14226 final String testPackageName2 = "com.google.apps.dialer"; 14227 mockGetApplicationInfo(TEST_PACKAGE_NAME, TEST_PACKAGE_UID); 14228 mockGetApplicationInfo(testPackageName2, TEST_PACKAGE_UID); 14229 14230 // Build OemNetworkPreferences object 14231 final int testOemPref = OEM_NETWORK_PREFERENCE_OEM_PAID; 14232 final int testOemPref2 = OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK; 14233 final OemNetworkPreferences pref = new OemNetworkPreferences.Builder() 14234 .addNetworkPreference(TEST_PACKAGE_NAME, testOemPref) 14235 .addNetworkPreference(testPackageName2, testOemPref2) 14236 .build(); 14237 14238 // Act on OemNetworkRequestFactory.createNrisFromOemNetworkPreferences() 14239 final ArraySet<NetworkRequestInfo> nris = 14240 mService.new OemNetworkRequestFactory().createNrisFromOemNetworkPreferences(pref); 14241 14242 assertNotNull(nris); 14243 assertEquals(expectedNumOfNris, nris.size()); 14244 } 14245 14246 @Test 14247 public void testOemNetworkRequestFactoryMultiplePrefsCorrectlySetsUids() 14248 throws Exception { 14249 // Arrange PackageManager mocks 14250 final String testPackageName2 = "com.google.apps.dialer"; 14251 final int testPackageNameUid2 = 456; 14252 mockGetApplicationInfo(TEST_PACKAGE_NAME, TEST_PACKAGE_UID); 14253 mockGetApplicationInfo(testPackageName2, testPackageNameUid2); 14254 14255 // Build OemNetworkPreferences object 14256 final int testOemPref = OEM_NETWORK_PREFERENCE_OEM_PAID; 14257 final int testOemPref2 = OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK; 14258 final OemNetworkPreferences pref = new OemNetworkPreferences.Builder() 14259 .addNetworkPreference(TEST_PACKAGE_NAME, testOemPref) 14260 .addNetworkPreference(testPackageName2, testOemPref2) 14261 .build(); 14262 14263 // Act on OemNetworkRequestFactory.createNrisFromOemNetworkPreferences() 14264 final List<NetworkRequestInfo> nris = 14265 new ArrayList<>( 14266 mService.new OemNetworkRequestFactory().createNrisFromOemNetworkPreferences( 14267 pref)); 14268 14269 // Sort by uid to access nris by index 14270 nris.sort(Comparator.comparingInt(nri -> getNriFirstUidRange(nri).getLower())); 14271 assertEquals(TEST_PACKAGE_UID, (int) getNriFirstUidRange(nris.get(0)).getLower()); 14272 assertEquals(TEST_PACKAGE_UID, (int) getNriFirstUidRange(nris.get(0)).getUpper()); 14273 assertEquals(testPackageNameUid2, (int) getNriFirstUidRange(nris.get(1)).getLower()); 14274 assertEquals(testPackageNameUid2, (int) getNriFirstUidRange(nris.get(1)).getUpper()); 14275 } 14276 14277 @Test 14278 public void testOemNetworkRequestFactoryMultipleUsersSetsUids() 14279 throws Exception { 14280 // Arrange users 14281 final int secondUserTestPackageUid = UserHandle.getUid(SECONDARY_USER, TEST_PACKAGE_UID); 14282 final int thirdUserTestPackageUid = UserHandle.getUid(TERTIARY_USER, TEST_PACKAGE_UID); 14283 doReturn(asList(PRIMARY_USER_HANDLE, SECONDARY_USER_HANDLE, TERTIARY_USER_HANDLE)) 14284 .when(mUserManager).getUserHandles(anyBoolean()); 14285 14286 // Arrange PackageManager mocks testing for users who have and don't have a package. 14287 mockGetApplicationInfoThrowsNameNotFound(TEST_PACKAGE_NAME, PRIMARY_USER_HANDLE); 14288 mockGetApplicationInfo(TEST_PACKAGE_NAME, secondUserTestPackageUid, SECONDARY_USER_HANDLE); 14289 mockGetApplicationInfo(TEST_PACKAGE_NAME, thirdUserTestPackageUid, TERTIARY_USER_HANDLE); 14290 14291 // Build OemNetworkPreferences object 14292 final int testOemPref = OEM_NETWORK_PREFERENCE_OEM_PAID; 14293 final OemNetworkPreferences pref = new OemNetworkPreferences.Builder() 14294 .addNetworkPreference(TEST_PACKAGE_NAME, testOemPref) 14295 .build(); 14296 14297 // Act on OemNetworkRequestFactory.createNrisFromOemNetworkPreferences() 14298 final List<NetworkRequestInfo> nris = 14299 new ArrayList<>( 14300 mService.new OemNetworkRequestFactory().createNrisFromOemNetworkPreferences( 14301 pref)); 14302 14303 // UIDs for users with installed packages should be present. 14304 // Three users exist, but only two have the test package installed. 14305 final int expectedUidSize = 2; 14306 final List<Range<Integer>> uids = 14307 new ArrayList<>(nris.get(0).mRequests.get(0).networkCapabilities.getUids()); 14308 assertEquals(expectedUidSize, uids.size()); 14309 14310 // Sort by uid to access nris by index 14311 uids.sort(Comparator.comparingInt(uid -> uid.getLower())); 14312 assertEquals(secondUserTestPackageUid, (int) uids.get(0).getLower()); 14313 assertEquals(secondUserTestPackageUid, (int) uids.get(0).getUpper()); 14314 assertEquals(thirdUserTestPackageUid, (int) uids.get(1).getLower()); 14315 assertEquals(thirdUserTestPackageUid, (int) uids.get(1).getUpper()); 14316 } 14317 14318 @Test 14319 public void testOemNetworkRequestFactoryAddsPackagesToCorrectPreference() 14320 throws Exception { 14321 // Expectations 14322 final int expectedNumOfNris = 1; 14323 final int expectedNumOfAppUids = 2; 14324 14325 // Arrange PackageManager mocks 14326 final String testPackageName2 = "com.google.apps.dialer"; 14327 final int testPackageNameUid2 = 456; 14328 mockGetApplicationInfo(TEST_PACKAGE_NAME, TEST_PACKAGE_UID); 14329 mockGetApplicationInfo(testPackageName2, testPackageNameUid2); 14330 14331 // Build OemNetworkPreferences object 14332 final int testOemPref = OEM_NETWORK_PREFERENCE_OEM_PAID; 14333 final OemNetworkPreferences pref = new OemNetworkPreferences.Builder() 14334 .addNetworkPreference(TEST_PACKAGE_NAME, testOemPref) 14335 .addNetworkPreference(testPackageName2, testOemPref) 14336 .build(); 14337 14338 // Act on OemNetworkRequestFactory.createNrisFromOemNetworkPreferences() 14339 final ArraySet<NetworkRequestInfo> nris = 14340 mService.new OemNetworkRequestFactory().createNrisFromOemNetworkPreferences(pref); 14341 14342 assertEquals(expectedNumOfNris, nris.size()); 14343 assertEquals(expectedNumOfAppUids, 14344 nris.iterator().next().mRequests.get(0).networkCapabilities.getUids().size()); 14345 } 14346 14347 @Test 14348 public void testSetOemNetworkPreferenceNullListenerAndPrefParamThrowsNpe() { 14349 mockHasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, true); 14350 14351 // Act on ConnectivityService.setOemNetworkPreference() 14352 assertThrows(NullPointerException.class, 14353 () -> mService.setOemNetworkPreference( 14354 null, 14355 null)); 14356 } 14357 14358 @Test 14359 public void testSetOemNetworkPreferenceFailsForNonAutomotive() 14360 throws Exception { 14361 mockHasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, false); 14362 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 14363 OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY; 14364 14365 // Act on ConnectivityService.setOemNetworkPreference() 14366 assertThrows(UnsupportedOperationException.class, 14367 () -> mService.setOemNetworkPreference( 14368 createDefaultOemNetworkPreferences(networkPref), 14369 null)); 14370 } 14371 14372 @Test 14373 public void testSetOemNetworkPreferenceFailsForTestRequestWithoutPermission() { 14374 // Calling setOemNetworkPreference() with a test pref requires the permission 14375 // MANAGE_TEST_NETWORKS. 14376 mockHasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, false); 14377 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 14378 OEM_NETWORK_PREFERENCE_TEST; 14379 14380 // Act on ConnectivityService.setOemNetworkPreference() 14381 assertThrows(SecurityException.class, 14382 () -> mService.setOemNetworkPreference( 14383 createDefaultOemNetworkPreferences(networkPref), 14384 null)); 14385 } 14386 14387 @Test 14388 public void testSetOemNetworkPreferenceFailsForInvalidTestRequest() { 14389 assertSetOemNetworkPreferenceFailsForInvalidTestRequest(OEM_NETWORK_PREFERENCE_TEST); 14390 } 14391 14392 @Test 14393 public void testSetOemNetworkPreferenceFailsForInvalidTestOnlyRequest() { 14394 assertSetOemNetworkPreferenceFailsForInvalidTestRequest(OEM_NETWORK_PREFERENCE_TEST_ONLY); 14395 } 14396 14397 private void assertSetOemNetworkPreferenceFailsForInvalidTestRequest( 14398 @OemNetworkPreferences.OemNetworkPreference final int oemNetworkPreferenceForTest) { 14399 mockHasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, true); 14400 final String secondPackage = "does.not.matter"; 14401 14402 // A valid test request would only have a single mapping. 14403 final OemNetworkPreferences pref = new OemNetworkPreferences.Builder() 14404 .addNetworkPreference(TEST_PACKAGE_NAME, oemNetworkPreferenceForTest) 14405 .addNetworkPreference(secondPackage, oemNetworkPreferenceForTest) 14406 .build(); 14407 14408 // Act on ConnectivityService.setOemNetworkPreference() 14409 assertThrows(IllegalArgumentException.class, 14410 () -> mService.setOemNetworkPreference(pref, null)); 14411 } 14412 14413 private void setOemNetworkPreferenceAgentConnected(final int transportType, 14414 final boolean connectAgent) throws Exception { 14415 switch(transportType) { 14416 // Corresponds to a metered cellular network. Will be used for the default network. 14417 case TRANSPORT_CELLULAR: 14418 if (!connectAgent) { 14419 mCellAgent.disconnect(); 14420 break; 14421 } 14422 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 14423 mCellAgent.removeCapability(NET_CAPABILITY_NOT_METERED); 14424 mCellAgent.connect(true); 14425 break; 14426 // Corresponds to a restricted ethernet network with OEM_PAID/OEM_PRIVATE. 14427 case TRANSPORT_ETHERNET: 14428 if (!connectAgent) { 14429 stopOemManagedNetwork(); 14430 break; 14431 } 14432 startOemManagedNetwork(true); 14433 break; 14434 // Corresponds to unmetered Wi-Fi. 14435 case TRANSPORT_WIFI: 14436 if (!connectAgent) { 14437 mWiFiAgent.disconnect(); 14438 break; 14439 } 14440 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 14441 mWiFiAgent.addCapability(NET_CAPABILITY_NOT_METERED); 14442 mWiFiAgent.connect(true); 14443 break; 14444 default: 14445 throw new AssertionError("Unsupported transport type passed in."); 14446 14447 } 14448 waitForIdle(); 14449 } 14450 14451 private void startOemManagedNetwork(final boolean isOemPaid) throws Exception { 14452 mEthernetAgent = new TestNetworkAgentWrapper(TRANSPORT_ETHERNET); 14453 mEthernetAgent.addCapability( 14454 isOemPaid ? NET_CAPABILITY_OEM_PAID : NET_CAPABILITY_OEM_PRIVATE); 14455 mEthernetAgent.removeCapability(NET_CAPABILITY_NOT_RESTRICTED); 14456 mEthernetAgent.connect(true); 14457 } 14458 14459 private void stopOemManagedNetwork() { 14460 mEthernetAgent.disconnect(); 14461 waitForIdle(); 14462 } 14463 14464 private void verifyMultipleDefaultNetworksTracksCorrectly( 14465 final int expectedOemRequestsSize, 14466 @NonNull final Network expectedDefaultNetwork, 14467 @NonNull final Network expectedPerAppNetwork) { 14468 // The current test setup assumes two tracked default network requests; one for the default 14469 // network and the other for the OEM network preference being tested. This will be validated 14470 // each time to confirm it doesn't change under test. 14471 final int expectedDefaultNetworkRequestsSize = 2; 14472 assertEquals(expectedDefaultNetworkRequestsSize, mService.mDefaultNetworkRequests.size()); 14473 for (final NetworkRequestInfo defaultRequest : mService.mDefaultNetworkRequests) { 14474 final Network defaultNetwork = defaultRequest.getSatisfier() == null 14475 ? null : defaultRequest.getSatisfier().network(); 14476 // If this is the default request. 14477 if (defaultRequest == mService.mDefaultRequest) { 14478 assertEquals( 14479 expectedDefaultNetwork, 14480 defaultNetwork); 14481 // Make sure this value doesn't change. 14482 assertEquals(1, defaultRequest.mRequests.size()); 14483 continue; 14484 } 14485 assertEquals(expectedPerAppNetwork, defaultNetwork); 14486 assertEquals(expectedOemRequestsSize, defaultRequest.mRequests.size()); 14487 } 14488 verifyMultipleDefaultCallbacks(expectedDefaultNetwork, expectedPerAppNetwork); 14489 } 14490 14491 /** 14492 * Verify default callbacks for 'available' fire as expected. This will only run if 14493 * registerDefaultNetworkCallbacks() was executed prior and will only be different if the 14494 * setOemNetworkPreference() per-app API was used for the current process. 14495 * @param expectedSystemDefault the expected network for the system default. 14496 * @param expectedPerAppDefault the expected network for the current process's default. 14497 */ 14498 private void verifyMultipleDefaultCallbacks( 14499 @NonNull final Network expectedSystemDefault, 14500 @NonNull final Network expectedPerAppDefault) { 14501 if (null != mSystemDefaultNetworkCallback && null != expectedSystemDefault 14502 && mService.mNoServiceNetwork.network() != expectedSystemDefault) { 14503 // getLastAvailableNetwork() is used as this method can be called successively with 14504 // the same network to validate therefore expectAvailableThenValidatedCallbacks 14505 // can't be used. 14506 assertEquals(mSystemDefaultNetworkCallback.getLastAvailableNetwork(), 14507 expectedSystemDefault); 14508 } 14509 if (null != mDefaultNetworkCallback && null != expectedPerAppDefault 14510 && mService.mNoServiceNetwork.network() != expectedPerAppDefault) { 14511 assertEquals(mDefaultNetworkCallback.getLastAvailableNetwork(), 14512 expectedPerAppDefault); 14513 } 14514 } 14515 14516 private void registerDefaultNetworkCallbacks() { 14517 if (mSystemDefaultNetworkCallback != null || mDefaultNetworkCallback != null 14518 || mProfileDefaultNetworkCallback != null 14519 || mProfileDefaultNetworkCallbackAsAppUid2 != null 14520 || mTestPackageDefaultNetworkCallback2 != null 14521 || mTestPackageDefaultNetworkCallback != null) { 14522 throw new IllegalStateException("Default network callbacks already registered"); 14523 } 14524 14525 mSystemDefaultNetworkCallback = new TestNetworkCallback(); 14526 mDefaultNetworkCallback = new TestNetworkCallback(); 14527 mProfileDefaultNetworkCallback = new TestNetworkCallback(); 14528 mTestPackageDefaultNetworkCallback = new TestNetworkCallback(); 14529 mProfileDefaultNetworkCallbackAsAppUid2 = new TestNetworkCallback(); 14530 mTestPackageDefaultNetworkCallback2 = new TestNetworkCallback(); 14531 mCm.registerSystemDefaultNetworkCallback(mSystemDefaultNetworkCallback, 14532 new Handler(ConnectivityThread.getInstanceLooper())); 14533 mCm.registerDefaultNetworkCallback(mDefaultNetworkCallback); 14534 registerDefaultNetworkCallbackAsUid(mProfileDefaultNetworkCallback, 14535 TEST_WORK_PROFILE_APP_UID); 14536 registerDefaultNetworkCallbackAsUid(mTestPackageDefaultNetworkCallback, TEST_PACKAGE_UID); 14537 registerDefaultNetworkCallbackAsUid(mProfileDefaultNetworkCallbackAsAppUid2, 14538 TEST_WORK_PROFILE_APP_UID_2); 14539 registerDefaultNetworkCallbackAsUid(mTestPackageDefaultNetworkCallback2, 14540 TEST_PACKAGE_UID2); 14541 // TODO: test using ConnectivityManager#registerDefaultNetworkCallbackAsUid as well. 14542 mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_DENIED); 14543 } 14544 14545 private void unregisterDefaultNetworkCallbacks() { 14546 if (null != mDefaultNetworkCallback) { 14547 mCm.unregisterNetworkCallback(mDefaultNetworkCallback); 14548 } 14549 if (null != mSystemDefaultNetworkCallback) { 14550 mCm.unregisterNetworkCallback(mSystemDefaultNetworkCallback); 14551 } 14552 if (null != mProfileDefaultNetworkCallback) { 14553 mCm.unregisterNetworkCallback(mProfileDefaultNetworkCallback); 14554 } 14555 if (null != mTestPackageDefaultNetworkCallback) { 14556 mCm.unregisterNetworkCallback(mTestPackageDefaultNetworkCallback); 14557 } 14558 if (null != mProfileDefaultNetworkCallbackAsAppUid2) { 14559 mCm.unregisterNetworkCallback(mProfileDefaultNetworkCallbackAsAppUid2); 14560 } 14561 if (null != mTestPackageDefaultNetworkCallback2) { 14562 mCm.unregisterNetworkCallback(mTestPackageDefaultNetworkCallback2); 14563 } 14564 mSystemDefaultNetworkCallback = null; 14565 mDefaultNetworkCallback = null; 14566 mProfileDefaultNetworkCallback = null; 14567 mTestPackageDefaultNetworkCallback = null; 14568 mProfileDefaultNetworkCallbackAsAppUid2 = null; 14569 mTestPackageDefaultNetworkCallback2 = null; 14570 } 14571 14572 private void setupMultipleDefaultNetworksForOemNetworkPreferenceNotCurrentUidTest( 14573 @OemNetworkPreferences.OemNetworkPreference final int networkPrefToSetup) 14574 throws Exception { 14575 final int testPackageNameUid = TEST_PACKAGE_UID; 14576 final String testPackageName = "per.app.defaults.package"; 14577 setupMultipleDefaultNetworksForOemNetworkPreferenceTest( 14578 networkPrefToSetup, testPackageNameUid, testPackageName); 14579 } 14580 14581 private void setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest( 14582 @OemNetworkPreferences.OemNetworkPreference final int networkPrefToSetup) 14583 throws Exception { 14584 final int testPackageNameUid = Process.myUid(); 14585 final String testPackageName = "per.app.defaults.package"; 14586 setupMultipleDefaultNetworksForOemNetworkPreferenceTest( 14587 networkPrefToSetup, testPackageNameUid, testPackageName); 14588 } 14589 14590 private void setupMultipleDefaultNetworksForOemNetworkPreferenceTest( 14591 @OemNetworkPreferences.OemNetworkPreference final int networkPrefToSetup, 14592 final int testPackageUid, @NonNull final String testPackageName) throws Exception { 14593 // Only the default request should be included at start. 14594 assertEquals(1, mService.mDefaultNetworkRequests.size()); 14595 14596 final UidRangeParcel[] uidRanges = 14597 toUidRangeStableParcels(uidRangesForUids(testPackageUid)); 14598 setupSetOemNetworkPreferenceForPreferenceTest( 14599 networkPrefToSetup, uidRanges, testPackageName); 14600 } 14601 14602 private void setupSetOemNetworkPreferenceForPreferenceTest( 14603 @OemNetworkPreferences.OemNetworkPreference final int networkPrefToSetup, 14604 @NonNull final UidRangeParcel[] uidRanges, 14605 @NonNull final String testPackageName) throws Exception { 14606 setupSetOemNetworkPreferenceForPreferenceTest(networkPrefToSetup, uidRanges, 14607 testPackageName, PRIMARY_USER_HANDLE, true /* hasAutomotiveFeature */); 14608 } 14609 14610 private void setupSetOemNetworkPreferenceForPreferenceTest( 14611 @OemNetworkPreferences.OemNetworkPreference final int networkPrefToSetup, 14612 @NonNull final UidRangeParcel[] uidRanges, 14613 @NonNull final String testPackageName, 14614 @NonNull final UserHandle user) throws Exception { 14615 setupSetOemNetworkPreferenceForPreferenceTest(networkPrefToSetup, uidRanges, 14616 testPackageName, user, true /* hasAutomotiveFeature */); 14617 } 14618 14619 private void setupSetOemNetworkPreferenceForPreferenceTest( 14620 @OemNetworkPreferences.OemNetworkPreference final int networkPrefToSetup, 14621 @NonNull final UidRangeParcel[] uidRanges, 14622 @NonNull final String testPackageName, 14623 @NonNull final UserHandle user, 14624 final boolean hasAutomotiveFeature) throws Exception { 14625 mockHasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, hasAutomotiveFeature); 14626 14627 // These tests work off a single UID therefore using 'start' is valid. 14628 mockGetApplicationInfo(testPackageName, uidRanges[0].start, user); 14629 14630 setOemNetworkPreference(networkPrefToSetup, testPackageName); 14631 } 14632 14633 private void setOemNetworkPreference(final int networkPrefToSetup, 14634 @NonNull final String... testPackageNames) 14635 throws Exception { 14636 mockHasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, true); 14637 14638 // Build OemNetworkPreferences object 14639 final OemNetworkPreferences.Builder builder = new OemNetworkPreferences.Builder(); 14640 for (final String packageName : testPackageNames) { 14641 builder.addNetworkPreference(packageName, networkPrefToSetup); 14642 } 14643 final OemNetworkPreferences pref = builder.build(); 14644 14645 // Act on ConnectivityService.setOemNetworkPreference() 14646 final TestOemListenerCallback oemPrefListener = new TestOemListenerCallback(); 14647 mService.setOemNetworkPreference(pref, oemPrefListener); 14648 14649 // Verify call returned successfully 14650 oemPrefListener.expectOnComplete(); 14651 } 14652 14653 private static class TestOemListenerCallback implements IOnCompleteListener { 14654 final CompletableFuture<Object> mDone = new CompletableFuture<>(); 14655 14656 @Override 14657 public void onComplete() { 14658 mDone.complete(new Object()); 14659 } 14660 14661 void expectOnComplete() { 14662 try { 14663 mDone.get(TIMEOUT_MS, TimeUnit.MILLISECONDS); 14664 } catch (TimeoutException e) { 14665 fail("Expected onComplete() not received after " + TIMEOUT_MS + " ms"); 14666 } catch (Exception e) { 14667 fail(e.getMessage()); 14668 } 14669 } 14670 14671 @Override 14672 public IBinder asBinder() { 14673 return null; 14674 } 14675 } 14676 14677 @Test 14678 public void testMultiDefaultGetActiveNetworkIsCorrect() throws Exception { 14679 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 14680 OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY; 14681 final int expectedOemPrefRequestSize = 1; 14682 registerDefaultNetworkCallbacks(); 14683 14684 // Setup the test process to use networkPref for their default network. 14685 setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest(networkPref); 14686 14687 // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID. 14688 // The active network for the default should be null at this point as this is a retricted 14689 // network. 14690 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true); 14691 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 14692 null, 14693 mEthernetAgent.getNetwork()); 14694 14695 // Verify that the active network is correct 14696 verifyActiveNetwork(TRANSPORT_ETHERNET); 14697 // default NCs will be unregistered in tearDown 14698 } 14699 14700 @Test 14701 public void testMultiDefaultIsActiveNetworkMeteredIsCorrect() throws Exception { 14702 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 14703 OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY; 14704 final int expectedOemPrefRequestSize = 1; 14705 registerDefaultNetworkCallbacks(); 14706 14707 // Setup the test process to use networkPref for their default network. 14708 setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest(networkPref); 14709 14710 // Returns true by default when no network is available. 14711 assertTrue(mCm.isActiveNetworkMetered()); 14712 14713 // Connect to an unmetered restricted network that will only be available to the OEM pref. 14714 mEthernetAgent = new TestNetworkAgentWrapper(TRANSPORT_ETHERNET); 14715 mEthernetAgent.addCapability(NET_CAPABILITY_OEM_PAID); 14716 mEthernetAgent.addCapability(NET_CAPABILITY_NOT_METERED); 14717 mEthernetAgent.removeCapability(NET_CAPABILITY_NOT_RESTRICTED); 14718 mEthernetAgent.connect(true); 14719 waitForIdle(); 14720 14721 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 14722 null, 14723 mEthernetAgent.getNetwork()); 14724 14725 assertFalse(mCm.isActiveNetworkMetered()); 14726 // default NCs will be unregistered in tearDown 14727 } 14728 14729 @Test 14730 public void testPerAppDefaultRegisterDefaultNetworkCallback() throws Exception { 14731 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 14732 OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY; 14733 final int expectedOemPrefRequestSize = 1; 14734 final TestNetworkCallback defaultNetworkCallback = new TestNetworkCallback(); 14735 14736 // Register the default network callback before the pref is already set. This means that 14737 // the policy will be applied to the callback on setOemNetworkPreference(). 14738 mCm.registerDefaultNetworkCallback(defaultNetworkCallback); 14739 defaultNetworkCallback.assertNoCallback(); 14740 14741 final TestNetworkCallback otherUidDefaultCallback = new TestNetworkCallback(); 14742 withPermission(NETWORK_SETTINGS, () -> 14743 mCm.registerDefaultNetworkCallbackForUid(TEST_PACKAGE_UID, otherUidDefaultCallback, 14744 new Handler(ConnectivityThread.getInstanceLooper()))); 14745 14746 // Setup the test process to use networkPref for their default network. 14747 setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest(networkPref); 14748 14749 // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID. 14750 // The active nai for the default is null at this point as this is a restricted network. 14751 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true); 14752 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 14753 null, 14754 mEthernetAgent.getNetwork()); 14755 14756 // At this point with a restricted network used, the available callback should trigger. 14757 defaultNetworkCallback.expectAvailableThenValidatedCallbacks(mEthernetAgent); 14758 assertEquals(defaultNetworkCallback.getLastAvailableNetwork(), mEthernetAgent.getNetwork()); 14759 otherUidDefaultCallback.assertNoCallback(); 14760 14761 // Now bring down the default network which should trigger a LOST callback. 14762 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, false); 14763 14764 // At this point, with no network is available, the lost callback should trigger 14765 defaultNetworkCallback.expect(LOST, mEthernetAgent); 14766 otherUidDefaultCallback.assertNoCallback(); 14767 14768 // Confirm we can unregister without issues. 14769 mCm.unregisterNetworkCallback(defaultNetworkCallback); 14770 mCm.unregisterNetworkCallback(otherUidDefaultCallback); 14771 } 14772 14773 @Test 14774 public void testPerAppDefaultRegisterDefaultNetworkCallbackAfterPrefSet() throws Exception { 14775 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 14776 OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY; 14777 final int expectedOemPrefRequestSize = 1; 14778 final TestNetworkCallback defaultNetworkCallback = new TestNetworkCallback(); 14779 14780 // Setup the test process to use networkPref for their default network. 14781 setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest(networkPref); 14782 14783 // Register the default network callback after the pref is already set. This means that 14784 // the policy will be applied to the callback on requestNetwork(). 14785 mCm.registerDefaultNetworkCallback(defaultNetworkCallback); 14786 defaultNetworkCallback.assertNoCallback(); 14787 14788 final TestNetworkCallback otherUidDefaultCallback = new TestNetworkCallback(); 14789 withPermission(NETWORK_SETTINGS, () -> 14790 mCm.registerDefaultNetworkCallbackForUid(TEST_PACKAGE_UID, otherUidDefaultCallback, 14791 new Handler(ConnectivityThread.getInstanceLooper()))); 14792 14793 // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID. 14794 // The active nai for the default is null at this point as this is a restricted network. 14795 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true); 14796 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 14797 null, 14798 mEthernetAgent.getNetwork()); 14799 14800 // At this point with a restricted network used, the available callback should trigger 14801 defaultNetworkCallback.expectAvailableThenValidatedCallbacks(mEthernetAgent); 14802 assertEquals(defaultNetworkCallback.getLastAvailableNetwork(), mEthernetAgent.getNetwork()); 14803 otherUidDefaultCallback.assertNoCallback(); 14804 14805 // Now bring down the default network which should trigger a LOST callback. 14806 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, false); 14807 otherUidDefaultCallback.assertNoCallback(); 14808 14809 // At this point, with no network is available, the lost callback should trigger 14810 defaultNetworkCallback.expect(LOST, mEthernetAgent); 14811 otherUidDefaultCallback.assertNoCallback(); 14812 14813 // Confirm we can unregister without issues. 14814 mCm.unregisterNetworkCallback(defaultNetworkCallback); 14815 mCm.unregisterNetworkCallback(otherUidDefaultCallback); 14816 } 14817 14818 @Test 14819 public void testPerAppDefaultRegisterDefaultNetworkCallbackDoesNotFire() throws Exception { 14820 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 14821 OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY; 14822 final int expectedOemPrefRequestSize = 1; 14823 final TestNetworkCallback defaultNetworkCallback = new TestNetworkCallback(); 14824 final int userId = UserHandle.getUserId(Process.myUid()); 14825 14826 mCm.registerDefaultNetworkCallback(defaultNetworkCallback); 14827 defaultNetworkCallback.assertNoCallback(); 14828 14829 final TestNetworkCallback otherUidDefaultCallback = new TestNetworkCallback(); 14830 withPermission(NETWORK_SETTINGS, () -> 14831 mCm.registerDefaultNetworkCallbackForUid(TEST_PACKAGE_UID, otherUidDefaultCallback, 14832 new Handler(ConnectivityThread.getInstanceLooper()))); 14833 14834 // Setup a process different than the test process to use the default network. This means 14835 // that the defaultNetworkCallback won't be tracked by the per-app policy. 14836 setupMultipleDefaultNetworksForOemNetworkPreferenceNotCurrentUidTest(networkPref); 14837 14838 // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID. 14839 // The active nai for the default is null at this point as this is a restricted network. 14840 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true); 14841 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 14842 null, 14843 mEthernetAgent.getNetwork()); 14844 14845 // As this callback does not have access to the OEM_PAID network, it will not fire. 14846 defaultNetworkCallback.assertNoCallback(); 14847 assertDefaultNetworkCapabilities(userId /* no networks */); 14848 14849 // The other UID does have access, and gets a callback. 14850 otherUidDefaultCallback.expectAvailableThenValidatedCallbacks(mEthernetAgent); 14851 14852 // Bring up unrestricted cellular. This should now satisfy the default network. 14853 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); 14854 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 14855 mCellAgent.getNetwork(), 14856 mEthernetAgent.getNetwork()); 14857 14858 // At this point with an unrestricted network used, the available callback should trigger 14859 // The other UID is unaffected and remains on the paid network. 14860 defaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 14861 assertEquals(defaultNetworkCallback.getLastAvailableNetwork(), mCellAgent.getNetwork()); 14862 assertDefaultNetworkCapabilities(userId, mCellAgent); 14863 otherUidDefaultCallback.assertNoCallback(); 14864 14865 // Now bring down the per-app network. 14866 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, false); 14867 14868 // Since the callback didn't use the per-app network, only the other UID gets a callback. 14869 // Because the preference specifies no fallback, it does not switch to cellular. 14870 defaultNetworkCallback.assertNoCallback(); 14871 otherUidDefaultCallback.expect(LOST, mEthernetAgent); 14872 14873 // Now bring down the default network. 14874 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, false); 14875 14876 // As this callback was tracking the default, this should now trigger. 14877 defaultNetworkCallback.expect(LOST, mCellAgent); 14878 otherUidDefaultCallback.assertNoCallback(); 14879 14880 // Confirm we can unregister without issues. 14881 mCm.unregisterNetworkCallback(defaultNetworkCallback); 14882 mCm.unregisterNetworkCallback(otherUidDefaultCallback); 14883 } 14884 14885 /** 14886 * This method assumes that the same uidRanges input will be used to verify that dependencies 14887 * are called as expected. 14888 */ 14889 private void verifySetOemNetworkPreferenceForPreference( 14890 @NonNull final UidRangeParcel[] uidRanges, 14891 final int addUidRangesNetId, 14892 final int addUidRangesTimes, 14893 final int removeUidRangesNetId, 14894 final int removeUidRangesTimes, 14895 final boolean shouldDestroyNetwork) throws RemoteException { 14896 verifySetOemNetworkPreferenceForPreference(uidRanges, uidRanges, 14897 addUidRangesNetId, addUidRangesTimes, removeUidRangesNetId, removeUidRangesTimes, 14898 shouldDestroyNetwork); 14899 } 14900 14901 private void verifySetOemNetworkPreferenceForPreference( 14902 @NonNull final UidRangeParcel[] addedUidRanges, 14903 @NonNull final UidRangeParcel[] removedUidRanges, 14904 final int addUidRangesNetId, 14905 final int addUidRangesTimes, 14906 final int removeUidRangesNetId, 14907 final int removeUidRangesTimes, 14908 final boolean shouldDestroyNetwork) throws RemoteException { 14909 final boolean useAnyIdForAdd = OEM_PREF_ANY_NET_ID == addUidRangesNetId; 14910 final boolean useAnyIdForRemove = OEM_PREF_ANY_NET_ID == removeUidRangesNetId; 14911 14912 // Validate that add/remove uid range (with oem priority) to/from netd. 14913 verify(mMockNetd, times(addUidRangesTimes)).networkAddUidRangesParcel(argThat(config -> 14914 (useAnyIdForAdd ? true : addUidRangesNetId == config.netId) 14915 && Arrays.equals(addedUidRanges, config.uidRanges) 14916 && PREFERENCE_ORDER_OEM == config.subPriority)); 14917 verify(mMockNetd, times(removeUidRangesTimes)).networkRemoveUidRangesParcel( 14918 argThat(config -> (useAnyIdForRemove ? true : removeUidRangesNetId == config.netId) 14919 && Arrays.equals(removedUidRanges, config.uidRanges) 14920 && PREFERENCE_ORDER_OEM == config.subPriority)); 14921 if (shouldDestroyNetwork) { 14922 verify(mMockNetd, times(1)) 14923 .networkDestroy((useAnyIdForRemove ? anyInt() : eq(removeUidRangesNetId))); 14924 } 14925 reset(mMockNetd); 14926 } 14927 14928 /** 14929 * Test the tracked default requests allows test requests without standard setup. 14930 */ 14931 @Test 14932 public void testSetOemNetworkPreferenceAllowsValidTestRequestWithoutChecks() throws Exception { 14933 @OemNetworkPreferences.OemNetworkPreference int networkPref = 14934 OEM_NETWORK_PREFERENCE_TEST; 14935 validateSetOemNetworkPreferenceAllowsValidTestPrefRequest(networkPref); 14936 } 14937 14938 /** 14939 * Test the tracked default requests allows test only requests without standard setup. 14940 */ 14941 @Test 14942 public void testSetOemNetworkPreferenceAllowsValidTestOnlyRequestWithoutChecks() 14943 throws Exception { 14944 @OemNetworkPreferences.OemNetworkPreference int networkPref = 14945 OEM_NETWORK_PREFERENCE_TEST_ONLY; 14946 validateSetOemNetworkPreferenceAllowsValidTestPrefRequest(networkPref); 14947 } 14948 14949 private void validateSetOemNetworkPreferenceAllowsValidTestPrefRequest(int networkPref) 14950 throws Exception { 14951 // The caller must have the MANAGE_TEST_NETWORKS permission. 14952 final int testPackageUid = 123; 14953 final String validTestPackageName = "does.not.matter"; 14954 final UidRangeParcel[] uidRanges = 14955 toUidRangeStableParcels(uidRangesForUids(testPackageUid)); 14956 mServiceContext.setPermission( 14957 Manifest.permission.MANAGE_TEST_NETWORKS, PERMISSION_GRANTED); 14958 14959 // Put the system into a state in which setOemNetworkPreference() would normally fail. This 14960 // will confirm that a valid test request can bypass these checks. 14961 mockHasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, false); 14962 mServiceContext.setPermission( 14963 Manifest.permission.CONTROL_OEM_PAID_NETWORK_PREFERENCE, PERMISSION_DENIED); 14964 14965 // Validate the starting requests only includes the system default request. 14966 assertEquals(1, mService.mDefaultNetworkRequests.size()); 14967 14968 // Add an OEM default network request to track. 14969 setupSetOemNetworkPreferenceForPreferenceTest( 14970 networkPref, uidRanges, validTestPackageName, PRIMARY_USER_HANDLE, 14971 false /* hasAutomotiveFeature */); 14972 14973 // Two requests should now exist; the system default and the test request. 14974 assertEquals(2, mService.mDefaultNetworkRequests.size()); 14975 } 14976 14977 /** 14978 * Test the tracked default requests clear previous OEM requests on setOemNetworkPreference(). 14979 */ 14980 @Test 14981 public void testSetOemNetworkPreferenceClearPreviousOemValues() throws Exception { 14982 @OemNetworkPreferences.OemNetworkPreference int networkPref = 14983 OEM_NETWORK_PREFERENCE_OEM_PAID; 14984 final int testPackageUid = 123; 14985 final String testPackageName = "com.google.apps.contacts"; 14986 final UidRangeParcel[] uidRanges = 14987 toUidRangeStableParcels(uidRangesForUids(testPackageUid)); 14988 14989 // Validate the starting requests only includes the system default request. 14990 assertEquals(1, mService.mDefaultNetworkRequests.size()); 14991 14992 // Add an OEM default network request to track. 14993 setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges, testPackageName); 14994 14995 // Two requests should exist, one for the fallback and one for the pref. 14996 assertEquals(2, mService.mDefaultNetworkRequests.size()); 14997 14998 networkPref = OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY; 14999 setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges, testPackageName); 15000 15001 // Two requests should still exist validating the previous per-app request was replaced. 15002 assertEquals(2, mService.mDefaultNetworkRequests.size()); 15003 } 15004 15005 /** 15006 * Test network priority for preference OEM_NETWORK_PREFERENCE_OEM_PAID in the following order: 15007 * NET_CAPABILITY_NOT_METERED -> NET_CAPABILITY_OEM_PAID -> fallback 15008 */ 15009 @Test 15010 public void testMultilayerForPreferenceOemPaidEvaluatesCorrectly() 15011 throws Exception { 15012 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 15013 OEM_NETWORK_PREFERENCE_OEM_PAID; 15014 15015 // Arrange PackageManager mocks 15016 final UidRangeParcel[] uidRanges = 15017 toUidRangeStableParcels(uidRangesForUids(TEST_PACKAGE_UID)); 15018 setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges, TEST_PACKAGE_NAME); 15019 15020 // Verify the starting state. No networks should be connected. 15021 verifySetOemNetworkPreferenceForPreference(uidRanges, 15022 OEM_PREF_ANY_NET_ID, 0 /* times */, 15023 OEM_PREF_ANY_NET_ID, 0 /* times */, 15024 false /* shouldDestroyNetwork */); 15025 15026 // Test lowest to highest priority requests. 15027 // Bring up metered cellular. This will satisfy the fallback network. 15028 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); 15029 verifySetOemNetworkPreferenceForPreference(uidRanges, 15030 mCellAgent.getNetwork().netId, 1 /* times */, 15031 OEM_PREF_ANY_NET_ID, 0 /* times */, 15032 false /* shouldDestroyNetwork */); 15033 15034 // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID. 15035 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true); 15036 verifySetOemNetworkPreferenceForPreference(uidRanges, 15037 mEthernetAgent.getNetwork().netId, 1 /* times */, 15038 mCellAgent.getNetwork().netId, 1 /* times */, 15039 false /* shouldDestroyNetwork */); 15040 15041 // Bring up unmetered Wi-Fi. This will satisfy NET_CAPABILITY_NOT_METERED. 15042 setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, true); 15043 verifySetOemNetworkPreferenceForPreference(uidRanges, 15044 mWiFiAgent.getNetwork().netId, 1 /* times */, 15045 mEthernetAgent.getNetwork().netId, 1 /* times */, 15046 false /* shouldDestroyNetwork */); 15047 15048 // Disconnecting OEM_PAID should have no effect as it is lower in priority then unmetered. 15049 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, false); 15050 // netd should not be called as default networks haven't changed. 15051 verifySetOemNetworkPreferenceForPreference(uidRanges, 15052 OEM_PREF_ANY_NET_ID, 0 /* times */, 15053 OEM_PREF_ANY_NET_ID, 0 /* times */, 15054 false /* shouldDestroyNetwork */); 15055 15056 // Disconnecting unmetered should put PANS on lowest priority fallback request. 15057 setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, false); 15058 verifySetOemNetworkPreferenceForPreference(uidRanges, 15059 mCellAgent.getNetwork().netId, 1 /* times */, 15060 mWiFiAgent.getNetwork().netId, 0 /* times */, 15061 true /* shouldDestroyNetwork */); 15062 15063 // Disconnecting the fallback network should result in no connectivity. 15064 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, false); 15065 verifySetOemNetworkPreferenceForPreference(uidRanges, 15066 OEM_PREF_ANY_NET_ID, 0 /* times */, 15067 mCellAgent.getNetwork().netId, 0 /* times */, 15068 true /* shouldDestroyNetwork */); 15069 } 15070 15071 /** 15072 * Test network priority for OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK in the following order: 15073 * NET_CAPABILITY_NOT_METERED -> NET_CAPABILITY_OEM_PAID 15074 */ 15075 @Test 15076 public void testMultilayerForPreferenceOemPaidNoFallbackEvaluatesCorrectly() 15077 throws Exception { 15078 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 15079 OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK; 15080 15081 // Arrange PackageManager mocks 15082 final UidRangeParcel[] uidRanges = 15083 toUidRangeStableParcels(uidRangesForUids(TEST_PACKAGE_UID)); 15084 setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges, TEST_PACKAGE_NAME); 15085 15086 // Verify the starting state. This preference doesn't support using the fallback network 15087 // therefore should be on the disconnected network as it has no networks to connect to. 15088 verifySetOemNetworkPreferenceForPreference(uidRanges, 15089 mService.mNoServiceNetwork.network.getNetId(), 1 /* times */, 15090 OEM_PREF_ANY_NET_ID, 0 /* times */, 15091 false /* shouldDestroyNetwork */); 15092 15093 // Test lowest to highest priority requests. 15094 // Bring up metered cellular. This will satisfy the fallback network. 15095 // This preference should not use this network as it doesn't support fallback usage. 15096 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); 15097 verifySetOemNetworkPreferenceForPreference(uidRanges, 15098 OEM_PREF_ANY_NET_ID, 0 /* times */, 15099 OEM_PREF_ANY_NET_ID, 0 /* times */, 15100 false /* shouldDestroyNetwork */); 15101 15102 // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID. 15103 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true); 15104 verifySetOemNetworkPreferenceForPreference(uidRanges, 15105 mEthernetAgent.getNetwork().netId, 1 /* times */, 15106 mService.mNoServiceNetwork.network.getNetId(), 1 /* times */, 15107 false /* shouldDestroyNetwork */); 15108 15109 // Bring up unmetered Wi-Fi. This will satisfy NET_CAPABILITY_NOT_METERED. 15110 setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, true); 15111 verifySetOemNetworkPreferenceForPreference(uidRanges, 15112 mWiFiAgent.getNetwork().netId, 1 /* times */, 15113 mEthernetAgent.getNetwork().netId, 1 /* times */, 15114 false /* shouldDestroyNetwork */); 15115 15116 // Disconnecting unmetered should put PANS on OEM_PAID. 15117 setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, false); 15118 verifySetOemNetworkPreferenceForPreference(uidRanges, 15119 mEthernetAgent.getNetwork().netId, 1 /* times */, 15120 mWiFiAgent.getNetwork().netId, 0 /* times */, 15121 true /* shouldDestroyNetwork */); 15122 15123 // Disconnecting OEM_PAID should result in no connectivity. 15124 // OEM_PAID_NO_FALLBACK not supporting a fallback now uses the disconnected network. 15125 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, false); 15126 verifySetOemNetworkPreferenceForPreference(uidRanges, 15127 mService.mNoServiceNetwork.network.getNetId(), 1 /* times */, 15128 mEthernetAgent.getNetwork().netId, 0 /* times */, 15129 true /* shouldDestroyNetwork */); 15130 } 15131 15132 /** 15133 * Test network priority for OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY in the following order: 15134 * NET_CAPABILITY_OEM_PAID 15135 * This preference should only apply to OEM_PAID networks. 15136 */ 15137 @Test 15138 public void testMultilayerForPreferenceOemPaidOnlyEvaluatesCorrectly() 15139 throws Exception { 15140 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 15141 OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY; 15142 15143 // Arrange PackageManager mocks 15144 final UidRangeParcel[] uidRanges = 15145 toUidRangeStableParcels(uidRangesForUids(TEST_PACKAGE_UID)); 15146 setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges, TEST_PACKAGE_NAME); 15147 15148 // Verify the starting state. This preference doesn't support using the fallback network 15149 // therefore should be on the disconnected network as it has no networks to connect to. 15150 verifySetOemNetworkPreferenceForPreference(uidRanges, 15151 mService.mNoServiceNetwork.network.getNetId(), 1 /* times */, 15152 OEM_PREF_ANY_NET_ID, 0 /* times */, 15153 false /* shouldDestroyNetwork */); 15154 15155 // Bring up metered cellular. This should not apply to this preference. 15156 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); 15157 verifySetOemNetworkPreferenceForPreference(uidRanges, 15158 OEM_PREF_ANY_NET_ID, 0 /* times */, 15159 OEM_PREF_ANY_NET_ID, 0 /* times */, 15160 false /* shouldDestroyNetwork */); 15161 15162 // Bring up unmetered Wi-Fi. This should not apply to this preference. 15163 setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, true); 15164 verifySetOemNetworkPreferenceForPreference(uidRanges, 15165 OEM_PREF_ANY_NET_ID, 0 /* times */, 15166 OEM_PREF_ANY_NET_ID, 0 /* times */, 15167 false /* shouldDestroyNetwork */); 15168 15169 // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID. 15170 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true); 15171 verifySetOemNetworkPreferenceForPreference(uidRanges, 15172 mEthernetAgent.getNetwork().netId, 1 /* times */, 15173 mService.mNoServiceNetwork.network.getNetId(), 1 /* times */, 15174 false /* shouldDestroyNetwork */); 15175 15176 // Disconnecting OEM_PAID should result in no connectivity. 15177 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, false); 15178 verifySetOemNetworkPreferenceForPreference(uidRanges, 15179 mService.mNoServiceNetwork.network.getNetId(), 1 /* times */, 15180 mEthernetAgent.getNetwork().netId, 0 /* times */, 15181 true /* shouldDestroyNetwork */); 15182 } 15183 15184 /** 15185 * Test network priority for OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY in the following order: 15186 * NET_CAPABILITY_OEM_PRIVATE 15187 * This preference should only apply to OEM_PRIVATE networks. 15188 */ 15189 @Test 15190 public void testMultilayerForPreferenceOemPrivateOnlyEvaluatesCorrectly() 15191 throws Exception { 15192 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 15193 OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY; 15194 15195 // Arrange PackageManager mocks 15196 final UidRangeParcel[] uidRanges = 15197 toUidRangeStableParcels(uidRangesForUids(TEST_PACKAGE_UID)); 15198 setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges, TEST_PACKAGE_NAME); 15199 15200 // Verify the starting state. This preference doesn't support using the fallback network 15201 // therefore should be on the disconnected network as it has no networks to connect to. 15202 verifySetOemNetworkPreferenceForPreference(uidRanges, 15203 mService.mNoServiceNetwork.network.getNetId(), 1 /* times */, 15204 OEM_PREF_ANY_NET_ID, 0 /* times */, 15205 false /* shouldDestroyNetwork */); 15206 15207 // Bring up metered cellular. This should not apply to this preference. 15208 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); 15209 verifySetOemNetworkPreferenceForPreference(uidRanges, 15210 OEM_PREF_ANY_NET_ID, 0 /* times */, 15211 OEM_PREF_ANY_NET_ID, 0 /* times */, 15212 false /* shouldDestroyNetwork */); 15213 15214 // Bring up unmetered Wi-Fi. This should not apply to this preference. 15215 setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, true); 15216 verifySetOemNetworkPreferenceForPreference(uidRanges, 15217 OEM_PREF_ANY_NET_ID, 0 /* times */, 15218 OEM_PREF_ANY_NET_ID, 0 /* times */, 15219 false /* shouldDestroyNetwork */); 15220 15221 // Bring up ethernet with OEM_PRIVATE. This will satisfy NET_CAPABILITY_OEM_PRIVATE. 15222 startOemManagedNetwork(false); 15223 verifySetOemNetworkPreferenceForPreference(uidRanges, 15224 mEthernetAgent.getNetwork().netId, 1 /* times */, 15225 mService.mNoServiceNetwork.network.getNetId(), 1 /* times */, 15226 false /* shouldDestroyNetwork */); 15227 15228 // Disconnecting OEM_PRIVATE should result in no connectivity. 15229 stopOemManagedNetwork(); 15230 verifySetOemNetworkPreferenceForPreference(uidRanges, 15231 mService.mNoServiceNetwork.network.getNetId(), 1 /* times */, 15232 mEthernetAgent.getNetwork().netId, 0 /* times */, 15233 true /* shouldDestroyNetwork */); 15234 } 15235 15236 @Test 15237 public void testMultilayerForMultipleUsersEvaluatesCorrectly() 15238 throws Exception { 15239 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 15240 OEM_NETWORK_PREFERENCE_OEM_PAID; 15241 15242 // Arrange users 15243 final int secondUser = 10; 15244 final UserHandle secondUserHandle = new UserHandle(secondUser); 15245 doReturn(asList(PRIMARY_USER_HANDLE, secondUserHandle)).when(mUserManager) 15246 .getUserHandles(anyBoolean()); 15247 15248 // Arrange PackageManager mocks 15249 final int secondUserTestPackageUid = UserHandle.getUid(secondUser, TEST_PACKAGE_UID); 15250 final UidRangeParcel[] uidRanges = 15251 toUidRangeStableParcels( 15252 uidRangesForUids(TEST_PACKAGE_UID, secondUserTestPackageUid)); 15253 mockGetApplicationInfo(TEST_PACKAGE_NAME, secondUserTestPackageUid, secondUserHandle); 15254 setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges, TEST_PACKAGE_NAME); 15255 15256 // Verify the starting state. No networks should be connected. 15257 verifySetOemNetworkPreferenceForPreference(uidRanges, 15258 OEM_PREF_ANY_NET_ID, 0 /* times */, 15259 OEM_PREF_ANY_NET_ID, 0 /* times */, 15260 false /* shouldDestroyNetwork */); 15261 15262 // Test that we correctly add the expected values for multiple users. 15263 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); 15264 verifySetOemNetworkPreferenceForPreference(uidRanges, 15265 mCellAgent.getNetwork().netId, 1 /* times */, 15266 OEM_PREF_ANY_NET_ID, 0 /* times */, 15267 false /* shouldDestroyNetwork */); 15268 15269 // Test that we correctly remove the expected values for multiple users. 15270 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, false); 15271 verifySetOemNetworkPreferenceForPreference(uidRanges, 15272 OEM_PREF_ANY_NET_ID, 0 /* times */, 15273 mCellAgent.getNetwork().netId, 0 /* times */, 15274 true /* shouldDestroyNetwork */); 15275 } 15276 15277 @Test 15278 public void testMultilayerForBroadcastedUsersEvaluatesCorrectly() 15279 throws Exception { 15280 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 15281 OEM_NETWORK_PREFERENCE_OEM_PAID; 15282 15283 // Arrange users 15284 final int secondUser = 10; 15285 final UserHandle secondUserHandle = new UserHandle(secondUser); 15286 doReturn(asList(PRIMARY_USER_HANDLE)).when(mUserManager).getUserHandles(anyBoolean()); 15287 15288 // Arrange PackageManager mocks 15289 final int secondUserTestPackageUid = UserHandle.getUid(secondUser, TEST_PACKAGE_UID); 15290 final UidRangeParcel[] uidRangesSingleUser = 15291 toUidRangeStableParcels(uidRangesForUids(TEST_PACKAGE_UID)); 15292 final UidRangeParcel[] uidRangesBothUsers = 15293 toUidRangeStableParcels( 15294 uidRangesForUids(TEST_PACKAGE_UID, secondUserTestPackageUid)); 15295 mockGetApplicationInfo(TEST_PACKAGE_NAME, secondUserTestPackageUid, secondUserHandle); 15296 setupSetOemNetworkPreferenceForPreferenceTest( 15297 networkPref, uidRangesSingleUser, TEST_PACKAGE_NAME); 15298 15299 // Verify the starting state. No networks should be connected. 15300 verifySetOemNetworkPreferenceForPreference(uidRangesSingleUser, 15301 OEM_PREF_ANY_NET_ID, 0 /* times */, 15302 OEM_PREF_ANY_NET_ID, 0 /* times */, 15303 false /* shouldDestroyNetwork */); 15304 15305 // Test that we correctly add the expected values for multiple users. 15306 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); 15307 verifySetOemNetworkPreferenceForPreference(uidRangesSingleUser, 15308 mCellAgent.getNetwork().netId, 1 /* times */, 15309 OEM_PREF_ANY_NET_ID, 0 /* times */, 15310 false /* shouldDestroyNetwork */); 15311 15312 // Send a broadcast indicating a user was added. 15313 doReturn(asList(PRIMARY_USER_HANDLE, secondUserHandle)).when(mUserManager) 15314 .getUserHandles(anyBoolean()); 15315 final Intent addedIntent = new Intent(ACTION_USER_ADDED); 15316 addedIntent.putExtra(Intent.EXTRA_USER, UserHandle.of(secondUser)); 15317 processBroadcast(addedIntent); 15318 15319 // Test that we correctly add values for all users and remove for the single user. 15320 verifySetOemNetworkPreferenceForPreference(uidRangesBothUsers, uidRangesSingleUser, 15321 mCellAgent.getNetwork().netId, 1 /* times */, 15322 mCellAgent.getNetwork().netId, 1 /* times */, 15323 false /* shouldDestroyNetwork */); 15324 15325 // Send a broadcast indicating a user was removed. 15326 doReturn(asList(PRIMARY_USER_HANDLE)).when(mUserManager).getUserHandles(anyBoolean()); 15327 final Intent removedIntent = new Intent(ACTION_USER_REMOVED); 15328 removedIntent.putExtra(Intent.EXTRA_USER, UserHandle.of(secondUser)); 15329 processBroadcast(removedIntent); 15330 15331 // Test that we correctly add values for the single user and remove for the all users. 15332 verifySetOemNetworkPreferenceForPreference(uidRangesSingleUser, uidRangesBothUsers, 15333 mCellAgent.getNetwork().netId, 1 /* times */, 15334 mCellAgent.getNetwork().netId, 1 /* times */, 15335 false /* shouldDestroyNetwork */); 15336 } 15337 15338 @Test 15339 public void testMultilayerForPackageChangesEvaluatesCorrectly() 15340 throws Exception { 15341 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 15342 OEM_NETWORK_PREFERENCE_OEM_PAID; 15343 final String packageScheme = "package:"; 15344 15345 // Arrange PackageManager mocks 15346 final String packageToInstall = "package.to.install"; 15347 final int packageToInstallUid = 81387; 15348 final UidRangeParcel[] uidRangesSinglePackage = 15349 toUidRangeStableParcels(uidRangesForUids(TEST_PACKAGE_UID)); 15350 mockGetApplicationInfo(TEST_PACKAGE_NAME, TEST_PACKAGE_UID); 15351 mockGetApplicationInfoThrowsNameNotFound(packageToInstall, PRIMARY_USER_HANDLE); 15352 setOemNetworkPreference(networkPref, TEST_PACKAGE_NAME, packageToInstall); 15353 grantUsingBackgroundNetworksPermissionForUid(Binder.getCallingUid(), packageToInstall); 15354 15355 // Verify the starting state. No networks should be connected. 15356 verifySetOemNetworkPreferenceForPreference(uidRangesSinglePackage, 15357 OEM_PREF_ANY_NET_ID, 0 /* times */, 15358 OEM_PREF_ANY_NET_ID, 0 /* times */, 15359 false /* shouldDestroyNetwork */); 15360 15361 // Test that we correctly add the expected values for installed packages. 15362 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); 15363 verifySetOemNetworkPreferenceForPreference(uidRangesSinglePackage, 15364 mCellAgent.getNetwork().netId, 1 /* times */, 15365 OEM_PREF_ANY_NET_ID, 0 /* times */, 15366 false /* shouldDestroyNetwork */); 15367 15368 // Set the system to recognize the package to be installed 15369 mockGetApplicationInfo(packageToInstall, packageToInstallUid); 15370 final UidRangeParcel[] uidRangesAllPackages = 15371 toUidRangeStableParcels(uidRangesForUids(TEST_PACKAGE_UID, packageToInstallUid)); 15372 15373 // Send a broadcast indicating a package was installed. 15374 final Intent addedIntent = new Intent(ACTION_PACKAGE_ADDED); 15375 addedIntent.setData(Uri.parse(packageScheme + packageToInstall)); 15376 processBroadcast(addedIntent); 15377 15378 // Test the single package is removed and the combined packages are added. 15379 verifySetOemNetworkPreferenceForPreference(uidRangesAllPackages, uidRangesSinglePackage, 15380 mCellAgent.getNetwork().netId, 1 /* times */, 15381 mCellAgent.getNetwork().netId, 1 /* times */, 15382 false /* shouldDestroyNetwork */); 15383 15384 // Set the system to no longer recognize the package to be installed 15385 mockGetApplicationInfoThrowsNameNotFound(packageToInstall, PRIMARY_USER_HANDLE); 15386 15387 // Send a broadcast indicating a package was removed. 15388 final Intent removedIntent = new Intent(ACTION_PACKAGE_REMOVED); 15389 removedIntent.setData(Uri.parse(packageScheme + packageToInstall)); 15390 processBroadcast(removedIntent); 15391 15392 // Test the combined packages are removed and the single package is added. 15393 verifySetOemNetworkPreferenceForPreference(uidRangesSinglePackage, uidRangesAllPackages, 15394 mCellAgent.getNetwork().netId, 1 /* times */, 15395 mCellAgent.getNetwork().netId, 1 /* times */, 15396 false /* shouldDestroyNetwork */); 15397 15398 // Set the system to change the installed package's uid 15399 final int replacedTestPackageUid = TEST_PACKAGE_UID + 1; 15400 mockGetApplicationInfo(TEST_PACKAGE_NAME, replacedTestPackageUid); 15401 final UidRangeParcel[] uidRangesReplacedPackage = 15402 toUidRangeStableParcels(uidRangesForUids(replacedTestPackageUid)); 15403 15404 // Send a broadcast indicating a package was replaced. 15405 final Intent replacedIntent = new Intent(ACTION_PACKAGE_REPLACED); 15406 replacedIntent.setData(Uri.parse(packageScheme + TEST_PACKAGE_NAME)); 15407 processBroadcast(replacedIntent); 15408 15409 // Test the original uid is removed and is replaced with the new uid. 15410 verifySetOemNetworkPreferenceForPreference(uidRangesReplacedPackage, uidRangesSinglePackage, 15411 mCellAgent.getNetwork().netId, 1 /* times */, 15412 mCellAgent.getNetwork().netId, 1 /* times */, 15413 false /* shouldDestroyNetwork */); 15414 } 15415 15416 /** 15417 * Test network priority for preference OEM_NETWORK_PREFERENCE_OEM_PAID in the following order: 15418 * NET_CAPABILITY_NOT_METERED -> NET_CAPABILITY_OEM_PAID -> fallback 15419 */ 15420 @Test 15421 public void testMultipleDefaultNetworksTracksOemNetworkPreferenceOemPaidCorrectly() 15422 throws Exception { 15423 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 15424 OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID; 15425 setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest(networkPref); 15426 final int expectedDefaultRequestSize = 2; 15427 final int expectedOemPrefRequestSize = 3; 15428 registerDefaultNetworkCallbacks(); 15429 15430 // The fallback as well as the OEM preference should now be tracked. 15431 assertEquals(expectedDefaultRequestSize, mService.mDefaultNetworkRequests.size()); 15432 15433 // Test lowest to highest priority requests. 15434 // Bring up metered cellular. This will satisfy the fallback network. 15435 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); 15436 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 15437 mCellAgent.getNetwork(), 15438 mCellAgent.getNetwork()); 15439 15440 // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID. 15441 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true); 15442 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 15443 mCellAgent.getNetwork(), 15444 mEthernetAgent.getNetwork()); 15445 15446 // Bring up unmetered Wi-Fi. This will satisfy NET_CAPABILITY_NOT_METERED. 15447 setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, true); 15448 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 15449 mWiFiAgent.getNetwork(), 15450 mWiFiAgent.getNetwork()); 15451 15452 // Disconnecting unmetered Wi-Fi will put the pref on OEM_PAID and fallback on cellular. 15453 setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, false); 15454 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 15455 mCellAgent.getNetwork(), 15456 mEthernetAgent.getNetwork()); 15457 15458 // Disconnecting cellular should keep OEM network on OEM_PAID and fallback will be null. 15459 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, false); 15460 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 15461 null, 15462 mEthernetAgent.getNetwork()); 15463 15464 // Disconnecting OEM_PAID will put both on null as it is the last network. 15465 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, false); 15466 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 15467 null, 15468 null); 15469 15470 // default callbacks will be unregistered in tearDown 15471 } 15472 15473 @Test 15474 public void testNetworkFactoryRequestsWithMultilayerRequest() 15475 throws Exception { 15476 // First use OEM_PAID preference to create a multi-layer request : 1. listen for 15477 // unmetered, 2. request network with cap OEM_PAID, 3, request the default network for 15478 // fallback. 15479 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 15480 OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID; 15481 setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest(networkPref); 15482 15483 final HandlerThread handlerThread = new HandlerThread("MockFactory"); 15484 handlerThread.start(); 15485 NetworkCapabilities internetFilter = new NetworkCapabilities() 15486 .addCapability(NET_CAPABILITY_INTERNET) 15487 .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED); 15488 final MockNetworkFactory internetFactory = new MockNetworkFactory(handlerThread.getLooper(), 15489 mServiceContext, "internetFactory", internetFilter, mCsHandlerThread); 15490 internetFactory.setScoreFilter(40); 15491 internetFactory.register(); 15492 // Default internet request only. The unmetered request is never sent to factories (it's a 15493 // LISTEN, not requestable). The 3rd (fallback) request in OEM_PAID NRI is TRACK_DEFAULT 15494 // which is also not sent to factories. Finally, the OEM_PAID request doesn't match the 15495 // internetFactory filter. 15496 internetFactory.expectRequestAdds(1); 15497 internetFactory.assertRequestCountEquals(1); 15498 15499 NetworkCapabilities oemPaidFilter = new NetworkCapabilities() 15500 .addCapability(NET_CAPABILITY_INTERNET) 15501 .addCapability(NET_CAPABILITY_OEM_PAID) 15502 .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED) 15503 .removeCapability(NET_CAPABILITY_NOT_RESTRICTED); 15504 final MockNetworkFactory oemPaidFactory = new MockNetworkFactory(handlerThread.getLooper(), 15505 mServiceContext, "oemPaidFactory", oemPaidFilter, mCsHandlerThread); 15506 oemPaidFactory.setScoreFilter(40); 15507 oemPaidFactory.register(); 15508 oemPaidFactory.expectRequestAdd(); // Because nobody satisfies the request 15509 15510 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 15511 mCellAgent.connect(true); 15512 15513 // A network connected that satisfies the default internet request. For the OEM_PAID 15514 // preference, this is not as good as an OEM_PAID network, so even if the score of 15515 // the network is better than the factory announced, it still should try to bring up 15516 // the network. 15517 expectNoRequestChanged(oemPaidFactory); 15518 oemPaidFactory.assertRequestCountEquals(1); 15519 // The internet factory however is outscored, and should lose its requests. 15520 internetFactory.expectRequestRemove(); 15521 internetFactory.assertRequestCountEquals(0); 15522 15523 final NetworkCapabilities oemPaidNc = new NetworkCapabilities(); 15524 oemPaidNc.addCapability(NET_CAPABILITY_OEM_PAID); 15525 oemPaidNc.removeCapability(NET_CAPABILITY_NOT_RESTRICTED); 15526 final TestNetworkAgentWrapper oemPaidAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, 15527 new LinkProperties(), oemPaidNc); 15528 oemPaidAgent.connect(true); 15529 15530 // The oemPaidAgent has score 50/cell transport, so it beats what the oemPaidFactory can 15531 // provide, therefore it loses the request. 15532 oemPaidFactory.expectRequestRemove(); 15533 oemPaidFactory.assertRequestCountEquals(0); 15534 expectNoRequestChanged(internetFactory); 15535 internetFactory.assertRequestCountEquals(0); 15536 15537 oemPaidAgent.setScore(new NetworkScore.Builder().setLegacyInt(20).setExiting(true).build()); 15538 // Now the that the agent is weak, the oemPaidFactory can beat the existing network for the 15539 // OEM_PAID request. The internet factory however can't beat a network that has OEM_PAID 15540 // for the preference request, so it doesn't see the request. 15541 oemPaidFactory.expectRequestAdd(); 15542 oemPaidFactory.assertRequestCountEquals(1); 15543 expectNoRequestChanged(internetFactory); 15544 internetFactory.assertRequestCountEquals(0); 15545 15546 mCellAgent.disconnect(); 15547 // The network satisfying the default internet request has disconnected, so the 15548 // internetFactory sees the default request again. However there is a network with OEM_PAID 15549 // connected, so the 2nd OEM_PAID req is already satisfied, so the oemPaidFactory doesn't 15550 // care about networks that don't have OEM_PAID. 15551 expectNoRequestChanged(oemPaidFactory); 15552 oemPaidFactory.assertRequestCountEquals(1); 15553 internetFactory.expectRequestAdd(); 15554 internetFactory.assertRequestCountEquals(1); 15555 15556 // Cell connects again, still with score 50. Back to the previous state. 15557 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 15558 mCellAgent.connect(true); 15559 expectNoRequestChanged(oemPaidFactory); 15560 oemPaidFactory.assertRequestCountEquals(1); 15561 internetFactory.expectRequestRemove(); 15562 internetFactory.assertRequestCountEquals(0); 15563 15564 // Create a request that holds the upcoming wifi network. 15565 final TestNetworkCallback wifiCallback = new TestNetworkCallback(); 15566 mCm.requestNetwork(new NetworkRequest.Builder().addTransportType(TRANSPORT_WIFI).build(), 15567 wifiCallback); 15568 15569 // Now WiFi connects and it's unmetered, but it's weaker than cell. 15570 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 15571 mWiFiAgent.addCapability(NET_CAPABILITY_NOT_METERED); 15572 mWiFiAgent.setScore(new NetworkScore.Builder().setLegacyInt(30).setExiting(true) 15573 .build()); // Not the best Internet network, but unmetered 15574 mWiFiAgent.connect(true); 15575 15576 // The OEM_PAID preference prefers an unmetered network to an OEM_PAID network, so 15577 // the oemPaidFactory can't beat wifi no matter how high its score. 15578 oemPaidFactory.expectRequestRemove(); 15579 expectNoRequestChanged(internetFactory); 15580 15581 mCellAgent.disconnect(); 15582 // Now that the best internet network (cell, with its 50 score compared to 30 for WiFi 15583 // at this point), the default internet request is satisfied by a network worse than 15584 // the internetFactory announced, so it gets the request. However, there is still an 15585 // unmetered network, so the oemPaidNetworkFactory still can't beat this. 15586 expectNoRequestChanged(oemPaidFactory); 15587 internetFactory.expectRequestAdd(); 15588 mCm.unregisterNetworkCallback(wifiCallback); 15589 handlerThread.quitSafely(); 15590 handlerThread.join(); 15591 } 15592 15593 /** 15594 * Test network priority for OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK in the following order: 15595 * NET_CAPABILITY_NOT_METERED -> NET_CAPABILITY_OEM_PAID 15596 */ 15597 @Test 15598 public void testMultipleDefaultNetworksTracksOemNetworkPreferenceOemPaidNoFallbackCorrectly() 15599 throws Exception { 15600 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 15601 OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK; 15602 setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest(networkPref); 15603 final int expectedDefaultRequestSize = 2; 15604 final int expectedOemPrefRequestSize = 2; 15605 registerDefaultNetworkCallbacks(); 15606 15607 // The fallback as well as the OEM preference should now be tracked. 15608 assertEquals(expectedDefaultRequestSize, mService.mDefaultNetworkRequests.size()); 15609 15610 // Test lowest to highest priority requests. 15611 // Bring up metered cellular. This will satisfy the fallback network but not the pref. 15612 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); 15613 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 15614 mCellAgent.getNetwork(), 15615 mService.mNoServiceNetwork.network()); 15616 15617 // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID. 15618 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true); 15619 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 15620 mCellAgent.getNetwork(), 15621 mEthernetAgent.getNetwork()); 15622 15623 // Bring up unmetered Wi-Fi. This will satisfy NET_CAPABILITY_NOT_METERED. 15624 setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, true); 15625 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 15626 mWiFiAgent.getNetwork(), 15627 mWiFiAgent.getNetwork()); 15628 15629 // Disconnecting unmetered Wi-Fi will put the OEM pref on OEM_PAID and fallback on cellular. 15630 setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, false); 15631 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 15632 mCellAgent.getNetwork(), 15633 mEthernetAgent.getNetwork()); 15634 15635 // Disconnecting cellular should keep OEM network on OEM_PAID and fallback will be null. 15636 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, false); 15637 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 15638 null, 15639 mEthernetAgent.getNetwork()); 15640 15641 // Disconnecting OEM_PAID puts the fallback on null and the pref on the disconnected net. 15642 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, false); 15643 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 15644 null, 15645 mService.mNoServiceNetwork.network()); 15646 15647 // default callbacks will be unregistered in tearDown 15648 } 15649 15650 /** 15651 * Test network priority for OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY in the following order: 15652 * NET_CAPABILITY_OEM_PAID 15653 * This preference should only apply to OEM_PAID networks. 15654 */ 15655 @Test 15656 public void testMultipleDefaultNetworksTracksOemNetworkPreferenceOemPaidOnlyCorrectly() 15657 throws Exception { 15658 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 15659 OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY; 15660 setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest(networkPref); 15661 final int expectedDefaultRequestSize = 2; 15662 final int expectedOemPrefRequestSize = 1; 15663 registerDefaultNetworkCallbacks(); 15664 15665 // The fallback as well as the OEM preference should now be tracked. 15666 assertEquals(expectedDefaultRequestSize, mService.mDefaultNetworkRequests.size()); 15667 15668 // Test lowest to highest priority requests. 15669 // Bring up metered cellular. This will satisfy the fallback network. 15670 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); 15671 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 15672 mCellAgent.getNetwork(), 15673 mService.mNoServiceNetwork.network()); 15674 15675 // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID. 15676 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true); 15677 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 15678 mCellAgent.getNetwork(), 15679 mEthernetAgent.getNetwork()); 15680 15681 // Bring up unmetered Wi-Fi. The OEM network shouldn't change, the fallback will take Wi-Fi. 15682 setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, true); 15683 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 15684 mWiFiAgent.getNetwork(), 15685 mEthernetAgent.getNetwork()); 15686 15687 // Disconnecting unmetered Wi-Fi shouldn't change the OEM network with fallback on cellular. 15688 setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, false); 15689 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 15690 mCellAgent.getNetwork(), 15691 mEthernetAgent.getNetwork()); 15692 15693 // Disconnecting OEM_PAID will keep the fallback on cellular and nothing for OEM_PAID. 15694 // OEM_PAID_ONLY not supporting a fallback now uses the disconnected network. 15695 setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, false); 15696 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 15697 mCellAgent.getNetwork(), 15698 mService.mNoServiceNetwork.network()); 15699 15700 // Disconnecting cellular will put the fallback on null and the pref on disconnected. 15701 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, false); 15702 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 15703 null, 15704 mService.mNoServiceNetwork.network()); 15705 15706 // default callbacks will be unregistered in tearDown 15707 } 15708 15709 /** 15710 * Test network priority for OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY in the following order: 15711 * NET_CAPABILITY_OEM_PRIVATE 15712 * This preference should only apply to OEM_PRIVATE networks. 15713 */ 15714 @Test 15715 public void testMultipleDefaultNetworksTracksOemNetworkPreferenceOemPrivateOnlyCorrectly() 15716 throws Exception { 15717 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 15718 OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY; 15719 setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest(networkPref); 15720 final int expectedDefaultRequestSize = 2; 15721 final int expectedOemPrefRequestSize = 1; 15722 registerDefaultNetworkCallbacks(); 15723 15724 // The fallback as well as the OEM preference should now be tracked. 15725 assertEquals(expectedDefaultRequestSize, mService.mDefaultNetworkRequests.size()); 15726 15727 // Test lowest to highest priority requests. 15728 // Bring up metered cellular. This will satisfy the fallback network. 15729 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); 15730 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 15731 mCellAgent.getNetwork(), 15732 mService.mNoServiceNetwork.network()); 15733 15734 // Bring up ethernet with OEM_PRIVATE. This will satisfy NET_CAPABILITY_OEM_PRIVATE. 15735 startOemManagedNetwork(false); 15736 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 15737 mCellAgent.getNetwork(), 15738 mEthernetAgent.getNetwork()); 15739 15740 // Bring up unmetered Wi-Fi. The OEM network shouldn't change, the fallback will take Wi-Fi. 15741 setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, true); 15742 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 15743 mWiFiAgent.getNetwork(), 15744 mEthernetAgent.getNetwork()); 15745 15746 // Disconnecting unmetered Wi-Fi shouldn't change the OEM network with fallback on cellular. 15747 setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, false); 15748 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 15749 mCellAgent.getNetwork(), 15750 mEthernetAgent.getNetwork()); 15751 15752 // Disconnecting OEM_PRIVATE will keep the fallback on cellular. 15753 // OEM_PRIVATE_ONLY not supporting a fallback now uses to the disconnected network. 15754 stopOemManagedNetwork(); 15755 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 15756 mCellAgent.getNetwork(), 15757 mService.mNoServiceNetwork.network()); 15758 15759 // Disconnecting cellular will put the fallback on null and pref on disconnected. 15760 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, false); 15761 verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, 15762 null, 15763 mService.mNoServiceNetwork.network()); 15764 15765 // default callbacks will be unregistered in tearDown 15766 } 15767 15768 @Test 15769 public void testCapabilityWithOemNetworkPreference() throws Exception { 15770 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 15771 OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY; 15772 setupMultipleDefaultNetworksForOemNetworkPreferenceNotCurrentUidTest(networkPref); 15773 registerDefaultNetworkCallbacks(); 15774 15775 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); 15776 15777 mSystemDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 15778 mDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 15779 15780 mCellAgent.addCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED); 15781 mSystemDefaultNetworkCallback.expectCaps(mCellAgent, 15782 c -> c.hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED)); 15783 mDefaultNetworkCallback.expectCaps(mCellAgent, 15784 c -> c.hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED)); 15785 15786 // default callbacks will be unregistered in tearDown 15787 } 15788 15789 @Test 15790 public void testSetOemNetworkPreferenceLogsRequest() throws Exception { 15791 mServiceContext.setPermission(DUMP, PERMISSION_GRANTED); 15792 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 15793 OEM_NETWORK_PREFERENCE_OEM_PAID; 15794 final StringWriter stringWriter = new StringWriter(); 15795 final String logIdentifier = "UPDATE INITIATED: OemNetworkPreferences"; 15796 final Pattern pattern = Pattern.compile(logIdentifier); 15797 15798 final int expectedNumLogs = 2; 15799 final UidRangeParcel[] uidRanges = 15800 toUidRangeStableParcels(uidRangesForUids(TEST_PACKAGE_UID)); 15801 15802 // Call twice to generate two logs. 15803 setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges, TEST_PACKAGE_NAME); 15804 setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges, TEST_PACKAGE_NAME); 15805 mService.dump(new FileDescriptor(), new PrintWriter(stringWriter), new String[0]); 15806 15807 final String dumpOutput = stringWriter.toString(); 15808 final Matcher matcher = pattern.matcher(dumpOutput); 15809 int count = 0; 15810 while (matcher.find()) { 15811 count++; 15812 } 15813 assertEquals(expectedNumLogs, count); 15814 } 15815 15816 @Test 15817 public void testGetAllNetworkStateSnapshots() throws Exception { 15818 verifyNoNetwork(); 15819 15820 // Setup test cellular network with specified LinkProperties and NetworkCapabilities, 15821 // verify the content of the snapshot matches. 15822 final LinkProperties cellLp = new LinkProperties(); 15823 final LinkAddress myIpv4Addr = new LinkAddress(InetAddress.getByName("192.0.2.129"), 25); 15824 final LinkAddress myIpv6Addr = new LinkAddress(InetAddress.getByName("2001:db8::1"), 64); 15825 cellLp.setInterfaceName("test01"); 15826 cellLp.addLinkAddress(myIpv4Addr); 15827 cellLp.addLinkAddress(myIpv6Addr); 15828 cellLp.addRoute(new RouteInfo(InetAddress.getByName("fe80::1234"))); 15829 cellLp.addRoute(new RouteInfo(InetAddress.getByName("192.0.2.254"))); 15830 cellLp.addRoute(new RouteInfo(myIpv4Addr, null)); 15831 cellLp.addRoute(new RouteInfo(myIpv6Addr, null)); 15832 final NetworkCapabilities cellNcTemplate = new NetworkCapabilities.Builder() 15833 .addTransportType(TRANSPORT_CELLULAR).addCapability(NET_CAPABILITY_MMS).build(); 15834 15835 final TestNetworkCallback cellCb = new TestNetworkCallback(); 15836 mCm.requestNetwork(new NetworkRequest.Builder().addCapability(NET_CAPABILITY_MMS).build(), 15837 cellCb); 15838 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp, cellNcTemplate); 15839 mCellAgent.connect(true); 15840 cellCb.expectAvailableCallbacksUnvalidated(mCellAgent); 15841 List<NetworkStateSnapshot> snapshots = mCm.getAllNetworkStateSnapshots(); 15842 assertLength(1, snapshots); 15843 15844 // Compose the expected cellular snapshot for verification. 15845 final NetworkCapabilities cellNc = 15846 mCm.getNetworkCapabilities(mCellAgent.getNetwork()); 15847 final NetworkStateSnapshot cellSnapshot = new NetworkStateSnapshot( 15848 mCellAgent.getNetwork(), cellNc, cellLp, 15849 null, ConnectivityManager.TYPE_MOBILE); 15850 assertEquals(cellSnapshot, snapshots.get(0)); 15851 15852 // Connect wifi and verify the snapshots. 15853 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 15854 mWiFiAgent.connect(true); 15855 waitForIdle(); 15856 // Compose the expected wifi snapshot for verification. 15857 final NetworkCapabilities wifiNc = 15858 mCm.getNetworkCapabilities(mWiFiAgent.getNetwork()); 15859 final NetworkStateSnapshot wifiSnapshot = new NetworkStateSnapshot( 15860 mWiFiAgent.getNetwork(), wifiNc, new LinkProperties(), null, 15861 ConnectivityManager.TYPE_WIFI); 15862 15863 snapshots = mCm.getAllNetworkStateSnapshots(); 15864 assertLength(2, snapshots); 15865 assertContainsAll(snapshots, cellSnapshot, wifiSnapshot); 15866 15867 // Set cellular as suspended, verify the snapshots will contain suspended networks. 15868 mCellAgent.suspend(); 15869 waitForIdle(); 15870 final NetworkCapabilities cellSuspendedNc = 15871 mCm.getNetworkCapabilities(mCellAgent.getNetwork()); 15872 assertFalse(cellSuspendedNc.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); 15873 final NetworkStateSnapshot cellSuspendedSnapshot = new NetworkStateSnapshot( 15874 mCellAgent.getNetwork(), cellSuspendedNc, cellLp, 15875 null, ConnectivityManager.TYPE_MOBILE); 15876 snapshots = mCm.getAllNetworkStateSnapshots(); 15877 assertLength(2, snapshots); 15878 assertContainsAll(snapshots, cellSuspendedSnapshot, wifiSnapshot); 15879 15880 // Disconnect wifi, verify the snapshots contain only cellular. 15881 mWiFiAgent.disconnect(); 15882 waitForIdle(); 15883 snapshots = mCm.getAllNetworkStateSnapshots(); 15884 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetwork()); 15885 assertLength(1, snapshots); 15886 assertEquals(cellSuspendedSnapshot, snapshots.get(0)); 15887 15888 mCellAgent.resume(); 15889 waitForIdle(); 15890 snapshots = mCm.getAllNetworkStateSnapshots(); 15891 assertLength(1, snapshots); 15892 assertEquals(cellSnapshot, snapshots.get(0)); 15893 15894 mCellAgent.disconnect(); 15895 waitForIdle(); 15896 verifyNoNetwork(); 15897 mCm.unregisterNetworkCallback(cellCb); 15898 } 15899 15900 // Cannot be part of MockNetworkFactory since it requires method of the test. 15901 private void expectNoRequestChanged(@NonNull MockNetworkFactory factory) { 15902 waitForIdle(); 15903 factory.assertNoRequestChanged(); 15904 } 15905 15906 @Test 15907 public void testRegisterBestMatchingNetworkCallback_noIssueToFactory() throws Exception { 15908 // Prepare mock mms factory. 15909 final HandlerThread handlerThread = new HandlerThread("MockCellularFactory"); 15910 handlerThread.start(); 15911 NetworkCapabilities filter = new NetworkCapabilities() 15912 .addTransportType(TRANSPORT_CELLULAR) 15913 .addCapability(NET_CAPABILITY_MMS); 15914 final MockNetworkFactory testFactory = new MockNetworkFactory(handlerThread.getLooper(), 15915 mServiceContext, "testFactory", filter, mCsHandlerThread); 15916 testFactory.setScoreFilter(40); 15917 15918 try { 15919 // Register the factory. It doesn't see the default request because its filter does 15920 // not include INTERNET. 15921 testFactory.register(); 15922 expectNoRequestChanged(testFactory); 15923 testFactory.assertRequestCountEquals(0); 15924 // The factory won't try to start the network since the default request doesn't 15925 // match the filter (no INTERNET capability). 15926 assertFalse(testFactory.getMyStartRequested()); 15927 15928 // Register callback for listening best matching network. Verify that the request won't 15929 // be sent to factory. 15930 final TestNetworkCallback bestMatchingCb = new TestNetworkCallback(); 15931 mCm.registerBestMatchingNetworkCallback( 15932 new NetworkRequest.Builder().addCapability(NET_CAPABILITY_MMS).build(), 15933 bestMatchingCb, mCsHandlerThread.getThreadHandler()); 15934 bestMatchingCb.assertNoCallback(); 15935 expectNoRequestChanged(testFactory); 15936 testFactory.assertRequestCountEquals(0); 15937 assertFalse(testFactory.getMyStartRequested()); 15938 15939 // Fire a normal mms request, verify the factory will only see the request. 15940 final TestNetworkCallback mmsNetworkCallback = new TestNetworkCallback(); 15941 final NetworkRequest mmsRequest = new NetworkRequest.Builder() 15942 .addCapability(NET_CAPABILITY_MMS).build(); 15943 mCm.requestNetwork(mmsRequest, mmsNetworkCallback); 15944 testFactory.expectRequestAdd(); 15945 testFactory.assertRequestCountEquals(1); 15946 assertTrue(testFactory.getMyStartRequested()); 15947 15948 // Unregister best matching callback, verify factory see no change. 15949 mCm.unregisterNetworkCallback(bestMatchingCb); 15950 expectNoRequestChanged(testFactory); 15951 testFactory.assertRequestCountEquals(1); 15952 assertTrue(testFactory.getMyStartRequested()); 15953 } finally { 15954 testFactory.terminate(); 15955 handlerThread.quitSafely(); 15956 handlerThread.join(); 15957 } 15958 } 15959 15960 @Test 15961 public void testRegisterBestMatchingNetworkCallback_trackBestNetwork() throws Exception { 15962 final TestNetworkCallback bestMatchingCb = new TestNetworkCallback(); 15963 mCm.registerBestMatchingNetworkCallback( 15964 new NetworkRequest.Builder().addCapability(NET_CAPABILITY_TRUSTED).build(), 15965 bestMatchingCb, mCsHandlerThread.getThreadHandler()); 15966 15967 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 15968 mCellAgent.connect(true); 15969 bestMatchingCb.expectAvailableThenValidatedCallbacks(mCellAgent); 15970 15971 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 15972 mWiFiAgent.connect(true); 15973 bestMatchingCb.expectAvailableDoubleValidatedCallbacks(mWiFiAgent); 15974 15975 // Change something on cellular to trigger capabilities changed, since the callback 15976 // only cares about the best network, verify it received nothing from cellular. 15977 mCellAgent.addCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED); 15978 bestMatchingCb.assertNoCallback(); 15979 15980 // Make cellular the best network again, verify the callback now tracks cellular. 15981 mWiFiAgent.adjustScore(-50); 15982 bestMatchingCb.expectAvailableCallbacksValidated(mCellAgent); 15983 15984 // Make cellular temporary non-trusted, which will not satisfying the request. 15985 // Verify the callback switch from/to the other network accordingly. 15986 mCellAgent.removeCapability(NET_CAPABILITY_TRUSTED); 15987 bestMatchingCb.expectAvailableCallbacksValidated(mWiFiAgent); 15988 mCellAgent.addCapability(NET_CAPABILITY_TRUSTED); 15989 bestMatchingCb.expectAvailableDoubleValidatedCallbacks(mCellAgent); 15990 15991 // Verify the callback doesn't care about wifi disconnect. 15992 mWiFiAgent.disconnect(); 15993 bestMatchingCb.assertNoCallback(); 15994 mCellAgent.disconnect(); 15995 bestMatchingCb.expect(LOST, mCellAgent); 15996 } 15997 15998 private UidRangeParcel[] uidRangeFor(final UserHandle handle) { 15999 final UidRange range = UidRange.createForUser(handle); 16000 return new UidRangeParcel[] { new UidRangeParcel(range.start, range.stop) }; 16001 } 16002 16003 private UidRangeParcel[] uidRangeFor(final UserHandle handle, 16004 ProfileNetworkPreference profileNetworkPreference) { 16005 final Set<UidRange> uidRangeSet; 16006 UidRange range = UidRange.createForUser(handle); 16007 if (profileNetworkPreference.getIncludedUids().length != 0) { 16008 uidRangeSet = UidRangeUtils.convertArrayToUidRange( 16009 profileNetworkPreference.getIncludedUids()); 16010 16011 } else if (profileNetworkPreference.getExcludedUids().length != 0) { 16012 uidRangeSet = UidRangeUtils.removeRangeSetFromUidRange( 16013 range, UidRangeUtils.convertArrayToUidRange( 16014 profileNetworkPreference.getExcludedUids())); 16015 } else { 16016 uidRangeSet = new ArraySet<>(); 16017 uidRangeSet.add(range); 16018 } 16019 UidRangeParcel[] uidRangeParcels = new UidRangeParcel[uidRangeSet.size()]; 16020 int i = 0; 16021 for (UidRange range1 : uidRangeSet) { 16022 uidRangeParcels[i] = new UidRangeParcel(range1.start, range1.stop); 16023 i++; 16024 } 16025 return uidRangeParcels; 16026 } 16027 16028 private static class TestOnCompleteListener implements Runnable { 16029 final class OnComplete {} 16030 final ArrayTrackRecord<OnComplete>.ReadHead mHistory = 16031 new ArrayTrackRecord<OnComplete>().newReadHead(); 16032 16033 @Override 16034 public void run() { 16035 mHistory.add(new OnComplete()); 16036 } 16037 16038 public void expectOnComplete() { 16039 assertNotNull(mHistory.poll(TIMEOUT_MS, it -> true)); 16040 } 16041 } 16042 16043 private TestNetworkAgentWrapper makeEnterpriseNetworkAgent() throws Exception { 16044 final NetworkCapabilities workNc = new NetworkCapabilities(); 16045 workNc.addCapability(NET_CAPABILITY_ENTERPRISE); 16046 workNc.removeCapability(NET_CAPABILITY_NOT_RESTRICTED); 16047 return new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, new LinkProperties(), workNc); 16048 } 16049 16050 private TestNetworkAgentWrapper makeEnterpriseNetworkAgent(int enterpriseId) throws Exception { 16051 final NetworkCapabilities workNc = new NetworkCapabilities(); 16052 workNc.addCapability(NET_CAPABILITY_ENTERPRISE); 16053 workNc.removeCapability(NET_CAPABILITY_NOT_RESTRICTED); 16054 workNc.addEnterpriseId(enterpriseId); 16055 return new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, new LinkProperties(), workNc); 16056 } 16057 16058 private TestNetworkCallback mEnterpriseCallback; 16059 private UserHandle setupEnterpriseNetwork() { 16060 final UserHandle userHandle = UserHandle.of(TEST_WORK_PROFILE_USER_ID); 16061 mServiceContext.setWorkProfile(userHandle, true); 16062 16063 // File a request to avoid the enterprise network being disconnected as soon as the default 16064 // request goes away – it would make impossible to test that networkRemoveUidRanges 16065 // is called, as the network would disconnect first for lack of a request. 16066 mEnterpriseCallback = new TestNetworkCallback(); 16067 final NetworkRequest keepUpRequest = new NetworkRequest.Builder() 16068 .addCapability(NET_CAPABILITY_ENTERPRISE) 16069 .build(); 16070 mCm.requestNetwork(keepUpRequest, mEnterpriseCallback); 16071 return userHandle; 16072 } 16073 16074 private void maybeTearDownEnterpriseNetwork() { 16075 if (null != mEnterpriseCallback) { 16076 mCm.unregisterNetworkCallback(mEnterpriseCallback); 16077 } 16078 } 16079 16080 /** 16081 * Make sure per profile network preferences behave as expected for a given 16082 * profile network preference. 16083 */ 16084 private void doTestPreferenceForUserNetworkUpDownForGivenPreference( 16085 ProfileNetworkPreference profileNetworkPreference, 16086 boolean connectWorkProfileAgentAhead, 16087 UserHandle testHandle, 16088 TestNetworkCallback profileDefaultNetworkCallback, 16089 TestNetworkCallback disAllowProfileDefaultNetworkCallback) throws Exception { 16090 final InOrder inOrder = inOrder(mMockNetd, mMockDnsResolver); 16091 16092 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 16093 mCellAgent.connect(true); 16094 16095 mSystemDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 16096 mDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 16097 profileDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 16098 if (disAllowProfileDefaultNetworkCallback != null) { 16099 disAllowProfileDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 16100 } 16101 inOrder.verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( 16102 mCellAgent.getNetwork().netId, INetd.PERMISSION_NONE)); 16103 16104 final TestNetworkAgentWrapper workAgent = 16105 makeEnterpriseNetworkAgent(profileNetworkPreference.getPreferenceEnterpriseId()); 16106 if (mService.shouldCreateNetworksImmediately(workAgent.getNetworkCapabilities())) { 16107 expectNativeNetworkCreated(workAgent.getNetwork().netId, INetd.PERMISSION_SYSTEM, 16108 null /* iface */, inOrder); 16109 } 16110 if (connectWorkProfileAgentAhead) { 16111 workAgent.connect(false); 16112 if (!mService.shouldCreateNetworksImmediately(workAgent.getNetworkCapabilities())) { 16113 expectNativeNetworkCreated(workAgent.getNetwork().netId, INetd.PERMISSION_SYSTEM, 16114 null /* iface */, inOrder); 16115 } 16116 } 16117 16118 final TestOnCompleteListener listener = new TestOnCompleteListener(); 16119 mCm.setProfileNetworkPreferences(testHandle, List.of(profileNetworkPreference), 16120 r -> r.run(), listener); 16121 listener.expectOnComplete(); 16122 boolean allowFallback = true; 16123 if (profileNetworkPreference.getPreference() 16124 == PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK) { 16125 allowFallback = false; 16126 } 16127 if (allowFallback && !connectWorkProfileAgentAhead) { 16128 // Setting a network preference for this user will create a new set of routing rules for 16129 // the UID range that corresponds to this user, inorder to define the default network 16130 // for these apps separately. This is true because the multi-layer request relevant to 16131 // this UID range contains a TRACK_DEFAULT, so the range will be moved through 16132 // UID-specific rules to the correct network – in this case the system default network. 16133 // The case where the default network for the profile happens to be the same as the 16134 // system default is not handled specially, the rules are always active as long as 16135 // a preference is set. 16136 inOrder.verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 16137 mCellAgent.getNetwork().netId, 16138 uidRangeFor(testHandle, profileNetworkPreference), 16139 PREFERENCE_ORDER_PROFILE)); 16140 } 16141 16142 // The enterprise network is not ready yet. 16143 assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback); 16144 if (allowFallback && !connectWorkProfileAgentAhead) { 16145 assertNoCallbacks(profileDefaultNetworkCallback); 16146 } else if (!connectWorkProfileAgentAhead) { 16147 profileDefaultNetworkCallback.expect(LOST, mCellAgent); 16148 if (disAllowProfileDefaultNetworkCallback != null) { 16149 assertNoCallbacks(disAllowProfileDefaultNetworkCallback); 16150 } 16151 } 16152 16153 if (!connectWorkProfileAgentAhead) { 16154 workAgent.connect(false); 16155 if (!mService.shouldCreateNetworksImmediately(workAgent.getNetworkCapabilities())) { 16156 inOrder.verify(mMockNetd).networkCreate( 16157 nativeNetworkConfigPhysical(workAgent.getNetwork().netId, 16158 INetd.PERMISSION_SYSTEM)); 16159 } 16160 } 16161 16162 profileDefaultNetworkCallback.expectAvailableCallbacksUnvalidated(workAgent); 16163 if (disAllowProfileDefaultNetworkCallback != null) { 16164 disAllowProfileDefaultNetworkCallback.assertNoCallback(); 16165 } 16166 mSystemDefaultNetworkCallback.assertNoCallback(); 16167 mDefaultNetworkCallback.assertNoCallback(); 16168 inOrder.verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 16169 workAgent.getNetwork().netId, 16170 uidRangeFor(testHandle, profileNetworkPreference), 16171 PREFERENCE_ORDER_PROFILE)); 16172 16173 if (allowFallback && !connectWorkProfileAgentAhead) { 16174 inOrder.verify(mMockNetd).networkRemoveUidRangesParcel(new NativeUidRangeConfig( 16175 mCellAgent.getNetwork().netId, 16176 uidRangeFor(testHandle, profileNetworkPreference), 16177 PREFERENCE_ORDER_PROFILE)); 16178 } 16179 16180 // Make sure changes to the work agent send callbacks to the app in the work profile, but 16181 // not to the other apps. 16182 workAgent.setNetworkValid(true /* privateDnsProbeSent */); 16183 workAgent.mNetworkMonitor.forceReevaluation(Process.myUid()); 16184 profileDefaultNetworkCallback.expectCaps(workAgent, 16185 c -> c.hasCapability(NET_CAPABILITY_VALIDATED) 16186 && c.hasCapability(NET_CAPABILITY_ENTERPRISE) 16187 && c.hasEnterpriseId(profileNetworkPreference.getPreferenceEnterpriseId()) 16188 && c.getEnterpriseIds().length == 1); 16189 if (disAllowProfileDefaultNetworkCallback != null) { 16190 assertNoCallbacks(disAllowProfileDefaultNetworkCallback); 16191 } 16192 assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback); 16193 16194 workAgent.addCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED); 16195 profileDefaultNetworkCallback.expectCaps(workAgent, 16196 c -> c.hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED)); 16197 if (disAllowProfileDefaultNetworkCallback != null) { 16198 assertNoCallbacks(disAllowProfileDefaultNetworkCallback); 16199 } 16200 assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback); 16201 16202 // Conversely, change a capability on the system-wide default network and make sure 16203 // that only the apps outside of the work profile receive the callbacks. 16204 mCellAgent.addCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED); 16205 mSystemDefaultNetworkCallback.expectCaps(mCellAgent, 16206 c -> c.hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED)); 16207 mDefaultNetworkCallback.expectCaps(mCellAgent, 16208 c -> c.hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED)); 16209 if (disAllowProfileDefaultNetworkCallback != null) { 16210 disAllowProfileDefaultNetworkCallback.expectCaps(mCellAgent, 16211 c -> c.hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED)); 16212 } 16213 profileDefaultNetworkCallback.assertNoCallback(); 16214 16215 // Disconnect and reconnect the system-wide default network and make sure that the 16216 // apps on this network see the appropriate callbacks, and the app on the work profile 16217 // doesn't because it continues to use the enterprise network. 16218 mCellAgent.disconnect(); 16219 mSystemDefaultNetworkCallback.expect(LOST, mCellAgent); 16220 mDefaultNetworkCallback.expect(LOST, mCellAgent); 16221 if (disAllowProfileDefaultNetworkCallback != null) { 16222 disAllowProfileDefaultNetworkCallback.expect(LOST, mCellAgent); 16223 } 16224 profileDefaultNetworkCallback.assertNoCallback(); 16225 inOrder.verify(mMockNetd).networkDestroy(mCellAgent.getNetwork().netId); 16226 16227 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 16228 mCellAgent.connect(true); 16229 mSystemDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 16230 mDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 16231 if (disAllowProfileDefaultNetworkCallback != null) { 16232 disAllowProfileDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 16233 16234 } 16235 profileDefaultNetworkCallback.assertNoCallback(); 16236 inOrder.verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( 16237 mCellAgent.getNetwork().netId, INetd.PERMISSION_NONE)); 16238 16239 // When the agent disconnects, test that the app on the work profile falls back to the 16240 // default network. 16241 workAgent.disconnect(); 16242 profileDefaultNetworkCallback.expect(LOST, workAgent); 16243 if (allowFallback) { 16244 profileDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellAgent); 16245 if (disAllowProfileDefaultNetworkCallback != null) { 16246 assertNoCallbacks(disAllowProfileDefaultNetworkCallback); 16247 } 16248 } 16249 assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback); 16250 if (allowFallback) { 16251 inOrder.verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 16252 mCellAgent.getNetwork().netId, 16253 uidRangeFor(testHandle, profileNetworkPreference), 16254 PREFERENCE_ORDER_PROFILE)); 16255 } 16256 inOrder.verify(mMockNetd).networkDestroy(workAgent.getNetwork().netId); 16257 16258 mCellAgent.disconnect(); 16259 mSystemDefaultNetworkCallback.expect(LOST, mCellAgent); 16260 mDefaultNetworkCallback.expect(LOST, mCellAgent); 16261 if (disAllowProfileDefaultNetworkCallback != null) { 16262 disAllowProfileDefaultNetworkCallback.expect(LOST, mCellAgent); 16263 } 16264 if (allowFallback) { 16265 profileDefaultNetworkCallback.expect(LOST, mCellAgent); 16266 } 16267 16268 // Waiting for the handler to be idle before checking for networkDestroy is necessary 16269 // here because ConnectivityService calls onLost before the network is fully torn down. 16270 waitForIdle(); 16271 inOrder.verify(mMockNetd).networkDestroy(mCellAgent.getNetwork().netId); 16272 16273 // If the control comes here, callbacks seem to behave correctly in the presence of 16274 // a default network when the enterprise network goes up and down. Now, make sure they 16275 // also behave correctly in the absence of a system-wide default network. 16276 final TestNetworkAgentWrapper workAgent2 = 16277 makeEnterpriseNetworkAgent(profileNetworkPreference.getPreferenceEnterpriseId()); 16278 workAgent2.connect(false); 16279 16280 profileDefaultNetworkCallback.expectAvailableCallbacksUnvalidated(workAgent2); 16281 if (disAllowProfileDefaultNetworkCallback != null) { 16282 assertNoCallbacks(disAllowProfileDefaultNetworkCallback); 16283 } 16284 assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback); 16285 inOrder.verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( 16286 workAgent2.getNetwork().netId, INetd.PERMISSION_SYSTEM)); 16287 inOrder.verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 16288 workAgent2.getNetwork().netId, 16289 uidRangeFor(testHandle, profileNetworkPreference), PREFERENCE_ORDER_PROFILE)); 16290 16291 workAgent2.setNetworkValid(true /* privateDnsProbeSent */); 16292 workAgent2.mNetworkMonitor.forceReevaluation(Process.myUid()); 16293 profileDefaultNetworkCallback.expectCaps(workAgent2, 16294 c -> c.hasCapability(NET_CAPABILITY_ENTERPRISE) 16295 && !c.hasCapability(NET_CAPABILITY_NOT_RESTRICTED) 16296 && c.hasEnterpriseId(profileNetworkPreference.getPreferenceEnterpriseId()) 16297 && c.getEnterpriseIds().length == 1); 16298 if (disAllowProfileDefaultNetworkCallback != null) { 16299 assertNoCallbacks(disAllowProfileDefaultNetworkCallback); 16300 } 16301 assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback); 16302 inOrder.verify(mMockNetd, never()).networkAddUidRangesParcel(any()); 16303 16304 // When the agent disconnects, test that the app on the work profile fall back to the 16305 // default network. 16306 workAgent2.disconnect(); 16307 profileDefaultNetworkCallback.expect(LOST, workAgent2); 16308 if (disAllowProfileDefaultNetworkCallback != null) { 16309 assertNoCallbacks(disAllowProfileDefaultNetworkCallback); 16310 } 16311 assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback); 16312 inOrder.verify(mMockNetd).networkDestroy(workAgent2.getNetwork().netId); 16313 16314 assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback, 16315 profileDefaultNetworkCallback); 16316 16317 // Callbacks will be unregistered by tearDown() 16318 } 16319 16320 /** 16321 * Make sure per-profile networking preference behaves as expected when the enterprise network 16322 * goes up and down while the preference is active. Make sure they behave as expected whether 16323 * there is a general default network or not. 16324 */ 16325 @Test 16326 public void testPreferenceForUserNetworkUpDown() throws Exception { 16327 final UserHandle testHandle = setupEnterpriseNetwork(); 16328 registerDefaultNetworkCallbacks(); 16329 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder = 16330 new ProfileNetworkPreference.Builder(); 16331 profileNetworkPreferenceBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE); 16332 profileNetworkPreferenceBuilder.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1); 16333 doTestPreferenceForUserNetworkUpDownForGivenPreference( 16334 profileNetworkPreferenceBuilder.build(), false, 16335 testHandle, mProfileDefaultNetworkCallback, null); 16336 } 16337 16338 /** 16339 * Make sure per-profile networking preference behaves as expected when the enterprise network 16340 * goes up and down while the preference is active. Make sure they behave as expected whether 16341 * there is a general default network or not when configured to not fallback to default network. 16342 */ 16343 @Test 16344 public void testPreferenceForUserNetworkUpDownWithNoFallback() throws Exception { 16345 final UserHandle testHandle = setupEnterpriseNetwork(); 16346 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder = 16347 new ProfileNetworkPreference.Builder(); 16348 profileNetworkPreferenceBuilder.setPreference( 16349 PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK); 16350 profileNetworkPreferenceBuilder.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1); 16351 registerDefaultNetworkCallbacks(); 16352 doTestPreferenceForUserNetworkUpDownForGivenPreference( 16353 profileNetworkPreferenceBuilder.build(), false, 16354 testHandle, mProfileDefaultNetworkCallback, null); 16355 } 16356 16357 /** 16358 * Make sure per-profile networking preference behaves as expected when the enterprise network 16359 * goes up and down while the preference is active. Make sure they behave as expected whether 16360 * there is a general default network or not when configured to not fallback to default network 16361 * along with already connected enterprise work agent 16362 */ 16363 @Test 16364 public void testPreferenceForUserNetworkUpDownWithNoFallbackWithAlreadyConnectedWorkAgent() 16365 throws Exception { 16366 final UserHandle testHandle = setupEnterpriseNetwork(); 16367 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder = 16368 new ProfileNetworkPreference.Builder(); 16369 profileNetworkPreferenceBuilder.setPreference( 16370 PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK); 16371 profileNetworkPreferenceBuilder.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1); 16372 registerDefaultNetworkCallbacks(); 16373 doTestPreferenceForUserNetworkUpDownForGivenPreference( 16374 profileNetworkPreferenceBuilder.build(), true, testHandle, 16375 mProfileDefaultNetworkCallback, null); 16376 } 16377 16378 /** 16379 * Make sure per-profile networking preference for specific uid of test handle 16380 * behaves as expected 16381 */ 16382 @Test 16383 public void testPreferenceForDefaultUidOfTestHandle() throws Exception { 16384 final UserHandle testHandle = setupEnterpriseNetwork(); 16385 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder = 16386 new ProfileNetworkPreference.Builder(); 16387 profileNetworkPreferenceBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE); 16388 profileNetworkPreferenceBuilder.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1); 16389 profileNetworkPreferenceBuilder.setIncludedUids( 16390 new int[]{testHandle.getUid(TEST_WORK_PROFILE_APP_UID)}); 16391 registerDefaultNetworkCallbacks(); 16392 doTestPreferenceForUserNetworkUpDownForGivenPreference( 16393 profileNetworkPreferenceBuilder.build(), false, testHandle, 16394 mProfileDefaultNetworkCallback, null); 16395 } 16396 16397 /** 16398 * Make sure per-profile networking preference for specific uid of test handle 16399 * behaves as expected 16400 */ 16401 @Test 16402 public void testPreferenceForSpecificUidOfOnlyOneApp() throws Exception { 16403 final UserHandle testHandle = setupEnterpriseNetwork(); 16404 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder = 16405 new ProfileNetworkPreference.Builder(); 16406 profileNetworkPreferenceBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE); 16407 profileNetworkPreferenceBuilder.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1); 16408 profileNetworkPreferenceBuilder.setIncludedUids( 16409 new int[]{testHandle.getUid(TEST_WORK_PROFILE_APP_UID_2)}); 16410 registerDefaultNetworkCallbacks(); 16411 doTestPreferenceForUserNetworkUpDownForGivenPreference( 16412 profileNetworkPreferenceBuilder.build(), false, 16413 testHandle, mProfileDefaultNetworkCallbackAsAppUid2, null); 16414 } 16415 16416 /** 16417 * Make sure per-profile networking preference for specific uid of test handle 16418 * behaves as expected 16419 */ 16420 @Test 16421 public void testPreferenceForDisallowSpecificUidOfApp() throws Exception { 16422 final UserHandle testHandle = setupEnterpriseNetwork(); 16423 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder = 16424 new ProfileNetworkPreference.Builder(); 16425 profileNetworkPreferenceBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE); 16426 profileNetworkPreferenceBuilder.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1); 16427 profileNetworkPreferenceBuilder.setExcludedUids( 16428 new int[]{testHandle.getUid(TEST_WORK_PROFILE_APP_UID_2)}); 16429 registerDefaultNetworkCallbacks(); 16430 doTestPreferenceForUserNetworkUpDownForGivenPreference( 16431 profileNetworkPreferenceBuilder.build(), false, 16432 testHandle, mProfileDefaultNetworkCallback, 16433 mProfileDefaultNetworkCallbackAsAppUid2); 16434 } 16435 16436 /** 16437 * Make sure per-profile networking preference for specific uid of test handle 16438 * invalid uid inputs 16439 */ 16440 @Test 16441 public void testPreferenceForInvalidUids() throws Exception { 16442 final UserHandle testHandle = setupEnterpriseNetwork(); 16443 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder = 16444 new ProfileNetworkPreference.Builder(); 16445 profileNetworkPreferenceBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE); 16446 profileNetworkPreferenceBuilder.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1); 16447 profileNetworkPreferenceBuilder.setExcludedUids( 16448 new int[]{testHandle.getUid(0) - 1}); 16449 final TestOnCompleteListener listener = new TestOnCompleteListener(); 16450 Assert.assertThrows(IllegalArgumentException.class, () -> mCm.setProfileNetworkPreferences( 16451 testHandle, List.of(profileNetworkPreferenceBuilder.build()), 16452 r -> r.run(), listener)); 16453 16454 profileNetworkPreferenceBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE); 16455 profileNetworkPreferenceBuilder.setIncludedUids( 16456 new int[]{testHandle.getUid(0) - 1}); 16457 Assert.assertThrows(IllegalArgumentException.class, 16458 () -> mCm.setProfileNetworkPreferences( 16459 testHandle, List.of(profileNetworkPreferenceBuilder.build()), 16460 r -> r.run(), listener)); 16461 16462 16463 profileNetworkPreferenceBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE); 16464 profileNetworkPreferenceBuilder.setIncludedUids( 16465 new int[]{testHandle.getUid(0) - 1}); 16466 profileNetworkPreferenceBuilder.setExcludedUids( 16467 new int[]{testHandle.getUid(TEST_WORK_PROFILE_APP_UID_2)}); 16468 Assert.assertThrows(IllegalArgumentException.class, 16469 () -> mCm.setProfileNetworkPreferences( 16470 testHandle, List.of(profileNetworkPreferenceBuilder.build()), 16471 r -> r.run(), listener)); 16472 16473 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder2 = 16474 new ProfileNetworkPreference.Builder(); 16475 profileNetworkPreferenceBuilder2.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE); 16476 profileNetworkPreferenceBuilder2.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1); 16477 profileNetworkPreferenceBuilder2.setIncludedUids( 16478 new int[]{testHandle.getUid(TEST_WORK_PROFILE_APP_UID_2)}); 16479 profileNetworkPreferenceBuilder.setIncludedUids( 16480 new int[]{testHandle.getUid(TEST_WORK_PROFILE_APP_UID_2)}); 16481 Assert.assertThrows(IllegalArgumentException.class, 16482 () -> mCm.setProfileNetworkPreferences( 16483 testHandle, List.of(profileNetworkPreferenceBuilder.build(), 16484 profileNetworkPreferenceBuilder2.build()), 16485 r -> r.run(), listener)); 16486 16487 profileNetworkPreferenceBuilder2.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE); 16488 profileNetworkPreferenceBuilder2.setExcludedUids( 16489 new int[]{testHandle.getUid(TEST_WORK_PROFILE_APP_UID_2)}); 16490 profileNetworkPreferenceBuilder.setExcludedUids( 16491 new int[]{testHandle.getUid(TEST_WORK_PROFILE_APP_UID_2)}); 16492 Assert.assertThrows(IllegalArgumentException.class, 16493 () -> mCm.setProfileNetworkPreferences( 16494 testHandle, List.of(profileNetworkPreferenceBuilder.build(), 16495 profileNetworkPreferenceBuilder2.build()), 16496 r -> r.run(), listener)); 16497 16498 profileNetworkPreferenceBuilder2.setPreference( 16499 PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK); 16500 profileNetworkPreferenceBuilder2.setExcludedUids( 16501 new int[]{testHandle.getUid(TEST_WORK_PROFILE_APP_UID_2)}); 16502 profileNetworkPreferenceBuilder.setExcludedUids( 16503 new int[]{testHandle.getUid(TEST_WORK_PROFILE_APP_UID_2)}); 16504 Assert.assertThrows(IllegalArgumentException.class, 16505 () -> mCm.setProfileNetworkPreferences( 16506 testHandle, List.of(profileNetworkPreferenceBuilder.build(), 16507 profileNetworkPreferenceBuilder2.build()), 16508 r -> r.run(), listener)); 16509 } 16510 16511 /** 16512 * Make sure per-profile networking preference behaves as expected when the enterprise network 16513 * goes up and down while the preference is active. Make sure they behave as expected whether 16514 * there is a general default network or not when configured to fallback to default network 16515 * along with already connected enterprise work agent 16516 */ 16517 @Test 16518 public void testPreferenceForUserNetworkUpDownWithFallbackWithAlreadyConnectedWorkAgent() 16519 throws Exception { 16520 final UserHandle testHandle = setupEnterpriseNetwork(); 16521 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder = 16522 new ProfileNetworkPreference.Builder(); 16523 profileNetworkPreferenceBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE); 16524 profileNetworkPreferenceBuilder.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1); 16525 registerDefaultNetworkCallbacks(); 16526 doTestPreferenceForUserNetworkUpDownForGivenPreference( 16527 profileNetworkPreferenceBuilder.build(), true, 16528 testHandle, mProfileDefaultNetworkCallback, 16529 null); 16530 } 16531 16532 /** 16533 * Make sure per-profile networking preference behaves as expected when the enterprise network 16534 * goes up and down while the preference is active for a given enterprise identifier 16535 */ 16536 @Test 16537 public void testPreferenceForUserNetworkUpDownWithDefaultEnterpriseId() 16538 throws Exception { 16539 final UserHandle testHandle = setupEnterpriseNetwork(); 16540 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder = 16541 new ProfileNetworkPreference.Builder(); 16542 profileNetworkPreferenceBuilder.setPreference( 16543 PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK); 16544 profileNetworkPreferenceBuilder.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1); 16545 registerDefaultNetworkCallbacks(); 16546 doTestPreferenceForUserNetworkUpDownForGivenPreference( 16547 profileNetworkPreferenceBuilder.build(), true, 16548 testHandle, mProfileDefaultNetworkCallback, 16549 null); 16550 } 16551 16552 /** 16553 * Make sure per-profile networking preference behaves as expected when the enterprise network 16554 * goes up and down while the preference is active for a given enterprise identifier 16555 */ 16556 @Test 16557 public void testPreferenceForUserNetworkUpDownWithId2() 16558 throws Exception { 16559 final UserHandle testHandle = setupEnterpriseNetwork(); 16560 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder = 16561 new ProfileNetworkPreference.Builder(); 16562 profileNetworkPreferenceBuilder.setPreference( 16563 PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK); 16564 profileNetworkPreferenceBuilder.setPreferenceEnterpriseId( 16565 NET_ENTERPRISE_ID_2); 16566 registerDefaultNetworkCallbacks(); 16567 doTestPreferenceForUserNetworkUpDownForGivenPreference( 16568 profileNetworkPreferenceBuilder.build(), true, 16569 testHandle, mProfileDefaultNetworkCallback, null); 16570 } 16571 16572 /** 16573 * Make sure per-profile networking preference behaves as expected when the enterprise network 16574 * goes up and down while the preference is active for a given enterprise identifier 16575 */ 16576 @Test 16577 public void testPreferenceForUserNetworkUpDownWithInvalidId() 16578 throws Exception { 16579 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder = 16580 new ProfileNetworkPreference.Builder(); 16581 profileNetworkPreferenceBuilder.setPreference( 16582 PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK); 16583 profileNetworkPreferenceBuilder.setPreferenceEnterpriseId(0); 16584 registerDefaultNetworkCallbacks(); 16585 assertThrows("Should not be able to set invalid enterprise id", 16586 IllegalStateException.class, () -> profileNetworkPreferenceBuilder.build()); 16587 } 16588 16589 /** 16590 * Make sure per-profile networking preference throws exception when default preference 16591 * is set along with enterprise preference. 16592 */ 16593 @Test 16594 public void testPreferenceWithInvalidPreferenceDefaultAndEnterpriseTogether() 16595 throws Exception { 16596 final UserHandle testHandle = setupEnterpriseNetwork(); 16597 mServiceContext.setWorkProfile(testHandle, true); 16598 16599 final int testWorkProfileAppUid1 = 16600 UserHandle.getUid(testHandle.getIdentifier(), TEST_APP_ID); 16601 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder1 = 16602 new ProfileNetworkPreference.Builder(); 16603 profileNetworkPreferenceBuilder1.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE); 16604 profileNetworkPreferenceBuilder1.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1); 16605 profileNetworkPreferenceBuilder1.setIncludedUids(new int[]{testWorkProfileAppUid1}); 16606 16607 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder2 = 16608 new ProfileNetworkPreference.Builder(); 16609 profileNetworkPreferenceBuilder2.setPreference(PROFILE_NETWORK_PREFERENCE_DEFAULT); 16610 final TestOnCompleteListener listener = new TestOnCompleteListener(); 16611 Assert.assertThrows(IllegalArgumentException.class, 16612 () -> mCm.setProfileNetworkPreferences( 16613 testHandle, List.of(profileNetworkPreferenceBuilder1.build(), 16614 profileNetworkPreferenceBuilder2.build()), 16615 r -> r.run(), listener)); 16616 Assert.assertThrows(IllegalArgumentException.class, 16617 () -> mCm.setProfileNetworkPreferences( 16618 testHandle, List.of(profileNetworkPreferenceBuilder2.build(), 16619 profileNetworkPreferenceBuilder1.build()), 16620 r -> r.run(), listener)); 16621 } 16622 16623 /** 16624 * Make sure per profile network preferences behave as expected when two slices with 16625 * two different apps within same user profile is configured 16626 * Make sure per profile network preferences overrides with latest preference when 16627 * same user preference is set twice 16628 */ 16629 @Test 16630 public void testSetPreferenceWithOverridingPreference() 16631 throws Exception { 16632 final InOrder inOrder = inOrder(mMockNetd); 16633 final UserHandle testHandle = setupEnterpriseNetwork(); 16634 mServiceContext.setWorkProfile(testHandle, true); 16635 registerDefaultNetworkCallbacks(); 16636 16637 final TestNetworkCallback appCb1 = new TestNetworkCallback(); 16638 final TestNetworkCallback appCb2 = new TestNetworkCallback(); 16639 final TestNetworkCallback appCb3 = new TestNetworkCallback(); 16640 16641 final int testWorkProfileAppUid1 = 16642 UserHandle.getUid(testHandle.getIdentifier(), TEST_APP_ID); 16643 final int testWorkProfileAppUid2 = 16644 UserHandle.getUid(testHandle.getIdentifier(), TEST_APP_ID_2); 16645 final int testWorkProfileAppUid3 = 16646 UserHandle.getUid(testHandle.getIdentifier(), TEST_APP_ID_3); 16647 16648 registerDefaultNetworkCallbackAsUid(appCb1, testWorkProfileAppUid1); 16649 registerDefaultNetworkCallbackAsUid(appCb2, testWorkProfileAppUid2); 16650 registerDefaultNetworkCallbackAsUid(appCb3, testWorkProfileAppUid3); 16651 16652 // Connect both a regular cell agent and an enterprise network first. 16653 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 16654 mCellAgent.connect(true); 16655 16656 final TestNetworkAgentWrapper workAgent1 = makeEnterpriseNetworkAgent(NET_ENTERPRISE_ID_1); 16657 final TestNetworkAgentWrapper workAgent2 = makeEnterpriseNetworkAgent(NET_ENTERPRISE_ID_2); 16658 workAgent1.connect(true); 16659 workAgent2.connect(true); 16660 16661 mSystemDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 16662 mDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 16663 16664 appCb1.expectAvailableThenValidatedCallbacks(mCellAgent); 16665 appCb2.expectAvailableThenValidatedCallbacks(mCellAgent); 16666 appCb3.expectAvailableThenValidatedCallbacks(mCellAgent); 16667 16668 verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( 16669 mCellAgent.getNetwork().netId, INetd.PERMISSION_NONE)); 16670 verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( 16671 workAgent1.getNetwork().netId, INetd.PERMISSION_SYSTEM)); 16672 verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( 16673 workAgent2.getNetwork().netId, INetd.PERMISSION_SYSTEM)); 16674 16675 final TestOnCompleteListener listener = new TestOnCompleteListener(); 16676 16677 // Set preferences for testHandle to map testWorkProfileAppUid1 to 16678 // NET_ENTERPRISE_ID_1 and testWorkProfileAppUid2 to NET_ENTERPRISE_ID_2. 16679 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder1 = 16680 new ProfileNetworkPreference.Builder(); 16681 profileNetworkPreferenceBuilder1.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE); 16682 profileNetworkPreferenceBuilder1.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1); 16683 profileNetworkPreferenceBuilder1.setIncludedUids(new int[]{testWorkProfileAppUid1}); 16684 16685 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder2 = 16686 new ProfileNetworkPreference.Builder(); 16687 profileNetworkPreferenceBuilder2.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE); 16688 profileNetworkPreferenceBuilder2.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_2); 16689 profileNetworkPreferenceBuilder2.setIncludedUids(new int[]{testWorkProfileAppUid2}); 16690 16691 mCm.setProfileNetworkPreferences(testHandle, 16692 List.of(profileNetworkPreferenceBuilder1.build(), 16693 profileNetworkPreferenceBuilder2.build()), 16694 r -> r.run(), listener); 16695 listener.expectOnComplete(); 16696 verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 16697 workAgent2.getNetwork().netId, 16698 uidRangeFor(testHandle, profileNetworkPreferenceBuilder2.build()), 16699 PREFERENCE_ORDER_PROFILE)); 16700 verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 16701 workAgent1.getNetwork().netId, 16702 uidRangeFor(testHandle, profileNetworkPreferenceBuilder1.build()), 16703 PREFERENCE_ORDER_PROFILE)); 16704 16705 assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback); 16706 appCb1.expectAvailableCallbacksValidated(workAgent1); 16707 appCb2.expectAvailableCallbacksValidated(workAgent2); 16708 16709 // Set preferences for testHandle to map testWorkProfileAppUid3 to 16710 // to NET_ENTERPRISE_ID_1. 16711 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder3 = 16712 new ProfileNetworkPreference.Builder(); 16713 profileNetworkPreferenceBuilder3.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE); 16714 profileNetworkPreferenceBuilder3.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1); 16715 profileNetworkPreferenceBuilder3.setIncludedUids(new int[]{testWorkProfileAppUid3}); 16716 16717 mCm.setProfileNetworkPreferences(testHandle, 16718 List.of(profileNetworkPreferenceBuilder3.build()), 16719 r -> r.run(), listener); 16720 listener.expectOnComplete(); 16721 verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 16722 workAgent1.getNetwork().netId, 16723 uidRangeFor(testHandle, profileNetworkPreferenceBuilder3.build()), 16724 PREFERENCE_ORDER_PROFILE)); 16725 verify(mMockNetd).networkRemoveUidRangesParcel(new NativeUidRangeConfig( 16726 workAgent2.getNetwork().netId, 16727 uidRangeFor(testHandle, profileNetworkPreferenceBuilder2.build()), 16728 PREFERENCE_ORDER_PROFILE)); 16729 verify(mMockNetd).networkRemoveUidRangesParcel(new NativeUidRangeConfig( 16730 workAgent1.getNetwork().netId, 16731 uidRangeFor(testHandle, profileNetworkPreferenceBuilder1.build()), 16732 PREFERENCE_ORDER_PROFILE)); 16733 16734 assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback); 16735 appCb3.expectAvailableCallbacksValidated(workAgent1); 16736 appCb2.expectAvailableCallbacksValidated(mCellAgent); 16737 appCb1.expectAvailableCallbacksValidated(mCellAgent); 16738 16739 // Set the preferences for testHandle to default. 16740 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder = 16741 new ProfileNetworkPreference.Builder(); 16742 profileNetworkPreferenceBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_DEFAULT); 16743 16744 mCm.setProfileNetworkPreferences(testHandle, 16745 List.of(profileNetworkPreferenceBuilder.build()), 16746 r -> r.run(), listener); 16747 listener.expectOnComplete(); 16748 verify(mMockNetd).networkRemoveUidRangesParcel(new NativeUidRangeConfig( 16749 workAgent1.getNetwork().netId, 16750 uidRangeFor(testHandle, profileNetworkPreferenceBuilder3.build()), 16751 PREFERENCE_ORDER_PROFILE)); 16752 16753 assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback, appCb1, appCb2); 16754 appCb3.expectAvailableCallbacksValidated(mCellAgent); 16755 workAgent2.disconnect(); 16756 mCellAgent.disconnect(); 16757 16758 mCm.unregisterNetworkCallback(appCb1); 16759 mCm.unregisterNetworkCallback(appCb2); 16760 mCm.unregisterNetworkCallback(appCb3); 16761 // Other callbacks will be unregistered by tearDown() 16762 } 16763 16764 private NetworkCallback requestForEnterpriseId(@NetworkCapabilities.EnterpriseId final int id) { 16765 final NetworkCapabilities nc = new NetworkCapabilities.Builder() 16766 .addCapability(NET_CAPABILITY_ENTERPRISE).addEnterpriseId(id).build(); 16767 final NetworkRequest req = new NetworkRequest.Builder().setCapabilities(nc).build(); 16768 final NetworkCallback cb = new TestableNetworkCallback(); 16769 mCm.requestNetwork(req, cb); 16770 return cb; 16771 } 16772 16773 /** 16774 * Make sure per profile network preferences behave as expected when multiple slices with 16775 * multiple different apps within same user profile is configured. 16776 */ 16777 @Test 16778 public void testSetPreferenceWithMultiplePreferences() 16779 throws Exception { 16780 final UserHandle testHandle = setupEnterpriseNetwork(); 16781 mServiceContext.setWorkProfile(testHandle, true); 16782 registerDefaultNetworkCallbacks(); 16783 16784 final TestNetworkCallback appCb1 = new TestNetworkCallback(); 16785 final TestNetworkCallback appCb2 = new TestNetworkCallback(); 16786 final TestNetworkCallback appCb3 = new TestNetworkCallback(); 16787 final TestNetworkCallback appCb4 = new TestNetworkCallback(); 16788 final TestNetworkCallback appCb5 = new TestNetworkCallback(); 16789 16790 final int testWorkProfileAppUid1 = 16791 UserHandle.getUid(testHandle.getIdentifier(), TEST_APP_ID); 16792 final int testWorkProfileAppUid2 = 16793 UserHandle.getUid(testHandle.getIdentifier(), TEST_APP_ID_2); 16794 final int testWorkProfileAppUid3 = 16795 UserHandle.getUid(testHandle.getIdentifier(), TEST_APP_ID_3); 16796 final int testWorkProfileAppUid4 = 16797 UserHandle.getUid(testHandle.getIdentifier(), TEST_APP_ID_4); 16798 final int testWorkProfileAppUid5 = 16799 UserHandle.getUid(testHandle.getIdentifier(), TEST_APP_ID_5); 16800 16801 registerDefaultNetworkCallbackAsUid(appCb1, testWorkProfileAppUid1); 16802 registerDefaultNetworkCallbackAsUid(appCb2, testWorkProfileAppUid2); 16803 registerDefaultNetworkCallbackAsUid(appCb3, testWorkProfileAppUid3); 16804 registerDefaultNetworkCallbackAsUid(appCb4, testWorkProfileAppUid4); 16805 registerDefaultNetworkCallbackAsUid(appCb5, testWorkProfileAppUid5); 16806 16807 // Connect both a regular cell agent and an enterprise network first. 16808 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 16809 mCellAgent.connect(true); 16810 16811 final TestNetworkAgentWrapper workAgent1 = makeEnterpriseNetworkAgent(NET_ENTERPRISE_ID_1); 16812 final TestNetworkAgentWrapper workAgent2 = makeEnterpriseNetworkAgent(NET_ENTERPRISE_ID_2); 16813 final TestNetworkAgentWrapper workAgent3 = makeEnterpriseNetworkAgent(NET_ENTERPRISE_ID_3); 16814 final TestNetworkAgentWrapper workAgent4 = makeEnterpriseNetworkAgent(NET_ENTERPRISE_ID_4); 16815 final TestNetworkAgentWrapper workAgent5 = makeEnterpriseNetworkAgent(NET_ENTERPRISE_ID_5); 16816 16817 final NetworkCallback keepupCb1 = requestForEnterpriseId(NET_ENTERPRISE_ID_1); 16818 final NetworkCallback keepupCb2 = requestForEnterpriseId(NET_ENTERPRISE_ID_2); 16819 final NetworkCallback keepupCb3 = requestForEnterpriseId(NET_ENTERPRISE_ID_3); 16820 final NetworkCallback keepupCb4 = requestForEnterpriseId(NET_ENTERPRISE_ID_4); 16821 final NetworkCallback keepupCb5 = requestForEnterpriseId(NET_ENTERPRISE_ID_5); 16822 16823 workAgent1.connect(true); 16824 workAgent2.connect(true); 16825 workAgent3.connect(true); 16826 workAgent4.connect(true); 16827 workAgent5.connect(true); 16828 16829 mSystemDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 16830 mDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 16831 appCb1.expectAvailableThenValidatedCallbacks(mCellAgent); 16832 appCb2.expectAvailableThenValidatedCallbacks(mCellAgent); 16833 appCb3.expectAvailableThenValidatedCallbacks(mCellAgent); 16834 appCb4.expectAvailableThenValidatedCallbacks(mCellAgent); 16835 appCb5.expectAvailableThenValidatedCallbacks(mCellAgent); 16836 16837 verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( 16838 mCellAgent.getNetwork().netId, INetd.PERMISSION_NONE)); 16839 verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( 16840 workAgent1.getNetwork().netId, INetd.PERMISSION_SYSTEM)); 16841 verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( 16842 workAgent2.getNetwork().netId, INetd.PERMISSION_SYSTEM)); 16843 verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( 16844 workAgent3.getNetwork().netId, INetd.PERMISSION_SYSTEM)); 16845 verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( 16846 workAgent4.getNetwork().netId, INetd.PERMISSION_SYSTEM)); 16847 verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( 16848 workAgent5.getNetwork().netId, INetd.PERMISSION_SYSTEM)); 16849 16850 final TestOnCompleteListener listener = new TestOnCompleteListener(); 16851 16852 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder1 = 16853 new ProfileNetworkPreference.Builder(); 16854 profileNetworkPreferenceBuilder1.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE); 16855 profileNetworkPreferenceBuilder1.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1); 16856 profileNetworkPreferenceBuilder1.setIncludedUids(new int[]{testWorkProfileAppUid1}); 16857 16858 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder2 = 16859 new ProfileNetworkPreference.Builder(); 16860 profileNetworkPreferenceBuilder2.setPreference( 16861 PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK); 16862 profileNetworkPreferenceBuilder2.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_2); 16863 profileNetworkPreferenceBuilder2.setIncludedUids(new int[]{testWorkProfileAppUid2}); 16864 16865 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder3 = 16866 new ProfileNetworkPreference.Builder(); 16867 profileNetworkPreferenceBuilder3.setPreference( 16868 PROFILE_NETWORK_PREFERENCE_ENTERPRISE); 16869 profileNetworkPreferenceBuilder3.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_3); 16870 profileNetworkPreferenceBuilder3.setIncludedUids(new int[]{testWorkProfileAppUid3}); 16871 16872 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder4 = 16873 new ProfileNetworkPreference.Builder(); 16874 profileNetworkPreferenceBuilder4.setPreference( 16875 PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK); 16876 profileNetworkPreferenceBuilder4.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_4); 16877 profileNetworkPreferenceBuilder4.setIncludedUids(new int[]{testWorkProfileAppUid4}); 16878 16879 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder5 = 16880 new ProfileNetworkPreference.Builder(); 16881 profileNetworkPreferenceBuilder5.setPreference( 16882 PROFILE_NETWORK_PREFERENCE_ENTERPRISE); 16883 profileNetworkPreferenceBuilder5.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_5); 16884 profileNetworkPreferenceBuilder5.setIncludedUids(new int[]{testWorkProfileAppUid5}); 16885 16886 mCm.setProfileNetworkPreferences(testHandle, 16887 List.of(profileNetworkPreferenceBuilder1.build(), 16888 profileNetworkPreferenceBuilder2.build(), 16889 profileNetworkPreferenceBuilder3.build(), 16890 profileNetworkPreferenceBuilder4.build(), 16891 profileNetworkPreferenceBuilder5.build()), 16892 r -> r.run(), listener); 16893 16894 listener.expectOnComplete(); 16895 16896 verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 16897 workAgent1.getNetwork().netId, 16898 uidRangeFor(testHandle, profileNetworkPreferenceBuilder1.build()), 16899 PREFERENCE_ORDER_PROFILE)); 16900 verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 16901 workAgent2.getNetwork().netId, 16902 uidRangeFor(testHandle, profileNetworkPreferenceBuilder2.build()), 16903 PREFERENCE_ORDER_PROFILE)); 16904 verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 16905 workAgent3.getNetwork().netId, 16906 uidRangeFor(testHandle, profileNetworkPreferenceBuilder3.build()), 16907 PREFERENCE_ORDER_PROFILE)); 16908 verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 16909 workAgent4.getNetwork().netId, 16910 uidRangeFor(testHandle, profileNetworkPreferenceBuilder4.build()), 16911 PREFERENCE_ORDER_PROFILE)); 16912 verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 16913 workAgent5.getNetwork().netId, 16914 uidRangeFor(testHandle, profileNetworkPreferenceBuilder5.build()), 16915 PREFERENCE_ORDER_PROFILE)); 16916 16917 assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback); 16918 appCb1.expectAvailableCallbacksValidated(workAgent1); 16919 appCb2.expectAvailableCallbacksValidated(workAgent2); 16920 appCb3.expectAvailableCallbacksValidated(workAgent3); 16921 appCb4.expectAvailableCallbacksValidated(workAgent4); 16922 appCb5.expectAvailableCallbacksValidated(workAgent5); 16923 16924 workAgent1.disconnect(); 16925 workAgent2.disconnect(); 16926 workAgent3.disconnect(); 16927 workAgent4.disconnect(); 16928 workAgent5.disconnect(); 16929 16930 appCb1.expect(LOST, workAgent1); 16931 appCb2.expect(LOST, workAgent2); 16932 appCb3.expect(LOST, workAgent3); 16933 appCb4.expect(LOST, workAgent4); 16934 appCb5.expect(LOST, workAgent5); 16935 16936 appCb1.expectAvailableCallbacksValidated(mCellAgent); 16937 appCb2.assertNoCallback(); 16938 appCb3.expectAvailableCallbacksValidated(mCellAgent); 16939 appCb4.assertNoCallback(); 16940 appCb5.expectAvailableCallbacksValidated(mCellAgent); 16941 16942 verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 16943 mCellAgent.getNetwork().netId, 16944 uidRangeFor(testHandle, profileNetworkPreferenceBuilder1.build()), 16945 PREFERENCE_ORDER_PROFILE)); 16946 verify(mMockNetd, never()).networkAddUidRangesParcel(new NativeUidRangeConfig( 16947 mCellAgent.getNetwork().netId, 16948 uidRangeFor(testHandle, profileNetworkPreferenceBuilder2.build()), 16949 PREFERENCE_ORDER_PROFILE)); 16950 verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 16951 mCellAgent.getNetwork().netId, 16952 uidRangeFor(testHandle, profileNetworkPreferenceBuilder3.build()), 16953 PREFERENCE_ORDER_PROFILE)); 16954 verify(mMockNetd, never()).networkAddUidRangesParcel(new NativeUidRangeConfig( 16955 mCellAgent.getNetwork().netId, 16956 uidRangeFor(testHandle, profileNetworkPreferenceBuilder4.build()), 16957 PREFERENCE_ORDER_PROFILE)); 16958 verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 16959 mCellAgent.getNetwork().netId, 16960 uidRangeFor(testHandle, profileNetworkPreferenceBuilder5.build()), 16961 PREFERENCE_ORDER_PROFILE)); 16962 16963 mSystemDefaultNetworkCallback.assertNoCallback(); 16964 mDefaultNetworkCallback.assertNoCallback(); 16965 16966 // Set the preferences for testHandle to default. 16967 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder = 16968 new ProfileNetworkPreference.Builder(); 16969 profileNetworkPreferenceBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_DEFAULT); 16970 16971 mCm.setProfileNetworkPreferences(testHandle, 16972 List.of(profileNetworkPreferenceBuilder.build()), 16973 r -> r.run(), listener); 16974 listener.expectOnComplete(); 16975 assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback, appCb1, appCb3, 16976 appCb5); 16977 appCb2.expectAvailableCallbacksValidated(mCellAgent); 16978 appCb4.expectAvailableCallbacksValidated(mCellAgent); 16979 mCellAgent.disconnect(); 16980 16981 mCm.unregisterNetworkCallback(keepupCb1); 16982 mCm.unregisterNetworkCallback(keepupCb2); 16983 mCm.unregisterNetworkCallback(keepupCb3); 16984 mCm.unregisterNetworkCallback(keepupCb4); 16985 mCm.unregisterNetworkCallback(keepupCb5); 16986 16987 mCm.unregisterNetworkCallback(appCb1); 16988 mCm.unregisterNetworkCallback(appCb2); 16989 mCm.unregisterNetworkCallback(appCb3); 16990 mCm.unregisterNetworkCallback(appCb4); 16991 mCm.unregisterNetworkCallback(appCb5); 16992 // Other callbacks will be unregistered by tearDown() 16993 } 16994 16995 /** 16996 * Test that, in a given networking context, calling setPreferenceForUser to set per-profile 16997 * defaults on then off works as expected. 16998 */ 16999 @Test 17000 public void testSetPreferenceForUserOnOff() throws Exception { 17001 final InOrder inOrder = inOrder(mMockNetd); 17002 final UserHandle testHandle = setupEnterpriseNetwork(); 17003 17004 // Connect both a regular cell agent and an enterprise network first. 17005 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 17006 mCellAgent.connect(true); 17007 17008 final TestNetworkAgentWrapper workAgent = makeEnterpriseNetworkAgent(); 17009 workAgent.connect(true); 17010 17011 final TestOnCompleteListener listener = new TestOnCompleteListener(); 17012 mCm.setProfileNetworkPreference(testHandle, PROFILE_NETWORK_PREFERENCE_ENTERPRISE, 17013 r -> r.run(), listener); 17014 listener.expectOnComplete(); 17015 inOrder.verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( 17016 mCellAgent.getNetwork().netId, INetd.PERMISSION_NONE)); 17017 inOrder.verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 17018 workAgent.getNetwork().netId, uidRangeFor(testHandle), PREFERENCE_ORDER_PROFILE)); 17019 17020 registerDefaultNetworkCallbacks(); 17021 17022 mSystemDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellAgent); 17023 mDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellAgent); 17024 mProfileDefaultNetworkCallback.expectAvailableCallbacksValidated(workAgent); 17025 17026 mCm.setProfileNetworkPreference(testHandle, PROFILE_NETWORK_PREFERENCE_DEFAULT, 17027 r -> r.run(), listener); 17028 listener.expectOnComplete(); 17029 17030 mProfileDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellAgent); 17031 assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback); 17032 inOrder.verify(mMockNetd).networkRemoveUidRangesParcel(new NativeUidRangeConfig( 17033 workAgent.getNetwork().netId, uidRangeFor(testHandle), PREFERENCE_ORDER_PROFILE)); 17034 17035 workAgent.disconnect(); 17036 mCellAgent.disconnect(); 17037 17038 // Callbacks will be unregistered by tearDown() 17039 } 17040 17041 /** 17042 * Test per-profile default networks for two different profiles concurrently. 17043 */ 17044 @Test 17045 public void testSetPreferenceForTwoProfiles() throws Exception { 17046 final InOrder inOrder = inOrder(mMockNetd); 17047 final UserHandle testHandle2 = setupEnterpriseNetwork(); 17048 final UserHandle testHandle4 = UserHandle.of(TEST_WORK_PROFILE_USER_ID + 2); 17049 mServiceContext.setWorkProfile(testHandle4, true); 17050 registerDefaultNetworkCallbacks(); 17051 17052 final TestNetworkCallback app4Cb = new TestNetworkCallback(); 17053 final int testWorkProfileAppUid4 = 17054 UserHandle.getUid(testHandle4.getIdentifier(), TEST_APP_ID); 17055 registerDefaultNetworkCallbackAsUid(app4Cb, testWorkProfileAppUid4); 17056 17057 // Connect both a regular cell agent and an enterprise network first. 17058 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 17059 mCellAgent.connect(true); 17060 17061 final TestNetworkAgentWrapper workAgent = makeEnterpriseNetworkAgent(); 17062 workAgent.connect(true); 17063 17064 mSystemDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 17065 mDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 17066 mProfileDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 17067 app4Cb.expectAvailableThenValidatedCallbacks(mCellAgent); 17068 inOrder.verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( 17069 mCellAgent.getNetwork().netId, INetd.PERMISSION_NONE)); 17070 inOrder.verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( 17071 workAgent.getNetwork().netId, INetd.PERMISSION_SYSTEM)); 17072 17073 final TestOnCompleteListener listener = new TestOnCompleteListener(); 17074 mCm.setProfileNetworkPreference(testHandle2, PROFILE_NETWORK_PREFERENCE_ENTERPRISE, 17075 r -> r.run(), listener); 17076 listener.expectOnComplete(); 17077 inOrder.verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 17078 workAgent.getNetwork().netId, uidRangeFor(testHandle2), PREFERENCE_ORDER_PROFILE)); 17079 17080 mProfileDefaultNetworkCallback.expectAvailableCallbacksValidated(workAgent); 17081 assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback, 17082 app4Cb); 17083 17084 mCm.setProfileNetworkPreference(testHandle4, PROFILE_NETWORK_PREFERENCE_ENTERPRISE, 17085 r -> r.run(), listener); 17086 listener.expectOnComplete(); 17087 inOrder.verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 17088 workAgent.getNetwork().netId, uidRangeFor(testHandle4), PREFERENCE_ORDER_PROFILE)); 17089 17090 app4Cb.expectAvailableCallbacksValidated(workAgent); 17091 assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback, 17092 mProfileDefaultNetworkCallback); 17093 17094 mCm.setProfileNetworkPreference(testHandle2, PROFILE_NETWORK_PREFERENCE_DEFAULT, 17095 r -> r.run(), listener); 17096 listener.expectOnComplete(); 17097 inOrder.verify(mMockNetd).networkRemoveUidRangesParcel(new NativeUidRangeConfig( 17098 workAgent.getNetwork().netId, uidRangeFor(testHandle2), PREFERENCE_ORDER_PROFILE)); 17099 17100 mProfileDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellAgent); 17101 assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback, 17102 app4Cb); 17103 17104 workAgent.disconnect(); 17105 mCellAgent.disconnect(); 17106 17107 mCm.unregisterNetworkCallback(app4Cb); 17108 // Other callbacks will be unregistered by tearDown() 17109 } 17110 17111 @Test 17112 public void testProfilePreferenceRemovedUponUserRemoved() throws Exception { 17113 final InOrder inOrder = inOrder(mMockNetd); 17114 final UserHandle testHandle = setupEnterpriseNetwork(); 17115 17116 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 17117 mCellAgent.connect(true); 17118 17119 final TestOnCompleteListener listener = new TestOnCompleteListener(); 17120 mCm.setProfileNetworkPreference(testHandle, PROFILE_NETWORK_PREFERENCE_ENTERPRISE, 17121 r -> r.run(), listener); 17122 listener.expectOnComplete(); 17123 inOrder.verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( 17124 mCellAgent.getNetwork().netId, INetd.PERMISSION_NONE)); 17125 inOrder.verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig( 17126 mCellAgent.getNetwork().netId, uidRangeFor(testHandle), 17127 PREFERENCE_ORDER_PROFILE)); 17128 17129 final Intent removedIntent = new Intent(ACTION_USER_REMOVED); 17130 removedIntent.putExtra(Intent.EXTRA_USER, testHandle); 17131 processBroadcast(removedIntent); 17132 17133 inOrder.verify(mMockNetd).networkRemoveUidRangesParcel(new NativeUidRangeConfig( 17134 mCellAgent.getNetwork().netId, uidRangeFor(testHandle), 17135 PREFERENCE_ORDER_PROFILE)); 17136 } 17137 17138 @Test 17139 public void testProfileNetworkPreferenceBlocking_addUser() throws Exception { 17140 final InOrder inOrder = inOrder(mMockNetd); 17141 doReturn(asList(PRIMARY_USER_HANDLE)).when(mUserManager).getUserHandles(anyBoolean()); 17142 17143 // Only one network 17144 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 17145 mCellAgent.connect(true); 17146 17147 // Verify uid ranges 0~99999 are allowed 17148 final ArraySet<UidRange> allowedRanges = new ArraySet<>(); 17149 allowedRanges.add(PRIMARY_UIDRANGE); 17150 final NativeUidRangeConfig config1User = new NativeUidRangeConfig( 17151 mCellAgent.getNetwork().netId, 17152 toUidRangeStableParcels(allowedRanges), 17153 0 /* subPriority */); 17154 if (mDeps.isAtLeastU()) { 17155 inOrder.verify(mMockNetd).setNetworkAllowlist(new NativeUidRangeConfig[]{config1User}); 17156 } else { 17157 inOrder.verify(mMockNetd, never()).setNetworkAllowlist(any()); 17158 } 17159 17160 doReturn(asList(PRIMARY_USER_HANDLE, SECONDARY_USER_HANDLE)) 17161 .when(mUserManager).getUserHandles(anyBoolean()); 17162 final Intent addedIntent = new Intent(ACTION_USER_ADDED); 17163 addedIntent.putExtra(Intent.EXTRA_USER, UserHandle.of(SECONDARY_USER)); 17164 processBroadcast(addedIntent); 17165 17166 // Make sure the allow list has been updated. 17167 allowedRanges.add(UidRange.createForUser(SECONDARY_USER_HANDLE)); 17168 final NativeUidRangeConfig config2Users = new NativeUidRangeConfig( 17169 mCellAgent.getNetwork().netId, 17170 toUidRangeStableParcels(allowedRanges), 17171 0 /* subPriority */); 17172 if (mDeps.isAtLeastU()) { 17173 inOrder.verify(mMockNetd).setNetworkAllowlist(new NativeUidRangeConfig[]{config2Users}); 17174 } else { 17175 inOrder.verify(mMockNetd, never()).setNetworkAllowlist(any()); 17176 } 17177 } 17178 17179 @Test 17180 public void testProfileNetworkPreferenceBlocking_changePreference() throws Exception { 17181 final InOrder inOrder = inOrder(mMockNetd); 17182 final UserHandle testHandle = setupEnterpriseNetwork(); 17183 doReturn(asList(PRIMARY_USER_HANDLE, testHandle)) 17184 .when(mUserManager).getUserHandles(anyBoolean()); 17185 17186 // Start with 1 default network and 1 enterprise network, both networks should 17187 // not be restricted since the blocking preference is not set yet. 17188 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 17189 mCellAgent.connect(true); 17190 17191 // Verify uid ranges 0~99999, 200000~299999 are all allowed for cellular. 17192 final UidRange profileUidRange = 17193 UidRange.createForUser(UserHandle.of(TEST_WORK_PROFILE_USER_ID)); 17194 ArraySet<UidRange> allowedAllUidRanges = new ArraySet<>(); 17195 allowedAllUidRanges.add(PRIMARY_UIDRANGE); 17196 allowedAllUidRanges.add(profileUidRange); 17197 final UidRangeParcel[] allowAllUidRangesParcel = toUidRangeStableParcels( 17198 allowedAllUidRanges); 17199 final NativeUidRangeConfig cellAllAllowedConfig = new NativeUidRangeConfig( 17200 mCellAgent.getNetwork().netId, 17201 allowAllUidRangesParcel, 17202 0 /* subPriority */); 17203 if (mDeps.isAtLeastU()) { 17204 inOrder.verify(mMockNetd).setNetworkAllowlist( 17205 new NativeUidRangeConfig[]{cellAllAllowedConfig}); 17206 } else { 17207 inOrder.verify(mMockNetd, never()).setNetworkAllowlist(any()); 17208 } 17209 17210 // Verify the same uid ranges are also applied for enterprise network. 17211 final TestNetworkAgentWrapper enterpriseAgent = makeEnterpriseNetworkAgent( 17212 NET_ENTERPRISE_ID_1); 17213 enterpriseAgent.connect(true); 17214 final NativeUidRangeConfig enterpriseAllAllowedConfig = new NativeUidRangeConfig( 17215 enterpriseAgent.getNetwork().netId, 17216 allowAllUidRangesParcel, 17217 0 /* subPriority */); 17218 // Network agents are stored in an ArraySet which does not guarantee the order and 17219 // making the order of the list undeterministic. Thus, verify this in order insensitive way. 17220 final ArgumentCaptor<NativeUidRangeConfig[]> configsCaptor = ArgumentCaptor.forClass( 17221 NativeUidRangeConfig[].class); 17222 if (mDeps.isAtLeastU()) { 17223 inOrder.verify(mMockNetd).setNetworkAllowlist(configsCaptor.capture()); 17224 assertContainsAll(List.of(configsCaptor.getValue()), 17225 List.of(cellAllAllowedConfig, enterpriseAllAllowedConfig)); 17226 } else { 17227 inOrder.verify(mMockNetd, never()).setNetworkAllowlist(any()); 17228 } 17229 17230 // Setup profile preference which only applies to test app uid on the managed profile. 17231 ProfileNetworkPreference.Builder prefBuilder = new ProfileNetworkPreference.Builder(); 17232 prefBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE_BLOCKING) 17233 .setIncludedUids(new int[]{testHandle.getUid(TEST_WORK_PROFILE_APP_UID)}) 17234 .setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1); 17235 final TestOnCompleteListener listener = new TestOnCompleteListener(); 17236 mCm.setProfileNetworkPreferences(testHandle, 17237 List.of(prefBuilder.build()), 17238 r -> r.run(), listener); 17239 listener.expectOnComplete(); 17240 17241 // Verify Netd is called for the preferences changed. 17242 // Cell: 0~99999, 200000~TEST_APP_UID-1, TEST_APP_UID+1~299999 17243 // Enterprise: 0~99999, 200000~299999 17244 final ArraySet<UidRange> excludeAppRanges = new ArraySet<>(); 17245 excludeAppRanges.add(PRIMARY_UIDRANGE); 17246 excludeAppRanges.addAll(UidRangeUtils.removeRangeSetFromUidRange( 17247 profileUidRange, 17248 new ArraySet(new UidRange[]{ 17249 (new UidRange(TEST_WORK_PROFILE_APP_UID, TEST_WORK_PROFILE_APP_UID))}) 17250 )); 17251 final UidRangeParcel[] excludeAppRangesParcel = toUidRangeStableParcels(excludeAppRanges); 17252 final NativeUidRangeConfig cellExcludeAppConfig = new NativeUidRangeConfig( 17253 mCellAgent.getNetwork().netId, 17254 excludeAppRangesParcel, 17255 0 /* subPriority */); 17256 if (mDeps.isAtLeastU()) { 17257 inOrder.verify(mMockNetd).setNetworkAllowlist(configsCaptor.capture()); 17258 assertContainsAll(List.of(configsCaptor.getValue()), 17259 List.of(cellExcludeAppConfig, enterpriseAllAllowedConfig)); 17260 } else { 17261 inOrder.verify(mMockNetd, never()).setNetworkAllowlist(any()); 17262 } 17263 17264 // Verify unset by giving all allowed set for all users when the preference got removed. 17265 mCm.setProfileNetworkPreference(testHandle, PROFILE_NETWORK_PREFERENCE_ENTERPRISE, 17266 r -> r.run(), listener); 17267 listener.expectOnComplete(); 17268 if (mDeps.isAtLeastU()) { 17269 inOrder.verify(mMockNetd).setNetworkAllowlist(configsCaptor.capture()); 17270 assertContainsAll(List.of(configsCaptor.getValue()), 17271 List.of(cellAllAllowedConfig, enterpriseAllAllowedConfig)); 17272 } else { 17273 inOrder.verify(mMockNetd, never()).setNetworkAllowlist(any()); 17274 } 17275 17276 // Verify issuing with cellular set only when a network with enterprise capability 17277 // disconnects. 17278 enterpriseAgent.disconnect(); 17279 waitForIdle(); 17280 if (mDeps.isAtLeastU()) { 17281 inOrder.verify(mMockNetd).setNetworkAllowlist( 17282 new NativeUidRangeConfig[]{cellAllAllowedConfig}); 17283 } else { 17284 inOrder.verify(mMockNetd, never()).setNetworkAllowlist(any()); 17285 } 17286 } 17287 17288 @Test 17289 public void testProfileNetworkPreferenceBlocking_networkChanges() throws Exception { 17290 final InOrder inOrder = inOrder(mMockNetd); 17291 final UserHandle testHandle = setupEnterpriseNetwork(); 17292 doReturn(asList(PRIMARY_USER_HANDLE, testHandle)) 17293 .when(mUserManager).getUserHandles(anyBoolean()); 17294 17295 // Setup profile preference which only applies to test app uid on the managed profile. 17296 ProfileNetworkPreference.Builder prefBuilder = new ProfileNetworkPreference.Builder(); 17297 prefBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE_BLOCKING) 17298 .setIncludedUids(new int[]{testHandle.getUid(TEST_WORK_PROFILE_APP_UID)}) 17299 .setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1); 17300 final TestOnCompleteListener listener = new TestOnCompleteListener(); 17301 mCm.setProfileNetworkPreferences(testHandle, 17302 List.of(prefBuilder.build()), 17303 r -> r.run(), listener); 17304 listener.expectOnComplete(); 17305 if (mDeps.isAtLeastU()) { 17306 inOrder.verify(mMockNetd).setNetworkAllowlist(new NativeUidRangeConfig[]{}); 17307 } else { 17308 inOrder.verify(mMockNetd, never()).setNetworkAllowlist(any()); 17309 } 17310 17311 // Start with 1 default network, which should be restricted since the blocking 17312 // preference is already set. 17313 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 17314 mCellAgent.connect(true); 17315 17316 // Verify cellular network applies to the allow list. 17317 // Cell: 0~99999, 200000~TEST_APP_UID-1, TEST_APP_UID+1~299999 17318 // Enterprise: 0~99999, 200000~299999 17319 final ArraySet<UidRange> excludeAppRanges = new ArraySet<>(); 17320 final UidRange profileUidRange = 17321 UidRange.createForUser(UserHandle.of(TEST_WORK_PROFILE_USER_ID)); 17322 excludeAppRanges.add(PRIMARY_UIDRANGE); 17323 excludeAppRanges.addAll(UidRangeUtils.removeRangeSetFromUidRange( 17324 profileUidRange, 17325 new ArraySet(new UidRange[]{ 17326 (new UidRange(TEST_WORK_PROFILE_APP_UID, TEST_WORK_PROFILE_APP_UID))}) 17327 )); 17328 final UidRangeParcel[] excludeAppRangesParcel = toUidRangeStableParcels(excludeAppRanges); 17329 final NativeUidRangeConfig cellExcludeAppConfig = new NativeUidRangeConfig( 17330 mCellAgent.getNetwork().netId, 17331 excludeAppRangesParcel, 17332 0 /* subPriority */); 17333 if (mDeps.isAtLeastU()) { 17334 inOrder.verify(mMockNetd).setNetworkAllowlist( 17335 new NativeUidRangeConfig[]{cellExcludeAppConfig}); 17336 } else { 17337 inOrder.verify(mMockNetd, never()).setNetworkAllowlist(any()); 17338 } 17339 17340 // Verify enterprise network is not blocked for test app. 17341 final TestNetworkAgentWrapper enterpriseAgent = makeEnterpriseNetworkAgent( 17342 NET_ENTERPRISE_ID_1); 17343 enterpriseAgent.connect(true); 17344 ArraySet<UidRange> allowedAllUidRanges = new ArraySet<>(); 17345 allowedAllUidRanges.add(PRIMARY_UIDRANGE); 17346 allowedAllUidRanges.add(profileUidRange); 17347 final UidRangeParcel[] allowAllUidRangesParcel = toUidRangeStableParcels( 17348 allowedAllUidRanges); 17349 final NativeUidRangeConfig enterpriseAllAllowedConfig = new NativeUidRangeConfig( 17350 enterpriseAgent.getNetwork().netId, 17351 allowAllUidRangesParcel, 17352 0 /* subPriority */); 17353 // Network agents are stored in an ArraySet which does not guarantee the order and 17354 // making the order of the list undeterministic. Thus, verify this in order insensitive way. 17355 final ArgumentCaptor<NativeUidRangeConfig[]> configsCaptor = ArgumentCaptor.forClass( 17356 NativeUidRangeConfig[].class); 17357 if (mDeps.isAtLeastU()) { 17358 inOrder.verify(mMockNetd).setNetworkAllowlist(configsCaptor.capture()); 17359 assertContainsAll(List.of(configsCaptor.getValue()), 17360 List.of(enterpriseAllAllowedConfig, cellExcludeAppConfig)); 17361 } else { 17362 inOrder.verify(mMockNetd, never()).setNetworkAllowlist(any()); 17363 } 17364 17365 // Verify issuing with cellular set only when enterprise network disconnects. 17366 enterpriseAgent.disconnect(); 17367 waitForIdle(); 17368 if (mDeps.isAtLeastU()) { 17369 inOrder.verify(mMockNetd).setNetworkAllowlist( 17370 new NativeUidRangeConfig[]{cellExcludeAppConfig}); 17371 } else { 17372 inOrder.verify(mMockNetd, never()).setNetworkAllowlist(any()); 17373 } 17374 17375 mCellAgent.disconnect(); 17376 waitForIdle(); 17377 if (mDeps.isAtLeastU()) { 17378 inOrder.verify(mMockNetd).setNetworkAllowlist(new NativeUidRangeConfig[]{}); 17379 } else { 17380 inOrder.verify(mMockNetd, never()).setNetworkAllowlist(any()); 17381 } 17382 } 17383 17384 /** 17385 * Make sure wrong preferences for per-profile default networking are rejected. 17386 */ 17387 @Test 17388 public void testProfileNetworkPrefWrongPreference() throws Exception { 17389 final UserHandle testHandle = UserHandle.of(TEST_WORK_PROFILE_USER_ID); 17390 mServiceContext.setWorkProfile(testHandle, true); 17391 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder = 17392 new ProfileNetworkPreference.Builder(); 17393 profileNetworkPreferenceBuilder.setPreference( 17394 PROFILE_NETWORK_PREFERENCE_ENTERPRISE_BLOCKING + 1); 17395 profileNetworkPreferenceBuilder.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1); 17396 assertThrows("Should not be able to set an illegal preference", 17397 IllegalArgumentException.class, 17398 () -> mCm.setProfileNetworkPreferences(testHandle, 17399 List.of(profileNetworkPreferenceBuilder.build()), 17400 null, null)); 17401 } 17402 17403 /** 17404 * Make sure requests for per-profile default networking for a non-work profile are 17405 * rejected 17406 */ 17407 @Test 17408 public void testProfileNetworkPrefWrongProfile() throws Exception { 17409 final UserHandle testHandle = UserHandle.of(TEST_WORK_PROFILE_USER_ID); 17410 mServiceContext.setWorkProfile(testHandle, false); 17411 mServiceContext.setDeviceOwner(testHandle, null); 17412 assertThrows("Should not be able to set a user pref for a non-work profile " 17413 + "and non device owner", 17414 IllegalArgumentException.class , () -> 17415 mCm.setProfileNetworkPreference(testHandle, 17416 PROFILE_NETWORK_PREFERENCE_ENTERPRISE, null, null)); 17417 } 17418 17419 /** 17420 * Make sure requests for per-profile default networking for a device owner is 17421 * accepted on T and not accepted on S 17422 */ 17423 @Test 17424 public void testProfileNetworkDeviceOwner() throws Exception { 17425 final UserHandle testHandle = UserHandle.of(TEST_WORK_PROFILE_USER_ID); 17426 mServiceContext.setWorkProfile(testHandle, false); 17427 mServiceContext.setDeviceOwner(testHandle, "deviceOwnerPackage"); 17428 ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder = 17429 new ProfileNetworkPreference.Builder(); 17430 profileNetworkPreferenceBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE); 17431 profileNetworkPreferenceBuilder.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1); 17432 final TestOnCompleteListener listener = new TestOnCompleteListener(); 17433 if (mDeps.isAtLeastT()) { 17434 mCm.setProfileNetworkPreferences(testHandle, 17435 List.of(profileNetworkPreferenceBuilder.build()), 17436 r -> r.run(), listener); 17437 } else { 17438 // S should not allow setting preference on device owner 17439 assertThrows("Should not be able to set a user pref for a non-work profile on S", 17440 IllegalArgumentException.class , () -> 17441 mCm.setProfileNetworkPreferences(testHandle, 17442 List.of(profileNetworkPreferenceBuilder.build()), 17443 r -> r.run(), listener)); 17444 } 17445 } 17446 17447 @Test 17448 public void testSubIdsExist() throws Exception { 17449 final Set<Integer> subIds = Collections.singleton(Process.myUid()); 17450 final NetworkCapabilities nc = new NetworkCapabilities(); 17451 nc.setSubscriptionIds(subIds); 17452 17453 final NetworkCapabilities result = 17454 mService.networkCapabilitiesRestrictedForCallerPermissions( 17455 nc, Process.myPid(), Process.myUid()); 17456 assertEquals(subIds, result.getSubscriptionIds()); 17457 } 17458 17459 private NetworkRequest getRequestWithSubIds() { 17460 return new NetworkRequest.Builder() 17461 .setSubscriptionIds(Collections.singleton(Process.myUid())) 17462 .build(); 17463 } 17464 17465 private NetworkRequest getRestrictedRequestForWifiWithSubIds() { 17466 return new NetworkRequest.Builder() 17467 .addTransportType(NetworkCapabilities.TRANSPORT_WIFI) 17468 .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED) 17469 .setSubscriptionIds(Collections.singleton(TEST_SUBSCRIPTION_ID)) 17470 .build(); 17471 } 17472 17473 @Test 17474 public void testNetworkRequestWithSubIds() throws Exception { 17475 final PendingIntent pendingIntent = PendingIntent.getBroadcast( 17476 mContext, 0 /* requestCode */, new Intent("a"), FLAG_IMMUTABLE); 17477 final NetworkCallback networkCallback1 = new NetworkCallback(); 17478 final NetworkCallback networkCallback2 = new NetworkCallback(); 17479 17480 mCm.requestNetwork(getRequestWithSubIds(), networkCallback1); 17481 mCm.requestNetwork(getRequestWithSubIds(), pendingIntent); 17482 mCm.registerNetworkCallback(getRequestWithSubIds(), networkCallback2); 17483 17484 mCm.unregisterNetworkCallback(networkCallback1); 17485 mCm.releaseNetworkRequest(pendingIntent); 17486 mCm.unregisterNetworkCallback(networkCallback2); 17487 } 17488 17489 @Test 17490 @IgnoreUpTo(Build.VERSION_CODES.TIRAMISU) 17491 public void testCarrierConfigAppSendNetworkRequestForRestrictedWifi() throws Exception { 17492 mServiceContext.setPermission(CONNECTIVITY_USE_RESTRICTED_NETWORKS, PERMISSION_DENIED); 17493 doReturn(true).when(mCarrierPrivilegeAuthenticator) 17494 .isCarrierServiceUidForNetworkCapabilities(anyInt(), any()); 17495 final PendingIntent pendingIntent = PendingIntent.getBroadcast( 17496 mContext, 0 /* requestCode */, new Intent("a"), FLAG_IMMUTABLE); 17497 final NetworkCallback networkCallback1 = new NetworkCallback(); 17498 final NetworkCallback networkCallback2 = new NetworkCallback(); 17499 17500 mCm.requestNetwork( 17501 getRestrictedRequestForWifiWithSubIds(), networkCallback1); 17502 mCm.requestNetwork( 17503 getRestrictedRequestForWifiWithSubIds(), pendingIntent); 17504 mCm.registerNetworkCallback( 17505 getRestrictedRequestForWifiWithSubIds(), networkCallback2); 17506 17507 mCm.unregisterNetworkCallback(networkCallback1); 17508 mCm.releaseNetworkRequest(pendingIntent); 17509 mCm.unregisterNetworkCallback(networkCallback2); 17510 } 17511 17512 private void doTestNetworkRequestWithCarrierPrivilegesLost( 17513 boolean shouldGrantRestrictedNetworkPermission, 17514 int lostPrivilegeUid, 17515 int lostPrivilegeSubId, 17516 boolean expectUnavailable, 17517 boolean expectCapChanged) throws Exception { 17518 if (shouldGrantRestrictedNetworkPermission) { 17519 mServiceContext.setPermission(CONNECTIVITY_USE_RESTRICTED_NETWORKS, PERMISSION_GRANTED); 17520 } else { 17521 mServiceContext.setPermission(CONNECTIVITY_USE_RESTRICTED_NETWORKS, PERMISSION_DENIED); 17522 } 17523 17524 NetworkCapabilities filter = 17525 getRestrictedRequestForWifiWithSubIds().networkCapabilities; 17526 final HandlerThread handlerThread = new HandlerThread("testRestrictedFactoryRequests"); 17527 handlerThread.start(); 17528 17529 final MockNetworkFactory testFactory = new MockNetworkFactory(handlerThread.getLooper(), 17530 mServiceContext, "testFactory", filter, mCsHandlerThread); 17531 testFactory.register(); 17532 testFactory.assertRequestCountEquals(0); 17533 17534 doReturn(true).when(mCarrierPrivilegeAuthenticator) 17535 .isCarrierServiceUidForNetworkCapabilities(eq(Process.myUid()), any()); 17536 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 17537 final NetworkRequest networkrequest = 17538 getRestrictedRequestForWifiWithSubIds(); 17539 mCm.requestNetwork(networkrequest, networkCallback); 17540 testFactory.expectRequestAdd(); 17541 testFactory.assertRequestCountEquals(1); 17542 17543 NetworkCapabilities nc = new NetworkCapabilities.Builder(filter) 17544 .setAllowedUids(Set.of(Process.myUid())) 17545 .build(); 17546 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, new LinkProperties(), nc); 17547 mWiFiAgent.connect(false); 17548 networkCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 17549 final NetworkAgentInfo nai = mService.getNetworkAgentInfoForNetwork( 17550 mWiFiAgent.getNetwork()); 17551 17552 doReturn(false).when(mCarrierPrivilegeAuthenticator) 17553 .isCarrierServiceUidForNetworkCapabilities(eq(Process.myUid()), any()); 17554 doReturn(TEST_SUBSCRIPTION_ID).when(mCarrierPrivilegeAuthenticator) 17555 .getSubIdFromNetworkCapabilities(any()); 17556 17557 visibleOnHandlerThread(mCsHandlerThread.getThreadHandler(), () -> { 17558 mDeps.mCarrierPrivilegesLostListener.accept(lostPrivilegeUid, lostPrivilegeSubId); 17559 }); 17560 waitForIdle(); 17561 17562 if (expectCapChanged) { 17563 networkCallback.expect(NETWORK_CAPS_UPDATED); 17564 } 17565 if (expectUnavailable) { 17566 networkCallback.expect(UNAVAILABLE); 17567 } 17568 if (!expectCapChanged && !expectUnavailable) { 17569 networkCallback.assertNoCallback(); 17570 } 17571 17572 mWiFiAgent.disconnect(); 17573 17574 if (expectUnavailable) { 17575 testFactory.expectRequestRemove(); 17576 testFactory.assertRequestCountEquals(0); 17577 } else { 17578 testFactory.expectRequestAdd(); 17579 testFactory.assertRequestCountEquals(1); 17580 } 17581 17582 handlerThread.quitSafely(); 17583 handlerThread.join(); 17584 } 17585 17586 @Test 17587 @IgnoreUpTo(Build.VERSION_CODES.TIRAMISU) 17588 public void testRestrictedRequestRemovedDueToCarrierPrivilegesLost() throws Exception { 17589 doTestNetworkRequestWithCarrierPrivilegesLost( 17590 false /* shouldGrantRestrictedNetworkPermission */, 17591 Process.myUid(), 17592 TEST_SUBSCRIPTION_ID, 17593 true /* expectUnavailable */, 17594 true /* expectCapChanged */); 17595 } 17596 17597 @Test 17598 @IgnoreUpTo(Build.VERSION_CODES.TIRAMISU) 17599 public void testRequestNotRemoved_MismatchSubId() throws Exception { 17600 doTestNetworkRequestWithCarrierPrivilegesLost( 17601 false /* shouldGrantRestrictedNetworkPermission */, 17602 Process.myUid(), 17603 TEST_SUBSCRIPTION_ID + 1, 17604 false /* expectUnavailable */, 17605 false /* expectCapChanged */); 17606 } 17607 @Test 17608 @IgnoreUpTo(Build.VERSION_CODES.TIRAMISU) 17609 public void testRequestNotRemoved_MismatchUid() throws Exception { 17610 doTestNetworkRequestWithCarrierPrivilegesLost( 17611 false /* shouldGrantRestrictedNetworkPermission */, 17612 Process.myUid() + 1, 17613 TEST_SUBSCRIPTION_ID, 17614 false /* expectUnavailable */, 17615 false /* expectCapChanged */); 17616 } 17617 17618 @Test 17619 @IgnoreUpTo(Build.VERSION_CODES.TIRAMISU) 17620 public void testRequestNotRemoved_HasRestrictedNetworkPermission() throws Exception { 17621 doTestNetworkRequestWithCarrierPrivilegesLost( 17622 true /* shouldGrantRestrictedNetworkPermission */, 17623 Process.myUid(), 17624 TEST_SUBSCRIPTION_ID, 17625 false /* expectUnavailable */, 17626 true /* expectCapChanged */); 17627 } 17628 17629 @Test 17630 public void testAllowedUidsExistWithoutNetworkFactoryPermission() throws Exception { 17631 // Make sure NETWORK_FACTORY permission is not granted. 17632 mServiceContext.setPermission(NETWORK_FACTORY, PERMISSION_DENIED); 17633 mServiceContext.setPermission(MANAGE_TEST_NETWORKS, PERMISSION_GRANTED); 17634 final TestNetworkCallback cb = new TestNetworkCallback(); 17635 mCm.requestNetwork(new NetworkRequest.Builder() 17636 .clearCapabilities() 17637 .addTransportType(TRANSPORT_TEST) 17638 .addTransportType(TRANSPORT_CELLULAR) 17639 .build(), 17640 cb); 17641 17642 final ArraySet<Integer> uids = new ArraySet<>(); 17643 uids.add(200); 17644 final NetworkCapabilities nc = new NetworkCapabilities.Builder() 17645 .addTransportType(TRANSPORT_TEST) 17646 .removeCapability(NET_CAPABILITY_NOT_RESTRICTED) 17647 .setAllowedUids(uids) 17648 .setOwnerUid(Process.myUid()) 17649 .setAdministratorUids(new int[] {Process.myUid()}) 17650 .build(); 17651 final TestNetworkAgentWrapper agent = new TestNetworkAgentWrapper(TRANSPORT_TEST, 17652 new LinkProperties(), nc); 17653 agent.connect(true); 17654 cb.expectAvailableThenValidatedCallbacks(agent); 17655 17656 uids.add(300); 17657 uids.add(400); 17658 nc.setAllowedUids(uids); 17659 agent.setNetworkCapabilities(nc, true /* sendToConnectivityService */); 17660 if (mDeps.isAtLeastT()) { 17661 // AllowedUids is not cleared even without the NETWORK_FACTORY permission 17662 // because the caller is the owner of the network. 17663 cb.expectCaps(agent, c -> c.getAllowedUids().equals(uids)); 17664 } else { 17665 cb.assertNoCallback(); 17666 } 17667 } 17668 17669 @Test 17670 public void testAllowedUids() throws Exception { 17671 final int preferenceOrder = 17672 ConnectivityService.PREFERENCE_ORDER_IRRELEVANT_BECAUSE_NOT_DEFAULT; 17673 mServiceContext.setPermission(NETWORK_FACTORY, PERMISSION_GRANTED); 17674 mServiceContext.setPermission(MANAGE_TEST_NETWORKS, PERMISSION_GRANTED); 17675 final TestNetworkCallback cb = new TestNetworkCallback(); 17676 mCm.requestNetwork(new NetworkRequest.Builder() 17677 .clearCapabilities() 17678 .addTransportType(TRANSPORT_TEST) 17679 .addTransportType(TRANSPORT_CELLULAR) 17680 .build(), 17681 cb); 17682 17683 final ArraySet<Integer> uids = new ArraySet<>(); 17684 uids.add(200); 17685 final NetworkCapabilities nc = new NetworkCapabilities.Builder() 17686 .addTransportType(TRANSPORT_TEST) 17687 .removeCapability(NET_CAPABILITY_NOT_RESTRICTED) 17688 .setAllowedUids(uids) 17689 .build(); 17690 final TestNetworkAgentWrapper agent = new TestNetworkAgentWrapper(TRANSPORT_TEST, 17691 new LinkProperties(), nc); 17692 agent.connect(true); 17693 cb.expectAvailableThenValidatedCallbacks(agent); 17694 17695 final InOrder inOrder = inOrder(mMockNetd); 17696 final NativeUidRangeConfig uids200Parcel = new NativeUidRangeConfig( 17697 agent.getNetwork().getNetId(), 17698 intToUidRangeStableParcels(uids), 17699 preferenceOrder); 17700 if (mDeps.isAtLeastT()) { 17701 inOrder.verify(mMockNetd, times(1)).networkAddUidRangesParcel(uids200Parcel); 17702 } 17703 17704 uids.add(300); 17705 uids.add(400); 17706 nc.setAllowedUids(uids); 17707 agent.setNetworkCapabilities(nc, true /* sendToConnectivityService */); 17708 if (mDeps.isAtLeastT()) { 17709 cb.expectCaps(agent, c -> c.getAllowedUids().equals(uids)); 17710 } else { 17711 cb.assertNoCallback(); 17712 } 17713 17714 uids.remove(200); 17715 final NativeUidRangeConfig uids300400Parcel = new NativeUidRangeConfig( 17716 agent.getNetwork().getNetId(), 17717 intToUidRangeStableParcels(uids), 17718 preferenceOrder); 17719 if (mDeps.isAtLeastT()) { 17720 inOrder.verify(mMockNetd, times(1)).networkAddUidRangesParcel(uids300400Parcel); 17721 } 17722 17723 nc.setAllowedUids(uids); 17724 agent.setNetworkCapabilities(nc, true /* sendToConnectivityService */); 17725 if (mDeps.isAtLeastT()) { 17726 cb.expectCaps(agent, c -> c.getAllowedUids().equals(uids)); 17727 inOrder.verify(mMockNetd, times(1)).networkRemoveUidRangesParcel(uids200Parcel); 17728 } else { 17729 cb.assertNoCallback(); 17730 } 17731 17732 uids.clear(); 17733 uids.add(600); 17734 nc.setAllowedUids(uids); 17735 agent.setNetworkCapabilities(nc, true /* sendToConnectivityService */); 17736 if (mDeps.isAtLeastT()) { 17737 cb.expectCaps(agent, c -> c.getAllowedUids().equals(uids)); 17738 } else { 17739 cb.assertNoCallback(); 17740 } 17741 final NativeUidRangeConfig uids600Parcel = new NativeUidRangeConfig( 17742 agent.getNetwork().getNetId(), 17743 intToUidRangeStableParcels(uids), 17744 preferenceOrder); 17745 if (mDeps.isAtLeastT()) { 17746 inOrder.verify(mMockNetd, times(1)).networkAddUidRangesParcel(uids600Parcel); 17747 inOrder.verify(mMockNetd, times(1)).networkRemoveUidRangesParcel(uids300400Parcel); 17748 } 17749 17750 uids.clear(); 17751 nc.setAllowedUids(uids); 17752 agent.setNetworkCapabilities(nc, true /* sendToConnectivityService */); 17753 if (mDeps.isAtLeastT()) { 17754 cb.expectCaps(agent, c -> c.getAllowedUids().isEmpty()); 17755 inOrder.verify(mMockNetd, times(1)).networkRemoveUidRangesParcel(uids600Parcel); 17756 } else { 17757 cb.assertNoCallback(); 17758 verify(mMockNetd, never()).networkAddUidRangesParcel(any()); 17759 verify(mMockNetd, never()).networkRemoveUidRangesParcel(any()); 17760 } 17761 17762 } 17763 17764 @Test 17765 public void testAutomotiveEthernetAllowedUids() throws Exception { 17766 mServiceContext.setPermission(NETWORK_FACTORY, PERMISSION_GRANTED); 17767 mServiceContext.setPermission(MANAGE_TEST_NETWORKS, PERMISSION_GRANTED); 17768 17769 // Has automotive feature. 17770 validateAutomotiveEthernetAllowedUids(true); 17771 17772 // No automotive feature. 17773 validateAutomotiveEthernetAllowedUids(false); 17774 } 17775 17776 private void validateAutomotiveEthernetAllowedUids(final boolean hasAutomotiveFeature) 17777 throws Exception { 17778 mockHasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, hasAutomotiveFeature); 17779 17780 // Simulate a restricted ethernet network. 17781 final NetworkCapabilities.Builder ncb = new NetworkCapabilities.Builder() 17782 .addTransportType(TRANSPORT_ETHERNET) 17783 .addCapability(NET_CAPABILITY_INTERNET) 17784 .addCapability(NET_CAPABILITY_NOT_SUSPENDED) 17785 .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED) 17786 .removeCapability(NET_CAPABILITY_NOT_RESTRICTED); 17787 17788 mEthernetAgent = new TestNetworkAgentWrapper(TRANSPORT_ETHERNET, 17789 new LinkProperties(), ncb.build()); 17790 17791 final ArraySet<Integer> serviceUidSet = new ArraySet<>(); 17792 serviceUidSet.add(TEST_PACKAGE_UID); 17793 17794 final TestNetworkCallback cb = new TestNetworkCallback(); 17795 17796 mCm.requestNetwork(new NetworkRequest.Builder() 17797 .addTransportType(TRANSPORT_ETHERNET) 17798 .removeCapability(NET_CAPABILITY_NOT_RESTRICTED) 17799 .build(), cb); 17800 mEthernetAgent.connect(true); 17801 cb.expectAvailableThenValidatedCallbacks(mEthernetAgent); 17802 17803 // Cell gets to set the service UID as access UID 17804 ncb.setAllowedUids(serviceUidSet); 17805 mEthernetAgent.setNetworkCapabilities(ncb.build(), true /* sendToCS */); 17806 if (mDeps.isAtLeastT() && hasAutomotiveFeature) { 17807 cb.expectCaps(mEthernetAgent, c -> c.getAllowedUids().equals(serviceUidSet)); 17808 } else { 17809 // S and no automotive feature must ignore access UIDs. 17810 cb.assertNoCallback(TEST_CALLBACK_TIMEOUT_MS); 17811 } 17812 17813 mEthernetAgent.disconnect(); 17814 cb.expect(LOST, mEthernetAgent); 17815 mCm.unregisterNetworkCallback(cb); 17816 } 17817 17818 @Test 17819 public void testCbsAllowedUids() throws Exception { 17820 mServiceContext.setPermission(NETWORK_FACTORY, PERMISSION_GRANTED); 17821 mServiceContext.setPermission(MANAGE_TEST_NETWORKS, PERMISSION_GRANTED); 17822 17823 // In this test TEST_PACKAGE_UID will be the UID of the carrier service UID. 17824 doReturn(true).when(mCarrierPrivilegeAuthenticator) 17825 .isCarrierServiceUidForNetworkCapabilities(eq(TEST_PACKAGE_UID), any()); 17826 17827 // Simulate a restricted telephony network. The telephony factory is entitled to set 17828 // the access UID to the service package on any of its restricted networks. 17829 final NetworkCapabilities.Builder ncb = new NetworkCapabilities.Builder() 17830 .addTransportType(TRANSPORT_CELLULAR) 17831 .addCapability(NET_CAPABILITY_INTERNET) 17832 .addCapability(NET_CAPABILITY_NOT_SUSPENDED) 17833 .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED) 17834 .removeCapability(NET_CAPABILITY_NOT_RESTRICTED) 17835 .setNetworkSpecifier(new TelephonyNetworkSpecifier(1 /* subid */)); 17836 17837 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, 17838 new LinkProperties(), ncb.build()); 17839 17840 final ArraySet<Integer> serviceUidSet = new ArraySet<>(); 17841 serviceUidSet.add(TEST_PACKAGE_UID); 17842 final ArraySet<Integer> nonServiceUidSet = new ArraySet<>(); 17843 nonServiceUidSet.add(TEST_PACKAGE_UID2); 17844 final ArraySet<Integer> serviceUidSetPlus = new ArraySet<>(); 17845 serviceUidSetPlus.add(TEST_PACKAGE_UID); 17846 serviceUidSetPlus.add(TEST_PACKAGE_UID2); 17847 17848 final TestNetworkCallback cb = new TestNetworkCallback(); 17849 17850 // Cell gets to set the service UID as access UID 17851 mCm.requestNetwork(new NetworkRequest.Builder() 17852 .addTransportType(TRANSPORT_CELLULAR) 17853 .removeCapability(NET_CAPABILITY_NOT_RESTRICTED) 17854 .build(), cb); 17855 mCellAgent.connect(true); 17856 cb.expectAvailableThenValidatedCallbacks(mCellAgent); 17857 ncb.setAllowedUids(serviceUidSet); 17858 mCellAgent.setNetworkCapabilities(ncb.build(), true /* sendToCS */); 17859 if (mDeps.isAtLeastT()) { 17860 cb.expectCaps(mCellAgent, c -> c.getAllowedUids().equals(serviceUidSet)); 17861 } else { 17862 // S must ignore access UIDs. 17863 cb.assertNoCallback(TEST_CALLBACK_TIMEOUT_MS); 17864 } 17865 17866 // ...but not to some other UID. Rejection sets UIDs to the empty set 17867 ncb.setAllowedUids(nonServiceUidSet); 17868 mCellAgent.setNetworkCapabilities(ncb.build(), true /* sendToCS */); 17869 if (mDeps.isAtLeastT()) { 17870 cb.expectCaps(mCellAgent, c -> c.getAllowedUids().isEmpty()); 17871 } else { 17872 // S must ignore access UIDs. 17873 cb.assertNoCallback(TEST_CALLBACK_TIMEOUT_MS); 17874 } 17875 17876 // ...and also not to multiple UIDs even including the service UID 17877 ncb.setAllowedUids(serviceUidSetPlus); 17878 mCellAgent.setNetworkCapabilities(ncb.build(), true /* sendToCS */); 17879 cb.assertNoCallback(TEST_CALLBACK_TIMEOUT_MS); 17880 17881 mCellAgent.disconnect(); 17882 cb.expect(LOST, mCellAgent); 17883 mCm.unregisterNetworkCallback(cb); 17884 17885 // Must be unset before touching the transports, because remove and add transport types 17886 // check the specifier on the builder immediately, contradicting normal builder semantics 17887 // TODO : fix the builder 17888 ncb.setNetworkSpecifier(null); 17889 ncb.removeTransportType(TRANSPORT_CELLULAR); 17890 ncb.addTransportType(TRANSPORT_BLUETOOTH); 17891 // Wifi does not get to set access UID, even to the correct UID 17892 mCm.requestNetwork(new NetworkRequest.Builder() 17893 .addTransportType(TRANSPORT_BLUETOOTH) 17894 .removeCapability(NET_CAPABILITY_NOT_RESTRICTED) 17895 .build(), cb); 17896 final TestNetworkAgentWrapper bluetoothAgent = new TestNetworkAgentWrapper( 17897 TRANSPORT_BLUETOOTH, new LinkProperties(), ncb.build()); 17898 bluetoothAgent.connect(true); 17899 cb.expectAvailableThenValidatedCallbacks(bluetoothAgent); 17900 ncb.setAllowedUids(serviceUidSet); 17901 bluetoothAgent.setNetworkCapabilities(ncb.build(), true /* sendToCS */); 17902 cb.assertNoCallback(TEST_CALLBACK_TIMEOUT_MS); 17903 mCm.unregisterNetworkCallback(cb); 17904 } 17905 17906 @Test 17907 public void testSanitizedCapabilitiesFromAgentDoesNotMutateArgument() 17908 throws Exception { 17909 // This NetworkCapabilities builds an usual object to maximize the chance that this requires 17910 // sanitization, so we have a high chance to detect any changes to the original. 17911 final NetworkCapabilities unsanitized = new NetworkCapabilities.Builder() 17912 .withoutDefaultCapabilities() 17913 .addTransportType(TRANSPORT_WIFI) 17914 .addCapability(NET_CAPABILITY_INTERNET) 17915 .setOwnerUid(12345) 17916 .setAdministratorUids(new int[] {12345, 23456, 34567}) 17917 .setLinkUpstreamBandwidthKbps(20) 17918 .setLinkDownstreamBandwidthKbps(10) 17919 .setNetworkSpecifier(new EthernetNetworkSpecifier("foobar")) 17920 .setTransportInfo(new WifiInfo.Builder().setBssid("AA:AA:AA:AA:AA:AA").build()) 17921 .setSignalStrength(-75) 17922 .setSsid("SSID1") 17923 .setRequestorUid(98765) 17924 .setRequestorPackageName("TestPackage") 17925 .setSubscriptionIds(Collections.singleton(Process.myUid())) 17926 .setUids(UidRange.toIntRanges(uidRangesForUids( 17927 UserHandle.getUid(PRIMARY_USER, 10100), 17928 UserHandle.getUid(SECONDARY_USER, 10101), 17929 UserHandle.getUid(TERTIARY_USER, 10043)))) 17930 .setAllowedUids(Set.of(45678, 56789, 65432)) 17931 .setUnderlyingNetworks(List.of(new Network(99999))) 17932 .build(); 17933 final NetworkCapabilities copyOfUnsanitized = new NetworkCapabilities(unsanitized); 17934 final NetworkInfo info = new NetworkInfo(TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_LTE, 17935 ConnectivityManager.getNetworkTypeName(TYPE_MOBILE), 17936 TelephonyManager.getNetworkTypeName(TelephonyManager.NETWORK_TYPE_LTE)); 17937 final NetworkAgentInfo agent = fakeNai(unsanitized, info); 17938 agent.setDeclaredCapabilities(unsanitized); 17939 final NetworkCapabilities sanitized = agent.getDeclaredCapabilitiesSanitized( 17940 null /* carrierPrivilegeAuthenticator */); 17941 assertEquals(copyOfUnsanitized, unsanitized); 17942 assertNotEquals(sanitized, unsanitized); 17943 } 17944 17945 /** 17946 * Validate request counts are counted accurately on setProfileNetworkPreference on set/replace. 17947 */ 17948 @Test 17949 public void testProfileNetworkPrefCountsRequestsCorrectlyOnSet() throws Exception { 17950 final UserHandle testHandle = setupEnterpriseNetwork(); 17951 final TestOnCompleteListener listener = new TestOnCompleteListener(); 17952 // Leave one request available so the profile preference can be set. 17953 withRequestCountersAcquired(1 /* countToLeaveAvailable */, () -> { 17954 withPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, 17955 Process.myPid(), Process.myUid(), () -> { 17956 // Set initially to test the limit prior to having existing requests. 17957 mCm.setProfileNetworkPreference(testHandle, 17958 PROFILE_NETWORK_PREFERENCE_ENTERPRISE, 17959 Runnable::run, listener); 17960 }); 17961 listener.expectOnComplete(); 17962 17963 // Simulate filing requests as some app on the work profile 17964 final int otherAppUid = UserHandle.getUid(TEST_WORK_PROFILE_USER_ID, 17965 UserHandle.getAppId(Process.myUid() + 1)); 17966 final int remainingCount = ConnectivityService.MAX_NETWORK_REQUESTS_PER_UID 17967 - mService.mNetworkRequestCounter.get(otherAppUid) 17968 - 1; 17969 final NetworkCallback[] callbacks = new NetworkCallback[remainingCount]; 17970 doAsUid(otherAppUid, () -> { 17971 for (int i = 0; i < remainingCount; ++i) { 17972 callbacks[i] = new TestNetworkCallback(); 17973 mCm.registerDefaultNetworkCallback(callbacks[i]); 17974 } 17975 }); 17976 17977 withPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, 17978 Process.myPid(), Process.myUid(), () -> { 17979 // re-set so as to test the limit as part of replacing existing requests. 17980 mCm.setProfileNetworkPreference(testHandle, 17981 PROFILE_NETWORK_PREFERENCE_ENTERPRISE, Runnable::run, listener); 17982 }); 17983 listener.expectOnComplete(); 17984 17985 doAsUid(otherAppUid, () -> { 17986 for (final NetworkCallback callback : callbacks) { 17987 mCm.unregisterNetworkCallback(callback); 17988 } 17989 }); 17990 }); 17991 } 17992 17993 /** 17994 * Validate request counts are counted accurately on setOemNetworkPreference on set/replace. 17995 */ 17996 @Test 17997 public void testSetOemNetworkPreferenceCountsRequestsCorrectlyOnSet() throws Exception { 17998 mockHasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, true); 17999 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 18000 OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY; 18001 // Leave one request available so the OEM preference can be set. 18002 withRequestCountersAcquired(1 /* countToLeaveAvailable */, () -> 18003 withPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, () -> { 18004 // Set initially to test the limit prior to having existing requests. 18005 final TestOemListenerCallback listener = new TestOemListenerCallback(); 18006 mService.setOemNetworkPreference( 18007 createDefaultOemNetworkPreferences(networkPref), listener); 18008 listener.expectOnComplete(); 18009 18010 // re-set so as to test the limit as part of replacing existing requests. 18011 mService.setOemNetworkPreference( 18012 createDefaultOemNetworkPreferences(networkPref), listener); 18013 listener.expectOnComplete(); 18014 })); 18015 } 18016 18017 private void withRequestCountersAcquired(final int countToLeaveAvailable, 18018 @NonNull final ThrowingRunnable r) throws Exception { 18019 final ArraySet<TestNetworkCallback> callbacks = new ArraySet<>(); 18020 try { 18021 final int requestCount = mService.mSystemNetworkRequestCounter.get(Process.myUid()); 18022 // The limit is hit when total requests = limit - 1, and exceeded with a crash when 18023 // total requests >= limit. 18024 final int countToFile = 18025 MAX_NETWORK_REQUESTS_PER_SYSTEM_UID - requestCount - countToLeaveAvailable; 18026 // Need permission so registerDefaultNetworkCallback uses mSystemNetworkRequestCounter 18027 withPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, () -> { 18028 for (int i = 1; i < countToFile; i++) { 18029 final TestNetworkCallback cb = new TestNetworkCallback(); 18030 mCm.registerDefaultNetworkCallback(cb); 18031 callbacks.add(cb); 18032 } 18033 assertEquals(MAX_NETWORK_REQUESTS_PER_SYSTEM_UID - 1 - countToLeaveAvailable, 18034 mService.mSystemNetworkRequestCounter.get(Process.myUid())); 18035 }); 18036 // Code to run to check if it triggers a max request count limit error. 18037 r.run(); 18038 } finally { 18039 for (final TestNetworkCallback cb : callbacks) { 18040 mCm.unregisterNetworkCallback(cb); 18041 } 18042 } 18043 } 18044 18045 private void assertCreateNrisFromMobileDataPreferredUids(Set<Integer> uids) { 18046 final Set<NetworkRequestInfo> nris = 18047 mService.createNrisFromMobileDataPreferredUids(uids); 18048 final NetworkRequestInfo nri = nris.iterator().next(); 18049 // Verify that one NRI is created with multilayer requests. Because one NRI can contain 18050 // multiple uid ranges, so it only need create one NRI here. 18051 assertEquals(1, nris.size()); 18052 assertTrue(nri.isMultilayerRequest()); 18053 assertEquals(nri.getUids(), uidRangesForUids(uids)); 18054 assertEquals(PREFERENCE_ORDER_MOBILE_DATA_PREFERERRED, nri.mPreferenceOrder); 18055 } 18056 18057 /** 18058 * Test createNrisFromMobileDataPreferredUids returns correct NetworkRequestInfo. 18059 */ 18060 @Test 18061 public void testCreateNrisFromMobileDataPreferredUids() { 18062 // Verify that empty uid set should not create any NRI for it. 18063 final Set<NetworkRequestInfo> nrisNoUid = 18064 mService.createNrisFromMobileDataPreferredUids(new ArraySet<>()); 18065 assertEquals(0, nrisNoUid.size()); 18066 18067 final int uid1 = PRIMARY_USER_HANDLE.getUid(TEST_PACKAGE_UID); 18068 final int uid2 = PRIMARY_USER_HANDLE.getUid(TEST_PACKAGE_UID2); 18069 final int uid3 = SECONDARY_USER_HANDLE.getUid(TEST_PACKAGE_UID); 18070 assertCreateNrisFromMobileDataPreferredUids(Set.of(uid1)); 18071 assertCreateNrisFromMobileDataPreferredUids(Set.of(uid1, uid3)); 18072 assertCreateNrisFromMobileDataPreferredUids(Set.of(uid1, uid2)); 18073 } 18074 18075 private void setAndUpdateMobileDataPreferredUids(Set<Integer> uids) { 18076 ConnectivitySettingsManager.setMobileDataPreferredUids(mServiceContext, uids); 18077 mService.updateMobileDataPreferredUids(); 18078 waitForIdle(); 18079 } 18080 18081 /** 18082 * Test that MOBILE_DATA_PREFERRED_UIDS changes will send correct net id and uid ranges to netd. 18083 */ 18084 @Test 18085 public void testMobileDataPreferredUidsChanged() throws Exception { 18086 final InOrder inorder = inOrder(mMockNetd); 18087 registerDefaultNetworkCallbacks(); 18088 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 18089 mCellAgent.connect(true); 18090 mDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 18091 mTestPackageDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 18092 18093 final int cellNetId = mCellAgent.getNetwork().netId; 18094 inorder.verify(mMockNetd, times(1)).networkCreate(nativeNetworkConfigPhysical( 18095 cellNetId, INetd.PERMISSION_NONE)); 18096 18097 // Initial mobile data preferred uids status. 18098 setAndUpdateMobileDataPreferredUids(Set.of()); 18099 inorder.verify(mMockNetd, never()).networkAddUidRangesParcel(any()); 18100 inorder.verify(mMockNetd, never()).networkRemoveUidRangesParcel(any()); 18101 18102 // Set MOBILE_DATA_PREFERRED_UIDS setting and verify that net id and uid ranges send to netd 18103 final Set<Integer> uids1 = Set.of(PRIMARY_USER_HANDLE.getUid(TEST_PACKAGE_UID)); 18104 final UidRangeParcel[] uidRanges1 = toUidRangeStableParcels(uidRangesForUids(uids1)); 18105 final NativeUidRangeConfig config1 = new NativeUidRangeConfig(cellNetId, uidRanges1, 18106 PREFERENCE_ORDER_MOBILE_DATA_PREFERERRED); 18107 setAndUpdateMobileDataPreferredUids(uids1); 18108 inorder.verify(mMockNetd, times(1)).networkAddUidRangesParcel(config1); 18109 inorder.verify(mMockNetd, never()).networkRemoveUidRangesParcel(any()); 18110 18111 // Set MOBILE_DATA_PREFERRED_UIDS setting again and verify that old rules are removed and 18112 // new rules are added. 18113 final Set<Integer> uids2 = Set.of(PRIMARY_USER_HANDLE.getUid(TEST_PACKAGE_UID), 18114 PRIMARY_USER_HANDLE.getUid(TEST_PACKAGE_UID2), 18115 SECONDARY_USER_HANDLE.getUid(TEST_PACKAGE_UID)); 18116 final UidRangeParcel[] uidRanges2 = toUidRangeStableParcels(uidRangesForUids(uids2)); 18117 final NativeUidRangeConfig config2 = new NativeUidRangeConfig(cellNetId, uidRanges2, 18118 PREFERENCE_ORDER_MOBILE_DATA_PREFERERRED); 18119 setAndUpdateMobileDataPreferredUids(uids2); 18120 inorder.verify(mMockNetd, times(1)).networkRemoveUidRangesParcel(config1); 18121 inorder.verify(mMockNetd, times(1)).networkAddUidRangesParcel(config2); 18122 18123 // Clear MOBILE_DATA_PREFERRED_UIDS setting again and verify that old rules are removed and 18124 // new rules are not added. 18125 setAndUpdateMobileDataPreferredUids(Set.of()); 18126 inorder.verify(mMockNetd, times(1)).networkRemoveUidRangesParcel(config2); 18127 inorder.verify(mMockNetd, never()).networkAddUidRangesParcel(any()); 18128 } 18129 18130 /** 18131 * Make sure mobile data preferred uids feature behaves as expected when the mobile network 18132 * goes up and down while the uids is set. Make sure they behave as expected whether 18133 * there is a general default network or not. 18134 */ 18135 @Test 18136 public void testMobileDataPreferenceForMobileNetworkUpDown() throws Exception { 18137 final InOrder inorder = inOrder(mMockNetd); 18138 // File a request for cell to ensure it doesn't go down. 18139 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback(); 18140 final NetworkRequest cellRequest = new NetworkRequest.Builder() 18141 .addTransportType(TRANSPORT_CELLULAR).build(); 18142 mCm.requestNetwork(cellRequest, cellNetworkCallback); 18143 cellNetworkCallback.assertNoCallback(); 18144 18145 registerDefaultNetworkCallbacks(); 18146 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 18147 mWiFiAgent.connect(true); 18148 mDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mWiFiAgent); 18149 mTestPackageDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mWiFiAgent); 18150 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetworkForUid(TEST_PACKAGE_UID)); 18151 18152 final int wifiNetId = mWiFiAgent.getNetwork().netId; 18153 inorder.verify(mMockNetd, times(1)).networkCreate(nativeNetworkConfigPhysical( 18154 wifiNetId, INetd.PERMISSION_NONE)); 18155 18156 // Initial mobile data preferred uids status. 18157 setAndUpdateMobileDataPreferredUids(Set.of()); 18158 inorder.verify(mMockNetd, never()).networkAddUidRangesParcel(any()); 18159 inorder.verify(mMockNetd, never()).networkRemoveUidRangesParcel(any()); 18160 18161 // Set MOBILE_DATA_PREFERRED_UIDS setting and verify that wifi net id and uid ranges send to 18162 // netd. 18163 final Set<Integer> uids = Set.of(PRIMARY_USER_HANDLE.getUid(TEST_PACKAGE_UID)); 18164 final UidRangeParcel[] uidRanges = toUidRangeStableParcels(uidRangesForUids(uids)); 18165 final NativeUidRangeConfig wifiConfig = new NativeUidRangeConfig(wifiNetId, uidRanges, 18166 PREFERENCE_ORDER_MOBILE_DATA_PREFERERRED); 18167 setAndUpdateMobileDataPreferredUids(uids); 18168 inorder.verify(mMockNetd, times(1)).networkAddUidRangesParcel(wifiConfig); 18169 inorder.verify(mMockNetd, never()).networkRemoveUidRangesParcel(any()); 18170 18171 // Cellular network connected. mTestPackageDefaultNetworkCallback should receive 18172 // callback with cellular network and net id and uid ranges should be updated to netd. 18173 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 18174 mCellAgent.connect(true); 18175 cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 18176 mDefaultNetworkCallback.assertNoCallback(); 18177 mTestPackageDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 18178 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetworkForUid(TEST_PACKAGE_UID)); 18179 18180 final int cellNetId = mCellAgent.getNetwork().netId; 18181 final NativeUidRangeConfig cellConfig = new NativeUidRangeConfig(cellNetId, uidRanges, 18182 PREFERENCE_ORDER_MOBILE_DATA_PREFERERRED); 18183 inorder.verify(mMockNetd, times(1)).networkCreate(nativeNetworkConfigPhysical( 18184 cellNetId, INetd.PERMISSION_NONE)); 18185 inorder.verify(mMockNetd, times(1)).networkAddUidRangesParcel(cellConfig); 18186 inorder.verify(mMockNetd, times(1)).networkRemoveUidRangesParcel(wifiConfig); 18187 18188 // Cellular network disconnected. mTestPackageDefaultNetworkCallback should receive 18189 // callback with wifi network from fallback request. 18190 mCellAgent.disconnect(); 18191 mDefaultNetworkCallback.assertNoCallback(); 18192 cellNetworkCallback.expect(LOST, mCellAgent); 18193 mTestPackageDefaultNetworkCallback.expect(LOST, mCellAgent); 18194 mTestPackageDefaultNetworkCallback.expectAvailableCallbacksValidated(mWiFiAgent); 18195 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetworkForUid(TEST_PACKAGE_UID)); 18196 inorder.verify(mMockNetd, times(1)).networkAddUidRangesParcel(wifiConfig); 18197 inorder.verify(mMockNetd, never()).networkRemoveUidRangesParcel(any()); 18198 inorder.verify(mMockNetd).networkDestroy(cellNetId); 18199 18200 // Cellular network comes back. mTestPackageDefaultNetworkCallback should receive 18201 // callback with cellular network. 18202 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 18203 mCellAgent.connect(true); 18204 cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 18205 mDefaultNetworkCallback.assertNoCallback(); 18206 mTestPackageDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 18207 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetworkForUid(TEST_PACKAGE_UID)); 18208 18209 final int cellNetId2 = mCellAgent.getNetwork().netId; 18210 final NativeUidRangeConfig cellConfig2 = new NativeUidRangeConfig(cellNetId2, uidRanges, 18211 PREFERENCE_ORDER_MOBILE_DATA_PREFERERRED); 18212 inorder.verify(mMockNetd, times(1)).networkCreate(nativeNetworkConfigPhysical( 18213 cellNetId2, INetd.PERMISSION_NONE)); 18214 inorder.verify(mMockNetd, times(1)).networkAddUidRangesParcel(cellConfig2); 18215 inorder.verify(mMockNetd, times(1)).networkRemoveUidRangesParcel(wifiConfig); 18216 18217 // Wifi network disconnected. mTestPackageDefaultNetworkCallback should not receive 18218 // any callback. 18219 mWiFiAgent.disconnect(); 18220 mDefaultNetworkCallback.expect(LOST, mWiFiAgent); 18221 mDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellAgent); 18222 mTestPackageDefaultNetworkCallback.assertNoCallback(); 18223 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetworkForUid(TEST_PACKAGE_UID)); 18224 waitForIdle(); 18225 inorder.verify(mMockNetd, never()).networkAddUidRangesParcel(any()); 18226 inorder.verify(mMockNetd, never()).networkRemoveUidRangesParcel(any()); 18227 inorder.verify(mMockNetd).networkDestroy(wifiNetId); 18228 18229 mCm.unregisterNetworkCallback(cellNetworkCallback); 18230 } 18231 18232 @Test 18233 public void testMultilayerRequestsOfSetMobileDataPreferredUids() throws Exception { 18234 // First set mobile data preferred uid to create a multi-layer requests: 1. request for 18235 // cellular, 2. track the default network for fallback. 18236 setAndUpdateMobileDataPreferredUids( 18237 Set.of(PRIMARY_USER_HANDLE.getUid(TEST_PACKAGE_UID))); 18238 18239 final HandlerThread handlerThread = new HandlerThread("MockFactory"); 18240 handlerThread.start(); 18241 final NetworkCapabilities cellFilter = new NetworkCapabilities() 18242 .addTransportType(TRANSPORT_CELLULAR) 18243 .addCapability(NET_CAPABILITY_INTERNET) 18244 .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED); 18245 final MockNetworkFactory cellFactory = new MockNetworkFactory(handlerThread.getLooper(), 18246 mServiceContext, "cellFactory", cellFilter, mCsHandlerThread); 18247 cellFactory.setScoreFilter(40); 18248 18249 try { 18250 cellFactory.register(); 18251 // Default internet request and the mobile data preferred request. 18252 cellFactory.expectRequestAdds(2); 18253 cellFactory.assertRequestCountEquals(2); 18254 18255 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 18256 mWiFiAgent.connect(true); 18257 18258 // The cellFactory however is outscored, and should lose default internet request. 18259 // But it should still see mobile data preferred request. 18260 cellFactory.expectRequestRemove(); 18261 cellFactory.assertRequestCountEquals(1); 18262 18263 mWiFiAgent.disconnect(); 18264 // The network satisfying the default internet request has disconnected, so the 18265 // cellFactory sees the default internet requests again. 18266 cellFactory.expectRequestAdd(); 18267 cellFactory.assertRequestCountEquals(2); 18268 } finally { 18269 cellFactory.terminate(); 18270 handlerThread.quitSafely(); 18271 handlerThread.join(); 18272 } 18273 } 18274 18275 /** 18276 * Validate request counts are counted accurately on MOBILE_DATA_PREFERRED_UIDS change 18277 * on set/replace. 18278 */ 18279 @Test 18280 public void testMobileDataPreferredUidsChangedCountsRequestsCorrectlyOnSet() throws Exception { 18281 ConnectivitySettingsManager.setMobileDataPreferredUids(mServiceContext, 18282 Set.of(PRIMARY_USER_HANDLE.getUid(TEST_PACKAGE_UID))); 18283 // Leave one request available so MDO preference set up above can be set. 18284 withRequestCountersAcquired(1 /* countToLeaveAvailable */, () -> 18285 withPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, 18286 Process.myPid(), Process.myUid(), () -> { 18287 // Set initially to test the limit prior to having existing requests. 18288 mService.updateMobileDataPreferredUids(); 18289 waitForIdle(); 18290 18291 // re-set so as to test the limit as part of replacing existing requests 18292 mService.updateMobileDataPreferredUids(); 18293 waitForIdle(); 18294 })); 18295 } 18296 18297 @Test 18298 public void testAllNetworkPreferencesCanCoexist() 18299 throws Exception { 18300 final InOrder inorder = inOrder(mMockNetd); 18301 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 18302 OEM_NETWORK_PREFERENCE_OEM_PAID; 18303 final UserHandle testHandle = setupEnterpriseNetwork(); 18304 18305 setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); 18306 final int cellNetId = mCellAgent.getNetwork().netId; 18307 inorder.verify(mMockNetd, times(1)).networkCreate(nativeNetworkConfigPhysical( 18308 cellNetId, INetd.PERMISSION_NONE)); 18309 18310 // Set oem network preference 18311 final int[] uids1 = new int[] { PRIMARY_USER_HANDLE.getUid(TEST_PACKAGE_UID) }; 18312 final UidRangeParcel[] uidRanges1 = toUidRangeStableParcels(uidRangesForUids(uids1)); 18313 final NativeUidRangeConfig config1 = new NativeUidRangeConfig(cellNetId, uidRanges1, 18314 PREFERENCE_ORDER_OEM); 18315 setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges1, TEST_PACKAGE_NAME); 18316 inorder.verify(mMockNetd, times(1)).networkAddUidRangesParcel(config1); 18317 inorder.verify(mMockNetd, never()).networkRemoveUidRangesParcel(any()); 18318 18319 // Set user profile network preference 18320 final TestNetworkAgentWrapper workAgent = makeEnterpriseNetworkAgent(); 18321 workAgent.connect(true); 18322 18323 final TestOnCompleteListener listener = new TestOnCompleteListener(); 18324 mCm.setProfileNetworkPreference(testHandle, PROFILE_NETWORK_PREFERENCE_ENTERPRISE, 18325 r -> r.run(), listener); 18326 listener.expectOnComplete(); 18327 final NativeUidRangeConfig config2 = new NativeUidRangeConfig(workAgent.getNetwork().netId, 18328 uidRangeFor(testHandle), PREFERENCE_ORDER_PROFILE); 18329 inorder.verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( 18330 workAgent.getNetwork().netId, INetd.PERMISSION_SYSTEM)); 18331 inorder.verify(mMockNetd, never()).networkRemoveUidRangesParcel(any()); 18332 inorder.verify(mMockNetd).networkAddUidRangesParcel(config2); 18333 18334 // Set MOBILE_DATA_PREFERRED_UIDS setting 18335 final Set<Integer> uids2 = Set.of(PRIMARY_USER_HANDLE.getUid(TEST_PACKAGE_UID2)); 18336 final UidRangeParcel[] uidRanges2 = toUidRangeStableParcels(uidRangesForUids(uids2)); 18337 final NativeUidRangeConfig config3 = new NativeUidRangeConfig(cellNetId, uidRanges2, 18338 PREFERENCE_ORDER_MOBILE_DATA_PREFERERRED); 18339 setAndUpdateMobileDataPreferredUids(uids2); 18340 inorder.verify(mMockNetd, never()).networkRemoveUidRangesParcel(any()); 18341 inorder.verify(mMockNetd, times(1)).networkAddUidRangesParcel(config3); 18342 18343 // Set oem network preference again with different uid. 18344 final Set<Integer> uids3 = Set.of(PRIMARY_USER_HANDLE.getUid(TEST_PACKAGE_UID3)); 18345 final UidRangeParcel[] uidRanges3 = toUidRangeStableParcels(uidRangesForUids(uids3)); 18346 final NativeUidRangeConfig config4 = new NativeUidRangeConfig(cellNetId, uidRanges3, 18347 PREFERENCE_ORDER_OEM); 18348 setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges3, "com.android.test"); 18349 inorder.verify(mMockNetd, times(1)).networkRemoveUidRangesParcel(config1); 18350 inorder.verify(mMockNetd, times(1)).networkAddUidRangesParcel(config4); 18351 18352 // Remove user profile network preference 18353 mCm.setProfileNetworkPreference(testHandle, PROFILE_NETWORK_PREFERENCE_DEFAULT, 18354 r -> r.run(), listener); 18355 listener.expectOnComplete(); 18356 inorder.verify(mMockNetd, times(1)).networkRemoveUidRangesParcel(config2); 18357 inorder.verify(mMockNetd, never()).networkAddUidRangesParcel(any()); 18358 18359 // Set MOBILE_DATA_PREFERRED_UIDS setting again with same uid as oem network preference. 18360 final NativeUidRangeConfig config6 = new NativeUidRangeConfig(cellNetId, uidRanges3, 18361 PREFERENCE_ORDER_MOBILE_DATA_PREFERERRED); 18362 setAndUpdateMobileDataPreferredUids(uids3); 18363 inorder.verify(mMockNetd, times(1)).networkRemoveUidRangesParcel(config3); 18364 inorder.verify(mMockNetd, times(1)).networkAddUidRangesParcel(config6); 18365 } 18366 18367 @Test 18368 public void testNetworkCallbackAndActiveNetworkForUid_AllNetworkPreferencesEnabled() 18369 throws Exception { 18370 // File a request for cell to ensure it doesn't go down. 18371 final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback(); 18372 final NetworkRequest cellRequest = new NetworkRequest.Builder() 18373 .addTransportType(TRANSPORT_CELLULAR).build(); 18374 mCm.requestNetwork(cellRequest, cellNetworkCallback); 18375 cellNetworkCallback.assertNoCallback(); 18376 18377 // Register callbacks and have wifi network as default network. 18378 registerDefaultNetworkCallbacks(); 18379 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 18380 mWiFiAgent.connect(true); 18381 mDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mWiFiAgent); 18382 mProfileDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mWiFiAgent); 18383 mTestPackageDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mWiFiAgent); 18384 assertEquals(mWiFiAgent.getNetwork(), 18385 mCm.getActiveNetworkForUid(TEST_WORK_PROFILE_APP_UID)); 18386 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetworkForUid(TEST_PACKAGE_UID)); 18387 18388 // Set MOBILE_DATA_PREFERRED_UIDS setting with TEST_WORK_PROFILE_APP_UID and 18389 // TEST_PACKAGE_UID. Both mProfileDefaultNetworkCallback and 18390 // mTestPackageDefaultNetworkCallback should receive callback with cell network. 18391 setAndUpdateMobileDataPreferredUids(Set.of(TEST_WORK_PROFILE_APP_UID, TEST_PACKAGE_UID)); 18392 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 18393 mCellAgent.connect(true); 18394 cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 18395 mDefaultNetworkCallback.assertNoCallback(); 18396 mProfileDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 18397 mTestPackageDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 18398 assertEquals(mCellAgent.getNetwork(), 18399 mCm.getActiveNetworkForUid(TEST_WORK_PROFILE_APP_UID)); 18400 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetworkForUid(TEST_PACKAGE_UID)); 18401 18402 // Set user profile network preference with test profile. mProfileDefaultNetworkCallback 18403 // should receive callback with higher priority network preference (enterprise network). 18404 // The others should have no callbacks. 18405 final UserHandle testHandle = setupEnterpriseNetwork(); 18406 final TestNetworkAgentWrapper workAgent = makeEnterpriseNetworkAgent(); 18407 workAgent.connect(true); 18408 final TestOnCompleteListener listener = new TestOnCompleteListener(); 18409 mCm.setProfileNetworkPreference(testHandle, PROFILE_NETWORK_PREFERENCE_ENTERPRISE, 18410 r -> r.run(), listener); 18411 listener.expectOnComplete(); 18412 assertNoCallbacks(mDefaultNetworkCallback, mTestPackageDefaultNetworkCallback); 18413 mProfileDefaultNetworkCallback.expectAvailableCallbacksValidated(workAgent); 18414 assertEquals(workAgent.getNetwork(), mCm.getActiveNetworkForUid(TEST_WORK_PROFILE_APP_UID)); 18415 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetworkForUid(TEST_PACKAGE_UID)); 18416 18417 // Set oem network preference with TEST_PACKAGE_UID. mTestPackageDefaultNetworkCallback 18418 // should receive callback with higher priority network preference (current default network) 18419 // and the others should have no callbacks. 18420 @OemNetworkPreferences.OemNetworkPreference final int networkPref = 18421 OEM_NETWORK_PREFERENCE_OEM_PAID; 18422 final int[] uids1 = new int[] { TEST_PACKAGE_UID }; 18423 final UidRangeParcel[] uidRanges1 = toUidRangeStableParcels(uidRangesForUids(uids1)); 18424 setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges1, TEST_PACKAGE_NAME); 18425 assertNoCallbacks(mDefaultNetworkCallback, mProfileDefaultNetworkCallback); 18426 mTestPackageDefaultNetworkCallback.expectAvailableCallbacksValidated(mWiFiAgent); 18427 assertEquals(mWiFiAgent.getNetwork(), mCm.getActiveNetworkForUid(TEST_PACKAGE_UID)); 18428 assertEquals(workAgent.getNetwork(), mCm.getActiveNetworkForUid(TEST_WORK_PROFILE_APP_UID)); 18429 18430 // Set oem network preference with TEST_WORK_PROFILE_APP_UID. Both 18431 // mProfileDefaultNetworkCallback and mTestPackageDefaultNetworkCallback should receive 18432 // callback. 18433 final int[] uids2 = new int[] { TEST_WORK_PROFILE_APP_UID }; 18434 final UidRangeParcel[] uidRanges2 = toUidRangeStableParcels(uidRangesForUids(uids2)); 18435 doReturn(Arrays.asList(testHandle)).when(mUserManager).getUserHandles(anyBoolean()); 18436 setupSetOemNetworkPreferenceForPreferenceTest( 18437 networkPref, uidRanges2, "com.android.test", testHandle); 18438 mDefaultNetworkCallback.assertNoCallback(); 18439 mProfileDefaultNetworkCallback.expectAvailableCallbacksValidated(mWiFiAgent); 18440 mTestPackageDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellAgent); 18441 assertEquals(mWiFiAgent.getNetwork(), 18442 mCm.getActiveNetworkForUid(TEST_WORK_PROFILE_APP_UID)); 18443 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetworkForUid(TEST_PACKAGE_UID)); 18444 18445 // Remove oem network preference, mProfileDefaultNetworkCallback should receive callback 18446 // with current highest priority network preference (enterprise network) and the others 18447 // should have no callbacks. 18448 final TestOemListenerCallback oemPrefListener = new TestOemListenerCallback(); 18449 mService.setOemNetworkPreference( 18450 new OemNetworkPreferences.Builder().build(), oemPrefListener); 18451 oemPrefListener.expectOnComplete(); 18452 assertNoCallbacks(mDefaultNetworkCallback, mTestPackageDefaultNetworkCallback); 18453 mProfileDefaultNetworkCallback.expectAvailableCallbacksValidated(workAgent); 18454 assertEquals(workAgent.getNetwork(), mCm.getActiveNetworkForUid(TEST_WORK_PROFILE_APP_UID)); 18455 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetworkForUid(TEST_PACKAGE_UID)); 18456 18457 // Remove user profile network preference. 18458 mCm.setProfileNetworkPreference(testHandle, PROFILE_NETWORK_PREFERENCE_DEFAULT, 18459 r -> r.run(), listener); 18460 listener.expectOnComplete(); 18461 assertNoCallbacks(mDefaultNetworkCallback, mTestPackageDefaultNetworkCallback); 18462 mProfileDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellAgent); 18463 assertEquals(mCellAgent.getNetwork(), 18464 mCm.getActiveNetworkForUid(TEST_WORK_PROFILE_APP_UID)); 18465 assertEquals(mCellAgent.getNetwork(), mCm.getActiveNetworkForUid(TEST_PACKAGE_UID)); 18466 18467 // Disconnect wifi 18468 mWiFiAgent.disconnect(); 18469 assertNoCallbacks(mProfileDefaultNetworkCallback, mTestPackageDefaultNetworkCallback); 18470 mDefaultNetworkCallback.expect(LOST, mWiFiAgent); 18471 mDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellAgent); 18472 } 18473 18474 @Test 18475 public void testRequestRouteToHostAddress_PackageDoesNotBelongToCaller() { 18476 assertThrows(SecurityException.class, () -> mService.requestRouteToHostAddress( 18477 ConnectivityManager.TYPE_NONE, null /* hostAddress */, "com.not.package.owner", 18478 null /* callingAttributionTag */)); 18479 } 18480 18481 @Test @IgnoreUpTo(SC_V2) 18482 public void testUpdateRateLimit_EnableDisable() throws Exception { 18483 final LinkProperties wifiLp = new LinkProperties(); 18484 wifiLp.setInterfaceName(WIFI_IFNAME); 18485 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, wifiLp); 18486 mWiFiAgent.connect(true); 18487 18488 final LinkProperties cellLp = new LinkProperties(); 18489 cellLp.setInterfaceName(MOBILE_IFNAME); 18490 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp); 18491 mCellAgent.connect(false); 18492 18493 waitForIdle(); 18494 18495 final ArrayTrackRecord<Pair<String, Long>>.ReadHead readHeadWifi = 18496 mDeps.mRateLimitHistory.newReadHead(); 18497 final ArrayTrackRecord<Pair<String, Long>>.ReadHead readHeadCell = 18498 mDeps.mRateLimitHistory.newReadHead(); 18499 18500 // set rate limit to 8MBit/s => 1MB/s 18501 final int rateLimitInBytesPerSec = 1 * 1000 * 1000; 18502 setIngressRateLimit(rateLimitInBytesPerSec); 18503 18504 assertNotNull(readHeadWifi.poll(TIMEOUT_MS, 18505 it -> it.first == wifiLp.getInterfaceName() 18506 && it.second == rateLimitInBytesPerSec)); 18507 assertNotNull(readHeadCell.poll(TIMEOUT_MS, 18508 it -> it.first == cellLp.getInterfaceName() 18509 && it.second == rateLimitInBytesPerSec)); 18510 18511 // disable rate limiting 18512 setIngressRateLimit(-1); 18513 18514 assertNotNull(readHeadWifi.poll(TIMEOUT_MS, 18515 it -> it.first == wifiLp.getInterfaceName() && it.second == -1)); 18516 assertNotNull(readHeadCell.poll(TIMEOUT_MS, 18517 it -> it.first == cellLp.getInterfaceName() && it.second == -1)); 18518 } 18519 18520 @Test @IgnoreUpTo(SC_V2) 18521 public void testUpdateRateLimit_WhenNewNetworkIsAdded() throws Exception { 18522 final LinkProperties wifiLp = new LinkProperties(); 18523 wifiLp.setInterfaceName(WIFI_IFNAME); 18524 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, wifiLp); 18525 mWiFiAgent.connect(true); 18526 18527 waitForIdle(); 18528 18529 final ArrayTrackRecord<Pair<String, Long>>.ReadHead readHead = 18530 mDeps.mRateLimitHistory.newReadHead(); 18531 18532 // set rate limit to 8MBit/s => 1MB/s 18533 final int rateLimitInBytesPerSec = 1 * 1000 * 1000; 18534 setIngressRateLimit(rateLimitInBytesPerSec); 18535 assertNotNull(readHead.poll(TIMEOUT_MS, it -> it.first == wifiLp.getInterfaceName() 18536 && it.second == rateLimitInBytesPerSec)); 18537 18538 final LinkProperties cellLp = new LinkProperties(); 18539 cellLp.setInterfaceName(MOBILE_IFNAME); 18540 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp); 18541 mCellAgent.connect(false); 18542 assertNotNull(readHead.poll(TIMEOUT_MS, it -> it.first == cellLp.getInterfaceName() 18543 && it.second == rateLimitInBytesPerSec)); 18544 } 18545 18546 @Test @IgnoreUpTo(SC_V2) 18547 public void testUpdateRateLimit_OnlyAffectsInternetCapableNetworks() throws Exception { 18548 final LinkProperties wifiLp = new LinkProperties(); 18549 wifiLp.setInterfaceName(WIFI_IFNAME); 18550 18551 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, wifiLp); 18552 mWiFiAgent.connectWithoutInternet(); 18553 18554 waitForIdle(); 18555 18556 setIngressRateLimit(1000); 18557 setIngressRateLimit(-1); 18558 18559 final ArrayTrackRecord<Pair<String, Long>>.ReadHead readHeadWifi = 18560 mDeps.mRateLimitHistory.newReadHead(); 18561 assertNull(readHeadWifi.poll(TIMEOUT_MS, it -> it.first == wifiLp.getInterfaceName())); 18562 } 18563 18564 @Test @IgnoreUpTo(SC_V2) 18565 public void testUpdateRateLimit_DisconnectingResetsRateLimit() 18566 throws Exception { 18567 // Steps: 18568 // - connect network 18569 // - set rate limit 18570 // - disconnect network (interface still exists) 18571 // - disable rate limit 18572 // - connect network 18573 // - ensure network interface is not rate limited 18574 final LinkProperties wifiLp = new LinkProperties(); 18575 wifiLp.setInterfaceName(WIFI_IFNAME); 18576 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, wifiLp); 18577 mWiFiAgent.connect(true); 18578 waitForIdle(); 18579 18580 final ArrayTrackRecord<Pair<String, Long>>.ReadHead readHeadWifi = 18581 mDeps.mRateLimitHistory.newReadHead(); 18582 18583 int rateLimitInBytesPerSec = 1000; 18584 setIngressRateLimit(rateLimitInBytesPerSec); 18585 assertNotNull(readHeadWifi.poll(TIMEOUT_MS, 18586 it -> it.first == wifiLp.getInterfaceName() 18587 && it.second == rateLimitInBytesPerSec)); 18588 18589 mWiFiAgent.disconnect(); 18590 assertNotNull(readHeadWifi.poll(TIMEOUT_MS, 18591 it -> it.first == wifiLp.getInterfaceName() && it.second == -1)); 18592 18593 setIngressRateLimit(-1); 18594 18595 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, wifiLp); 18596 mWiFiAgent.connect(true); 18597 assertNull(readHeadWifi.poll(TIMEOUT_MS, it -> it.first == wifiLp.getInterfaceName())); 18598 } 18599 18600 @Test @IgnoreUpTo(SC_V2) 18601 public void testUpdateRateLimit_UpdateExistingRateLimit() throws Exception { 18602 final LinkProperties wifiLp = new LinkProperties(); 18603 wifiLp.setInterfaceName(WIFI_IFNAME); 18604 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, wifiLp); 18605 mWiFiAgent.connect(true); 18606 waitForIdle(); 18607 18608 final ArrayTrackRecord<Pair<String, Long>>.ReadHead readHeadWifi = 18609 mDeps.mRateLimitHistory.newReadHead(); 18610 18611 // update an active ingress rate limit 18612 setIngressRateLimit(1000); 18613 setIngressRateLimit(2000); 18614 18615 // verify the following order of execution: 18616 // 1. ingress rate limit set to 1000. 18617 // 2. ingress rate limit disabled (triggered by updating active rate limit). 18618 // 3. ingress rate limit set to 2000. 18619 assertNotNull(readHeadWifi.poll(TIMEOUT_MS, 18620 it -> it.first == wifiLp.getInterfaceName() 18621 && it.second == 1000)); 18622 assertNotNull(readHeadWifi.poll(TIMEOUT_MS, 18623 it -> it.first == wifiLp.getInterfaceName() 18624 && it.second == -1)); 18625 assertNotNull(readHeadWifi.poll(TIMEOUT_MS, 18626 it -> it.first == wifiLp.getInterfaceName() 18627 && it.second == 2000)); 18628 } 18629 18630 @Test @IgnoreAfter(SC_V2) 18631 public void testUpdateRateLimit_DoesNothingBeforeT() throws Exception { 18632 final LinkProperties wifiLp = new LinkProperties(); 18633 wifiLp.setInterfaceName(WIFI_IFNAME); 18634 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, wifiLp); 18635 mWiFiAgent.connect(true); 18636 waitForIdle(); 18637 18638 final ArrayTrackRecord<Pair<String, Long>>.ReadHead readHead = 18639 mDeps.mRateLimitHistory.newReadHead(); 18640 18641 setIngressRateLimit(1000); 18642 waitForIdle(); 18643 18644 assertNull(readHead.poll(TEST_CALLBACK_TIMEOUT_MS, it -> true)); 18645 } 18646 18647 @Test 18648 public void testOfferNetwork_ChecksArgumentsOutsideOfHandler() throws Exception { 18649 final TestableNetworkOfferCallback callback = new TestableNetworkOfferCallback( 18650 TIMEOUT_MS /* timeout */, TEST_CALLBACK_TIMEOUT_MS /* noCallbackTimeout */); 18651 final NetworkProvider testProvider = new NetworkProvider(mServiceContext, 18652 mCsHandlerThread.getLooper(), "Test provider"); 18653 final NetworkCapabilities caps = new NetworkCapabilities.Builder() 18654 .addCapability(NET_CAPABILITY_INTERNET) 18655 .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED) 18656 .build(); 18657 18658 final NetworkScore score = new NetworkScore.Builder().build(); 18659 testProvider.registerNetworkOffer(score, caps, r -> r.run(), callback); 18660 testProvider.unregisterNetworkOffer(callback); 18661 18662 assertThrows(NullPointerException.class, 18663 () -> mService.offerNetwork(100, score, caps, null)); 18664 assertThrows(NullPointerException.class, () -> mService.unofferNetwork(null)); 18665 } 18666 18667 public void doTestIgnoreValidationAfterRoam(int resValue, final boolean enabled) 18668 throws Exception { 18669 doReturn(resValue).when(mResources) 18670 .getInteger(R.integer.config_validationFailureAfterRoamIgnoreTimeMillis); 18671 18672 final String bssid1 = "AA:AA:AA:AA:AA:AA"; 18673 final String bssid2 = "BB:BB:BB:BB:BB:BB"; 18674 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); 18675 mCellAgent.connect(true); 18676 NetworkCapabilities wifiNc1 = new NetworkCapabilities() 18677 .addCapability(NET_CAPABILITY_INTERNET) 18678 .addCapability(NET_CAPABILITY_NOT_VPN) 18679 .addCapability(NET_CAPABILITY_NOT_RESTRICTED) 18680 .addCapability(NET_CAPABILITY_TRUSTED) 18681 .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED) 18682 .addTransportType(TRANSPORT_WIFI) 18683 .setTransportInfo(new WifiInfo.Builder().setBssid(bssid1).build()); 18684 NetworkCapabilities wifiNc2 = new NetworkCapabilities(wifiNc1) 18685 .setTransportInfo(new WifiInfo.Builder().setBssid(bssid2).build()); 18686 final LinkProperties wifiLp = new LinkProperties(); 18687 wifiLp.setInterfaceName(WIFI_IFNAME); 18688 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, wifiLp, wifiNc1); 18689 mWiFiAgent.connect(true); 18690 18691 // The default network will be switching to Wi-Fi Network. 18692 final TestNetworkCallback wifiNetworkCallback = new TestNetworkCallback(); 18693 final NetworkRequest wifiRequest = new NetworkRequest.Builder() 18694 .addTransportType(TRANSPORT_WIFI).build(); 18695 mCm.requestNetwork(wifiRequest, wifiNetworkCallback); 18696 wifiNetworkCallback.expectAvailableCallbacksValidated(mWiFiAgent); 18697 registerDefaultNetworkCallbacks(); 18698 mDefaultNetworkCallback.expectAvailableCallbacksValidated(mWiFiAgent); 18699 18700 // There is a bug in the current code where ignoring validation after roam will not 18701 // correctly change the default network if the result if the validation is partial or 18702 // captive portal. TODO : fix the bug and reinstate this code. 18703 if (false) { 18704 // Wi-Fi roaming from wifiNc1 to wifiNc2 but the network is now behind a captive portal. 18705 mWiFiAgent.setNetworkCapabilities(wifiNc2, true /* sendToConnectivityService */); 18706 // The only thing changed in this CAPS is the BSSID, which can't be tested for in this 18707 // test because it's redacted. 18708 wifiNetworkCallback.expectCaps(mWiFiAgent); 18709 mDefaultNetworkCallback.expectCaps(mWiFiAgent); 18710 mWiFiAgent.setNetworkPortal(TEST_REDIRECT_URL, false /* privateDnsProbeSent */); 18711 mCm.reportNetworkConnectivity(mWiFiAgent.getNetwork(), false); 18712 // Wi-Fi is now detected to have a portal : cell should become the default network. 18713 mDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellAgent); 18714 wifiNetworkCallback.expectCaps(mWiFiAgent, 18715 c -> !c.hasCapability(NET_CAPABILITY_VALIDATED)); 18716 wifiNetworkCallback.expectCaps(mWiFiAgent, 18717 c -> c.hasCapability(NET_CAPABILITY_CAPTIVE_PORTAL)); 18718 18719 // Wi-Fi becomes valid again. The default network goes back to Wi-Fi. 18720 mWiFiAgent.setNetworkValid(false /* privateDnsProbeSent */); 18721 mCm.reportNetworkConnectivity(mWiFiAgent.getNetwork(), true); 18722 mDefaultNetworkCallback.expectAvailableCallbacksValidated(mWiFiAgent); 18723 wifiNetworkCallback.expectCaps(mWiFiAgent, 18724 c -> !c.hasCapability(NET_CAPABILITY_CAPTIVE_PORTAL)); 18725 18726 // Wi-Fi roaming from wifiNc2 to wifiNc1, and the network now has partial connectivity. 18727 mWiFiAgent.setNetworkCapabilities(wifiNc1, true); 18728 wifiNetworkCallback.expectCaps(mWiFiAgent); 18729 mDefaultNetworkCallback.expectCaps(mWiFiAgent); 18730 mWiFiAgent.setNetworkPartial(); 18731 mCm.reportNetworkConnectivity(mWiFiAgent.getNetwork(), false); 18732 // Wi-Fi now only offers partial connectivity, so in the absence of accepting partial 18733 // connectivity explicitly for this network, it loses default status to cell. 18734 mDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellAgent); 18735 wifiNetworkCallback.expectCaps(mWiFiAgent, 18736 c -> c.hasCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY)); 18737 18738 // Wi-Fi becomes valid again. The default network goes back to Wi-Fi. 18739 mWiFiAgent.setNetworkValid(false /* privateDnsProbeSent */); 18740 mCm.reportNetworkConnectivity(mWiFiAgent.getNetwork(), true); 18741 mDefaultNetworkCallback.expectAvailableCallbacksValidated(mWiFiAgent); 18742 wifiNetworkCallback.expectCaps(mWiFiAgent, 18743 c -> !c.hasCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY)); 18744 } 18745 mCm.unregisterNetworkCallback(wifiNetworkCallback); 18746 18747 // Wi-Fi roams from wifiNc1 to wifiNc2, and now becomes really invalid. If validation 18748 // failures after roam are not ignored, this will cause cell to become the default network. 18749 // If they are ignored, this will not cause a switch until later. 18750 mWiFiAgent.setNetworkCapabilities(wifiNc2, true); 18751 mDefaultNetworkCallback.expectCaps(mWiFiAgent); 18752 mWiFiAgent.setNetworkInvalid(false /* invalidBecauseOfPrivateDns */); 18753 mCm.reportNetworkConnectivity(mWiFiAgent.getNetwork(), false); 18754 18755 if (enabled) { 18756 // Network validation failed, but the result will be ignored. 18757 assertTrue(mCm.getNetworkCapabilities(mWiFiAgent.getNetwork()).hasCapability( 18758 NET_CAPABILITY_VALIDATED)); 18759 mWiFiAgent.setNetworkValid(false); 18760 18761 // Behavior of after config_validationFailureAfterRoamIgnoreTimeMillis 18762 ConditionVariable waitForValidationBlock = new ConditionVariable(); 18763 doReturn(50).when(mResources) 18764 .getInteger(R.integer.config_validationFailureAfterRoamIgnoreTimeMillis); 18765 // Wi-Fi roaming from wifiNc2 to wifiNc1. 18766 mWiFiAgent.setNetworkCapabilities(wifiNc1, true); 18767 mWiFiAgent.setNetworkInvalid(false); 18768 waitForValidationBlock.block(150); 18769 mCm.reportNetworkConnectivity(mWiFiAgent.getNetwork(), false); 18770 mDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellAgent); 18771 } else { 18772 mDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellAgent); 18773 } 18774 18775 // Wi-Fi is still connected and would become the default network if cell were to 18776 // disconnect. This assertion ensures that the switch to cellular was not caused by 18777 // Wi-Fi disconnecting (e.g., because the capability change to wifiNc2 caused it 18778 // to stop satisfying the default request). 18779 mCellAgent.disconnect(); 18780 mDefaultNetworkCallback.expect(LOST, mCellAgent); 18781 mDefaultNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiAgent); 18782 18783 } 18784 18785 @Test 18786 public void testIgnoreValidationAfterRoamDisabled() throws Exception { 18787 doTestIgnoreValidationAfterRoam(-1, false /* enabled */); 18788 } 18789 18790 @Test 18791 public void testIgnoreValidationAfterRoamEnabled() throws Exception { 18792 final boolean enabled = !mDeps.isAtLeastT(); 18793 doTestIgnoreValidationAfterRoam(5_000, enabled); 18794 } 18795 18796 @Test 18797 public void testShouldIgnoreValidationFailureAfterRoam() { 18798 // Always disabled on T+. 18799 assumeFalse(mDeps.isAtLeastT()); 18800 18801 NetworkAgentInfo nai = fakeWifiNai(new NetworkCapabilities()); 18802 18803 // Enabled, but never roamed. 18804 doReturn(5_000).when(mResources) 18805 .getInteger(R.integer.config_validationFailureAfterRoamIgnoreTimeMillis); 18806 assertEquals(0, nai.lastRoamTime); 18807 assertFalse(mService.shouldIgnoreValidationFailureAfterRoam(nai)); 18808 18809 // Roamed recently. 18810 nai.lastRoamTime = SystemClock.elapsedRealtime() - 500 /* ms */; 18811 assertTrue(mService.shouldIgnoreValidationFailureAfterRoam(nai)); 18812 18813 // Disabled due to invalid setting (maximum is 10 seconds). 18814 doReturn(15_000).when(mResources) 18815 .getInteger(R.integer.config_validationFailureAfterRoamIgnoreTimeMillis); 18816 assertFalse(mService.shouldIgnoreValidationFailureAfterRoam(nai)); 18817 18818 // Disabled. 18819 doReturn(-1).when(mResources) 18820 .getInteger(R.integer.config_validationFailureAfterRoamIgnoreTimeMillis); 18821 assertFalse(mService.shouldIgnoreValidationFailureAfterRoam(nai)); 18822 } 18823 18824 18825 @Test 18826 public void testLegacyTetheringApiGuardWithProperPermission() throws Exception { 18827 final String testIface = "test0"; 18828 mServiceContext.setPermission(ACCESS_NETWORK_STATE, PERMISSION_DENIED); 18829 assertThrows(SecurityException.class, () -> mService.getLastTetherError(testIface)); 18830 assertThrows(SecurityException.class, () -> mService.getTetherableIfaces()); 18831 assertThrows(SecurityException.class, () -> mService.getTetheredIfaces()); 18832 assertThrows(SecurityException.class, () -> mService.getTetheringErroredIfaces()); 18833 assertThrows(SecurityException.class, () -> mService.getTetherableUsbRegexs()); 18834 assertThrows(SecurityException.class, () -> mService.getTetherableWifiRegexs()); 18835 18836 withPermission(ACCESS_NETWORK_STATE, () -> { 18837 mService.getLastTetherError(testIface); 18838 verify(mTetheringManager).getLastTetherError(testIface); 18839 18840 mService.getTetherableIfaces(); 18841 verify(mTetheringManager).getTetherableIfaces(); 18842 18843 mService.getTetheredIfaces(); 18844 verify(mTetheringManager).getTetheredIfaces(); 18845 18846 mService.getTetheringErroredIfaces(); 18847 verify(mTetheringManager).getTetheringErroredIfaces(); 18848 18849 mService.getTetherableUsbRegexs(); 18850 verify(mTetheringManager).getTetherableUsbRegexs(); 18851 18852 mService.getTetherableWifiRegexs(); 18853 verify(mTetheringManager).getTetherableWifiRegexs(); 18854 }); 18855 } 18856 18857 private void verifyMtuSetOnWifiInterface(int mtu) throws Exception { 18858 verify(mMockNetd, times(1)).interfaceSetMtu(WIFI_IFNAME, mtu); 18859 } 18860 18861 private void verifyMtuNeverSetOnWifiInterface() throws Exception { 18862 verify(mMockNetd, never()).interfaceSetMtu(eq(WIFI_IFNAME), anyInt()); 18863 } 18864 18865 private void verifyMtuSetOnWifiInterfaceOnlyUpToT(int mtu) throws Exception { 18866 if (!mService.shouldCreateNetworksImmediately(mWiFiAgent.getNetworkCapabilities())) { 18867 verify(mMockNetd, times(1)).interfaceSetMtu(WIFI_IFNAME, mtu); 18868 } else { 18869 verify(mMockNetd, never()).interfaceSetMtu(eq(WIFI_IFNAME), anyInt()); 18870 } 18871 } 18872 18873 private void verifyMtuSetOnWifiInterfaceOnlyStartingFromU(int mtu) throws Exception { 18874 if (mService.shouldCreateNetworksImmediately(mWiFiAgent.getNetworkCapabilities())) { 18875 verify(mMockNetd, times(1)).interfaceSetMtu(WIFI_IFNAME, mtu); 18876 } else { 18877 verify(mMockNetd, never()).interfaceSetMtu(eq(WIFI_IFNAME), anyInt()); 18878 } 18879 } 18880 18881 @Test 18882 public void testSendLinkPropertiesSetInterfaceMtuBeforeConnect() throws Exception { 18883 final int mtu = 1281; 18884 LinkProperties lp = new LinkProperties(); 18885 lp.setInterfaceName(WIFI_IFNAME); 18886 lp.setMtu(mtu); 18887 18888 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 18889 mWiFiAgent.sendLinkProperties(lp); 18890 waitForIdle(); 18891 verifyMtuSetOnWifiInterface(mtu); 18892 reset(mMockNetd); 18893 18894 mWiFiAgent.connect(false /* validated */); 18895 // Before U, the MTU is always (re-)applied when the network connects. 18896 verifyMtuSetOnWifiInterfaceOnlyUpToT(mtu); 18897 } 18898 18899 @Test 18900 public void testSendLinkPropertiesUpdateInterfaceMtuBeforeConnect() throws Exception { 18901 final int mtu = 1327; 18902 LinkProperties lp = new LinkProperties(); 18903 lp.setInterfaceName(WIFI_IFNAME); 18904 lp.setMtu(mtu); 18905 18906 // Registering an agent with an MTU only sets the MTU on U+. 18907 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, lp); 18908 waitForIdle(); 18909 verifyMtuSetOnWifiInterfaceOnlyStartingFromU(mtu); 18910 reset(mMockNetd); 18911 18912 // Future updates with the same MTU don't set the MTU even on T when it's not set initially. 18913 mWiFiAgent.sendLinkProperties(lp); 18914 waitForIdle(); 18915 verifyMtuNeverSetOnWifiInterface(); 18916 18917 // Updating with a different MTU does work. 18918 lp.setMtu(mtu + 1); 18919 mWiFiAgent.sendLinkProperties(lp); 18920 waitForIdle(); 18921 verifyMtuSetOnWifiInterface(mtu + 1); 18922 reset(mMockNetd); 18923 18924 mWiFiAgent.connect(false /* validated */); 18925 // Before U, the MTU is always (re-)applied when the network connects. 18926 verifyMtuSetOnWifiInterfaceOnlyUpToT(mtu + 1); 18927 } 18928 18929 @Test 18930 public void testSendLinkPropertiesUpdateInterfaceMtuAfterConnect() throws Exception { 18931 final int mtu = 1327; 18932 LinkProperties lp = new LinkProperties(); 18933 lp.setInterfaceName(WIFI_IFNAME); 18934 lp.setMtu(mtu); 18935 18936 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); 18937 mWiFiAgent.connect(false /* validated */); 18938 verifyMtuNeverSetOnWifiInterface(); 18939 18940 mWiFiAgent.sendLinkProperties(lp); 18941 waitForIdle(); 18942 // The MTU is always (re-)applied when the network connects. 18943 verifyMtuSetOnWifiInterface(mtu); 18944 } 18945 18946 @Test 18947 public void testSendLinkPropertiesSetInterfaceMtu_DifferentMtu() throws Exception { 18948 final int mtu = 1328, mtu2 = 1500; 18949 LinkProperties lp = new LinkProperties(); 18950 lp.setInterfaceName(WIFI_IFNAME); 18951 lp.setMtu(mtu); 18952 18953 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, lp); 18954 mWiFiAgent.connect(false /* validated */); 18955 verifyMtuSetOnWifiInterface(mtu); 18956 reset(mMockNetd); 18957 18958 LinkProperties lp2 = new LinkProperties(lp); 18959 lp2.setMtu(mtu2); 18960 mWiFiAgent.sendLinkProperties(lp2); 18961 waitForIdle(); 18962 verifyMtuSetOnWifiInterface(mtu2); 18963 } 18964 18965 @Test 18966 public void testSendLinkPropertiesSetInterfaceMtu_IdenticalMtuAndIface() throws Exception { 18967 final int mtu = 1329; 18968 LinkProperties lp = new LinkProperties(); 18969 lp.setInterfaceName(WIFI_IFNAME); 18970 lp.setMtu(mtu); 18971 18972 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, lp); 18973 mWiFiAgent.connect(false /* validated */); 18974 verifyMtuSetOnWifiInterface(mtu); 18975 reset(mMockNetd); 18976 18977 mWiFiAgent.sendLinkProperties(new LinkProperties(lp)); 18978 waitForIdle(); 18979 verifyMtuNeverSetOnWifiInterface(); 18980 } 18981 18982 @Test 18983 public void testSendLinkPropertiesSetInterfaceMtu_IdenticalMtuAndNullIface() throws Exception { 18984 final int mtu = 1330; 18985 LinkProperties lp = new LinkProperties(); 18986 lp.setInterfaceName(WIFI_IFNAME); 18987 lp.setMtu(mtu); 18988 18989 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, lp); 18990 mWiFiAgent.connect(false /* validated */); 18991 verifyMtuSetOnWifiInterface(mtu); 18992 reset(mMockNetd); 18993 18994 LinkProperties lp2 = new LinkProperties(lp); 18995 lp2.setInterfaceName(null); 18996 mWiFiAgent.sendLinkProperties(new LinkProperties(lp2)); 18997 waitForIdle(); 18998 verifyMtuNeverSetOnWifiInterface(); 18999 } 19000 19001 @Test 19002 public void testSendLinkPropertiesSetInterfaceMtu_IdenticalMtuDiffIface() throws Exception { 19003 final int mtu = 1331; 19004 LinkProperties lp = new LinkProperties(); 19005 lp.setInterfaceName(WIFI_IFNAME); 19006 lp.setMtu(mtu); 19007 19008 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, lp); 19009 mWiFiAgent.connect(false /* validated */); 19010 verifyMtuSetOnWifiInterface(mtu); 19011 reset(mMockNetd); 19012 19013 final String ifaceName2 = WIFI_IFNAME + "_2"; 19014 LinkProperties lp2 = new LinkProperties(lp); 19015 lp2.setInterfaceName(ifaceName2); 19016 19017 mWiFiAgent.sendLinkProperties(new LinkProperties(lp2)); 19018 waitForIdle(); 19019 verify(mMockNetd, times(1)).interfaceSetMtu(eq(ifaceName2), eq(mtu)); 19020 verifyMtuNeverSetOnWifiInterface(); 19021 } 19022 19023 @Test 19024 public void testCreateDeliveryGroupKeyForConnectivityAction() throws Exception { 19025 final NetworkInfo info = new NetworkInfo(0 /* type */, 2 /* subtype */, 19026 "MOBILE" /* typeName */, "LTE" /* subtypeName */); 19027 assertEquals("0;2;null", createDeliveryGroupKeyForConnectivityAction(info)); 19028 19029 info.setExtraInfo("test_info"); 19030 assertEquals("0;2;test_info", createDeliveryGroupKeyForConnectivityAction(info)); 19031 } 19032 19033 @Test 19034 public void testNetdWakeupAddInterfaceForWifiTransport() throws Exception { 19035 final LinkProperties wifiLp = new LinkProperties(); 19036 wifiLp.setInterfaceName(WIFI_IFNAME); 19037 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, wifiLp); 19038 mWiFiAgent.connect(false /* validated */); 19039 19040 final String expectedPrefix = makeNflogPrefix(WIFI_IFNAME, 19041 mWiFiAgent.getNetwork().getNetworkHandle()); 19042 verify(mMockNetd).wakeupAddInterface(WIFI_IFNAME, expectedPrefix, PACKET_WAKEUP_MARK_MASK, 19043 PACKET_WAKEUP_MARK_MASK); 19044 } 19045 19046 @Test 19047 public void testNetdWakeupAddInterfaceForCellularTransport() throws Exception { 19048 final LinkProperties cellLp = new LinkProperties(); 19049 cellLp.setInterfaceName(MOBILE_IFNAME); 19050 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp); 19051 mCellAgent.connect(false /* validated */); 19052 19053 if (mDeps.isAtLeastU()) { 19054 final String expectedPrefix = makeNflogPrefix(MOBILE_IFNAME, 19055 mCellAgent.getNetwork().getNetworkHandle()); 19056 verify(mMockNetd).wakeupAddInterface(MOBILE_IFNAME, expectedPrefix, 19057 PACKET_WAKEUP_MARK_MASK, PACKET_WAKEUP_MARK_MASK); 19058 } else { 19059 verify(mMockNetd, never()).wakeupAddInterface(eq(MOBILE_IFNAME), anyString(), anyInt(), 19060 anyInt()); 19061 } 19062 } 19063 19064 @Test 19065 public void testNetdWakeupAddInterfaceForEthernetTransport() throws Exception { 19066 final String ethernetIface = "eth42"; 19067 19068 final LinkProperties ethLp = new LinkProperties(); 19069 ethLp.setInterfaceName(ethernetIface); 19070 mEthernetAgent = new TestNetworkAgentWrapper(TRANSPORT_ETHERNET, ethLp); 19071 mEthernetAgent.connect(false /* validated */); 19072 19073 verify(mMockNetd, never()).wakeupAddInterface(eq(ethernetIface), anyString(), anyInt(), 19074 anyInt()); 19075 } 19076 19077 // UidFrozenStateChangedCallback is added in U API. 19078 // Returning UidFrozenStateChangedCallback directly makes the test fail on T- devices since 19079 // AndroidJUnit4ClassRunner iterates all declared methods and tries to resolve the return type. 19080 // Solve this by wrapping it in an AtomicReference. Because of erasure, this removes the 19081 // resolving problem as the type isn't seen dynamically. 19082 private AtomicReference<UidFrozenStateChangedCallback> getUidFrozenStateChangedCallback() { 19083 ArgumentCaptor<UidFrozenStateChangedCallback> activityManagerCallbackCaptor = 19084 ArgumentCaptor.forClass(UidFrozenStateChangedCallback.class); 19085 verify(mActivityManager).registerUidFrozenStateChangedCallback(any(), 19086 activityManagerCallbackCaptor.capture()); 19087 return new AtomicReference<>(activityManagerCallbackCaptor.getValue()); 19088 } 19089 19090 private BaseNetdUnsolicitedEventListener getRegisteredNetdUnsolicitedEventListener() 19091 throws RemoteException { 19092 ArgumentCaptor<BaseNetdUnsolicitedEventListener> netdCallbackCaptor = 19093 ArgumentCaptor.forClass(BaseNetdUnsolicitedEventListener.class); 19094 verify(mMockNetd).registerUnsolicitedEventListener(netdCallbackCaptor.capture()); 19095 return netdCallbackCaptor.getValue(); 19096 } 19097 19098 private static final int TEST_FROZEN_UID = 1000; 19099 private static final int TEST_UNFROZEN_UID = 2000; 19100 19101 /** 19102 * Send a UidFrozenStateChanged message to ConnectivityService. Verify that only the frozen UID 19103 * gets passed to socketDestroy(). 19104 */ 19105 @Test 19106 @IgnoreUpTo(Build.VERSION_CODES.TIRAMISU) 19107 public void testFrozenUidSocketDestroy() throws Exception { 19108 final UidFrozenStateChangedCallback callback = 19109 getUidFrozenStateChangedCallback().get(); 19110 19111 final int[] uids = {TEST_FROZEN_UID, TEST_UNFROZEN_UID}; 19112 final int[] frozenStates = {UID_FROZEN_STATE_FROZEN, UID_FROZEN_STATE_UNFROZEN}; 19113 19114 callback.onUidFrozenStateChanged(uids, frozenStates); 19115 19116 waitForIdle(); 19117 19118 verify(mDestroySocketsWrapper).destroyLiveTcpSocketsByOwnerUids(Set.of(TEST_FROZEN_UID)); 19119 } 19120 19121 private void doTestDelayFrozenUidSocketDestroy(int transportType, 19122 boolean freezeWithNetworkInactive, boolean expectDelay) throws Exception { 19123 final TestNetworkCallback defaultCallback = new TestNetworkCallback(); 19124 final LinkProperties lp = new LinkProperties(); 19125 lp.setInterfaceName(transportToTestIfaceName(transportType)); 19126 final TestNetworkAgentWrapper agent = new TestNetworkAgentWrapper(transportType, lp); 19127 final int idleTimerLabel = getIdleTimerLabel(agent.getNetwork().netId, transportType); 19128 testAndCleanup(() -> { 19129 final UidFrozenStateChangedCallback uidFrozenStateChangedCallback = 19130 getUidFrozenStateChangedCallback().get(); 19131 final BaseNetdUnsolicitedEventListener netdUnsolicitedEventListener = 19132 getRegisteredNetdUnsolicitedEventListener(); 19133 19134 mCm.registerDefaultNetworkCallback(defaultCallback); 19135 agent.connect(true); 19136 defaultCallback.expectAvailableThenValidatedCallbacks(agent); 19137 if (freezeWithNetworkInactive) { 19138 // Make network inactive 19139 netdUnsolicitedEventListener.onInterfaceClassActivityChanged(false /* isActive */, 19140 idleTimerLabel, TIMESTAMP, NETWORK_ACTIVITY_NO_UID); 19141 } 19142 19143 // Freeze TEST_FROZEN_UID and TEST_UNFROZEN_UID 19144 final int[] uids1 = {TEST_FROZEN_UID, TEST_UNFROZEN_UID}; 19145 final int[] frozenStates1 = {UID_FROZEN_STATE_FROZEN, UID_FROZEN_STATE_FROZEN}; 19146 uidFrozenStateChangedCallback.onUidFrozenStateChanged(uids1, frozenStates1); 19147 waitForIdle(); 19148 19149 if (expectDelay) { 19150 verify(mDestroySocketsWrapper, never()).destroyLiveTcpSocketsByOwnerUids(any()); 19151 } else { 19152 verify(mDestroySocketsWrapper).destroyLiveTcpSocketsByOwnerUids( 19153 Set.of(TEST_FROZEN_UID, TEST_UNFROZEN_UID)); 19154 clearInvocations(mDestroySocketsWrapper); 19155 } 19156 19157 // Unfreeze TEST_UNFROZEN_UID 19158 final int[] uids2 = {TEST_UNFROZEN_UID}; 19159 final int[] frozenStates2 = {UID_FROZEN_STATE_UNFROZEN}; 19160 uidFrozenStateChangedCallback.onUidFrozenStateChanged(uids2, frozenStates2); 19161 19162 // Make network active 19163 netdUnsolicitedEventListener.onInterfaceClassActivityChanged(true /* isActive */, 19164 idleTimerLabel, TIMESTAMP, TEST_PACKAGE_UID); 19165 waitForIdle(); 19166 19167 if (expectDelay) { 19168 verify(mDestroySocketsWrapper).destroyLiveTcpSocketsByOwnerUids( 19169 Set.of(TEST_FROZEN_UID)); 19170 } else { 19171 verify(mDestroySocketsWrapper, never()).destroyLiveTcpSocketsByOwnerUids(any()); 19172 } 19173 }, () -> { // Cleanup 19174 agent.disconnect(); 19175 }, () -> { 19176 mCm.unregisterNetworkCallback(defaultCallback); 19177 }); 19178 } 19179 19180 @Test 19181 @IgnoreUpTo(Build.VERSION_CODES.TIRAMISU) 19182 public void testDelayFrozenUidSocketDestroy_ActiveCellular() throws Exception { 19183 doTestDelayFrozenUidSocketDestroy(TRANSPORT_CELLULAR, false /* freezeWithNetworkInactive */, 19184 false /* expectDelay */); 19185 } 19186 19187 @Test 19188 @IgnoreUpTo(Build.VERSION_CODES.TIRAMISU) 19189 public void testDelayFrozenUidSocketDestroy_InactiveCellular() throws Exception { 19190 // When the default network is cellular and cellular network is inactive, closing socket 19191 // is delayed. 19192 doTestDelayFrozenUidSocketDestroy(TRANSPORT_CELLULAR, true /* freezeWithNetworkInactive */, 19193 true /* expectDelay */); 19194 } 19195 19196 @Test 19197 @IgnoreUpTo(Build.VERSION_CODES.TIRAMISU) 19198 public void testDelayFrozenUidSocketDestroy_ActiveWifi() throws Exception { 19199 doTestDelayFrozenUidSocketDestroy(TRANSPORT_WIFI, false /* freezeWithNetworkInactive */, 19200 false /* expectDelay */); 19201 } 19202 19203 @Test 19204 @IgnoreUpTo(Build.VERSION_CODES.TIRAMISU) 19205 public void testDelayFrozenUidSocketDestroy_InactiveWifi() throws Exception { 19206 doTestDelayFrozenUidSocketDestroy(TRANSPORT_WIFI, true /* freezeWithNetworkInactive */, 19207 false /* expectDelay */); 19208 } 19209 19210 /** 19211 * @param switchToWifi if true, simulate a migration of the default network to wifi 19212 * if false, simulate a cell disconnection 19213 */ 19214 private void doTestLoseCellDefaultNetwork_ClosePendingFrozenSockets(final boolean switchToWifi) 19215 throws Exception { 19216 final UidFrozenStateChangedCallback uidFrozenStateChangedCallback = 19217 getUidFrozenStateChangedCallback().get(); 19218 final BaseNetdUnsolicitedEventListener netdUnsolicitedEventListener = 19219 getRegisteredNetdUnsolicitedEventListener(); 19220 19221 final LinkProperties wifiLp = new LinkProperties(); 19222 wifiLp.setInterfaceName(WIFI_IFNAME); 19223 mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, wifiLp); 19224 19225 final LinkProperties cellLp = new LinkProperties(); 19226 cellLp.setInterfaceName(MOBILE_IFNAME); 19227 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp); 19228 final int idleTimerLabel = 19229 getIdleTimerLabel(mCellAgent.getNetwork().netId, TRANSPORT_CELLULAR); 19230 19231 final TestNetworkCallback defaultCallback = new TestNetworkCallback(); 19232 mCm.registerDefaultNetworkCallback(defaultCallback); 19233 try { 19234 mCellAgent.connect(true); 19235 defaultCallback.expectAvailableThenValidatedCallbacks(mCellAgent); 19236 19237 // Make cell network inactive 19238 netdUnsolicitedEventListener.onInterfaceClassActivityChanged(false /* isActive */, 19239 idleTimerLabel, TIMESTAMP, NETWORK_ACTIVITY_NO_UID); 19240 19241 // Freeze TEST_FROZEN_UID 19242 final int[] uids = {TEST_FROZEN_UID}; 19243 final int[] frozenStates = {UID_FROZEN_STATE_FROZEN}; 19244 uidFrozenStateChangedCallback.onUidFrozenStateChanged(uids, frozenStates); 19245 waitForIdle(); 19246 19247 // Closing frozen sockets should be delayed since the default network is cellular 19248 // and cellular network is inactive. 19249 verify(mDestroySocketsWrapper, never()).destroyLiveTcpSocketsByOwnerUids(any()); 19250 19251 if (switchToWifi) { 19252 mWiFiAgent.connect(true); 19253 defaultCallback.expectAvailableDoubleValidatedCallbacks(mWiFiAgent); 19254 } else { 19255 mCellAgent.disconnect(); 19256 waitForIdle(); 19257 } 19258 19259 // Pending frozen sockets should be closed since the cellular network is no longer the 19260 // default network. 19261 verify(mDestroySocketsWrapper) 19262 .destroyLiveTcpSocketsByOwnerUids(Set.of(TEST_FROZEN_UID)); 19263 } finally { 19264 mCm.unregisterNetworkCallback(defaultCallback); 19265 } 19266 } 19267 19268 @Test 19269 @IgnoreUpTo(Build.VERSION_CODES.TIRAMISU) 19270 public void testLoseCellDefaultNetwork_SwitchToWifi_ClosePendingFrozenSockets() 19271 throws Exception { 19272 doTestLoseCellDefaultNetwork_ClosePendingFrozenSockets(true /* switchToWifi */); 19273 } 19274 19275 @Test 19276 @IgnoreUpTo(Build.VERSION_CODES.TIRAMISU) 19277 public void testLoseCellDefaultNetwork_NoDefaultNetwork_ClosePendingFrozenSockets() 19278 throws Exception { 19279 doTestLoseCellDefaultNetwork_ClosePendingFrozenSockets(false /* switchToWifi */); 19280 } 19281 19282 @Test 19283 public void testDisconnectSuspendedNetworkStopClatd() throws Exception { 19284 final TestNetworkCallback networkCallback = new TestNetworkCallback(); 19285 final NetworkRequest networkRequest = new NetworkRequest.Builder() 19286 .addCapability(NET_CAPABILITY_DUN) 19287 .build(); 19288 mCm.requestNetwork(networkRequest, networkCallback); 19289 19290 final IpPrefix nat64Prefix = new IpPrefix(InetAddress.getByName("64:ff9b::"), 96); 19291 NetworkCapabilities nc = new NetworkCapabilities().addCapability(NET_CAPABILITY_DUN); 19292 final LinkProperties lp = new LinkProperties(); 19293 lp.setInterfaceName(MOBILE_IFNAME); 19294 lp.addLinkAddress(new LinkAddress("2001:db8:1::1/64")); 19295 lp.setNat64Prefix(nat64Prefix); 19296 mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, lp, nc); 19297 mCellAgent.connect(true /* validated */, false /* hasInternet */, 19298 false /* privateDnsProbeSent */); 19299 19300 verifyClatdStart(null /* inOrder */, MOBILE_IFNAME, mCellAgent.getNetwork().netId, 19301 nat64Prefix.toString()); 19302 19303 mCellAgent.suspend(); 19304 mCm.unregisterNetworkCallback(networkCallback); 19305 mCellAgent.expectDisconnected(); 19306 waitForIdle(); 19307 19308 verifyClatdStop(null /* inOrder */, MOBILE_IFNAME); 19309 } 19310 19311 private static final int EXPECTED_TEST_METHOD_COUNT = 332; 19312 19313 @Test 19314 public void testTestMethodCount() { 19315 final Class<?> testClass = this.getClass(); 19316 19317 int actualTestMethodCount = 0; 19318 for (final Method method : testClass.getDeclaredMethods()) { 19319 if (method.isAnnotationPresent(Test.class)) { 19320 actualTestMethodCount++; 19321 } 19322 } 19323 19324 assertEquals("Adding tests in ConnectivityServiceTest is deprecated, " 19325 + "as it is too big for maintenance. Please consider adding new tests " 19326 + "in subclasses of CSTest instead.", 19327 EXPECTED_TEST_METHOD_COUNT, actualTestMethodCount); 19328 } 19329 19330 // Note : adding tests in ConnectivityServiceTest is deprecated, as it is too big for 19331 // maintenance. Please consider adding new tests in subclasses of CSTest instead. 19332 } 19333