merge in mnc-release history after reset to mnc-dev
diff --git a/CtsTestCaseList.mk b/CtsTestCaseList.mk
index f683840..9021921 100644
--- a/CtsTestCaseList.mk
+++ b/CtsTestCaseList.mk
@@ -62,7 +62,9 @@
CtsKeySetSharedUserSigningBUpgradeB \
CtsKeySetSigningABadUpgradeB \
CtsKeySetSigningCBadAUpgradeAB \
- CtsKeySetSigningANoDefUpgradeB
+ CtsKeySetSigningANoDefUpgradeB \
+ CtsKeySetSigningAUpgradeEcA \
+ CtsKeySetSigningEcAUpgradeA
cts_support_packages := \
CtsAccelerationTestStubs \
diff --git a/hostsidetests/appsecurity/certs/keysets/cts-keyset-test-dsa-a.pk8 b/hostsidetests/appsecurity/certs/keysets/cts-keyset-test-dsa-a.pk8
new file mode 100644
index 0000000..ac0b0c1
--- /dev/null
+++ b/hostsidetests/appsecurity/certs/keysets/cts-keyset-test-dsa-a.pk8
Binary files differ
diff --git a/hostsidetests/appsecurity/certs/keysets/cts-keyset-test-ec-a.pk8 b/hostsidetests/appsecurity/certs/keysets/cts-keyset-test-ec-a.pk8
new file mode 100644
index 0000000..ec27be1
--- /dev/null
+++ b/hostsidetests/appsecurity/certs/keysets/cts-keyset-test-ec-a.pk8
Binary files differ
diff --git a/hostsidetests/appsecurity/certs/keysets/cts-keyset-test-ec-a.x509.pem b/hostsidetests/appsecurity/certs/keysets/cts-keyset-test-ec-a.x509.pem
new file mode 100644
index 0000000..183691d
--- /dev/null
+++ b/hostsidetests/appsecurity/certs/keysets/cts-keyset-test-ec-a.x509.pem
@@ -0,0 +1,10 @@
+-----BEGIN CERTIFICATE-----
+MIIBejCCAR+gAwIBAgIJAMsY4Fz5jr/IMAoGCCqGSM49BAMCMBkxFzAVBgNVBAMM
+DnVuaXRfdGVzdF9lY19hMB4XDTE1MDYwMTIxNDU1M1oXDTQyMTAxNzIxNDU1M1ow
+GTEXMBUGA1UEAwwOdW5pdF90ZXN0X2VjX2EwWTATBgcqhkjOPQIBBggqhkjOPQMB
+BwNCAAR8Q+7lg4KSOs2Be0XhFwlFCsiCCIh3iX2t6fE+V/MD+QBT1265hIyBKEH/
+oAsTpLy8FdGKLC0x+TwuCedui0SBo1AwTjAdBgNVHQ4EFgQUX4h7gPTgwQXorm0H
+7R12wN2yNrwwHwYDVR0jBBgwFoAUX4h7gPTgwQXorm0H7R12wN2yNrwwDAYDVR0T
+BAUwAwEB/zAKBggqhkjOPQQDAgNJADBGAiEA5kHO4aK20dwt81mCABAywD7Y6V1O
+vqoff9yIx3USW8oCIQDTzo8tbHuPc+i3vBsb5Uo1+4BE/pcOe/je6PGlRHG8rg==
+-----END CERTIFICATE-----
diff --git a/hostsidetests/appsecurity/src/com/android/cts/appsecurity/KeySetHostTest.java b/hostsidetests/appsecurity/src/com/android/cts/appsecurity/KeySetHostTest.java
index 7f3737d..9637a6c 100644
--- a/hostsidetests/appsecurity/src/com/android/cts/appsecurity/KeySetHostTest.java
+++ b/hostsidetests/appsecurity/src/com/android/cts/appsecurity/KeySetHostTest.java
@@ -76,6 +76,10 @@
"CtsKeySetSigningCBadAUpgradeAB.apk";
private static final String A_SIGNED_NO_B_B_UPGRADE =
"CtsKeySetSigningANoDefUpgradeB.apk";
+ private static final String A_SIGNED_EC_A_UPGRADE =
+ "CtsKeySetSigningAUpgradeEcA.apk";
+ private static final String EC_A_SIGNED_A_UPGRADE =
+ "CtsKeySetSigningEcAUpgradeA.apk";
/* package which defines the KEYSET_PERM_NAME signature permission */
private static final String KEYSET_PERM_DEF_PKG =
@@ -486,4 +490,26 @@
assertNotNull("Installation of apk with upgrade key referring to a bad public key succeeded!",
installResult);
}
+
+ /*
+ * Check if an apk signed by RSA pub key can upgrade to apk signed by EC key.
+ */
+ public void testUpgradeKSRsaToEC() throws Exception {
+ String installResult = testPackageUpgrade(KEYSET_PKG, A_SIGNED_EC_A_UPGRADE,
+ EC_A_SIGNED_A_UPGRADE);
+ assertNull(String.format("failed to upgrade keyset app from one signed by RSA key"
+ + "to version signed by EC upgrade-key-set, Reason: %s", installResult),
+ installResult);
+ }
+
+ /*
+ * Check if an apk signed by EC pub key can upgrade to apk signed by RSA key.
+ */
+ public void testUpgradeKSECToRSA() throws Exception {
+ String installResult = testPackageUpgrade(KEYSET_PKG, EC_A_SIGNED_A_UPGRADE,
+ A_SIGNED_EC_A_UPGRADE);
+ assertNull(String.format("failed to upgrade keyset app from one signed by EC key"
+ + "to version signed by RSA upgrade-key-set, Reason: %s", installResult),
+ installResult);
+ }
}
diff --git a/hostsidetests/appsecurity/test-apps/DocumentProvider/src/com/android/cts/documentprovider/MyDocumentsProvider.java b/hostsidetests/appsecurity/test-apps/DocumentProvider/src/com/android/cts/documentprovider/MyDocumentsProvider.java
index fb8993c..14f215c 100644
--- a/hostsidetests/appsecurity/test-apps/DocumentProvider/src/com/android/cts/documentprovider/MyDocumentsProvider.java
+++ b/hostsidetests/appsecurity/test-apps/DocumentProvider/src/com/android/cts/documentprovider/MyDocumentsProvider.java
@@ -239,13 +239,16 @@
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
- try {
- final InputStream is = new ParcelFileDescriptor.AutoCloseInputStream(
- pipe[0]);
- doc.contents = readFullyNoClose(is);
- is.close();
- } catch (IOException e) {
- Log.w(TAG, "Failed to stream", e);
+ synchronized (doc) {
+ try {
+ final InputStream is = new ParcelFileDescriptor.AutoCloseInputStream(
+ pipe[0]);
+ doc.contents = readFullyNoClose(is);
+ is.close();
+ doc.notifyAll();
+ } catch (IOException e) {
+ Log.w(TAG, "Failed to stream", e);
+ }
}
return null;
}
@@ -255,13 +258,20 @@
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
- try {
- final OutputStream os = new ParcelFileDescriptor.AutoCloseOutputStream(
- pipe[1]);
- os.write(doc.contents);
- os.close();
- } catch (IOException e) {
- Log.w(TAG, "Failed to stream", e);
+ synchronized (doc) {
+ try {
+ final OutputStream os = new ParcelFileDescriptor.AutoCloseOutputStream(
+ pipe[1]);
+ while (doc.contents == null) {
+ doc.wait();
+ }
+ os.write(doc.contents);
+ os.close();
+ } catch (IOException e) {
+ Log.w(TAG, "Failed to stream", e);
+ } catch (InterruptedException e) {
+ Log.w(TAG, "Interuppted", e);
+ }
}
return null;
}
diff --git a/hostsidetests/appsecurity/test-apps/keysets/uA/Android.mk b/hostsidetests/appsecurity/test-apps/keysets/uA/Android.mk
index 4d441de..79d053b 100644
--- a/hostsidetests/appsecurity/test-apps/keysets/uA/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/keysets/uA/Android.mk
@@ -37,6 +37,18 @@
include $(BUILD_CTS_SUPPORT_PACKAGE)
+#apks signed by cts-keyset-test-ec-a
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+LOCAL_SDK_VERSION := current
+LOCAL_STATIC_JAVA_LIBRARIES := android-support-test
+LOCAL_PACKAGE_NAME := CtsKeySetSigningEcAUpgradeA
+LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/keysets/cts-keyset-test-ec-a
+LOCAL_DEX_PREOPT := false
+
+include $(BUILD_CTS_SUPPORT_PACKAGE)
+
#apks signed by cts-keyset-test-a and cts-keyset-test-b
include $(CLEAR_VARS)
diff --git a/hostsidetests/appsecurity/test-apps/keysets/uEcA/Android.mk b/hostsidetests/appsecurity/test-apps/keysets/uEcA/Android.mk
new file mode 100644
index 0000000..3d0109a
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/keysets/uEcA/Android.mk
@@ -0,0 +1,27 @@
+# Copyright (C) 2014 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.
+
+LOCAL_PATH:= $(call my-dir)
+
+#apks signed by cts-keyset-test-a
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+LOCAL_SDK_VERSION := current
+LOCAL_STATIC_JAVA_LIBRARIES := android-support-test
+LOCAL_PACKAGE_NAME := CtsKeySetSigningAUpgradeEcA
+LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/keysets/cts-keyset-test-a
+LOCAL_DEX_PREOPT := false
+
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/keysets/uEcA/AndroidManifest.xml b/hostsidetests/appsecurity/test-apps/keysets/uEcA/AndroidManifest.xml
new file mode 100644
index 0000000..a84704a
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/keysets/uEcA/AndroidManifest.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.cts.keysets">
+ <application android:hasCode="false">
+ </application>
+ <key-sets>
+ <key-set android:name="EcA" >
+ <public-key android:name="keyEcA"
+ android:value="MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEfEPu5YOCkjrNgXtF4RcJRQrIggiId4l9renxPlfzA/kAU9duuYSMgShB/6ALE6S8vBXRiiwtMfk8LgnnbotEgQ=="/>
+ </key-set>
+ <upgrade-key-set android:name="EcA"/>
+ </key-sets>
+</manifest>
diff --git a/tests/tests/graphics/src/android/graphics/cts/PaintTest.java b/tests/tests/graphics/src/android/graphics/cts/PaintTest.java
index 629e85e..8d96d91 100644
--- a/tests/tests/graphics/src/android/graphics/cts/PaintTest.java
+++ b/tests/tests/graphics/src/android/graphics/cts/PaintTest.java
@@ -1268,7 +1268,7 @@
try {
// start < context start
- p.getOffsetForAdvance(string, 1, string.length(), 0, string.length(), false, 0.0f);
+ p.getOffsetForAdvance(string, 0, string.length(), 1, string.length(), false, 0.0f);
fail("Should throw an IndexOutOfBoundsException.");
} catch (IndexOutOfBoundsException e) {
} catch (Exception e) {
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/RecordingTest.java b/tests/tests/hardware/src/android/hardware/camera2/cts/RecordingTest.java
index 9851ad8..7368376 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/RecordingTest.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/RecordingTest.java
@@ -763,12 +763,6 @@
CamcorderProfile profile = CamcorderProfile.get(cameraId, profileId);
Size videoSz = new Size(profile.videoFrameWidth, profile.videoFrameHeight);
- if (!mSupportedVideoSizes.contains(videoSz)) {
- mCollector.addMessage("Video size " + videoSz.toString() + " for profile ID " +
- profileId + " must be one of the camera device supported video size!");
- continue;
- }
-
Size maxPreviewSize = mOrderedPreviewSizes.get(0);
if (mStaticInfo.isHardwareLevelLegacy() &&
@@ -778,6 +772,12 @@
continue;
}
+ if (!mSupportedVideoSizes.contains(videoSz)) {
+ mCollector.addMessage("Video size " + videoSz.toString() + " for profile ID " +
+ profileId + " must be one of the camera device supported video size!");
+ continue;
+ }
+
// For LEGACY, find closest supported smaller or equal JPEG size to the current video
// size; if no size is smaller than the video, pick the smallest JPEG size. The assert
// for video size above guarantees that for LIMITED or FULL, we select videoSz here.
diff --git a/tests/tests/keystore/src/android/keystore/cts/KeyGenParameterSpecTest.java b/tests/tests/keystore/src/android/keystore/cts/KeyGenParameterSpecTest.java
new file mode 100644
index 0000000..a3e5d96
--- /dev/null
+++ b/tests/tests/keystore/src/android/keystore/cts/KeyGenParameterSpecTest.java
@@ -0,0 +1,328 @@
+/*
+ * Copyright 2015 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.keystore.cts;
+
+import android.security.keystore.KeyGenParameterSpec;
+import android.security.keystore.KeyProperties;
+import android.test.MoreAsserts;
+
+import junit.framework.TestCase;
+
+import java.math.BigInteger;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.ECGenParameterSpec;
+import java.util.Arrays;
+import java.util.Date;
+
+import javax.security.auth.x500.X500Principal;
+
+public class KeyGenParameterSpecTest extends TestCase {
+
+ private static final X500Principal DEFAULT_CERT_SUBJECT = new X500Principal("CN=fake");
+ private static final BigInteger DEFAULT_CERT_SERIAL_NUMBER = new BigInteger("1");
+ private static final Date DEFAULT_CERT_NOT_BEFORE = new Date(0L); // Jan 1 1970
+ private static final Date DEFAULT_CERT_NOT_AFTER = new Date(2461449600000L); // Jan 1 2048
+
+ public void testDefaults() {
+ // Set only the mandatory parameters and assert values returned by getters.
+
+ KeyGenParameterSpec spec = new KeyGenParameterSpec.Builder(
+ "arbitrary", KeyProperties.PURPOSE_ENCRYPT)
+ .build();
+
+ assertEquals("arbitrary", spec.getKeystoreAlias());
+ assertEquals(KeyProperties.PURPOSE_ENCRYPT, spec.getPurposes());
+ assertNull(null, spec.getAlgorithmParameterSpec());
+ MoreAsserts.assertEmpty(Arrays.asList(spec.getBlockModes()));
+ assertEquals(DEFAULT_CERT_NOT_BEFORE, spec.getCertificateNotBefore());
+ assertEquals(DEFAULT_CERT_NOT_AFTER, spec.getCertificateNotAfter());
+ assertEquals(DEFAULT_CERT_SERIAL_NUMBER, spec.getCertificateSerialNumber());
+ assertEquals(DEFAULT_CERT_SUBJECT, spec.getCertificateSubject());
+ assertFalse(spec.isDigestsSpecified());
+ try {
+ spec.getDigests();
+ fail();
+ } catch (IllegalStateException expected) {}
+ MoreAsserts.assertEmpty(Arrays.asList(spec.getEncryptionPaddings()));
+ assertEquals(-1, spec.getKeySize());
+ assertNull(spec.getKeyValidityStart());
+ assertNull(spec.getKeyValidityForOriginationEnd());
+ assertNull(spec.getKeyValidityForConsumptionEnd());
+ assertTrue(spec.isRandomizedEncryptionRequired());
+ MoreAsserts.assertEmpty(Arrays.asList(spec.getSignaturePaddings()));
+ assertFalse(spec.isUserAuthenticationRequired());
+ assertEquals(-1, spec.getUserAuthenticationValidityDurationSeconds());
+ }
+
+ public void testSettersReflectedInGetters() {
+ // Set all parameters to non-default values and then assert that getters reflect that.
+
+ Date certNotBeforeDate = new Date(System.currentTimeMillis());
+ Date certNotAfterDate = new Date(System.currentTimeMillis() + 12345678);
+ Date keyValidityStartDate = new Date(System.currentTimeMillis() - 2222222);
+ Date keyValidityEndDateForOrigination = new Date(System.currentTimeMillis() + 11111111);
+ Date keyValidityEndDateForConsumption = new Date(System.currentTimeMillis() + 33333333);
+ AlgorithmParameterSpec algSpecificParams = new ECGenParameterSpec("secp256r1");
+
+ KeyGenParameterSpec spec = new KeyGenParameterSpec.Builder(
+ "arbitrary", KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_ENCRYPT)
+ .setAlgorithmParameterSpec(algSpecificParams)
+ .setBlockModes(KeyProperties.BLOCK_MODE_GCM, KeyProperties.BLOCK_MODE_CBC)
+ .setCertificateNotBefore(certNotBeforeDate)
+ .setCertificateNotAfter(certNotAfterDate)
+ .setCertificateSerialNumber(new BigInteger("13946146"))
+ .setCertificateSubject(new X500Principal("CN=test"))
+ .setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA384)
+ .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_OAEP,
+ KeyProperties.ENCRYPTION_PADDING_PKCS7)
+ .setKeySize(1234)
+ .setKeyValidityStart(keyValidityStartDate)
+ .setKeyValidityForOriginationEnd(keyValidityEndDateForOrigination)
+ .setKeyValidityForConsumptionEnd(keyValidityEndDateForConsumption)
+ .setRandomizedEncryptionRequired(false)
+ .setSignaturePaddings(KeyProperties.SIGNATURE_PADDING_RSA_PSS,
+ KeyProperties.SIGNATURE_PADDING_RSA_PKCS1)
+ .setUserAuthenticationRequired(true)
+ .setUserAuthenticationValidityDurationSeconds(12345)
+ .build();
+
+ assertEquals("arbitrary", spec.getKeystoreAlias());
+ assertEquals(
+ KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_ENCRYPT, spec.getPurposes());
+ assertSame(algSpecificParams, spec.getAlgorithmParameterSpec());
+ MoreAsserts.assertContentsInOrder(Arrays.asList(spec.getBlockModes()),
+ KeyProperties.BLOCK_MODE_GCM, KeyProperties.BLOCK_MODE_CBC);
+ assertEquals(certNotBeforeDate, spec.getCertificateNotBefore());
+ assertEquals(certNotAfterDate, spec.getCertificateNotAfter());
+ assertEquals(new BigInteger("13946146"), spec.getCertificateSerialNumber());
+ assertEquals(new X500Principal("CN=test"), spec.getCertificateSubject());
+ assertTrue(spec.isDigestsSpecified());
+ MoreAsserts.assertContentsInOrder(Arrays.asList(spec.getDigests()),
+ KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA384);
+ MoreAsserts.assertContentsInOrder(Arrays.asList(spec.getEncryptionPaddings()),
+ KeyProperties.ENCRYPTION_PADDING_RSA_OAEP, KeyProperties.ENCRYPTION_PADDING_PKCS7);
+ assertEquals(1234, spec.getKeySize());
+ assertEquals(keyValidityStartDate, spec.getKeyValidityStart());
+ assertEquals(keyValidityEndDateForOrigination, spec.getKeyValidityForOriginationEnd());
+ assertEquals(keyValidityEndDateForConsumption, spec.getKeyValidityForConsumptionEnd());
+ assertFalse(spec.isRandomizedEncryptionRequired());
+ MoreAsserts.assertContentsInOrder(Arrays.asList(spec.getSignaturePaddings()),
+ KeyProperties.SIGNATURE_PADDING_RSA_PSS, KeyProperties.SIGNATURE_PADDING_RSA_PKCS1);
+ assertTrue(spec.isUserAuthenticationRequired());
+ assertEquals(12345, spec.getUserAuthenticationValidityDurationSeconds());
+ }
+
+ public void testNullAliasNotPermitted() {
+ try {
+ new KeyGenParameterSpec.Builder(null, KeyProperties.PURPOSE_ENCRYPT);
+ fail();
+ } catch (NullPointerException expected) {}
+ }
+
+ public void testEmptyAliasNotPermitted() {
+ try {
+ new KeyGenParameterSpec.Builder("", KeyProperties.PURPOSE_ENCRYPT);
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ }
+
+ public void testSetKeyValidityEndDateAppliesToBothEndDates() {
+ Date date = new Date(System.currentTimeMillis() + 555555);
+ KeyGenParameterSpec spec = new KeyGenParameterSpec.Builder(
+ "ignore", KeyProperties.PURPOSE_VERIFY)
+ .setKeyValidityEnd(date)
+ .build();
+ assertEquals(date, spec.getKeyValidityForOriginationEnd());
+ assertEquals(date, spec.getKeyValidityForConsumptionEnd());
+ }
+
+ public void testSetUserAuthenticationValidityDurationSecondsValidityCheck() {
+ KeyGenParameterSpec.Builder builder = new KeyGenParameterSpec.Builder("alias", 0);
+ try {
+ builder.setUserAuthenticationValidityDurationSeconds(-2);
+ fail();
+ } catch (IllegalArgumentException expected) {}
+
+ try {
+ builder.setUserAuthenticationValidityDurationSeconds(-100);
+ fail();
+ } catch (IllegalArgumentException expected) {}
+
+ try {
+ builder.setUserAuthenticationValidityDurationSeconds(Integer.MIN_VALUE);
+ fail();
+ } catch (IllegalArgumentException expected) {}
+
+ builder.setUserAuthenticationValidityDurationSeconds(-1);
+ builder.setUserAuthenticationValidityDurationSeconds(0);
+ builder.setUserAuthenticationValidityDurationSeconds(1);
+ builder.setUserAuthenticationValidityDurationSeconds(Integer.MAX_VALUE);
+
+ try {
+ builder.setUserAuthenticationValidityDurationSeconds(-2);
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ }
+
+ public void testImmutabilityViaSetterParams() {
+ // Assert that all mutable parameters provided to setters are copied to ensure that values
+ // returned by getters never change.
+ String[] blockModes =
+ new String[] {KeyProperties.BLOCK_MODE_GCM, KeyProperties.BLOCK_MODE_CBC};
+ String[] originalBlockModes = blockModes.clone();
+ Date certNotBeforeDate = new Date(System.currentTimeMillis());
+ Date originalCertNotBeforeDate = new Date(certNotBeforeDate.getTime());
+ Date certNotAfterDate = new Date(System.currentTimeMillis() + 12345678);
+ Date originalCertNotAfterDate = new Date(certNotAfterDate.getTime());
+ Date keyValidityStartDate = new Date(System.currentTimeMillis() - 2222222);
+ Date originalKeyValidityStartDate = new Date(keyValidityStartDate.getTime());
+ Date keyValidityEndDateForOrigination = new Date(System.currentTimeMillis() + 11111111);
+ Date originalKeyValidityEndDateForOrigination =
+ new Date(keyValidityEndDateForOrigination.getTime());
+ Date keyValidityEndDateForConsumption = new Date(System.currentTimeMillis() + 33333333);
+ Date originalKeyValidityEndDateForConsumption =
+ new Date(keyValidityEndDateForConsumption.getTime());
+ String[] digests = new String[] {KeyProperties.DIGEST_MD5, KeyProperties.DIGEST_SHA512};
+ String[] originalDigests = digests.clone();
+ String[] encryptionPaddings = new String[] {
+ KeyProperties.ENCRYPTION_PADDING_RSA_OAEP, KeyProperties.ENCRYPTION_PADDING_PKCS7};
+ String[] originalEncryptionPaddings = encryptionPaddings.clone();
+ String[] signaturePaddings = new String[] {
+ KeyProperties.SIGNATURE_PADDING_RSA_PSS, KeyProperties.SIGNATURE_PADDING_RSA_PKCS1};
+ String[] originalSignaturePaddings = signaturePaddings.clone();
+
+ KeyGenParameterSpec spec = new KeyGenParameterSpec.Builder(
+ "arbitrary", KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_ENCRYPT)
+ .setBlockModes(blockModes)
+ .setCertificateNotBefore(certNotBeforeDate)
+ .setCertificateNotAfter(certNotAfterDate)
+ .setDigests(digests)
+ .setEncryptionPaddings(encryptionPaddings)
+ .setKeyValidityStart(keyValidityStartDate)
+ .setKeyValidityForOriginationEnd(keyValidityEndDateForOrigination)
+ .setKeyValidityForConsumptionEnd(keyValidityEndDateForConsumption)
+ .setSignaturePaddings(signaturePaddings)
+ .build();
+
+ assertEquals(Arrays.asList(originalBlockModes), Arrays.asList(spec.getBlockModes()));
+ blockModes[0] = null;
+ assertEquals(Arrays.asList(originalBlockModes), Arrays.asList(spec.getBlockModes()));
+
+ assertEquals(originalCertNotBeforeDate, spec.getCertificateNotBefore());
+ certNotBeforeDate.setTime(1234567890L);
+ assertEquals(originalCertNotBeforeDate, spec.getCertificateNotBefore());
+
+ assertEquals(originalCertNotAfterDate, spec.getCertificateNotAfter());
+ certNotAfterDate.setTime(1234567890L);
+ assertEquals(originalCertNotAfterDate, spec.getCertificateNotAfter());
+
+ assertEquals(Arrays.asList(originalDigests), Arrays.asList(spec.getDigests()));
+ digests[1] = null;
+ assertEquals(Arrays.asList(originalDigests), Arrays.asList(spec.getDigests()));
+
+ assertEquals(Arrays.asList(originalEncryptionPaddings),
+ Arrays.asList(spec.getEncryptionPaddings()));
+ encryptionPaddings[0] = null;
+ assertEquals(Arrays.asList(originalEncryptionPaddings),
+ Arrays.asList(spec.getEncryptionPaddings()));
+
+ assertEquals(originalKeyValidityStartDate, spec.getKeyValidityStart());
+ keyValidityStartDate.setTime(1234567890L);
+ assertEquals(originalKeyValidityStartDate, spec.getKeyValidityStart());
+
+ assertEquals(originalKeyValidityEndDateForOrigination,
+ spec.getKeyValidityForOriginationEnd());
+ keyValidityEndDateForOrigination.setTime(1234567890L);
+ assertEquals(originalKeyValidityEndDateForOrigination,
+ spec.getKeyValidityForOriginationEnd());
+
+ assertEquals(originalKeyValidityEndDateForConsumption,
+ spec.getKeyValidityForConsumptionEnd());
+ keyValidityEndDateForConsumption.setTime(1234567890L);
+ assertEquals(originalKeyValidityEndDateForConsumption,
+ spec.getKeyValidityForConsumptionEnd());
+
+ assertEquals(Arrays.asList(originalSignaturePaddings),
+ Arrays.asList(spec.getSignaturePaddings()));
+ signaturePaddings[1] = null;
+ assertEquals(Arrays.asList(originalSignaturePaddings),
+ Arrays.asList(spec.getSignaturePaddings()));
+ }
+
+ public void testImmutabilityViaGetterReturnValues() {
+ // Assert that none of the mutable return values from getters modify the state of the spec.
+
+ KeyGenParameterSpec spec = new KeyGenParameterSpec.Builder(
+ "arbitrary", KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_ENCRYPT)
+ .setBlockModes(KeyProperties.BLOCK_MODE_GCM, KeyProperties.BLOCK_MODE_CBC)
+ .setCertificateNotBefore(new Date(System.currentTimeMillis()))
+ .setCertificateNotAfter(new Date(System.currentTimeMillis() + 12345678))
+ .setDigests(KeyProperties.DIGEST_MD5, KeyProperties.DIGEST_SHA512)
+ .setEncryptionPaddings(
+ KeyProperties.ENCRYPTION_PADDING_RSA_OAEP,
+ KeyProperties.ENCRYPTION_PADDING_PKCS7)
+ .setKeyValidityStart(new Date(System.currentTimeMillis() - 2222222))
+ .setKeyValidityForOriginationEnd(new Date(System.currentTimeMillis() + 11111111))
+ .setKeyValidityForConsumptionEnd(new Date(System.currentTimeMillis() + 33333333))
+ .setSignaturePaddings(
+ KeyProperties.SIGNATURE_PADDING_RSA_PSS,
+ KeyProperties.SIGNATURE_PADDING_RSA_PKCS1)
+ .build();
+
+ String[] originalBlockModes = spec.getBlockModes().clone();
+ spec.getBlockModes()[0] = null;
+ assertEquals(Arrays.asList(originalBlockModes), Arrays.asList(spec.getBlockModes()));
+
+ Date originalCertNotBeforeDate = (Date) spec.getCertificateNotBefore().clone();
+ spec.getCertificateNotBefore().setTime(1234567890L);
+ assertEquals(originalCertNotBeforeDate, spec.getCertificateNotBefore());
+
+ Date originalCertNotAfterDate = (Date) spec.getCertificateNotAfter().clone();
+ spec.getCertificateNotAfter().setTime(1234567890L);
+ assertEquals(originalCertNotAfterDate, spec.getCertificateNotAfter());
+
+ String[] originalDigests = spec.getDigests().clone();
+ spec.getDigests()[0] = null;
+ assertEquals(Arrays.asList(originalDigests), Arrays.asList(spec.getDigests()));
+
+ String[] originalEncryptionPaddings = spec.getEncryptionPaddings().clone();
+ spec.getEncryptionPaddings()[0] = null;
+ assertEquals(Arrays.asList(originalEncryptionPaddings),
+ Arrays.asList(spec.getEncryptionPaddings()));
+
+ Date originalKeyValidityStartDate = (Date) spec.getKeyValidityStart().clone();
+ spec.getKeyValidityStart().setTime(1234567890L);
+ assertEquals(originalKeyValidityStartDate, spec.getKeyValidityStart());
+
+ Date originalKeyValidityEndDateForOrigination =
+ (Date) spec.getKeyValidityForOriginationEnd().clone();
+ spec.getKeyValidityForOriginationEnd().setTime(1234567890L);
+ assertEquals(originalKeyValidityEndDateForOrigination,
+ spec.getKeyValidityForOriginationEnd());
+
+ Date originalKeyValidityEndDateForConsumption =
+ (Date) spec.getKeyValidityForConsumptionEnd().clone();
+ spec.getKeyValidityForConsumptionEnd().setTime(1234567890L);
+ assertEquals(originalKeyValidityEndDateForConsumption,
+ spec.getKeyValidityForConsumptionEnd());
+
+ String[] originalSignaturePaddings = spec.getSignaturePaddings().clone();
+ spec.getSignaturePaddings()[0] = null;
+ assertEquals(Arrays.asList(originalSignaturePaddings),
+ Arrays.asList(spec.getSignaturePaddings()));
+ }
+}
diff --git a/tests/tests/keystore/src/android/keystore/cts/KeyInfoTest.java b/tests/tests/keystore/src/android/keystore/cts/KeyInfoTest.java
new file mode 100644
index 0000000..2b1d6fc
--- /dev/null
+++ b/tests/tests/keystore/src/android/keystore/cts/KeyInfoTest.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2015 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.keystore.cts;
+
+import android.security.keystore.KeyGenParameterSpec;
+import android.security.keystore.KeyInfo;
+import android.security.keystore.KeyProperties;
+
+import junit.framework.TestCase;
+
+import java.security.KeyFactory;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.PrivateKey;
+import java.util.Arrays;
+import java.util.Date;
+
+public class KeyInfoTest extends TestCase {
+
+ public void testImmutabilityViaGetterReturnValues() throws Exception {
+ // Assert that none of the mutable return values from getters modify the state of the
+ // instance.
+
+ Date keyValidityStartDate = new Date(System.currentTimeMillis() - 2222222);
+ Date keyValidityEndDateForOrigination = new Date(System.currentTimeMillis() + 11111111);
+ Date keyValidityEndDateForConsumption = new Date(System.currentTimeMillis() + 33333333);
+
+ KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA", "AndroidKeyStore");
+ keyPairGenerator.initialize(new KeyGenParameterSpec.Builder(
+ KeyInfoTest.class.getSimpleName(),
+ KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_ENCRYPT)
+ .setKeySize(1024) // use smaller key size to speed the test up
+ .setKeyValidityStart(keyValidityStartDate)
+ .setKeyValidityForOriginationEnd(keyValidityEndDateForOrigination)
+ .setKeyValidityForConsumptionEnd(keyValidityEndDateForConsumption)
+ .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1,
+ KeyProperties.ENCRYPTION_PADDING_RSA_OAEP)
+ .setSignaturePaddings(KeyProperties.SIGNATURE_PADDING_RSA_PKCS1,
+ KeyProperties.SIGNATURE_PADDING_RSA_PSS)
+ .setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA512)
+ .setBlockModes(KeyProperties.BLOCK_MODE_ECB)
+ .build());
+ KeyPair keyPair = keyPairGenerator.generateKeyPair();
+
+ PrivateKey key = keyPair.getPrivate();
+ KeyFactory keyFactory = KeyFactory.getInstance(key.getAlgorithm(), "AndroidKeyStore");
+ KeyInfo info = keyFactory.getKeySpec(key, KeyInfo.class);
+
+ Date originalKeyValidityStartDate = (Date) info.getKeyValidityStart().clone();
+ info.getKeyValidityStart().setTime(1234567890L);
+ assertEquals(originalKeyValidityStartDate, info.getKeyValidityStart());
+
+ Date originalKeyValidityEndDateForOrigination =
+ (Date) info.getKeyValidityForOriginationEnd().clone();
+ info.getKeyValidityForOriginationEnd().setTime(1234567890L);
+ assertEquals(originalKeyValidityEndDateForOrigination,
+ info.getKeyValidityForOriginationEnd());
+
+ Date originalKeyValidityEndDateForConsumption =
+ (Date) info.getKeyValidityForConsumptionEnd().clone();
+ info.getKeyValidityForConsumptionEnd().setTime(1234567890L);
+ assertEquals(originalKeyValidityEndDateForConsumption,
+ info.getKeyValidityForConsumptionEnd());
+
+ String[] originalEncryptionPaddings = info.getEncryptionPaddings().clone();
+ info.getEncryptionPaddings()[0] = null;
+ assertEquals(Arrays.asList(originalEncryptionPaddings),
+ Arrays.asList(info.getEncryptionPaddings()));
+
+ String[] originalSignaturePaddings = info.getSignaturePaddings().clone();
+ info.getSignaturePaddings()[0] = null;
+ assertEquals(Arrays.asList(originalSignaturePaddings),
+ Arrays.asList(info.getSignaturePaddings()));
+
+ String[] originalDigests = info.getDigests().clone();
+ info.getDigests()[0] = null;
+ assertEquals(Arrays.asList(originalDigests), Arrays.asList(info.getDigests()));
+
+ String[] originalBlockModes = info.getBlockModes().clone();
+ info.getBlockModes()[0] = null;
+ assertEquals(Arrays.asList(originalBlockModes), Arrays.asList(info.getBlockModes()));
+ }
+}
diff --git a/tests/tests/keystore/src/android/keystore/cts/KeyProtectionTest.java b/tests/tests/keystore/src/android/keystore/cts/KeyProtectionTest.java
new file mode 100644
index 0000000..ee24eed
--- /dev/null
+++ b/tests/tests/keystore/src/android/keystore/cts/KeyProtectionTest.java
@@ -0,0 +1,255 @@
+/*
+ * Copyright 2015 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.keystore.cts;
+
+import android.security.keystore.KeyProperties;
+import android.security.keystore.KeyProtection;
+import android.test.MoreAsserts;
+
+import junit.framework.TestCase;
+
+import java.util.Arrays;
+import java.util.Date;
+
+public class KeyProtectionTest extends TestCase {
+ public void testDefaults() {
+ // Set only the mandatory parameters and assert values returned by getters.
+
+ KeyProtection spec = new KeyProtection.Builder(KeyProperties.PURPOSE_ENCRYPT)
+ .build();
+
+ assertEquals(KeyProperties.PURPOSE_ENCRYPT, spec.getPurposes());
+ MoreAsserts.assertEmpty(Arrays.asList(spec.getBlockModes()));
+ assertFalse(spec.isDigestsSpecified());
+ try {
+ spec.getDigests();
+ fail();
+ } catch (IllegalStateException expected) {}
+ MoreAsserts.assertEmpty(Arrays.asList(spec.getEncryptionPaddings()));
+ assertNull(spec.getKeyValidityStart());
+ assertNull(spec.getKeyValidityForOriginationEnd());
+ assertNull(spec.getKeyValidityForConsumptionEnd());
+ assertTrue(spec.isRandomizedEncryptionRequired());
+ MoreAsserts.assertEmpty(Arrays.asList(spec.getSignaturePaddings()));
+ assertFalse(spec.isUserAuthenticationRequired());
+ assertEquals(-1, spec.getUserAuthenticationValidityDurationSeconds());
+ }
+
+ public void testSettersReflectedInGetters() {
+ // Set all parameters to non-default values and then assert that getters reflect that.
+
+ Date keyValidityStartDate = new Date(System.currentTimeMillis() - 2222222);
+ Date keyValidityEndDateForOrigination = new Date(System.currentTimeMillis() + 11111111);
+ Date keyValidityEndDateForConsumption = new Date(System.currentTimeMillis() + 33333333);
+
+ KeyProtection spec = new KeyProtection.Builder(
+ KeyProperties.PURPOSE_DECRYPT | KeyProperties.PURPOSE_VERIFY)
+ .setBlockModes(KeyProperties.BLOCK_MODE_GCM, KeyProperties.BLOCK_MODE_CTR)
+ .setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA512)
+ .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1,
+ KeyProperties.ENCRYPTION_PADDING_PKCS7)
+ .setKeyValidityStart(keyValidityStartDate)
+ .setKeyValidityForOriginationEnd(keyValidityEndDateForOrigination)
+ .setKeyValidityForConsumptionEnd(keyValidityEndDateForConsumption)
+ .setRandomizedEncryptionRequired(false)
+ .setSignaturePaddings(KeyProperties.SIGNATURE_PADDING_RSA_PKCS1,
+ KeyProperties.SIGNATURE_PADDING_RSA_PSS)
+ .setUserAuthenticationRequired(true)
+ .setUserAuthenticationValidityDurationSeconds(123456)
+ .build();
+
+ assertEquals(
+ KeyProperties.PURPOSE_DECRYPT| KeyProperties.PURPOSE_VERIFY, spec.getPurposes());
+ MoreAsserts.assertContentsInOrder(Arrays.asList(spec.getBlockModes()),
+ KeyProperties.BLOCK_MODE_GCM, KeyProperties.BLOCK_MODE_CTR);
+ assertTrue(spec.isDigestsSpecified());
+ MoreAsserts.assertContentsInOrder(Arrays.asList(spec.getDigests()),
+ KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA512);
+ MoreAsserts.assertContentsInOrder(Arrays.asList(spec.getEncryptionPaddings()),
+ KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1, KeyProperties.ENCRYPTION_PADDING_PKCS7);
+ assertEquals(keyValidityStartDate, spec.getKeyValidityStart());
+ assertEquals(keyValidityEndDateForOrigination, spec.getKeyValidityForOriginationEnd());
+ assertEquals(keyValidityEndDateForConsumption, spec.getKeyValidityForConsumptionEnd());
+ assertFalse(spec.isRandomizedEncryptionRequired());
+ MoreAsserts.assertContentsInOrder(Arrays.asList(spec.getSignaturePaddings()),
+ KeyProperties.SIGNATURE_PADDING_RSA_PKCS1, KeyProperties.SIGNATURE_PADDING_RSA_PSS);
+ assertTrue(spec.isUserAuthenticationRequired());
+ assertEquals(123456, spec.getUserAuthenticationValidityDurationSeconds());
+ }
+
+ public void testSetKeyValidityEndDateAppliesToBothEndDates() {
+ Date date = new Date(System.currentTimeMillis() + 555555);
+ KeyProtection spec = new KeyProtection.Builder(
+ KeyProperties.PURPOSE_SIGN)
+ .setKeyValidityEnd(date)
+ .build();
+ assertEquals(date, spec.getKeyValidityForOriginationEnd());
+ assertEquals(date, spec.getKeyValidityForConsumptionEnd());
+ }
+
+ public void testSetUserAuthenticationValidityDurationSecondsValidityCheck() {
+ KeyProtection.Builder builder = new KeyProtection.Builder(0);
+ try {
+ builder.setUserAuthenticationValidityDurationSeconds(-2);
+ fail();
+ } catch (IllegalArgumentException expected) {}
+
+ try {
+ builder.setUserAuthenticationValidityDurationSeconds(-100);
+ fail();
+ } catch (IllegalArgumentException expected) {}
+
+ try {
+ builder.setUserAuthenticationValidityDurationSeconds(Integer.MIN_VALUE);
+ fail();
+ } catch (IllegalArgumentException expected) {}
+
+ builder.setUserAuthenticationValidityDurationSeconds(-1);
+ builder.setUserAuthenticationValidityDurationSeconds(0);
+ builder.setUserAuthenticationValidityDurationSeconds(1);
+ builder.setUserAuthenticationValidityDurationSeconds(Integer.MAX_VALUE);
+
+ try {
+ builder.setUserAuthenticationValidityDurationSeconds(-2);
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ }
+
+ public void testImmutabilityViaSetterParams() {
+ // Assert that all mutable parameters provided to setters are copied to ensure that values
+ // returned by getters never change.
+ String[] blockModes =
+ new String[] {KeyProperties.BLOCK_MODE_GCM, KeyProperties.BLOCK_MODE_CBC};
+ String[] originalBlockModes = blockModes.clone();
+ Date keyValidityStartDate = new Date(System.currentTimeMillis() - 2222222);
+ Date originalKeyValidityStartDate = new Date(keyValidityStartDate.getTime());
+ Date keyValidityEndDateForOrigination = new Date(System.currentTimeMillis() + 11111111);
+ Date originalKeyValidityEndDateForOrigination =
+ new Date(keyValidityEndDateForOrigination.getTime());
+ Date keyValidityEndDateForConsumption = new Date(System.currentTimeMillis() + 33333333);
+ Date originalKeyValidityEndDateForConsumption =
+ new Date(keyValidityEndDateForConsumption.getTime());
+ String[] digests = new String[] {KeyProperties.DIGEST_MD5, KeyProperties.DIGEST_SHA512};
+ String[] originalDigests = digests.clone();
+ String[] encryptionPaddings = new String[] {
+ KeyProperties.ENCRYPTION_PADDING_RSA_OAEP, KeyProperties.ENCRYPTION_PADDING_PKCS7};
+ String[] originalEncryptionPaddings = encryptionPaddings.clone();
+ String[] signaturePaddings = new String[] {
+ KeyProperties.SIGNATURE_PADDING_RSA_PSS, KeyProperties.SIGNATURE_PADDING_RSA_PKCS1};
+ String[] originalSignaturePaddings = signaturePaddings.clone();
+
+ KeyProtection spec = new KeyProtection.Builder(
+ KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_ENCRYPT)
+ .setBlockModes(blockModes)
+ .setDigests(digests)
+ .setEncryptionPaddings(encryptionPaddings)
+ .setKeyValidityStart(keyValidityStartDate)
+ .setKeyValidityForOriginationEnd(keyValidityEndDateForOrigination)
+ .setKeyValidityForConsumptionEnd(keyValidityEndDateForConsumption)
+ .setSignaturePaddings(signaturePaddings)
+ .build();
+
+ assertEquals(Arrays.asList(originalBlockModes), Arrays.asList(spec.getBlockModes()));
+ blockModes[0] = null;
+ assertEquals(Arrays.asList(originalBlockModes), Arrays.asList(spec.getBlockModes()));
+
+ assertEquals(Arrays.asList(originalDigests), Arrays.asList(spec.getDigests()));
+ digests[1] = null;
+ assertEquals(Arrays.asList(originalDigests), Arrays.asList(spec.getDigests()));
+
+ assertEquals(Arrays.asList(originalEncryptionPaddings),
+ Arrays.asList(spec.getEncryptionPaddings()));
+ encryptionPaddings[0] = null;
+ assertEquals(Arrays.asList(originalEncryptionPaddings),
+ Arrays.asList(spec.getEncryptionPaddings()));
+
+ assertEquals(originalKeyValidityStartDate, spec.getKeyValidityStart());
+ keyValidityStartDate.setTime(1234567890L);
+ assertEquals(originalKeyValidityStartDate, spec.getKeyValidityStart());
+
+ assertEquals(originalKeyValidityEndDateForOrigination,
+ spec.getKeyValidityForOriginationEnd());
+ keyValidityEndDateForOrigination.setTime(1234567890L);
+ assertEquals(originalKeyValidityEndDateForOrigination,
+ spec.getKeyValidityForOriginationEnd());
+
+ assertEquals(originalKeyValidityEndDateForConsumption,
+ spec.getKeyValidityForConsumptionEnd());
+ keyValidityEndDateForConsumption.setTime(1234567890L);
+ assertEquals(originalKeyValidityEndDateForConsumption,
+ spec.getKeyValidityForConsumptionEnd());
+
+ assertEquals(Arrays.asList(originalSignaturePaddings),
+ Arrays.asList(spec.getSignaturePaddings()));
+ signaturePaddings[1] = null;
+ assertEquals(Arrays.asList(originalSignaturePaddings),
+ Arrays.asList(spec.getSignaturePaddings()));
+ }
+
+ public void testImmutabilityViaGetterReturnValues() {
+ // Assert that none of the mutable return values from getters modify the state of the spec.
+
+ KeyProtection spec = new KeyProtection.Builder(
+ KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_ENCRYPT)
+ .setBlockModes(KeyProperties.BLOCK_MODE_GCM, KeyProperties.BLOCK_MODE_CBC)
+ .setDigests(KeyProperties.DIGEST_MD5, KeyProperties.DIGEST_SHA512)
+ .setEncryptionPaddings(
+ KeyProperties.ENCRYPTION_PADDING_RSA_OAEP,
+ KeyProperties.ENCRYPTION_PADDING_PKCS7)
+ .setKeyValidityStart(new Date(System.currentTimeMillis() - 2222222))
+ .setKeyValidityForOriginationEnd(new Date(System.currentTimeMillis() + 11111111))
+ .setKeyValidityForConsumptionEnd(new Date(System.currentTimeMillis() + 33333333))
+ .setSignaturePaddings(
+ KeyProperties.SIGNATURE_PADDING_RSA_PSS,
+ KeyProperties.SIGNATURE_PADDING_RSA_PKCS1)
+ .build();
+
+ String[] originalBlockModes = spec.getBlockModes().clone();
+ spec.getBlockModes()[0] = null;
+ assertEquals(Arrays.asList(originalBlockModes), Arrays.asList(spec.getBlockModes()));
+
+ String[] originalDigests = spec.getDigests().clone();
+ spec.getDigests()[0] = null;
+ assertEquals(Arrays.asList(originalDigests), Arrays.asList(spec.getDigests()));
+
+ String[] originalEncryptionPaddings = spec.getEncryptionPaddings().clone();
+ spec.getEncryptionPaddings()[0] = null;
+ assertEquals(Arrays.asList(originalEncryptionPaddings),
+ Arrays.asList(spec.getEncryptionPaddings()));
+
+ Date originalKeyValidityStartDate = (Date) spec.getKeyValidityStart().clone();
+ spec.getKeyValidityStart().setTime(1234567890L);
+ assertEquals(originalKeyValidityStartDate, spec.getKeyValidityStart());
+
+ Date originalKeyValidityEndDateForOrigination =
+ (Date) spec.getKeyValidityForOriginationEnd().clone();
+ spec.getKeyValidityForOriginationEnd().setTime(1234567890L);
+ assertEquals(originalKeyValidityEndDateForOrigination,
+ spec.getKeyValidityForOriginationEnd());
+
+ Date originalKeyValidityEndDateForConsumption =
+ (Date) spec.getKeyValidityForConsumptionEnd().clone();
+ spec.getKeyValidityForConsumptionEnd().setTime(1234567890L);
+ assertEquals(originalKeyValidityEndDateForConsumption,
+ spec.getKeyValidityForConsumptionEnd());
+
+ String[] originalSignaturePaddings = spec.getSignaturePaddings().clone();
+ spec.getSignaturePaddings()[0] = null;
+ assertEquals(Arrays.asList(originalSignaturePaddings),
+ Arrays.asList(spec.getSignaturePaddings()));
+ }
+}
diff --git a/tests/tests/telephony/src/android/telephony/cts/PhoneStateListenerTest.java b/tests/tests/telephony/src/android/telephony/cts/PhoneStateListenerTest.java
index f0f977a..18aa23f 100644
--- a/tests/tests/telephony/src/android/telephony/cts/PhoneStateListenerTest.java
+++ b/tests/tests/telephony/src/android/telephony/cts/PhoneStateListenerTest.java
@@ -22,6 +22,7 @@
import android.telephony.CellLocation;
import android.telephony.PhoneStateListener;
import android.telephony.ServiceState;
+import android.telephony.SignalStrength;
import android.telephony.TelephonyManager;
import android.net.ConnectivityManager;
import android.test.InstrumentationTestCase;
@@ -40,6 +41,7 @@
private boolean mOnMessageWaitingIndicatorChangedCalled;
private boolean mOnServiceStateChangedCalled;
private boolean mOnSignalStrengthChangedCalled;
+ private SignalStrength mSignalStrength;
private TelephonyManager mTelephonyManager;
private PhoneStateListener mListener;
private final Object mLock = new Object();
@@ -152,6 +154,54 @@
assertTrue(mOnSignalStrengthChangedCalled);
}
+ public void testOnSignalStrengthsChanged() throws Throwable {
+ if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
+ Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
+ return;
+ }
+
+ TestThread t = new TestThread(new Runnable() {
+ public void run() {
+ Looper.prepare();
+
+ mListener = new PhoneStateListener() {
+ @Override
+ public void onSignalStrengthsChanged(SignalStrength signalStrength) {
+ synchronized(mLock) {
+ mSignalStrength = signalStrength;
+ mLock.notify();
+ }
+ }
+ };
+ mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);
+
+ Looper.loop();
+ }
+ });
+
+ assertTrue(mSignalStrength == null);
+ t.start();
+
+ synchronized (mLock) {
+ while(mSignalStrength == null) {
+ mLock.wait();
+ }
+ }
+ t.checkException();
+ assertTrue(mSignalStrength != null);
+
+ // Call SignalStrength methods to make sure they do not throw any exceptions
+ mSignalStrength.getCdmaDbm();
+ mSignalStrength.getCdmaEcio();
+ mSignalStrength.getEvdoDbm();
+ mSignalStrength.getEvdoEcio();
+ mSignalStrength.getEvdoSnr();
+ mSignalStrength.getGsmBitErrorRate();
+ mSignalStrength.getGsmSignalStrength();
+ mSignalStrength.isGsm();
+ mSignalStrength.getLevel();
+ }
+
public void testOnMessageWaitingIndicatorChanged() throws Throwable {
if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
diff --git a/tests/tests/telephony/src/android/telephony/cts/TelephonyManagerTest.java b/tests/tests/telephony/src/android/telephony/cts/TelephonyManagerTest.java
index 2be1dcb..ce3fe78 100644
--- a/tests/tests/telephony/src/android/telephony/cts/TelephonyManagerTest.java
+++ b/tests/tests/telephony/src/android/telephony/cts/TelephonyManagerTest.java
@@ -160,7 +160,28 @@
mTelephonyManager.getNeighboringCellInfo();
mTelephonyManager.isNetworkRoaming();
mTelephonyManager.getDeviceId();
+ mTelephonyManager.getDeviceId(mTelephonyManager.getDefaultSim());
mTelephonyManager.getDeviceSoftwareVersion();
+ mTelephonyManager.getPhoneCount();
+ }
+
+ /**
+ * Tests that the phone count returned is valid.
+ */
+ public void testGetPhoneCount() {
+ int phoneCount = mTelephonyManager.getPhoneCount();
+ int phoneType = mTelephonyManager.getPhoneType();
+ switch (phoneType) {
+ case TelephonyManager.PHONE_TYPE_GSM:
+ case TelephonyManager.PHONE_TYPE_CDMA:
+ assertTrue("Phone count should be > 0", phoneCount > 0);
+ break;
+ case TelephonyManager.PHONE_TYPE_NONE:
+ assertTrue("Phone count should be 0", phoneCount == 0);
+ break;
+ default:
+ throw new IllegalArgumentException("Did you add a new phone type? " + phoneType);
+ }
}
/**
@@ -170,6 +191,24 @@
*/
public void testGetDeviceId() {
String deviceId = mTelephonyManager.getDeviceId();
+ verifyDeviceId(deviceId);
+ }
+
+ /**
+ * Tests that the device properly reports either a valid IMEI if
+ * GSM, a valid MEID or ESN if CDMA, or a valid MAC address if
+ * only a WiFi device.
+ */
+ public void testGetDeviceIdForSlotId() {
+ String deviceId = mTelephonyManager.getDeviceId(mTelephonyManager.getDefaultSim());
+ verifyDeviceId(deviceId);
+ // Also verify that no exception is thrown for any slot id (including invalid ones)
+ for (int i = -1; i <= mTelephonyManager.getPhoneCount(); i++) {
+ mTelephonyManager.getDeviceId(i);
+ }
+ }
+
+ private void verifyDeviceId(String deviceId) {
int phoneType = mTelephonyManager.getPhoneType();
switch (phoneType) {
case TelephonyManager.PHONE_TYPE_GSM:
diff --git a/tests/tests/text/src/android/text/cts/SpannableStringBuilderTest.java b/tests/tests/text/src/android/text/cts/SpannableStringBuilderTest.java
index 4895ca9..36b081c 100644
--- a/tests/tests/text/src/android/text/cts/SpannableStringBuilderTest.java
+++ b/tests/tests/text/src/android/text/cts/SpannableStringBuilderTest.java
@@ -18,10 +18,12 @@
import android.test.AndroidTestCase;
+import android.text.Editable;
import android.text.InputFilter;
import android.text.SpannableString;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
+import android.text.TextWatcher;
import android.text.style.StrikethroughSpan;
import android.text.style.TabStopSpan;
import android.text.style.UnderlineSpan;
@@ -596,4 +598,46 @@
// expected exception
}
}
+
+ private static class MockTextWatcher implements TextWatcher {
+ private int mDepth = 0;
+
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+ SpannableStringBuilder builder = (SpannableStringBuilder)s;
+ mDepth++;
+ assertEquals(mDepth, builder.getTextWatcherDepth());
+ mDepth--;
+ }
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
+ SpannableStringBuilder builder = (SpannableStringBuilder)s;
+ mDepth++;
+ assertEquals(mDepth, builder.getTextWatcherDepth());
+ mDepth--;
+ }
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ SpannableStringBuilder builder = (SpannableStringBuilder)s;
+ mDepth++;
+ assertEquals(mDepth, builder.getTextWatcherDepth());
+ if (mDepth <= builder.length()) {
+ // This will recursively call afterTextChanged.
+ builder.replace(mDepth - 1, mDepth, "a");
+ }
+ mDepth--;
+ }
+ }
+
+ public void testGetTextWatcherDepth() {
+ SpannableStringBuilder builder = new SpannableStringBuilder("hello");
+ builder.setSpan(new MockTextWatcher(), 0, builder.length(), 0);
+ assertEquals(0, builder.getTextWatcherDepth());
+ builder.replace(0, 1, "H");
+ assertEquals(0, builder.getTextWatcherDepth());
+ // MockTextWatcher replaces each character with 'a'.
+ assertEquals("aaaaa", builder.toString());
+ }
}