diff options
Diffstat (limited to 'tests')
14 files changed, 420 insertions, 176 deletions
diff --git a/tests/SilkFX/OWNERS b/tests/SilkFX/OWNERS new file mode 100644 index 000000000000..c88a9f82c347 --- /dev/null +++ b/tests/SilkFX/OWNERS @@ -0,0 +1 @@ +include /libs/hwui/OWNERS diff --git a/tests/UpdatableSystemFontTest/Android.bp b/tests/UpdatableSystemFontTest/Android.bp index d4f1ad317d31..8b0ae5c37bae 100644 --- a/tests/UpdatableSystemFontTest/Android.bp +++ b/tests/UpdatableSystemFontTest/Android.bp @@ -24,18 +24,27 @@ package { java_test_host { name: "UpdatableSystemFontTest", srcs: ["src/**/*.java"], - libs: ["tradefed", "compatibility-tradefed", "compatibility-host-util"], + libs: [ + "tradefed", + "compatibility-tradefed", + "compatibility-host-util", + ], static_libs: [ "frameworks-base-hostutils", ], - test_suites: ["general-tests", "vts"], + test_suites: [ + "general-tests", + "vts", + ], data: [ ":NotoColorEmojiTtf", ":UpdatableSystemFontTestCertDer", ":UpdatableSystemFontTestNotoColorEmojiTtfFsvSig", - ":UpdatableSystemFontTestNotoColorEmojiV1Ttf", - ":UpdatableSystemFontTestNotoColorEmojiV1TtfFsvSig", - ":UpdatableSystemFontTestNotoColorEmojiV2Ttf", - ":UpdatableSystemFontTestNotoColorEmojiV2TtfFsvSig", + ":UpdatableSystemFontTestNotoColorEmojiV0Ttf", + ":UpdatableSystemFontTestNotoColorEmojiV0TtfFsvSig", + ":UpdatableSystemFontTestNotoColorEmojiVPlus1Ttf", + ":UpdatableSystemFontTestNotoColorEmojiVPlus1TtfFsvSig", + ":UpdatableSystemFontTestNotoColorEmojiVPlus2Ttf", + ":UpdatableSystemFontTestNotoColorEmojiVPlus2TtfFsvSig", ], } diff --git a/tests/UpdatableSystemFontTest/AndroidTest.xml b/tests/UpdatableSystemFontTest/AndroidTest.xml index efe5d703880c..d573e93e4a4c 100644 --- a/tests/UpdatableSystemFontTest/AndroidTest.xml +++ b/tests/UpdatableSystemFontTest/AndroidTest.xml @@ -24,10 +24,12 @@ <option name="push" value="UpdatableSystemFontTestCert.der->/data/local/tmp/UpdatableSystemFontTestCert.der" /> <option name="push" value="NotoColorEmoji.ttf->/data/local/tmp/NotoColorEmoji.ttf" /> <option name="push" value="UpdatableSystemFontTestNotoColorEmoji.ttf.fsv_sig->/data/local/tmp/UpdatableSystemFontTestNotoColorEmoji.ttf.fsv_sig" /> - <option name="push" value="UpdatableSystemFontTestNotoColorEmojiV1.ttf->/data/local/tmp/UpdatableSystemFontTestNotoColorEmojiV1.ttf" /> - <option name="push" value="UpdatableSystemFontTestNotoColorEmojiV1.ttf.fsv_sig->/data/local/tmp/UpdatableSystemFontTestNotoColorEmojiV1.ttf.fsv_sig" /> - <option name="push" value="UpdatableSystemFontTestNotoColorEmojiV2.ttf->/data/local/tmp/UpdatableSystemFontTestNotoColorEmojiV2.ttf" /> - <option name="push" value="UpdatableSystemFontTestNotoColorEmojiV2.ttf.fsv_sig->/data/local/tmp/UpdatableSystemFontTestNotoColorEmojiV2.ttf.fsv_sig" /> + <option name="push" value="UpdatableSystemFontTestNotoColorEmojiV0.ttf->/data/local/tmp/UpdatableSystemFontTestNotoColorEmojiV0.ttf" /> + <option name="push" value="UpdatableSystemFontTestNotoColorEmojiV0.ttf.fsv_sig->/data/local/tmp/UpdatableSystemFontTestNotoColorEmojiV0.ttf.fsv_sig" /> + <option name="push" value="UpdatableSystemFontTestNotoColorEmojiVPlus1.ttf->/data/local/tmp/UpdatableSystemFontTestNotoColorEmojiVPlus1.ttf" /> + <option name="push" value="UpdatableSystemFontTestNotoColorEmojiVPlus1.ttf.fsv_sig->/data/local/tmp/UpdatableSystemFontTestNotoColorEmojiVPlus1.ttf.fsv_sig" /> + <option name="push" value="UpdatableSystemFontTestNotoColorEmojiVPlus2.ttf->/data/local/tmp/UpdatableSystemFontTestNotoColorEmojiVPlus2.ttf" /> + <option name="push" value="UpdatableSystemFontTestNotoColorEmojiVPlus2.ttf.fsv_sig->/data/local/tmp/UpdatableSystemFontTestNotoColorEmojiVPlus2.ttf.fsv_sig" /> </target_preparer> <test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" > diff --git a/tests/UpdatableSystemFontTest/src/com/android/updatablesystemfont/UpdatableSystemFontTest.java b/tests/UpdatableSystemFontTest/src/com/android/updatablesystemfont/UpdatableSystemFontTest.java index 92fa498f8326..e68455612c7e 100644 --- a/tests/UpdatableSystemFontTest/src/com/android/updatablesystemfont/UpdatableSystemFontTest.java +++ b/tests/UpdatableSystemFontTest/src/com/android/updatablesystemfont/UpdatableSystemFontTest.java @@ -51,18 +51,26 @@ public class UpdatableSystemFontTest extends BaseHostJUnit4Test { private static final Pattern PATTERN_FONT = Pattern.compile("path = ([^, \n]*)"); private static final String NOTO_COLOR_EMOJI_TTF = "NotoColorEmoji.ttf"; - private static final String TEST_NOTO_COLOR_EMOJI_V1_TTF = - "/data/local/tmp/UpdatableSystemFontTestNotoColorEmojiV1.ttf"; - private static final String TEST_NOTO_COLOR_EMOJI_V1_TTF_FSV_SIG = - "/data/local/tmp/UpdatableSystemFontTestNotoColorEmojiV1.ttf.fsv_sig"; - private static final String TEST_NOTO_COLOR_EMOJI_V2_TTF = - "/data/local/tmp/UpdatableSystemFontTestNotoColorEmojiV2.ttf"; - private static final String TEST_NOTO_COLOR_EMOJI_V2_TTF_FSV_SIG = - "/data/local/tmp/UpdatableSystemFontTestNotoColorEmojiV2.ttf.fsv_sig"; + private static final String ORIGINAL_NOTO_COLOR_EMOJI_TTF = "/data/local/tmp/NotoColorEmoji.ttf"; private static final String ORIGINAL_NOTO_COLOR_EMOJI_TTF_FSV_SIG = "/data/local/tmp/UpdatableSystemFontTestNotoColorEmoji.ttf.fsv_sig"; + // A font with revision == 0. + private static final String TEST_NOTO_COLOR_EMOJI_V0_TTF = + "/data/local/tmp/UpdatableSystemFontTestNotoColorEmojiV0.ttf"; + private static final String TEST_NOTO_COLOR_EMOJI_V0_TTF_FSV_SIG = + "/data/local/tmp/UpdatableSystemFontTestNotoColorEmojiV0.ttf.fsv_sig"; + // A font with revision == original + 1 + private static final String TEST_NOTO_COLOR_EMOJI_VPLUS1_TTF = + "/data/local/tmp/UpdatableSystemFontTestNotoColorEmojiVPlus1.ttf"; + private static final String TEST_NOTO_COLOR_EMOJI_VPLUS1_TTF_FSV_SIG = + "/data/local/tmp/UpdatableSystemFontTestNotoColorEmojiVPlus1.ttf.fsv_sig"; + // A font with revision == original + 2 + private static final String TEST_NOTO_COLOR_EMOJI_VPLUS2_TTF = + "/data/local/tmp/UpdatableSystemFontTestNotoColorEmojiVPlus2.ttf"; + private static final String TEST_NOTO_COLOR_EMOJI_VPLUS2_TTF_FSV_SIG = + "/data/local/tmp/UpdatableSystemFontTestNotoColorEmojiVPlus2.ttf.fsv_sig"; @Rule public final AddFsVerityCertRule mAddFsverityCertRule = @@ -81,7 +89,7 @@ public class UpdatableSystemFontTest extends BaseHostJUnit4Test { @Test public void updateFont() throws Exception { expectRemoteCommandToSucceed(String.format("cmd font update %s %s", - TEST_NOTO_COLOR_EMOJI_V1_TTF, TEST_NOTO_COLOR_EMOJI_V1_TTF_FSV_SIG)); + TEST_NOTO_COLOR_EMOJI_VPLUS1_TTF, TEST_NOTO_COLOR_EMOJI_VPLUS1_TTF_FSV_SIG)); String fontPath = getFontPath(NOTO_COLOR_EMOJI_TTF); assertThat(fontPath).startsWith("/data/fonts/files/"); } @@ -89,19 +97,39 @@ public class UpdatableSystemFontTest extends BaseHostJUnit4Test { @Test public void updateFont_twice() throws Exception { expectRemoteCommandToSucceed(String.format("cmd font update %s %s", - TEST_NOTO_COLOR_EMOJI_V1_TTF, TEST_NOTO_COLOR_EMOJI_V1_TTF_FSV_SIG)); + TEST_NOTO_COLOR_EMOJI_VPLUS1_TTF, TEST_NOTO_COLOR_EMOJI_VPLUS1_TTF_FSV_SIG)); String fontPath = getFontPath(NOTO_COLOR_EMOJI_TTF); expectRemoteCommandToSucceed(String.format("cmd font update %s %s", - TEST_NOTO_COLOR_EMOJI_V2_TTF, TEST_NOTO_COLOR_EMOJI_V2_TTF_FSV_SIG)); + TEST_NOTO_COLOR_EMOJI_VPLUS2_TTF, TEST_NOTO_COLOR_EMOJI_VPLUS2_TTF_FSV_SIG)); String fontPath2 = getFontPath(NOTO_COLOR_EMOJI_TTF); assertThat(fontPath2).startsWith("/data/fonts/files/"); assertThat(fontPath2).isNotEqualTo(fontPath); } @Test + public void updateFont_allowSameVersion() throws Exception { + // Update original font to the same version + expectRemoteCommandToSucceed(String.format("cmd font update %s %s", + ORIGINAL_NOTO_COLOR_EMOJI_TTF, ORIGINAL_NOTO_COLOR_EMOJI_TTF_FSV_SIG)); + String fontPath = getFontPath(NOTO_COLOR_EMOJI_TTF); + expectRemoteCommandToSucceed(String.format("cmd font update %s %s", + TEST_NOTO_COLOR_EMOJI_VPLUS1_TTF, TEST_NOTO_COLOR_EMOJI_VPLUS1_TTF_FSV_SIG)); + String fontPath2 = getFontPath(NOTO_COLOR_EMOJI_TTF); + // Update updated font to the same version + expectRemoteCommandToSucceed(String.format("cmd font update %s %s", + TEST_NOTO_COLOR_EMOJI_VPLUS1_TTF, TEST_NOTO_COLOR_EMOJI_VPLUS1_TTF_FSV_SIG)); + String fontPath3 = getFontPath(NOTO_COLOR_EMOJI_TTF); + assertThat(fontPath).startsWith("/data/fonts/files/"); + assertThat(fontPath2).isNotEqualTo(fontPath); + assertThat(fontPath2).startsWith("/data/fonts/files/"); + assertThat(fontPath3).startsWith("/data/fonts/files/"); + assertThat(fontPath3).isNotEqualTo(fontPath); + } + + @Test public void updatedFont_dataFileIsImmutableAndReadable() throws Exception { expectRemoteCommandToSucceed(String.format("cmd font update %s %s", - TEST_NOTO_COLOR_EMOJI_V1_TTF, TEST_NOTO_COLOR_EMOJI_V1_TTF_FSV_SIG)); + TEST_NOTO_COLOR_EMOJI_VPLUS1_TTF, TEST_NOTO_COLOR_EMOJI_VPLUS1_TTF_FSV_SIG)); String fontPath = getFontPath(NOTO_COLOR_EMOJI_TTF); assertThat(fontPath).startsWith("/data"); @@ -112,27 +140,27 @@ public class UpdatableSystemFontTest extends BaseHostJUnit4Test { @Test public void updateFont_invalidCert() throws Exception { expectRemoteCommandToFail(String.format("cmd font update %s %s", - TEST_NOTO_COLOR_EMOJI_V1_TTF, TEST_NOTO_COLOR_EMOJI_V2_TTF_FSV_SIG)); + TEST_NOTO_COLOR_EMOJI_VPLUS1_TTF, TEST_NOTO_COLOR_EMOJI_VPLUS2_TTF_FSV_SIG)); } @Test public void updateFont_downgradeFromSystem() throws Exception { expectRemoteCommandToFail(String.format("cmd font update %s %s", - ORIGINAL_NOTO_COLOR_EMOJI_TTF, ORIGINAL_NOTO_COLOR_EMOJI_TTF_FSV_SIG)); + TEST_NOTO_COLOR_EMOJI_V0_TTF, TEST_NOTO_COLOR_EMOJI_V0_TTF_FSV_SIG)); } @Test public void updateFont_downgradeFromData() throws Exception { expectRemoteCommandToSucceed(String.format("cmd font update %s %s", - TEST_NOTO_COLOR_EMOJI_V2_TTF, TEST_NOTO_COLOR_EMOJI_V2_TTF_FSV_SIG)); + TEST_NOTO_COLOR_EMOJI_VPLUS2_TTF, TEST_NOTO_COLOR_EMOJI_VPLUS2_TTF_FSV_SIG)); expectRemoteCommandToFail(String.format("cmd font update %s %s", - TEST_NOTO_COLOR_EMOJI_V1_TTF, TEST_NOTO_COLOR_EMOJI_V1_TTF_FSV_SIG)); + TEST_NOTO_COLOR_EMOJI_VPLUS1_TTF, TEST_NOTO_COLOR_EMOJI_VPLUS1_TTF_FSV_SIG)); } @Test public void reboot() throws Exception { expectRemoteCommandToSucceed(String.format("cmd font update %s %s", - TEST_NOTO_COLOR_EMOJI_V1_TTF, TEST_NOTO_COLOR_EMOJI_V1_TTF_FSV_SIG)); + TEST_NOTO_COLOR_EMOJI_VPLUS1_TTF, TEST_NOTO_COLOR_EMOJI_VPLUS1_TTF_FSV_SIG)); String fontPath = getFontPath(NOTO_COLOR_EMOJI_TTF); assertThat(fontPath).startsWith("/data/fonts/files/"); @@ -182,17 +210,6 @@ public class UpdatableSystemFontTest extends BaseHostJUnit4Test { }); } - private void waitUntilSystemServerIsGone() { - waitUntil(TimeUnit.SECONDS.toMillis(30), () -> { - try { - return getDevice().executeShellV2Command("pid system_server").getStatus() - == CommandStatus.FAILED; - } catch (DeviceNotAvailableException e) { - return false; - } - }); - } - private void waitUntil(long timeoutMillis, Supplier<Boolean> func) { long untilMillis = System.currentTimeMillis() + timeoutMillis; do { diff --git a/tests/UpdatableSystemFontTest/testdata/Android.bp b/tests/UpdatableSystemFontTest/testdata/Android.bp index f744d5dd2b51..0f01be014d52 100644 --- a/tests/UpdatableSystemFontTest/testdata/Android.bp +++ b/tests/UpdatableSystemFontTest/testdata/Android.bp @@ -38,31 +38,48 @@ filegroup { genrule_defaults { name: "updatable_system_font_increment_font_revision_default", +} + +genrule { + name: "UpdatableSystemFontTestNotoColorEmojiV0Ttf", + srcs: [":NotoColorEmojiTtf"], + out: ["UpdatableSystemFontTestNotoColorEmojiV0.ttf"], tools: ["update_font_metadata"], cmd: "$(location update_font_metadata) " + "--input=$(in) " + "--output=$(out) " + - "--revision=+1", + "--revision=0", } genrule { - name: "UpdatableSystemFontTestNotoColorEmojiV1Ttf", - defaults: ["updatable_system_font_increment_font_revision_default"], + name: "UpdatableSystemFontTestNotoColorEmojiVPlus1Ttf", srcs: [":NotoColorEmojiTtf"], - out: ["UpdatableSystemFontTestNotoColorEmojiV1.ttf"], + out: ["UpdatableSystemFontTestNotoColorEmojiVPlus1.ttf"], + tools: ["update_font_metadata"], + cmd: "$(location update_font_metadata) " + + "--input=$(in) " + + "--output=$(out) " + + "--revision=+1", } genrule { - name: "UpdatableSystemFontTestNotoColorEmojiV2Ttf", - defaults: ["updatable_system_font_increment_font_revision_default"], - srcs: [":UpdatableSystemFontTestNotoColorEmojiV1Ttf"], - out: ["UpdatableSystemFontTestNotoColorEmojiV2.ttf"], + name: "UpdatableSystemFontTestNotoColorEmojiVPlus2Ttf", + srcs: [":NotoColorEmojiTtf"], + out: ["UpdatableSystemFontTestNotoColorEmojiVPlus2.ttf"], + tools: ["update_font_metadata"], + cmd: "$(location update_font_metadata) " + + "--input=$(in) " + + "--output=$(out) " + + "--revision=+2", } genrule_defaults { name: "updatable_system_font_sig_gen_default", tools: ["fsverity"], - tool_files: [":UpdatableSystemFontTestKeyPem", ":UpdatableSystemFontTestCertPem"], + tool_files: [ + ":UpdatableSystemFontTestKeyPem", + ":UpdatableSystemFontTestCertPem", + ], cmd: "$(location fsverity) sign $(in) $(out) " + "--key=$(location :UpdatableSystemFontTestKeyPem) " + "--cert=$(location :UpdatableSystemFontTestCertPem) " + @@ -77,15 +94,22 @@ genrule { } genrule { - name: "UpdatableSystemFontTestNotoColorEmojiV1TtfFsvSig", + name: "UpdatableSystemFontTestNotoColorEmojiV0TtfFsvSig", + defaults: ["updatable_system_font_sig_gen_default"], + srcs: [":UpdatableSystemFontTestNotoColorEmojiV0Ttf"], + out: ["UpdatableSystemFontTestNotoColorEmojiV0.ttf.fsv_sig"], +} + +genrule { + name: "UpdatableSystemFontTestNotoColorEmojiVPlus1TtfFsvSig", defaults: ["updatable_system_font_sig_gen_default"], - srcs: [":UpdatableSystemFontTestNotoColorEmojiV1Ttf"], - out: ["UpdatableSystemFontTestNotoColorEmojiV1.ttf.fsv_sig"], + srcs: [":UpdatableSystemFontTestNotoColorEmojiVPlus1Ttf"], + out: ["UpdatableSystemFontTestNotoColorEmojiVPlus1.ttf.fsv_sig"], } genrule { - name: "UpdatableSystemFontTestNotoColorEmojiV2TtfFsvSig", + name: "UpdatableSystemFontTestNotoColorEmojiVPlus2TtfFsvSig", defaults: ["updatable_system_font_sig_gen_default"], - srcs: [":UpdatableSystemFontTestNotoColorEmojiV2Ttf"], - out: ["UpdatableSystemFontTestNotoColorEmojiV2.ttf.fsv_sig"], + srcs: [":UpdatableSystemFontTestNotoColorEmojiVPlus2Ttf"], + out: ["UpdatableSystemFontTestNotoColorEmojiVPlus2.ttf.fsv_sig"], } diff --git a/tests/UsesFeature2Test/AndroidManifest.xml b/tests/UsesFeature2Test/AndroidManifest.xml index 1f1a90958298..a0ea45adae19 100644 --- a/tests/UsesFeature2Test/AndroidManifest.xml +++ b/tests/UsesFeature2Test/AndroidManifest.xml @@ -23,6 +23,7 @@ <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> + <uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE"/> <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" /> <uses-permission android:name="android.permission.BLUETOOTH_SCAN" /> diff --git a/tests/net/common/java/android/net/TcpKeepalivePacketDataTest.kt b/tests/net/common/java/android/net/TcpKeepalivePacketDataTest.kt index 677006692f84..7a18bb08faa8 100644 --- a/tests/net/common/java/android/net/TcpKeepalivePacketDataTest.kt +++ b/tests/net/common/java/android/net/TcpKeepalivePacketDataTest.kt @@ -92,12 +92,12 @@ class TcpKeepalivePacketDataTest { assertTrue(str.contains(data.dstAddress.hostAddress)) assertTrue(str.contains(data.dstPort.toString())) // .packet not included in toString() - assertTrue(str.contains(data.tcpSeq.toString())) - assertTrue(str.contains(data.tcpAck.toString())) - assertTrue(str.contains(data.tcpWindow.toString())) - assertTrue(str.contains(data.tcpWindowScale.toString())) - assertTrue(str.contains(data.ipTos.toString())) - assertTrue(str.contains(data.ipTtl.toString())) + assertTrue(str.contains(data.getTcpSeq().toString())) + assertTrue(str.contains(data.getTcpAck().toString())) + assertTrue(str.contains(data.getTcpWindow().toString())) + assertTrue(str.contains(data.getTcpWindowScale().toString())) + assertTrue(str.contains(data.getIpTos().toString())) + assertTrue(str.contains(data.getIpTtl().toString())) // Update above assertions if field is added assertFieldCountEquals(5, KeepalivePacketData::class.java) diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java index af7eb59a3d55..3865fdfe7c68 100644 --- a/tests/net/java/com/android/server/ConnectivityServiceTest.java +++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java @@ -18,6 +18,7 @@ package com.android.server; import static android.Manifest.permission.CHANGE_NETWORK_STATE; import static android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS; +import static android.Manifest.permission.DUMP; import static android.Manifest.permission.NETWORK_FACTORY; import static android.Manifest.permission.NETWORK_SETTINGS; import static android.app.PendingIntent.FLAG_IMMUTABLE; @@ -63,6 +64,7 @@ import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_HTTPS; import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_PRIVDNS; import static android.net.INetworkMonitor.NETWORK_VALIDATION_RESULT_PARTIAL; import static android.net.INetworkMonitor.NETWORK_VALIDATION_RESULT_VALID; +import static android.net.NetworkCapabilities.NET_CAPABILITY_BIP; 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; @@ -89,6 +91,7 @@ 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_VSIM; import static android.net.NetworkCapabilities.NET_CAPABILITY_WIFI_P2P; import static android.net.NetworkCapabilities.NET_CAPABILITY_XCAP; import static android.net.NetworkCapabilities.REDACT_FOR_ACCESS_FINE_LOCATION; @@ -354,6 +357,8 @@ import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; import java.util.function.Predicate; import java.util.function.Supplier; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import java.util.stream.Collectors; import kotlin.reflect.KClass; @@ -3030,10 +3035,11 @@ public class ConnectivityServiceTest { // Verify NOT_RESTRICTED is set appropriately final NetworkCapabilities nc = new NetworkRequest.Builder().addCapability(capability) .build().networkCapabilities; - 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 + 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_VSIM || capability == NET_CAPABILITY_BIP || capability == NET_CAPABILITY_ENTERPRISE) { assertFalse(nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)); } else { @@ -3168,6 +3174,8 @@ public class ConnectivityServiceTest { tryNetworkFactoryRequests(NET_CAPABILITY_INTERNET); tryNetworkFactoryRequests(NET_CAPABILITY_TRUSTED); tryNetworkFactoryRequests(NET_CAPABILITY_NOT_VPN); + tryNetworkFactoryRequests(NET_CAPABILITY_VSIM); + tryNetworkFactoryRequests(NET_CAPABILITY_BIP); // Skipping VALIDATED and CAPTIVE_PORTAL as they're disallowed. } @@ -9251,7 +9259,7 @@ public class ConnectivityServiceTest { final int expectedOwnerUidWithoutIncludeFlag = shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag - ? Process.myUid() : INVALID_UID; + ? myUid : INVALID_UID; assertEquals(expectedOwnerUidWithoutIncludeFlag, getOwnerUidNetCapsPermission( myUid, myUid, false /* includeLocationSensitiveInfo */)); @@ -9270,40 +9278,35 @@ public class ConnectivityServiceTest { } - @Test - public void testCreateWithLocationInfoSanitizedWithFineLocationAfterQ() - throws Exception { - setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION, - Manifest.permission.ACCESS_FINE_LOCATION); - + private void verifyOwnerUidAndTransportInfoNetCapsPermissionPreS() { verifyOwnerUidAndTransportInfoNetCapsPermission( - // Ensure that we include owner uid even if the request asks to remove it since the - // app has necessary permissions and targetSdk < S. + // Ensure that owner uid is included even if the request asks to remove it (which is + // the default) since the app has necessary permissions and targetSdk < S. true, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */ true, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */ - false, /* shouldInclLocationSensitiveTransportInfoWithoutIncludeFlag */ - // Ensure that we remove location info if the request asks to remove it even if the + // Ensure that location info is removed if the request asks to remove it even if the // app has necessary permissions. + false, /* shouldInclLocationSensitiveTransportInfoWithoutIncludeFlag */ true /* shouldInclLocationSensitiveTransportInfoWithIncludeFlag */ ); } @Test + public void testCreateWithLocationInfoSanitizedWithFineLocationAfterQPreS() + throws Exception { + setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION); + + verifyOwnerUidAndTransportInfoNetCapsPermissionPreS(); + } + + @Test public void testCreateWithLocationInfoSanitizedWithFineLocationPreSWithAndWithoutCallbackFlag() throws Exception { setupLocationPermissions(Build.VERSION_CODES.R, true, AppOpsManager.OPSTR_FINE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION); - verifyOwnerUidAndTransportInfoNetCapsPermission( - // Ensure that we include owner uid even if the request asks to remove it since the - // app has necessary permissions and targetSdk < S. - true, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */ - true, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */ - false, /* shouldInclLocationSensitiveTransportInfoWithoutIncludeFlag */ - // Ensure that we remove location info if the request asks to remove it even if the - // app has necessary permissions. - true /* shouldInclLocationSensitiveTransportInfoWithIncludeFlag */ - ); + verifyOwnerUidAndTransportInfoNetCapsPermissionPreS(); } @Test @@ -9314,13 +9317,13 @@ public class ConnectivityServiceTest { Manifest.permission.ACCESS_FINE_LOCATION); verifyOwnerUidAndTransportInfoNetCapsPermission( - // Ensure that we owner UID if the request asks us to remove it even if the app - // has necessary permissions since targetSdk >= S. + // Ensure that the owner UID is removed if the request asks us to remove it even + // if the app has necessary permissions since targetSdk >= S. false, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */ true, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */ - false, /* shouldInclLocationSensitiveTransportInfoWithoutIncludeFlag */ - // Ensure that we remove location info if the request asks to remove it even if the + // Ensure that location info is removed if the request asks to remove it even if the // app has necessary permissions. + false, /* shouldInclLocationSensitiveTransportInfoWithoutIncludeFlag */ true /* shouldInclLocationSensitiveTransportInfoWithIncludeFlag */ ); } @@ -9331,15 +9334,15 @@ public class ConnectivityServiceTest { setupLocationPermissions(Build.VERSION_CODES.P, true, AppOpsManager.OPSTR_COARSE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION); + verifyOwnerUidAndTransportInfoNetCapsPermissionPreS(); + } + + private void verifyOwnerUidAndTransportInfoNetCapsNotIncluded() { verifyOwnerUidAndTransportInfoNetCapsPermission( - // Ensure that we owner UID if the request asks us to remove it even if the app - // has necessary permissions since targetSdk >= S. - true, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */ - true, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */ + false, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */ + false, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */ false, /* shouldInclLocationSensitiveTransportInfoWithoutIncludeFlag */ - // Ensure that we remove location info if the request asks to remove it even if the - // app has necessary permissions. - true /* shouldInclLocationSensitiveTransportInfoWithIncludeFlag */ + false /* shouldInclLocationSensitiveTransportInfoWithIncludeFlag */ ); } @@ -9349,12 +9352,7 @@ public class ConnectivityServiceTest { setupLocationPermissions(Build.VERSION_CODES.Q, false, AppOpsManager.OPSTR_FINE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION); - verifyOwnerUidAndTransportInfoNetCapsPermission( - false, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */ - false, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */ - false, /* shouldInclLocationSensitiveTransportInfoWithoutIncludeFlag */ - false /* shouldInclLocationSensitiveTransportInfoWithIncludeFlag */ - ); + verifyOwnerUidAndTransportInfoNetCapsNotIncluded(); } @Test @@ -9376,26 +9374,17 @@ public class ConnectivityServiceTest { setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_COARSE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION); - verifyOwnerUidAndTransportInfoNetCapsPermission( - false, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */ - false, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */ - false, /* shouldInclLocationSensitiveTransportInfoWithoutIncludeFlag */ - false /* shouldInclLocationSensitiveTransportInfoWithIncludeFlag */ - ); + verifyOwnerUidAndTransportInfoNetCapsNotIncluded(); } @Test - public void testCreateWithLocationInfoSanitizedWithoutLocationPermission() + public void testCreateWithLocationInfoSanitizedWithCoarseLocationAfterS() throws Exception { // Test that not having fine location permission leads to sanitization. - setupLocationPermissions(Build.VERSION_CODES.Q, true, null /* op */, null /* perm */); + setupLocationPermissions(Build.VERSION_CODES.S, true, AppOpsManager.OPSTR_COARSE_LOCATION, + Manifest.permission.ACCESS_COARSE_LOCATION); - verifyOwnerUidAndTransportInfoNetCapsPermission( - false, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */ - false, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */ - false, /* shouldInclLocationSensitiveTransportInfoWithoutIncludeFlag */ - false /* shouldInclLocationSensitiveTransportInfoWithIncludeFlag */ - ); + verifyOwnerUidAndTransportInfoNetCapsNotIncluded(); } @Test @@ -10063,6 +10052,7 @@ public class ConnectivityServiceTest { @Test public void testDumpDoesNotCrash() { + mServiceContext.setPermission(DUMP, PERMISSION_GRANTED); // Filing a couple requests prior to testing the dump. final TestNetworkCallback genericNetworkCallback = new TestNetworkCallback(); final TestNetworkCallback wifiNetworkCallback = new TestNetworkCallback(); @@ -12006,6 +11996,33 @@ public class ConnectivityServiceTest { } @Test + public void testSetOemNetworkPreferenceLogsRequest() throws Exception { + mServiceContext.setPermission(DUMP, PERMISSION_GRANTED); + @OemNetworkPreferences.OemNetworkPreference final int networkPref = + OEM_NETWORK_PREFERENCE_OEM_PAID; + final StringWriter stringWriter = new StringWriter(); + final String logIdentifier = "UPDATE INITIATED: OemNetworkPreferences"; + final Pattern pattern = Pattern.compile(logIdentifier); + + final int expectedNumLogs = 2; + final UidRangeParcel[] uidRanges = + toUidRangeStableParcels(uidRangesForUids(TEST_PACKAGE_UID)); + + // Call twice to generate two logs. + setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges, TEST_PACKAGE_NAME); + setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges, TEST_PACKAGE_NAME); + mService.dump(new FileDescriptor(), new PrintWriter(stringWriter), new String[0]); + + final String dumpOutput = stringWriter.toString(); + final Matcher matcher = pattern.matcher(dumpOutput); + int count = 0; + while (matcher.find()) { + count++; + } + assertEquals(expectedNumLogs, count); + } + + @Test public void testGetAllNetworkStateSnapshot() throws Exception { verifyNoNetwork(); diff --git a/tests/net/java/com/android/server/connectivity/FullScoreTest.kt b/tests/net/java/com/android/server/connectivity/FullScoreTest.kt index f0d7d86feb2f..45b575a4365d 100644 --- a/tests/net/java/com/android/server/connectivity/FullScoreTest.kt +++ b/tests/net/java/com/android/server/connectivity/FullScoreTest.kt @@ -56,7 +56,7 @@ class FullScoreTest { if (vpn) addTransportType(NetworkCapabilities.TRANSPORT_VPN) if (validated) addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED) }.build() - return mixInScore(nc, nac, false /* avoidBadWifi */) + return mixInScore(nc, nac, validated, false /* yieldToBadWifi */) } @Test diff --git a/tests/net/java/com/android/server/connectivity/NetworkNotificationManagerTest.java b/tests/net/java/com/android/server/connectivity/NetworkNotificationManagerTest.java index 2f3ee68249ab..c353cea266bb 100644 --- a/tests/net/java/com/android/server/connectivity/NetworkNotificationManagerTest.java +++ b/tests/net/java/com/android/server/connectivity/NetworkNotificationManagerTest.java @@ -16,8 +16,16 @@ package com.android.server.connectivity; -import static com.android.server.connectivity.NetworkNotificationManager.NotificationType.*; +import static android.app.Notification.FLAG_ONGOING_EVENT; +import static com.android.server.connectivity.NetworkNotificationManager.NotificationType.LOST_INTERNET; +import static com.android.server.connectivity.NetworkNotificationManager.NotificationType.NETWORK_SWITCH; +import static com.android.server.connectivity.NetworkNotificationManager.NotificationType.NO_INTERNET; +import static com.android.server.connectivity.NetworkNotificationManager.NotificationType.PARTIAL_CONNECTIVITY; +import static com.android.server.connectivity.NetworkNotificationManager.NotificationType.PRIVATE_DNS_BROKEN; +import static com.android.server.connectivity.NetworkNotificationManager.NotificationType.SIGN_IN; + +import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.any; import static org.mockito.Mockito.anyInt; import static org.mockito.Mockito.clearInvocations; @@ -230,19 +238,47 @@ public class NetworkNotificationManagerTest { verify(mNotificationManager, never()).notify(any(), anyInt(), any()); } + private void assertNotification(NotificationType type, boolean ongoing) { + final int id = 101; + final String tag = NetworkNotificationManager.tagFor(id); + final ArgumentCaptor<Notification> noteCaptor = ArgumentCaptor.forClass(Notification.class); + mManager.showNotification(id, type, mWifiNai, mCellNai, null, false); + verify(mNotificationManager, times(1)).notify(eq(tag), eq(type.eventId), + noteCaptor.capture()); + + assertEquals("Notification ongoing flag should be " + (ongoing ? "set" : "unset"), + ongoing, (noteCaptor.getValue().flags & FLAG_ONGOING_EVENT) != 0); + } + @Test public void testDuplicatedNotificationsNoInternetThenSignIn() { final int id = 101; final String tag = NetworkNotificationManager.tagFor(id); // Show first NO_INTERNET - mManager.showNotification(id, NO_INTERNET, mWifiNai, mCellNai, null, false); - verify(mNotificationManager, times(1)).notify(eq(tag), eq(NO_INTERNET.eventId), any()); + assertNotification(NO_INTERNET, false /* ongoing */); // Captive portal detection triggers SIGN_IN a bit later, clearing the previous NO_INTERNET - mManager.showNotification(id, SIGN_IN, mWifiNai, mCellNai, null, false); + assertNotification(SIGN_IN, false /* ongoing */); + verify(mNotificationManager, times(1)).cancel(eq(tag), eq(NO_INTERNET.eventId)); + + // Network disconnects + mManager.clearNotification(id); + verify(mNotificationManager, times(1)).cancel(eq(tag), eq(SIGN_IN.eventId)); + } + + @Test + public void testOngoingSignInNotification() { + doReturn(true).when(mResources).getBoolean(R.bool.config_ongoingSignInNotification); + final int id = 101; + final String tag = NetworkNotificationManager.tagFor(id); + + // Show first NO_INTERNET + assertNotification(NO_INTERNET, false /* ongoing */); + + // Captive portal detection triggers SIGN_IN a bit later, clearing the previous NO_INTERNET + assertNotification(SIGN_IN, true /* ongoing */); verify(mNotificationManager, times(1)).cancel(eq(tag), eq(NO_INTERNET.eventId)); - verify(mNotificationManager, times(1)).notify(eq(tag), eq(SIGN_IN.eventId), any()); // Network disconnects mManager.clearNotification(id); diff --git a/tests/vcn/java/com/android/server/VcnManagementServiceTest.java b/tests/vcn/java/com/android/server/VcnManagementServiceTest.java index 43e6676e1d4c..bbc9bb600f6d 100644 --- a/tests/vcn/java/com/android/server/VcnManagementServiceTest.java +++ b/tests/vcn/java/com/android/server/VcnManagementServiceTest.java @@ -81,7 +81,6 @@ import android.telephony.TelephonyManager; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; -import com.android.net.module.util.LocationPermissionChecker; import com.android.server.VcnManagementService.VcnCallback; import com.android.server.VcnManagementService.VcnStatusCallbackInfo; import com.android.server.vcn.TelephonySubscriptionTracker; @@ -162,8 +161,6 @@ public class VcnManagementServiceTest { mock(PersistableBundleUtils.LockingReadWriteHelper.class); private final TelephonySubscriptionTracker mSubscriptionTracker = mock(TelephonySubscriptionTracker.class); - private final LocationPermissionChecker mLocationPermissionChecker = - mock(LocationPermissionChecker.class); private final ArgumentCaptor<VcnCallback> mVcnCallbackCaptor = ArgumentCaptor.forClass(VcnCallback.class); @@ -207,9 +204,6 @@ public class VcnManagementServiceTest { doReturn(mConfigReadWriteHelper) .when(mMockDeps) .newPersistableBundleLockingReadWriteHelper(any()); - doReturn(mLocationPermissionChecker) - .when(mMockDeps) - .newLocationPermissionChecker(eq(mMockContext)); // Setup VCN instance generation doAnswer((invocation) -> { @@ -521,10 +515,6 @@ 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); @@ -697,10 +687,6 @@ public class VcnManagementServiceTest { doReturn(isVcnActive ? VCN_STATUS_CODE_ACTIVE : VCN_STATUS_CODE_SAFE_MODE) .when(vcn) .getStatus(); - - doReturn(true) - .when(mLocationPermissionChecker) - .checkLocationPermission(eq(TEST_PACKAGE_NAME), any(), eq(TEST_UID), any()); } private NetworkCapabilities.Builder getNetworkCapabilitiesBuilderForTransport( @@ -933,8 +919,7 @@ public class VcnManagementServiceTest { @NonNull ParcelUuid subGroup, @NonNull String pkgName, int uid, - boolean hasPermissionsforSubGroup, - boolean hasLocationPermission) + boolean hasPermissionsforSubGroup) throws Exception { TelephonySubscriptionSnapshot snapshot = triggerSubscriptionTrackerCbAndGetSnapshot(Collections.singleton(subGroup)); @@ -946,10 +931,6 @@ public class VcnManagementServiceTest { .when(snapshot) .packageHasPermissionsForSubscriptionGroup(eq(subGroup), eq(pkgName)); - doReturn(hasLocationPermission) - .when(mLocationPermissionChecker) - .checkLocationPermission(eq(pkgName), any(), eq(uid), any()); - mVcnMgmtSvc.registerVcnStatusCallback(subGroup, mMockStatusCallback, pkgName); triggerVcnSafeMode(subGroup, snapshot, true /* enterSafeMode */); @@ -959,11 +940,7 @@ public class VcnManagementServiceTest { public void testVcnStatusCallbackOnSafeModeStatusChangedWithCarrierPrivileges() throws Exception { triggerVcnStatusCallbackOnSafeModeStatusChanged( - TEST_UUID_1, - TEST_PACKAGE_NAME, - TEST_UID, - true /* hasPermissionsforSubGroup */, - true /* hasLocationPermission */); + TEST_UUID_1, TEST_PACKAGE_NAME, TEST_UID, true /* hasPermissionsforSubGroup */); verify(mMockStatusCallback).onVcnStatusChanged(VcnManager.VCN_STATUS_CODE_SAFE_MODE); } @@ -972,25 +949,7 @@ public class VcnManagementServiceTest { public void testVcnStatusCallbackOnSafeModeStatusChangedWithoutCarrierPrivileges() throws Exception { triggerVcnStatusCallbackOnSafeModeStatusChanged( - TEST_UUID_1, - TEST_PACKAGE_NAME, - TEST_UID, - false /* hasPermissionsforSubGroup */, - true /* hasLocationPermission */); - - verify(mMockStatusCallback, never()) - .onVcnStatusChanged(VcnManager.VCN_STATUS_CODE_SAFE_MODE); - } - - @Test - public void testVcnStatusCallbackOnSafeModeStatusChangedWithoutLocationPermission() - throws Exception { - triggerVcnStatusCallbackOnSafeModeStatusChanged( - TEST_UUID_1, - TEST_PACKAGE_NAME, - TEST_UID, - true /* hasPermissionsforSubGroup */, - false /* hasLocationPermission */); + TEST_UUID_1, TEST_PACKAGE_NAME, TEST_UID, false /* hasPermissionsforSubGroup */); verify(mMockStatusCallback, never()) .onVcnStatusChanged(VcnManager.VCN_STATUS_CODE_SAFE_MODE); @@ -1052,9 +1011,6 @@ public class VcnManagementServiceTest { .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); diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java index 34c00182f855..bb67593d84ba 100644 --- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java +++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java @@ -26,6 +26,7 @@ import static android.net.vcn.VcnManager.VCN_ERROR_CODE_NETWORK_ERROR; import static com.android.server.vcn.VcnGatewayConnection.VcnChildSessionConfiguration; import static com.android.server.vcn.VcnGatewayConnection.VcnIkeSession; +import static com.android.server.vcn.VcnGatewayConnection.VcnNetworkAgent; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -46,15 +47,19 @@ import android.net.LinkAddress; import android.net.LinkProperties; import android.net.NetworkAgent; import android.net.NetworkCapabilities; +import android.net.ipsec.ike.ChildSaProposal; import android.net.ipsec.ike.exceptions.AuthenticationFailedException; import android.net.ipsec.ike.exceptions.IkeException; import android.net.ipsec.ike.exceptions.IkeInternalException; import android.net.ipsec.ike.exceptions.TemporaryFailureException; +import android.net.vcn.VcnControlPlaneIkeConfig; import android.net.vcn.VcnManager.VcnErrorCode; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; +import com.android.server.vcn.util.MtuUtils; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -73,13 +78,13 @@ import java.util.function.Consumer; @SmallTest public class VcnGatewayConnectionConnectedStateTest extends VcnGatewayConnectionTestBase { private VcnIkeSession mIkeSession; - private NetworkAgent mNetworkAgent; + private VcnNetworkAgent mNetworkAgent; @Before public void setUp() throws Exception { super.setUp(); - mNetworkAgent = mock(NetworkAgent.class); + mNetworkAgent = mock(VcnNetworkAgent.class); doReturn(mNetworkAgent) .when(mDeps) .newNetworkAgent(any(), any(), any(), any(), anyInt(), any(), any(), any(), any()); @@ -152,7 +157,9 @@ public class VcnGatewayConnectionConnectedStateTest extends VcnGatewayConnection } @Test - public void testMigratedTransformsAreApplied() throws Exception { + public void testMigration() throws Exception { + triggerChildOpened(); + getChildSessionCallback() .onIpSecTransformsMigrated(makeDummyIpSecTransform(), makeDummyIpSecTransform()); mTestLooper.dispatchAll(); @@ -170,6 +177,17 @@ public class VcnGatewayConnectionConnectedStateTest extends VcnGatewayConnection } assertEquals(mGatewayConnection.mConnectedState, mGatewayConnection.getCurrentState()); + + final List<ChildSaProposal> saProposals = + ((VcnControlPlaneIkeConfig) mConfig.getControlPlaneConfig()) + .getChildSessionParams() + .getSaProposals(); + final int expectedMtu = + MtuUtils.getMtu( + saProposals, + mConfig.getMaxMtu(), + TEST_UNDERLYING_NETWORK_RECORD_1.linkProperties.getMtu()); + verify(mNetworkAgent).sendLinkProperties(argThat(lp -> expectedMtu == lp.getMtu())); } private void triggerChildOpened() { @@ -299,8 +317,9 @@ public class VcnGatewayConnectionConnectedStateTest extends VcnGatewayConnection .removeAddressFromTunnelInterface( eq(TEST_IPSEC_TUNNEL_RESOURCE_ID), eq(TEST_INTERNAL_ADDR), any()); - // TODO(b/184579891): Also verify link properties updated and sent when sendLinkProperties - // is mockable + verify(mNetworkAgent).sendLinkProperties(argThat( + lp -> newInternalAddrs.equals(lp.getLinkAddresses()) + && Collections.singletonList(TEST_DNS_ADDR_2).equals(lp.getDnsServers()))); // Verify that IpSecTunnelInterface only created once verify(mIpSecSvc).createTunnelInterface(any(), any(), any(), any(), any()); @@ -323,6 +342,66 @@ public class VcnGatewayConnectionConnectedStateTest extends VcnGatewayConnection assertFalse(mGatewayConnection.isInSafeMode()); } + private Consumer<VcnNetworkAgent> setupNetworkAndGetUnwantedCallback() { + triggerChildOpened(); + mTestLooper.dispatchAll(); + + final ArgumentCaptor<Consumer<VcnNetworkAgent>> unwantedCallbackCaptor = + ArgumentCaptor.forClass(Consumer.class); + verify(mDeps) + .newNetworkAgent( + any(), + any(), + any(), + any(), + anyInt(), + any(), + any(), + unwantedCallbackCaptor.capture(), + any()); + + return unwantedCallbackCaptor.getValue(); + } + + @Test + public void testUnwantedNetworkAgentTriggersTeardown() throws Exception { + final Consumer<VcnNetworkAgent> unwantedCallback = setupNetworkAndGetUnwantedCallback(); + + unwantedCallback.accept(mNetworkAgent); + mTestLooper.dispatchAll(); + + assertTrue(mGatewayConnection.isQuitting()); + assertEquals(mGatewayConnection.mDisconnectingState, mGatewayConnection.getCurrentState()); + } + + @Test + public void testUnwantedNetworkAgentWithDisconnectedNetworkAgent() throws Exception { + final Consumer<VcnNetworkAgent> unwantedCallback = setupNetworkAndGetUnwantedCallback(); + + mGatewayConnection.setNetworkAgent(null); + unwantedCallback.accept(mNetworkAgent); + mTestLooper.dispatchAll(); + + // Verify that the call was ignored; the state machine is still running, and the state has + // not changed. + assertFalse(mGatewayConnection.isQuitting()); + assertEquals(mGatewayConnection.mConnectedState, mGatewayConnection.getCurrentState()); + } + + @Test + public void testUnwantedNetworkAgentWithNewNetworkAgent() throws Exception { + final Consumer<VcnNetworkAgent> unwantedCallback = setupNetworkAndGetUnwantedCallback(); + final VcnNetworkAgent testAgent = mock(VcnNetworkAgent.class); + + mGatewayConnection.setNetworkAgent(testAgent); + unwantedCallback.accept(mNetworkAgent); + mTestLooper.dispatchAll(); + + assertFalse(mGatewayConnection.isQuitting()); + assertEquals(mGatewayConnection.mConnectedState, mGatewayConnection.getCurrentState()); + assertEquals(testAgent, mGatewayConnection.getNetworkAgent()); + } + @Test public void testChildSessionClosedTriggersDisconnect() throws Exception { // Verify scheduled but not canceled when entering ConnectedState diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTestBase.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTestBase.java index c5ed8f6ddcc7..dc73be25ffa3 100644 --- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTestBase.java +++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTestBase.java @@ -18,6 +18,7 @@ package com.android.server.vcn; import static com.android.server.vcn.UnderlyingNetworkTracker.UnderlyingNetworkRecord; import static com.android.server.vcn.VcnGatewayConnection.VcnIkeSession; +import static com.android.server.vcn.VcnGatewayConnection.VcnNetworkAgent; import static com.android.server.vcn.VcnTestUtils.setupIpSecManager; import static org.junit.Assert.assertEquals; @@ -44,7 +45,6 @@ import android.net.IpSecTunnelInterfaceResponse; import android.net.LinkAddress; import android.net.LinkProperties; import android.net.Network; -import android.net.NetworkAgent; import android.net.NetworkCapabilities; import android.net.ipsec.ike.ChildSessionCallback; import android.net.ipsec.ike.IkeSessionCallback; @@ -90,12 +90,18 @@ public class VcnGatewayConnectionTestBase { protected static final int TEST_SUB_ID = 5; protected static final long ELAPSED_REAL_TIME = 123456789L; protected static final String TEST_IPSEC_TUNNEL_IFACE = "IPSEC_IFACE"; + protected static final UnderlyingNetworkRecord TEST_UNDERLYING_NETWORK_RECORD_1 = new UnderlyingNetworkRecord( new Network(0), new NetworkCapabilities(), new LinkProperties(), false /* blocked */); + + static { + TEST_UNDERLYING_NETWORK_RECORD_1.linkProperties.setMtu(1500); + } + protected static final UnderlyingNetworkRecord TEST_UNDERLYING_NETWORK_RECORD_2 = new UnderlyingNetworkRecord( new Network(1), @@ -103,6 +109,10 @@ public class VcnGatewayConnectionTestBase { new LinkProperties(), false /* blocked */); + static { + TEST_UNDERLYING_NETWORK_RECORD_2.linkProperties.setMtu(1460); + } + protected static final TelephonySubscriptionSnapshot TEST_SUBSCRIPTION_SNAPSHOT = new TelephonySubscriptionSnapshot( Collections.singletonMap(TEST_SUB_ID, TEST_SUB_GRP), Collections.EMPTY_MAP); @@ -278,8 +288,8 @@ public class VcnGatewayConnectionTestBase { protected void verifySafeModeTimeoutNotifiesCallbackAndUnregistersNetworkAgent( @NonNull State expectedState) { - // Set a NetworkAgent, and expect it to be unregistered and cleared - final NetworkAgent mockNetworkAgent = mock(NetworkAgent.class); + // Set a VcnNetworkAgent, and expect it to be unregistered and cleared + final VcnNetworkAgent mockNetworkAgent = mock(VcnNetworkAgent.class); mGatewayConnection.setNetworkAgent(mockNetworkAgent); // SafeMode timer starts when VcnGatewayConnection exits DisconnectedState (the initial diff --git a/tests/vcn/java/com/android/server/vcn/util/MtuUtilsTest.java b/tests/vcn/java/com/android/server/vcn/util/MtuUtilsTest.java new file mode 100644 index 000000000000..29511f780bf6 --- /dev/null +++ b/tests/vcn/java/com/android/server/vcn/util/MtuUtilsTest.java @@ -0,0 +1,92 @@ +/* + * 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.server.vcn.util; + +import static android.net.ipsec.ike.SaProposal.ENCRYPTION_ALGORITHM_AES_CBC; +import static android.net.ipsec.ike.SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_12; +import static android.net.ipsec.ike.SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_16; +import static android.net.ipsec.ike.SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_8; +import static android.net.ipsec.ike.SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA2_256_128; +import static android.net.ipsec.ike.SaProposal.KEY_LEN_AES_256; + +import static com.android.net.module.util.NetworkStackConstants.ETHER_MTU; +import static com.android.net.module.util.NetworkStackConstants.IPV6_MIN_MTU; +import static com.android.server.vcn.util.MtuUtils.getMtu; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import static java.util.Collections.emptyList; + +import android.net.ipsec.ike.ChildSaProposal; + +import androidx.test.filters.SmallTest; +import androidx.test.runner.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.util.Arrays; +import java.util.List; + +@RunWith(AndroidJUnit4.class) +@SmallTest +public class MtuUtilsTest { + @Test + public void testUnderlyingMtuZero() { + assertEquals( + IPV6_MIN_MTU, getMtu(emptyList(), ETHER_MTU /* maxMtu */, 0 /* underlyingMtu */)); + } + + @Test + public void testClampsToMaxMtu() { + assertEquals(0, getMtu(emptyList(), 0 /* maxMtu */, IPV6_MIN_MTU /* underlyingMtu */)); + } + + @Test + public void testNormalModeAlgorithmLessThanUnderlyingMtu() { + final List<ChildSaProposal> saProposals = + Arrays.asList( + new ChildSaProposal.Builder() + .addEncryptionAlgorithm( + ENCRYPTION_ALGORITHM_AES_CBC, KEY_LEN_AES_256) + .addIntegrityAlgorithm(INTEGRITY_ALGORITHM_HMAC_SHA2_256_128) + .build()); + + final int actualMtu = + getMtu(saProposals, ETHER_MTU /* maxMtu */, ETHER_MTU /* underlyingMtu */); + assertTrue(ETHER_MTU > actualMtu); + } + + @Test + public void testCombinedModeAlgorithmLessThanUnderlyingMtu() { + final List<ChildSaProposal> saProposals = + Arrays.asList( + new ChildSaProposal.Builder() + .addEncryptionAlgorithm( + ENCRYPTION_ALGORITHM_AES_GCM_16, KEY_LEN_AES_256) + .addEncryptionAlgorithm( + ENCRYPTION_ALGORITHM_AES_GCM_12, KEY_LEN_AES_256) + .addEncryptionAlgorithm( + ENCRYPTION_ALGORITHM_AES_GCM_8, KEY_LEN_AES_256) + .build()); + + final int actualMtu = + getMtu(saProposals, ETHER_MTU /* maxMtu */, ETHER_MTU /* underlyingMtu */); + assertTrue(ETHER_MTU > actualMtu); + } +} |