diff options
18 files changed, 412 insertions, 121 deletions
diff --git a/core/java/android/nfc/cardemulation/ApduServiceInfo.java b/core/java/android/nfc/cardemulation/ApduServiceInfo.java index 00b2ee3..f10e530 100644 --- a/core/java/android/nfc/cardemulation/ApduServiceInfo.java +++ b/core/java/android/nfc/cardemulation/ApduServiceInfo.java @@ -40,6 +40,7 @@ import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; /** @@ -262,7 +263,7 @@ public final class ApduServiceInfo implements Parcelable { * for that category. * @return List of AIDs registered by the service */ - public ArrayList<String> getAids() { + public List<String> getAids() { final ArrayList<String> aids = new ArrayList<String>(); for (AidGroup group : getAidGroups()) { aids.addAll(group.aids); @@ -270,6 +271,18 @@ public final class ApduServiceInfo implements Parcelable { return aids; } + public List<String> getPrefixAids() { + final ArrayList<String> prefixAids = new ArrayList<String>(); + for (AidGroup group : getAidGroups()) { + for (String aid : group.aids) { + if (aid.endsWith("*")) { + prefixAids.add(aid); + } + } + } + return prefixAids; + } + /** * Returns the registered AID group for this category. */ diff --git a/core/java/android/os/Debug.java b/core/java/android/os/Debug.java index 2d92c7b..2a60b4d 100644 --- a/core/java/android/os/Debug.java +++ b/core/java/android/os/Debug.java @@ -34,6 +34,7 @@ import java.lang.annotation.Target; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import java.util.Map; import org.apache.harmony.dalvik.ddmc.Chunk; import org.apache.harmony.dalvik.ddmc.ChunkHandler; @@ -1035,6 +1036,95 @@ href="{@docRoot}guide/developing/tools/traceview.html">Traceview: A Graphical Lo } /** + * Returns the value of a particular runtime statistic or {@code null} if no + * such runtime statistic exists. + * + * <p>The following table lists the runtime statistics that the runtime supports. + * Note runtime statistics may be added or removed in a future API level.</p> + * + * <table> + * <thead> + * <tr> + * <th>Runtime statistic name</th> + * <th>Meaning</th> + * <th>Example</th> + * <th>Supported (API Levels)</th> + * </tr> + * </thead> + * <tbody> + * <tr> + * <td>art.gc.gc-count</td> + * <td>The number of garbage collection runs.</td> + * <td>{@code 164}</td> + * <td>23</td> + * </tr> + * <tr> + * <td>art.gc.gc-time</td> + * <td>The total duration of garbage collection runs in ms.</td> + * <td>{@code 62364}</td> + * <td>23</td> + * </tr> + * <tr> + * <td>art.gc.bytes-allocated</td> + * <td>The total number of bytes that the application allocated.</td> + * <td>{@code 1463948408}</td> + * <td>23</td> + * </tr> + * <tr> + * <td>art.gc.bytes-freed</td> + * <td>The total number of bytes that garbage collection reclaimed.</td> + * <td>{@code 1313493084}</td> + * <td>23</td> + * </tr> + * <tr> + * <td>art.gc.blocking-gc-count</td> + * <td>The number of blocking garbage collection runs.</td> + * <td>{@code 2}</td> + * <td>23</td> + * </tr> + * <tr> + * <td>art.gc.blocking-gc-time</td> + * <td>The total duration of blocking garbage collection runs in ms.</td> + * <td>{@code 804}</td> + * <td>23</td> + * </tr> + * <tr> + * <td>art.gc.gc-count-rate-histogram</td> + * <td>The histogram of the number of garbage collection runs per 10 seconds.</td> + * <td>{@code 0:34503,1:45350,2:11281,3:8088,4:43,5:8}</td> + * <td>23</td> + * </tr> + * <tr> + * <td>art.gc.blocking-gc-count-rate-histogram</td> + * <td>The histogram of the number of garbage collection runs per 10 seconds.</td> + * <td>{@code 0:99269,1:1,2:1}</td> + * <td>23</td> + * </tr> + * </tbody> + * </table> + * + * @param statName + * the name of the runtime statistic to look up. + * @return the value of the specified runtime statistic or {@code null} if the + * runtime statistic doesn't exist. + * @hide + */ + public static String getRuntimeStat(String statName) { + return VMDebug.getRuntimeStat(statName); + } + + /** + * Returns a map of the names/values of the runtime statistics + * that {@link #getRuntimeStat(String)} supports. + * + * @return a map of the names/values of the supported runtime statistics. + * @hide + */ + public static Map<String, String> getRuntimeStats() { + return VMDebug.getRuntimeStats(); + } + + /** * Returns the size of the native heap. * @return The size of the native heap in bytes. */ diff --git a/core/java/android/security/keymaster/KeymasterDefs.java b/core/java/android/security/keymaster/KeymasterDefs.java index 298636b..25ebe75 100644 --- a/core/java/android/security/keymaster/KeymasterDefs.java +++ b/core/java/android/security/keymaster/KeymasterDefs.java @@ -191,6 +191,8 @@ public final class KeymasterDefs { public static final int KM_ERROR_SECURE_HW_BUSY = -48; public static final int KM_ERROR_SECURE_HW_COMMUNICATION_FAILED = -49; public static final int KM_ERROR_UNSUPPORTED_EC_FIELD = -50; + public static final int KM_ERROR_MISSING_NONCE = -51; + public static final int KM_ERROR_INVALID_NONCE = -52; public static final int KM_ERROR_UNIMPLEMENTED = -100; public static final int KM_ERROR_VERSION_MISMATCH = -101; public static final int KM_ERROR_UNKNOWN_ERROR = -1000; @@ -230,6 +232,8 @@ public final class KeymasterDefs { sErrorCodeToString.put(KM_ERROR_INVALID_TAG, "Invalid tag"); sErrorCodeToString.put(KM_ERROR_MEMORY_ALLOCATION_FAILED, "Memory allocation failed"); sErrorCodeToString.put(KM_ERROR_UNSUPPORTED_EC_FIELD, "Unsupported EC field"); + sErrorCodeToString.put(KM_ERROR_MISSING_NONCE, "Required IV missing"); + sErrorCodeToString.put(KM_ERROR_INVALID_NONCE, "Invalid IV"); sErrorCodeToString.put(KM_ERROR_UNIMPLEMENTED, "Not implemented"); sErrorCodeToString.put(KM_ERROR_UNKNOWN_ERROR, "Unknown error"); } diff --git a/docs/html/tools/help/hprof-conv.jd b/docs/html/tools/help/hprof-conv.jd index f96def2..982f337 100644 --- a/docs/html/tools/help/hprof-conv.jd +++ b/docs/html/tools/help/hprof-conv.jd @@ -8,9 +8,13 @@ The <code>hprof-conv</code> tool converts the HPROF file that is generated by the Android SDK tools to a standard format so you can view the file in a profiling tool of your choice. </p> -<pre> hprof-conv <infile> <outfile></pre> +<pre> hprof-conv [-z] <infile> <outfile></pre> <p> You can use "-" for <code><infile></code> or <code><outfile></code> to specify stdin or stdout. </p> + +<p> +You can use "-z" to filter out zygote allocations shared by all applications. +</p> diff --git a/include/androidfw/ResourceTypes.h b/include/androidfw/ResourceTypes.h index 0822afd..8de0138 100644 --- a/include/androidfw/ResourceTypes.h +++ b/include/androidfw/ResourceTypes.h @@ -372,7 +372,8 @@ struct Res_value }; // The data for this item, as interpreted according to dataType. - uint32_t data; + typedef uint32_t data_type; + data_type data; void copyFrom_dtoh(const Res_value& src); }; @@ -1502,6 +1503,8 @@ private: KeyedVector<String16, uint8_t> mEntries; }; +bool U16StringToInt(const char16_t* s, size_t len, Res_value* outValue); + /** * Convenience class for accessing data in a ResTable resource. */ diff --git a/keystore/java/android/security/AndroidKeyStore.java b/keystore/java/android/security/AndroidKeyStore.java index fcee9fc..964fb21 100644 --- a/keystore/java/android/security/AndroidKeyStore.java +++ b/keystore/java/android/security/AndroidKeyStore.java @@ -55,6 +55,7 @@ import java.util.Date; import java.util.Enumeration; import java.util.HashSet; import java.util.Iterator; +import java.util.List; import java.util.Set; import javax.crypto.SecretKey; @@ -116,11 +117,15 @@ public class AndroidKeyStore extends KeyStoreSpi { throw new UnrecoverableKeyException("Key algorithm unknown"); } - int keymasterDigest = - keyCharacteristics.hwEnforced.getInt(KeymasterDefs.KM_TAG_DIGEST, -1); - if (keymasterDigest == -1) { - keymasterDigest = - keyCharacteristics.swEnforced.getInt(KeymasterDefs.KM_TAG_DIGEST, -1); + List<Integer> keymasterDigests = + keyCharacteristics.getInts(KeymasterDefs.KM_TAG_DIGEST); + int keymasterDigest; + if (keymasterDigests.isEmpty()) { + keymasterDigest = -1; + } else { + // More than one digest can be permitted for this key. Use the first one to form the + // JCA key algorithm name. + keymasterDigest = keymasterDigests.get(0); } String keyAlgorithmString; diff --git a/keystore/java/android/security/EcIesParameterSpec.java b/keystore/java/android/security/EcIesParameterSpec.java index 0f19812..3372da9 100644 --- a/keystore/java/android/security/EcIesParameterSpec.java +++ b/keystore/java/android/security/EcIesParameterSpec.java @@ -85,11 +85,10 @@ public class EcIesParameterSpec implements AlgorithmParameterSpec { } /** - * Default parameter spec: NIST P-256 curve (aka secp256r1 aka prime256v1), compressed point - * format, {@code HKDFwithSHA256}, DEM uses 128-bit AES GCM. + * Default parameter spec: compressed point format, {@code HKDFwithSHA256}, DEM uses 128-bit AES + * GCM. */ public static final EcIesParameterSpec DEFAULT = new EcIesParameterSpec( - "P-256", PointFormat.COMPRESSED, "HKDFwithSHA256", "AES/GCM/NoPadding", @@ -97,7 +96,6 @@ public class EcIesParameterSpec implements AlgorithmParameterSpec { null, 0); - private final String mKemCurveName; private final @PointFormatEnum int mKemPointFormat; private final String mKemKdfAlgorithm; private final String mDemCipherTransformation; @@ -106,14 +104,12 @@ public class EcIesParameterSpec implements AlgorithmParameterSpec { private final int mDemMacKeySize; private EcIesParameterSpec( - String kemCurveName, @PointFormatEnum int kemPointFormat, String kemKdfAlgorithm, String demCipherTransformation, int demCipherKeySize, String demMacAlgorithm, int demMacKeySize) { - mKemCurveName = kemCurveName; mKemPointFormat = kemPointFormat; mKemKdfAlgorithm = kemKdfAlgorithm; mDemCipherTransformation = demCipherTransformation; @@ -123,13 +119,6 @@ public class EcIesParameterSpec implements AlgorithmParameterSpec { } /** - * Returns KEM EC curve name (e.g., {@code secp256r1}) or {@code null} if not specified. - */ - public String getKemCurveName() { - return mKemCurveName; - } - - /** * Returns KEM EC point wire format or {@link PointFormat#UNSPECIFIED} if not specified. */ public @PointFormatEnum int getKemPointFormat() { @@ -188,7 +177,6 @@ public class EcIesParameterSpec implements AlgorithmParameterSpec { * Builder of {@link EcIesParameterSpec}. */ public static class Builder { - private String mKemCurveName; private @PointFormatEnum int mKemPointFormat = PointFormat.UNSPECIFIED; private String mKemKdfAlgorithm; private String mDemCipherTransformation; @@ -197,16 +185,6 @@ public class EcIesParameterSpec implements AlgorithmParameterSpec { private int mDemMacKeySize = -1; /** - * Sets KEM EC curve name. For example, {@code P-256} or {@code secp256r1}. - * - * <p>NOTE: Only curves with cofactor of {@code 1} are supported. - */ - public Builder setKemCurveName(String name) { - mKemCurveName = name; - return this; - } - - /** * Sets KEM EC point wire format. */ public Builder setKemPointFormat(@PointFormatEnum int pointFormat) { @@ -274,7 +252,6 @@ public class EcIesParameterSpec implements AlgorithmParameterSpec { public EcIesParameterSpec build() { int demMacKeySize = (mDemMacKeySize != -1) ? mDemMacKeySize : mDemCipherKeySize; return new EcIesParameterSpec( - mKemCurveName, mKemPointFormat, mKemKdfAlgorithm, mDemCipherTransformation, diff --git a/keystore/java/android/security/KeyPairGeneratorSpec.java b/keystore/java/android/security/KeyPairGeneratorSpec.java index 9d6701a..fce02df 100644 --- a/keystore/java/android/security/KeyPairGeneratorSpec.java +++ b/keystore/java/android/security/KeyPairGeneratorSpec.java @@ -52,6 +52,11 @@ import javax.security.auth.x500.X500Principal; */ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec { + 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 + private final Context mContext; private final String mKeystoreAlias; @@ -144,22 +149,29 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec { throw new IllegalArgumentException("context == null"); } else if (TextUtils.isEmpty(keyStoreAlias)) { throw new IllegalArgumentException("keyStoreAlias must not be empty"); - } else if (subjectDN == null) { - throw new IllegalArgumentException("subjectDN == null"); - } else if (serialNumber == null) { - throw new IllegalArgumentException("serialNumber == null"); - } else if (startDate == null) { - throw new IllegalArgumentException("startDate == null"); - } else if (endDate == null) { - throw new IllegalArgumentException("endDate == null"); - } else if (endDate.before(startDate)) { - throw new IllegalArgumentException("endDate < startDate"); } else if ((userAuthenticationValidityDurationSeconds < 0) && (userAuthenticationValidityDurationSeconds != -1)) { throw new IllegalArgumentException( "userAuthenticationValidityDurationSeconds must not be negative"); } + if (subjectDN == null) { + subjectDN = DEFAULT_CERT_SUBJECT; + } + if (startDate == null) { + startDate = DEFAULT_CERT_NOT_BEFORE; + } + if (endDate == null) { + endDate = DEFAULT_CERT_NOT_AFTER; + } + if (serialNumber == null) { + serialNumber = DEFAULT_CERT_SERIAL_NUMBER; + } + + if (endDate.before(startDate)) { + throw new IllegalArgumentException("endDate < startDate"); + } + mContext = context; mKeystoreAlias = keyStoreAlias; mKeyType = keyType; @@ -559,6 +571,10 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec { /** * Sets the subject used for the self-signed certificate of the * generated key pair. + * + * <p>The subject must be specified on API Level + * {@link android.os.Build.VERSION_CODES#LOLLIPOP_MR1 LOLLIPOP_MR1} and older platforms. On + * newer platforms the subject defaults to {@code CN=fake} if not specified. */ public Builder setSubject(X500Principal subject) { if (subject == null) { @@ -571,6 +587,10 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec { /** * Sets the serial number used for the self-signed certificate of the * generated key pair. + * + * <p>The serial number must be specified on API Level + * {@link android.os.Build.VERSION_CODES#LOLLIPOP_MR1 LOLLIPOP_MR1} and older platforms. On + * newer platforms the serial number defaults to {@code 1} if not specified. */ public Builder setSerialNumber(BigInteger serialNumber) { if (serialNumber == null) { @@ -583,6 +603,10 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec { /** * Sets the start of the validity period for the self-signed certificate * of the generated key pair. + * + * <p>The date must be specified on API Level + * {@link android.os.Build.VERSION_CODES#LOLLIPOP_MR1 LOLLIPOP_MR1} and older platforms. On + * newer platforms the date defaults to {@code Jan 1 1970} if not specified. */ public Builder setStartDate(Date startDate) { if (startDate == null) { @@ -595,6 +619,10 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec { /** * Sets the end of the validity period for the self-signed certificate * of the generated key pair. + * + * <p>The date must be specified on API Level + * {@link android.os.Build.VERSION_CODES#LOLLIPOP_MR1 LOLLIPOP_MR1} and older platforms. On + * newer platforms the date defaults to {@code Jan 1 2048} if not specified. */ public Builder setEndDate(Date endDate) { if (endDate == null) { diff --git a/keystore/java/android/security/KeyStoreCipherSpi.java b/keystore/java/android/security/KeyStoreCipherSpi.java index 7bc6378..37e00b2 100644 --- a/keystore/java/android/security/KeyStoreCipherSpi.java +++ b/keystore/java/android/security/KeyStoreCipherSpi.java @@ -547,18 +547,12 @@ public abstract class KeyStoreCipherSpi extends CipherSpi implements KeyStoreCry if (mIvRequired) { // IV is needed if ((mIv == null) && (mEncrypting)) { - // TODO: Switch to keymaster-generated IV code below once keymaster supports - // that. - // IV is needed but was not provided by the caller -- generate an IV. - mIv = new byte[mBlockSizeBytes]; - SecureRandom rng = (mRng != null) ? mRng : new SecureRandom(); - rng.nextBytes(mIv); -// // IV was not provided by the caller and thus will be generated by keymaster. -// // Mix in some additional entropy from the provided SecureRandom. -// if (mRng != null) { -// mAdditionalEntropyForBegin = new byte[mBlockSizeBytes]; -// mRng.nextBytes(mAdditionalEntropyForBegin); -// } + // IV was not provided by the caller and thus will be generated by keymaster. + // Mix in some additional entropy from the provided SecureRandom. + if (mRng != null) { + mAdditionalEntropyForBegin = new byte[mBlockSizeBytes]; + mRng.nextBytes(mAdditionalEntropyForBegin); + } } } } diff --git a/keystore/tests/src/android/security/KeyPairGeneratorSpecTest.java b/keystore/tests/src/android/security/KeyPairGeneratorSpecTest.java index bc8dd13..681a9ff 100644 --- a/keystore/tests/src/android/security/KeyPairGeneratorSpecTest.java +++ b/keystore/tests/src/android/security/KeyPairGeneratorSpecTest.java @@ -24,6 +24,11 @@ import java.util.Date; import javax.security.auth.x500.X500Principal; public class KeyPairGeneratorSpecTest extends AndroidTestCase { + 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 1980 + private static final Date DEFAULT_CERT_NOT_AFTER = new Date(2461449600000L); // Jan 1 2048 + private static final String TEST_ALIAS_1 = "test1"; private static final X500Principal TEST_DN_1 = new X500Principal("CN=test1"); @@ -105,46 +110,37 @@ public class KeyPairGeneratorSpecTest extends AndroidTestCase { } } - public void testConstructor_NullSubjectDN_Failure() throws Exception { - try { - new KeyPairGeneratorSpec(getContext(), TEST_ALIAS_1, "RSA", 1024, null, null, SERIAL_1, NOW, - NOW_PLUS_10_YEARS, 0); - fail("Should throw IllegalArgumentException when subjectDN is null"); - } catch (IllegalArgumentException success) { - } + public void testConstructor_NullSubjectDN_Success() throws Exception { + KeyPairGeneratorSpec spec = new KeyPairGeneratorSpec( + getContext(), TEST_ALIAS_1, "RSA", 1024, null, null, SERIAL_1, NOW, + NOW_PLUS_10_YEARS, 0); + assertEquals(DEFAULT_CERT_SUBJECT, spec.getSubjectDN()); } - public void testConstructor_NullSerial_Failure() throws Exception { - try { - new KeyPairGeneratorSpec(getContext(), TEST_ALIAS_1, "RSA", 1024, null, TEST_DN_1, null, NOW, - NOW_PLUS_10_YEARS, 0); - fail("Should throw IllegalArgumentException when startDate is null"); - } catch (IllegalArgumentException success) { - } + public void testConstructor_NullSerial_Success() throws Exception { + KeyPairGeneratorSpec spec = new KeyPairGeneratorSpec( + getContext(), TEST_ALIAS_1, "RSA", 1024, null, TEST_DN_1, null, NOW, + NOW_PLUS_10_YEARS, 0); + assertEquals(DEFAULT_CERT_SERIAL_NUMBER, spec.getSerialNumber()); } - public void testConstructor_NullStartDate_Failure() throws Exception { - try { - new KeyPairGeneratorSpec(getContext(), TEST_ALIAS_1, "RSA", 1024, null, TEST_DN_1, SERIAL_1, - null, NOW_PLUS_10_YEARS, 0); - fail("Should throw IllegalArgumentException when startDate is null"); - } catch (IllegalArgumentException success) { - } + public void testConstructor_NullStartDate_Success() throws Exception { + KeyPairGeneratorSpec spec = new KeyPairGeneratorSpec( + getContext(), TEST_ALIAS_1, "RSA", 1024, null, TEST_DN_1, SERIAL_1, null, + NOW_PLUS_10_YEARS, 0); + assertEquals(DEFAULT_CERT_NOT_BEFORE, spec.getStartDate()); } - public void testConstructor_NullEndDate_Failure() throws Exception { - try { - new KeyPairGeneratorSpec(getContext(), TEST_ALIAS_1, "RSA", 1024, null, TEST_DN_1, SERIAL_1, - NOW, null, 0); - fail("Should throw IllegalArgumentException when keystoreAlias is null"); - } catch (IllegalArgumentException success) { - } + public void testConstructor_NullEndDate_Success() throws Exception { + KeyPairGeneratorSpec spec = new KeyPairGeneratorSpec( + getContext(), TEST_ALIAS_1, "RSA", 1024, null, TEST_DN_1, SERIAL_1, NOW, null, 0); + assertEquals(DEFAULT_CERT_NOT_AFTER, spec.getEndDate()); } public void testConstructor_EndBeforeStart_Failure() throws Exception { try { - new KeyPairGeneratorSpec(getContext(), TEST_ALIAS_1, "RSA", 1024, null, TEST_DN_1, SERIAL_1, - NOW_PLUS_10_YEARS, NOW, 0); + new KeyPairGeneratorSpec(getContext(), TEST_ALIAS_1, "RSA", 1024, null, TEST_DN_1, + SERIAL_1, NOW_PLUS_10_YEARS, NOW, 0); fail("Should throw IllegalArgumentException when end is before start"); } catch (IllegalArgumentException success) { } diff --git a/libs/androidfw/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp index 7241069..fbe08ec 100644 --- a/libs/androidfw/ResourceTypes.cpp +++ b/libs/androidfw/ResourceTypes.cpp @@ -17,6 +17,16 @@ #define LOG_TAG "ResourceType" //#define LOG_NDEBUG 0 +#include <ctype.h> +#include <memory.h> +#include <stddef.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> + +#include <limits> +#include <type_traits> + #include <androidfw/ByteBucketArray.h> #include <androidfw/ResourceTypes.h> #include <androidfw/TypeWrappers.h> @@ -27,17 +37,10 @@ #include <utils/String16.h> #include <utils/String8.h> -#ifdef HAVE_ANDROID_OS +#ifdef __ANDROID__ #include <binder/TextOutput.h> #endif -#include <stdlib.h> -#include <string.h> -#include <memory.h> -#include <ctype.h> -#include <stdint.h> -#include <stddef.h> - #ifndef INT32_MAX #define INT32_MAX ((int32_t)(2147483647)) #endif @@ -4551,8 +4554,7 @@ static bool parse_unit(const char* str, Res_value* outValue, return false; } - -bool ResTable::stringToInt(const char16_t* s, size_t len, Res_value* outValue) +bool U16StringToInt(const char16_t* s, size_t len, Res_value* outValue) { while (len > 0 && isspace16(*s)) { s++; @@ -4564,7 +4566,7 @@ bool ResTable::stringToInt(const char16_t* s, size_t len, Res_value* outValue) } size_t i = 0; - int32_t val = 0; + int64_t val = 0; bool neg = false; if (*s == '-') { @@ -4576,28 +4578,50 @@ bool ResTable::stringToInt(const char16_t* s, size_t len, Res_value* outValue) return false; } + static_assert(std::is_same<uint32_t, Res_value::data_type>::value, + "Res_value::data_type has changed. The range checks in this " + "function are no longer correct."); + // Decimal or hex? - if (s[i] == '0' && s[i+1] == 'x') { - if (outValue) - outValue->dataType = outValue->TYPE_INT_HEX; + bool isHex; + if (len > 1 && s[i] == '0' && s[i+1] == 'x') { + isHex = true; i += 2; + + if (neg) { + return false; + } + + if (i == len) { + // Just u"0x" + return false; + } + bool error = false; while (i < len && !error) { val = (val*16) + get_hex(s[i], &error); i++; + + if (val > std::numeric_limits<uint32_t>::max()) { + return false; + } } if (error) { return false; } } else { - if (outValue) - outValue->dataType = outValue->TYPE_INT_DEC; + isHex = false; while (i < len) { if (s[i] < '0' || s[i] > '9') { return false; } val = (val*10) + s[i]-'0'; i++; + + if ((neg && -val < std::numeric_limits<int32_t>::min()) || + (!neg && val > std::numeric_limits<int32_t>::max())) { + return false; + } } } @@ -4607,13 +4631,21 @@ bool ResTable::stringToInt(const char16_t* s, size_t len, Res_value* outValue) i++; } - if (i == len) { - if (outValue) - outValue->data = val; - return true; + if (i != len) { + return false; } - return false; + if (outValue) { + outValue->dataType = + isHex ? outValue->TYPE_INT_HEX : outValue->TYPE_INT_DEC; + outValue->data = static_cast<Res_value::data_type>(val); + } + return true; +} + +bool ResTable::stringToInt(const char16_t* s, size_t len, Res_value* outValue) +{ + return U16StringToInt(s, len, outValue); } bool ResTable::stringToFloat(const char16_t* s, size_t len, Res_value* outValue) diff --git a/libs/androidfw/tests/Android.mk b/libs/androidfw/tests/Android.mk index 58b78b5..a353575 100644 --- a/libs/androidfw/tests/Android.mk +++ b/libs/androidfw/tests/Android.mk @@ -19,6 +19,7 @@ # targets here. # ========================================================== LOCAL_PATH:= $(call my-dir) + testFiles := \ AttributeFinder_test.cpp \ ByteBucketArray_test.cpp \ @@ -32,27 +33,33 @@ testFiles := \ TypeWrappers_test.cpp \ ZipUtils_test.cpp +androidfw_test_cflags := \ + -Wall \ + -Werror \ + -Wunused \ + -Wunreachable-code \ + -Wno-missing-field-initializers \ + +# gtest is broken. +androidfw_test_cflags += -Wno-unnamed-type-template-args + # ========================================================== # Build the host tests: libandroidfw_tests # ========================================================== include $(CLEAR_VARS) LOCAL_MODULE := libandroidfw_tests - -LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code -# gtest is broken. -LOCAL_CFLAGS += -Wno-unnamed-type-template-args - +LOCAL_CFLAGS := $(androidfw_test_cflags) LOCAL_SRC_FILES := $(testFiles) LOCAL_STATIC_LIBRARIES := \ libandroidfw \ libutils \ libcutils \ - liblog + liblog \ + libz \ include $(BUILD_HOST_NATIVE_TEST) - # ========================================================== # Build the device tests: libandroidfw_tests # ========================================================== @@ -60,14 +67,11 @@ ifneq ($(SDK_ONLY),true) include $(CLEAR_VARS) LOCAL_MODULE := libandroidfw_tests - -LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code -# gtest is broken. -LOCAL_CFLAGS += -Wno-unnamed-type-template-args - +LOCAL_CFLAGS := $(androidfw_test_cflags) LOCAL_SRC_FILES := $(testFiles) \ BackupData_test.cpp \ - ObbFile_test.cpp + ObbFile_test.cpp \ + LOCAL_SHARED_LIBRARIES := \ libandroidfw \ libcutils \ diff --git a/libs/androidfw/tests/ResTable_test.cpp b/libs/androidfw/tests/ResTable_test.cpp index 6a9314e..dcfe91e 100644 --- a/libs/androidfw/tests/ResTable_test.cpp +++ b/libs/androidfw/tests/ResTable_test.cpp @@ -16,6 +16,10 @@ #include <androidfw/ResourceTypes.h> +#include <codecvt> +#include <locale> +#include <string> + #include <utils/String8.h> #include <utils/String16.h> #include "TestHelpers.h" @@ -201,4 +205,81 @@ TEST(ResTableTest, emptyTableHasSensibleDefaults) { ASSERT_LT(table.getResource(base::R::integer::number1, &val, MAY_NOT_BE_BAG), 0); } +void testU16StringToInt(const char16_t* str, uint32_t expectedValue, + bool expectSuccess, bool expectHex) { + size_t len = std::char_traits<char16_t>::length(str); + + // Gtest can't print UTF-16 strings, so we have to convert to UTF-8 :( + std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> convert; + std::string s = convert.to_bytes(std::u16string(str, len)); + + Res_value out = {}; + ASSERT_EQ(expectSuccess, U16StringToInt(str, len, &out)) + << "Failed with " << s; + + if (!expectSuccess) { + ASSERT_EQ(out.TYPE_NULL, out.dataType) << "Failed with " << s; + return; + } + + if (expectHex) { + ASSERT_EQ(out.TYPE_INT_HEX, out.dataType) << "Failed with " << s; + } else { + ASSERT_EQ(out.TYPE_INT_DEC, out.dataType) << "Failed with " << s; + } + + ASSERT_EQ(expectedValue, out.data) << "Failed with " << s; +} + +TEST(ResTableTest, U16StringToInt) { + testU16StringToInt(u"", 0U, false, false); + testU16StringToInt(u" ", 0U, false, false); + testU16StringToInt(u"\t\n", 0U, false, false); + + testU16StringToInt(u"abcd", 0U, false, false); + testU16StringToInt(u"10abcd", 0U, false, false); + testU16StringToInt(u"42 42", 0U, false, false); + testU16StringToInt(u"- 42", 0U, false, false); + testU16StringToInt(u"-", 0U, false, false); + + testU16StringToInt(u"0x", 0U, false, true); + testU16StringToInt(u"0xnope", 0U, false, true); + testU16StringToInt(u"0X42", 0U, false, true); + testU16StringToInt(u"0x42 0x42", 0U, false, true); + testU16StringToInt(u"-0x0", 0U, false, true); + testU16StringToInt(u"-0x42", 0U, false, true); + testU16StringToInt(u"- 0x42", 0U, false, true); + + // Note that u" 42" would pass. This preserves the old behavior, but it may + // not be desired. + testU16StringToInt(u"42 ", 0U, false, false); + testU16StringToInt(u"0x42 ", 0U, false, true); + + // Decimal cases. + testU16StringToInt(u"0", 0U, true, false); + testU16StringToInt(u"-0", 0U, true, false); + testU16StringToInt(u"42", 42U, true, false); + testU16StringToInt(u" 42", 42U, true, false); + testU16StringToInt(u"-42", static_cast<uint32_t>(-42), true, false); + testU16StringToInt(u" -42", static_cast<uint32_t>(-42), true, false); + testU16StringToInt(u"042", 42U, true, false); + testU16StringToInt(u"-042", static_cast<uint32_t>(-42), true, false); + + // Hex cases. + testU16StringToInt(u"0x0", 0x0, true, true); + testU16StringToInt(u"0x42", 0x42, true, true); + testU16StringToInt(u" 0x42", 0x42, true, true); + + // Just before overflow cases: + testU16StringToInt(u"2147483647", INT_MAX, true, false); + testU16StringToInt(u"-2147483648", static_cast<uint32_t>(INT_MIN), true, + false); + testU16StringToInt(u"0xffffffff", UINT_MAX, true, true); + + // Overflow cases: + testU16StringToInt(u"2147483648", 0U, false, false); + testU16StringToInt(u"-2147483649", 0U, false, false); + testU16StringToInt(u"0x1ffffffff", 0U, false, true); +} + } diff --git a/rs/java/android/renderscript/Allocation.java b/rs/java/android/renderscript/Allocation.java index 28547cc..4fa2c81 100644 --- a/rs/java/android/renderscript/Allocation.java +++ b/rs/java/android/renderscript/Allocation.java @@ -276,7 +276,7 @@ public class Allocation extends BaseObj { * @hide * Enable/Disable AutoPadding for Vec3 elements. * - * @param useAutoPadding True: enable AutoPadding; flase: disable AutoPadding + * @param useAutoPadding True: enable AutoPadding; False: disable AutoPadding * */ public void setAutoPadding(boolean useAutoPadding) { diff --git a/rs/java/android/renderscript/RenderScript.java b/rs/java/android/renderscript/RenderScript.java index 9f3348c..6b1939c 100644 --- a/rs/java/android/renderscript/RenderScript.java +++ b/rs/java/android/renderscript/RenderScript.java @@ -951,6 +951,17 @@ public class RenderScript { rsnScriptIntrinsicBLAS_Z(mContext, id, func, TransA, TransB, Side, Uplo, Diag, M, N, K, alphaX, alphaY, A, B, betaX, betaY, C, incX, incY, KL, KU); } + native void rsnScriptIntrinsicBLAS_BNNM(long con, long id, int M, int N, int K, + long A, int a_offset, long B, int b_offset, long C, int c_offset, + int c_mult_int); + synchronized void nScriptIntrinsicBLAS_BNNM(long id, int M, int N, int K, + long A, int a_offset, long B, int b_offset, long C, int c_offset, + int c_mult_int) { + validate(); + rsnScriptIntrinsicBLAS_BNNM(mContext, id, M, N, K, A, a_offset, B, b_offset, C, c_offset, c_mult_int); + } + + long mDev; long mContext; diff --git a/rs/java/android/renderscript/ScriptIntrinsicBLAS.java b/rs/java/android/renderscript/ScriptIntrinsicBLAS.java index 90d2300..16b7033 100644 --- a/rs/java/android/renderscript/ScriptIntrinsicBLAS.java +++ b/rs/java/android/renderscript/ScriptIntrinsicBLAS.java @@ -176,6 +176,9 @@ public final class ScriptIntrinsicBLAS extends ScriptIntrinsic { private static final int RsBlas_zherk = 141; private static final int RsBlas_zher2k = 142; + // BLAS extensions start here + private static final int RsBlas_bnnm = 1000; + /** */ public static ScriptIntrinsicBLAS create(RenderScript rs) { @@ -1485,5 +1488,23 @@ public final class ScriptIntrinsicBLAS extends ScriptIntrinsic { } + /** + * + * 8-bit GEMM-like operation for neural networks + * + * @hide + **/ + public void BNNM(Allocation A, int a_offset, Allocation B, int b_offset, Allocation C, int c_offset, int c_mult) { + validateL3(Element.U8(mRS), NO_TRANSPOSE, TRANSPOSE, 0, A, B, C); + + int M = -1, N = -1, K = -1; + M = A.getType().getY(); + N = B.getType().getY(); + K = A.getType().getX(); + + + mRS.nScriptIntrinsicBLAS_BNNM(getID(mRS), M, N, K, A.getID(mRS), a_offset, B.getID(mRS), b_offset, C.getID(mRS), c_offset, c_mult); + + } } diff --git a/rs/jni/android_renderscript_RenderScript.cpp b/rs/jni/android_renderscript_RenderScript.cpp index ba194ee..6f6729b 100644 --- a/rs/jni/android_renderscript_RenderScript.cpp +++ b/rs/jni/android_renderscript_RenderScript.cpp @@ -584,6 +584,32 @@ nScriptIntrinsicBLAS_Z(JNIEnv *_env, jobject _this, jlong con, jlong id, jint fu static void +nScriptIntrinsicBLAS_BNNM(JNIEnv *_env, jobject _this, jlong con, jlong id, jint M, jint N, jint K, + jlong A, jint a_offset, jlong B, jint b_offset, jlong C, jint c_offset, + jint c_mult_int) { + RsBlasCall call; + memset(&call, 0, sizeof(call)); + call.func = RsBlas_bnnm; + call.M = M; + call.N = N; + call.K = K; + call.a_offset = a_offset; + call.b_offset = b_offset; + call.c_offset = c_offset; + call.c_mult_int = c_mult_int; + + RsAllocation in_allocs[3]; + in_allocs[0] = (RsAllocation)A; + in_allocs[1] = (RsAllocation)B; + in_allocs[2] = (RsAllocation)C; + + rsScriptForEachMulti((RsContext)con, (RsScript)id, 0, + in_allocs, sizeof(in_allocs), nullptr, + &call, sizeof(call), nullptr, 0); +} + + +static void nAssignName(JNIEnv *_env, jobject _this, jlong con, jlong obj, jbyteArray str) { if (kLogApi) { @@ -2427,6 +2453,8 @@ static JNINativeMethod methods[] = { {"rsnScriptIntrinsicBLAS_Complex", "(JJIIIIIIIIIFFJJFFJIIII)V", (void*)nScriptIntrinsicBLAS_Complex }, {"rsnScriptIntrinsicBLAS_Z", "(JJIIIIIIIIIDDJJDDJIIII)V", (void*)nScriptIntrinsicBLAS_Z }, +{"rsnScriptIntrinsicBLAS_BNNM", "(JJIIIJIJIJII)V", (void*)nScriptIntrinsicBLAS_BNNM }, + {"rsnProgramStoreCreate", "(JZZZZZZIII)J", (void*)nProgramStoreCreate }, {"rsnProgramBindConstants", "(JJIJ)V", (void*)nProgramBindConstants }, diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java index 27ac32a..ad50e05a 100644 --- a/services/core/java/com/android/server/wm/InputMonitor.java +++ b/services/core/java/com/android/server/wm/InputMonitor.java @@ -148,7 +148,7 @@ final class InputMonitor implements InputManagerService.WindowManagerCallbacks { if (timeout >= 0) { // The activity manager declined to abort dispatching. // Wait a bit longer and timeout again later. - return timeout; + return timeout * 1000000L; // nanoseconds } } catch (RemoteException ex) { } |