summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/RollbackTest/Android.bp3
-rw-r--r--tests/StagedInstallTest/src/com/android/tests/stagedinstallinternal/host/StagedInstallInternalTest.java52
-rw-r--r--tests/net/common/java/android/net/CaptivePortalDataTest.kt50
-rw-r--r--tests/net/common/java/android/net/CaptivePortalTest.java20
-rw-r--r--tests/net/common/java/android/net/NetworkStackTest.java41
-rw-r--r--tests/net/common/java/android/net/NetworkStateSnapshotTest.kt73
-rw-r--r--tests/net/common/java/android/net/UidRangeTest.java113
-rw-r--r--tests/net/integration/Android.bp2
-rw-r--r--tests/net/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt19
-rw-r--r--tests/net/integration/util/com/android/server/NetworkAgentWrapper.java2
-rw-r--r--tests/net/java/android/net/IpSecAlgorithmTest.java1
-rw-r--r--tests/net/java/android/net/NetworkIdentityTest.kt54
-rw-r--r--tests/net/java/android/net/NetworkTemplateTest.kt118
-rw-r--r--tests/net/java/android/net/UidRangeTest.java67
-rw-r--r--tests/net/java/android/net/VpnTransportInfoTest.java2
-rw-r--r--tests/net/java/android/net/util/MultinetworkPolicyTrackerTest.kt137
-rw-r--r--tests/net/java/com/android/server/ConnectivityServiceTest.java1711
-rw-r--r--tests/net/java/com/android/server/IpSecServiceParameterizedTest.java26
-rw-r--r--tests/net/java/com/android/server/IpSecServiceRefcountedResourceTest.java4
-rw-r--r--tests/net/java/com/android/server/IpSecServiceTest.java9
-rw-r--r--tests/net/java/com/android/server/connectivity/DnsManagerTest.java35
-rw-r--r--tests/net/java/com/android/server/connectivity/LingerMonitorTest.java6
-rw-r--r--tests/net/java/com/android/server/connectivity/Nat464XlatTest.java20
-rw-r--r--tests/net/java/com/android/server/connectivity/NetworkNotificationManagerTest.java4
-rw-r--r--tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java23
-rw-r--r--tests/net/java/com/android/server/connectivity/VpnTest.java126
-rw-r--r--tests/net/java/com/android/server/net/NetworkStatsCollectionTest.java5
-rw-r--r--tests/net/java/com/android/server/net/NetworkStatsObserversTest.java3
-rw-r--r--tests/net/java/com/android/server/net/NetworkStatsServiceTest.java201
-rw-r--r--tests/utils/testutils/java/com/android/internal/util/test/FakeSettingsProvider.java8
-rw-r--r--tests/utils/testutils/java/com/android/internal/util/test/FakeSettingsProviderRule.java76
-rw-r--r--tests/vcn/java/android/net/vcn/VcnManagerTest.java8
-rw-r--r--tests/vcn/java/android/net/vcn/VcnUnderlyingNetworkPolicyTest.java2
-rw-r--r--tests/vcn/java/com/android/server/VcnManagementServiceTest.java183
-rw-r--r--tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java33
-rw-r--r--tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectingStateTest.java20
-rw-r--r--tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionDisconnectedStateTest.java20
-rw-r--r--tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionDisconnectingStateTest.java12
-rw-r--r--tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionRetryTimeoutStateTest.java21
-rw-r--r--tests/vcn/java/com/android/server/vcn/VcnTest.java130
40 files changed, 2854 insertions, 586 deletions
diff --git a/tests/RollbackTest/Android.bp b/tests/RollbackTest/Android.bp
index 025ac420fd4f..f7dda5798a83 100644
--- a/tests/RollbackTest/Android.bp
+++ b/tests/RollbackTest/Android.bp
@@ -104,6 +104,7 @@ apex {
key: "com.android.apex.apkrollback.test.key",
apps: ["TestAppAv1"],
installable: false,
+ updatable: false,
}
apex {
@@ -114,6 +115,7 @@ apex {
key: "com.android.apex.apkrollback.test.key",
apps: ["TestAppAv2"],
installable: false,
+ updatable: false,
}
apex {
@@ -124,4 +126,5 @@ apex {
key: "com.android.apex.apkrollback.test.key",
apps: ["TestAppACrashingV2"],
installable: false,
+ updatable: false,
}
diff --git a/tests/StagedInstallTest/src/com/android/tests/stagedinstallinternal/host/StagedInstallInternalTest.java b/tests/StagedInstallTest/src/com/android/tests/stagedinstallinternal/host/StagedInstallInternalTest.java
index 1b5e6dd65540..dddb317f31e5 100644
--- a/tests/StagedInstallTest/src/com/android/tests/stagedinstallinternal/host/StagedInstallInternalTest.java
+++ b/tests/StagedInstallTest/src/com/android/tests/stagedinstallinternal/host/StagedInstallInternalTest.java
@@ -28,6 +28,7 @@ import android.platform.test.annotations.LargeTest;
import com.android.ddmlib.Log;
import com.android.tests.rollback.host.AbandonSessionsRule;
+import com.android.tradefed.device.DeviceNotAvailableException;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
import com.android.tradefed.util.ProcessInfo;
@@ -39,6 +40,9 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import java.io.File;
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
@RunWith(DeviceJUnit4ClassRunner.class)
public class StagedInstallInternalTest extends BaseHostJUnit4Test {
@@ -182,9 +186,55 @@ public class StagedInstallInternalTest extends BaseHostJUnit4Test {
assertThat(sessionIds.length).isEqualTo(3);
}
+ @Test
+ public void testStagedInstallationShouldCleanUpOnValidationFailure() throws Exception {
+ List<String> before = getStagingDirectories();
+ runPhase("testStagedInstallationShouldCleanUpOnValidationFailure");
+ List<String> after = getStagingDirectories();
+ assertThat(after).isEqualTo(before);
+ }
+
+ @Test
+ public void testStagedInstallationShouldCleanUpOnValidationFailureMultiPackage()
+ throws Exception {
+ List<String> before = getStagingDirectories();
+ runPhase("testStagedInstallationShouldCleanUpOnValidationFailureMultiPackage");
+ List<String> after = getStagingDirectories();
+ assertThat(after).isEqualTo(before);
+ }
+
+ @Test
+ public void testOrphanedStagingDirectoryGetsCleanedUpOnReboot() throws Exception {
+ //create random directories in /data/app-staging folder
+ getDevice().enableAdbRoot();
+ getDevice().executeShellCommand("mkdir /data/app-staging/session_123");
+ getDevice().executeShellCommand("mkdir /data/app-staging/random_name");
+ getDevice().disableAdbRoot();
+
+ assertThat(getStagingDirectories()).isNotEmpty();
+ getDevice().reboot();
+ assertThat(getStagingDirectories()).isEmpty();
+ }
+
+ private List<String> getStagingDirectories() throws DeviceNotAvailableException {
+ String baseDir = "/data/app-staging";
+ try {
+ getDevice().enableAdbRoot();
+ return getDevice().getFileEntry(baseDir).getChildren(false)
+ .stream().filter(entry -> entry.getName().matches("session_\\d+"))
+ .map(entry -> entry.getName())
+ .collect(Collectors.toList());
+ } catch (Exception e) {
+ // Return an empty list if any error
+ return Collections.EMPTY_LIST;
+ } finally {
+ getDevice().disableAdbRoot();
+ }
+ }
+
private void restartSystemServer() throws Exception {
// Restart the system server
- final long oldStartTime = getDevice().getProcessByName("system_server").getStartTime();
+ long oldStartTime = getDevice().getProcessByName("system_server").getStartTime();
getDevice().enableAdbRoot(); // Need root to restart system server
assertThat(getDevice().executeShellCommand("am restart")).contains("Restart the system");
diff --git a/tests/net/common/java/android/net/CaptivePortalDataTest.kt b/tests/net/common/java/android/net/CaptivePortalDataTest.kt
index ad5bbf220d57..18a93319b271 100644
--- a/tests/net/common/java/android/net/CaptivePortalDataTest.kt
+++ b/tests/net/common/java/android/net/CaptivePortalDataTest.kt
@@ -55,14 +55,14 @@ class CaptivePortalDataTest {
.build()
private val dataFromPasspoint = CaptivePortalData.Builder()
- .setUserPortalUrl(Uri.parse("https://tc.example.com/passpoint"),
- CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT)
- .setVenueInfoUrl(Uri.parse("https://venue.example.com/passpoint"),
- CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT)
.setCaptive(true)
.apply {
if (SdkLevel.isAtLeastS()) {
setVenueFriendlyName("venue friendly name")
+ setUserPortalUrl(Uri.parse("https://tc.example.com/passpoint"),
+ CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT)
+ setVenueInfoUrl(Uri.parse("https://venue.example.com/passpoint"),
+ CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT)
}
}
.build()
@@ -96,28 +96,28 @@ class CaptivePortalDataTest {
if (SdkLevel.isAtLeastS()) {
assertNotEqualsAfterChange { it.setVenueFriendlyName("another friendly name") }
assertNotEqualsAfterChange { it.setVenueFriendlyName(null) }
- }
- assertEquals(dataFromPasspoint, CaptivePortalData.Builder(dataFromPasspoint).build())
- assertNotEqualsAfterChange { it.setUserPortalUrl(
- Uri.parse("https://tc.example.com/passpoint")) }
- assertNotEqualsAfterChange { it.setUserPortalUrl(
- Uri.parse("https://tc.example.com/passpoint"),
- CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_OTHER) }
- assertNotEqualsAfterChange { it.setUserPortalUrl(
- Uri.parse("https://tc.example.com/other"),
- CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT) }
- assertNotEqualsAfterChange { it.setUserPortalUrl(
- Uri.parse("https://tc.example.com/passpoint"),
- CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_OTHER) }
- assertNotEqualsAfterChange { it.setVenueInfoUrl(
- Uri.parse("https://venue.example.com/passpoint")) }
- assertNotEqualsAfterChange { it.setVenueInfoUrl(
- Uri.parse("https://venue.example.com/other"),
- CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT) }
- assertNotEqualsAfterChange { it.setVenueInfoUrl(
- Uri.parse("https://venue.example.com/passpoint"),
- CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_OTHER) }
+ assertEquals(dataFromPasspoint, CaptivePortalData.Builder(dataFromPasspoint).build())
+ assertNotEqualsAfterChange { it.setUserPortalUrl(
+ Uri.parse("https://tc.example.com/passpoint")) }
+ assertNotEqualsAfterChange { it.setUserPortalUrl(
+ Uri.parse("https://tc.example.com/passpoint"),
+ CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_OTHER) }
+ assertNotEqualsAfterChange { it.setUserPortalUrl(
+ Uri.parse("https://tc.example.com/other"),
+ CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT) }
+ assertNotEqualsAfterChange { it.setUserPortalUrl(
+ Uri.parse("https://tc.example.com/passpoint"),
+ CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_OTHER) }
+ assertNotEqualsAfterChange { it.setVenueInfoUrl(
+ Uri.parse("https://venue.example.com/passpoint")) }
+ assertNotEqualsAfterChange { it.setVenueInfoUrl(
+ Uri.parse("https://venue.example.com/other"),
+ CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT) }
+ assertNotEqualsAfterChange { it.setVenueInfoUrl(
+ Uri.parse("https://venue.example.com/passpoint"),
+ CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_OTHER) }
+ }
}
@Test
diff --git a/tests/net/common/java/android/net/CaptivePortalTest.java b/tests/net/common/java/android/net/CaptivePortalTest.java
index 7a60cc105a26..15d3398d43c0 100644
--- a/tests/net/common/java/android/net/CaptivePortalTest.java
+++ b/tests/net/common/java/android/net/CaptivePortalTest.java
@@ -24,8 +24,8 @@ import android.os.RemoteException;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRule.IgnoreAfter;
import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
import org.junit.Rule;
@@ -55,7 +55,7 @@ public class CaptivePortalTest {
mCode = request;
}
- @Override
+ // This is only @Override on R-
public void logEvent(int eventId, String packageName) throws RemoteException {
mCode = eventId;
mPackageName = packageName;
@@ -98,12 +98,24 @@ public class CaptivePortalTest {
assertEquals(result.mCode, CaptivePortal.APP_REQUEST_REEVALUATION_REQUIRED);
}
+ @IgnoreUpTo(Build.VERSION_CODES.R)
@Test
public void testLogEvent() {
+ /**
+ * From S testLogEvent is expected to do nothing but shouldn't crash (the API
+ * logEvent has been deprecated).
+ */
final MyCaptivePortalImpl result = runCaptivePortalTest(c -> c.logEvent(
- MetricsEvent.ACTION_CAPTIVE_PORTAL_LOGIN_ACTIVITY,
+ 0,
TEST_PACKAGE_NAME));
- assertEquals(result.mCode, MetricsEvent.ACTION_CAPTIVE_PORTAL_LOGIN_ACTIVITY);
+ }
+
+ @IgnoreAfter(Build.VERSION_CODES.R)
+ @Test
+ public void testLogEvent_UntilR() {
+ final MyCaptivePortalImpl result = runCaptivePortalTest(c -> c.logEvent(
+ 42, TEST_PACKAGE_NAME));
+ assertEquals(result.mCode, 42);
assertEquals(result.mPackageName, TEST_PACKAGE_NAME);
}
}
diff --git a/tests/net/common/java/android/net/NetworkStackTest.java b/tests/net/common/java/android/net/NetworkStackTest.java
index a99aa0106655..f8f9c72374ad 100644
--- a/tests/net/common/java/android/net/NetworkStackTest.java
+++ b/tests/net/common/java/android/net/NetworkStackTest.java
@@ -15,20 +15,8 @@
*/
package android.net;
-import static android.Manifest.permission.NETWORK_STACK;
-import static android.content.pm.PackageManager.PERMISSION_DENIED;
-import static android.content.pm.PackageManager.PERMISSION_GRANTED;
-import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK;
-import static android.net.NetworkStack.checkNetworkStackPermission;
-import static android.net.NetworkStack.checkNetworkStackPermissionOr;
-
import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.when;
-import android.content.Context;
import android.os.Build;
import android.os.IBinder;
@@ -46,44 +34,15 @@ import org.mockito.MockitoAnnotations;
@RunWith(AndroidJUnit4.class)
public class NetworkStackTest {
- private static final String [] OTHER_PERMISSION = {"otherpermission1", "otherpermission2"};
-
@Rule
public DevSdkIgnoreRule mDevSdkIgnoreRule = new DevSdkIgnoreRule();
- @Mock Context mCtx;
@Mock private IBinder mConnectorBinder;
@Before public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
}
- @Test
- public void testCheckNetworkStackPermission() throws Exception {
- when(mCtx.checkCallingOrSelfPermission(eq(NETWORK_STACK))).thenReturn(PERMISSION_GRANTED);
- when(mCtx.checkCallingOrSelfPermission(eq(PERMISSION_MAINLINE_NETWORK_STACK)))
- .thenReturn(PERMISSION_DENIED);
- checkNetworkStackPermission(mCtx);
- checkNetworkStackPermissionOr(mCtx, OTHER_PERMISSION);
-
- when(mCtx.checkCallingOrSelfPermission(eq(NETWORK_STACK))).thenReturn(PERMISSION_DENIED);
- when(mCtx.checkCallingOrSelfPermission(eq(PERMISSION_MAINLINE_NETWORK_STACK)))
- .thenReturn(PERMISSION_GRANTED);
- checkNetworkStackPermission(mCtx);
- checkNetworkStackPermissionOr(mCtx, OTHER_PERMISSION);
-
- when(mCtx.checkCallingOrSelfPermission(any())).thenReturn(PERMISSION_DENIED);
-
- try {
- checkNetworkStackPermissionOr(mCtx, OTHER_PERMISSION);
- } catch (SecurityException e) {
- // Expect to get a SecurityException
- return;
- }
-
- fail("Expect fail but permission granted.");
- }
-
@Test @IgnoreUpTo(Build.VERSION_CODES.Q)
public void testGetService() {
NetworkStack.setServiceForTest(mConnectorBinder);
diff --git a/tests/net/common/java/android/net/NetworkStateSnapshotTest.kt b/tests/net/common/java/android/net/NetworkStateSnapshotTest.kt
new file mode 100644
index 000000000000..0ca4d9551f39
--- /dev/null
+++ b/tests/net/common/java/android/net/NetworkStateSnapshotTest.kt
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net
+
+import android.net.ConnectivityManager.TYPE_NONE
+import android.net.ConnectivityManager.TYPE_WIFI
+import android.net.InetAddresses.parseNumericAddress
+import android.net.NetworkCapabilities.TRANSPORT_WIFI
+import android.os.Build
+import androidx.test.filters.SmallTest
+import com.android.testutils.DevSdkIgnoreRule
+import com.android.testutils.DevSdkIgnoreRunner
+import com.android.testutils.assertParcelSane
+import org.junit.Test
+import org.junit.runner.RunWith
+import java.net.Inet4Address
+import java.net.Inet6Address
+
+private const val TEST_IMSI = "imsi1"
+private const val TEST_SSID = "SSID1"
+private const val TEST_NETID = 123
+
+private val TEST_IPV4_GATEWAY = parseNumericAddress("192.168.222.3") as Inet4Address
+private val TEST_IPV6_GATEWAY = parseNumericAddress("2001:db8::1") as Inet6Address
+private val TEST_IPV4_LINKADDR = LinkAddress("192.168.222.123/24")
+private val TEST_IPV6_LINKADDR = LinkAddress("2001:db8::123/64")
+private val TEST_IFACE = "fake0"
+private val TEST_LINK_PROPERTIES = LinkProperties().apply {
+ interfaceName = TEST_IFACE
+ addLinkAddress(TEST_IPV4_LINKADDR)
+ addLinkAddress(TEST_IPV6_LINKADDR)
+
+ // Add default routes
+ addRoute(RouteInfo(IpPrefix(parseNumericAddress("0.0.0.0"), 0), TEST_IPV4_GATEWAY))
+ addRoute(RouteInfo(IpPrefix(parseNumericAddress("::"), 0), TEST_IPV6_GATEWAY))
+}
+
+private val TEST_CAPABILITIES = NetworkCapabilities().apply {
+ addTransportType(TRANSPORT_WIFI)
+ setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED, false)
+ setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING, true)
+ setSSID(TEST_SSID)
+}
+
+@SmallTest
+@RunWith(DevSdkIgnoreRunner::class)
+@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.R)
+class NetworkStateSnapshotTest {
+
+ @Test
+ fun testParcelUnparcel() {
+ val emptySnapshot = NetworkStateSnapshot(Network(TEST_NETID), NetworkCapabilities(),
+ LinkProperties(), null, TYPE_NONE)
+ val snapshot = NetworkStateSnapshot(
+ Network(TEST_NETID), TEST_CAPABILITIES, TEST_LINK_PROPERTIES, TEST_IMSI, TYPE_WIFI)
+ assertParcelSane(emptySnapshot, 5)
+ assertParcelSane(snapshot, 5)
+ }
+}
diff --git a/tests/net/common/java/android/net/UidRangeTest.java b/tests/net/common/java/android/net/UidRangeTest.java
new file mode 100644
index 000000000000..1b1c95431d6f
--- /dev/null
+++ b/tests/net/common/java/android/net/UidRangeTest.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net;
+
+import static android.os.UserHandle.MIN_SECONDARY_USER_ID;
+import static android.os.UserHandle.SYSTEM;
+import static android.os.UserHandle.USER_SYSTEM;
+import static android.os.UserHandle.getUid;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import android.os.Build;
+import android.os.UserHandle;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class UidRangeTest {
+
+ /*
+ * UidRange is no longer passed to netd. UID ranges between the framework and netd are passed as
+ * UidRangeParcel objects.
+ */
+
+ @Rule
+ public final DevSdkIgnoreRule mIgnoreRule = new DevSdkIgnoreRule();
+
+ @Test
+ public void testSingleItemUidRangeAllowed() {
+ new UidRange(123, 123);
+ new UidRange(0, 0);
+ new UidRange(Integer.MAX_VALUE, Integer.MAX_VALUE);
+ }
+
+ @Test
+ public void testNegativeUidsDisallowed() {
+ try {
+ new UidRange(-2, 100);
+ fail("Exception not thrown for negative start UID");
+ } catch (IllegalArgumentException expected) {
+ }
+
+ try {
+ new UidRange(-200, -100);
+ fail("Exception not thrown for negative stop UID");
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ @Test
+ public void testStopLessThanStartDisallowed() {
+ final int x = 4195000;
+ try {
+ new UidRange(x, x - 1);
+ fail("Exception not thrown for negative-length UID range");
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ @Test
+ public void testGetStartAndEndUser() throws Exception {
+ final UidRange uidRangeOfPrimaryUser = new UidRange(
+ getUid(USER_SYSTEM, 10000), getUid(USER_SYSTEM, 10100));
+ final UidRange uidRangeOfSecondaryUser = new UidRange(
+ getUid(MIN_SECONDARY_USER_ID, 10000), getUid(MIN_SECONDARY_USER_ID, 10100));
+ assertEquals(USER_SYSTEM, uidRangeOfPrimaryUser.getStartUser());
+ assertEquals(USER_SYSTEM, uidRangeOfPrimaryUser.getEndUser());
+ assertEquals(MIN_SECONDARY_USER_ID, uidRangeOfSecondaryUser.getStartUser());
+ assertEquals(MIN_SECONDARY_USER_ID, uidRangeOfSecondaryUser.getEndUser());
+
+ final UidRange uidRangeForDifferentUsers = new UidRange(
+ getUid(USER_SYSTEM, 10000), getUid(MIN_SECONDARY_USER_ID, 10100));
+ assertEquals(USER_SYSTEM, uidRangeOfPrimaryUser.getStartUser());
+ assertEquals(MIN_SECONDARY_USER_ID, uidRangeOfSecondaryUser.getEndUser());
+ }
+
+ @Test @IgnoreUpTo(Build.VERSION_CODES.R)
+ public void testCreateForUser() throws Exception {
+ final UidRange uidRangeOfPrimaryUser = UidRange.createForUser(SYSTEM);
+ final UidRange uidRangeOfSecondaryUser = UidRange.createForUser(
+ UserHandle.of(USER_SYSTEM + 1));
+ assertTrue(uidRangeOfPrimaryUser.stop < uidRangeOfSecondaryUser.start);
+ assertEquals(USER_SYSTEM, uidRangeOfPrimaryUser.getStartUser());
+ assertEquals(USER_SYSTEM, uidRangeOfPrimaryUser.getEndUser());
+ assertEquals(USER_SYSTEM + 1, uidRangeOfSecondaryUser.getStartUser());
+ assertEquals(USER_SYSTEM + 1, uidRangeOfSecondaryUser.getEndUser());
+ }
+}
diff --git a/tests/net/integration/Android.bp b/tests/net/integration/Android.bp
index 4d1e3371e0a7..56f9df78c83e 100644
--- a/tests/net/integration/Android.bp
+++ b/tests/net/integration/Android.bp
@@ -35,7 +35,7 @@ android_test {
"android.test.mock",
],
static_libs: [
- "TestNetworkStackLib",
+ "NetworkStackApiStableLib",
"androidx.test.ext.junit",
"frameworks-net-integration-testutils",
"kotlin-reflect",
diff --git a/tests/net/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt b/tests/net/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt
index 083c8c8741da..2a2dc5628ecd 100644
--- a/tests/net/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt
+++ b/tests/net/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt
@@ -16,6 +16,7 @@
package com.android.server.net.integrationtests
+import android.app.usage.NetworkStatsManager
import android.content.ComponentName
import android.content.Context
import android.content.Context.BIND_AUTO_CREATE
@@ -25,7 +26,6 @@ import android.content.ServiceConnection
import android.net.ConnectivityManager
import android.net.IDnsResolver
import android.net.INetd
-import android.net.INetworkStatsService
import android.net.LinkProperties
import android.net.NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL
import android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET
@@ -37,7 +37,7 @@ import android.net.Uri
import android.net.metrics.IpConnectivityLog
import android.os.ConditionVariable
import android.os.IBinder
-import android.os.INetworkManagementService
+import android.os.SystemConfigManager
import android.os.UserHandle
import android.testing.TestableContext
import android.util.Log
@@ -57,6 +57,7 @@ import org.junit.BeforeClass
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.AdditionalAnswers
+import org.mockito.ArgumentMatchers.anyString
import org.mockito.Mock
import org.mockito.Mockito.any
import org.mockito.Mockito.anyInt
@@ -85,15 +86,15 @@ class ConnectivityServiceIntegrationTest {
// lateinit used here for mocks as they need to be reinitialized between each test and the test
// should crash if they are used before being initialized.
@Mock
- private lateinit var netManager: INetworkManagementService
- @Mock
- private lateinit var statsService: INetworkStatsService
+ private lateinit var statsManager: NetworkStatsManager
@Mock
private lateinit var log: IpConnectivityLog
@Mock
private lateinit var netd: INetd
@Mock
private lateinit var dnsResolver: IDnsResolver
+ @Mock
+ private lateinit var systemConfigManager: SystemConfigManager
@Spy
private var context = TestableContext(realContext)
@@ -151,6 +152,11 @@ class ConnectivityServiceIntegrationTest {
doReturn(UserHandle.ALL).`when`(asUserCtx).user
doReturn(asUserCtx).`when`(context).createContextAsUser(eq(UserHandle.ALL), anyInt())
doNothing().`when`(context).sendStickyBroadcast(any(), any())
+ doReturn(Context.SYSTEM_CONFIG_SERVICE).`when`(context)
+ .getSystemServiceName(SystemConfigManager::class.java)
+ doReturn(systemConfigManager).`when`(context)
+ .getSystemService(Context.SYSTEM_CONFIG_SERVICE)
+ doReturn(IntArray(0)).`when`(systemConfigManager).getSystemPermissionUids(anyString())
networkStackClient = TestNetworkStackClient(realContext)
networkStackClient.init()
@@ -163,12 +169,13 @@ class ConnectivityServiceIntegrationTest {
service = TestConnectivityService(makeDependencies())
cm = ConnectivityManager(context, service)
context.addMockSystemService(Context.CONNECTIVITY_SERVICE, cm)
+ context.addMockSystemService(Context.NETWORK_STATS_SERVICE, statsManager)
service.systemReadyInternal()
}
private inner class TestConnectivityService(deps: Dependencies) : ConnectivityService(
- context, netManager, statsService, dnsResolver, log, netd, deps)
+ context, dnsResolver, log, netd, deps)
private fun makeDependencies(): ConnectivityService.Dependencies {
val deps = spy(ConnectivityService.Dependencies())
diff --git a/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java b/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java
index dc9e587332cb..e1da3d0ae2b3 100644
--- a/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java
+++ b/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java
@@ -17,6 +17,7 @@
package com.android.server;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN;
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
import static android.net.NetworkCapabilities.TRANSPORT_ETHERNET;
@@ -84,6 +85,7 @@ public class NetworkAgentWrapper implements TestableNetworkCallback.HasNetwork {
final String typeName = ConnectivityManager.getNetworkTypeName(type);
mNetworkCapabilities = (ncTemplate != null) ? ncTemplate : new NetworkCapabilities();
mNetworkCapabilities.addCapability(NET_CAPABILITY_NOT_SUSPENDED);
+ mNetworkCapabilities.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED);
mNetworkCapabilities.addTransportType(transport);
switch (transport) {
case TRANSPORT_ETHERNET:
diff --git a/tests/net/java/android/net/IpSecAlgorithmTest.java b/tests/net/java/android/net/IpSecAlgorithmTest.java
index 2e1c29a2e405..3a8d6004f66f 100644
--- a/tests/net/java/android/net/IpSecAlgorithmTest.java
+++ b/tests/net/java/android/net/IpSecAlgorithmTest.java
@@ -129,6 +129,7 @@ public class IpSecAlgorithmTest {
checkCryptKeyLenValidation(IpSecAlgorithm.CRYPT_AES_CTR, len);
}
checkAuthKeyAndTruncLenValidation(IpSecAlgorithm.AUTH_AES_XCBC, 128, 96);
+ checkAuthKeyAndTruncLenValidation(IpSecAlgorithm.AUTH_AES_CMAC, 128, 96);
checkAuthKeyAndTruncLenValidation(IpSecAlgorithm.AUTH_CRYPT_CHACHA20_POLY1305, 288, 128);
}
diff --git a/tests/net/java/android/net/NetworkIdentityTest.kt b/tests/net/java/android/net/NetworkIdentityTest.kt
new file mode 100644
index 000000000000..eb2b85c14578
--- /dev/null
+++ b/tests/net/java/android/net/NetworkIdentityTest.kt
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net
+
+import android.net.NetworkIdentity.OEM_NONE
+import android.net.NetworkIdentity.OEM_PAID
+import android.net.NetworkIdentity.OEM_PRIVATE
+import android.net.NetworkIdentity.getOemBitfield
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+import kotlin.test.assertEquals
+
+@RunWith(JUnit4::class)
+class NetworkIdentityTest {
+ @Test
+ fun testGetOemBitfield() {
+ val oemNone = NetworkCapabilities().apply {
+ setCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PAID, false)
+ setCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE, false)
+ }
+ val oemPaid = NetworkCapabilities().apply {
+ setCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PAID, true)
+ setCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE, false)
+ }
+ val oemPrivate = NetworkCapabilities().apply {
+ setCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PAID, false)
+ setCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE, true)
+ }
+ val oemAll = NetworkCapabilities().apply {
+ setCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PAID, true)
+ setCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE, true)
+ }
+
+ assertEquals(getOemBitfield(oemNone), OEM_NONE)
+ assertEquals(getOemBitfield(oemPaid), OEM_PAID)
+ assertEquals(getOemBitfield(oemPrivate), OEM_PRIVATE)
+ assertEquals(getOemBitfield(oemAll), OEM_PAID or OEM_PRIVATE)
+ }
+}
diff --git a/tests/net/java/android/net/NetworkTemplateTest.kt b/tests/net/java/android/net/NetworkTemplateTest.kt
index 1f8f6f311069..64b774cc4340 100644
--- a/tests/net/java/android/net/NetworkTemplateTest.kt
+++ b/tests/net/java/android/net/NetworkTemplateTest.kt
@@ -20,14 +20,22 @@ import android.content.Context
import android.net.ConnectivityManager.TYPE_MOBILE
import android.net.ConnectivityManager.TYPE_WIFI
import android.net.NetworkIdentity.SUBTYPE_COMBINED
+import android.net.NetworkIdentity.OEM_NONE
+import android.net.NetworkIdentity.OEM_PAID
+import android.net.NetworkIdentity.OEM_PRIVATE
import android.net.NetworkIdentity.buildNetworkIdentity
import android.net.NetworkStats.DEFAULT_NETWORK_ALL
import android.net.NetworkStats.METERED_ALL
import android.net.NetworkStats.ROAMING_ALL
import android.net.NetworkTemplate.MATCH_MOBILE
+import android.net.NetworkTemplate.MATCH_MOBILE_WILDCARD
import android.net.NetworkTemplate.MATCH_WIFI
+import android.net.NetworkTemplate.MATCH_WIFI_WILDCARD
import android.net.NetworkTemplate.NETWORK_TYPE_5G_NSA
import android.net.NetworkTemplate.NETWORK_TYPE_ALL
+import android.net.NetworkTemplate.OEM_MANAGED_ALL
+import android.net.NetworkTemplate.OEM_MANAGED_NO
+import android.net.NetworkTemplate.OEM_MANAGED_YES
import android.net.NetworkTemplate.buildTemplateMobileWithRatType
import android.telephony.TelephonyManager
import com.android.testutils.assertParcelSane
@@ -37,6 +45,7 @@ import org.junit.runner.RunWith
import org.junit.runners.JUnit4
import org.mockito.Mockito.mock
import org.mockito.MockitoAnnotations
+import kotlin.test.assertEquals
import kotlin.test.assertFalse
import kotlin.test.assertNotEquals
import kotlin.test.assertTrue
@@ -49,23 +58,28 @@ private const val TEST_SSID1 = "ssid1"
class NetworkTemplateTest {
private val mockContext = mock(Context::class.java)
- private fun buildMobileNetworkState(subscriberId: String): NetworkState =
+ private fun buildMobileNetworkState(subscriberId: String): NetworkStateSnapshot =
buildNetworkState(TYPE_MOBILE, subscriberId = subscriberId)
- private fun buildWifiNetworkState(ssid: String): NetworkState =
+ private fun buildWifiNetworkState(ssid: String): NetworkStateSnapshot =
buildNetworkState(TYPE_WIFI, ssid = ssid)
private fun buildNetworkState(
type: Int,
subscriberId: String? = null,
- ssid: String? = null
- ): NetworkState {
+ ssid: String? = null,
+ oemManaged: Int = OEM_NONE
+ ): NetworkStateSnapshot {
val lp = LinkProperties()
val caps = NetworkCapabilities().apply {
setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED, false)
setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING, true)
setSSID(ssid)
+ setCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PAID,
+ (oemManaged and OEM_PAID) == OEM_PAID)
+ setCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE,
+ (oemManaged and OEM_PRIVATE) == OEM_PRIVATE)
}
- return NetworkState(type, lp, caps, mock(Network::class.java), subscriberId, ssid)
+ return NetworkStateSnapshot(mock(Network::class.java), caps, lp, subscriberId, type)
}
private fun NetworkTemplate.assertMatches(ident: NetworkIdentity) =
@@ -136,11 +150,15 @@ class NetworkTemplateTest {
@Test
fun testParcelUnparcel() {
val templateMobile = NetworkTemplate(MATCH_MOBILE, TEST_IMSI1, null, null, METERED_ALL,
- ROAMING_ALL, DEFAULT_NETWORK_ALL, TelephonyManager.NETWORK_TYPE_LTE)
+ ROAMING_ALL, DEFAULT_NETWORK_ALL, TelephonyManager.NETWORK_TYPE_LTE,
+ OEM_MANAGED_ALL)
val templateWifi = NetworkTemplate(MATCH_WIFI, null, null, TEST_SSID1, METERED_ALL,
- ROAMING_ALL, DEFAULT_NETWORK_ALL, 0)
- assertParcelSane(templateMobile, 8)
- assertParcelSane(templateWifi, 8)
+ ROAMING_ALL, DEFAULT_NETWORK_ALL, 0, OEM_MANAGED_ALL)
+ val templateOem = NetworkTemplate(MATCH_MOBILE, null, null, null, METERED_ALL,
+ ROAMING_ALL, DEFAULT_NETWORK_ALL, 0, OEM_MANAGED_YES)
+ assertParcelSane(templateMobile, 9)
+ assertParcelSane(templateWifi, 9)
+ assertParcelSane(templateOem, 9)
}
// Verify NETWORK_TYPE_* constants in NetworkTemplate do not conflict with
@@ -152,4 +170,86 @@ class NetworkTemplateTest {
assertNotEquals(NETWORK_TYPE_5G_NSA, ratType)
}
}
+
+ @Test
+ fun testOemNetworkConstants() {
+ val constantValues = arrayOf(OEM_MANAGED_YES, OEM_MANAGED_ALL, OEM_MANAGED_NO,
+ OEM_PAID, OEM_PRIVATE, OEM_PAID or OEM_PRIVATE)
+
+ // Verify that "not OEM managed network" constants are equal.
+ assertEquals(OEM_MANAGED_NO, OEM_NONE)
+
+ // Verify the constants don't conflict.
+ assertEquals(constantValues.size, constantValues.distinct().count())
+ }
+
+ /**
+ * Helper to enumerate and assert OEM managed wifi and mobile {@code NetworkTemplate}s match
+ * their the appropriate OEM managed {@code NetworkIdentity}s.
+ *
+ * @param networkType {@code TYPE_MOBILE} or {@code TYPE_WIFI}
+ * @param matchType A match rule from {@code NetworkTemplate.MATCH_*} corresponding to the
+ * networkType.
+ * @param subscriberId To be populated with {@code TEST_IMSI*} only if networkType is
+ * {@code TYPE_MOBILE}. May be left as null when matchType is
+ * {@link NetworkTemplate.MATCH_MOBILE_WILDCARD}.
+ * @param templateSsid Top be populated with {@code TEST_SSID*} only if networkType is
+ * {@code TYPE_WIFI}. May be left as null when matchType is
+ * {@link NetworkTemplate.MATCH_WIFI_WILDCARD}.
+ * @param identSsid If networkType is {@code TYPE_WIFI}, this value must *NOT* be null. Provide
+ * one of {@code TEST_SSID*}.
+ */
+ private fun matchOemManagedIdent(
+ networkType: Int,
+ matchType: Int,
+ subscriberId: String? = null,
+ templateSsid: String? = null,
+ identSsid: String? = null
+ ) {
+ val oemManagedStates = arrayOf(OEM_NONE, OEM_PAID, OEM_PRIVATE, OEM_PAID or OEM_PRIVATE)
+ // A null subscriberId needs a null matchSubscriberIds argument as well.
+ val matchSubscriberIds = if (subscriberId == null) null else arrayOf(subscriberId)
+
+ val templateOemYes = NetworkTemplate(matchType, subscriberId, matchSubscriberIds,
+ templateSsid, METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL,
+ OEM_MANAGED_YES)
+ val templateOemAll = NetworkTemplate(matchType, subscriberId, matchSubscriberIds,
+ templateSsid, METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL,
+ OEM_MANAGED_ALL)
+
+ for (identityOemManagedState in oemManagedStates) {
+ val ident = buildNetworkIdentity(mockContext, buildNetworkState(networkType,
+ subscriberId, identSsid, identityOemManagedState), /*defaultNetwork=*/false,
+ /*subType=*/0)
+
+ // Create a template with each OEM managed type and match it against the NetworkIdentity
+ for (templateOemManagedState in oemManagedStates) {
+ val template = NetworkTemplate(matchType, subscriberId, matchSubscriberIds,
+ templateSsid, METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL,
+ NETWORK_TYPE_ALL, templateOemManagedState)
+ if (identityOemManagedState == templateOemManagedState) {
+ template.assertMatches(ident)
+ } else {
+ template.assertDoesNotMatch(ident)
+ }
+ }
+ // OEM_MANAGED_ALL ignores OEM state.
+ templateOemAll.assertMatches(ident)
+ if (identityOemManagedState == OEM_NONE) {
+ // OEM_MANAGED_YES matches everything except OEM_NONE.
+ templateOemYes.assertDoesNotMatch(ident)
+ } else {
+ templateOemYes.assertMatches(ident)
+ }
+ }
+ }
+
+ @Test
+ fun testOemManagedMatchesIdent() {
+ matchOemManagedIdent(TYPE_MOBILE, MATCH_MOBILE, subscriberId = TEST_IMSI1)
+ matchOemManagedIdent(TYPE_MOBILE, MATCH_MOBILE_WILDCARD)
+ matchOemManagedIdent(TYPE_WIFI, MATCH_WIFI, templateSsid = TEST_SSID1,
+ identSsid = TEST_SSID1)
+ matchOemManagedIdent(TYPE_WIFI, MATCH_WIFI_WILDCARD, identSsid = TEST_SSID1)
+ }
}
diff --git a/tests/net/java/android/net/UidRangeTest.java b/tests/net/java/android/net/UidRangeTest.java
deleted file mode 100644
index ea1df096e208..000000000000
--- a/tests/net/java/android/net/UidRangeTest.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net;
-
-import static org.junit.Assert.fail;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class UidRangeTest {
-
- /*
- * UidRange is no longer passed to netd. UID ranges between the framework and netd are passed as
- * UidRangeParcel objects.
- */
-
- @Test
- public void testSingleItemUidRangeAllowed() {
- new UidRange(123, 123);
- new UidRange(0, 0);
- new UidRange(Integer.MAX_VALUE, Integer.MAX_VALUE);
- }
-
- @Test
- public void testNegativeUidsDisallowed() {
- try {
- new UidRange(-2, 100);
- fail("Exception not thrown for negative start UID");
- } catch (IllegalArgumentException expected) {
- }
-
- try {
- new UidRange(-200, -100);
- fail("Exception not thrown for negative stop UID");
- } catch (IllegalArgumentException expected) {
- }
- }
-
- @Test
- public void testStopLessThanStartDisallowed() {
- final int x = 4195000;
- try {
- new UidRange(x, x - 1);
- fail("Exception not thrown for negative-length UID range");
- } catch (IllegalArgumentException expected) {
- }
- }
-} \ No newline at end of file
diff --git a/tests/net/java/android/net/VpnTransportInfoTest.java b/tests/net/java/android/net/VpnTransportInfoTest.java
index 866f38c84333..d04c87b29c25 100644
--- a/tests/net/java/android/net/VpnTransportInfoTest.java
+++ b/tests/net/java/android/net/VpnTransportInfoTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 The Android Open Source Project
+ * Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/tests/net/java/android/net/util/MultinetworkPolicyTrackerTest.kt b/tests/net/java/android/net/util/MultinetworkPolicyTrackerTest.kt
new file mode 100644
index 000000000000..c1315f64c56b
--- /dev/null
+++ b/tests/net/java/android/net/util/MultinetworkPolicyTrackerTest.kt
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.util
+
+import android.content.Context
+import android.content.res.Resources
+import android.net.ConnectivityManager.MULTIPATH_PREFERENCE_HANDOVER
+import android.net.ConnectivityManager.MULTIPATH_PREFERENCE_PERFORMANCE
+import android.net.ConnectivityManager.MULTIPATH_PREFERENCE_RELIABILITY
+import android.net.util.MultinetworkPolicyTracker.ActiveDataSubscriptionIdListener
+import android.provider.Settings
+import android.provider.Settings.Global.NETWORK_AVOID_BAD_WIFI
+import android.provider.Settings.Global.NETWORK_METERED_MULTIPATH_PREFERENCE
+import android.telephony.SubscriptionInfo
+import android.telephony.SubscriptionManager
+import android.telephony.TelephonyManager
+import android.test.mock.MockContentResolver
+import androidx.test.filters.SmallTest
+import androidx.test.runner.AndroidJUnit4
+import com.android.internal.R
+import com.android.internal.util.test.FakeSettingsProvider
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertFalse
+import org.junit.Assert.assertTrue
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentCaptor
+import org.mockito.ArgumentMatchers.anyInt
+import org.mockito.ArgumentMatchers.argThat
+import org.mockito.Mockito.any
+import org.mockito.Mockito.doReturn
+import org.mockito.Mockito.mock
+import org.mockito.Mockito.times
+import org.mockito.Mockito.verify
+
+/**
+ * Tests for [MultinetworkPolicyTracker].
+ *
+ * Build, install and run with:
+ * atest android.net.util.MultinetworkPolicyTrackerTest
+ */
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+class MultinetworkPolicyTrackerTest {
+ private val resources = mock(Resources::class.java).also {
+ doReturn(0).`when`(it).getInteger(R.integer.config_networkAvoidBadWifi)
+ }
+ private val telephonyManager = mock(TelephonyManager::class.java)
+ private val subscriptionManager = mock(SubscriptionManager::class.java).also {
+ doReturn(null).`when`(it).getActiveSubscriptionInfo(anyInt())
+ }
+ private val resolver = MockContentResolver().apply {
+ addProvider(Settings.AUTHORITY, FakeSettingsProvider()) }
+ private val context = mock(Context::class.java).also {
+ doReturn(Context.TELEPHONY_SERVICE).`when`(it)
+ .getSystemServiceName(TelephonyManager::class.java)
+ doReturn(telephonyManager).`when`(it).getSystemService(Context.TELEPHONY_SERVICE)
+ doReturn(subscriptionManager).`when`(it)
+ .getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE)
+ doReturn(resolver).`when`(it).contentResolver
+ doReturn(resources).`when`(it).resources
+ doReturn(it).`when`(it).createConfigurationContext(any())
+ Settings.Global.putString(resolver, NETWORK_AVOID_BAD_WIFI, "1")
+ }
+ private val tracker = MultinetworkPolicyTracker(context, null /* handler */)
+
+ private fun assertMultipathPreference(preference: Int) {
+ Settings.Global.putString(resolver, NETWORK_METERED_MULTIPATH_PREFERENCE,
+ preference.toString())
+ tracker.updateMeteredMultipathPreference()
+ assertEquals(preference, tracker.meteredMultipathPreference)
+ }
+
+ @Test
+ fun testUpdateMeteredMultipathPreference() {
+ assertMultipathPreference(MULTIPATH_PREFERENCE_HANDOVER)
+ assertMultipathPreference(MULTIPATH_PREFERENCE_RELIABILITY)
+ assertMultipathPreference(MULTIPATH_PREFERENCE_PERFORMANCE)
+ }
+
+ @Test
+ fun testUpdateAvoidBadWifi() {
+ Settings.Global.putString(resolver, NETWORK_AVOID_BAD_WIFI, "0")
+ assertTrue(tracker.updateAvoidBadWifi())
+ assertFalse(tracker.avoidBadWifi)
+
+ doReturn(1).`when`(resources).getInteger(R.integer.config_networkAvoidBadWifi)
+ assertTrue(tracker.updateAvoidBadWifi())
+ assertTrue(tracker.avoidBadWifi)
+ }
+
+ @Test
+ fun testOnActiveDataSubscriptionIdChanged() {
+ val testSubId = 1000
+ val subscriptionInfo = SubscriptionInfo(testSubId, ""/* iccId */, 1/* iccId */,
+ "TMO"/* displayName */, "TMO"/* carrierName */, 1/* nameSource */, 1/* iconTint */,
+ "123"/* number */, 1/* roaming */, null/* icon */, "310"/* mcc */, "210"/* mnc */,
+ ""/* countryIso */, false/* isEmbedded */, null/* nativeAccessRules */,
+ "1"/* cardString */)
+ doReturn(subscriptionInfo).`when`(subscriptionManager).getActiveSubscriptionInfo(testSubId)
+
+ // Modify avoidBadWifi and meteredMultipathPreference settings value and local variables in
+ // MultinetworkPolicyTracker should be also updated after subId changed.
+ Settings.Global.putString(resolver, NETWORK_AVOID_BAD_WIFI, "0")
+ Settings.Global.putString(resolver, NETWORK_METERED_MULTIPATH_PREFERENCE,
+ MULTIPATH_PREFERENCE_PERFORMANCE.toString())
+
+ val listenerCaptor = ArgumentCaptor.forClass(
+ ActiveDataSubscriptionIdListener::class.java)
+ verify(telephonyManager, times(1))
+ .registerTelephonyCallback(any(), listenerCaptor.capture())
+ val listener = listenerCaptor.value
+ listener.onActiveDataSubscriptionIdChanged(testSubId)
+
+ // Check it get resource value with test sub id.
+ verify(subscriptionManager, times(1)).getActiveSubscriptionInfo(testSubId)
+ verify(context).createConfigurationContext(argThat { it.mcc == 310 && it.mnc == 210 })
+
+ // Check if avoidBadWifi and meteredMultipathPreference values have been updated.
+ assertFalse(tracker.avoidBadWifi)
+ assertEquals(MULTIPATH_PREFERENCE_PERFORMANCE, tracker.meteredMultipathPreference)
+ }
+}
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index 182897e37e0a..a643bc8a94c0 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -53,6 +53,7 @@ import static android.net.NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL;
import static android.net.NetworkCapabilities.NET_CAPABILITY_CBS;
import static android.net.NetworkCapabilities.NET_CAPABILITY_DUN;
import static android.net.NetworkCapabilities.NET_CAPABILITY_EIMS;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_ENTERPRISE;
import static android.net.NetworkCapabilities.NET_CAPABILITY_FOREGROUND;
import static android.net.NetworkCapabilities.NET_CAPABILITY_FOTA;
import static android.net.NetworkCapabilities.NET_CAPABILITY_IA;
@@ -71,6 +72,7 @@ import static android.net.NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE;
import static android.net.NetworkCapabilities.NET_CAPABILITY_PARTIAL_CONNECTIVITY;
import static android.net.NetworkCapabilities.NET_CAPABILITY_RCS;
import static android.net.NetworkCapabilities.NET_CAPABILITY_SUPL;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_TRUSTED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_WIFI_P2P;
@@ -84,7 +86,16 @@ import static android.net.NetworkPolicyManager.RULE_ALLOW_METERED;
import static android.net.NetworkPolicyManager.RULE_NONE;
import static android.net.NetworkPolicyManager.RULE_REJECT_ALL;
import static android.net.NetworkPolicyManager.RULE_REJECT_METERED;
+import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID;
+import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK;
+import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY;
+import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY;
+import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_UNINITIALIZED;
import static android.net.RouteInfo.RTN_UNREACHABLE;
+import static android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener.PREFIX_OPERATION_ADDED;
+import static android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener.PREFIX_OPERATION_REMOVED;
+import static android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener.VALIDATION_RESULT_FAILURE;
+import static android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener.VALIDATION_RESULT_SUCCESS;
import static android.os.Process.INVALID_UID;
import static android.system.OsConstants.IPPROTO_TCP;
@@ -93,6 +104,7 @@ import static com.android.testutils.ConcurrentUtils.await;
import static com.android.testutils.ConcurrentUtils.durationOf;
import static com.android.testutils.ExceptionUtils.ignoreExceptions;
import static com.android.testutils.HandlerUtils.waitForIdleSerialExecutor;
+import static com.android.testutils.MiscAsserts.assertContainsAll;
import static com.android.testutils.MiscAsserts.assertContainsExactly;
import static com.android.testutils.MiscAsserts.assertEmpty;
import static com.android.testutils.MiscAsserts.assertLength;
@@ -139,6 +151,7 @@ import android.app.AlarmManager;
import android.app.AppOpsManager;
import android.app.NotificationManager;
import android.app.PendingIntent;
+import android.app.usage.NetworkStatsManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.ContentProvider;
@@ -170,7 +183,6 @@ import android.net.INetd;
import android.net.INetworkMonitor;
import android.net.INetworkMonitorCallbacks;
import android.net.INetworkPolicyListener;
-import android.net.INetworkStatsService;
import android.net.IOnSetOemNetworkPreferenceListener;
import android.net.IQosCallback;
import android.net.InetAddresses;
@@ -193,7 +205,7 @@ import android.net.NetworkRequest;
import android.net.NetworkSpecifier;
import android.net.NetworkStack;
import android.net.NetworkStackClient;
-import android.net.NetworkState;
+import android.net.NetworkStateSnapshot;
import android.net.NetworkTestResultParcelable;
import android.net.OemNetworkPreferences;
import android.net.ProxyInfo;
@@ -212,6 +224,8 @@ import android.net.Uri;
import android.net.VpnManager;
import android.net.VpnTransportInfo;
import android.net.metrics.IpConnectivityLog;
+import android.net.resolv.aidl.Nat64PrefixEventParcel;
+import android.net.resolv.aidl.PrivateDnsValidationEventParcel;
import android.net.shared.NetworkMonitorUtils;
import android.net.shared.PrivateDnsConfig;
import android.net.util.MultinetworkPolicyTracker;
@@ -233,11 +247,11 @@ import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceSpecificException;
import android.os.SystemClock;
+import android.os.SystemConfigManager;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
import android.security.Credentials;
-import android.security.KeyStore;
import android.system.Os;
import android.telephony.TelephonyManager;
import android.telephony.data.EpsBearerQosSessionAttributes;
@@ -269,6 +283,7 @@ import com.android.server.connectivity.NetworkNotificationManager.NotificationTy
import com.android.server.connectivity.ProxyTracker;
import com.android.server.connectivity.QosCallbackTracker;
import com.android.server.connectivity.Vpn;
+import com.android.server.connectivity.VpnProfileStore;
import com.android.server.net.NetworkPinner;
import com.android.server.net.NetworkPolicyManagerInternal;
import com.android.testutils.ExceptionUtils;
@@ -338,6 +353,9 @@ public class ConnectivityServiceTest {
private static final String TAG = "ConnectivityServiceTest";
private static final int TIMEOUT_MS = 500;
+ // Broadcasts can take a long time to be delivered. The test will not wait for that long unless
+ // there is a failure, so use a long timeout.
+ private static final int BROADCAST_TIMEOUT_MS = 30_000;
private static final int TEST_LINGER_DELAY_MS = 400;
private static final int TEST_NASCENT_DELAY_MS = 300;
// Chosen to be less than the linger and nascent timeout. This ensures that we can distinguish
@@ -355,6 +373,7 @@ public class ConnectivityServiceTest {
private static final long TIMESTAMP = 1234L;
private static final int NET_ID = 110;
+ private static final int OEM_PREF_ANY_NET_ID = -1;
// Set a non-zero value to verify the flow to set tcp init rwnd value.
private static final int TEST_TCP_INIT_RWND = 60;
@@ -399,6 +418,8 @@ public class ConnectivityServiceTest {
private QosCallbackMockHelper mQosCallbackMockHelper;
private QosCallbackTracker mQosCallbackTracker;
private VpnManagerService mVpnManagerService;
+ private TestNetworkCallback mDefaultNetworkCallback;
+ private TestNetworkCallback mSystemDefaultNetworkCallback;
// State variables required to emulate NetworkPolicyManagerService behaviour.
private int mUidRules = RULE_NONE;
@@ -406,7 +427,7 @@ public class ConnectivityServiceTest {
@Mock DeviceIdleInternal mDeviceIdleInternal;
@Mock INetworkManagementService mNetworkManagementService;
- @Mock INetworkStatsService mStatsService;
+ @Mock NetworkStatsManager mStatsManager;
@Mock IBatteryStats mBatteryStatsService;
@Mock IDnsResolver mMockDnsResolver;
@Mock INetd mMockNetd;
@@ -423,8 +444,8 @@ public class ConnectivityServiceTest {
@Mock MockableSystemProperties mSystemProperties;
@Mock EthernetManager mEthernetManager;
@Mock NetworkPolicyManager mNetworkPolicyManager;
- @Mock KeyStore mKeyStore;
- @Mock IOnSetOemNetworkPreferenceListener mOnSetOemNetworkPreferenceListener;
+ @Mock VpnProfileStore mVpnProfileStore;
+ @Mock SystemConfigManager mSystemConfigManager;
private ArgumentCaptor<ResolverParamsParcel> mResolverParamsParcelCaptor =
ArgumentCaptor.forClass(ResolverParamsParcel.class);
@@ -521,6 +542,8 @@ public class ConnectivityServiceTest {
if (Context.TELEPHONY_SERVICE.equals(name)) return mTelephonyManager;
if (Context.ETHERNET_SERVICE.equals(name)) return mEthernetManager;
if (Context.NETWORK_POLICY_SERVICE.equals(name)) return mNetworkPolicyManager;
+ if (Context.SYSTEM_CONFIG_SERVICE.equals(name)) return mSystemConfigManager;
+ if (Context.NETWORK_STATS_SERVICE.equals(name)) return mStatsManager;
return super.getSystemService(name);
}
@@ -994,10 +1017,12 @@ public class ConnectivityServiceTest {
// Used to collect the networks requests managed by this factory. This is a duplicate of
// the internal information stored in the NetworkFactory (which is private).
private SparseArray<NetworkRequest> mNetworkRequests = new SparseArray<>();
+ private final HandlerThread mHandlerSendingRequests;
public MockNetworkFactory(Looper looper, Context context, String logTag,
- NetworkCapabilities filter) {
+ NetworkCapabilities filter, HandlerThread threadSendingRequests) {
super(looper, context, logTag, filter);
+ mHandlerSendingRequests = threadSendingRequests;
}
public int getMyRequestCount() {
@@ -1051,7 +1076,8 @@ public class ConnectivityServiceTest {
public void terminate() {
super.terminate();
// Make sure there are no remaining requests unaccounted for.
- assertNull(mRequestHistory.poll(TIMEOUT_MS, r -> true));
+ HandlerUtils.waitForIdle(mHandlerSendingRequests, TIMEOUT_MS);
+ assertNull(mRequestHistory.poll(0, r -> true));
}
// Trigger releasing the request as unfulfillable
@@ -1060,9 +1086,11 @@ public class ConnectivityServiceTest {
}
}
- private Set<UidRange> uidRangesForUid(int uid) {
+ private Set<UidRange> uidRangesForUids(int... uids) {
final ArraySet<UidRange> ranges = new ArraySet<>();
- ranges.add(new UidRange(uid, uid));
+ for (final int uid : uids) {
+ ranges.add(new UidRange(uid, uid));
+ }
return ranges;
}
@@ -1103,7 +1131,7 @@ public class ConnectivityServiceTest {
return mDeviceIdleInternal;
}
},
- mNetworkManagementService, mMockNetd, userId, mKeyStore);
+ mNetworkManagementService, mMockNetd, userId, mVpnProfileStore);
}
public void setUids(Set<UidRange> uids) {
@@ -1192,13 +1220,13 @@ public class ConnectivityServiceTest {
public void establishForMyUid(LinkProperties lp) throws Exception {
final int uid = Process.myUid();
- establish(lp, uid, uidRangesForUid(uid), true, true, false);
+ establish(lp, uid, uidRangesForUids(uid), true, true, false);
}
public void establishForMyUid(boolean validated, boolean hasInternet, boolean isStrictMode)
throws Exception {
final int uid = Process.myUid();
- establish(makeLinkProperties(), uid, uidRangesForUid(uid), validated, hasInternet,
+ establish(makeLinkProperties(), uid, uidRangesForUids(uid), validated, hasInternet,
isStrictMode);
}
@@ -1282,8 +1310,9 @@ public class ConnectivityServiceTest {
return mVMSHandlerThread;
}
- public KeyStore getKeyStore() {
- return mKeyStore;
+ @Override
+ public VpnProfileStore getVpnProfileStore() {
+ return mVpnProfileStore;
}
public INetd getNetd() {
@@ -1306,7 +1335,7 @@ public class ConnectivityServiceTest {
}
- private void processBroadcastForVpn(Intent intent) {
+ private void processBroadcast(Intent intent) {
mServiceContext.sendBroadcast(intent);
HandlerUtils.waitForIdle(mVMSHandlerThread, TIMEOUT_MS);
waitForIdle();
@@ -1397,6 +1426,7 @@ public class ConnectivityServiceTest {
private static final int VPN_UID = UserHandle.getUid(PRIMARY_USER, 10043);
private static final UserInfo PRIMARY_USER_INFO = new UserInfo(PRIMARY_USER, "",
UserInfo.FLAG_PRIMARY);
+ private static final UserHandle PRIMARY_USER_HANDLE = new UserHandle(PRIMARY_USER);
private static final int RESTRICTED_USER = 1;
private static final UserInfo RESTRICTED_USER_INFO = new UserInfo(RESTRICTED_USER, "",
@@ -1414,6 +1444,8 @@ public class ConnectivityServiceTest {
MockitoAnnotations.initMocks(this);
when(mUserManager.getAliveUsers()).thenReturn(Arrays.asList(PRIMARY_USER_INFO));
+ when(mUserManager.getUserHandles(anyBoolean())).thenReturn(
+ Arrays.asList(PRIMARY_USER_HANDLE));
when(mUserManager.getUserInfo(PRIMARY_USER)).thenReturn(PRIMARY_USER_INFO);
// canHaveRestrictedProfile does not take a userId. It applies to the userId of the context
// it was started from, i.e., PRIMARY_USER.
@@ -1424,6 +1456,7 @@ public class ConnectivityServiceTest {
applicationInfo.targetSdkVersion = Build.VERSION_CODES.Q;
when(mPackageManager.getApplicationInfoAsUser(anyString(), anyInt(), any()))
.thenReturn(applicationInfo);
+ when(mSystemConfigManager.getSystemPermissionUids(anyString())).thenReturn(new int[0]);
// InstrumentationTestRunner prepares a looper, but AndroidJUnitRunner does not.
// http://b/25897652 .
@@ -1449,8 +1482,6 @@ public class ConnectivityServiceTest {
mDeps = makeDependencies();
returnRealCallingUid();
mService = new ConnectivityService(mServiceContext,
- mNetworkManagementService,
- mStatsService,
mMockDnsResolver,
mock(IpConnectivityLog.class),
mMockNetd,
@@ -1534,6 +1565,7 @@ public class ConnectivityServiceTest {
@After
public void tearDown() throws Exception {
+ unregisterDefaultNetworkCallbacks();
setAlwaysOnNetworks(false);
if (mCellNetworkAgent != null) {
mCellNetworkAgent.disconnect();
@@ -1609,10 +1641,13 @@ public class ConnectivityServiceTest {
}
switch (transport) {
case TRANSPORT_WIFI:
- assertEquals(mCm.getActiveNetwork(), mWiFiNetworkAgent.getNetwork());
+ assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
break;
case TRANSPORT_CELLULAR:
- assertEquals(mCm.getActiveNetwork(), mCellNetworkAgent.getNetwork());
+ assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
+ break;
+ case TRANSPORT_ETHERNET:
+ assertEquals(mEthernetNetworkAgent.getNetwork(), mCm.getActiveNetwork());
break;
default:
break;
@@ -1621,6 +1656,7 @@ public class ConnectivityServiceTest {
assertNotNull(mCm.getNetworkInfo(mCm.getActiveNetwork()));
assertEquals(transportToLegacyType(transport),
mCm.getNetworkInfo(mCm.getActiveNetwork()).getType());
+ assertNotNull(mCm.getActiveNetworkInfoForUid(Process.myUid()));
// Test getNetworkCapabilities(Network)
assertNotNull(mCm.getNetworkCapabilities(mCm.getActiveNetwork()));
assertTrue(mCm.getNetworkCapabilities(mCm.getActiveNetwork()).hasTransport(transport));
@@ -1635,6 +1671,7 @@ public class ConnectivityServiceTest {
assertNull(mCm.getActiveNetworkForUid(Process.myUid()));
// Test getAllNetworks()
assertEmpty(mCm.getAllNetworks());
+ assertEmpty(mCm.getAllNetworkStateSnapshot());
}
/**
@@ -1663,7 +1700,7 @@ public class ConnectivityServiceTest {
}
public Intent expectBroadcast() throws Exception {
- return expectBroadcast(TIMEOUT_MS);
+ return expectBroadcast(BROADCAST_TIMEOUT_MS);
}
public void expectNoBroadcast(int timeoutMs) throws Exception {
@@ -2158,6 +2195,24 @@ public class ConnectivityServiceTest {
}
}
+ static void expectOnLost(TestNetworkAgentWrapper network, TestNetworkCallback ... callbacks) {
+ for (TestNetworkCallback c : callbacks) {
+ c.expectCallback(CallbackEntry.LOST, network);
+ }
+ }
+
+ static void expectAvailableCallbacksUnvalidatedWithSpecifier(TestNetworkAgentWrapper network,
+ NetworkSpecifier specifier, TestNetworkCallback ... callbacks) {
+ for (TestNetworkCallback c : callbacks) {
+ c.expectCallback(CallbackEntry.AVAILABLE, network);
+ c.expectCapabilitiesThat(network, (nc) ->
+ !nc.hasCapability(NET_CAPABILITY_VALIDATED)
+ && Objects.equals(specifier, nc.getNetworkSpecifier()));
+ c.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, network);
+ c.expectCallback(CallbackEntry.BLOCKED_STATUS, network);
+ }
+ }
+
@Test
public void testStateChangeNetworkCallbacks() throws Exception {
final TestNetworkCallback genericNetworkCallback = new TestNetworkCallback();
@@ -2753,7 +2808,8 @@ public class ConnectivityServiceTest {
if (capability == NET_CAPABILITY_CBS || capability == NET_CAPABILITY_DUN ||
capability == NET_CAPABILITY_EIMS || capability == NET_CAPABILITY_FOTA ||
capability == NET_CAPABILITY_IA || capability == NET_CAPABILITY_IMS ||
- capability == NET_CAPABILITY_RCS || capability == NET_CAPABILITY_XCAP) {
+ capability == NET_CAPABILITY_RCS || capability == NET_CAPABILITY_XCAP
+ || capability == NET_CAPABILITY_ENTERPRISE) {
assertFalse(nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED));
} else {
assertTrue(nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED));
@@ -2761,10 +2817,14 @@ public class ConnectivityServiceTest {
NetworkCapabilities filter = new NetworkCapabilities();
filter.addCapability(capability);
+ // Add NOT_VCN_MANAGED capability into filter unconditionally since some request will add
+ // NOT_VCN_MANAGED automatically but not for NetworkCapabilities,
+ // see {@code NetworkCapabilities#deduceNotVcnManagedCapability} for more details.
+ filter.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED);
final HandlerThread handlerThread = new HandlerThread("testNetworkFactoryRequests");
handlerThread.start();
final MockNetworkFactory testFactory = new MockNetworkFactory(handlerThread.getLooper(),
- mServiceContext, "testFactory", filter);
+ mServiceContext, "testFactory", filter, mCsHandlerThread);
testFactory.setScoreFilter(40);
ConditionVariable cv = testFactory.getNetworkStartedCV();
testFactory.register();
@@ -2852,6 +2912,7 @@ public class ConnectivityServiceTest {
tryNetworkFactoryRequests(NET_CAPABILITY_IA);
tryNetworkFactoryRequests(NET_CAPABILITY_RCS);
tryNetworkFactoryRequests(NET_CAPABILITY_XCAP);
+ tryNetworkFactoryRequests(NET_CAPABILITY_ENTERPRISE);
tryNetworkFactoryRequests(NET_CAPABILITY_EIMS);
tryNetworkFactoryRequests(NET_CAPABILITY_NOT_METERED);
tryNetworkFactoryRequests(NET_CAPABILITY_INTERNET);
@@ -2872,7 +2933,7 @@ public class ConnectivityServiceTest {
// does not crash.
for (int i = 0; i < 100; i++) {
final MockNetworkFactory testFactory = new MockNetworkFactory(handlerThread.getLooper(),
- mServiceContext, "testFactory", filter);
+ mServiceContext, "testFactory", filter, mCsHandlerThread);
// Register the factory and don't be surprised when the default request arrives.
testFactory.register();
testFactory.expectRequestAdd();
@@ -3521,11 +3582,9 @@ public class ConnectivityServiceTest {
/**
* Verify request matching behavior with network specifiers.
*
- * Note: this test is somewhat problematic since it involves removing capabilities from
- * agents - i.e. agents rejecting requests which they previously accepted. This is flagged
- * as a WTF bug in
- * {@link ConnectivityService#mixInCapabilities(NetworkAgentInfo, NetworkCapabilities)} but
- * does work.
+ * This test does not check updating the specifier on a live network because the specifier is
+ * immutable and this triggers a WTF in
+ * {@link ConnectivityService#mixInCapabilities(NetworkAgentInfo, NetworkCapabilities)}.
*/
@Test
public void testNetworkSpecifier() throws Exception {
@@ -3610,60 +3669,49 @@ public class ConnectivityServiceTest {
mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
mWiFiNetworkAgent.connect(false);
- cEmpty1.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
- cEmpty2.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
- cEmpty3.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
- cEmpty4.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
+ expectAvailableCallbacksUnvalidatedWithSpecifier(mWiFiNetworkAgent, null /* specifier */,
+ cEmpty1, cEmpty2, cEmpty3, cEmpty4);
assertNoCallbacks(cFoo, cBar);
+ mWiFiNetworkAgent.disconnect();
+ expectOnLost(mWiFiNetworkAgent, cEmpty1, cEmpty2, cEmpty3, cEmpty4);
+
+ mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
mWiFiNetworkAgent.setNetworkSpecifier(nsFoo);
- cFoo.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
- for (TestNetworkCallback c: emptyCallbacks) {
- c.expectCapabilitiesThat(mWiFiNetworkAgent,
- (caps) -> caps.getNetworkSpecifier().equals(nsFoo));
- }
- cFoo.expectCapabilitiesThat(mWiFiNetworkAgent,
- (caps) -> caps.getNetworkSpecifier().equals(nsFoo));
+ mWiFiNetworkAgent.connect(false);
+ expectAvailableCallbacksUnvalidatedWithSpecifier(mWiFiNetworkAgent, nsFoo,
+ cEmpty1, cEmpty2, cEmpty3, cEmpty4, cFoo);
+ cBar.assertNoCallback();
assertEquals(nsFoo,
mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).getNetworkSpecifier());
- cFoo.assertNoCallback();
+ assertNoCallbacks(cEmpty1, cEmpty2, cEmpty3, cEmpty4, cFoo);
+
+ mWiFiNetworkAgent.disconnect();
+ expectOnLost(mWiFiNetworkAgent, cEmpty1, cEmpty2, cEmpty3, cEmpty4, cFoo);
+ mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
mWiFiNetworkAgent.setNetworkSpecifier(nsBar);
- cFoo.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
- cBar.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
- for (TestNetworkCallback c: emptyCallbacks) {
- c.expectCapabilitiesThat(mWiFiNetworkAgent,
- (caps) -> caps.getNetworkSpecifier().equals(nsBar));
- }
- cBar.expectCapabilitiesThat(mWiFiNetworkAgent,
- (caps) -> caps.getNetworkSpecifier().equals(nsBar));
+ mWiFiNetworkAgent.connect(false);
+ expectAvailableCallbacksUnvalidatedWithSpecifier(mWiFiNetworkAgent, nsBar,
+ cEmpty1, cEmpty2, cEmpty3, cEmpty4, cBar);
+ cFoo.assertNoCallback();
assertEquals(nsBar,
mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).getNetworkSpecifier());
- cBar.assertNoCallback();
+ mWiFiNetworkAgent.disconnect();
+ expectOnLost(mWiFiNetworkAgent, cEmpty1, cEmpty2, cEmpty3, cEmpty4, cBar);
+ cFoo.assertNoCallback();
+
+ mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
mWiFiNetworkAgent.setNetworkSpecifier(new ConfidentialMatchAllNetworkSpecifier());
- cFoo.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
- for (TestNetworkCallback c : emptyCallbacks) {
- c.expectCapabilitiesThat(mWiFiNetworkAgent,
- (caps) -> caps.getNetworkSpecifier() == null);
- }
- cFoo.expectCapabilitiesThat(mWiFiNetworkAgent,
- (caps) -> caps.getNetworkSpecifier() == null);
- cBar.expectCapabilitiesThat(mWiFiNetworkAgent,
- (caps) -> caps.getNetworkSpecifier() == null);
+ mWiFiNetworkAgent.connect(false);
+ expectAvailableCallbacksUnvalidatedWithSpecifier(mWiFiNetworkAgent, null /* specifier */,
+ cEmpty1, cEmpty2, cEmpty3, cEmpty4, cFoo, cBar);
assertNull(
mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).getNetworkSpecifier());
- cFoo.assertNoCallback();
- cBar.assertNoCallback();
-
- mWiFiNetworkAgent.setNetworkSpecifier(null);
- cFoo.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
- cBar.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
- for (TestNetworkCallback c: emptyCallbacks) {
- c.expectCallback(CallbackEntry.NETWORK_CAPS_UPDATED, mWiFiNetworkAgent);
- }
- assertNoCallbacks(cEmpty1, cEmpty2, cEmpty3, cEmpty4, cFoo, cBar);
+ mWiFiNetworkAgent.disconnect();
+ expectOnLost(mWiFiNetworkAgent, cEmpty1, cEmpty2, cEmpty3, cEmpty4, cFoo, cBar);
}
/**
@@ -4120,9 +4168,10 @@ public class ConnectivityServiceTest {
handlerThread.start();
NetworkCapabilities filter = new NetworkCapabilities()
.addTransportType(TRANSPORT_CELLULAR)
+ .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED)
.addCapability(NET_CAPABILITY_INTERNET);
final MockNetworkFactory testFactory = new MockNetworkFactory(handlerThread.getLooper(),
- mServiceContext, "testFactory", filter);
+ mServiceContext, "testFactory", filter, mCsHandlerThread);
testFactory.setScoreFilter(40);
// Register the factory and expect it to start looking for a network.
@@ -4170,6 +4219,7 @@ public class ConnectivityServiceTest {
// ... and cell data to be torn down after nascent network timeout.
cellNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent,
mService.mNascentDelayMs + TEST_CALLBACK_TIMEOUT_MS);
+ waitForIdle();
assertLength(1, mCm.getAllNetworks());
} finally {
testFactory.terminate();
@@ -4469,7 +4519,7 @@ public class ConnectivityServiceTest {
.addTransportType(TRANSPORT_WIFI)
.addCapability(NET_CAPABILITY_INTERNET);
final MockNetworkFactory testFactory = new MockNetworkFactory(handlerThread.getLooper(),
- mServiceContext, "testFactory", filter);
+ mServiceContext, "testFactory", filter, mCsHandlerThread);
testFactory.setScoreFilter(40);
// Register the factory and expect it to receive the default request.
@@ -5448,18 +5498,19 @@ public class ConnectivityServiceTest {
assertEquals(expectedSet, actualSet);
}
- private void expectForceUpdateIfaces(Network[] networks, String defaultIface,
+ private void expectNetworkStatus(Network[] networks, String defaultIface,
Integer vpnUid, String vpnIfname, String[] underlyingIfaces) throws Exception {
- ArgumentCaptor<Network[]> networksCaptor = ArgumentCaptor.forClass(Network[].class);
- ArgumentCaptor<UnderlyingNetworkInfo[]> vpnInfosCaptor = ArgumentCaptor.forClass(
- UnderlyingNetworkInfo[].class);
+ ArgumentCaptor<List<Network>> networksCaptor = ArgumentCaptor.forClass(List.class);
+ ArgumentCaptor<List<UnderlyingNetworkInfo>> vpnInfosCaptor =
+ ArgumentCaptor.forClass(List.class);
- verify(mStatsService, atLeastOnce()).forceUpdateIfaces(networksCaptor.capture(),
- any(NetworkState[].class), eq(defaultIface), vpnInfosCaptor.capture());
+ verify(mStatsManager, atLeastOnce()).notifyNetworkStatus(networksCaptor.capture(),
+ any(List.class), eq(defaultIface), vpnInfosCaptor.capture());
- assertSameElementsNoDuplicates(networksCaptor.getValue(), networks);
+ assertSameElementsNoDuplicates(networksCaptor.getValue().toArray(), networks);
- UnderlyingNetworkInfo[] infos = vpnInfosCaptor.getValue();
+ UnderlyingNetworkInfo[] infos =
+ vpnInfosCaptor.getValue().toArray(new UnderlyingNetworkInfo[0]);
if (vpnUid != null) {
assertEquals("Should have exactly one VPN:", 1, infos.length);
UnderlyingNetworkInfo info = infos[0];
@@ -5473,8 +5524,9 @@ public class ConnectivityServiceTest {
}
}
- private void expectForceUpdateIfaces(Network[] networks, String defaultIface) throws Exception {
- expectForceUpdateIfaces(networks, defaultIface, null, null, new String[0]);
+ private void expectNetworkStatus(
+ Network[] networks, String defaultIface) throws Exception {
+ expectNetworkStatus(networks, defaultIface, null, null, new String[0]);
}
@Test
@@ -5494,47 +5546,46 @@ public class ConnectivityServiceTest {
mCellNetworkAgent.connect(false);
mCellNetworkAgent.sendLinkProperties(cellLp);
waitForIdle();
- expectForceUpdateIfaces(onlyCell, MOBILE_IFNAME);
- reset(mStatsService);
+ expectNetworkStatus(onlyCell, MOBILE_IFNAME);
+ reset(mStatsManager);
// Default network switch should update ifaces.
mWiFiNetworkAgent.connect(false);
mWiFiNetworkAgent.sendLinkProperties(wifiLp);
waitForIdle();
assertEquals(wifiLp, mService.getActiveLinkProperties());
- expectForceUpdateIfaces(onlyWifi, WIFI_IFNAME);
- reset(mStatsService);
+ expectNetworkStatus(onlyWifi, WIFI_IFNAME);
+ reset(mStatsManager);
// Disconnect should update ifaces.
mWiFiNetworkAgent.disconnect();
waitForIdle();
- expectForceUpdateIfaces(onlyCell, MOBILE_IFNAME);
- reset(mStatsService);
+ expectNetworkStatus(onlyCell, MOBILE_IFNAME);
+ reset(mStatsManager);
// Metered change should update ifaces
mCellNetworkAgent.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
waitForIdle();
- expectForceUpdateIfaces(onlyCell, MOBILE_IFNAME);
- reset(mStatsService);
+ expectNetworkStatus(onlyCell, MOBILE_IFNAME);
+ reset(mStatsManager);
mCellNetworkAgent.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
waitForIdle();
- expectForceUpdateIfaces(onlyCell, MOBILE_IFNAME);
- reset(mStatsService);
+ expectNetworkStatus(onlyCell, MOBILE_IFNAME);
+ reset(mStatsManager);
// Temp metered change shouldn't update ifaces
- mCellNetworkAgent.addCapability(NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED);
+ mCellNetworkAgent.addCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED);
waitForIdle();
- verify(mStatsService, never())
- .forceUpdateIfaces(eq(onlyCell), any(NetworkState[].class), eq(MOBILE_IFNAME),
- eq(new UnderlyingNetworkInfo[0]));
- reset(mStatsService);
+ verify(mStatsManager, never()).notifyNetworkStatus(eq(Arrays.asList(onlyCell)),
+ any(List.class), eq(MOBILE_IFNAME), any(List.class));
+ reset(mStatsManager);
// Roaming change should update ifaces
mCellNetworkAgent.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING);
waitForIdle();
- expectForceUpdateIfaces(onlyCell, MOBILE_IFNAME);
- reset(mStatsService);
+ expectNetworkStatus(onlyCell, MOBILE_IFNAME);
+ reset(mStatsManager);
// Test VPNs.
final LinkProperties lp = new LinkProperties();
@@ -5547,7 +5598,7 @@ public class ConnectivityServiceTest {
mCellNetworkAgent.getNetwork(), mMockVpn.getNetwork()};
// A VPN with default (null) underlying networks sets the underlying network's interfaces...
- expectForceUpdateIfaces(cellAndVpn, MOBILE_IFNAME, Process.myUid(), VPN_IFNAME,
+ expectNetworkStatus(cellAndVpn, MOBILE_IFNAME, Process.myUid(), VPN_IFNAME,
new String[]{MOBILE_IFNAME});
// ...and updates them as the default network switches.
@@ -5564,9 +5615,9 @@ public class ConnectivityServiceTest {
waitForIdle();
assertEquals(wifiLp, mService.getActiveLinkProperties());
- expectForceUpdateIfaces(wifiAndVpn, WIFI_IFNAME, Process.myUid(), VPN_IFNAME,
+ expectNetworkStatus(wifiAndVpn, WIFI_IFNAME, Process.myUid(), VPN_IFNAME,
new String[]{WIFI_IFNAME});
- reset(mStatsService);
+ reset(mStatsManager);
// A VPN that sets its underlying networks passes the underlying interfaces, and influences
// the default interface sent to NetworkStatsService by virtue of applying to the system
@@ -5576,22 +5627,22 @@ public class ConnectivityServiceTest {
// applies to the system server UID should not have any bearing on network stats.
mMockVpn.setUnderlyingNetworks(onlyCell);
waitForIdle();
- expectForceUpdateIfaces(wifiAndVpn, MOBILE_IFNAME, Process.myUid(), VPN_IFNAME,
+ expectNetworkStatus(wifiAndVpn, MOBILE_IFNAME, Process.myUid(), VPN_IFNAME,
new String[]{MOBILE_IFNAME});
- reset(mStatsService);
+ reset(mStatsManager);
mMockVpn.setUnderlyingNetworks(cellAndWifi);
waitForIdle();
- expectForceUpdateIfaces(wifiAndVpn, MOBILE_IFNAME, Process.myUid(), VPN_IFNAME,
+ expectNetworkStatus(wifiAndVpn, MOBILE_IFNAME, Process.myUid(), VPN_IFNAME,
new String[]{MOBILE_IFNAME, WIFI_IFNAME});
- reset(mStatsService);
+ reset(mStatsManager);
// Null underlying networks are ignored.
mMockVpn.setUnderlyingNetworks(cellNullAndWifi);
waitForIdle();
- expectForceUpdateIfaces(wifiAndVpn, MOBILE_IFNAME, Process.myUid(), VPN_IFNAME,
+ expectNetworkStatus(wifiAndVpn, MOBILE_IFNAME, Process.myUid(), VPN_IFNAME,
new String[]{MOBILE_IFNAME, WIFI_IFNAME});
- reset(mStatsService);
+ reset(mStatsManager);
// If an underlying network disconnects, that interface should no longer be underlying.
// This doesn't actually work because disconnectAndDestroyNetwork only notifies
@@ -5603,17 +5654,17 @@ public class ConnectivityServiceTest {
mCellNetworkAgent.disconnect();
waitForIdle();
assertNull(mService.getLinkProperties(mCellNetworkAgent.getNetwork()));
- expectForceUpdateIfaces(wifiAndVpn, MOBILE_IFNAME, Process.myUid(), VPN_IFNAME,
+ expectNetworkStatus(wifiAndVpn, MOBILE_IFNAME, Process.myUid(), VPN_IFNAME,
new String[]{MOBILE_IFNAME, WIFI_IFNAME});
// Confirm that we never tell NetworkStatsService that cell is no longer the underlying
// network for the VPN...
- verify(mStatsService, never()).forceUpdateIfaces(any(Network[].class),
- any(NetworkState[].class), any() /* anyString() doesn't match null */,
- argThat(infos -> infos[0].underlyingIfaces.size() == 1
- && WIFI_IFNAME.equals(infos[0].underlyingIfaces.get(0))));
- verifyNoMoreInteractions(mStatsService);
- reset(mStatsService);
+ verify(mStatsManager, never()).notifyNetworkStatus(any(List.class),
+ any(List.class), any() /* anyString() doesn't match null */,
+ argThat(infos -> infos.get(0).underlyingIfaces.size() == 1
+ && WIFI_IFNAME.equals(infos.get(0).underlyingIfaces.get(0))));
+ verifyNoMoreInteractions(mStatsManager);
+ reset(mStatsManager);
// ... but if something else happens that causes notifyIfacesChangedForNetworkStats to be
// called again, it does. For example, connect Ethernet, but with a low score, such that it
@@ -5622,13 +5673,13 @@ public class ConnectivityServiceTest {
mEthernetNetworkAgent.adjustScore(-40);
mEthernetNetworkAgent.connect(false);
waitForIdle();
- verify(mStatsService).forceUpdateIfaces(any(Network[].class),
- any(NetworkState[].class), any() /* anyString() doesn't match null */,
- argThat(vpnInfos -> vpnInfos[0].underlyingIfaces.size() == 1
- && WIFI_IFNAME.equals(vpnInfos[0].underlyingIfaces.get(0))));
+ verify(mStatsManager).notifyNetworkStatus(any(List.class),
+ any(List.class), any() /* anyString() doesn't match null */,
+ argThat(vpnInfos -> vpnInfos.get(0).underlyingIfaces.size() == 1
+ && WIFI_IFNAME.equals(vpnInfos.get(0).underlyingIfaces.get(0))));
mEthernetNetworkAgent.disconnect();
waitForIdle();
- reset(mStatsService);
+ reset(mStatsManager);
// When a VPN declares no underlying networks (i.e., no connectivity), getAllVpnInfo
// does not return the VPN, so CS does not pass it to NetworkStatsService. This causes
@@ -5638,27 +5689,27 @@ public class ConnectivityServiceTest {
// Also, for the same reason as above, the active interface passed in is null.
mMockVpn.setUnderlyingNetworks(new Network[0]);
waitForIdle();
- expectForceUpdateIfaces(wifiAndVpn, null);
- reset(mStatsService);
+ expectNetworkStatus(wifiAndVpn, null);
+ reset(mStatsManager);
// Specifying only a null underlying network is the same as no networks.
mMockVpn.setUnderlyingNetworks(onlyNull);
waitForIdle();
- expectForceUpdateIfaces(wifiAndVpn, null);
- reset(mStatsService);
+ expectNetworkStatus(wifiAndVpn, null);
+ reset(mStatsManager);
// Specifying networks that are all disconnected is the same as specifying no networks.
mMockVpn.setUnderlyingNetworks(onlyCell);
waitForIdle();
- expectForceUpdateIfaces(wifiAndVpn, null);
- reset(mStatsService);
+ expectNetworkStatus(wifiAndVpn, null);
+ reset(mStatsManager);
// Passing in null again means follow the default network again.
mMockVpn.setUnderlyingNetworks(null);
waitForIdle();
- expectForceUpdateIfaces(wifiAndVpn, WIFI_IFNAME, Process.myUid(), VPN_IFNAME,
+ expectNetworkStatus(wifiAndVpn, WIFI_IFNAME, Process.myUid(), VPN_IFNAME,
new String[]{WIFI_IFNAME});
- reset(mStatsService);
+ reset(mStatsManager);
}
@Test
@@ -5891,6 +5942,16 @@ public class ConnectivityServiceTest {
assertEquals("strict.example.com", cbi.getLp().getPrivateDnsServerName());
}
+ private PrivateDnsValidationEventParcel makePrivateDnsValidationEvent(
+ final int netId, final String ipAddress, final String hostname, final int validation) {
+ final PrivateDnsValidationEventParcel event = new PrivateDnsValidationEventParcel();
+ event.netId = netId;
+ event.ipAddress = ipAddress;
+ event.hostname = hostname;
+ event.validation = validation;
+ return event;
+ }
+
@Test
public void testLinkPropertiesWithPrivateDnsValidationEvents() throws Exception {
// The default on Android is opportunistic mode ("Automatic").
@@ -5921,8 +5982,9 @@ public class ConnectivityServiceTest {
// Send a validation event for a server that is not part of the current
// resolver config. The validation event should be ignored.
- mService.mNetdEventCallback.onPrivateDnsValidationEvent(
- mCellNetworkAgent.getNetwork().netId, "", "145.100.185.18", true);
+ mService.mResolverUnsolEventCallback.onPrivateDnsValidationEvent(
+ makePrivateDnsValidationEvent(mCellNetworkAgent.getNetwork().netId, "",
+ "145.100.185.18", VALIDATION_RESULT_SUCCESS));
cellNetworkCallback.assertNoCallback();
// Add a dns server to the LinkProperties.
@@ -5939,20 +6001,23 @@ public class ConnectivityServiceTest {
// Send a validation event containing a hostname that is not part of
// the current resolver config. The validation event should be ignored.
- mService.mNetdEventCallback.onPrivateDnsValidationEvent(
- mCellNetworkAgent.getNetwork().netId, "145.100.185.16", "hostname", true);
+ mService.mResolverUnsolEventCallback.onPrivateDnsValidationEvent(
+ makePrivateDnsValidationEvent(mCellNetworkAgent.getNetwork().netId,
+ "145.100.185.16", "hostname", VALIDATION_RESULT_SUCCESS));
cellNetworkCallback.assertNoCallback();
// Send a validation event where validation failed.
- mService.mNetdEventCallback.onPrivateDnsValidationEvent(
- mCellNetworkAgent.getNetwork().netId, "145.100.185.16", "", false);
+ mService.mResolverUnsolEventCallback.onPrivateDnsValidationEvent(
+ makePrivateDnsValidationEvent(mCellNetworkAgent.getNetwork().netId,
+ "145.100.185.16", "", VALIDATION_RESULT_FAILURE));
cellNetworkCallback.assertNoCallback();
// Send a validation event where validation succeeded for a server in
// the current resolver config. A LinkProperties callback with updated
// private dns fields should be sent.
- mService.mNetdEventCallback.onPrivateDnsValidationEvent(
- mCellNetworkAgent.getNetwork().netId, "145.100.185.16", "", true);
+ mService.mResolverUnsolEventCallback.onPrivateDnsValidationEvent(
+ makePrivateDnsValidationEvent(mCellNetworkAgent.getNetwork().netId,
+ "145.100.185.16", "", VALIDATION_RESULT_SUCCESS));
cbi = cellNetworkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED,
mCellNetworkAgent);
cellNetworkCallback.assertNoCallback();
@@ -6023,6 +6088,7 @@ public class ConnectivityServiceTest {
.addTransportType(TRANSPORT_CELLULAR)
.addCapability(NET_CAPABILITY_INTERNET)
.addCapability(NET_CAPABILITY_NOT_CONGESTED)
+ .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED)
.setLinkDownstreamBandwidthKbps(10);
final NetworkCapabilities wifiNc = new NetworkCapabilities()
.addTransportType(TRANSPORT_WIFI)
@@ -6031,6 +6097,7 @@ public class ConnectivityServiceTest {
.addCapability(NET_CAPABILITY_NOT_ROAMING)
.addCapability(NET_CAPABILITY_NOT_CONGESTED)
.addCapability(NET_CAPABILITY_NOT_SUSPENDED)
+ .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED)
.setLinkUpstreamBandwidthKbps(20);
mCellNetworkAgent.setNetworkCapabilities(cellNc, true /* sendToConnectivityService */);
mWiFiNetworkAgent.setNetworkCapabilities(wifiNc, true /* sendToConnectivityService */);
@@ -6329,7 +6396,7 @@ public class ConnectivityServiceTest {
vpnNetworkCallback.assertNoCallback();
assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
- final Set<UidRange> ranges = uidRangesForUid(uid);
+ final Set<UidRange> ranges = uidRangesForUids(uid);
mMockVpn.registerAgent(ranges);
mMockVpn.setUnderlyingNetworks(new Network[0]);
@@ -6801,7 +6868,7 @@ public class ConnectivityServiceTest {
final int uid = Process.myUid();
NetworkCapabilities nc = mCm.getNetworkCapabilities(mMockVpn.getNetwork());
assertNotNull("nc=" + nc, nc.getUids());
- assertEquals(nc.getUids(), uidRangesForUid(uid));
+ assertEquals(nc.getUids(), uidRangesForUids(uid));
assertVpnTransportInfo(nc, VpnManager.TYPE_VPN_SERVICE);
// Set an underlying network and expect to see the VPN transports change.
@@ -6818,17 +6885,18 @@ public class ConnectivityServiceTest {
.thenReturn(UserHandle.getUid(RESTRICTED_USER, VPN_UID));
final Intent addedIntent = new Intent(ACTION_USER_ADDED);
+ addedIntent.putExtra(Intent.EXTRA_USER, UserHandle.of(RESTRICTED_USER));
addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, RESTRICTED_USER);
// Send a USER_ADDED broadcast for it.
- processBroadcastForVpn(addedIntent);
+ processBroadcast(addedIntent);
// Expect that the VPN UID ranges contain both |uid| and the UID range for the newly-added
// restricted user.
callback.expectCapabilitiesThat(mMockVpn, (caps)
-> caps.getUids().size() == 2
&& caps.getUids().contains(new UidRange(uid, uid))
- && caps.getUids().contains(UidRange.createForUser(RESTRICTED_USER))
+ && caps.getUids().contains(createUidRange(RESTRICTED_USER))
&& caps.hasTransport(TRANSPORT_VPN)
&& caps.hasTransport(TRANSPORT_WIFI));
@@ -6838,14 +6906,15 @@ public class ConnectivityServiceTest {
callback.expectCapabilitiesThat(mMockVpn, (caps)
-> caps.getUids().size() == 2
&& caps.getUids().contains(new UidRange(uid, uid))
- && caps.getUids().contains(UidRange.createForUser(RESTRICTED_USER))
+ && caps.getUids().contains(createUidRange(RESTRICTED_USER))
&& caps.hasTransport(TRANSPORT_VPN)
&& !caps.hasTransport(TRANSPORT_WIFI));
// Send a USER_REMOVED broadcast and expect to lose the UID range for the restricted user.
final Intent removedIntent = new Intent(ACTION_USER_REMOVED);
+ removedIntent.putExtra(Intent.EXTRA_USER, UserHandle.of(RESTRICTED_USER));
removedIntent.putExtra(Intent.EXTRA_USER_HANDLE, RESTRICTED_USER);
- processBroadcastForVpn(removedIntent);
+ processBroadcast(removedIntent);
// Expect that the VPN gains the UID range for the restricted user, and that the capability
// change made just before that (i.e., loss of TRANSPORT_WIFI) is preserved.
@@ -6901,8 +6970,9 @@ public class ConnectivityServiceTest {
RESTRICTED_USER_INFO));
// TODO: check that VPN app within restricted profile still has access, etc.
final Intent addedIntent = new Intent(ACTION_USER_ADDED);
+ addedIntent.putExtra(Intent.EXTRA_USER, UserHandle.of(RESTRICTED_USER));
addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, RESTRICTED_USER);
- processBroadcastForVpn(addedIntent);
+ processBroadcast(addedIntent);
assertNull(mCm.getActiveNetworkForUid(uid));
assertNull(mCm.getActiveNetworkForUid(restrictedUid));
@@ -6911,8 +6981,9 @@ public class ConnectivityServiceTest {
// Send a USER_REMOVED broadcast and expect to lose the UID range for the restricted user.
final Intent removedIntent = new Intent(ACTION_USER_REMOVED);
+ removedIntent.putExtra(Intent.EXTRA_USER, UserHandle.of(RESTRICTED_USER));
removedIntent.putExtra(Intent.EXTRA_USER_HANDLE, RESTRICTED_USER);
- processBroadcastForVpn(removedIntent);
+ processBroadcast(removedIntent);
assertNull(mCm.getActiveNetworkForUid(uid));
assertNotNull(mCm.getActiveNetworkForUid(restrictedUid));
@@ -7067,7 +7138,7 @@ public class ConnectivityServiceTest {
assertFalse(mCm.isActiveNetworkMetered());
// Connect VPN network.
- mMockVpn.registerAgent(true /* isAlwaysMetered */, uidRangesForUid(Process.myUid()),
+ mMockVpn.registerAgent(true /* isAlwaysMetered */, uidRangesForUids(Process.myUid()),
new LinkProperties());
mMockVpn.connect(true);
waitForIdle();
@@ -7452,8 +7523,7 @@ public class ConnectivityServiceTest {
private void setupLegacyLockdownVpn() {
final String profileName = "testVpnProfile";
final byte[] profileTag = profileName.getBytes(StandardCharsets.UTF_8);
- when(mKeyStore.contains(Credentials.LOCKDOWN_VPN)).thenReturn(true);
- when(mKeyStore.get(Credentials.LOCKDOWN_VPN)).thenReturn(profileTag);
+ when(mVpnProfileStore.get(Credentials.LOCKDOWN_VPN)).thenReturn(profileTag);
final VpnProfile profile = new VpnProfile(profileName);
profile.name = "My VPN";
@@ -7461,7 +7531,7 @@ public class ConnectivityServiceTest {
profile.dnsServers = "8.8.8.8";
profile.type = VpnProfile.TYPE_IPSEC_XAUTH_PSK;
final byte[] encodedProfile = profile.encode();
- when(mKeyStore.get(Credentials.VPN + profileName)).thenReturn(encodedProfile);
+ when(mVpnProfileStore.get(Credentials.VPN + profileName)).thenReturn(encodedProfile);
}
private void establishLegacyLockdownVpn(Network underlying) throws Exception {
@@ -7469,7 +7539,7 @@ public class ConnectivityServiceTest {
assertNotNull(underlying);
mMockVpn.setVpnType(VpnManager.TYPE_VPN_LEGACY);
// The legacy lockdown VPN only supports userId 0.
- final Set<UidRange> ranges = Collections.singleton(UidRange.createForUser(PRIMARY_USER));
+ final Set<UidRange> ranges = Collections.singleton(createUidRange(PRIMARY_USER));
mMockVpn.registerAgent(ranges);
mMockVpn.setUnderlyingNetworks(new Network[]{underlying});
mMockVpn.connect(true);
@@ -7505,8 +7575,9 @@ public class ConnectivityServiceTest {
// Send a USER_UNLOCKED broadcast so CS starts LockdownVpnTracker.
final int userId = UserHandle.getUserId(Process.myUid());
final Intent addedIntent = new Intent(ACTION_USER_UNLOCKED);
+ addedIntent.putExtra(Intent.EXTRA_USER, UserHandle.of(userId));
addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
- processBroadcastForVpn(addedIntent);
+ processBroadcast(addedIntent);
// Lockdown VPN disables teardown and enables lockdown.
assertFalse(mMockVpn.getEnableTeardown());
@@ -7718,19 +7789,13 @@ public class ConnectivityServiceTest {
mWiFiNetworkAgent.removeCapability(testCap);
callbackWithCap.expectAvailableCallbacksValidated(mCellNetworkAgent);
callbackWithoutCap.expectCapabilitiesWithout(testCap, mWiFiNetworkAgent);
- // TODO: Test default network changes for NOT_VCN_MANAGED once the default request has
- // it.
- if (testCap == NET_CAPABILITY_TRUSTED) {
- verify(mMockNetd).networkSetDefault(eq(mCellNetworkAgent.getNetwork().netId));
- reset(mMockNetd);
- }
+ verify(mMockNetd).networkSetDefault(eq(mCellNetworkAgent.getNetwork().netId));
+ reset(mMockNetd);
mCellNetworkAgent.removeCapability(testCap);
callbackWithCap.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
callbackWithoutCap.assertNoCallback();
- if (testCap == NET_CAPABILITY_TRUSTED) {
- verify(mMockNetd).networkClearDefault();
- }
+ verify(mMockNetd).networkClearDefault();
mCm.unregisterNetworkCallback(callbackWithCap);
mCm.unregisterNetworkCallback(callbackWithoutCap);
@@ -7744,7 +7809,8 @@ public class ConnectivityServiceTest {
mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp);
mCellNetworkAgent.connect(true);
waitForIdle();
- verify(mBatteryStatsService).noteNetworkInterfaceForTransports(cellLp.getInterfaceName(),
+ verify(mDeps).reportNetworkInterfaceForTransports(mServiceContext,
+ cellLp.getInterfaceName(),
new int[] { TRANSPORT_CELLULAR });
reset(mBatteryStatsService);
@@ -7753,7 +7819,8 @@ public class ConnectivityServiceTest {
mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, wifiLp);
mWiFiNetworkAgent.connect(true);
waitForIdle();
- verify(mBatteryStatsService).noteNetworkInterfaceForTransports(wifiLp.getInterfaceName(),
+ verify(mDeps).reportNetworkInterfaceForTransports(mServiceContext,
+ wifiLp.getInterfaceName(),
new int[] { TRANSPORT_WIFI });
reset(mBatteryStatsService);
@@ -7764,7 +7831,8 @@ public class ConnectivityServiceTest {
mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp);
mCellNetworkAgent.connect(true);
waitForIdle();
- verify(mBatteryStatsService).noteNetworkInterfaceForTransports(cellLp.getInterfaceName(),
+ verify(mDeps).reportNetworkInterfaceForTransports(mServiceContext,
+ cellLp.getInterfaceName(),
new int[] { TRANSPORT_CELLULAR });
mCellNetworkAgent.disconnect();
}
@@ -7795,6 +7863,16 @@ public class ConnectivityServiceTest {
return stacked;
}
+ private Nat64PrefixEventParcel makeNat64PrefixEvent(final int netId, final int prefixOperation,
+ final String prefixAddress, final int prefixLength) {
+ final Nat64PrefixEventParcel event = new Nat64PrefixEventParcel();
+ event.netId = netId;
+ event.prefixOperation = prefixOperation;
+ event.prefixAddress = prefixAddress;
+ event.prefixLength = prefixLength;
+ return event;
+ }
+
@Test
public void testStackedLinkProperties() throws Exception {
final LinkAddress myIpv4 = new LinkAddress("1.2.3.4/24");
@@ -7825,7 +7903,6 @@ public class ConnectivityServiceTest {
cellLp.addRoute(defaultRoute);
cellLp.addRoute(ipv6Subnet);
mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp);
- reset(mNetworkManagementService);
reset(mMockDnsResolver);
reset(mMockNetd);
reset(mBatteryStatsService);
@@ -7839,7 +7916,8 @@ public class ConnectivityServiceTest {
assertRoutesAdded(cellNetId, ipv6Subnet, defaultRoute);
verify(mMockDnsResolver, times(1)).createNetworkCache(eq(cellNetId));
verify(mMockNetd, times(1)).networkAddInterface(cellNetId, MOBILE_IFNAME);
- verify(mBatteryStatsService).noteNetworkInterfaceForTransports(cellLp.getInterfaceName(),
+ verify(mDeps).reportNetworkInterfaceForTransports(mServiceContext,
+ cellLp.getInterfaceName(),
new int[] { TRANSPORT_CELLULAR });
networkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent);
@@ -7860,12 +7938,11 @@ public class ConnectivityServiceTest {
// Make sure BatteryStats was not told about any v4- interfaces, as none should have
// come online yet.
waitForIdle();
- verify(mBatteryStatsService, never()).noteNetworkInterfaceForTransports(startsWith("v4-"),
- any());
+ verify(mDeps, never())
+ .reportNetworkInterfaceForTransports(eq(mServiceContext), startsWith("v4-"), any());
verifyNoMoreInteractions(mMockNetd);
verifyNoMoreInteractions(mMockDnsResolver);
- reset(mNetworkManagementService);
reset(mMockNetd);
reset(mMockDnsResolver);
when(mMockNetd.interfaceGetCfg(CLAT_PREFIX + MOBILE_IFNAME))
@@ -7881,8 +7958,8 @@ public class ConnectivityServiceTest {
// When NAT64 prefix discovery succeeds, LinkProperties are updated and clatd is started.
Nat464Xlat clat = getNat464Xlat(mCellNetworkAgent);
assertNull(mCm.getLinkProperties(mCellNetworkAgent.getNetwork()).getNat64Prefix());
- mService.mNetdEventCallback.onNat64PrefixEvent(cellNetId, true /* added */,
- kNat64PrefixString, 96);
+ mService.mResolverUnsolEventCallback.onNat64PrefixEvent(
+ makeNat64PrefixEvent(cellNetId, PREFIX_OPERATION_ADDED, kNat64PrefixString, 96));
LinkProperties lpBeforeClat = networkCallback.expectCallback(
CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent).getLp();
assertEquals(0, lpBeforeClat.getStackedLinks().size());
@@ -7914,16 +7991,17 @@ public class ConnectivityServiceTest {
assertTrue(ArrayUtils.contains(resolvrParams.servers, "8.8.8.8"));
for (final LinkProperties stackedLp : stackedLpsAfterChange) {
- verify(mBatteryStatsService).noteNetworkInterfaceForTransports(
- stackedLp.getInterfaceName(), new int[] { TRANSPORT_CELLULAR });
+ verify(mDeps).reportNetworkInterfaceForTransports(
+ mServiceContext, stackedLp.getInterfaceName(),
+ new int[] { TRANSPORT_CELLULAR });
}
reset(mMockNetd);
when(mMockNetd.interfaceGetCfg(CLAT_PREFIX + MOBILE_IFNAME))
.thenReturn(getClatInterfaceConfigParcel(myIpv4));
// Change the NAT64 prefix without first removing it.
// Expect clatd to be stopped and started with the new prefix.
- mService.mNetdEventCallback.onNat64PrefixEvent(cellNetId, true /* added */,
- kOtherNat64PrefixString, 96);
+ mService.mResolverUnsolEventCallback.onNat64PrefixEvent(makeNat64PrefixEvent(
+ cellNetId, PREFIX_OPERATION_ADDED, kOtherNat64PrefixString, 96));
networkCallback.expectLinkPropertiesThat(mCellNetworkAgent,
(lp) -> lp.getStackedLinks().size() == 0);
verify(mMockNetd, times(1)).clatdStop(MOBILE_IFNAME);
@@ -7965,15 +8043,14 @@ public class ConnectivityServiceTest {
verify(mMockNetd, times(1)).networkRemoveInterface(cellNetId, CLAT_PREFIX + MOBILE_IFNAME);
verifyNoMoreInteractions(mMockNetd);
verifyNoMoreInteractions(mMockDnsResolver);
- reset(mNetworkManagementService);
reset(mMockNetd);
reset(mMockDnsResolver);
when(mMockNetd.interfaceGetCfg(CLAT_PREFIX + MOBILE_IFNAME))
.thenReturn(getClatInterfaceConfigParcel(myIpv4));
// Stopping prefix discovery causes netd to tell us that the NAT64 prefix is gone.
- mService.mNetdEventCallback.onNat64PrefixEvent(cellNetId, false /* added */,
- kOtherNat64PrefixString, 96);
+ mService.mResolverUnsolEventCallback.onNat64PrefixEvent(makeNat64PrefixEvent(
+ cellNetId, PREFIX_OPERATION_REMOVED, kOtherNat64PrefixString, 96));
networkCallback.expectLinkPropertiesThat(mCellNetworkAgent,
(lp) -> lp.getNat64Prefix() == null);
@@ -7985,8 +8062,8 @@ public class ConnectivityServiceTest {
networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent);
assertRoutesRemoved(cellNetId, ipv4Subnet); // Directly-connected routes auto-added.
verify(mMockDnsResolver, times(1)).startPrefix64Discovery(cellNetId);
- mService.mNetdEventCallback.onNat64PrefixEvent(cellNetId, true /* added */,
- kNat64PrefixString, 96);
+ mService.mResolverUnsolEventCallback.onNat64PrefixEvent(makeNat64PrefixEvent(
+ cellNetId, PREFIX_OPERATION_ADDED, kNat64PrefixString, 96));
networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent);
verify(mMockNetd, times(1)).clatdStart(MOBILE_IFNAME, kNat64Prefix.toString());
@@ -7998,8 +8075,8 @@ public class ConnectivityServiceTest {
verify(mMockNetd, times(1)).networkAddInterface(cellNetId, CLAT_PREFIX + MOBILE_IFNAME);
// NAT64 prefix is removed. Expect that clat is stopped.
- mService.mNetdEventCallback.onNat64PrefixEvent(cellNetId, false /* added */,
- kNat64PrefixString, 96);
+ mService.mResolverUnsolEventCallback.onNat64PrefixEvent(makeNat64PrefixEvent(
+ cellNetId, PREFIX_OPERATION_REMOVED, kNat64PrefixString, 96));
networkCallback.expectLinkPropertiesThat(mCellNetworkAgent,
(lp) -> lp.getStackedLinks().size() == 0 && lp.getNat64Prefix() == null);
assertRoutesRemoved(cellNetId, ipv4Subnet, stackedDefault);
@@ -8087,8 +8164,8 @@ public class ConnectivityServiceTest {
inOrder.verify(mMockDnsResolver).setPrefix64(netId, "");
inOrder.verify(mMockDnsResolver).startPrefix64Discovery(netId);
- mService.mNetdEventCallback.onNat64PrefixEvent(netId, true /* added */,
- pref64FromDnsStr, 96);
+ mService.mResolverUnsolEventCallback.onNat64PrefixEvent(
+ makeNat64PrefixEvent(netId, PREFIX_OPERATION_ADDED, pref64FromDnsStr, 96));
expectNat64PrefixChange(callback, mWiFiNetworkAgent, pref64FromDns);
inOrder.verify(mMockNetd).clatdStart(iface, pref64FromDns.toString());
@@ -8121,8 +8198,8 @@ public class ConnectivityServiceTest {
inOrder.verify(mMockDnsResolver).stopPrefix64Discovery(netId);
// Stopping prefix discovery results in a prefix removed notification.
- mService.mNetdEventCallback.onNat64PrefixEvent(netId, false /* added */,
- pref64FromDnsStr, 96);
+ mService.mResolverUnsolEventCallback.onNat64PrefixEvent(
+ makeNat64PrefixEvent(netId, PREFIX_OPERATION_REMOVED, pref64FromDnsStr, 96));
inOrder.verify(mMockNetd).clatdStart(iface, pref64FromRa.toString());
inOrder.verify(mMockDnsResolver).setPrefix64(netId, pref64FromRa.toString());
@@ -8160,8 +8237,8 @@ public class ConnectivityServiceTest {
inOrder.verify(mMockNetd).clatdStop(iface);
inOrder.verify(mMockDnsResolver).setPrefix64(netId, "");
inOrder.verify(mMockDnsResolver).startPrefix64Discovery(netId);
- mService.mNetdEventCallback.onNat64PrefixEvent(netId, true /* added */,
- pref64FromDnsStr, 96);
+ mService.mResolverUnsolEventCallback.onNat64PrefixEvent(
+ makeNat64PrefixEvent(netId, PREFIX_OPERATION_ADDED, pref64FromDnsStr, 96));
expectNat64PrefixChange(callback, mWiFiNetworkAgent, pref64FromDns);
inOrder.verify(mMockNetd).clatdStart(iface, pref64FromDns.toString());
inOrder.verify(mMockDnsResolver, never()).setPrefix64(eq(netId), any());
@@ -8202,11 +8279,10 @@ public class ConnectivityServiceTest {
final LinkProperties cellLp = new LinkProperties();
cellLp.setInterfaceName(MOBILE_IFNAME);
mCellNetworkAgent.sendLinkProperties(cellLp);
- reset(mNetworkManagementService);
mCellNetworkAgent.connect(true);
networkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent);
- verify(mNetworkManagementService, times(1)).addIdleTimer(eq(MOBILE_IFNAME), anyInt(),
- eq(NetworkCapabilities.TRANSPORT_CELLULAR));
+ verify(mMockNetd, times(1)).idletimerAddInterface(eq(MOBILE_IFNAME), anyInt(),
+ eq(Integer.toString(TRANSPORT_CELLULAR)));
mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
final LinkProperties wifiLp = new LinkProperties();
@@ -8214,25 +8290,27 @@ public class ConnectivityServiceTest {
mWiFiNetworkAgent.sendLinkProperties(wifiLp);
// Network switch
- reset(mNetworkManagementService);
mWiFiNetworkAgent.connect(true);
networkCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
networkCallback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent);
networkCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
- verify(mNetworkManagementService, times(1)).addIdleTimer(eq(WIFI_IFNAME), anyInt(),
- eq(NetworkCapabilities.TRANSPORT_WIFI));
- verify(mNetworkManagementService, times(1)).removeIdleTimer(eq(MOBILE_IFNAME));
+ verify(mMockNetd, times(1)).idletimerAddInterface(eq(WIFI_IFNAME), anyInt(),
+ eq(Integer.toString(TRANSPORT_WIFI)));
+ verify(mMockNetd, times(1)).idletimerRemoveInterface(eq(MOBILE_IFNAME), anyInt(),
+ eq(Integer.toString(TRANSPORT_CELLULAR)));
// Disconnect wifi and switch back to cell
- reset(mNetworkManagementService);
+ reset(mMockNetd);
mWiFiNetworkAgent.disconnect();
networkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
assertNoCallbacks(networkCallback);
- verify(mNetworkManagementService, times(1)).removeIdleTimer(eq(WIFI_IFNAME));
- verify(mNetworkManagementService, times(1)).addIdleTimer(eq(MOBILE_IFNAME), anyInt(),
- eq(NetworkCapabilities.TRANSPORT_CELLULAR));
+ verify(mMockNetd, times(1)).idletimerRemoveInterface(eq(WIFI_IFNAME), anyInt(),
+ eq(Integer.toString(TRANSPORT_WIFI)));
+ verify(mMockNetd, times(1)).idletimerAddInterface(eq(MOBILE_IFNAME), anyInt(),
+ eq(Integer.toString(TRANSPORT_CELLULAR)));
// reconnect wifi
+ reset(mMockNetd);
mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
wifiLp.setInterfaceName(WIFI_IFNAME);
mWiFiNetworkAgent.sendLinkProperties(wifiLp);
@@ -8240,9 +8318,12 @@ public class ConnectivityServiceTest {
networkCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
networkCallback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent);
networkCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
+ verify(mMockNetd, times(1)).idletimerAddInterface(eq(WIFI_IFNAME), anyInt(),
+ eq(Integer.toString(TRANSPORT_WIFI)));
+ verify(mMockNetd, times(1)).idletimerRemoveInterface(eq(MOBILE_IFNAME), anyInt(),
+ eq(Integer.toString(TRANSPORT_CELLULAR)));
// Disconnect cell
- reset(mNetworkManagementService);
reset(mMockNetd);
mCellNetworkAgent.disconnect();
networkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
@@ -8250,17 +8331,18 @@ public class ConnectivityServiceTest {
// sent as network being switched. Ensure rule removal for cell will not be triggered
// unexpectedly before network being removed.
waitForIdle();
- verify(mNetworkManagementService, times(0)).removeIdleTimer(eq(MOBILE_IFNAME));
+ verify(mMockNetd, times(0)).idletimerRemoveInterface(eq(MOBILE_IFNAME), anyInt(),
+ eq(Integer.toString(TRANSPORT_CELLULAR)));
verify(mMockNetd, times(1)).networkDestroy(eq(mCellNetworkAgent.getNetwork().netId));
verify(mMockDnsResolver, times(1))
.destroyNetworkCache(eq(mCellNetworkAgent.getNetwork().netId));
// Disconnect wifi
ExpectedBroadcast b = expectConnectivityAction(TYPE_WIFI, DetailedState.DISCONNECTED);
- reset(mNetworkManagementService);
mWiFiNetworkAgent.disconnect();
b.expectBroadcast();
- verify(mNetworkManagementService, times(1)).removeIdleTimer(eq(WIFI_IFNAME));
+ verify(mMockNetd, times(1)).idletimerRemoveInterface(eq(WIFI_IFNAME), anyInt(),
+ eq(Integer.toString(TRANSPORT_WIFI)));
// Clean up
mCm.unregisterNetworkCallback(networkCallback);
@@ -8381,7 +8463,7 @@ public class ConnectivityServiceTest {
lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), null));
lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), RTN_UNREACHABLE));
// The uid range needs to cover the test app so the network is visible to it.
- final Set<UidRange> vpnRange = Collections.singleton(UidRange.createForUser(PRIMARY_USER));
+ final Set<UidRange> vpnRange = Collections.singleton(createUidRange(PRIMARY_USER));
mMockVpn.establish(lp, VPN_UID, vpnRange);
assertVpnUidRangesUpdated(true, vpnRange, VPN_UID);
@@ -8409,7 +8491,7 @@ public class ConnectivityServiceTest {
lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), null));
lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), null));
// The uid range needs to cover the test app so the network is visible to it.
- final Set<UidRange> vpnRange = Collections.singleton(UidRange.createForUser(PRIMARY_USER));
+ final Set<UidRange> vpnRange = Collections.singleton(createUidRange(PRIMARY_USER));
mMockVpn.establish(lp, Process.SYSTEM_UID, vpnRange);
assertVpnUidRangesUpdated(true, vpnRange, Process.SYSTEM_UID);
@@ -8425,7 +8507,7 @@ public class ConnectivityServiceTest {
lp.addRoute(new RouteInfo(new IpPrefix("192.0.2.0/24"), null, "tun0"));
lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), RTN_UNREACHABLE));
// The uid range needs to cover the test app so the network is visible to it.
- final Set<UidRange> vpnRange = Collections.singleton(UidRange.createForUser(PRIMARY_USER));
+ final Set<UidRange> vpnRange = Collections.singleton(createUidRange(PRIMARY_USER));
mMockVpn.establish(lp, Process.SYSTEM_UID, vpnRange);
assertVpnUidRangesUpdated(true, vpnRange, Process.SYSTEM_UID);
@@ -8440,7 +8522,7 @@ public class ConnectivityServiceTest {
lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), null));
lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), null));
// The uid range needs to cover the test app so the network is visible to it.
- final Set<UidRange> vpnRange = Collections.singleton(UidRange.createForUser(PRIMARY_USER));
+ final Set<UidRange> vpnRange = Collections.singleton(createUidRange(PRIMARY_USER));
mMockVpn.establish(lp, VPN_UID, vpnRange);
assertVpnUidRangesUpdated(true, vpnRange, VPN_UID);
@@ -8492,7 +8574,7 @@ public class ConnectivityServiceTest {
lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), RTN_UNREACHABLE));
lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), null));
// The uid range needs to cover the test app so the network is visible to it.
- final UidRange vpnRange = UidRange.createForUser(PRIMARY_USER);
+ final UidRange vpnRange = createUidRange(PRIMARY_USER);
final Set<UidRange> vpnRanges = Collections.singleton(vpnRange);
mMockVpn.establish(lp, VPN_UID, vpnRanges);
assertVpnUidRangesUpdated(true, vpnRanges, VPN_UID);
@@ -8691,7 +8773,7 @@ public class ConnectivityServiceTest {
private void setupConnectionOwnerUid(int vpnOwnerUid, @VpnManager.VpnType int vpnType)
throws Exception {
- final Set<UidRange> vpnRange = Collections.singleton(UidRange.createForUser(PRIMARY_USER));
+ final Set<UidRange> vpnRange = Collections.singleton(createUidRange(PRIMARY_USER));
mMockVpn.setVpnType(vpnType);
mMockVpn.establish(new LinkProperties(), vpnOwnerUid, vpnRange);
assertVpnUidRangesUpdated(true, vpnRange, vpnOwnerUid);
@@ -8890,8 +8972,8 @@ public class ConnectivityServiceTest {
ConnectivityManager.getNetworkTypeName(TYPE_MOBILE),
TelephonyManager.getNetworkTypeName(TelephonyManager.NETWORK_TYPE_LTE));
return new NetworkAgentInfo(null, new Network(NET_ID), info, new LinkProperties(),
- nc, 0, mServiceContext, null, new NetworkAgentConfig(), mService, null, null, null,
- 0, INVALID_UID, mQosCallbackTracker);
+ nc, 0, mServiceContext, null, new NetworkAgentConfig(), mService, null, null, 0,
+ INVALID_UID, mQosCallbackTracker);
}
@Test
@@ -9219,7 +9301,7 @@ public class ConnectivityServiceTest {
private void assertUidRangesUpdatedForMyUid(boolean add) throws Exception {
final int uid = Process.myUid();
- assertVpnUidRangesUpdated(add, uidRangesForUid(uid), uid);
+ assertVpnUidRangesUpdated(add, uidRangesForUids(uid), uid);
}
private void assertVpnUidRangesUpdated(boolean add, Set<UidRange> vpnRanges, int exemptUid)
@@ -9250,7 +9332,7 @@ public class ConnectivityServiceTest {
lp.setInterfaceName("tun0");
lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), null));
lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), null));
- final UidRange vpnRange = UidRange.createForUser(PRIMARY_USER);
+ final UidRange vpnRange = createUidRange(PRIMARY_USER);
Set<UidRange> vpnRanges = Collections.singleton(vpnRange);
mMockVpn.establish(lp, VPN_UID, vpnRanges);
assertVpnUidRangesUpdated(true, vpnRanges, VPN_UID);
@@ -9430,8 +9512,12 @@ public class ConnectivityServiceTest {
fail("TOO_MANY_REQUESTS never thrown");
}
+ private UidRange createUidRange(int userId) {
+ return UidRange.createForUser(UserHandle.of(userId));
+ }
+
private void mockGetApplicationInfo(@NonNull final String packageName, @NonNull final int uid)
- throws PackageManager.NameNotFoundException {
+ throws Exception {
final ApplicationInfo applicationInfo = new ApplicationInfo();
applicationInfo.uid = uid;
when(mPackageManager.getApplicationInfo(eq(packageName), anyInt()))
@@ -9451,7 +9537,7 @@ public class ConnectivityServiceTest {
private OemNetworkPreferences createDefaultOemNetworkPreferences(
@OemNetworkPreferences.OemNetworkPreference final int preference)
- throws PackageManager.NameNotFoundException {
+ throws Exception {
// Arrange PackageManager mocks
mockGetApplicationInfo(TEST_PACKAGE_NAME, TEST_PACKAGE_UID);
@@ -9465,7 +9551,7 @@ public class ConnectivityServiceTest {
public void testOemNetworkRequestFactoryPreferenceUninitializedThrowsError()
throws PackageManager.NameNotFoundException {
@OemNetworkPreferences.OemNetworkPreference final int prefToTest =
- OemNetworkPreferences.OEM_NETWORK_PREFERENCE_UNINITIALIZED;
+ OEM_NETWORK_PREFERENCE_UNINITIALIZED;
// Act on OemNetworkRequestFactory.createNrisFromOemNetworkPreferences()
assertThrows(IllegalArgumentException.class,
@@ -9476,13 +9562,13 @@ public class ConnectivityServiceTest {
@Test
public void testOemNetworkRequestFactoryPreferenceOemPaid()
- throws PackageManager.NameNotFoundException {
+ throws Exception {
// Expectations
final int expectedNumOfNris = 1;
final int expectedNumOfRequests = 3;
@OemNetworkPreferences.OemNetworkPreference final int prefToTest =
- OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID;
+ OEM_NETWORK_PREFERENCE_OEM_PAID;
// Act on OemNetworkRequestFactory.createNrisFromOemNetworkPreferences()
final ArraySet<ConnectivityService.NetworkRequestInfo> nris =
@@ -9505,13 +9591,13 @@ public class ConnectivityServiceTest {
@Test
public void testOemNetworkRequestFactoryPreferenceOemPaidNoFallback()
- throws PackageManager.NameNotFoundException {
+ throws Exception {
// Expectations
final int expectedNumOfNris = 1;
final int expectedNumOfRequests = 2;
@OemNetworkPreferences.OemNetworkPreference final int prefToTest =
- OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK;
+ OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK;
// Act on OemNetworkRequestFactory.createNrisFromOemNetworkPreferences()
final ArraySet<ConnectivityService.NetworkRequestInfo> nris =
@@ -9531,13 +9617,13 @@ public class ConnectivityServiceTest {
@Test
public void testOemNetworkRequestFactoryPreferenceOemPaidOnly()
- throws PackageManager.NameNotFoundException {
+ throws Exception {
// Expectations
final int expectedNumOfNris = 1;
final int expectedNumOfRequests = 1;
@OemNetworkPreferences.OemNetworkPreference final int prefToTest =
- OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY;
+ OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY;
// Act on OemNetworkRequestFactory.createNrisFromOemNetworkPreferences()
final ArraySet<ConnectivityService.NetworkRequestInfo> nris =
@@ -9554,13 +9640,13 @@ public class ConnectivityServiceTest {
@Test
public void testOemNetworkRequestFactoryPreferenceOemPrivateOnly()
- throws PackageManager.NameNotFoundException {
+ throws Exception {
// Expectations
final int expectedNumOfNris = 1;
final int expectedNumOfRequests = 1;
@OemNetworkPreferences.OemNetworkPreference final int prefToTest =
- OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY;
+ OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY;
// Act on OemNetworkRequestFactory.createNrisFromOemNetworkPreferences()
final ArraySet<ConnectivityService.NetworkRequestInfo> nris =
@@ -9578,7 +9664,7 @@ public class ConnectivityServiceTest {
@Test
public void testOemNetworkRequestFactoryCreatesCorrectNumOfNris()
- throws PackageManager.NameNotFoundException {
+ throws Exception {
// Expectations
final int expectedNumOfNris = 2;
@@ -9588,8 +9674,8 @@ public class ConnectivityServiceTest {
mockGetApplicationInfo(testPackageName2, TEST_PACKAGE_UID);
// Build OemNetworkPreferences object
- final int testOemPref = OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID;
- final int testOemPref2 = OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK;
+ final int testOemPref = OEM_NETWORK_PREFERENCE_OEM_PAID;
+ final int testOemPref2 = OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK;
final OemNetworkPreferences pref = new OemNetworkPreferences.Builder()
.addNetworkPreference(TEST_PACKAGE_NAME, testOemPref)
.addNetworkPreference(testPackageName2, testOemPref2)
@@ -9604,8 +9690,8 @@ public class ConnectivityServiceTest {
}
@Test
- public void testOemNetworkRequestFactoryCorrectlySetsUids()
- throws PackageManager.NameNotFoundException {
+ public void testOemNetworkRequestFactoryMultiplePrefsCorrectlySetsUids()
+ throws Exception {
// Arrange PackageManager mocks
final String testPackageName2 = "com.google.apps.dialer";
final int testPackageNameUid2 = 456;
@@ -9613,8 +9699,8 @@ public class ConnectivityServiceTest {
mockGetApplicationInfo(testPackageName2, testPackageNameUid2);
// Build OemNetworkPreferences object
- final int testOemPref = OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID;
- final int testOemPref2 = OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK;
+ final int testOemPref = OEM_NETWORK_PREFERENCE_OEM_PAID;
+ final int testOemPref2 = OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK;
final OemNetworkPreferences pref = new OemNetworkPreferences.Builder()
.addNetworkPreference(TEST_PACKAGE_NAME, testOemPref)
.addNetworkPreference(testPackageName2, testOemPref2)
@@ -9635,8 +9721,48 @@ public class ConnectivityServiceTest {
}
@Test
+ public void testOemNetworkRequestFactoryMultipleUsersCorrectlySetsUids()
+ throws Exception {
+ // Arrange users
+ final int secondUser = 10;
+ final UserHandle secondUserHandle = new UserHandle(secondUser);
+ when(mUserManager.getUserHandles(anyBoolean())).thenReturn(
+ Arrays.asList(PRIMARY_USER_HANDLE, secondUserHandle));
+
+ // Arrange PackageManager mocks
+ mockGetApplicationInfo(TEST_PACKAGE_NAME, TEST_PACKAGE_UID);
+
+ // Build OemNetworkPreferences object
+ final int testOemPref = OEM_NETWORK_PREFERENCE_OEM_PAID;
+ final OemNetworkPreferences pref = new OemNetworkPreferences.Builder()
+ .addNetworkPreference(TEST_PACKAGE_NAME, testOemPref)
+ .build();
+
+ // Act on OemNetworkRequestFactory.createNrisFromOemNetworkPreferences()
+ final List<ConnectivityService.NetworkRequestInfo> nris =
+ new ArrayList<>(
+ mService.new OemNetworkRequestFactory().createNrisFromOemNetworkPreferences(
+ pref));
+
+ // UIDs for all users and all managed packages should be present.
+ // Two users each with two packages.
+ final int expectedUidSize = 2;
+ final List<UidRange> uids =
+ new ArrayList<>(nris.get(0).mRequests.get(0).networkCapabilities.getUids());
+ assertEquals(expectedUidSize, uids.size());
+
+ // Sort by uid to access nris by index
+ uids.sort(Comparator.comparingInt(uid -> uid.start));
+ final int secondUserTestPackageUid = UserHandle.getUid(secondUser, TEST_PACKAGE_UID);
+ assertEquals(TEST_PACKAGE_UID, uids.get(0).start);
+ assertEquals(TEST_PACKAGE_UID, uids.get(0).stop);
+ assertEquals(secondUserTestPackageUid, uids.get(1).start);
+ assertEquals(secondUserTestPackageUid, uids.get(1).stop);
+ }
+
+ @Test
public void testOemNetworkRequestFactoryAddsPackagesToCorrectPreference()
- throws PackageManager.NameNotFoundException {
+ throws Exception {
// Expectations
final int expectedNumOfNris = 1;
final int expectedNumOfAppUids = 2;
@@ -9648,7 +9774,7 @@ public class ConnectivityServiceTest {
mockGetApplicationInfo(testPackageName2, testPackageNameUid2);
// Build OemNetworkPreferences object
- final int testOemPref = OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID;
+ final int testOemPref = OEM_NETWORK_PREFERENCE_OEM_PAID;
final OemNetworkPreferences pref = new OemNetworkPreferences.Builder()
.addNetworkPreference(TEST_PACKAGE_NAME, testOemPref)
.addNetworkPreference(testPackageName2, testOemPref)
@@ -9666,8 +9792,6 @@ public class ConnectivityServiceTest {
@Test
public void testSetOemNetworkPreferenceNullListenerAndPrefParamThrowsNpe() {
mockHasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, true);
- @OemNetworkPreferences.OemNetworkPreference final int networkPref =
- OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY;
// Act on ConnectivityService.setOemNetworkPreference()
assertThrows(NullPointerException.class,
@@ -9678,15 +9802,1132 @@ public class ConnectivityServiceTest {
@Test
public void testSetOemNetworkPreferenceFailsForNonAutomotive()
- throws PackageManager.NameNotFoundException, RemoteException {
+ throws Exception {
mockHasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, false);
@OemNetworkPreferences.OemNetworkPreference final int networkPref =
- OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY;
+ OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY;
// Act on ConnectivityService.setOemNetworkPreference()
assertThrows(UnsupportedOperationException.class,
() -> mService.setOemNetworkPreference(
createDefaultOemNetworkPreferences(networkPref),
- mOnSetOemNetworkPreferenceListener));
+ new TestOemListenerCallback()));
+ }
+
+ private void setOemNetworkPreferenceAgentConnected(final int transportType,
+ final boolean connectAgent) throws Exception {
+ switch(transportType) {
+ // Corresponds to a metered cellular network. Will be used for the default network.
+ case TRANSPORT_CELLULAR:
+ if (!connectAgent) {
+ mCellNetworkAgent.disconnect();
+ break;
+ }
+ mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR);
+ mCellNetworkAgent.removeCapability(NET_CAPABILITY_NOT_METERED);
+ mCellNetworkAgent.connect(true);
+ break;
+ // Corresponds to a restricted ethernet network with OEM_PAID/OEM_PRIVATE.
+ case TRANSPORT_ETHERNET:
+ if (!connectAgent) {
+ stopOemManagedNetwork();
+ break;
+ }
+ startOemManagedNetwork(true);
+ break;
+ // Corresponds to unmetered Wi-Fi.
+ case TRANSPORT_WIFI:
+ if (!connectAgent) {
+ mWiFiNetworkAgent.disconnect();
+ break;
+ }
+ mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
+ mWiFiNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED);
+ mWiFiNetworkAgent.connect(true);
+ break;
+ default:
+ throw new AssertionError("Unsupported transport type passed in.");
+
+ }
+ waitForIdle();
+ }
+
+ private void startOemManagedNetwork(final boolean isOemPaid) throws Exception {
+ mEthernetNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_ETHERNET);
+ mEthernetNetworkAgent.addCapability(
+ isOemPaid ? NET_CAPABILITY_OEM_PAID : NET_CAPABILITY_OEM_PRIVATE);
+ mEthernetNetworkAgent.removeCapability(NET_CAPABILITY_NOT_RESTRICTED);
+ mEthernetNetworkAgent.connect(true);
+ }
+
+ private void stopOemManagedNetwork() {
+ mEthernetNetworkAgent.disconnect();
+ waitForIdle();
+ }
+
+ private void verifyMultipleDefaultNetworksTracksCorrectly(
+ final int expectedOemRequestsSize,
+ @NonNull final Network expectedDefaultNetwork,
+ @NonNull final Network expectedPerAppNetwork) {
+ // The current test setup assumes two tracked default network requests; one for the default
+ // network and the other for the OEM network preference being tested. This will be validated
+ // each time to confirm it doesn't change under test.
+ final int expectedDefaultNetworkRequestsSize = 2;
+ assertEquals(expectedDefaultNetworkRequestsSize, mService.mDefaultNetworkRequests.size());
+ for (final ConnectivityService.NetworkRequestInfo defaultRequest
+ : mService.mDefaultNetworkRequests) {
+ final Network defaultNetwork = defaultRequest.getSatisfier() == null
+ ? null : defaultRequest.getSatisfier().network();
+ // If this is the default request.
+ if (defaultRequest == mService.mDefaultRequest) {
+ assertEquals(
+ expectedDefaultNetwork,
+ defaultNetwork);
+ // Make sure this value doesn't change.
+ assertEquals(1, defaultRequest.mRequests.size());
+ continue;
+ }
+ assertEquals(expectedPerAppNetwork, defaultNetwork);
+ assertEquals(expectedOemRequestsSize, defaultRequest.mRequests.size());
+ }
+ verifyMultipleDefaultCallbacks(expectedDefaultNetwork, expectedPerAppNetwork);
+ }
+
+ /**
+ * Verify default callbacks for 'available' fire as expected. This will only run if
+ * registerDefaultNetworkCallbacks() was executed prior and will only be different if the
+ * setOemNetworkPreference() per-app API was used for the current process.
+ * @param expectedSystemDefault the expected network for the system default.
+ * @param expectedPerAppDefault the expected network for the current process's default.
+ */
+ private void verifyMultipleDefaultCallbacks(
+ @NonNull final Network expectedSystemDefault,
+ @NonNull final Network expectedPerAppDefault) {
+ if (null != mSystemDefaultNetworkCallback && null != expectedSystemDefault
+ && mService.mNoServiceNetwork.network() != expectedSystemDefault) {
+ // getLastAvailableNetwork() is used as this method can be called successively with
+ // the same network to validate therefore expectAvailableThenValidatedCallbacks
+ // can't be used.
+ assertEquals(mSystemDefaultNetworkCallback.getLastAvailableNetwork(),
+ expectedSystemDefault);
+ }
+ if (null != mDefaultNetworkCallback && null != expectedPerAppDefault
+ && mService.mNoServiceNetwork.network() != expectedPerAppDefault) {
+ assertEquals(mDefaultNetworkCallback.getLastAvailableNetwork(),
+ expectedPerAppDefault);
+ }
+ }
+
+ private void registerDefaultNetworkCallbacks() {
+ // Using Manifest.permission.NETWORK_SETTINGS for registerSystemDefaultNetworkCallback()
+ mServiceContext.setPermission(
+ Manifest.permission.NETWORK_SETTINGS, PERMISSION_GRANTED);
+ mSystemDefaultNetworkCallback = new TestNetworkCallback();
+ mDefaultNetworkCallback = new TestNetworkCallback();
+ mCm.registerSystemDefaultNetworkCallback(mSystemDefaultNetworkCallback,
+ new Handler(ConnectivityThread.getInstanceLooper()));
+ mCm.registerDefaultNetworkCallback(mDefaultNetworkCallback);
+ mServiceContext.setPermission(
+ Manifest.permission.NETWORK_SETTINGS, PERMISSION_DENIED);
+ }
+
+ private void unregisterDefaultNetworkCallbacks() {
+ if (null != mDefaultNetworkCallback) {
+ mCm.unregisterNetworkCallback(mDefaultNetworkCallback);
+ }
+ if (null != mSystemDefaultNetworkCallback) {
+ mCm.unregisterNetworkCallback(mSystemDefaultNetworkCallback);
+ }
+ }
+
+ private void setupMultipleDefaultNetworksForOemNetworkPreferenceNotCurrentUidTest(
+ @OemNetworkPreferences.OemNetworkPreference final int networkPrefToSetup)
+ throws Exception {
+ final int testPackageNameUid = 123;
+ final String testPackageName = "per.app.defaults.package";
+ setupMultipleDefaultNetworksForOemNetworkPreferenceTest(
+ networkPrefToSetup, testPackageNameUid, testPackageName);
+ }
+
+ private void setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest(
+ @OemNetworkPreferences.OemNetworkPreference final int networkPrefToSetup)
+ throws Exception {
+ final int testPackageNameUid = Process.myUid();
+ final String testPackageName = "per.app.defaults.package";
+ setupMultipleDefaultNetworksForOemNetworkPreferenceTest(
+ networkPrefToSetup, testPackageNameUid, testPackageName);
+ }
+
+ private void setupMultipleDefaultNetworksForOemNetworkPreferenceTest(
+ @OemNetworkPreferences.OemNetworkPreference final int networkPrefToSetup,
+ final int testPackageUid, @NonNull final String testPackageName) throws Exception {
+ // Only the default request should be included at start.
+ assertEquals(1, mService.mDefaultNetworkRequests.size());
+
+ final UidRangeParcel[] uidRanges =
+ toUidRangeStableParcels(uidRangesForUids(testPackageUid));
+ setupSetOemNetworkPreferenceForPreferenceTest(
+ networkPrefToSetup, uidRanges, testPackageName);
+ }
+
+ private void setupSetOemNetworkPreferenceForPreferenceTest(
+ @OemNetworkPreferences.OemNetworkPreference final int networkPrefToSetup,
+ @NonNull final UidRangeParcel[] uidRanges,
+ @NonNull final String testPackageName)
+ throws Exception {
+ mockHasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, true);
+
+ // These tests work off a single UID therefore using 'start' is valid.
+ mockGetApplicationInfo(testPackageName, uidRanges[0].start);
+
+ // Build OemNetworkPreferences object
+ final OemNetworkPreferences pref = new OemNetworkPreferences.Builder()
+ .addNetworkPreference(testPackageName, networkPrefToSetup)
+ .build();
+
+ // Act on ConnectivityService.setOemNetworkPreference()
+ final TestOemListenerCallback oemPrefListener = new TestOemListenerCallback();
+ mService.setOemNetworkPreference(pref, oemPrefListener);
+
+ // Verify call returned successfully
+ oemPrefListener.expectOnComplete();
+ }
+
+ private static class TestOemListenerCallback implements IOnSetOemNetworkPreferenceListener {
+ final CompletableFuture<Object> mDone = new CompletableFuture<>();
+
+ @Override
+ public void onComplete() {
+ mDone.complete(new Object());
+ }
+
+ void expectOnComplete() throws Exception {
+ try {
+ mDone.get(TIMEOUT_MS, TimeUnit.MILLISECONDS);
+ } catch (TimeoutException e) {
+ fail("Expected onComplete() not received after " + TIMEOUT_MS + " ms");
+ }
+ }
+
+ @Override
+ public IBinder asBinder() {
+ return null;
+ }
+ }
+
+ @Test
+ public void testMultiDefaultGetActiveNetworkIsCorrect() throws Exception {
+ @OemNetworkPreferences.OemNetworkPreference final int networkPref =
+ OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY;
+ final int expectedOemPrefRequestSize = 1;
+ registerDefaultNetworkCallbacks();
+
+ // Setup the test process to use networkPref for their default network.
+ setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest(networkPref);
+
+ // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID.
+ // The active network for the default should be null at this point as this is a retricted
+ // network.
+ setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true);
+ verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize,
+ null,
+ mEthernetNetworkAgent.getNetwork());
+
+ // Verify that the active network is correct
+ verifyActiveNetwork(TRANSPORT_ETHERNET);
+ // default NCs will be unregistered in tearDown
+ }
+
+ @Test
+ public void testMultiDefaultIsActiveNetworkMeteredIsCorrect() throws Exception {
+ @OemNetworkPreferences.OemNetworkPreference final int networkPref =
+ OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY;
+ final int expectedOemPrefRequestSize = 1;
+ registerDefaultNetworkCallbacks();
+
+ // Setup the test process to use networkPref for their default network.
+ setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest(networkPref);
+
+ // Returns true by default when no network is available.
+ assertTrue(mCm.isActiveNetworkMetered());
+
+ // Connect to an unmetered restricted network that will only be available to the OEM pref.
+ mEthernetNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_ETHERNET);
+ mEthernetNetworkAgent.addCapability(NET_CAPABILITY_OEM_PAID);
+ mEthernetNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED);
+ mEthernetNetworkAgent.removeCapability(NET_CAPABILITY_NOT_RESTRICTED);
+ mEthernetNetworkAgent.connect(true);
+ waitForIdle();
+
+ verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize,
+ null,
+ mEthernetNetworkAgent.getNetwork());
+
+ assertFalse(mCm.isActiveNetworkMetered());
+ // default NCs will be unregistered in tearDown
+ }
+
+ @Test
+ public void testPerAppDefaultRegisterDefaultNetworkCallback() throws Exception {
+ @OemNetworkPreferences.OemNetworkPreference final int networkPref =
+ OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY;
+ final int expectedOemPrefRequestSize = 1;
+ final TestNetworkCallback defaultNetworkCallback = new TestNetworkCallback();
+
+ // Register the default network callback before the pref is already set. This means that
+ // the policy will be applied to the callback on setOemNetworkPreference().
+ mCm.registerDefaultNetworkCallback(defaultNetworkCallback);
+ defaultNetworkCallback.assertNoCallback();
+
+ // Setup the test process to use networkPref for their default network.
+ setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest(networkPref);
+
+ // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID.
+ // The active nai for the default is null at this point as this is a restricted network.
+ setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true);
+ verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize,
+ null,
+ mEthernetNetworkAgent.getNetwork());
+
+ // At this point with a restricted network used, the available callback should trigger
+ defaultNetworkCallback.expectAvailableThenValidatedCallbacks(mEthernetNetworkAgent);
+ assertEquals(defaultNetworkCallback.getLastAvailableNetwork(),
+ mEthernetNetworkAgent.getNetwork());
+
+ // Now bring down the default network which should trigger a LOST callback.
+ setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, false);
+
+ // At this point, with no network is available, the lost callback should trigger
+ defaultNetworkCallback.expectCallback(CallbackEntry.LOST, mEthernetNetworkAgent);
+
+ // Confirm we can unregister without issues.
+ mCm.unregisterNetworkCallback(defaultNetworkCallback);
+ }
+
+ @Test
+ public void testPerAppDefaultRegisterDefaultNetworkCallbackAfterPrefSet() throws Exception {
+ @OemNetworkPreferences.OemNetworkPreference final int networkPref =
+ OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY;
+ final int expectedOemPrefRequestSize = 1;
+ final TestNetworkCallback defaultNetworkCallback = new TestNetworkCallback();
+
+ // Setup the test process to use networkPref for their default network.
+ setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest(networkPref);
+
+ // Register the default network callback after the pref is already set. This means that
+ // the policy will be applied to the callback on requestNetwork().
+ mCm.registerDefaultNetworkCallback(defaultNetworkCallback);
+ defaultNetworkCallback.assertNoCallback();
+
+ // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID.
+ // The active nai for the default is null at this point as this is a restricted network.
+ setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true);
+ verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize,
+ null,
+ mEthernetNetworkAgent.getNetwork());
+
+ // At this point with a restricted network used, the available callback should trigger
+ defaultNetworkCallback.expectAvailableThenValidatedCallbacks(mEthernetNetworkAgent);
+ assertEquals(defaultNetworkCallback.getLastAvailableNetwork(),
+ mEthernetNetworkAgent.getNetwork());
+
+ // Now bring down the default network which should trigger a LOST callback.
+ setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, false);
+
+ // At this point, with no network is available, the lost callback should trigger
+ defaultNetworkCallback.expectCallback(CallbackEntry.LOST, mEthernetNetworkAgent);
+
+ // Confirm we can unregister without issues.
+ mCm.unregisterNetworkCallback(defaultNetworkCallback);
+ }
+
+ @Test
+ public void testPerAppDefaultRegisterDefaultNetworkCallbackDoesNotFire() throws Exception {
+ @OemNetworkPreferences.OemNetworkPreference final int networkPref =
+ OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY;
+ final int expectedOemPrefRequestSize = 1;
+ final TestNetworkCallback defaultNetworkCallback = new TestNetworkCallback();
+ final int userId = UserHandle.getUserId(Process.myUid());
+
+ mCm.registerDefaultNetworkCallback(defaultNetworkCallback);
+ defaultNetworkCallback.assertNoCallback();
+
+ // Setup a process different than the test process to use the default network. This means
+ // that the defaultNetworkCallback won't be tracked by the per-app policy.
+ setupMultipleDefaultNetworksForOemNetworkPreferenceNotCurrentUidTest(networkPref);
+
+ // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID.
+ // The active nai for the default is null at this point as this is a restricted network.
+ setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true);
+ verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize,
+ null,
+ mEthernetNetworkAgent.getNetwork());
+
+ // As this callback does not have access to the OEM_PAID network, it will not fire.
+ defaultNetworkCallback.assertNoCallback();
+ assertDefaultNetworkCapabilities(userId /* no networks */);
+
+ // Bring up unrestricted cellular. This should now satisfy the default network.
+ setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true);
+ verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize,
+ mCellNetworkAgent.getNetwork(),
+ mEthernetNetworkAgent.getNetwork());
+
+ // At this point with an unrestricted network used, the available callback should trigger
+ defaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent);
+ assertEquals(defaultNetworkCallback.getLastAvailableNetwork(),
+ mCellNetworkAgent.getNetwork());
+ assertDefaultNetworkCapabilities(userId, mCellNetworkAgent);
+
+ // Now bring down the per-app network.
+ setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, false);
+
+ // Since the callback didn't use the per-app network, no callback should fire.
+ defaultNetworkCallback.assertNoCallback();
+
+ // Now bring down the default network.
+ setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, false);
+
+ // As this callback was tracking the default, this should now trigger.
+ defaultNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
+
+ // Confirm we can unregister without issues.
+ mCm.unregisterNetworkCallback(defaultNetworkCallback);
+ }
+
+ /**
+ * This method assumes that the same uidRanges input will be used to verify that dependencies
+ * are called as expected.
+ */
+ private void verifySetOemNetworkPreferenceForPreference(
+ @NonNull final UidRangeParcel[] uidRanges,
+ final int addUidRangesNetId,
+ final int addUidRangesTimes,
+ final int removeUidRangesNetId,
+ final int removeUidRangesTimes,
+ final boolean shouldDestroyNetwork) throws RemoteException {
+ verifySetOemNetworkPreferenceForPreference(uidRanges, uidRanges,
+ addUidRangesNetId, addUidRangesTimes, removeUidRangesNetId, removeUidRangesTimes,
+ shouldDestroyNetwork);
+ }
+
+ private void verifySetOemNetworkPreferenceForPreference(
+ @NonNull final UidRangeParcel[] addedUidRanges,
+ @NonNull final UidRangeParcel[] removedUidRanges,
+ final int addUidRangesNetId,
+ final int addUidRangesTimes,
+ final int removeUidRangesNetId,
+ final int removeUidRangesTimes,
+ final boolean shouldDestroyNetwork) throws RemoteException {
+ final boolean useAnyIdForAdd = OEM_PREF_ANY_NET_ID == addUidRangesNetId;
+ final boolean useAnyIdForRemove = OEM_PREF_ANY_NET_ID == removeUidRangesNetId;
+
+ // Validate netd.
+ verify(mMockNetd, times(addUidRangesTimes))
+ .networkAddUidRanges(
+ (useAnyIdForAdd ? anyInt() : eq(addUidRangesNetId)), eq(addedUidRanges));
+ verify(mMockNetd, times(removeUidRangesTimes))
+ .networkRemoveUidRanges(
+ (useAnyIdForRemove ? anyInt() : eq(removeUidRangesNetId)),
+ eq(removedUidRanges));
+ if (shouldDestroyNetwork) {
+ verify(mMockNetd, times(1))
+ .networkDestroy((useAnyIdForRemove ? anyInt() : eq(removeUidRangesNetId)));
+ }
+ reset(mMockNetd);
+ }
+
+ /**
+ * Test the tracked default requests clear previous OEM requests on setOemNetworkPreference().
+ */
+ @Test
+ public void testSetOemNetworkPreferenceClearPreviousOemValues() throws Exception {
+ @OemNetworkPreferences.OemNetworkPreference int networkPref =
+ OEM_NETWORK_PREFERENCE_OEM_PAID;
+ final int testPackageUid = 123;
+ final String testPackageName = "com.google.apps.contacts";
+ final UidRangeParcel[] uidRanges =
+ toUidRangeStableParcels(uidRangesForUids(testPackageUid));
+
+ // Validate the starting requests only includes the fallback request.
+ assertEquals(1, mService.mDefaultNetworkRequests.size());
+
+ // Add an OEM default network request to track.
+ setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges, testPackageName);
+
+ // Two requests should exist, one for the fallback and one for the pref.
+ assertEquals(2, mService.mDefaultNetworkRequests.size());
+
+ networkPref = OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY;
+ setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges, testPackageName);
+
+ // Two requests should still exist validating the previous per-app request was replaced.
+ assertEquals(2, mService.mDefaultNetworkRequests.size());
+ }
+
+ /**
+ * Test network priority for preference OEM_NETWORK_PREFERENCE_OEM_PAID in the following order:
+ * NET_CAPABILITY_NOT_METERED -> NET_CAPABILITY_OEM_PAID -> fallback
+ */
+ @Test
+ public void testMultilayerForPreferenceOemPaidEvaluatesCorrectly()
+ throws Exception {
+ @OemNetworkPreferences.OemNetworkPreference final int networkPref =
+ OEM_NETWORK_PREFERENCE_OEM_PAID;
+
+ // Arrange PackageManager mocks
+ final UidRangeParcel[] uidRanges =
+ toUidRangeStableParcels(uidRangesForUids(TEST_PACKAGE_UID));
+ setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges, TEST_PACKAGE_NAME);
+
+ // Verify the starting state. No networks should be connected.
+ verifySetOemNetworkPreferenceForPreference(uidRanges,
+ OEM_PREF_ANY_NET_ID, 0 /* times */,
+ OEM_PREF_ANY_NET_ID, 0 /* times */,
+ false /* shouldDestroyNetwork */);
+
+ // Test lowest to highest priority requests.
+ // Bring up metered cellular. This will satisfy the fallback network.
+ setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true);
+ verifySetOemNetworkPreferenceForPreference(uidRanges,
+ mCellNetworkAgent.getNetwork().netId, 1 /* times */,
+ OEM_PREF_ANY_NET_ID, 0 /* times */,
+ false /* shouldDestroyNetwork */);
+
+ // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID.
+ setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true);
+ verifySetOemNetworkPreferenceForPreference(uidRanges,
+ mEthernetNetworkAgent.getNetwork().netId, 1 /* times */,
+ mCellNetworkAgent.getNetwork().netId, 1 /* times */,
+ false /* shouldDestroyNetwork */);
+
+ // Bring up unmetered Wi-Fi. This will satisfy NET_CAPABILITY_NOT_METERED.
+ setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, true);
+ verifySetOemNetworkPreferenceForPreference(uidRanges,
+ mWiFiNetworkAgent.getNetwork().netId, 1 /* times */,
+ mEthernetNetworkAgent.getNetwork().netId, 1 /* times */,
+ false /* shouldDestroyNetwork */);
+
+ // Disconnecting OEM_PAID should have no effect as it is lower in priority then unmetered.
+ setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, false);
+ // netd should not be called as default networks haven't changed.
+ verifySetOemNetworkPreferenceForPreference(uidRanges,
+ OEM_PREF_ANY_NET_ID, 0 /* times */,
+ OEM_PREF_ANY_NET_ID, 0 /* times */,
+ false /* shouldDestroyNetwork */);
+
+ // Disconnecting unmetered should put PANS on lowest priority fallback request.
+ setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, false);
+ verifySetOemNetworkPreferenceForPreference(uidRanges,
+ mCellNetworkAgent.getNetwork().netId, 1 /* times */,
+ mWiFiNetworkAgent.getNetwork().netId, 0 /* times */,
+ true /* shouldDestroyNetwork */);
+
+ // Disconnecting the fallback network should result in no connectivity.
+ setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, false);
+ verifySetOemNetworkPreferenceForPreference(uidRanges,
+ OEM_PREF_ANY_NET_ID, 0 /* times */,
+ mCellNetworkAgent.getNetwork().netId, 0 /* times */,
+ true /* shouldDestroyNetwork */);
+ }
+
+ /**
+ * Test network priority for OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK in the following order:
+ * NET_CAPABILITY_NOT_METERED -> NET_CAPABILITY_OEM_PAID
+ */
+ @Test
+ public void testMultilayerForPreferenceOemPaidNoFallbackEvaluatesCorrectly()
+ throws Exception {
+ @OemNetworkPreferences.OemNetworkPreference final int networkPref =
+ OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK;
+
+ // Arrange PackageManager mocks
+ final UidRangeParcel[] uidRanges =
+ toUidRangeStableParcels(uidRangesForUids(TEST_PACKAGE_UID));
+ setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges, TEST_PACKAGE_NAME);
+
+ // Verify the starting state. This preference doesn't support using the fallback network
+ // therefore should be on the disconnected network as it has no networks to connect to.
+ verifySetOemNetworkPreferenceForPreference(uidRanges,
+ mService.mNoServiceNetwork.network.getNetId(), 1 /* times */,
+ OEM_PREF_ANY_NET_ID, 0 /* times */,
+ false /* shouldDestroyNetwork */);
+
+ // Test lowest to highest priority requests.
+ // Bring up metered cellular. This will satisfy the fallback network.
+ // This preference should not use this network as it doesn't support fallback usage.
+ setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true);
+ verifySetOemNetworkPreferenceForPreference(uidRanges,
+ OEM_PREF_ANY_NET_ID, 0 /* times */,
+ OEM_PREF_ANY_NET_ID, 0 /* times */,
+ false /* shouldDestroyNetwork */);
+
+ // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID.
+ setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true);
+ verifySetOemNetworkPreferenceForPreference(uidRanges,
+ mEthernetNetworkAgent.getNetwork().netId, 1 /* times */,
+ mService.mNoServiceNetwork.network.getNetId(), 1 /* times */,
+ false /* shouldDestroyNetwork */);
+
+ // Bring up unmetered Wi-Fi. This will satisfy NET_CAPABILITY_NOT_METERED.
+ setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, true);
+ verifySetOemNetworkPreferenceForPreference(uidRanges,
+ mWiFiNetworkAgent.getNetwork().netId, 1 /* times */,
+ mEthernetNetworkAgent.getNetwork().netId, 1 /* times */,
+ false /* shouldDestroyNetwork */);
+
+ // Disconnecting unmetered should put PANS on OEM_PAID.
+ setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, false);
+ verifySetOemNetworkPreferenceForPreference(uidRanges,
+ mEthernetNetworkAgent.getNetwork().netId, 1 /* times */,
+ mWiFiNetworkAgent.getNetwork().netId, 0 /* times */,
+ true /* shouldDestroyNetwork */);
+
+ // Disconnecting OEM_PAID should result in no connectivity.
+ // OEM_PAID_NO_FALLBACK not supporting a fallback now uses the disconnected network.
+ setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, false);
+ verifySetOemNetworkPreferenceForPreference(uidRanges,
+ mService.mNoServiceNetwork.network.getNetId(), 1 /* times */,
+ mEthernetNetworkAgent.getNetwork().netId, 0 /* times */,
+ true /* shouldDestroyNetwork */);
+ }
+
+ /**
+ * Test network priority for OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY in the following order:
+ * NET_CAPABILITY_OEM_PAID
+ * This preference should only apply to OEM_PAID networks.
+ */
+ @Test
+ public void testMultilayerForPreferenceOemPaidOnlyEvaluatesCorrectly()
+ throws Exception {
+ @OemNetworkPreferences.OemNetworkPreference final int networkPref =
+ OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY;
+
+ // Arrange PackageManager mocks
+ final UidRangeParcel[] uidRanges =
+ toUidRangeStableParcels(uidRangesForUids(TEST_PACKAGE_UID));
+ setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges, TEST_PACKAGE_NAME);
+
+ // Verify the starting state. This preference doesn't support using the fallback network
+ // therefore should be on the disconnected network as it has no networks to connect to.
+ verifySetOemNetworkPreferenceForPreference(uidRanges,
+ mService.mNoServiceNetwork.network.getNetId(), 1 /* times */,
+ OEM_PREF_ANY_NET_ID, 0 /* times */,
+ false /* shouldDestroyNetwork */);
+
+ // Bring up metered cellular. This should not apply to this preference.
+ setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true);
+ verifySetOemNetworkPreferenceForPreference(uidRanges,
+ OEM_PREF_ANY_NET_ID, 0 /* times */,
+ OEM_PREF_ANY_NET_ID, 0 /* times */,
+ false /* shouldDestroyNetwork */);
+
+ // Bring up unmetered Wi-Fi. This should not apply to this preference.
+ setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, true);
+ verifySetOemNetworkPreferenceForPreference(uidRanges,
+ OEM_PREF_ANY_NET_ID, 0 /* times */,
+ OEM_PREF_ANY_NET_ID, 0 /* times */,
+ false /* shouldDestroyNetwork */);
+
+ // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID.
+ setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true);
+ verifySetOemNetworkPreferenceForPreference(uidRanges,
+ mEthernetNetworkAgent.getNetwork().netId, 1 /* times */,
+ mService.mNoServiceNetwork.network.getNetId(), 1 /* times */,
+ false /* shouldDestroyNetwork */);
+
+ // Disconnecting OEM_PAID should result in no connectivity.
+ setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, false);
+ verifySetOemNetworkPreferenceForPreference(uidRanges,
+ mService.mNoServiceNetwork.network.getNetId(), 1 /* times */,
+ mEthernetNetworkAgent.getNetwork().netId, 0 /* times */,
+ true /* shouldDestroyNetwork */);
+ }
+
+ /**
+ * Test network priority for OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY in the following order:
+ * NET_CAPABILITY_OEM_PRIVATE
+ * This preference should only apply to OEM_PRIVATE networks.
+ */
+ @Test
+ public void testMultilayerForPreferenceOemPrivateOnlyEvaluatesCorrectly()
+ throws Exception {
+ @OemNetworkPreferences.OemNetworkPreference final int networkPref =
+ OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY;
+
+ // Arrange PackageManager mocks
+ final UidRangeParcel[] uidRanges =
+ toUidRangeStableParcels(uidRangesForUids(TEST_PACKAGE_UID));
+ setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges, TEST_PACKAGE_NAME);
+
+ // Verify the starting state. This preference doesn't support using the fallback network
+ // therefore should be on the disconnected network as it has no networks to connect to.
+ verifySetOemNetworkPreferenceForPreference(uidRanges,
+ mService.mNoServiceNetwork.network.getNetId(), 1 /* times */,
+ OEM_PREF_ANY_NET_ID, 0 /* times */,
+ false /* shouldDestroyNetwork */);
+
+ // Bring up metered cellular. This should not apply to this preference.
+ setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true);
+ verifySetOemNetworkPreferenceForPreference(uidRanges,
+ OEM_PREF_ANY_NET_ID, 0 /* times */,
+ OEM_PREF_ANY_NET_ID, 0 /* times */,
+ false /* shouldDestroyNetwork */);
+
+ // Bring up unmetered Wi-Fi. This should not apply to this preference.
+ setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, true);
+ verifySetOemNetworkPreferenceForPreference(uidRanges,
+ OEM_PREF_ANY_NET_ID, 0 /* times */,
+ OEM_PREF_ANY_NET_ID, 0 /* times */,
+ false /* shouldDestroyNetwork */);
+
+ // Bring up ethernet with OEM_PRIVATE. This will satisfy NET_CAPABILITY_OEM_PRIVATE.
+ startOemManagedNetwork(false);
+ verifySetOemNetworkPreferenceForPreference(uidRanges,
+ mEthernetNetworkAgent.getNetwork().netId, 1 /* times */,
+ mService.mNoServiceNetwork.network.getNetId(), 1 /* times */,
+ false /* shouldDestroyNetwork */);
+
+ // Disconnecting OEM_PRIVATE should result in no connectivity.
+ stopOemManagedNetwork();
+ verifySetOemNetworkPreferenceForPreference(uidRanges,
+ mService.mNoServiceNetwork.network.getNetId(), 1 /* times */,
+ mEthernetNetworkAgent.getNetwork().netId, 0 /* times */,
+ true /* shouldDestroyNetwork */);
+ }
+
+ @Test
+ public void testMultilayerForMultipleUsersEvaluatesCorrectly()
+ throws Exception {
+ @OemNetworkPreferences.OemNetworkPreference final int networkPref =
+ OEM_NETWORK_PREFERENCE_OEM_PAID;
+
+ // Arrange users
+ final int secondUser = 10;
+ final UserHandle secondUserHandle = new UserHandle(secondUser);
+ when(mUserManager.getUserHandles(anyBoolean())).thenReturn(
+ Arrays.asList(PRIMARY_USER_HANDLE, secondUserHandle));
+
+ // Arrange PackageManager mocks
+ final int secondUserTestPackageUid = UserHandle.getUid(secondUser, TEST_PACKAGE_UID);
+ final UidRangeParcel[] uidRanges =
+ toUidRangeStableParcels(
+ uidRangesForUids(TEST_PACKAGE_UID, secondUserTestPackageUid));
+ setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges, TEST_PACKAGE_NAME);
+
+ // Verify the starting state. No networks should be connected.
+ verifySetOemNetworkPreferenceForPreference(uidRanges,
+ OEM_PREF_ANY_NET_ID, 0 /* times */,
+ OEM_PREF_ANY_NET_ID, 0 /* times */,
+ false /* shouldDestroyNetwork */);
+
+ // Test that we correctly add the expected values for multiple users.
+ setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true);
+ verifySetOemNetworkPreferenceForPreference(uidRanges,
+ mCellNetworkAgent.getNetwork().netId, 1 /* times */,
+ OEM_PREF_ANY_NET_ID, 0 /* times */,
+ false /* shouldDestroyNetwork */);
+
+ // Test that we correctly remove the expected values for multiple users.
+ setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, false);
+ verifySetOemNetworkPreferenceForPreference(uidRanges,
+ OEM_PREF_ANY_NET_ID, 0 /* times */,
+ mCellNetworkAgent.getNetwork().netId, 0 /* times */,
+ true /* shouldDestroyNetwork */);
+ }
+
+ @Test
+ public void testMultilayerForBroadcastedUsersEvaluatesCorrectly()
+ throws Exception {
+ @OemNetworkPreferences.OemNetworkPreference final int networkPref =
+ OEM_NETWORK_PREFERENCE_OEM_PAID;
+
+ // Arrange users
+ final int secondUser = 10;
+ final UserHandle secondUserHandle = new UserHandle(secondUser);
+ when(mUserManager.getUserHandles(anyBoolean())).thenReturn(
+ Arrays.asList(PRIMARY_USER_HANDLE));
+
+ // Arrange PackageManager mocks
+ final int secondUserTestPackageUid = UserHandle.getUid(secondUser, TEST_PACKAGE_UID);
+ final UidRangeParcel[] uidRangesSingleUser =
+ toUidRangeStableParcels(
+ uidRangesForUids(TEST_PACKAGE_UID));
+ final UidRangeParcel[] uidRangesBothUsers =
+ toUidRangeStableParcels(
+ uidRangesForUids(TEST_PACKAGE_UID, secondUserTestPackageUid));
+ setupSetOemNetworkPreferenceForPreferenceTest(
+ networkPref, uidRangesSingleUser, TEST_PACKAGE_NAME);
+
+ // Verify the starting state. No networks should be connected.
+ verifySetOemNetworkPreferenceForPreference(uidRangesSingleUser,
+ OEM_PREF_ANY_NET_ID, 0 /* times */,
+ OEM_PREF_ANY_NET_ID, 0 /* times */,
+ false /* shouldDestroyNetwork */);
+
+ // Test that we correctly add the expected values for multiple users.
+ setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true);
+ verifySetOemNetworkPreferenceForPreference(uidRangesSingleUser,
+ mCellNetworkAgent.getNetwork().netId, 1 /* times */,
+ OEM_PREF_ANY_NET_ID, 0 /* times */,
+ false /* shouldDestroyNetwork */);
+
+ // Send a broadcast indicating a user was added.
+ when(mUserManager.getUserHandles(anyBoolean())).thenReturn(
+ Arrays.asList(PRIMARY_USER_HANDLE, secondUserHandle));
+ final Intent addedIntent = new Intent(ACTION_USER_ADDED);
+ addedIntent.putExtra(Intent.EXTRA_USER, UserHandle.of(secondUser));
+ processBroadcast(addedIntent);
+
+ // Test that we correctly add values for all users and remove for the single user.
+ verifySetOemNetworkPreferenceForPreference(uidRangesBothUsers, uidRangesSingleUser,
+ mCellNetworkAgent.getNetwork().netId, 1 /* times */,
+ mCellNetworkAgent.getNetwork().netId, 1 /* times */,
+ false /* shouldDestroyNetwork */);
+
+ // Send a broadcast indicating a user was removed.
+ when(mUserManager.getUserHandles(anyBoolean())).thenReturn(
+ Arrays.asList(PRIMARY_USER_HANDLE));
+ final Intent removedIntent = new Intent(ACTION_USER_REMOVED);
+ removedIntent.putExtra(Intent.EXTRA_USER, UserHandle.of(secondUser));
+ processBroadcast(removedIntent);
+
+ // Test that we correctly add values for the single user and remove for the all users.
+ verifySetOemNetworkPreferenceForPreference(uidRangesSingleUser, uidRangesBothUsers,
+ mCellNetworkAgent.getNetwork().netId, 1 /* times */,
+ mCellNetworkAgent.getNetwork().netId, 1 /* times */,
+ false /* shouldDestroyNetwork */);
+ }
+
+ /**
+ * Test network priority for preference OEM_NETWORK_PREFERENCE_OEM_PAID in the following order:
+ * NET_CAPABILITY_NOT_METERED -> NET_CAPABILITY_OEM_PAID -> fallback
+ */
+ @Test
+ public void testMultipleDefaultNetworksTracksOemNetworkPreferenceOemPaidCorrectly()
+ throws Exception {
+ @OemNetworkPreferences.OemNetworkPreference final int networkPref =
+ OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID;
+ setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest(networkPref);
+ final int expectedDefaultRequestSize = 2;
+ final int expectedOemPrefRequestSize = 3;
+ registerDefaultNetworkCallbacks();
+
+ // The fallback as well as the OEM preference should now be tracked.
+ assertEquals(expectedDefaultRequestSize, mService.mDefaultNetworkRequests.size());
+
+ // Test lowest to highest priority requests.
+ // Bring up metered cellular. This will satisfy the fallback network.
+ setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true);
+ verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize,
+ mCellNetworkAgent.getNetwork(),
+ mCellNetworkAgent.getNetwork());
+
+ // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID.
+ setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true);
+ verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize,
+ mCellNetworkAgent.getNetwork(),
+ mEthernetNetworkAgent.getNetwork());
+
+ // Bring up unmetered Wi-Fi. This will satisfy NET_CAPABILITY_NOT_METERED.
+ setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, true);
+ verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize,
+ mWiFiNetworkAgent.getNetwork(),
+ mWiFiNetworkAgent.getNetwork());
+
+ // Disconnecting unmetered Wi-Fi will put the pref on OEM_PAID and fallback on cellular.
+ setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, false);
+ verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize,
+ mCellNetworkAgent.getNetwork(),
+ mEthernetNetworkAgent.getNetwork());
+
+ // Disconnecting cellular should keep OEM network on OEM_PAID and fallback will be null.
+ setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, false);
+ verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize,
+ null,
+ mEthernetNetworkAgent.getNetwork());
+
+ // Disconnecting OEM_PAID will put both on null as it is the last network.
+ setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, false);
+ verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize,
+ null,
+ null);
+
+ // default callbacks will be unregistered in tearDown
+ }
+
+ /**
+ * Test network priority for OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK in the following order:
+ * NET_CAPABILITY_NOT_METERED -> NET_CAPABILITY_OEM_PAID
+ */
+ @Test
+ public void testMultipleDefaultNetworksTracksOemNetworkPreferenceOemPaidNoFallbackCorrectly()
+ throws Exception {
+ @OemNetworkPreferences.OemNetworkPreference final int networkPref =
+ OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK;
+ setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest(networkPref);
+ final int expectedDefaultRequestSize = 2;
+ final int expectedOemPrefRequestSize = 2;
+ registerDefaultNetworkCallbacks();
+
+ // The fallback as well as the OEM preference should now be tracked.
+ assertEquals(expectedDefaultRequestSize, mService.mDefaultNetworkRequests.size());
+
+ // Test lowest to highest priority requests.
+ // Bring up metered cellular. This will satisfy the fallback network but not the pref.
+ setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true);
+ verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize,
+ mCellNetworkAgent.getNetwork(),
+ mService.mNoServiceNetwork.network());
+
+ // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID.
+ setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true);
+ verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize,
+ mCellNetworkAgent.getNetwork(),
+ mEthernetNetworkAgent.getNetwork());
+
+ // Bring up unmetered Wi-Fi. This will satisfy NET_CAPABILITY_NOT_METERED.
+ setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, true);
+ verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize,
+ mWiFiNetworkAgent.getNetwork(),
+ mWiFiNetworkAgent.getNetwork());
+
+ // Disconnecting unmetered Wi-Fi will put the OEM pref on OEM_PAID and fallback on cellular.
+ setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, false);
+ verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize,
+ mCellNetworkAgent.getNetwork(),
+ mEthernetNetworkAgent.getNetwork());
+
+ // Disconnecting cellular should keep OEM network on OEM_PAID and fallback will be null.
+ setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, false);
+ verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize,
+ null,
+ mEthernetNetworkAgent.getNetwork());
+
+ // Disconnecting OEM_PAID puts the fallback on null and the pref on the disconnected net.
+ setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, false);
+ verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize,
+ null,
+ mService.mNoServiceNetwork.network());
+
+ // default callbacks will be unregistered in tearDown
+ }
+
+ /**
+ * Test network priority for OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY in the following order:
+ * NET_CAPABILITY_OEM_PAID
+ * This preference should only apply to OEM_PAID networks.
+ */
+ @Test
+ public void testMultipleDefaultNetworksTracksOemNetworkPreferenceOemPaidOnlyCorrectly()
+ throws Exception {
+ @OemNetworkPreferences.OemNetworkPreference final int networkPref =
+ OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY;
+ setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest(networkPref);
+ final int expectedDefaultRequestSize = 2;
+ final int expectedOemPrefRequestSize = 1;
+ registerDefaultNetworkCallbacks();
+
+ // The fallback as well as the OEM preference should now be tracked.
+ assertEquals(expectedDefaultRequestSize, mService.mDefaultNetworkRequests.size());
+
+ // Test lowest to highest priority requests.
+ // Bring up metered cellular. This will satisfy the fallback network.
+ setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true);
+ verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize,
+ mCellNetworkAgent.getNetwork(),
+ mService.mNoServiceNetwork.network());
+
+ // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID.
+ setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true);
+ verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize,
+ mCellNetworkAgent.getNetwork(),
+ mEthernetNetworkAgent.getNetwork());
+
+ // Bring up unmetered Wi-Fi. The OEM network shouldn't change, the fallback will take Wi-Fi.
+ setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, true);
+ verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize,
+ mWiFiNetworkAgent.getNetwork(),
+ mEthernetNetworkAgent.getNetwork());
+
+ // Disconnecting unmetered Wi-Fi shouldn't change the OEM network with fallback on cellular.
+ setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, false);
+ verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize,
+ mCellNetworkAgent.getNetwork(),
+ mEthernetNetworkAgent.getNetwork());
+
+ // Disconnecting OEM_PAID will keep the fallback on cellular and nothing for OEM_PAID.
+ // OEM_PAID_ONLY not supporting a fallback now uses the disconnected network.
+ setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, false);
+ verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize,
+ mCellNetworkAgent.getNetwork(),
+ mService.mNoServiceNetwork.network());
+
+ // Disconnecting cellular will put the fallback on null and the pref on disconnected.
+ setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, false);
+ verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize,
+ null,
+ mService.mNoServiceNetwork.network());
+
+ // default callbacks will be unregistered in tearDown
+ }
+
+ /**
+ * Test network priority for OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY in the following order:
+ * NET_CAPABILITY_OEM_PRIVATE
+ * This preference should only apply to OEM_PRIVATE networks.
+ */
+ @Test
+ public void testMultipleDefaultNetworksTracksOemNetworkPreferenceOemPrivateOnlyCorrectly()
+ throws Exception {
+ @OemNetworkPreferences.OemNetworkPreference final int networkPref =
+ OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY;
+ setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest(networkPref);
+ final int expectedDefaultRequestSize = 2;
+ final int expectedOemPrefRequestSize = 1;
+ registerDefaultNetworkCallbacks();
+
+ // The fallback as well as the OEM preference should now be tracked.
+ assertEquals(expectedDefaultRequestSize, mService.mDefaultNetworkRequests.size());
+
+ // Test lowest to highest priority requests.
+ // Bring up metered cellular. This will satisfy the fallback network.
+ setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true);
+ verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize,
+ mCellNetworkAgent.getNetwork(),
+ mService.mNoServiceNetwork.network());
+
+ // Bring up ethernet with OEM_PRIVATE. This will satisfy NET_CAPABILITY_OEM_PRIVATE.
+ startOemManagedNetwork(false);
+ verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize,
+ mCellNetworkAgent.getNetwork(),
+ mEthernetNetworkAgent.getNetwork());
+
+ // Bring up unmetered Wi-Fi. The OEM network shouldn't change, the fallback will take Wi-Fi.
+ setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, true);
+ verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize,
+ mWiFiNetworkAgent.getNetwork(),
+ mEthernetNetworkAgent.getNetwork());
+
+ // Disconnecting unmetered Wi-Fi shouldn't change the OEM network with fallback on cellular.
+ setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, false);
+ verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize,
+ mCellNetworkAgent.getNetwork(),
+ mEthernetNetworkAgent.getNetwork());
+
+ // Disconnecting OEM_PRIVATE will keep the fallback on cellular.
+ // OEM_PRIVATE_ONLY not supporting a fallback now uses to the disconnected network.
+ stopOemManagedNetwork();
+ verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize,
+ mCellNetworkAgent.getNetwork(),
+ mService.mNoServiceNetwork.network());
+
+ // Disconnecting cellular will put the fallback on null and pref on disconnected.
+ setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, false);
+ verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize,
+ null,
+ mService.mNoServiceNetwork.network());
+
+ // default callbacks will be unregistered in tearDown
+ }
+
+ @Test
+ public void testCapabilityWithOemNetworkPreference() throws Exception {
+ @OemNetworkPreferences.OemNetworkPreference final int networkPref =
+ OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY;
+ setupMultipleDefaultNetworksForOemNetworkPreferenceNotCurrentUidTest(networkPref);
+ registerDefaultNetworkCallbacks();
+
+ setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true);
+
+ mSystemDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent);
+ mDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent);
+
+ mCellNetworkAgent.addCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED);
+ mSystemDefaultNetworkCallback.expectCapabilitiesThat(mCellNetworkAgent, nc ->
+ nc.hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED));
+ mDefaultNetworkCallback.expectCapabilitiesThat(mCellNetworkAgent, nc ->
+ nc.hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED));
+
+ // default callbacks will be unregistered in tearDown
+ }
+
+ @Test
+ public void testGetAllNetworkStateSnapshot() throws Exception {
+ verifyNoNetwork();
+
+ // Setup test cellular network with specified LinkProperties and NetworkCapabilities,
+ // verify the content of the snapshot matches.
+ final LinkProperties cellLp = new LinkProperties();
+ final LinkAddress myIpv4Addr = new LinkAddress(InetAddress.getByName("192.0.2.129"), 25);
+ final LinkAddress myIpv6Addr = new LinkAddress(InetAddress.getByName("2001:db8::1"), 64);
+ cellLp.setInterfaceName("test01");
+ cellLp.addLinkAddress(myIpv4Addr);
+ cellLp.addLinkAddress(myIpv6Addr);
+ cellLp.addRoute(new RouteInfo(InetAddress.getByName("fe80::1234")));
+ cellLp.addRoute(new RouteInfo(InetAddress.getByName("192.0.2.254")));
+ cellLp.addRoute(new RouteInfo(myIpv4Addr, null));
+ cellLp.addRoute(new RouteInfo(myIpv6Addr, null));
+ final NetworkCapabilities cellNcTemplate = new NetworkCapabilities.Builder()
+ .addTransportType(TRANSPORT_CELLULAR).addCapability(NET_CAPABILITY_MMS).build();
+
+ final TestNetworkCallback cellCb = new TestNetworkCallback();
+ mCm.requestNetwork(new NetworkRequest.Builder().addCapability(NET_CAPABILITY_MMS).build(),
+ cellCb);
+ mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp, cellNcTemplate);
+ mCellNetworkAgent.connect(true);
+ cellCb.expectAvailableCallbacksUnvalidated(mCellNetworkAgent);
+ List<NetworkStateSnapshot> snapshots = mCm.getAllNetworkStateSnapshot();
+ assertLength(1, snapshots);
+
+ // Compose the expected cellular snapshot for verification.
+ final NetworkCapabilities cellNc =
+ mCm.getNetworkCapabilities(mCellNetworkAgent.getNetwork());
+ final NetworkStateSnapshot cellSnapshot = new NetworkStateSnapshot(
+ mCellNetworkAgent.getNetwork(), cellNc, cellLp,
+ null, ConnectivityManager.TYPE_MOBILE);
+ assertEquals(cellSnapshot, snapshots.get(0));
+
+ // Connect wifi and verify the snapshots.
+ mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
+ mWiFiNetworkAgent.connect(true);
+ waitForIdle();
+ // Compose the expected wifi snapshot for verification.
+ final NetworkCapabilities wifiNc =
+ mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork());
+ final NetworkStateSnapshot wifiSnapshot = new NetworkStateSnapshot(
+ mWiFiNetworkAgent.getNetwork(), wifiNc, new LinkProperties(), null,
+ ConnectivityManager.TYPE_WIFI);
+
+ snapshots = mCm.getAllNetworkStateSnapshot();
+ assertLength(2, snapshots);
+ assertContainsAll(snapshots, cellSnapshot, wifiSnapshot);
+
+ // Set cellular as suspended, verify the snapshots will not contain suspended networks.
+ // TODO: Consider include SUSPENDED networks, which should be considered as
+ // temporary shortage of connectivity of a connected network.
+ mCellNetworkAgent.suspend();
+ waitForIdle();
+ snapshots = mCm.getAllNetworkStateSnapshot();
+ assertLength(1, snapshots);
+ assertEquals(wifiSnapshot, snapshots.get(0));
+
+ // Disconnect wifi, verify the snapshots contain nothing.
+ mWiFiNetworkAgent.disconnect();
+ waitForIdle();
+ snapshots = mCm.getAllNetworkStateSnapshot();
+ assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
+ assertLength(0, snapshots);
+
+ mCellNetworkAgent.resume();
+ waitForIdle();
+ snapshots = mCm.getAllNetworkStateSnapshot();
+ assertLength(1, snapshots);
+ assertEquals(cellSnapshot, snapshots.get(0));
+
+ mCellNetworkAgent.disconnect();
+ waitForIdle();
+ verifyNoNetwork();
+ mCm.unregisterNetworkCallback(cellCb);
}
}
diff --git a/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java b/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java
index c86224a71978..32c95f149979 100644
--- a/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java
+++ b/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java
@@ -16,12 +16,16 @@
package com.android.server;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+import static android.net.INetd.IF_STATE_DOWN;
+import static android.net.INetd.IF_STATE_UP;
import static android.system.OsConstants.AF_INET;
import static android.system.OsConstants.AF_INET6;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail;
+import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
@@ -36,6 +40,7 @@ import android.content.pm.PackageManager;
import android.net.ConnectivityManager;
import android.net.INetd;
import android.net.InetAddresses;
+import android.net.InterfaceConfigurationParcel;
import android.net.IpSecAlgorithm;
import android.net.IpSecConfig;
import android.net.IpSecManager;
@@ -48,7 +53,6 @@ import android.net.LinkAddress;
import android.net.LinkProperties;
import android.net.Network;
import android.os.Binder;
-import android.os.INetworkManagementService;
import android.os.ParcelFileDescriptor;
import android.system.Os;
import android.test.mock.MockContext;
@@ -148,10 +152,17 @@ public class IpSecServiceParameterizedTest {
}
throw new SecurityException("Unavailable permission requested");
}
+
+ @Override
+ public int checkCallingOrSelfPermission(String permission) {
+ if (android.Manifest.permission.NETWORK_STACK.equals(permission)) {
+ return PERMISSION_GRANTED;
+ }
+ throw new UnsupportedOperationException();
+ }
};
INetd mMockNetd;
- INetworkManagementService mNetworkManager;
PackageManager mMockPkgMgr;
IpSecService.IpSecServiceConfiguration mMockIpSecSrvConfig;
IpSecService mIpSecService;
@@ -181,10 +192,9 @@ public class IpSecServiceParameterizedTest {
@Before
public void setUp() throws Exception {
mMockNetd = mock(INetd.class);
- mNetworkManager = mock(INetworkManagementService.class);
mMockPkgMgr = mock(PackageManager.class);
mMockIpSecSrvConfig = mock(IpSecService.IpSecServiceConfiguration.class);
- mIpSecService = new IpSecService(mMockContext, mNetworkManager, mMockIpSecSrvConfig);
+ mIpSecService = new IpSecService(mMockContext, mMockIpSecSrvConfig);
// Injecting mock netd
when(mMockIpSecSrvConfig.getNetdInstance()).thenReturn(mMockNetd);
@@ -644,7 +654,10 @@ public class IpSecServiceParameterizedTest {
}
private IpSecTunnelInterfaceResponse createAndValidateTunnel(
- String localAddr, String remoteAddr, String pkgName) {
+ String localAddr, String remoteAddr, String pkgName) throws Exception {
+ final InterfaceConfigurationParcel config = new InterfaceConfigurationParcel();
+ config.flags = new String[] {IF_STATE_DOWN};
+ when(mMockNetd.interfaceGetCfg(anyString())).thenReturn(config);
IpSecTunnelInterfaceResponse createTunnelResp =
mIpSecService.createTunnelInterface(
mSourceAddr, mDestinationAddr, fakeNetwork, new Binder(), pkgName);
@@ -674,7 +687,8 @@ public class IpSecServiceParameterizedTest {
anyInt(),
anyInt(),
anyInt());
- verify(mNetworkManager).setInterfaceUp(createTunnelResp.interfaceName);
+ verify(mMockNetd).interfaceSetCfg(argThat(
+ config -> Arrays.asList(config.flags).contains(IF_STATE_UP)));
}
@Test
diff --git a/tests/net/java/com/android/server/IpSecServiceRefcountedResourceTest.java b/tests/net/java/com/android/server/IpSecServiceRefcountedResourceTest.java
index 788e4efe097e..22a2c94fc194 100644
--- a/tests/net/java/com/android/server/IpSecServiceRefcountedResourceTest.java
+++ b/tests/net/java/com/android/server/IpSecServiceRefcountedResourceTest.java
@@ -31,7 +31,6 @@ import static org.mockito.Mockito.verify;
import android.content.Context;
import android.os.Binder;
import android.os.IBinder;
-import android.os.INetworkManagementService;
import android.os.RemoteException;
import androidx.test.filters.SmallTest;
@@ -62,8 +61,7 @@ public class IpSecServiceRefcountedResourceTest {
public void setUp() throws Exception {
mMockContext = mock(Context.class);
mMockIpSecSrvConfig = mock(IpSecService.IpSecServiceConfiguration.class);
- mIpSecService = new IpSecService(
- mMockContext, mock(INetworkManagementService.class), mMockIpSecSrvConfig);
+ mIpSecService = new IpSecService(mMockContext, mMockIpSecSrvConfig);
}
private void assertResourceState(
diff --git a/tests/net/java/com/android/server/IpSecServiceTest.java b/tests/net/java/com/android/server/IpSecServiceTest.java
index 536e98327e1f..f97eabf6366d 100644
--- a/tests/net/java/com/android/server/IpSecServiceTest.java
+++ b/tests/net/java/com/android/server/IpSecServiceTest.java
@@ -42,7 +42,6 @@ import android.net.IpSecManager;
import android.net.IpSecSpiResponse;
import android.net.IpSecUdpEncapResponse;
import android.os.Binder;
-import android.os.INetworkManagementService;
import android.os.ParcelFileDescriptor;
import android.os.Process;
import android.system.ErrnoException;
@@ -116,7 +115,6 @@ public class IpSecServiceTest {
}
Context mMockContext;
- INetworkManagementService mMockNetworkManager;
INetd mMockNetd;
IpSecService.IpSecServiceConfiguration mMockIpSecSrvConfig;
IpSecService mIpSecService;
@@ -124,10 +122,9 @@ public class IpSecServiceTest {
@Before
public void setUp() throws Exception {
mMockContext = mock(Context.class);
- mMockNetworkManager = mock(INetworkManagementService.class);
mMockNetd = mock(INetd.class);
mMockIpSecSrvConfig = mock(IpSecService.IpSecServiceConfiguration.class);
- mIpSecService = new IpSecService(mMockContext, mMockNetworkManager, mMockIpSecSrvConfig);
+ mIpSecService = new IpSecService(mMockContext, mMockIpSecSrvConfig);
// Injecting mock netd
when(mMockIpSecSrvConfig.getNetdInstance()).thenReturn(mMockNetd);
@@ -135,7 +132,7 @@ public class IpSecServiceTest {
@Test
public void testIpSecServiceCreate() throws InterruptedException {
- IpSecService ipSecSrv = IpSecService.create(mMockContext, mMockNetworkManager);
+ IpSecService ipSecSrv = IpSecService.create(mMockContext);
assertNotNull(ipSecSrv);
}
@@ -608,7 +605,7 @@ public class IpSecServiceTest {
public void testOpenUdpEncapSocketTagsSocket() throws Exception {
IpSecService.UidFdTagger mockTagger = mock(IpSecService.UidFdTagger.class);
IpSecService testIpSecService = new IpSecService(
- mMockContext, mMockNetworkManager, mMockIpSecSrvConfig, mockTagger);
+ mMockContext, mMockIpSecSrvConfig, mockTagger);
IpSecUdpEncapResponse udpEncapResp =
testIpSecService.openUdpEncapsulationSocket(0, new Binder());
diff --git a/tests/net/java/com/android/server/connectivity/DnsManagerTest.java b/tests/net/java/com/android/server/connectivity/DnsManagerTest.java
index f5b85ca06f92..5760211d9a27 100644
--- a/tests/net/java/com/android/server/connectivity/DnsManagerTest.java
+++ b/tests/net/java/com/android/server/connectivity/DnsManagerTest.java
@@ -22,6 +22,8 @@ import static android.net.NetworkCapabilities.MAX_TRANSPORT;
import static android.net.NetworkCapabilities.MIN_TRANSPORT;
import static android.net.NetworkCapabilities.TRANSPORT_VPN;
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
+import static android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener.VALIDATION_RESULT_FAILURE;
+import static android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener.VALIDATION_RESULT_SUCCESS;
import static android.provider.Settings.Global.PRIVATE_DNS_DEFAULT_MODE;
import static android.provider.Settings.Global.PRIVATE_DNS_MODE;
import static android.provider.Settings.Global.PRIVATE_DNS_SPECIFIER;
@@ -164,7 +166,8 @@ public class DnsManagerTest {
mDnsManager.flushVmDnsCache();
mDnsManager.updatePrivateDnsValidation(
new DnsManager.PrivateDnsValidationUpdate(TEST_NETID_ALTERNATE,
- InetAddress.parseNumericAddress("4.4.4.4"), "", true));
+ InetAddress.parseNumericAddress("4.4.4.4"), "",
+ VALIDATION_RESULT_SUCCESS));
LinkProperties fixedLp = new LinkProperties(lp);
mDnsManager.updatePrivateDnsStatus(TEST_NETID, fixedLp);
assertFalse(fixedLp.isPrivateDnsActive());
@@ -204,7 +207,8 @@ public class DnsManagerTest {
// Validate one.
mDnsManager.updatePrivateDnsValidation(
new DnsManager.PrivateDnsValidationUpdate(TEST_NETID,
- InetAddress.parseNumericAddress("6.6.6.6"), "strictmode.com", true));
+ InetAddress.parseNumericAddress("6.6.6.6"), "strictmode.com",
+ VALIDATION_RESULT_SUCCESS));
fixedLp = new LinkProperties(lp);
mDnsManager.updatePrivateDnsStatus(TEST_NETID, fixedLp);
assertEquals(Arrays.asList(InetAddress.parseNumericAddress("6.6.6.6")),
@@ -212,7 +216,8 @@ public class DnsManagerTest {
// Validate the 2nd one.
mDnsManager.updatePrivateDnsValidation(
new DnsManager.PrivateDnsValidationUpdate(TEST_NETID,
- InetAddress.parseNumericAddress("2001:db8:66:66::1"), "strictmode.com", true));
+ InetAddress.parseNumericAddress("2001:db8:66:66::1"), "strictmode.com",
+ VALIDATION_RESULT_SUCCESS));
fixedLp = new LinkProperties(lp);
mDnsManager.updatePrivateDnsStatus(TEST_NETID, fixedLp);
assertEquals(Arrays.asList(
@@ -232,7 +237,8 @@ public class DnsManagerTest {
mDnsManager.flushVmDnsCache();
mDnsManager.updatePrivateDnsValidation(
new DnsManager.PrivateDnsValidationUpdate(TEST_NETID,
- InetAddress.parseNumericAddress("3.3.3.3"), "", true));
+ InetAddress.parseNumericAddress("3.3.3.3"), "",
+ VALIDATION_RESULT_SUCCESS));
mDnsManager.updatePrivateDnsStatus(TEST_NETID, lp);
assertFalse(lp.isPrivateDnsActive());
assertNull(lp.getPrivateDnsServerName());
@@ -245,7 +251,8 @@ public class DnsManagerTest {
mDnsManager.flushVmDnsCache();
mDnsManager.updatePrivateDnsValidation(
new DnsManager.PrivateDnsValidationUpdate(TEST_NETID_UNTRACKED,
- InetAddress.parseNumericAddress("3.3.3.3"), "", true));
+ InetAddress.parseNumericAddress("3.3.3.3"), "",
+ VALIDATION_RESULT_SUCCESS));
mDnsManager.updatePrivateDnsStatus(TEST_NETID, lp);
assertFalse(lp.isPrivateDnsActive());
assertNull(lp.getPrivateDnsServerName());
@@ -253,7 +260,8 @@ public class DnsManagerTest {
// Validation event has untracked ipAddress
mDnsManager.updatePrivateDnsValidation(
new DnsManager.PrivateDnsValidationUpdate(TEST_NETID,
- InetAddress.parseNumericAddress("4.4.4.4"), "", true));
+ InetAddress.parseNumericAddress("4.4.4.4"), "",
+ VALIDATION_RESULT_SUCCESS));
mDnsManager.updatePrivateDnsStatus(TEST_NETID, lp);
assertFalse(lp.isPrivateDnsActive());
assertNull(lp.getPrivateDnsServerName());
@@ -261,8 +269,8 @@ public class DnsManagerTest {
// Validation event has untracked hostname
mDnsManager.updatePrivateDnsValidation(
new DnsManager.PrivateDnsValidationUpdate(TEST_NETID,
- InetAddress.parseNumericAddress("3.3.3.3"), "hostname",
- true));
+ InetAddress.parseNumericAddress("3.3.3.3"), "hostname",
+ VALIDATION_RESULT_SUCCESS));
mDnsManager.updatePrivateDnsStatus(TEST_NETID, lp);
assertFalse(lp.isPrivateDnsActive());
assertNull(lp.getPrivateDnsServerName());
@@ -270,7 +278,8 @@ public class DnsManagerTest {
// Validation event failed
mDnsManager.updatePrivateDnsValidation(
new DnsManager.PrivateDnsValidationUpdate(TEST_NETID,
- InetAddress.parseNumericAddress("3.3.3.3"), "", false));
+ InetAddress.parseNumericAddress("3.3.3.3"), "",
+ VALIDATION_RESULT_FAILURE));
mDnsManager.updatePrivateDnsStatus(TEST_NETID, lp);
assertFalse(lp.isPrivateDnsActive());
assertNull(lp.getPrivateDnsServerName());
@@ -279,7 +288,7 @@ public class DnsManagerTest {
mDnsManager.removeNetwork(new Network(TEST_NETID));
mDnsManager.updatePrivateDnsValidation(
new DnsManager.PrivateDnsValidationUpdate(TEST_NETID,
- InetAddress.parseNumericAddress("3.3.3.3"), "", true));
+ InetAddress.parseNumericAddress("3.3.3.3"), "", VALIDATION_RESULT_SUCCESS));
mDnsManager.updatePrivateDnsStatus(TEST_NETID, lp);
assertFalse(lp.isPrivateDnsActive());
assertNull(lp.getPrivateDnsServerName());
@@ -293,7 +302,8 @@ public class DnsManagerTest {
mDnsManager.flushVmDnsCache();
mDnsManager.updatePrivateDnsValidation(
new DnsManager.PrivateDnsValidationUpdate(TEST_NETID,
- InetAddress.parseNumericAddress("3.3.3.3"), "", true));
+ InetAddress.parseNumericAddress("3.3.3.3"), "",
+ VALIDATION_RESULT_SUCCESS));
mDnsManager.updatePrivateDnsStatus(TEST_NETID, lp);
assertFalse(lp.isPrivateDnsActive());
assertNull(lp.getPrivateDnsServerName());
@@ -398,7 +408,8 @@ public class DnsManagerTest {
mDnsManager.updatePrivateDns(network, mDnsManager.getPrivateDnsConfig());
mDnsManager.noteDnsServersForNetwork(TEST_NETID, lp);
mDnsManager.updatePrivateDnsValidation(
- new DnsManager.PrivateDnsValidationUpdate(TEST_NETID, dnsAddr, "", true));
+ new DnsManager.PrivateDnsValidationUpdate(TEST_NETID, dnsAddr, "",
+ VALIDATION_RESULT_SUCCESS));
mDnsManager.updatePrivateDnsStatus(TEST_NETID, lp);
privateDnsCfg = mDnsManager.getPrivateDnsConfig(network);
assertTrue(privateDnsCfg.useTls);
diff --git a/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java b/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java
index 52cb836e19c8..a913673c2a1e 100644
--- a/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java
+++ b/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java
@@ -41,7 +41,6 @@ import android.net.NetworkCapabilities;
import android.net.NetworkInfo;
import android.net.NetworkProvider;
import android.os.Binder;
-import android.os.INetworkManagementService;
import android.text.format.DateUtils;
import androidx.test.filters.SmallTest;
@@ -74,7 +73,6 @@ public class LingerMonitorTest {
@Mock ConnectivityService mConnService;
@Mock IDnsResolver mDnsResolver;
@Mock INetd mNetd;
- @Mock INetworkManagementService mNMS;
@Mock Context mCtx;
@Mock NetworkNotificationManager mNotifier;
@Mock Resources mResources;
@@ -358,8 +356,8 @@ public class LingerMonitorTest {
caps.addTransportType(transport);
NetworkAgentInfo nai = new NetworkAgentInfo(null, new Network(netId), info,
new LinkProperties(), caps, 50, mCtx, null, new NetworkAgentConfig() /* config */,
- mConnService, mNetd, mDnsResolver, mNMS, NetworkProvider.ID_NONE,
- Binder.getCallingUid(), mQosCallbackTracker);
+ mConnService, mNetd, mDnsResolver, NetworkProvider.ID_NONE, Binder.getCallingUid(),
+ mQosCallbackTracker);
nai.everValidated = true;
return nai;
}
diff --git a/tests/net/java/com/android/server/connectivity/Nat464XlatTest.java b/tests/net/java/com/android/server/connectivity/Nat464XlatTest.java
index 4f65b67fa3da..5f56e25356c2 100644
--- a/tests/net/java/com/android/server/connectivity/Nat464XlatTest.java
+++ b/tests/net/java/com/android/server/connectivity/Nat464XlatTest.java
@@ -36,7 +36,6 @@ import android.net.LinkProperties;
import android.net.NetworkAgentConfig;
import android.net.NetworkInfo;
import android.os.Handler;
-import android.os.INetworkManagementService;
import android.os.test.TestLooper;
import androidx.test.filters.SmallTest;
@@ -67,7 +66,6 @@ public class Nat464XlatTest {
@Mock ConnectivityService mConnectivity;
@Mock IDnsResolver mDnsResolver;
@Mock INetd mNetd;
- @Mock INetworkManagementService mNms;
@Mock NetworkAgentInfo mNai;
TestLooper mLooper;
@@ -75,7 +73,7 @@ public class Nat464XlatTest {
NetworkAgentConfig mAgentConfig = new NetworkAgentConfig();
Nat464Xlat makeNat464Xlat() {
- return new Nat464Xlat(mNai, mNetd, mDnsResolver, mNms) {
+ return new Nat464Xlat(mNai, mNetd, mDnsResolver) {
@Override protected int getNetId() {
return NETID;
}
@@ -206,7 +204,6 @@ public class Nat464XlatTest {
// Start clat.
nat.start();
- verify(mNms).registerObserver(eq(nat));
verify(mNetd).clatdStart(eq(BASE_IFACE), eq(NAT64_PREFIX));
// Stacked interface up notification arrives.
@@ -225,7 +222,6 @@ public class Nat464XlatTest {
verify(mNetd).clatdStop(eq(BASE_IFACE));
verify(mConnectivity, times(2)).handleUpdateLinkProperties(eq(mNai), c.capture());
- verify(mNms).unregisterObserver(eq(nat));
assertTrue(c.getValue().getStackedLinks().isEmpty());
assertFalse(c.getValue().getAllInterfaceNames().contains(STACKED_IFACE));
verify(mDnsResolver).stopPrefix64Discovery(eq(NETID));
@@ -235,7 +231,7 @@ public class Nat464XlatTest {
nat.interfaceRemoved(STACKED_IFACE);
mLooper.dispatchNext();
- verifyNoMoreInteractions(mNetd, mNms, mConnectivity);
+ verifyNoMoreInteractions(mNetd, mConnectivity);
}
@Test
@@ -346,7 +342,6 @@ public class Nat464XlatTest {
nat.start();
- verify(mNms).registerObserver(eq(nat));
verify(mNetd).clatdStart(eq(BASE_IFACE), eq(NAT64_PREFIX));
// Stacked interface up notification arrives.
@@ -365,7 +360,6 @@ public class Nat464XlatTest {
verify(mNetd).clatdStop(eq(BASE_IFACE));
verify(mConnectivity, times(2)).handleUpdateLinkProperties(eq(mNai), c.capture());
- verify(mNms).unregisterObserver(eq(nat));
verify(mDnsResolver).stopPrefix64Discovery(eq(NETID));
assertTrue(c.getValue().getStackedLinks().isEmpty());
assertFalse(c.getValue().getAllInterfaceNames().contains(STACKED_IFACE));
@@ -374,7 +368,7 @@ public class Nat464XlatTest {
// ConnectivityService stops clat: no-op.
nat.stop();
- verifyNoMoreInteractions(mNetd, mNms, mConnectivity);
+ verifyNoMoreInteractions(mNetd, mConnectivity);
}
private void checkStopBeforeClatdStarts(boolean dueToDisconnect) throws Exception {
@@ -386,7 +380,6 @@ public class Nat464XlatTest {
nat.start();
- verify(mNms).registerObserver(eq(nat));
verify(mNetd).clatdStart(eq(BASE_IFACE), eq(NAT64_PREFIX));
// ConnectivityService immediately stops clat (Network disconnects, IPv4 addr appears, ...)
@@ -394,7 +387,6 @@ public class Nat464XlatTest {
nat.stop();
verify(mNetd).clatdStop(eq(BASE_IFACE));
- verify(mNms).unregisterObserver(eq(nat));
verify(mDnsResolver).stopPrefix64Discovery(eq(NETID));
assertIdle(nat);
@@ -408,7 +400,7 @@ public class Nat464XlatTest {
assertIdle(nat);
- verifyNoMoreInteractions(mNetd, mNms, mConnectivity);
+ verifyNoMoreInteractions(mNetd, mConnectivity);
}
@Test
@@ -430,7 +422,6 @@ public class Nat464XlatTest {
nat.start();
- verify(mNms).registerObserver(eq(nat));
verify(mNetd).clatdStart(eq(BASE_IFACE), eq(NAT64_PREFIX));
// ConnectivityService immediately stops clat (Network disconnects, IPv4 addr appears, ...)
@@ -438,11 +429,10 @@ public class Nat464XlatTest {
nat.stop();
verify(mNetd).clatdStop(eq(BASE_IFACE));
- verify(mNms).unregisterObserver(eq(nat));
verify(mDnsResolver).stopPrefix64Discovery(eq(NETID));
assertIdle(nat);
- verifyNoMoreInteractions(mNetd, mNms, mConnectivity);
+ verifyNoMoreInteractions(mNetd, mConnectivity);
}
@Test
diff --git a/tests/net/java/com/android/server/connectivity/NetworkNotificationManagerTest.java b/tests/net/java/com/android/server/connectivity/NetworkNotificationManagerTest.java
index 697dbc48880c..ff8c632833f2 100644
--- a/tests/net/java/com/android/server/connectivity/NetworkNotificationManagerTest.java
+++ b/tests/net/java/com/android/server/connectivity/NetworkNotificationManagerTest.java
@@ -49,6 +49,7 @@ import com.android.server.connectivity.NetworkNotificationManager.NotificationTy
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
+import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.AdditionalAnswers;
@@ -183,6 +184,9 @@ public class NetworkNotificationManagerTest {
}
@Test
+ @Ignore
+ // Ignored because the code under test calls Log.wtf, which crashes the tests on eng builds.
+ // TODO: re-enable after fixing this (e.g., turn Log.wtf into exceptions that this test catches)
public void testNoInternetNotificationsNotShownForCellular() {
mManager.showNotification(100, NO_INTERNET, mCellNai, mWifiNai, null, false);
mManager.showNotification(101, LOST_INTERNET, mCellNai, mWifiNai, null, false);
diff --git a/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java b/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java
index 8f5ae97bc4c5..e4e24b464838 100644
--- a/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java
+++ b/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java
@@ -61,6 +61,7 @@ import android.content.pm.PackageManagerInternal;
import android.net.INetd;
import android.net.UidRange;
import android.os.Build;
+import android.os.SystemConfigManager;
import android.os.UserHandle;
import android.os.UserManager;
import android.util.SparseIntArray;
@@ -114,6 +115,7 @@ public class PermissionMonitorTest {
@Mock private PackageManagerInternal mMockPmi;
@Mock private UserManager mUserManager;
@Mock private PermissionMonitor.Dependencies mDeps;
+ @Mock private SystemConfigManager mSystemConfigManager;
private PermissionMonitor mPermissionMonitor;
@@ -124,6 +126,11 @@ public class PermissionMonitorTest {
when(mContext.getSystemService(eq(Context.USER_SERVICE))).thenReturn(mUserManager);
when(mUserManager.getUserHandles(eq(true))).thenReturn(
Arrays.asList(new UserHandle[] { MOCK_USER1, MOCK_USER2 }));
+ when(mContext.getSystemServiceName(SystemConfigManager.class))
+ .thenReturn(Context.SYSTEM_CONFIG_SERVICE);
+ when(mContext.getSystemService(Context.SYSTEM_CONFIG_SERVICE))
+ .thenReturn(mSystemConfigManager);
+ when(mSystemConfigManager.getSystemPermissionUids(anyString())).thenReturn(new int[0]);
mPermissionMonitor = spy(new PermissionMonitor(mContext, mNetdService, mDeps));
@@ -747,4 +754,20 @@ public class PermissionMonitorTest {
GET_PERMISSIONS | MATCH_ANY_USER);
assertTrue(monitor.hasPermission(systemInfo, CONNECTIVITY_USE_RESTRICTED_NETWORKS));
}
+
+ @Test
+ public void testUpdateUidPermissionsFromSystemConfig() throws Exception {
+ final NetdServiceMonitor mNetdServiceMonitor = new NetdServiceMonitor(mNetdService);
+ when(mPackageManager.getInstalledPackages(anyInt())).thenReturn(new ArrayList<>());
+ when(mSystemConfigManager.getSystemPermissionUids(eq(INTERNET)))
+ .thenReturn(new int[]{ MOCK_UID1, MOCK_UID2 });
+ when(mSystemConfigManager.getSystemPermissionUids(eq(UPDATE_DEVICE_STATS)))
+ .thenReturn(new int[]{ MOCK_UID2 });
+
+ mPermissionMonitor.startMonitoring();
+ mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET, new int[]{ MOCK_UID1 });
+ mNetdServiceMonitor.expectPermission(
+ INetd.PERMISSION_INTERNET | INetd.PERMISSION_UPDATE_DEVICE_STATS,
+ new int[]{ MOCK_UID2 });
+ }
}
diff --git a/tests/net/java/com/android/server/connectivity/VpnTest.java b/tests/net/java/com/android/server/connectivity/VpnTest.java
index cffd2d1d428f..b8f7fbca3983 100644
--- a/tests/net/java/com/android/server/connectivity/VpnTest.java
+++ b/tests/net/java/com/android/server/connectivity/VpnTest.java
@@ -21,6 +21,8 @@ import static android.content.pm.UserInfo.FLAG_MANAGED_PROFILE;
import static android.content.pm.UserInfo.FLAG_PRIMARY;
import static android.content.pm.UserInfo.FLAG_RESTRICTED;
import static android.net.ConnectivityManager.NetworkCallback;
+import static android.net.INetd.IF_STATE_DOWN;
+import static android.net.INetd.IF_STATE_UP;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
@@ -62,6 +64,7 @@ import android.net.ConnectivityManager;
import android.net.INetd;
import android.net.Ikev2VpnProfile;
import android.net.InetAddresses;
+import android.net.InterfaceConfigurationParcel;
import android.net.IpPrefix;
import android.net.IpSecManager;
import android.net.IpSecTunnelInterfaceResponse;
@@ -88,7 +91,6 @@ import android.os.UserManager;
import android.os.test.TestLooper;
import android.provider.Settings;
import android.security.Credentials;
-import android.security.KeyStore;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Range;
@@ -179,7 +181,8 @@ public class VpnTest {
mPackages.put(PKGS[i], PKG_UIDS[i]);
}
}
- private static final UidRange PRI_USER_RANGE = UidRange.createForUser(primaryUser.id);
+ private static final UidRange PRI_USER_RANGE =
+ UidRange.createForUser(UserHandle.of(primaryUser.id));
@Mock(answer = Answers.RETURNS_DEEP_STUBS) private Context mContext;
@Mock private UserManager mUserManager;
@@ -192,7 +195,7 @@ public class VpnTest {
@Mock private Vpn.Ikev2SessionCreator mIkev2SessionCreator;
@Mock private ConnectivityManager mConnectivityManager;
@Mock private IpSecService mIpSecService;
- @Mock private KeyStore mKeyStore;
+ @Mock private VpnProfileStore mVpnProfileStore;
private final VpnProfile mVpnProfile;
private IpSecManager mIpSecManager;
@@ -269,7 +272,7 @@ public class VpnTest {
vpn.createUserAndRestrictedProfilesRanges(primaryUser.id, null, null);
assertEquals(new ArraySet<>(Arrays.asList(new UidRange[] {
- PRI_USER_RANGE, UidRange.createForUser(restrictedProfileA.id)
+ PRI_USER_RANGE, UidRange.createForUser(UserHandle.of(restrictedProfileA.id))
})), ranges);
}
@@ -329,17 +332,17 @@ public class VpnTest {
assertFalse(vpn.getLockdown());
// Set always-on without lockdown.
- assertTrue(vpn.setAlwaysOnPackage(PKGS[1], false, Collections.emptyList(), mKeyStore));
+ assertTrue(vpn.setAlwaysOnPackage(PKGS[1], false, Collections.emptyList()));
assertTrue(vpn.getAlwaysOn());
assertFalse(vpn.getLockdown());
// Set always-on with lockdown.
- assertTrue(vpn.setAlwaysOnPackage(PKGS[1], true, Collections.emptyList(), mKeyStore));
+ assertTrue(vpn.setAlwaysOnPackage(PKGS[1], true, Collections.emptyList()));
assertTrue(vpn.getAlwaysOn());
assertTrue(vpn.getLockdown());
// Remove always-on configuration.
- assertTrue(vpn.setAlwaysOnPackage(null, false, Collections.emptyList(), mKeyStore));
+ assertTrue(vpn.setAlwaysOnPackage(null, false, Collections.emptyList()));
assertFalse(vpn.getAlwaysOn());
assertFalse(vpn.getLockdown());
}
@@ -350,17 +353,17 @@ public class VpnTest {
final UidRange user = PRI_USER_RANGE;
// Set always-on without lockdown.
- assertTrue(vpn.setAlwaysOnPackage(PKGS[1], false, null, mKeyStore));
+ assertTrue(vpn.setAlwaysOnPackage(PKGS[1], false, null));
// Set always-on with lockdown.
- assertTrue(vpn.setAlwaysOnPackage(PKGS[1], true, null, mKeyStore));
+ assertTrue(vpn.setAlwaysOnPackage(PKGS[1], true, null));
verify(mConnectivityManager).setRequireVpnForUids(true, toRanges(new UidRangeParcel[] {
new UidRangeParcel(user.start, user.start + PKG_UIDS[1] - 1),
new UidRangeParcel(user.start + PKG_UIDS[1] + 1, user.stop)
}));
// Switch to another app.
- assertTrue(vpn.setAlwaysOnPackage(PKGS[3], true, null, mKeyStore));
+ assertTrue(vpn.setAlwaysOnPackage(PKGS[3], true, null));
verify(mConnectivityManager).setRequireVpnForUids(false, toRanges(new UidRangeParcel[] {
new UidRangeParcel(user.start, user.start + PKG_UIDS[1] - 1),
new UidRangeParcel(user.start + PKG_UIDS[1] + 1, user.stop)
@@ -378,14 +381,14 @@ public class VpnTest {
// Set always-on with lockdown and allow app PKGS[2] from lockdown.
assertTrue(vpn.setAlwaysOnPackage(
- PKGS[1], true, Collections.singletonList(PKGS[2]), mKeyStore));
+ PKGS[1], true, Collections.singletonList(PKGS[2])));
verify(mConnectivityManager).setRequireVpnForUids(true, toRanges(new UidRangeParcel[] {
new UidRangeParcel(user.start, user.start + PKG_UIDS[1] - 1),
new UidRangeParcel(user.start + PKG_UIDS[2] + 1, user.stop)
}));
// Change allowed app list to PKGS[3].
assertTrue(vpn.setAlwaysOnPackage(
- PKGS[1], true, Collections.singletonList(PKGS[3]), mKeyStore));
+ PKGS[1], true, Collections.singletonList(PKGS[3])));
verify(mConnectivityManager).setRequireVpnForUids(false, toRanges(new UidRangeParcel[] {
new UidRangeParcel(user.start + PKG_UIDS[2] + 1, user.stop)
}));
@@ -396,7 +399,7 @@ public class VpnTest {
// Change the VPN app.
assertTrue(vpn.setAlwaysOnPackage(
- PKGS[0], true, Collections.singletonList(PKGS[3]), mKeyStore));
+ PKGS[0], true, Collections.singletonList(PKGS[3])));
verify(mConnectivityManager).setRequireVpnForUids(false, toRanges(new UidRangeParcel[] {
new UidRangeParcel(user.start, user.start + PKG_UIDS[1] - 1),
new UidRangeParcel(user.start + PKG_UIDS[1] + 1, user.start + PKG_UIDS[3] - 1)
@@ -407,7 +410,7 @@ public class VpnTest {
}));
// Remove the list of allowed packages.
- assertTrue(vpn.setAlwaysOnPackage(PKGS[0], true, null, mKeyStore));
+ assertTrue(vpn.setAlwaysOnPackage(PKGS[0], true, null));
verify(mConnectivityManager).setRequireVpnForUids(false, toRanges(new UidRangeParcel[] {
new UidRangeParcel(user.start + PKG_UIDS[0] + 1, user.start + PKG_UIDS[3] - 1),
new UidRangeParcel(user.start + PKG_UIDS[3] + 1, user.stop)
@@ -418,7 +421,7 @@ public class VpnTest {
// Add the list of allowed packages.
assertTrue(vpn.setAlwaysOnPackage(
- PKGS[0], true, Collections.singletonList(PKGS[1]), mKeyStore));
+ PKGS[0], true, Collections.singletonList(PKGS[1])));
verify(mConnectivityManager).setRequireVpnForUids(false, toRanges(new UidRangeParcel[] {
new UidRangeParcel(user.start + PKG_UIDS[0] + 1, user.stop)
}));
@@ -429,12 +432,12 @@ public class VpnTest {
// Try allowing a package with a comma, should be rejected.
assertFalse(vpn.setAlwaysOnPackage(
- PKGS[0], true, Collections.singletonList("a.b,c.d"), mKeyStore));
+ PKGS[0], true, Collections.singletonList("a.b,c.d")));
// Pass a non-existent packages in the allowlist, they (and only they) should be ignored.
// allowed package should change from PGKS[1] to PKGS[2].
assertTrue(vpn.setAlwaysOnPackage(
- PKGS[0], true, Arrays.asList("com.foo.app", PKGS[2], "com.bar.app"), mKeyStore));
+ PKGS[0], true, Arrays.asList("com.foo.app", PKGS[2], "com.bar.app")));
verify(mConnectivityManager).setRequireVpnForUids(false, toRanges(new UidRangeParcel[] {
new UidRangeParcel(user.start + PKG_UIDS[0] + 1, user.start + PKG_UIDS[1] - 1),
new UidRangeParcel(user.start + PKG_UIDS[1] + 1, user.stop)
@@ -521,22 +524,22 @@ public class VpnTest {
.thenReturn(Collections.singletonList(resInfo));
// null package name should return false
- assertFalse(vpn.isAlwaysOnPackageSupported(null, mKeyStore));
+ assertFalse(vpn.isAlwaysOnPackageSupported(null));
// Pre-N apps are not supported
appInfo.targetSdkVersion = VERSION_CODES.M;
- assertFalse(vpn.isAlwaysOnPackageSupported(PKGS[0], mKeyStore));
+ assertFalse(vpn.isAlwaysOnPackageSupported(PKGS[0]));
// N+ apps are supported by default
appInfo.targetSdkVersion = VERSION_CODES.N;
- assertTrue(vpn.isAlwaysOnPackageSupported(PKGS[0], mKeyStore));
+ assertTrue(vpn.isAlwaysOnPackageSupported(PKGS[0]));
// Apps that opt out explicitly are not supported
appInfo.targetSdkVersion = VERSION_CODES.CUR_DEVELOPMENT;
Bundle metaData = new Bundle();
metaData.putBoolean(VpnService.SERVICE_META_DATA_SUPPORTS_ALWAYS_ON, false);
svcInfo.metaData = metaData;
- assertFalse(vpn.isAlwaysOnPackageSupported(PKGS[0], mKeyStore));
+ assertFalse(vpn.isAlwaysOnPackageSupported(PKGS[0]));
}
@Test
@@ -552,7 +555,7 @@ public class VpnTest {
order.verify(mNotificationManager, atLeastOnce()).cancel(anyString(), anyInt());
// Start showing a notification for disconnected once always-on.
- vpn.setAlwaysOnPackage(PKGS[0], false, null, mKeyStore);
+ vpn.setAlwaysOnPackage(PKGS[0], false, null);
order.verify(mNotificationManager).notify(anyString(), anyInt(), any());
// Stop showing the notification once connected.
@@ -564,7 +567,7 @@ public class VpnTest {
order.verify(mNotificationManager).notify(anyString(), anyInt(), any());
// Notification should be cleared after unsetting always-on package.
- vpn.setAlwaysOnPackage(null, false, null, mKeyStore);
+ vpn.setAlwaysOnPackage(null, false, null);
order.verify(mNotificationManager).cancel(anyString(), anyInt());
}
@@ -604,15 +607,13 @@ public class VpnTest {
}
private void checkProvisionVpnProfile(Vpn vpn, boolean expectedResult, String... checkedOps) {
- assertEquals(expectedResult, vpn.provisionVpnProfile(TEST_VPN_PKG, mVpnProfile, mKeyStore));
+ assertEquals(expectedResult, vpn.provisionVpnProfile(TEST_VPN_PKG, mVpnProfile));
// The profile should always be stored, whether or not consent has been previously granted.
- verify(mKeyStore)
+ verify(mVpnProfileStore)
.put(
eq(vpn.getProfileNameForPackage(TEST_VPN_PKG)),
- eq(mVpnProfile.encode()),
- eq(Process.SYSTEM_UID),
- eq(0));
+ eq(mVpnProfile.encode()));
for (final String checkedOpStr : checkedOps) {
verify(mAppOps).noteOpNoThrow(checkedOpStr, Process.myUid(), TEST_VPN_PKG,
@@ -667,7 +668,7 @@ public class VpnTest {
bigProfile.name = new String(new byte[Vpn.MAX_VPN_PROFILE_SIZE_BYTES + 1]);
try {
- vpn.provisionVpnProfile(TEST_VPN_PKG, bigProfile, mKeyStore);
+ vpn.provisionVpnProfile(TEST_VPN_PKG, bigProfile);
fail("Expected IAE due to profile size");
} catch (IllegalArgumentException expected) {
}
@@ -680,7 +681,7 @@ public class VpnTest {
restrictedProfileA, AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN);
try {
- vpn.provisionVpnProfile(TEST_VPN_PKG, mVpnProfile, mKeyStore);
+ vpn.provisionVpnProfile(TEST_VPN_PKG, mVpnProfile);
fail("Expected SecurityException due to restricted user");
} catch (SecurityException expected) {
}
@@ -690,10 +691,10 @@ public class VpnTest {
public void testDeleteVpnProfile() throws Exception {
final Vpn vpn = createVpnAndSetupUidChecks();
- vpn.deleteVpnProfile(TEST_VPN_PKG, mKeyStore);
+ vpn.deleteVpnProfile(TEST_VPN_PKG);
- verify(mKeyStore)
- .delete(eq(vpn.getProfileNameForPackage(TEST_VPN_PKG)), eq(Process.SYSTEM_UID));
+ verify(mVpnProfileStore)
+ .remove(eq(vpn.getProfileNameForPackage(TEST_VPN_PKG)));
}
@Test
@@ -703,7 +704,7 @@ public class VpnTest {
restrictedProfileA, AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN);
try {
- vpn.deleteVpnProfile(TEST_VPN_PKG, mKeyStore);
+ vpn.deleteVpnProfile(TEST_VPN_PKG);
fail("Expected SecurityException due to restricted user");
} catch (SecurityException expected) {
}
@@ -713,24 +714,24 @@ public class VpnTest {
public void testGetVpnProfilePrivileged() throws Exception {
final Vpn vpn = createVpnAndSetupUidChecks();
- when(mKeyStore.get(vpn.getProfileNameForPackage(TEST_VPN_PKG)))
+ when(mVpnProfileStore.get(vpn.getProfileNameForPackage(TEST_VPN_PKG)))
.thenReturn(new VpnProfile("").encode());
- vpn.getVpnProfilePrivileged(TEST_VPN_PKG, mKeyStore);
+ vpn.getVpnProfilePrivileged(TEST_VPN_PKG);
- verify(mKeyStore).get(eq(vpn.getProfileNameForPackage(TEST_VPN_PKG)));
+ verify(mVpnProfileStore).get(eq(vpn.getProfileNameForPackage(TEST_VPN_PKG)));
}
@Test
public void testStartVpnProfile() throws Exception {
final Vpn vpn = createVpnAndSetupUidChecks(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN);
- when(mKeyStore.get(vpn.getProfileNameForPackage(TEST_VPN_PKG)))
+ when(mVpnProfileStore.get(vpn.getProfileNameForPackage(TEST_VPN_PKG)))
.thenReturn(mVpnProfile.encode());
- vpn.startVpnProfile(TEST_VPN_PKG, mKeyStore);
+ vpn.startVpnProfile(TEST_VPN_PKG);
- verify(mKeyStore).get(eq(vpn.getProfileNameForPackage(TEST_VPN_PKG)));
+ verify(mVpnProfileStore).get(eq(vpn.getProfileNameForPackage(TEST_VPN_PKG)));
verify(mAppOps)
.noteOpNoThrow(
eq(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN),
@@ -744,10 +745,10 @@ public class VpnTest {
public void testStartVpnProfileVpnServicePreconsented() throws Exception {
final Vpn vpn = createVpnAndSetupUidChecks(AppOpsManager.OPSTR_ACTIVATE_VPN);
- when(mKeyStore.get(vpn.getProfileNameForPackage(TEST_VPN_PKG)))
+ when(mVpnProfileStore.get(vpn.getProfileNameForPackage(TEST_VPN_PKG)))
.thenReturn(mVpnProfile.encode());
- vpn.startVpnProfile(TEST_VPN_PKG, mKeyStore);
+ vpn.startVpnProfile(TEST_VPN_PKG);
// Verify that the the ACTIVATE_VPN appop was checked, but no error was thrown.
verify(mAppOps).noteOpNoThrow(AppOpsManager.OPSTR_ACTIVATE_VPN, Process.myUid(),
@@ -759,7 +760,7 @@ public class VpnTest {
final Vpn vpn = createVpnAndSetupUidChecks();
try {
- vpn.startVpnProfile(TEST_VPN_PKG, mKeyStore);
+ vpn.startVpnProfile(TEST_VPN_PKG);
fail("Expected failure due to no user consent");
} catch (SecurityException expected) {
}
@@ -776,22 +777,22 @@ public class VpnTest {
TEST_VPN_PKG, null /* attributionTag */, null /* message */);
// Keystore should never have been accessed.
- verify(mKeyStore, never()).get(any());
+ verify(mVpnProfileStore, never()).get(any());
}
@Test
public void testStartVpnProfileMissingProfile() throws Exception {
final Vpn vpn = createVpnAndSetupUidChecks(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN);
- when(mKeyStore.get(vpn.getProfileNameForPackage(TEST_VPN_PKG))).thenReturn(null);
+ when(mVpnProfileStore.get(vpn.getProfileNameForPackage(TEST_VPN_PKG))).thenReturn(null);
try {
- vpn.startVpnProfile(TEST_VPN_PKG, mKeyStore);
+ vpn.startVpnProfile(TEST_VPN_PKG);
fail("Expected failure due to missing profile");
} catch (IllegalArgumentException expected) {
}
- verify(mKeyStore).get(vpn.getProfileNameForPackage(TEST_VPN_PKG));
+ verify(mVpnProfileStore).get(vpn.getProfileNameForPackage(TEST_VPN_PKG));
verify(mAppOps)
.noteOpNoThrow(
eq(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN),
@@ -808,7 +809,7 @@ public class VpnTest {
restrictedProfileA, AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN);
try {
- vpn.startVpnProfile(TEST_VPN_PKG, mKeyStore);
+ vpn.startVpnProfile(TEST_VPN_PKG);
fail("Expected SecurityException due to restricted user");
} catch (SecurityException expected) {
}
@@ -872,17 +873,28 @@ public class VpnTest {
eq(AppOpsManager.MODE_IGNORED));
}
- private NetworkCallback triggerOnAvailableAndGetCallback() {
+ private NetworkCallback triggerOnAvailableAndGetCallback() throws Exception {
final ArgumentCaptor<NetworkCallback> networkCallbackCaptor =
ArgumentCaptor.forClass(NetworkCallback.class);
verify(mConnectivityManager, timeout(TEST_TIMEOUT_MS))
.requestNetwork(any(), networkCallbackCaptor.capture());
+ // onAvailable() will trigger onDefaultNetworkChanged(), so NetdUtils#setInterfaceUp will be
+ // invoked. Set the return value of INetd#interfaceGetCfg to prevent NullPointerException.
+ final InterfaceConfigurationParcel config = new InterfaceConfigurationParcel();
+ config.flags = new String[] {IF_STATE_DOWN};
+ when(mNetd.interfaceGetCfg(anyString())).thenReturn(config);
final NetworkCallback cb = networkCallbackCaptor.getValue();
cb.onAvailable(TEST_NETWORK);
return cb;
}
+ private void verifyInterfaceSetCfgWithFlags(String flag) throws Exception {
+ // Add a timeout for waiting for interfaceSetCfg to be called.
+ verify(mNetd, timeout(TEST_TIMEOUT_MS)).interfaceSetCfg(argThat(
+ config -> Arrays.asList(config.flags).contains(flag)));
+ }
+
@Test
public void testStartPlatformVpnAuthenticationFailed() throws Exception {
final ArgumentCaptor<IkeSessionCallback> captor =
@@ -894,6 +906,8 @@ public class VpnTest {
final Vpn vpn = startLegacyVpn(createVpn(primaryUser.id), (mVpnProfile));
final NetworkCallback cb = triggerOnAvailableAndGetCallback();
+ verifyInterfaceSetCfgWithFlags(IF_STATE_UP);
+
// Wait for createIkeSession() to be called before proceeding in order to ensure consistent
// state
verify(mIkev2SessionCreator, timeout(TEST_TIMEOUT_MS))
@@ -912,6 +926,8 @@ public class VpnTest {
final Vpn vpn = startLegacyVpn(createVpn(primaryUser.id), mVpnProfile);
final NetworkCallback cb = triggerOnAvailableAndGetCallback();
+ verifyInterfaceSetCfgWithFlags(IF_STATE_UP);
+
// Wait for createIkeSession() to be called before proceeding in order to ensure consistent
// state
verify(mConnectivityManager, timeout(TEST_TIMEOUT_MS)).unregisterNetworkCallback(eq(cb));
@@ -919,9 +935,9 @@ public class VpnTest {
}
private void setAndVerifyAlwaysOnPackage(Vpn vpn, int uid, boolean lockdownEnabled) {
- assertTrue(vpn.setAlwaysOnPackage(TEST_VPN_PKG, lockdownEnabled, null, mKeyStore));
+ assertTrue(vpn.setAlwaysOnPackage(TEST_VPN_PKG, lockdownEnabled, null));
- verify(mKeyStore).get(eq(vpn.getProfileNameForPackage(TEST_VPN_PKG)));
+ verify(mVpnProfileStore).get(eq(vpn.getProfileNameForPackage(TEST_VPN_PKG)));
verify(mAppOps).setMode(
eq(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN), eq(uid), eq(TEST_VPN_PKG),
eq(AppOpsManager.MODE_ALLOWED));
@@ -944,11 +960,11 @@ public class VpnTest {
final int uid = Process.myUid() + 1;
when(mPackageManager.getPackageUidAsUser(eq(TEST_VPN_PKG), anyInt()))
.thenReturn(uid);
- when(mKeyStore.get(vpn.getProfileNameForPackage(TEST_VPN_PKG)))
+ when(mVpnProfileStore.get(vpn.getProfileNameForPackage(TEST_VPN_PKG)))
.thenReturn(mVpnProfile.encode());
setAndVerifyAlwaysOnPackage(vpn, uid, false);
- assertTrue(vpn.startAlwaysOnVpn(mKeyStore));
+ assertTrue(vpn.startAlwaysOnVpn());
// TODO: Test the Ikev2VpnRunner started up properly. Relies on utility methods added in
// a subsequent CL.
@@ -965,7 +981,7 @@ public class VpnTest {
InetAddresses.parseNumericAddress("192.0.2.0"), EGRESS_IFACE);
lp.addRoute(defaultRoute);
- vpn.startLegacyVpn(vpnProfile, mKeyStore, EGRESS_NETWORK, lp);
+ vpn.startLegacyVpn(vpnProfile, EGRESS_NETWORK, lp);
return vpn;
}
@@ -1167,7 +1183,7 @@ public class VpnTest {
.thenReturn(asUserContext);
final TestLooper testLooper = new TestLooper();
final Vpn vpn = new Vpn(testLooper.getLooper(), mContext, new TestDeps(), mNetService,
- mNetd, userId, mKeyStore, mSystemServices, mIkev2SessionCreator);
+ mNetd, userId, mVpnProfileStore, mSystemServices, mIkev2SessionCreator);
verify(mConnectivityManager, times(1)).registerNetworkProvider(argThat(
provider -> provider.getName().contains("VpnNetworkProvider")
));
diff --git a/tests/net/java/com/android/server/net/NetworkStatsCollectionTest.java b/tests/net/java/com/android/server/net/NetworkStatsCollectionTest.java
index 435c3c0af817..505ff9b6a34b 100644
--- a/tests/net/java/com/android/server/net/NetworkStatsCollectionTest.java
+++ b/tests/net/java/com/android/server/net/NetworkStatsCollectionTest.java
@@ -17,6 +17,7 @@
package com.android.server.net;
import static android.net.ConnectivityManager.TYPE_MOBILE;
+import static android.net.NetworkIdentity.OEM_NONE;
import static android.net.NetworkStats.SET_ALL;
import static android.net.NetworkStats.SET_DEFAULT;
import static android.net.NetworkStats.TAG_NONE;
@@ -213,7 +214,7 @@ public class NetworkStatsCollectionTest {
final NetworkStats.Entry entry = new NetworkStats.Entry();
final NetworkIdentitySet identSet = new NetworkIdentitySet();
identSet.add(new NetworkIdentity(TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_UNKNOWN,
- TEST_IMSI, null, false, true, true));
+ TEST_IMSI, null, false, true, true, OEM_NONE));
int myUid = Process.myUid();
int otherUidInSameUser = Process.myUid() + 1;
@@ -468,7 +469,7 @@ public class NetworkStatsCollectionTest {
final NetworkStatsCollection large = new NetworkStatsCollection(HOUR_IN_MILLIS);
final NetworkIdentitySet ident = new NetworkIdentitySet();
ident.add(new NetworkIdentity(ConnectivityManager.TYPE_MOBILE, -1, TEST_IMSI, null,
- false, true, true));
+ false, true, true, OEM_NONE));
large.recordData(ident, UID_ALL, SET_ALL, TAG_NONE, TIME_A, TIME_B,
new NetworkStats.Entry(12_730_893_164L, 1, 0, 0, 0));
diff --git a/tests/net/java/com/android/server/net/NetworkStatsObserversTest.java b/tests/net/java/com/android/server/net/NetworkStatsObserversTest.java
index 291efc74aa47..9fa1c50423d9 100644
--- a/tests/net/java/com/android/server/net/NetworkStatsObserversTest.java
+++ b/tests/net/java/com/android/server/net/NetworkStatsObserversTest.java
@@ -17,6 +17,7 @@
package com.android.server.net;
import static android.net.ConnectivityManager.TYPE_MOBILE;
+import static android.net.NetworkIdentity.OEM_NONE;
import static android.net.NetworkStats.DEFAULT_NETWORK_NO;
import static android.net.NetworkStats.DEFAULT_NETWORK_YES;
import static android.net.NetworkStats.METERED_NO;
@@ -220,7 +221,7 @@ public class NetworkStatsObserversTest {
identSet.add(new NetworkIdentity(
TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_UNKNOWN,
IMSI_1, null /* networkId */, false /* roaming */, true /* metered */,
- true /* defaultNetwork */));
+ true /* defaultNetwork */, OEM_NONE));
return identSet;
}
diff --git a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
index 214c82da17dc..9334e2c4ad77 100644
--- a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
+++ b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
@@ -19,8 +19,9 @@ package com.android.server.net;
import static android.content.Intent.ACTION_UID_REMOVED;
import static android.content.Intent.EXTRA_UID;
import static android.net.ConnectivityManager.TYPE_MOBILE;
-import static android.net.ConnectivityManager.TYPE_VPN;
import static android.net.ConnectivityManager.TYPE_WIFI;
+import static android.net.NetworkIdentity.OEM_PAID;
+import static android.net.NetworkIdentity.OEM_PRIVATE;
import static android.net.NetworkStats.DEFAULT_NETWORK_ALL;
import static android.net.NetworkStats.DEFAULT_NETWORK_NO;
import static android.net.NetworkStats.DEFAULT_NETWORK_YES;
@@ -40,7 +41,10 @@ import static android.net.NetworkStats.TAG_ALL;
import static android.net.NetworkStats.TAG_NONE;
import static android.net.NetworkStats.UID_ALL;
import static android.net.NetworkStatsHistory.FIELD_ALL;
+import static android.net.NetworkTemplate.MATCH_MOBILE_WILDCARD;
import static android.net.NetworkTemplate.NETWORK_TYPE_ALL;
+import static android.net.NetworkTemplate.OEM_MANAGED_NO;
+import static android.net.NetworkTemplate.OEM_MANAGED_YES;
import static android.net.NetworkTemplate.buildTemplateMobileAll;
import static android.net.NetworkTemplate.buildTemplateMobileWithRatType;
import static android.net.NetworkTemplate.buildTemplateWifi;
@@ -80,7 +84,7 @@ import android.net.INetworkStatsSession;
import android.net.LinkProperties;
import android.net.Network;
import android.net.NetworkCapabilities;
-import android.net.NetworkState;
+import android.net.NetworkStateSnapshot;
import android.net.NetworkStats;
import android.net.NetworkStatsHistory;
import android.net.NetworkTemplate;
@@ -280,7 +284,7 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
// pretend that wifi network comes online; service should ask about full
// network state, and poll any existing interfaces before updating.
expectDefaultSettings();
- NetworkState[] states = new NetworkState[] {buildWifiState()};
+ NetworkStateSnapshot[] states = new NetworkStateSnapshot[] {buildWifiState()};
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
@@ -323,7 +327,7 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
// pretend that wifi network comes online; service should ask about full
// network state, and poll any existing interfaces before updating.
expectDefaultSettings();
- NetworkState[] states = new NetworkState[] {buildWifiState()};
+ NetworkStateSnapshot[] states = new NetworkStateSnapshot[] {buildWifiState()};
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
@@ -397,7 +401,7 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
// pretend that wifi network comes online; service should ask about full
// network state, and poll any existing interfaces before updating.
expectSettings(0L, HOUR_IN_MILLIS, WEEK_IN_MILLIS);
- NetworkState[] states = new NetworkState[] {buildWifiState()};
+ NetworkStateSnapshot[] states = new NetworkStateSnapshot[] {buildWifiState()};
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
@@ -438,7 +442,7 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
public void testUidStatsAcrossNetworks() throws Exception {
// pretend first mobile network comes online
expectDefaultSettings();
- NetworkState[] states = new NetworkState[] {buildMobile3gState(IMSI_1)};
+ NetworkStateSnapshot[] states = new NetworkStateSnapshot[] {buildMobile3gState(IMSI_1)};
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
@@ -469,7 +473,7 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
// disappearing, to verify we don't count backwards.
incrementCurrentTime(HOUR_IN_MILLIS);
expectDefaultSettings();
- states = new NetworkState[] {buildMobile3gState(IMSI_2)};
+ states = new NetworkStateSnapshot[] {buildMobile3gState(IMSI_2)};
expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
.insertEntry(TEST_IFACE, 2048L, 16L, 512L, 4L));
expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 3)
@@ -513,7 +517,7 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
public void testUidRemovedIsMoved() throws Exception {
// pretend that network comes online
expectDefaultSettings();
- NetworkState[] states = new NetworkState[] {buildWifiState()};
+ NetworkStateSnapshot[] states = new NetworkStateSnapshot[] {buildWifiState()};
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
@@ -577,7 +581,8 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
buildTemplateMobileWithRatType(null, TelephonyManager.NETWORK_TYPE_LTE);
final NetworkTemplate template5g =
buildTemplateMobileWithRatType(null, TelephonyManager.NETWORK_TYPE_NR);
- final NetworkState[] states = new NetworkState[]{buildMobile3gState(IMSI_1)};
+ final NetworkStateSnapshot[] states =
+ new NetworkStateSnapshot[]{buildMobile3gState(IMSI_1)};
// 3G network comes online.
expectNetworkStatsSummary(buildEmptyStats());
@@ -643,6 +648,117 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
assertUidTotal(template5g, UID_RED, 5L, 13L, 31L, 9L, 2);
}
+ @Test
+ public void testMobileStatsOemManaged() throws Exception {
+ final NetworkTemplate templateOemPaid = new NetworkTemplate(MATCH_MOBILE_WILDCARD,
+ /*subscriberId=*/null, /*matchSubscriberIds=*/null, /*networkId=*/null,
+ METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, OEM_PAID);
+
+ final NetworkTemplate templateOemPrivate = new NetworkTemplate(MATCH_MOBILE_WILDCARD,
+ /*subscriberId=*/null, /*matchSubscriberIds=*/null, /*networkId=*/null,
+ METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, OEM_PRIVATE);
+
+ final NetworkTemplate templateOemAll = new NetworkTemplate(MATCH_MOBILE_WILDCARD,
+ /*subscriberId=*/null, /*matchSubscriberIds=*/null, /*networkId=*/null,
+ METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL,
+ OEM_PAID | OEM_PRIVATE);
+
+ final NetworkTemplate templateOemYes = new NetworkTemplate(MATCH_MOBILE_WILDCARD,
+ /*subscriberId=*/null, /*matchSubscriberIds=*/null, /*networkId=*/null,
+ METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, OEM_MANAGED_YES);
+
+ final NetworkTemplate templateOemNone = new NetworkTemplate(MATCH_MOBILE_WILDCARD,
+ /*subscriberId=*/null, /*matchSubscriberIds=*/null, /*networkId=*/null,
+ METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, OEM_MANAGED_NO);
+
+ // OEM_PAID network comes online.
+ NetworkStateSnapshot[] states = new NetworkStateSnapshot[]{
+ buildOemManagedMobileState(IMSI_1, false,
+ new int[]{NetworkCapabilities.NET_CAPABILITY_OEM_PAID})};
+ expectNetworkStatsSummary(buildEmptyStats());
+ expectNetworkStatsUidDetail(buildEmptyStats());
+ mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states),
+ new UnderlyingNetworkInfo[0]);
+
+ // Create some traffic.
+ incrementCurrentTime(MINUTE_IN_MILLIS);
+ expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
+ .addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE,
+ 36L, 41L, 24L, 96L, 0L)));
+ forcePollAndWaitForIdle();
+
+ // OEM_PRIVATE network comes online.
+ states = new NetworkStateSnapshot[]{buildOemManagedMobileState(IMSI_1, false,
+ new int[]{NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE})};
+ expectNetworkStatsSummary(buildEmptyStats());
+ expectNetworkStatsUidDetail(buildEmptyStats());
+ mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states),
+ new UnderlyingNetworkInfo[0]);
+
+ // Create some traffic.
+ incrementCurrentTime(MINUTE_IN_MILLIS);
+ expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
+ .addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE,
+ 49L, 71L, 72L, 48L, 0L)));
+ forcePollAndWaitForIdle();
+
+ // OEM_PAID + OEM_PRIVATE network comes online.
+ states = new NetworkStateSnapshot[]{buildOemManagedMobileState(IMSI_1, false,
+ new int[]{NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE,
+ NetworkCapabilities.NET_CAPABILITY_OEM_PAID})};
+ expectNetworkStatsSummary(buildEmptyStats());
+ expectNetworkStatsUidDetail(buildEmptyStats());
+ mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states),
+ new UnderlyingNetworkInfo[0]);
+
+ // Create some traffic.
+ incrementCurrentTime(MINUTE_IN_MILLIS);
+ expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
+ .addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE,
+ 57L, 86L, 83L, 93L, 0L)));
+ forcePollAndWaitForIdle();
+
+ // OEM_NONE network comes online.
+ states = new NetworkStateSnapshot[]{buildOemManagedMobileState(IMSI_1, false, new int[]{})};
+ expectNetworkStatsSummary(buildEmptyStats());
+ expectNetworkStatsUidDetail(buildEmptyStats());
+ mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states),
+ new UnderlyingNetworkInfo[0]);
+
+ // Create some traffic.
+ incrementCurrentTime(MINUTE_IN_MILLIS);
+ expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
+ .addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE,
+ 29L, 73L, 34L, 31L, 0L)));
+ forcePollAndWaitForIdle();
+
+ // Verify OEM_PAID template gets only relevant stats.
+ assertUidTotal(templateOemPaid, UID_RED, 36L, 41L, 24L, 96L, 0);
+
+ // Verify OEM_PRIVATE template gets only relevant stats.
+ assertUidTotal(templateOemPrivate, UID_RED, 49L, 71L, 72L, 48L, 0);
+
+ // Verify OEM_PAID + OEM_PRIVATE template gets only relevant stats.
+ assertUidTotal(templateOemAll, UID_RED, 57L, 86L, 83L, 93L, 0);
+
+ // Verify OEM_NONE sees only non-OEM managed stats.
+ assertUidTotal(templateOemNone, UID_RED, 29L, 73L, 34L, 31L, 0);
+
+ // Verify OEM_MANAGED_YES sees all OEM managed stats.
+ assertUidTotal(templateOemYes, UID_RED,
+ 36L + 49L + 57L,
+ 41L + 71L + 86L,
+ 24L + 72L + 83L,
+ 96L + 48L + 93L, 0);
+
+ // Verify ALL_MOBILE template gets both OEM managed and non-OEM managed stats.
+ assertUidTotal(sTemplateImsi1, UID_RED,
+ 36L + 49L + 57L + 29L,
+ 41L + 71L + 86L + 73L,
+ 24L + 72L + 83L + 34L,
+ 96L + 48L + 93L + 31L, 0);
+ }
+
// TODO: support per IMSI state
private void setMobileRatTypeAndWaitForIdle(int ratType) {
when(mNetworkStatsSubscriptionsMonitor.getRatTypeForSubscriberId(anyString()))
@@ -655,7 +771,7 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
public void testSummaryForAllUid() throws Exception {
// pretend that network comes online
expectDefaultSettings();
- NetworkState[] states = new NetworkState[] {buildWifiState()};
+ NetworkStateSnapshot[] states = new NetworkStateSnapshot[] {buildWifiState()};
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
@@ -714,7 +830,7 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
public void testDetailedUidStats() throws Exception {
// pretend that network comes online
expectDefaultSettings();
- NetworkState[] states = new NetworkState[] {buildWifiState()};
+ NetworkStateSnapshot[] states = new NetworkStateSnapshot[] {buildWifiState()};
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
@@ -755,9 +871,9 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
final String stackedIface = "stacked-test0";
final LinkProperties stackedProp = new LinkProperties();
stackedProp.setInterfaceName(stackedIface);
- final NetworkState wifiState = buildWifiState();
+ final NetworkStateSnapshot wifiState = buildWifiState();
wifiState.linkProperties.addStackedLink(stackedProp);
- NetworkState[] states = new NetworkState[] {wifiState};
+ NetworkStateSnapshot[] states = new NetworkStateSnapshot[] {wifiState};
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
@@ -813,7 +929,7 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
public void testForegroundBackground() throws Exception {
// pretend that network comes online
expectDefaultSettings();
- NetworkState[] states = new NetworkState[] {buildWifiState()};
+ NetworkStateSnapshot[] states = new NetworkStateSnapshot[] {buildWifiState()};
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
@@ -870,8 +986,8 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
public void testMetered() throws Exception {
// pretend that network comes online
expectDefaultSettings();
- NetworkState[] states =
- new NetworkState[] {buildWifiState(true /* isMetered */, TEST_IFACE)};
+ NetworkStateSnapshot[] states =
+ new NetworkStateSnapshot[] {buildWifiState(true /* isMetered */, TEST_IFACE)};
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
@@ -910,8 +1026,8 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
public void testRoaming() throws Exception {
// pretend that network comes online
expectDefaultSettings();
- NetworkState[] states =
- new NetworkState[] {buildMobile3gState(IMSI_1, true /* isRoaming */)};
+ NetworkStateSnapshot[] states =
+ new NetworkStateSnapshot[] {buildMobile3gState(IMSI_1, true /* isRoaming */)};
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
@@ -949,7 +1065,8 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
public void testTethering() throws Exception {
// pretend first mobile network comes online
expectDefaultSettings();
- final NetworkState[] states = new NetworkState[]{buildMobile3gState(IMSI_1)};
+ final NetworkStateSnapshot[] states =
+ new NetworkStateSnapshot[]{buildMobile3gState(IMSI_1)};
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
@@ -1006,7 +1123,7 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
// pretend that wifi network comes online; service should ask about full
// network state, and poll any existing interfaces before updating.
expectDefaultSettings();
- NetworkState[] states = new NetworkState[] {buildWifiState()};
+ NetworkStateSnapshot[] states = new NetworkStateSnapshot[] {buildWifiState()};
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
@@ -1104,8 +1221,8 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
public void testStatsProviderUpdateStats() throws Exception {
// Pretend that network comes online.
expectDefaultSettings();
- final NetworkState[] states =
- new NetworkState[]{buildWifiState(true /* isMetered */, TEST_IFACE)};
+ final NetworkStateSnapshot[] states =
+ new NetworkStateSnapshot[]{buildWifiState(true /* isMetered */, TEST_IFACE)};
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
@@ -1166,8 +1283,8 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
public void testStatsProviderSetAlert() throws Exception {
// Pretend that network comes online.
expectDefaultSettings();
- NetworkState[] states =
- new NetworkState[]{buildWifiState(true /* isMetered */, TEST_IFACE)};
+ NetworkStateSnapshot[] states =
+ new NetworkStateSnapshot[]{buildWifiState(true /* isMetered */, TEST_IFACE)};
mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states),
new UnderlyingNetworkInfo[0]);
@@ -1210,7 +1327,8 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
buildTemplateMobileWithRatType(null, TelephonyManager.NETWORK_TYPE_UNKNOWN);
final NetworkTemplate templateAll =
buildTemplateMobileWithRatType(null, NETWORK_TYPE_ALL);
- final NetworkState[] states = new NetworkState[]{buildMobile3gState(IMSI_1)};
+ final NetworkStateSnapshot[] states =
+ new NetworkStateSnapshot[]{buildMobile3gState(IMSI_1)};
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
@@ -1285,7 +1403,7 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
public void testOperationCount_nonDefault_traffic() throws Exception {
// Pretend mobile network comes online, but wifi is the default network.
expectDefaultSettings();
- NetworkState[] states = new NetworkState[]{
+ NetworkStateSnapshot[] states = new NetworkStateSnapshot[]{
buildWifiState(true /*isMetered*/, TEST_IFACE2), buildMobile3gState(IMSI_1)};
expectNetworkStatsUidDetail(buildEmptyStats());
mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states),
@@ -1373,7 +1491,7 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
expectNetworkStatsSummary(buildEmptyStats());
}
- private String getActiveIface(NetworkState... states) throws Exception {
+ private String getActiveIface(NetworkStateSnapshot... states) throws Exception {
if (states == null || states.length == 0 || states[0].linkProperties == null) {
return null;
}
@@ -1449,11 +1567,11 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
assertEquals("unexpected operations", operations, entry.operations);
}
- private static NetworkState buildWifiState() {
+ private static NetworkStateSnapshot buildWifiState() {
return buildWifiState(false, TEST_IFACE);
}
- private static NetworkState buildWifiState(boolean isMetered, @NonNull String iface) {
+ private static NetworkStateSnapshot buildWifiState(boolean isMetered, @NonNull String iface) {
final LinkProperties prop = new LinkProperties();
prop.setInterfaceName(iface);
final NetworkCapabilities capabilities = new NetworkCapabilities();
@@ -1461,32 +1579,41 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING, true);
capabilities.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
capabilities.setSSID(TEST_SSID);
- return new NetworkState(TYPE_WIFI, prop, capabilities, WIFI_NETWORK, null, TEST_SSID);
+ return new NetworkStateSnapshot(WIFI_NETWORK, capabilities, prop, null, TYPE_WIFI);
}
- private static NetworkState buildMobile3gState(String subscriberId) {
+ private static NetworkStateSnapshot buildMobile3gState(String subscriberId) {
return buildMobile3gState(subscriberId, false /* isRoaming */);
}
- private static NetworkState buildMobile3gState(String subscriberId, boolean isRoaming) {
+ private static NetworkStateSnapshot buildMobile3gState(String subscriberId, boolean isRoaming) {
final LinkProperties prop = new LinkProperties();
prop.setInterfaceName(TEST_IFACE);
final NetworkCapabilities capabilities = new NetworkCapabilities();
capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED, false);
capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING, !isRoaming);
capabilities.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
- return new NetworkState(
- TYPE_MOBILE, prop, capabilities, MOBILE_NETWORK, subscriberId, null);
+ return new NetworkStateSnapshot(
+ MOBILE_NETWORK, capabilities, prop, subscriberId, TYPE_MOBILE);
}
private NetworkStats buildEmptyStats() {
return new NetworkStats(getElapsedRealtime(), 0);
}
- private static NetworkState buildVpnState() {
+ private static NetworkStateSnapshot buildOemManagedMobileState(
+ String subscriberId, boolean isRoaming, int[] oemNetCapabilities) {
final LinkProperties prop = new LinkProperties();
- prop.setInterfaceName(TUN_IFACE);
- return new NetworkState(TYPE_VPN, prop, new NetworkCapabilities(), VPN_NETWORK, null, null);
+ prop.setInterfaceName(TEST_IFACE);
+ final NetworkCapabilities capabilities = new NetworkCapabilities();
+ capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED, false);
+ capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING, !isRoaming);
+ for (int nc : oemNetCapabilities) {
+ capabilities.setCapability(nc, true);
+ }
+ capabilities.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
+ return new NetworkStateSnapshot(MOBILE_NETWORK, capabilities, prop, subscriberId,
+ TYPE_MOBILE);
}
private long getElapsedRealtime() {
diff --git a/tests/utils/testutils/java/com/android/internal/util/test/FakeSettingsProvider.java b/tests/utils/testutils/java/com/android/internal/util/test/FakeSettingsProvider.java
index e482708e385b..a0a5a293f2e4 100644
--- a/tests/utils/testutils/java/com/android/internal/util/test/FakeSettingsProvider.java
+++ b/tests/utils/testutils/java/com/android/internal/util/test/FakeSettingsProvider.java
@@ -92,6 +92,14 @@ public class FakeSettingsProvider extends MockContentProvider {
}
/**
+ * Creates a {@link org.junit.rules.TestRule} that makes sure {@link #clearSettingsProvider()}
+ * is triggered before and after each test.
+ */
+ public static FakeSettingsProviderRule rule() {
+ return new FakeSettingsProviderRule();
+ }
+
+ /**
* This needs to be called before and after using the FakeSettingsProvider class.
*/
public static void clearSettingsProvider() {
diff --git a/tests/utils/testutils/java/com/android/internal/util/test/FakeSettingsProviderRule.java b/tests/utils/testutils/java/com/android/internal/util/test/FakeSettingsProviderRule.java
new file mode 100644
index 000000000000..c4e9545dfde2
--- /dev/null
+++ b/tests/utils/testutils/java/com/android/internal/util/test/FakeSettingsProviderRule.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.util.test;
+
+import android.content.Context;
+import android.provider.Settings;
+import android.test.mock.MockContentResolver;
+
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+
+/**
+ * JUnit Rule helps keeping test {@link FakeSettingsProvider} clean.
+ *
+ * <p>It clears {@link FakeSettingsProvider} before and after each test. Example use:
+ * <pre class="code"><code class="java">
+ * public class ExampleTest {
+ *
+ * &#064;Rule public FakeSettingsProviderRule rule = FakeSettingsProvider.rule();
+ *
+ * &#064;Test
+ * public void shouldDoSomething() {
+ * ContextResolver cr = rule.mockContentResolver(mContext);
+ * Settings.Global.putInt(cr, "my_setting_name", 1);
+ * // Test code relying on my_setting_name value using cr
+ * }
+ * }
+ * </code></pre>
+ *
+ * @see FakeSettingsProvider
+ */
+public final class FakeSettingsProviderRule implements TestRule {
+
+ /** Prevent initialization outside {@link FakeSettingsProvider}. */
+ FakeSettingsProviderRule() {
+ }
+
+ /**
+ * Creates a {@link MockContentResolver} that uses the {@link FakeSettingsProvider} as the
+ * {@link Settings#AUTHORITY} provider.
+ */
+ public MockContentResolver mockContentResolver(Context context) {
+ MockContentResolver contentResolver = new MockContentResolver(context);
+ contentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
+ return contentResolver;
+ }
+
+ @Override
+ public Statement apply(Statement base, Description description) {
+ return new Statement() {
+ public void evaluate() throws Throwable {
+ FakeSettingsProvider.clearSettingsProvider();
+ try {
+ base.evaluate();
+ } finally {
+ FakeSettingsProvider.clearSettingsProvider();
+ }
+ }
+ };
+ }
+}
diff --git a/tests/vcn/java/android/net/vcn/VcnManagerTest.java b/tests/vcn/java/android/net/vcn/VcnManagerTest.java
index 708767605508..7515971b8307 100644
--- a/tests/vcn/java/android/net/vcn/VcnManagerTest.java
+++ b/tests/vcn/java/android/net/vcn/VcnManagerTest.java
@@ -16,6 +16,8 @@
package android.net.vcn;
+import static android.net.vcn.VcnManager.VCN_STATUS_CODE_ACTIVE;
+
import static androidx.test.InstrumentationRegistry.getContext;
import static org.junit.Assert.assertEquals;
@@ -201,13 +203,13 @@ public class VcnManagerTest {
IVcnStatusCallback cbBinder =
new VcnStatusCallbackBinder(INLINE_EXECUTOR, mMockStatusCallback);
- cbBinder.onEnteredSafeMode();
- verify(mMockStatusCallback).onEnteredSafeMode();
+ cbBinder.onVcnStatusChanged(VCN_STATUS_CODE_ACTIVE);
+ verify(mMockStatusCallback).onVcnStatusChanged(VCN_STATUS_CODE_ACTIVE);
cbBinder.onGatewayConnectionError(
UNDERLYING_NETWORK_CAPABILITIES,
VcnManager.VCN_ERROR_CODE_NETWORK_ERROR,
- "java.net.UnknownHostException",
+ UnknownHostException.class.getName(),
"exception_message");
verify(mMockStatusCallback)
.onGatewayConnectionError(
diff --git a/tests/vcn/java/android/net/vcn/VcnUnderlyingNetworkPolicyTest.java b/tests/vcn/java/android/net/vcn/VcnUnderlyingNetworkPolicyTest.java
index 3ba0a1f53a9f..a674425efea3 100644
--- a/tests/vcn/java/android/net/vcn/VcnUnderlyingNetworkPolicyTest.java
+++ b/tests/vcn/java/android/net/vcn/VcnUnderlyingNetworkPolicyTest.java
@@ -46,6 +46,6 @@ public class VcnUnderlyingNetworkPolicyTest {
@Test
public void testParcelUnparcel() {
- assertParcelSane(SAMPLE_NETWORK_POLICY, 2);
+ assertParcelSane(SAMPLE_NETWORK_POLICY, 1);
}
}
diff --git a/tests/vcn/java/com/android/server/VcnManagementServiceTest.java b/tests/vcn/java/com/android/server/VcnManagementServiceTest.java
index 45b2381ce06d..11498dec8165 100644
--- a/tests/vcn/java/com/android/server/VcnManagementServiceTest.java
+++ b/tests/vcn/java/com/android/server/VcnManagementServiceTest.java
@@ -43,7 +43,6 @@ import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -59,6 +58,7 @@ import android.net.vcn.IVcnStatusCallback;
import android.net.vcn.IVcnUnderlyingNetworkPolicyListener;
import android.net.vcn.VcnConfig;
import android.net.vcn.VcnConfigTest;
+import android.net.vcn.VcnManager;
import android.net.vcn.VcnUnderlyingNetworkPolicy;
import android.net.wifi.WifiInfo;
import android.os.IBinder;
@@ -100,6 +100,8 @@ import java.util.UUID;
public class VcnManagementServiceTest {
private static final String TEST_PACKAGE_NAME =
VcnManagementServiceTest.class.getPackage().getName();
+ private static final String TEST_CB_PACKAGE_NAME =
+ VcnManagementServiceTest.class.getPackage().getName() + ".callback";
private static final ParcelUuid TEST_UUID_1 = new ParcelUuid(new UUID(0, 0));
private static final ParcelUuid TEST_UUID_2 = new ParcelUuid(new UUID(1, 1));
private static final VcnConfig TEST_VCN_CONFIG;
@@ -288,6 +290,14 @@ public class VcnManagementServiceTest {
private TelephonySubscriptionSnapshot triggerSubscriptionTrackerCbAndGetSnapshot(
Set<ParcelUuid> activeSubscriptionGroups, Map<Integer, ParcelUuid> subIdToGroupMap) {
+ return triggerSubscriptionTrackerCbAndGetSnapshot(
+ activeSubscriptionGroups, subIdToGroupMap, true /* hasCarrierPrivileges */);
+ }
+
+ private TelephonySubscriptionSnapshot triggerSubscriptionTrackerCbAndGetSnapshot(
+ Set<ParcelUuid> activeSubscriptionGroups,
+ Map<Integer, ParcelUuid> subIdToGroupMap,
+ boolean hasCarrierPrivileges) {
final TelephonySubscriptionSnapshot snapshot = mock(TelephonySubscriptionSnapshot.class);
doReturn(activeSubscriptionGroups).when(snapshot).getActiveSubscriptionGroups();
@@ -295,7 +305,7 @@ public class VcnManagementServiceTest {
(activeSubscriptionGroups == null || activeSubscriptionGroups.isEmpty())
? Collections.emptySet()
: Collections.singleton(TEST_PACKAGE_NAME);
- doReturn(true)
+ doReturn(hasCarrierPrivileges)
.when(snapshot)
.packageHasPermissionsForSubscriptionGroup(
argThat(val -> activeSubscriptionGroups.contains(val)),
@@ -451,6 +461,34 @@ public class VcnManagementServiceTest {
}
@Test
+ public void testSetVcnConfigNotifiesStatusCallback() throws Exception {
+ mVcnMgmtSvc.systemReady();
+ doReturn(true)
+ .when(mLocationPermissionChecker)
+ .checkLocationPermission(eq(TEST_PACKAGE_NAME), any(), eq(TEST_UID), any());
+ triggerSubscriptionTrackerCbAndGetSnapshot(Collections.singleton(TEST_UUID_2));
+
+ mVcnMgmtSvc.registerVcnStatusCallback(TEST_UUID_2, mMockStatusCallback, TEST_PACKAGE_NAME);
+ verify(mMockStatusCallback).onVcnStatusChanged(VcnManager.VCN_STATUS_CODE_NOT_CONFIGURED);
+
+ // Use a different UUID to simulate a new VCN config.
+ mVcnMgmtSvc.setVcnConfig(TEST_UUID_2, TEST_VCN_CONFIG, TEST_PACKAGE_NAME);
+
+ verify(mMockStatusCallback).onVcnStatusChanged(VcnManager.VCN_STATUS_CODE_ACTIVE);
+ }
+
+ @Test
+ public void testSetVcnConfigInSafeModeNotifiesStatusCallback() throws Exception {
+ setupSubscriptionAndStartVcn(TEST_SUBSCRIPTION_ID, TEST_UUID_2, false /* isActive */);
+ mVcnMgmtSvc.registerVcnStatusCallback(TEST_UUID_2, mMockStatusCallback, TEST_PACKAGE_NAME);
+ verify(mMockStatusCallback).onVcnStatusChanged(VcnManager.VCN_STATUS_CODE_SAFE_MODE);
+
+ mVcnMgmtSvc.setVcnConfig(TEST_UUID_2, TEST_VCN_CONFIG, TEST_PACKAGE_NAME);
+
+ verify(mMockStatusCallback).onVcnStatusChanged(VcnManager.VCN_STATUS_CODE_ACTIVE);
+ }
+
+ @Test
public void testClearVcnConfigRequiresNonSystemServer() throws Exception {
doReturn(Process.SYSTEM_UID).when(mMockDeps).getBinderCallingUid();
@@ -493,6 +531,17 @@ public class VcnManagementServiceTest {
}
@Test
+ public void testClearVcnConfigNotifiesStatusCallback() throws Exception {
+ setupSubscriptionAndStartVcn(TEST_SUBSCRIPTION_ID, TEST_UUID_2, true /* isActive */);
+ mVcnMgmtSvc.registerVcnStatusCallback(TEST_UUID_2, mMockStatusCallback, TEST_PACKAGE_NAME);
+ verify(mMockStatusCallback).onVcnStatusChanged(VcnManager.VCN_STATUS_CODE_ACTIVE);
+
+ mVcnMgmtSvc.clearVcnConfig(TEST_UUID_2);
+
+ verify(mMockStatusCallback).onVcnStatusChanged(VcnManager.VCN_STATUS_CODE_NOT_CONFIGURED);
+ }
+
+ @Test
public void testSetVcnConfigClearVcnConfigStartsUpdatesAndTeardsDownVcns() throws Exception {
// Use a different UUID to simulate a new VCN config.
mVcnMgmtSvc.setVcnConfig(TEST_UUID_2, TEST_VCN_CONFIG, TEST_PACKAGE_NAME);
@@ -549,13 +598,6 @@ public class VcnManagementServiceTest {
mVcnMgmtSvc.removeVcnUnderlyingNetworkPolicyListener(mMockPolicyListener);
}
- private void setUpVcnSubscription(int subId, ParcelUuid subGroup) {
- mVcnMgmtSvc.setVcnConfig(subGroup, TEST_VCN_CONFIG, TEST_PACKAGE_NAME);
-
- triggerSubscriptionTrackerCbAndGetSnapshot(
- Collections.singleton(subGroup), Collections.singletonMap(subId, subGroup));
- }
-
private void verifyMergedNetworkCapabilities(
NetworkCapabilities mergedCapabilities,
@Transport int transportType,
@@ -573,9 +615,23 @@ public class VcnManagementServiceTest {
}
private void setupSubscriptionAndStartVcn(int subId, ParcelUuid subGrp, boolean isVcnActive) {
- setUpVcnSubscription(subId, subGrp);
+ setupSubscriptionAndStartVcn(subId, subGrp, isVcnActive, true /* hasCarrierPrivileges */);
+ }
+
+ private void setupSubscriptionAndStartVcn(
+ int subId, ParcelUuid subGrp, boolean isVcnActive, boolean hasCarrierPrivileges) {
+ mVcnMgmtSvc.systemReady();
+ triggerSubscriptionTrackerCbAndGetSnapshot(
+ Collections.singleton(subGrp),
+ Collections.singletonMap(subId, subGrp),
+ hasCarrierPrivileges);
+
final Vcn vcn = startAndGetVcnInstance(subGrp);
doReturn(isVcnActive).when(vcn).isActive();
+
+ doReturn(true)
+ .when(mLocationPermissionChecker)
+ .checkLocationPermission(eq(TEST_PACKAGE_NAME), any(), eq(TEST_UID), any());
}
private VcnUnderlyingNetworkPolicy startVcnAndGetPolicyForTransport(
@@ -721,7 +777,7 @@ public class VcnManagementServiceTest {
verify(mMockPolicyListener).onPolicyChanged();
}
- private void verifyVcnCallback(
+ private void triggerVcnSafeMode(
@NonNull ParcelUuid subGroup, @NonNull TelephonySubscriptionSnapshot snapshot)
throws Exception {
verify(mMockDeps)
@@ -732,20 +788,20 @@ public class VcnManagementServiceTest {
eq(snapshot),
mVcnCallbackCaptor.capture());
- mVcnMgmtSvc.addVcnUnderlyingNetworkPolicyListener(mMockPolicyListener);
-
VcnCallback vcnCallback = mVcnCallbackCaptor.getValue();
vcnCallback.onEnteredSafeMode();
-
- verify(mMockPolicyListener).onPolicyChanged();
}
@Test
- public void testVcnCallbackOnEnteredSafeMode() throws Exception {
+ public void testVcnEnteringSafeModeNotifiesPolicyListeners() throws Exception {
TelephonySubscriptionSnapshot snapshot =
triggerSubscriptionTrackerCbAndGetSnapshot(Collections.singleton(TEST_UUID_1));
- verifyVcnCallback(TEST_UUID_1, snapshot);
+ mVcnMgmtSvc.addVcnUnderlyingNetworkPolicyListener(mMockPolicyListener);
+
+ triggerVcnSafeMode(TEST_UUID_1, snapshot);
+
+ verify(mMockPolicyListener).onPolicyChanged();
}
private void triggerVcnStatusCallbackOnEnteredSafeMode(
@@ -758,6 +814,9 @@ public class VcnManagementServiceTest {
TelephonySubscriptionSnapshot snapshot =
triggerSubscriptionTrackerCbAndGetSnapshot(Collections.singleton(subGroup));
+ setupSubscriptionAndStartVcn(
+ TEST_SUBSCRIPTION_ID, subGroup, true /* isActive */, hasPermissionsforSubGroup);
+
doReturn(hasPermissionsforSubGroup)
.when(snapshot)
.packageHasPermissionsForSubscriptionGroup(eq(subGroup), eq(pkgName));
@@ -768,10 +827,7 @@ public class VcnManagementServiceTest {
mVcnMgmtSvc.registerVcnStatusCallback(subGroup, mMockStatusCallback, pkgName);
- // Trigger systemReady() to set up LocationPermissionChecker
- mVcnMgmtSvc.systemReady();
-
- verifyVcnCallback(subGroup, snapshot);
+ triggerVcnSafeMode(subGroup, snapshot);
}
@Test
@@ -783,7 +839,7 @@ public class VcnManagementServiceTest {
true /* hasPermissionsforSubGroup */,
true /* hasLocationPermission */);
- verify(mMockStatusCallback, times(1)).onEnteredSafeMode();
+ verify(mMockStatusCallback).onVcnStatusChanged(VcnManager.VCN_STATUS_CODE_SAFE_MODE);
}
@Test
@@ -795,7 +851,8 @@ public class VcnManagementServiceTest {
false /* hasPermissionsforSubGroup */,
true /* hasLocationPermission */);
- verify(mMockStatusCallback, never()).onEnteredSafeMode();
+ verify(mMockStatusCallback, never())
+ .onVcnStatusChanged(VcnManager.VCN_STATUS_CODE_SAFE_MODE);
}
@Test
@@ -807,7 +864,8 @@ public class VcnManagementServiceTest {
true /* hasPermissionsforSubGroup */,
false /* hasLocationPermission */);
- verify(mMockStatusCallback, never()).onEnteredSafeMode();
+ verify(mMockStatusCallback, never())
+ .onVcnStatusChanged(VcnManager.VCN_STATUS_CODE_SAFE_MODE);
}
@Test
@@ -823,6 +881,83 @@ public class VcnManagementServiceTest {
assertEquals(TEST_PACKAGE_NAME, cbInfo.mPkgName);
assertEquals(TEST_UID, cbInfo.mUid);
verify(mMockIBinder).linkToDeath(eq(cbInfo), anyInt());
+
+ verify(mMockStatusCallback).onVcnStatusChanged(VcnManager.VCN_STATUS_CODE_NOT_CONFIGURED);
+ }
+
+ @Test
+ public void testRegisterVcnStatusCallback_MissingPermission() throws Exception {
+ setupSubscriptionAndStartVcn(
+ TEST_SUBSCRIPTION_ID,
+ TEST_UUID_1,
+ true /* isActive */,
+ false /* hasCarrierPrivileges */);
+
+ mVcnMgmtSvc.registerVcnStatusCallback(TEST_UUID_1, mMockStatusCallback, TEST_PACKAGE_NAME);
+
+ verify(mMockStatusCallback).onVcnStatusChanged(VcnManager.VCN_STATUS_CODE_NOT_CONFIGURED);
+ }
+
+ @Test
+ public void testRegisterVcnStatusCallback_VcnInactive() throws Exception {
+ setupSubscriptionAndStartVcn(
+ TEST_SUBSCRIPTION_ID,
+ TEST_UUID_1,
+ true /* isActive */,
+ true /* hasCarrierPrivileges */);
+
+ // VCN is currently active. Lose carrier privileges for TEST_PACKAGE and hit teardown
+ // timeout so the VCN goes inactive.
+ final TelephonySubscriptionSnapshot snapshot =
+ triggerSubscriptionTrackerCbAndGetSnapshot(
+ Collections.singleton(TEST_UUID_1),
+ Collections.singletonMap(TEST_SUBSCRIPTION_ID, TEST_UUID_1),
+ false /* hasCarrierPrivileges */);
+ mTestLooper.moveTimeForward(VcnManagementService.CARRIER_PRIVILEGES_LOST_TEARDOWN_DELAY_MS);
+ mTestLooper.dispatchAll();
+
+ // Giving TEST_PACKAGE privileges again will restart the VCN (which will indicate ACTIVE
+ // when the status callback is registered). Instead, setup permissions for TEST_CB_PACKAGE
+ // so that it's permissioned to receive INACTIVE (instead of NOT_CONFIGURED) without
+ // reactivating the VCN.
+ doReturn(true)
+ .when(snapshot)
+ .packageHasPermissionsForSubscriptionGroup(
+ eq(TEST_UUID_1), eq(TEST_CB_PACKAGE_NAME));
+ doReturn(true)
+ .when(mLocationPermissionChecker)
+ .checkLocationPermission(eq(TEST_CB_PACKAGE_NAME), any(), eq(TEST_UID), any());
+
+ mVcnMgmtSvc.registerVcnStatusCallback(
+ TEST_UUID_1, mMockStatusCallback, TEST_CB_PACKAGE_NAME);
+
+ verify(mMockStatusCallback).onVcnStatusChanged(VcnManager.VCN_STATUS_CODE_INACTIVE);
+ }
+
+ @Test
+ public void testRegisterVcnStatusCallback_VcnActive() throws Exception {
+ setupSubscriptionAndStartVcn(
+ TEST_SUBSCRIPTION_ID,
+ TEST_UUID_1,
+ true /* isActive */,
+ true /* hasCarrierPrivileges */);
+
+ mVcnMgmtSvc.registerVcnStatusCallback(TEST_UUID_1, mMockStatusCallback, TEST_PACKAGE_NAME);
+
+ verify(mMockStatusCallback).onVcnStatusChanged(VcnManager.VCN_STATUS_CODE_ACTIVE);
+ }
+
+ @Test
+ public void testRegisterVcnStatusCallback_VcnSafeMode() throws Exception {
+ setupSubscriptionAndStartVcn(
+ TEST_SUBSCRIPTION_ID,
+ TEST_UUID_1,
+ false /* isActive */,
+ true /* hasCarrierPrivileges */);
+
+ mVcnMgmtSvc.registerVcnStatusCallback(TEST_UUID_1, mMockStatusCallback, TEST_PACKAGE_NAME);
+
+ verify(mMockStatusCallback).onVcnStatusChanged(VcnManager.VCN_STATUS_CODE_SAFE_MODE);
}
@Test(expected = IllegalStateException.class)
diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java
index 69c21b967917..4bf849111a5d 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java
@@ -36,6 +36,7 @@ import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
@@ -143,11 +144,18 @@ public class VcnGatewayConnectionConnectedStateTest extends VcnGatewayConnection
.onIpSecTransformsMigrated(makeDummyIpSecTransform(), makeDummyIpSecTransform());
mTestLooper.dispatchAll();
+ verify(mIpSecSvc, times(2))
+ .setNetworkForTunnelInterface(
+ eq(TEST_IPSEC_TUNNEL_RESOURCE_ID),
+ eq(TEST_UNDERLYING_NETWORK_RECORD_1.network),
+ any());
+
for (int direction : new int[] {DIRECTION_IN, DIRECTION_OUT}) {
verify(mIpSecSvc)
.applyTunnelModeTransform(
eq(TEST_IPSEC_TUNNEL_RESOURCE_ID), eq(direction), anyInt(), any());
}
+
assertEquals(mGatewayConnection.mConnectedState, mGatewayConnection.getCurrentState());
}
@@ -233,7 +241,7 @@ public class VcnGatewayConnectionConnectedStateTest extends VcnGatewayConnection
verify(mGatewayStatusCallback)
.onGatewayConnectionError(
- eq(mConfig.getRequiredUnderlyingCapabilities()),
+ eq(mConfig.getExposedCapabilities()),
eq(VCN_ERROR_CODE_INTERNAL_ERROR),
any(),
any());
@@ -267,10 +275,7 @@ public class VcnGatewayConnectionConnectedStateTest extends VcnGatewayConnection
verify(mGatewayStatusCallback)
.onGatewayConnectionError(
- eq(mConfig.getRequiredUnderlyingCapabilities()),
- eq(expectedErrorType),
- any(),
- any());
+ eq(mConfig.getExposedCapabilities()), eq(expectedErrorType), any(), any());
}
@Test
@@ -290,4 +295,22 @@ public class VcnGatewayConnectionConnectedStateTest extends VcnGatewayConnection
verifyIkeSessionClosedExceptionalltyNotifiesStatusCallback(
new TemporaryFailureException("vcn test"), VCN_ERROR_CODE_INTERNAL_ERROR);
}
+
+ @Test
+ public void testTeardown() throws Exception {
+ mGatewayConnection.teardownAsynchronously();
+ mTestLooper.dispatchAll();
+
+ assertEquals(mGatewayConnection.mDisconnectingState, mGatewayConnection.getCurrentState());
+ assertTrue(mGatewayConnection.isQuitting());
+ }
+
+ @Test
+ public void testNonTeardownDisconnectRequest() throws Exception {
+ mGatewayConnection.sendDisconnectRequestedAndAcquireWakelock("TEST", false);
+ mTestLooper.dispatchAll();
+
+ assertEquals(mGatewayConnection.mDisconnectingState, mGatewayConnection.getCurrentState());
+ assertFalse(mGatewayConnection.isQuitting());
+ }
}
diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectingStateTest.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectingStateTest.java
index 17ae19e086cf..d07d2cf4f1bb 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectingStateTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectingStateTest.java
@@ -19,6 +19,8 @@ package com.android.server.vcn;
import static com.android.server.vcn.VcnGatewayConnection.VcnIkeSession;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
@@ -111,4 +113,22 @@ public class VcnGatewayConnectionConnectingStateTest extends VcnGatewayConnectio
public void testSafeModeTimeoutNotifiesCallback() {
verifySafeModeTimeoutNotifiesCallback(mGatewayConnection.mConnectingState);
}
+
+ @Test
+ public void testTeardown() throws Exception {
+ mGatewayConnection.teardownAsynchronously();
+ mTestLooper.dispatchAll();
+
+ assertEquals(mGatewayConnection.mDisconnectingState, mGatewayConnection.getCurrentState());
+ assertTrue(mGatewayConnection.isQuitting());
+ }
+
+ @Test
+ public void testNonTeardownDisconnectRequest() throws Exception {
+ mGatewayConnection.sendDisconnectRequestedAndAcquireWakelock("TEST", false);
+ mTestLooper.dispatchAll();
+
+ assertEquals(mGatewayConnection.mDisconnectingState, mGatewayConnection.getCurrentState());
+ assertFalse(mGatewayConnection.isQuitting());
+ }
}
diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionDisconnectedStateTest.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionDisconnectedStateTest.java
index 9ea641f52e48..5f27fabb62b0 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionDisconnectedStateTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionDisconnectedStateTest.java
@@ -21,9 +21,12 @@ import static android.net.IpSecManager.IpSecTunnelInterface;
import static com.android.server.vcn.VcnGatewayConnection.DUMMY_ADDR;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import android.net.IpSecManager;
@@ -54,7 +57,7 @@ public class VcnGatewayConnectionDisconnectedStateTest extends VcnGatewayConnect
}
@Test
- public void testEnterWhileNotRunningTriggersQuit() throws Exception {
+ public void testEnterWhileQuittingTriggersQuit() throws Exception {
final VcnGatewayConnection vgc =
new VcnGatewayConnection(
mVcnContext,
@@ -64,7 +67,7 @@ public class VcnGatewayConnectionDisconnectedStateTest extends VcnGatewayConnect
mGatewayStatusCallback,
mDeps);
- vgc.setIsRunning(false);
+ vgc.setIsQuitting(true);
vgc.transitionTo(vgc.mDisconnectedState);
mTestLooper.dispatchAll();
@@ -101,5 +104,18 @@ public class VcnGatewayConnectionDisconnectedStateTest extends VcnGatewayConnect
assertNull(mGatewayConnection.getCurrentState());
verify(mIpSecSvc).deleteTunnelInterface(eq(TEST_IPSEC_TUNNEL_RESOURCE_ID), any());
verifySafeModeTimeoutAlarmAndGetCallback(true /* expectCanceled */);
+ assertTrue(mGatewayConnection.isQuitting());
+ verify(mGatewayStatusCallback).onQuit();
+ }
+
+ @Test
+ public void testNonTeardownDisconnectRequest() throws Exception {
+ mGatewayConnection.sendDisconnectRequestedAndAcquireWakelock("TEST", false);
+ mTestLooper.dispatchAll();
+
+ assertEquals(mGatewayConnection.mDisconnectedState, mGatewayConnection.getCurrentState());
+ assertFalse(mGatewayConnection.isQuitting());
+ verify(mGatewayStatusCallback, never()).onQuit();
+ // No safe mode timer changes expected.
}
}
diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionDisconnectingStateTest.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionDisconnectingStateTest.java
index 7385204993c0..661e03af4f84 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionDisconnectingStateTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionDisconnectingStateTest.java
@@ -18,6 +18,8 @@ package com.android.server.vcn;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
@@ -79,10 +81,20 @@ public class VcnGatewayConnectionDisconnectingStateTest extends VcnGatewayConnec
// Should do nothing; already tearing down.
assertEquals(mGatewayConnection.mDisconnectingState, mGatewayConnection.getCurrentState());
verifyTeardownTimeoutAlarmAndGetCallback(false /* expectCanceled */);
+ assertTrue(mGatewayConnection.isQuitting());
}
@Test
public void testSafeModeTimeoutNotifiesCallback() {
verifySafeModeTimeoutNotifiesCallback(mGatewayConnection.mDisconnectingState);
}
+
+ @Test
+ public void testNonTeardownDisconnectRequest() throws Exception {
+ mGatewayConnection.sendDisconnectRequestedAndAcquireWakelock("TEST", false);
+ mTestLooper.dispatchAll();
+
+ assertEquals(mGatewayConnection.mDisconnectingState, mGatewayConnection.getCurrentState());
+ assertFalse(mGatewayConnection.isQuitting());
+ }
}
diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionRetryTimeoutStateTest.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionRetryTimeoutStateTest.java
index 5b0850b03f1a..85a0277f8b48 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionRetryTimeoutStateTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionRetryTimeoutStateTest.java
@@ -17,6 +17,9 @@
package com.android.server.vcn;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
@@ -96,4 +99,22 @@ public class VcnGatewayConnectionRetryTimeoutStateTest extends VcnGatewayConnect
public void testSafeModeTimeoutNotifiesCallback() {
verifySafeModeTimeoutNotifiesCallback(mGatewayConnection.mRetryTimeoutState);
}
+
+ @Test
+ public void testTeardownDisconnectRequest() throws Exception {
+ mGatewayConnection.teardownAsynchronously();
+ mTestLooper.dispatchAll();
+
+ assertNull(mGatewayConnection.getCurrentState());
+ assertTrue(mGatewayConnection.isQuitting());
+ }
+
+ @Test
+ public void testNonTeardownDisconnectRequest() throws Exception {
+ mGatewayConnection.sendDisconnectRequestedAndAcquireWakelock("TEST", false);
+ mTestLooper.dispatchAll();
+
+ assertEquals(mGatewayConnection.mDisconnectedState, mGatewayConnection.getCurrentState());
+ assertFalse(mGatewayConnection.isQuitting());
+ }
}
diff --git a/tests/vcn/java/com/android/server/vcn/VcnTest.java b/tests/vcn/java/com/android/server/vcn/VcnTest.java
index 9d3368271243..4fa63d4ff640 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnTest.java
@@ -16,9 +16,15 @@
package com.android.server.vcn;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_DUN;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_MMS;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.argThat;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doReturn;
@@ -33,6 +39,7 @@ import android.net.vcn.VcnGatewayConnectionConfig;
import android.net.vcn.VcnGatewayConnectionConfigTest;
import android.os.ParcelUuid;
import android.os.test.TestLooper;
+import android.util.ArraySet;
import com.android.server.VcnManagementService.VcnCallback;
import com.android.server.vcn.TelephonySubscriptionTracker.TelephonySubscriptionSnapshot;
@@ -43,6 +50,7 @@ import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
+import java.util.Arrays;
import java.util.Set;
import java.util.UUID;
@@ -51,6 +59,11 @@ public class VcnTest {
private static final ParcelUuid TEST_SUB_GROUP = new ParcelUuid(new UUID(0, 0));
private static final int NETWORK_SCORE = 0;
private static final int PROVIDER_ID = 5;
+ private static final int[][] TEST_CAPS =
+ new int[][] {
+ new int[] {NET_CAPABILITY_MMS, NET_CAPABILITY_INTERNET},
+ new int[] {NET_CAPABILITY_DUN}
+ };
private Context mContext;
private VcnContext mVcnContext;
@@ -91,13 +104,12 @@ public class VcnTest {
mGatewayStatusCallbackCaptor = ArgumentCaptor.forClass(VcnGatewayStatusCallback.class);
final VcnConfig.Builder configBuilder = new VcnConfig.Builder(mContext);
- for (final int capability : VcnGatewayConnectionConfigTest.EXPOSED_CAPS) {
+ for (final int[] caps : TEST_CAPS) {
configBuilder.addGatewayConnectionConfig(
- VcnGatewayConnectionConfigTest.buildTestConfigWithExposedCaps(capability));
+ VcnGatewayConnectionConfigTest.buildTestConfigWithExposedCaps(caps));
}
- configBuilder.addGatewayConnectionConfig(VcnGatewayConnectionConfigTest.buildTestConfig());
- mConfig = configBuilder.build();
+ mConfig = configBuilder.build();
mVcn =
new Vcn(
mVcnContext,
@@ -130,8 +142,7 @@ public class VcnTest {
@Test
public void testSubscriptionSnapshotUpdatesVcnGatewayConnections() {
final NetworkRequestListener requestListener = verifyAndGetRequestListener();
- startVcnGatewayWithCapabilities(
- requestListener, VcnGatewayConnectionConfigTest.EXPOSED_CAPS);
+ startVcnGatewayWithCapabilities(requestListener, TEST_CAPS[0]);
final Set<VcnGatewayConnection> gatewayConnections = mVcn.getVcnGatewayConnections();
assertFalse(gatewayConnections.isEmpty());
@@ -147,16 +158,17 @@ public class VcnTest {
}
}
- @Test
- public void testGatewayEnteringSafeModeNotifiesVcn() {
- final NetworkRequestListener requestListener = verifyAndGetRequestListener();
- for (final int capability : VcnGatewayConnectionConfigTest.EXPOSED_CAPS) {
- startVcnGatewayWithCapabilities(requestListener, capability);
+ private void triggerVcnRequestListeners(NetworkRequestListener requestListener) {
+ for (final int[] caps : TEST_CAPS) {
+ startVcnGatewayWithCapabilities(requestListener, caps);
}
+ }
- // Each Capability in EXPOSED_CAPS was split into a separate VcnGatewayConnection in #setUp.
- // Expect one VcnGatewayConnection per capability.
- final int numExpectedGateways = VcnGatewayConnectionConfigTest.EXPOSED_CAPS.length;
+ public Set<VcnGatewayConnection> startGatewaysAndGetGatewayConnections(
+ NetworkRequestListener requestListener) {
+ triggerVcnRequestListeners(requestListener);
+
+ final int numExpectedGateways = TEST_CAPS.length;
final Set<VcnGatewayConnection> gatewayConnections = mVcn.getVcnGatewayConnections();
assertEquals(numExpectedGateways, gatewayConnections.size());
@@ -168,17 +180,95 @@ public class VcnTest {
any(),
mGatewayStatusCallbackCaptor.capture());
- // Doesn't matter which callback this gets - any Gateway entering safe mode should shut down
- // all Gateways
- final VcnGatewayStatusCallback statusCallback = mGatewayStatusCallbackCaptor.getValue();
- statusCallback.onEnteredSafeMode();
- mTestLooper.dispatchAll();
+ return gatewayConnections;
+ }
+ private void verifySafeMode(
+ NetworkRequestListener requestListener,
+ Set<VcnGatewayConnection> expectedGatewaysTornDown) {
assertFalse(mVcn.isActive());
- for (final VcnGatewayConnection gatewayConnection : gatewayConnections) {
+ assertTrue(mVcn.getVcnGatewayConnections().isEmpty());
+ for (final VcnGatewayConnection gatewayConnection : expectedGatewaysTornDown) {
verify(gatewayConnection).teardownAsynchronously();
}
verify(mVcnNetworkProvider).unregisterListener(requestListener);
verify(mVcnCallback).onEnteredSafeMode();
}
+
+ @Test
+ public void testGatewayEnteringSafeModeNotifiesVcn() {
+ final NetworkRequestListener requestListener = verifyAndGetRequestListener();
+ final Set<VcnGatewayConnection> gatewayConnections =
+ startGatewaysAndGetGatewayConnections(requestListener);
+
+ // Doesn't matter which callback this gets - any Gateway entering Safemode should shut down
+ // all Gateways
+ final VcnGatewayStatusCallback statusCallback = mGatewayStatusCallbackCaptor.getValue();
+ statusCallback.onEnteredSafeMode();
+ mTestLooper.dispatchAll();
+
+ verifySafeMode(requestListener, gatewayConnections);
+ }
+
+ @Test
+ public void testGatewayQuit() {
+ final NetworkRequestListener requestListener = verifyAndGetRequestListener();
+ final Set<VcnGatewayConnection> gatewayConnections =
+ new ArraySet<>(startGatewaysAndGetGatewayConnections(requestListener));
+
+ final VcnGatewayStatusCallback statusCallback = mGatewayStatusCallbackCaptor.getValue();
+ statusCallback.onQuit();
+ mTestLooper.dispatchAll();
+
+ // Verify that the VCN requests the networkRequests be resent
+ assertEquals(1, mVcn.getVcnGatewayConnections().size());
+ verify(mVcnNetworkProvider).resendAllRequests(requestListener);
+
+ // Verify that the VcnGatewayConnection is restarted
+ triggerVcnRequestListeners(requestListener);
+ mTestLooper.dispatchAll();
+ assertEquals(2, mVcn.getVcnGatewayConnections().size());
+ verify(mDeps, times(gatewayConnections.size() + 1))
+ .newVcnGatewayConnection(
+ eq(mVcnContext),
+ eq(TEST_SUB_GROUP),
+ eq(mSubscriptionSnapshot),
+ any(),
+ mGatewayStatusCallbackCaptor.capture());
+ }
+
+ @Test
+ public void testUpdateConfigExitsSafeMode() {
+ final NetworkRequestListener requestListener = verifyAndGetRequestListener();
+ final Set<VcnGatewayConnection> gatewayConnections =
+ new ArraySet<>(startGatewaysAndGetGatewayConnections(requestListener));
+
+ final VcnGatewayStatusCallback statusCallback = mGatewayStatusCallbackCaptor.getValue();
+ statusCallback.onEnteredSafeMode();
+ mTestLooper.dispatchAll();
+ verifySafeMode(requestListener, gatewayConnections);
+
+ doAnswer(invocation -> {
+ final NetworkRequestListener listener = invocation.getArgument(0);
+ triggerVcnRequestListeners(listener);
+ return null;
+ }).when(mVcnNetworkProvider).registerListener(eq(requestListener));
+
+ mVcn.updateConfig(mConfig);
+ mTestLooper.dispatchAll();
+
+ // Registered on start, then re-registered with new configs
+ verify(mVcnNetworkProvider, times(2)).registerListener(eq(requestListener));
+ assertTrue(mVcn.isActive());
+ for (final int[] caps : TEST_CAPS) {
+ // Expect each gateway connection created on initial startup, and again with new configs
+ verify(mDeps, times(2))
+ .newVcnGatewayConnection(
+ eq(mVcnContext),
+ eq(TEST_SUB_GROUP),
+ eq(mSubscriptionSnapshot),
+ argThat(config -> Arrays.equals(caps, config.getExposedCapabilities())),
+ any());
+ }
+ }
}