diff options
14 files changed, 282 insertions, 20 deletions
diff --git a/core/java/android/security/net/config/CertificatesEntryRef.java b/core/java/android/security/net/config/CertificatesEntryRef.java index 45cd0f011299..a46049fb2f6d 100644 --- a/core/java/android/security/net/config/CertificatesEntryRef.java +++ b/core/java/android/security/net/config/CertificatesEntryRef.java @@ -17,6 +17,7 @@ package android.security.net.config; import android.util.ArraySet; + import java.security.cert.X509Certificate; import java.util.Set; @@ -24,16 +25,23 @@ import java.util.Set; public final class CertificatesEntryRef { private final CertificateSource mSource; private final boolean mOverridesPins; + private final boolean mDisableCT; - public CertificatesEntryRef(CertificateSource source, boolean overridesPins) { + public CertificatesEntryRef(CertificateSource source, boolean overridesPins, + boolean disableCT) { mSource = source; mOverridesPins = overridesPins; + mDisableCT = disableCT; } boolean overridesPins() { return mOverridesPins; } + boolean disableCT() { + return mDisableCT; + } + public Set<TrustAnchor> getTrustAnchors() { // TODO: cache this [but handle mutable sources] Set<TrustAnchor> anchors = new ArraySet<TrustAnchor>(); diff --git a/core/java/android/security/net/config/KeyStoreConfigSource.java b/core/java/android/security/net/config/KeyStoreConfigSource.java index 8d4f098bcb37..a54d8d0499cb 100644 --- a/core/java/android/security/net/config/KeyStoreConfigSource.java +++ b/core/java/android/security/net/config/KeyStoreConfigSource.java @@ -17,8 +17,8 @@ package android.security.net.config; import android.util.Pair; + import java.security.KeyStore; -import java.security.KeyStoreException; import java.util.Set; /** @@ -32,7 +32,7 @@ class KeyStoreConfigSource implements ConfigSource { mConfig = new NetworkSecurityConfig.Builder() .addCertificatesEntryRef( // Use the KeyStore and do not override pins (of which there are none). - new CertificatesEntryRef(new KeyStoreCertificateSource(ks), false)) + new CertificatesEntryRef(new KeyStoreCertificateSource(ks), false, false)) .build(); } diff --git a/core/java/android/security/net/config/NetworkSecurityConfig.java b/core/java/android/security/net/config/NetworkSecurityConfig.java index 129ae63ec9c0..410c68b8d04d 100644 --- a/core/java/android/security/net/config/NetworkSecurityConfig.java +++ b/core/java/android/security/net/config/NetworkSecurityConfig.java @@ -112,7 +112,6 @@ public final class NetworkSecurityConfig { return mHstsEnforced; } - // TODO(b/28746284): add exceptions for user-added certificates and enterprise overrides. public boolean isCertificateTransparencyVerificationRequired() { return mCertificateTransparencyVerificationRequired; } @@ -192,20 +191,21 @@ public final class NetworkSecurityConfig { * @hide */ public static Builder getDefaultBuilder(ApplicationInfo info) { + // System certificate store, does not bypass static pins, does not disable CT. + CertificatesEntryRef systemRef = new CertificatesEntryRef( + SystemCertificateSource.getInstance(), false, false); Builder builder = new Builder() .setHstsEnforced(DEFAULT_HSTS_ENFORCED) - // System certificate store, does not bypass static pins. - .addCertificatesEntryRef( - new CertificatesEntryRef(SystemCertificateSource.getInstance(), false)); + .addCertificatesEntryRef(systemRef); final boolean cleartextTrafficPermitted = info.targetSdkVersion < Build.VERSION_CODES.P && !info.isInstantApp(); builder.setCleartextTrafficPermitted(cleartextTrafficPermitted); // Applications targeting N and above must opt in into trusting the user added certificate // store. if (info.targetSdkVersion <= Build.VERSION_CODES.M && !info.isPrivilegedApp()) { - // User certificate store, does not bypass static pins. + // User certificate store, does not bypass static pins. CT is disabled. builder.addCertificatesEntryRef( - new CertificatesEntryRef(UserCertificateSource.getInstance(), false)); + new CertificatesEntryRef(UserCertificateSource.getInstance(), false, true)); } return builder; } @@ -339,6 +339,16 @@ public final class NetworkSecurityConfig { if (mCertificateTransparencyVerificationRequiredSet) { return mCertificateTransparencyVerificationRequired; } + // CT verification has not been set explicitly. Before deferring to + // the parent, check if any of the CertificatesEntryRef requires it + // to be disabled (i.e., user store or inline certificate). + if (hasCertificatesEntryRefs()) { + for (CertificatesEntryRef ref : getCertificatesEntryRefs()) { + if (ref.disableCT()) { + return false; + } + } + } if (mParentBuilder != null) { return mParentBuilder.getCertificateTransparencyVerificationRequired(); } diff --git a/core/java/android/security/net/config/XmlConfigSource.java b/core/java/android/security/net/config/XmlConfigSource.java index b1c14793bbbd..95e579fc538b 100644 --- a/core/java/android/security/net/config/XmlConfigSource.java +++ b/core/java/android/security/net/config/XmlConfigSource.java @@ -182,6 +182,7 @@ public class XmlConfigSource implements ConfigSource { boolean overridePins = parser.getAttributeBooleanValue(null, "overridePins", defaultOverridePins); int sourceId = parser.getAttributeResourceValue(null, "src", -1); + boolean disableCT = false; String sourceString = parser.getAttributeValue(null, "src"); CertificateSource source = null; if (sourceString == null) { @@ -190,10 +191,12 @@ public class XmlConfigSource implements ConfigSource { if (sourceId != -1) { // TODO: Cache ResourceCertificateSources by sourceId source = new ResourceCertificateSource(sourceId, mContext); + disableCT = true; } else if ("system".equals(sourceString)) { source = SystemCertificateSource.getInstance(); } else if ("user".equals(sourceString)) { source = UserCertificateSource.getInstance(); + disableCT = true; } else if ("wfa".equals(sourceString)) { source = WfaCertificateSource.getInstance(); } else { @@ -201,7 +204,7 @@ public class XmlConfigSource implements ConfigSource { + "Should be one of system|user|@resourceVal"); } XmlUtils.skipCurrentTag(parser); - return new CertificatesEntryRef(source, overridePins); + return new CertificatesEntryRef(source, overridePins, disableCT); } private Collection<CertificatesEntryRef> parseTrustAnchors(XmlResourceParser parser, diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/LetterboxConfiguration.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/LetterboxConfiguration.kt index 83a8e3103e3f..244ff99cadd0 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/LetterboxConfiguration.kt +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/LetterboxConfiguration.kt @@ -36,6 +36,21 @@ class LetterboxConfiguration @Inject constructor( // Color resource id for the solid color letterbox background type. private var letterboxBackgroundColorResourceIdOverride: Int? = null + // Default value for corners radius for activities presented in the letterbox mode. + // Values < 0 will be ignored. + private val letterboxActivityDefaultCornersRadius: Int + + // Current corners radius for activities presented in the letterbox mode. + // Values can be modified at runtime and values < 0 will be ignored. + private var letterboxActivityCornersRadius = 0 + + init { + letterboxActivityDefaultCornersRadius = context.resources.getInteger( + R.integer.config_letterboxActivityCornersRadius + ) + letterboxActivityCornersRadius = letterboxActivityDefaultCornersRadius + } + /** * Sets color of letterbox background which is used when using the solid background mode. */ @@ -64,7 +79,7 @@ class LetterboxConfiguration @Inject constructor( } // Query color dynamically because material colors extracted from wallpaper are updated // when wallpaper is changed. - return Color.valueOf(context.getResources().getColor(colorId!!, /* theme */null)) + return Color.valueOf(context.getResources().getColor(colorId!!, null)) } /** @@ -79,4 +94,33 @@ class LetterboxConfiguration @Inject constructor( * The background color for the Letterbox. */ fun getBackgroundColorRgbArray(): FloatArray = getLetterboxBackgroundColor().components + + /** + * Overrides corners radius for activities presented in the letterbox mode. Values < 0, + * will be ignored and corners of the activity won't be rounded. + */ + fun setLetterboxActivityCornersRadius(cornersRadius: Int) { + letterboxActivityCornersRadius = cornersRadius + } + + /** + * Resets corners radius for activities presented in the letterbox mode. + */ + fun resetLetterboxActivityCornersRadius() { + letterboxActivityCornersRadius = letterboxActivityDefaultCornersRadius + } + + /** + * Whether corners of letterboxed activities are rounded. + */ + fun isLetterboxActivityCornersRounded(): Boolean { + return getLetterboxActivityCornersRadius() > 0 + } + + /** + * Gets corners radius for activities presented in the letterbox mode. + */ + fun getLetterboxActivityCornersRadius(): Int { + return maxOf(letterboxActivityCornersRadius, 0) + } } diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterbox/LetterboxConfigurationTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterbox/LetterboxConfigurationTest.kt index 75025d9064d3..1399600d5ab9 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterbox/LetterboxConfigurationTest.kt +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterbox/LetterboxConfigurationTest.kt @@ -26,6 +26,7 @@ import com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn import com.android.internal.R import com.android.wm.shell.ShellTestCase import java.util.function.Consumer +import kotlin.test.assertEquals import org.junit.Test import org.junit.runner.RunWith import org.mockito.kotlin.doReturn @@ -51,6 +52,14 @@ class LetterboxConfigurationTest : ShellTestCase() { val COLOR_WHITE_RESOURCE_ID = android.R.color.white @JvmStatic val COLOR_BLACK_RESOURCE_ID = android.R.color.black + @JvmStatic + val ROUNDED_CORNER_RADIUS_DEFAULT = 32 + @JvmStatic + val ROUNDED_CORNER_RADIUS_VALID = 16 + @JvmStatic + val ROUNDED_CORNER_RADIUS_NONE = 0 + @JvmStatic + val ROUNDED_CORNER_RADIUS_INVALID = -10 } @Test @@ -112,6 +121,68 @@ class LetterboxConfigurationTest : ShellTestCase() { } } + @Test + fun `default rounded corner radius is used if override is not set`() { + runTestScenario { r -> + r.setDefaultRoundedCornerRadius(ROUNDED_CORNER_RADIUS_DEFAULT) + r.loadConfiguration() + r.checkRoundedCornersRadius(ROUNDED_CORNER_RADIUS_DEFAULT) + } + } + + @Test + fun `new rounded corner radius is used after setting a valid value`() { + runTestScenario { r -> + r.setDefaultRoundedCornerRadius(ROUNDED_CORNER_RADIUS_DEFAULT) + r.loadConfiguration() + r.overrideRoundedCornersRadius(ROUNDED_CORNER_RADIUS_VALID) + r.checkRoundedCornersRadius(ROUNDED_CORNER_RADIUS_VALID) + } + } + + @Test + fun `no rounded corner radius is used after setting an invalid value`() { + runTestScenario { r -> + r.setDefaultRoundedCornerRadius(ROUNDED_CORNER_RADIUS_DEFAULT) + r.loadConfiguration() + r.overrideRoundedCornersRadius(ROUNDED_CORNER_RADIUS_INVALID) + r.checkRoundedCornersRadius(ROUNDED_CORNER_RADIUS_NONE) + } + } + + @Test + fun `has rounded corners for different values`() { + runTestScenario { r -> + r.setDefaultRoundedCornerRadius(ROUNDED_CORNER_RADIUS_DEFAULT) + r.loadConfiguration() + r.checkIsLetterboxActivityCornersRounded(true) + + r.overrideRoundedCornersRadius(ROUNDED_CORNER_RADIUS_INVALID) + r.checkIsLetterboxActivityCornersRounded(false) + + r.overrideRoundedCornersRadius(ROUNDED_CORNER_RADIUS_NONE) + r.checkIsLetterboxActivityCornersRounded(false) + + r.overrideRoundedCornersRadius(ROUNDED_CORNER_RADIUS_VALID) + r.checkIsLetterboxActivityCornersRounded(true) + } + } + + @Test + fun `reset rounded corners radius`() { + runTestScenario { r -> + r.setDefaultRoundedCornerRadius(ROUNDED_CORNER_RADIUS_DEFAULT) + r.loadConfiguration() + r.checkRoundedCornersRadius(ROUNDED_CORNER_RADIUS_DEFAULT) + + r.overrideRoundedCornersRadius(ROUNDED_CORNER_RADIUS_VALID) + r.checkRoundedCornersRadius(ROUNDED_CORNER_RADIUS_VALID) + + r.resetRoundedCornersRadius() + r.checkRoundedCornersRadius(ROUNDED_CORNER_RADIUS_DEFAULT) + } + } + /** * Runs a test scenario providing a Robot. */ @@ -135,6 +206,11 @@ class LetterboxConfigurationTest : ShellTestCase() { .getColor(R.color.config_letterboxBackgroundColor, null) } + fun setDefaultRoundedCornerRadius(radius: Int) { + doReturn(radius).`when`(resources) + .getInteger(R.integer.config_letterboxActivityCornersRadius) + } + fun loadConfiguration() { letterboxConfig = LetterboxConfiguration(ctx) } @@ -147,14 +223,30 @@ class LetterboxConfigurationTest : ShellTestCase() { letterboxConfig.resetLetterboxBackgroundColor() } + fun resetRoundedCornersRadius() { + letterboxConfig.resetLetterboxActivityCornersRadius() + } + fun overrideBackgroundColorId(@ColorRes colorId: Int) { letterboxConfig.setLetterboxBackgroundColorResourceId(colorId) } + fun overrideRoundedCornersRadius(radius: Int) { + letterboxConfig.setLetterboxActivityCornersRadius(radius) + } + fun checkBackgroundColor(expected: Color) { val colorComponents = letterboxConfig.getBackgroundColorRgbArray() val expectedComponents = expected.components assert(expectedComponents.contentEquals(colorComponents)) } + + fun checkRoundedCornersRadius(expected: Int) { + assertEquals(expected, letterboxConfig.getLetterboxActivityCornersRadius()) + } + + fun checkIsLetterboxActivityCornersRounded(expected: Boolean) { + assertEquals(expected, letterboxConfig.isLetterboxActivityCornersRounded()) + } } } diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index e19096354d64..1f224e238c6e 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -2274,7 +2274,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp if (shellTransitions) { // Before setDisplayProjection is applied by the start transaction of transition, // set the transform hint to avoid using surface in old rotation. - getPendingTransaction().setFixedTransformHint(mSurfaceControl, rotation); + setFixedTransformHint(getPendingTransaction(), mSurfaceControl, rotation); // The sync transaction should already contains setDisplayProjection, so unset the // hint to restore the natural state when the transaction is applied. transaction.unsetFixedTransformHint(mSurfaceControl); @@ -2284,6 +2284,10 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp mWmService.mRotationWatcherController.dispatchDisplayRotationChange(mDisplayId, rotation); } + void setFixedTransformHint(Transaction t, SurfaceControl sc, int rotation) { + t.setFixedTransformHint(sc, (rotation + mDisplayInfo.installOrientation) % 4); + } + void configureDisplayPolicy() { mRootWindowContainer.updateDisplayImePolicyCache(); mDisplayPolicy.updateConfigurationAndScreenSizeDependentBehaviors(); diff --git a/services/core/java/com/android/server/wm/SeamlessRotator.java b/services/core/java/com/android/server/wm/SeamlessRotator.java index c20b85858c44..8f0f6860ceb6 100644 --- a/services/core/java/com/android/server/wm/SeamlessRotator.java +++ b/services/core/java/com/android/server/wm/SeamlessRotator.java @@ -56,7 +56,7 @@ public class SeamlessRotator { mOldRotation = oldRotation; mNewRotation = newRotation; mApplyFixedTransformHint = applyFixedTransformationHint; - mFixedTransformHint = oldRotation; + mFixedTransformHint = (oldRotation + info.installOrientation) % 4; final boolean flipped = info.rotation == ROTATION_90 || info.rotation == ROTATION_270; final int pH = flipped ? info.logicalWidth : info.logicalHeight; final int pW = flipped ? info.logicalHeight : info.logicalWidth; diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java index 2397e032fcc8..aa60f939f9aa 100644 --- a/services/core/java/com/android/server/wm/WindowContainer.java +++ b/services/core/java/com/android/server/wm/WindowContainer.java @@ -3733,7 +3733,7 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< && !mTransitionController.useShellTransitionsRotation()) { if (deltaRotation != Surface.ROTATION_0) { updateSurfaceRotation(t, deltaRotation, null /* positionLeash */); - getPendingTransaction().setFixedTransformHint(mSurfaceControl, + mDisplayContent.setFixedTransformHint(getPendingTransaction(), mSurfaceControl, getWindowConfiguration().getDisplayRotation()); } else if (deltaRotation != mLastDeltaRotation) { t.setMatrix(mSurfaceControl, 1, 0, 0, 1); diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java index 004f406035c0..832295a7e031 100644 --- a/services/core/java/com/android/server/wm/WindowToken.java +++ b/services/core/java/com/android/server/wm/WindowToken.java @@ -629,7 +629,7 @@ class WindowToken extends WindowContainer<WindowState> { .build(); t.setPosition(leash, mLastSurfacePosition.x, mLastSurfacePosition.y); t.reparent(getSurfaceControl(), leash); - getPendingTransaction().setFixedTransformHint(leash, + mDisplayContent.setFixedTransformHint(getPendingTransaction(), leash, getWindowConfiguration().getDisplayRotation()); mFixedRotationTransformLeash = leash; updateSurfaceRotation(t, rotation, mFixedRotationTransformLeash); diff --git a/tests/NetworkSecurityConfigTest/res/xml/ct_domains.xml b/tests/NetworkSecurityConfigTest/res/xml/ct_domains.xml new file mode 100644 index 000000000000..67d4397afe7d --- /dev/null +++ b/tests/NetworkSecurityConfigTest/res/xml/ct_domains.xml @@ -0,0 +1,38 @@ +<?xml version="1.0" encoding="utf-8"?> +<network-security-config> + <base-config> + <certificateTransparency enabled="true" /> + </base-config> + <domain-config> + <domain>android.com</domain> + <trust-anchors> + <certificates src="system" /> + </trust-anchors> + </domain-config> + <domain-config> + <domain>subdomain_user.android.com</domain> + <trust-anchors> + <certificates src="user" /> + </trust-anchors> + </domain-config> + <domain-config> + <certificateTransparency enabled="true" /> + <domain>subdomain_user_ct.android.com</domain> + <trust-anchors> + <certificates src="user" /> + </trust-anchors> + </domain-config> + <domain-config> + <domain>subdomain_inline.android.com</domain> + <trust-anchors> + <certificates src="@raw/ca_certs_pem" /> + </trust-anchors> + </domain-config> + <domain-config> + <certificateTransparency enabled="true" /> + <domain>subdomain_inline_ct.android.com</domain> + <trust-anchors> + <certificates src="@raw/ca_certs_pem" /> + </trust-anchors> + </domain-config> +</network-security-config> diff --git a/tests/NetworkSecurityConfigTest/res/xml/ct_users.xml b/tests/NetworkSecurityConfigTest/res/xml/ct_users.xml new file mode 100644 index 000000000000..c35fd71c3178 --- /dev/null +++ b/tests/NetworkSecurityConfigTest/res/xml/ct_users.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="utf-8"?> +<network-security-config> + <base-config> + <trust-anchors> + <certificates src="user" /> + </trust-anchors> + </base-config> + <domain-config> + <domain>android.com</domain> + </domain-config> + <domain-config> + <certificateTransparency enabled="true" /> + <domain>subdomain.android.com</domain> + </domain-config> +</network-security-config> diff --git a/tests/NetworkSecurityConfigTest/src/android/security/net/config/NetworkSecurityConfigTests.java b/tests/NetworkSecurityConfigTest/src/android/security/net/config/NetworkSecurityConfigTests.java index 0494f174f191..c6fe06858e3f 100644 --- a/tests/NetworkSecurityConfigTest/src/android/security/net/config/NetworkSecurityConfigTests.java +++ b/tests/NetworkSecurityConfigTest/src/android/security/net/config/NetworkSecurityConfigTests.java @@ -111,7 +111,8 @@ public class NetworkSecurityConfigTests extends ActivityUnitTestCase<Activity> { private NetworkSecurityConfig getSystemStoreConfig() { return new NetworkSecurityConfig.Builder() .addCertificatesEntryRef( - new CertificatesEntryRef(SystemCertificateSource.getInstance(), false)) + new CertificatesEntryRef( + SystemCertificateSource.getInstance(), false, false)) .build(); } @@ -141,7 +142,8 @@ public class NetworkSecurityConfigTests extends ActivityUnitTestCase<Activity> { NetworkSecurityConfig domain = new NetworkSecurityConfig.Builder() .setPinSet(new PinSet(pins, Long.MAX_VALUE)) .addCertificatesEntryRef( - new CertificatesEntryRef(SystemCertificateSource.getInstance(), false)) + new CertificatesEntryRef( + SystemCertificateSource.getInstance(), false, false)) .build(); ArraySet<Pair<Domain, NetworkSecurityConfig>> domainMap = new ArraySet<Pair<Domain, NetworkSecurityConfig>>(); @@ -159,7 +161,8 @@ public class NetworkSecurityConfigTests extends ActivityUnitTestCase<Activity> { NetworkSecurityConfig domain = new NetworkSecurityConfig.Builder() .setPinSet(new PinSet(pins, Long.MAX_VALUE)) .addCertificatesEntryRef( - new CertificatesEntryRef(SystemCertificateSource.getInstance(), false)) + new CertificatesEntryRef( + SystemCertificateSource.getInstance(), false, false)) .build(); ArraySet<Pair<Domain, NetworkSecurityConfig>> domainMap = new ArraySet<Pair<Domain, NetworkSecurityConfig>>(); @@ -178,7 +181,8 @@ public class NetworkSecurityConfigTests extends ActivityUnitTestCase<Activity> { NetworkSecurityConfig domain = new NetworkSecurityConfig.Builder() .setPinSet(new PinSet(pins, Long.MAX_VALUE)) .addCertificatesEntryRef( - new CertificatesEntryRef(SystemCertificateSource.getInstance(), true)) + new CertificatesEntryRef( + SystemCertificateSource.getInstance(), true, false)) .build(); ArraySet<Pair<Domain, NetworkSecurityConfig>> domainMap = new ArraySet<Pair<Domain, NetworkSecurityConfig>>(); @@ -245,7 +249,8 @@ public class NetworkSecurityConfigTests extends ActivityUnitTestCase<Activity> { NetworkSecurityConfig domain = new NetworkSecurityConfig.Builder() .setPinSet(new PinSet(pins, Long.MAX_VALUE)) .addCertificatesEntryRef( - new CertificatesEntryRef(SystemCertificateSource.getInstance(), false)) + new CertificatesEntryRef( + SystemCertificateSource.getInstance(), false, false)) .build(); ArraySet<Pair<Domain, NetworkSecurityConfig>> domainMap = new ArraySet<Pair<Domain, NetworkSecurityConfig>>(); diff --git a/tests/NetworkSecurityConfigTest/src/android/security/net/config/XmlConfigTests.java b/tests/NetworkSecurityConfigTest/src/android/security/net/config/XmlConfigTests.java index 81e05c1d4e42..542465d62a66 100644 --- a/tests/NetworkSecurityConfigTest/src/android/security/net/config/XmlConfigTests.java +++ b/tests/NetworkSecurityConfigTest/src/android/security/net/config/XmlConfigTests.java @@ -502,4 +502,47 @@ public class XmlConfigTests extends AndroidTestCase { TestUtils.assertConnectionSucceeds(context, "android.com", 443); TestUtils.assertConnectionSucceeds(context, "developer.android.com", 443); } + + public void testCertificateTransparencyDomainConfig() throws Exception { + XmlConfigSource source = new XmlConfigSource(getContext(), R.xml.ct_domains, + TestUtils.makeApplicationInfo()); + ApplicationConfig appConfig = new ApplicationConfig(source); + assertTrue(appConfig.hasPerDomainConfigs()); + NetworkSecurityConfig config = appConfig.getConfigForHostname(""); + assertNotNull(config); + // Check defaults. + assertTrue(config.isCertificateTransparencyVerificationRequired()); + + config = appConfig.getConfigForHostname("android.com"); + assertTrue(config.isCertificateTransparencyVerificationRequired()); + + config = appConfig.getConfigForHostname("subdomain_user.android.com"); + assertFalse(config.isCertificateTransparencyVerificationRequired()); + + config = appConfig.getConfigForHostname("subdomain_user_ct.android.com"); + assertTrue(config.isCertificateTransparencyVerificationRequired()); + + config = appConfig.getConfigForHostname("subdomain_inline.android.com"); + assertFalse(config.isCertificateTransparencyVerificationRequired()); + + config = appConfig.getConfigForHostname("subdomain_inline_ct.android.com"); + assertTrue(config.isCertificateTransparencyVerificationRequired()); + } + + public void testCertificateTransparencyUserConfig() throws Exception { + XmlConfigSource source = new XmlConfigSource(getContext(), R.xml.ct_users, + TestUtils.makeApplicationInfo()); + ApplicationConfig appConfig = new ApplicationConfig(source); + assertTrue(appConfig.hasPerDomainConfigs()); + NetworkSecurityConfig config = appConfig.getConfigForHostname(""); + assertNotNull(config); + // Check defaults. + assertFalse(config.isCertificateTransparencyVerificationRequired()); + + config = appConfig.getConfigForHostname("android.com"); + assertFalse(config.isCertificateTransparencyVerificationRequired()); + + config = appConfig.getConfigForHostname("subdomain.android.com"); + assertTrue(config.isCertificateTransparencyVerificationRequired()); + } } |