diff options
27 files changed, 495 insertions, 283 deletions
diff --git a/apct-tests/perftests/core/src/android/libcore/ZipFilePerfTest.java b/apct-tests/perftests/core/src/android/libcore/ZipFilePerfTest.java index 517e3ce39d7e..31c92ba5e207 100644 --- a/apct-tests/perftests/core/src/android/libcore/ZipFilePerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/ZipFilePerfTest.java @@ -70,6 +70,9 @@ public class ZipFilePerfTest { BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); while (state.keepRunning()) { ZipFile zf = new ZipFile(mFile); + state.pauseTiming(); + zf.close(); + state.resumeTiming(); } } diff --git a/apct-tests/perftests/core/src/android/libcore/regression/ExpensiveObjectsPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/ExpensiveObjectsPerfTest.java index 32117dcd1d9f..03c9d43d3258 100644 --- a/apct-tests/perftests/core/src/android/libcore/regression/ExpensiveObjectsPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/regression/ExpensiveObjectsPerfTest.java @@ -141,15 +141,6 @@ public class ExpensiveObjectsPerfTest { } @Test - public void timeNumberFormatTrivialFormatLong() { - NumberFormat nf = NumberFormat.getInstance(Locale.US); - BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); - while (state.keepRunning()) { - nf.format(1024L); - } - } - - @Test public void timeLongToString() { BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); while (state.keepRunning()) { diff --git a/apct-tests/perftests/core/src/android/libcore/regression/HostnameVerifierPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/HostnameVerifierPerfTest.java deleted file mode 100644 index f2b7fdfdc1ca..000000000000 --- a/apct-tests/perftests/core/src/android/libcore/regression/HostnameVerifierPerfTest.java +++ /dev/null @@ -1,192 +0,0 @@ -/* - * Copyright (C) 2022 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.libcore.regression; - -import android.perftests.utils.BenchmarkState; -import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; - -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; -import org.junit.runners.Parameterized.Parameters; - -import java.io.ByteArrayInputStream; -import java.net.URL; -import java.security.Principal; -import java.security.cert.Certificate; -import java.security.cert.CertificateFactory; -import java.util.Arrays; -import java.util.Collection; - -import javax.net.ssl.HostnameVerifier; -import javax.net.ssl.HttpsURLConnection; -import javax.net.ssl.SSLSession; -import javax.net.ssl.SSLSessionContext; - -/** - * This benchmark makes a real HTTP connection to a handful of hosts and - * captures the served certificates as a byte array. It then verifies each - * certificate in the benchmark loop, being careful to convert from the - * byte[] to the certificate each time. Otherwise the certificate class - * caches previous results which skews the results of the benchmark: In practice - * each certificate instance is verified once and then released. - */ -@RunWith(Parameterized.class) -@LargeTest -public final class HostnameVerifierPerfTest { - @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter(); - - @Parameters(name = "mHost({0})") - public static Collection<Object[]> data() { - return Arrays.asList( - new Object[][] { - {"m.google.com"}, - {"www.google.com"}, - {"www.amazon.com"}, - {"www.ubs.com"} - }); - } - - @Parameterized.Parameter(0) - public String mHost; - - - private String mHostname; - private HostnameVerifier mHostnameVerifier; - private byte[][] mEncodedCertificates; - - @Before - public void setUp() throws Exception { - URL url = new URL("https", mHost, "/"); - mHostnameVerifier = HttpsURLConnection.getDefaultHostnameVerifier(); - HttpsURLConnection connection = (HttpsURLConnection) url.openConnection(); - connection.setHostnameVerifier(new HostnameVerifier() { - public boolean verify(String mHostname, SSLSession sslSession) { - try { - mEncodedCertificates = certificatesToBytes(sslSession.getPeerCertificates()); - } catch (Exception e) { - throw new RuntimeException(e); - } - HostnameVerifierPerfTest.this.mHostname = mHostname; - return true; - } - }); - connection.getInputStream(); - connection.disconnect(); - } - - @Test - public void timeVerify() throws Exception { - BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); - while (state.keepRunning()) { - final Certificate[] certificates = bytesToCertificates(mEncodedCertificates); - FakeSSLSession sslSession = new FakeSSLSession() { - @Override public Certificate[] getPeerCertificates() { - return certificates; - } - }; - mHostnameVerifier.verify(mHostname, sslSession); - } - } - - private byte[][] certificatesToBytes(Certificate[] certificates) throws Exception { - byte[][] result = new byte[certificates.length][]; - for (int i = 0, certificatesLength = certificates.length; i < certificatesLength; i++) { - result[i] = certificates[i].getEncoded(); - } - return result; - } - - private Certificate[] bytesToCertificates(byte[][] encodedCertificates) throws Exception { - CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509"); - Certificate[] result = new Certificate[encodedCertificates.length]; - for (int i = 0; i < encodedCertificates.length; i++) { - result[i] = certificateFactory.generateCertificate( - new ByteArrayInputStream(encodedCertificates[i])); - } - return result; - } - - private static class FakeSSLSession implements SSLSession { - public int getApplicationBufferSize() { - throw new UnsupportedOperationException(); - } - public String getCipherSuite() { - throw new UnsupportedOperationException(); - } - public long getCreationTime() { - throw new UnsupportedOperationException(); - } - public byte[] getId() { - throw new UnsupportedOperationException(); - } - public long getLastAccessedTime() { - throw new UnsupportedOperationException(); - } - public Certificate[] getLocalCertificates() { - throw new UnsupportedOperationException(); - } - public Principal getLocalPrincipal() { - throw new UnsupportedOperationException(); - } - public int getPacketBufferSize() { - throw new UnsupportedOperationException(); - } - public javax.security.cert.X509Certificate[] getPeerCertificateChain() { - throw new UnsupportedOperationException(); - } - public Certificate[] getPeerCertificates() { - throw new UnsupportedOperationException(); - } - public String getPeerHost() { - throw new UnsupportedOperationException(); - } - public int getPeerPort() { - throw new UnsupportedOperationException(); - } - public Principal getPeerPrincipal() { - throw new UnsupportedOperationException(); - } - public String getProtocol() { - throw new UnsupportedOperationException(); - } - public SSLSessionContext getSessionContext() { - throw new UnsupportedOperationException(); - } - public Object getValue(String name) { - throw new UnsupportedOperationException(); - } - public String[] getValueNames() { - throw new UnsupportedOperationException(); - } - public void invalidate() { - throw new UnsupportedOperationException(); - } - public boolean isValid() { - throw new UnsupportedOperationException(); - } - public void putValue(String name, Object value) { - throw new UnsupportedOperationException(); - } - public void removeValue(String name) { - throw new UnsupportedOperationException(); - } - } -} diff --git a/apct-tests/perftests/core/src/android/libcore/regression/NumberFormatTrivialFormatLongPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/NumberFormatTrivialFormatLongPerfTest.java new file mode 100644 index 000000000000..5ff2b225d64f --- /dev/null +++ b/apct-tests/perftests/core/src/android/libcore/regression/NumberFormatTrivialFormatLongPerfTest.java @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2022 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.libcore.regression; + +import android.perftests.utils.BenchmarkState; +import android.perftests.utils.PerfStatusReporter; +import android.test.suitebuilder.annotation.LargeTest; + +import androidx.test.runner.AndroidJUnit4; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.text.NumberFormat; +import java.util.Locale; + +/** + * Benchmarks creation and cloning various expensive objects. + */ +@RunWith(AndroidJUnit4.class) +@LargeTest +public class NumberFormatTrivialFormatLongPerfTest { + @Rule + public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter(); + + @Test + public void timeNumberFormatTrivialFormatLong() { + NumberFormat nf = NumberFormat.getInstance(Locale.US); + BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); + while (state.keepRunning()) { + nf.format(1024L); + } + } +} diff --git a/core/api/current.txt b/core/api/current.txt index 77e964f60918..18286ebd7a66 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -21444,6 +21444,7 @@ package android.media { field public static final String KEY_VIDEO_QP_P_MAX = "video-qp-p-max"; field public static final String KEY_VIDEO_QP_P_MIN = "video-qp-p-min"; field public static final String KEY_WIDTH = "width"; + field public static final String LOG_SESSION_ID = "log-session-id"; field public static final String MIMETYPE_AUDIO_AAC = "audio/mp4a-latm"; field public static final String MIMETYPE_AUDIO_AC3 = "audio/ac3"; field public static final String MIMETYPE_AUDIO_AC4 = "audio/ac4"; @@ -41221,8 +41222,11 @@ package android.telephony { field public static final String MMS_CONFIG_UA_PROF_URL = "uaProfUrl"; field public static final String MMS_CONFIG_USER_AGENT = "userAgent"; field public static final int MMS_ERROR_CONFIGURATION_ERROR = 7; // 0x7 + field public static final int MMS_ERROR_DATA_DISABLED = 11; // 0xb field public static final int MMS_ERROR_HTTP_FAILURE = 4; // 0x4 + field public static final int MMS_ERROR_INACTIVE_SUBSCRIPTION = 10; // 0xa field public static final int MMS_ERROR_INVALID_APN = 2; // 0x2 + field public static final int MMS_ERROR_INVALID_SUBSCRIPTION_ID = 9; // 0x9 field public static final int MMS_ERROR_IO_ERROR = 5; // 0x5 field public static final int MMS_ERROR_NO_DATA_NETWORK = 8; // 0x8 field public static final int MMS_ERROR_RETRY = 6; // 0x6 diff --git a/core/res/res/values/config_telephony.xml b/core/res/res/values/config_telephony.xml index 107bdd7fa1ea..d24a95db3cd9 100644 --- a/core/res/res/values/config_telephony.xml +++ b/core/res/res/values/config_telephony.xml @@ -35,7 +35,7 @@ rmem_min,rmem_def,rmem_max,wmem_min,wmem_def,wmem_max If this is configured as an empty string, the system default will be applied. --> - <string name="config_tcp_buffers" translatable="false"></string> + <string name="config_tcp_buffers" translatable="false">2097152,6291456,16777216,512000,2097152,8388608</string> <java-symbol type="string" name="config_tcp_buffers" /> <!-- What source to use to estimate link upstream and downstream bandwidth capacities. diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreBCWorkaroundProvider.java b/keystore/java/android/security/keystore2/AndroidKeyStoreBCWorkaroundProvider.java index 9ad6f3adbd33..6fff52a20062 100644 --- a/keystore/java/android/security/keystore2/AndroidKeyStoreBCWorkaroundProvider.java +++ b/keystore/java/android/security/keystore2/AndroidKeyStoreBCWorkaroundProvider.java @@ -206,6 +206,8 @@ class AndroidKeyStoreBCWorkaroundProvider extends Provider { putSignatureImpl("NONEwithECDSA", PACKAGE_NAME + ".AndroidKeyStoreECDSASignatureSpi$NONE"); + putSignatureImpl("Ed25519", + PACKAGE_NAME + ".AndroidKeyStoreECDSASignatureSpi$Ed25519"); putSignatureImpl("SHA1withECDSA", PACKAGE_NAME + ".AndroidKeyStoreECDSASignatureSpi$SHA1"); put("Alg.Alias.Signature.ECDSA", "SHA1withECDSA"); diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreECDSASignatureSpi.java b/keystore/java/android/security/keystore2/AndroidKeyStoreECDSASignatureSpi.java index 8289671de212..5216a908826b 100644 --- a/keystore/java/android/security/keystore2/AndroidKeyStoreECDSASignatureSpi.java +++ b/keystore/java/android/security/keystore2/AndroidKeyStoreECDSASignatureSpi.java @@ -29,7 +29,10 @@ import libcore.util.EmptyArray; import java.io.ByteArrayOutputStream; import java.security.InvalidKeyException; import java.security.SignatureSpi; +import java.security.spec.NamedParameterSpec; +import java.util.Arrays; import java.util.List; +import java.util.Set; /** * Base class for {@link SignatureSpi} providing Android KeyStore backed ECDSA signatures. @@ -37,6 +40,10 @@ import java.util.List; * @hide */ abstract class AndroidKeyStoreECDSASignatureSpi extends AndroidKeyStoreSignatureSpiBase { + private static final Set<String> ACCEPTED_SIGNING_SCHEMES = Set.of( + KeyProperties.KEY_ALGORITHM_EC.toLowerCase(), + NamedParameterSpec.ED25519.getName().toLowerCase(), + "eddsa"); public final static class NONE extends AndroidKeyStoreECDSASignatureSpi { public NONE() { @@ -114,6 +121,18 @@ abstract class AndroidKeyStoreECDSASignatureSpi extends AndroidKeyStoreSignature } } + public static final class Ed25519 extends AndroidKeyStoreECDSASignatureSpi { + public Ed25519() { + // Ed25519 uses an internal digest system. + super(KeymasterDefs.KM_DIGEST_NONE); + } + + @Override + protected String getAlgorithm() { + return NamedParameterSpec.ED25519.getName(); + } + } + public final static class SHA1 extends AndroidKeyStoreECDSASignatureSpi { public SHA1() { super(KeymasterDefs.KM_DIGEST_SHA1); @@ -174,9 +193,10 @@ abstract class AndroidKeyStoreECDSASignatureSpi extends AndroidKeyStoreSignature @Override protected final void initKey(AndroidKeyStoreKey key) throws InvalidKeyException { - if (!KeyProperties.KEY_ALGORITHM_EC.equalsIgnoreCase(key.getAlgorithm())) { + if (!ACCEPTED_SIGNING_SCHEMES.contains(key.getAlgorithm().toLowerCase())) { throw new InvalidKeyException("Unsupported key algorithm: " + key.getAlgorithm() - + ". Only" + KeyProperties.KEY_ALGORITHM_EC + " supported"); + + ". Only" + Arrays.toString(ACCEPTED_SIGNING_SCHEMES.stream().toArray()) + + " supported"); } long keySizeBits = -1; diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreKeyAgreementSpi.java b/keystore/java/android/security/keystore2/AndroidKeyStoreKeyAgreementSpi.java index fc963a88c4d1..b1338d164055 100644 --- a/keystore/java/android/security/keystore2/AndroidKeyStoreKeyAgreementSpi.java +++ b/keystore/java/android/security/keystore2/AndroidKeyStoreKeyAgreementSpi.java @@ -61,6 +61,17 @@ public class AndroidKeyStoreKeyAgreementSpi extends KeyAgreementSpi } } + /** + * X25519 key agreement support. + * + * @hide + */ + public static class XDH extends AndroidKeyStoreKeyAgreementSpi { + public XDH() { + super(Algorithm.EC); + } + } + private final int mKeymintAlgorithm; // Fields below are populated by engineInit and should be preserved after engineDoFinal. diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java b/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java index 0355628b8135..9947d34495ab 100644 --- a/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java +++ b/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java @@ -104,6 +104,7 @@ public class AndroidKeyStoreProvider extends Provider { // javax.crypto.KeyAgreement put("KeyAgreement.ECDH", PACKAGE_NAME + ".AndroidKeyStoreKeyAgreementSpi$ECDH"); + put("KeyAgreement.XDH", PACKAGE_NAME + ".AndroidKeyStoreKeyAgreementSpi$XDH"); // java.security.SecretKeyFactory putSecretKeyFactoryImpl("AES"); @@ -235,8 +236,8 @@ public class AndroidKeyStoreProvider extends Provider { return new AndroidKeyStoreEdECPublicKey(descriptor, metadata, ED25519_OID, iSecurityLevel, publicKeyEncoded); } else if (X25519_ALIAS.equalsIgnoreCase(jcaKeyAlgorithm)) { - //TODO(b/214203951) missing classes in conscrypt - throw new ProviderException("Curve " + X25519_ALIAS + " not supported yet"); + return new AndroidKeyStoreXDHPublicKey(descriptor, metadata, X25519_ALIAS, + iSecurityLevel, publicKey.getEncoded()); } else { throw new ProviderException("Unsupported Android Keystore public key algorithm: " + jcaKeyAlgorithm); diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreXDHPrivateKey.java b/keystore/java/android/security/keystore2/AndroidKeyStoreXDHPrivateKey.java new file mode 100644 index 000000000000..42589640d2b7 --- /dev/null +++ b/keystore/java/android/security/keystore2/AndroidKeyStoreXDHPrivateKey.java @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2022 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.security.keystore2; + +import android.annotation.NonNull; +import android.security.KeyStoreSecurityLevel; +import android.system.keystore2.Authorization; +import android.system.keystore2.KeyDescriptor; + +import java.security.PrivateKey; +import java.security.interfaces.EdECKey; +import java.security.spec.NamedParameterSpec; + +/** + * X25519 Private Key backed by Keystore. + * instance of {@link PrivateKey} and {@link EdECKey} + * + * @hide + */ +public class AndroidKeyStoreXDHPrivateKey extends AndroidKeyStorePrivateKey implements EdECKey { + public AndroidKeyStoreXDHPrivateKey( + @NonNull KeyDescriptor descriptor, long keyId, + @NonNull Authorization[] authorizations, + @NonNull String algorithm, + @NonNull KeyStoreSecurityLevel securityLevel) { + super(descriptor, keyId, authorizations, algorithm, securityLevel); + } + + @Override + public NamedParameterSpec getParams() { + return NamedParameterSpec.X25519; + } +} diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreXDHPublicKey.java b/keystore/java/android/security/keystore2/AndroidKeyStoreXDHPublicKey.java new file mode 100644 index 000000000000..9f3df3d72d86 --- /dev/null +++ b/keystore/java/android/security/keystore2/AndroidKeyStoreXDHPublicKey.java @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2022 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.security.keystore2; + +import android.annotation.NonNull; +import android.security.KeyStoreSecurityLevel; +import android.system.keystore2.KeyDescriptor; +import android.system.keystore2.KeyMetadata; + +import java.math.BigInteger; +import java.security.interfaces.XECPublicKey; +import java.security.spec.AlgorithmParameterSpec; +import java.security.spec.NamedParameterSpec; +import java.util.Arrays; + +/** + * {@link XECPublicKey} backed by keystore. + * This class re-implements Conscrypt's OpenSSLX25519PublicKey. The reason is that + * OpenSSLX25519PublicKey does not implement XECPublicKey and is not a part of Conscrypt's public + * interface so it cannot be referred to. + * + * So the functionality is duplicated here until (likely Android U) one of the things mentioned + * above is fixed. + * + * @hide + */ +public class AndroidKeyStoreXDHPublicKey extends AndroidKeyStorePublicKey implements XECPublicKey { + private static final byte[] X509_PREAMBLE = new byte[] { + 0x30, 0x2a, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65, 0x6e, 0x03, 0x21, 0x00, + }; + + private static final byte[] X509_PREAMBLE_WITH_NULL = new byte[] { + 0x30, 0x2C, 0x30, 0x07, 0x06, 0x03, 0x2B, 0x65, 0x6E, 0x05, 0x00, 0x03, 0x21, 0x00, + }; + + private static final int X25519_KEY_SIZE_BYTES = 32; + + private final byte[] mEncodedKey; + private final int mPreambleLength; + + public AndroidKeyStoreXDHPublicKey( + @NonNull KeyDescriptor descriptor, + @NonNull KeyMetadata metadata, + @NonNull String algorithm, + @NonNull KeyStoreSecurityLevel iSecurityLevel, + @NonNull byte[] encodedKey) { + super(descriptor, metadata, encodedKey, algorithm, iSecurityLevel); + mEncodedKey = encodedKey; + if (mEncodedKey == null) { + throw new IllegalArgumentException("empty encoded key."); + } + + mPreambleLength = matchesPreamble(X509_PREAMBLE, mEncodedKey) | matchesPreamble( + X509_PREAMBLE_WITH_NULL, mEncodedKey); + if (mPreambleLength == 0) { + throw new IllegalArgumentException("Key size is not correct size"); + } + } + + private static int matchesPreamble(byte[] preamble, byte[] encoded) { + if (encoded.length != (preamble.length + X25519_KEY_SIZE_BYTES)) { + return 0; + } + + if (Arrays.compare(preamble, 0, preamble.length, encoded, 0, preamble.length) != 0) { + return 0; + } + return preamble.length; + } + + @Override + AndroidKeyStorePrivateKey getPrivateKey() { + return new AndroidKeyStoreXDHPrivateKey( + getUserKeyDescriptor(), + getKeyIdDescriptor().nspace, + getAuthorizations(), + "x25519", + getSecurityLevel()); + } + + @Override + public BigInteger getU() { + return new BigInteger(Arrays.copyOfRange(mEncodedKey, mPreambleLength, mEncodedKey.length)); + } + + @Override + public byte[] getEncoded() { + return mEncodedKey.clone(); + } + + @Override + public String getAlgorithm() { + return "XDH"; + } + + @Override + public String getFormat() { + return "x.509"; + } + + @Override + public AlgorithmParameterSpec getParams() { + return NamedParameterSpec.X25519; + } +} + diff --git a/media/java/android/media/MediaFormat.java b/media/java/android/media/MediaFormat.java index 050ae7268ef2..66e2c413312e 100644 --- a/media/java/android/media/MediaFormat.java +++ b/media/java/android/media/MediaFormat.java @@ -230,9 +230,10 @@ public final class MediaFormat { /** * A key describing the log session ID for MediaCodec. The log session ID is a random 32-byte * hexadecimal string that is used to associate metrics from multiple media codec instances - * to the same playback or recording session. + * to the same playback or recording session. The value is created as + * {@link android.media.metrics.LogSessionId LogSessionId}. Sessions are created in + * {@link android.media.metrics.MediaMetricsManager MediaMetricsManager}. * The associated value is a string. - * @hide */ public static final String LOG_SESSION_ID = "log-session-id"; diff --git a/packages/SettingsLib/ActionBarShadow/Android.bp b/packages/SettingsLib/ActionBarShadow/Android.bp index 4a07d49fcde5..2c86201591fb 100644 --- a/packages/SettingsLib/ActionBarShadow/Android.bp +++ b/packages/SettingsLib/ActionBarShadow/Android.bp @@ -20,4 +20,8 @@ android_library { sdk_version: "system_current", min_sdk_version: "28", + apex_available: [ + "//apex_available:platform", + "com.android.permission", + ], } diff --git a/packages/SettingsLib/AppPreference/Android.bp b/packages/SettingsLib/AppPreference/Android.bp index 1817a77981a9..122f60672b2a 100644 --- a/packages/SettingsLib/AppPreference/Android.bp +++ b/packages/SettingsLib/AppPreference/Android.bp @@ -20,4 +20,8 @@ android_library { ], sdk_version: "system_current", min_sdk_version: "21", + apex_available: [ + "//apex_available:platform", + "com.android.permission", + ], } diff --git a/packages/SettingsLib/BarChartPreference/Android.bp b/packages/SettingsLib/BarChartPreference/Android.bp index 4f6537334770..5c5da9827e61 100644 --- a/packages/SettingsLib/BarChartPreference/Android.bp +++ b/packages/SettingsLib/BarChartPreference/Android.bp @@ -19,4 +19,8 @@ android_library { sdk_version: "system_current", min_sdk_version: "21", + apex_available: [ + "//apex_available:platform", + "com.android.permission", + ], } diff --git a/packages/SettingsLib/HelpUtils/Android.bp b/packages/SettingsLib/HelpUtils/Android.bp index 5826047b9f52..aea51b1bba2d 100644 --- a/packages/SettingsLib/HelpUtils/Android.bp +++ b/packages/SettingsLib/HelpUtils/Android.bp @@ -19,4 +19,8 @@ android_library { sdk_version: "system_current", min_sdk_version: "21", + apex_available: [ + "//apex_available:platform", + "com.android.permission", + ], } diff --git a/packages/SettingsLib/LayoutPreference/Android.bp b/packages/SettingsLib/LayoutPreference/Android.bp index 8a4e53d80a7c..aaffdc922875 100644 --- a/packages/SettingsLib/LayoutPreference/Android.bp +++ b/packages/SettingsLib/LayoutPreference/Android.bp @@ -14,9 +14,13 @@ android_library { resource_dirs: ["res"], static_libs: [ - "androidx.preference_preference", + "androidx.preference_preference", ], sdk_version: "system_current", min_sdk_version: "21", + apex_available: [ + "//apex_available:platform", + "com.android.permission", + ], } diff --git a/packages/SettingsLib/ProgressBar/Android.bp b/packages/SettingsLib/ProgressBar/Android.bp index b5bc8f77045b..fb3c4e6efd90 100644 --- a/packages/SettingsLib/ProgressBar/Android.bp +++ b/packages/SettingsLib/ProgressBar/Android.bp @@ -15,4 +15,8 @@ android_library { sdk_version: "system_current", min_sdk_version: "21", + apex_available: [ + "//apex_available:platform", + "com.android.permission", + ], } diff --git a/packages/SettingsLib/RestrictedLockUtils/Android.bp b/packages/SettingsLib/RestrictedLockUtils/Android.bp index c0623edabefe..a7dcf8d52915 100644 --- a/packages/SettingsLib/RestrictedLockUtils/Android.bp +++ b/packages/SettingsLib/RestrictedLockUtils/Android.bp @@ -19,4 +19,8 @@ android_library { sdk_version: "system_current", min_sdk_version: "21", + apex_available: [ + "//apex_available:platform", + "com.android.permission", + ], } diff --git a/packages/SettingsLib/SearchWidget/Android.bp b/packages/SettingsLib/SearchWidget/Android.bp index b7367b4a10a7..5aaee2afc069 100644 --- a/packages/SettingsLib/SearchWidget/Android.bp +++ b/packages/SettingsLib/SearchWidget/Android.bp @@ -14,4 +14,8 @@ android_library { resource_dirs: ["res"], sdk_version: "system_current", min_sdk_version: "21", + apex_available: [ + "//apex_available:platform", + "com.android.permission", + ], } diff --git a/packages/SettingsLib/SettingsTheme/Android.bp b/packages/SettingsLib/SettingsTheme/Android.bp index 73459c277df1..da01f62b97d4 100644 --- a/packages/SettingsLib/SettingsTheme/Android.bp +++ b/packages/SettingsLib/SettingsTheme/Android.bp @@ -13,13 +13,14 @@ android_library { resource_dirs: ["res"], static_libs: [ - "androidx.preference_preference", - ], + "androidx.preference_preference", + ], sdk_version: "system_current", min_sdk_version: "21", apex_available: [ "//apex_available:platform", "com.android.cellbroadcast", + "com.android.permission", ], } diff --git a/services/core/java/com/android/server/clipboard/EmulatorClipboardMonitor.java b/services/core/java/com/android/server/clipboard/EmulatorClipboardMonitor.java index c37d4c6bcaef..ab3b2506f5ac 100644 --- a/services/core/java/com/android/server/clipboard/EmulatorClipboardMonitor.java +++ b/services/core/java/com/android/server/clipboard/EmulatorClipboardMonitor.java @@ -60,11 +60,11 @@ class EmulatorClipboardMonitor implements Consumer<ClipData> { return mPipe; } - private synchronized boolean openPipe() { - if (mPipe != null) { - return true; - } + private synchronized void setPipeFD(final FileDescriptor fd) { + mPipe = fd; + } + private static FileDescriptor openPipeImpl() { try { final FileDescriptor fd = Os.socket(OsConstants.AF_VSOCK, OsConstants.SOCK_STREAM, 0); @@ -72,39 +72,42 @@ class EmulatorClipboardMonitor implements Consumer<ClipData> { Os.connect(fd, new VmSocketAddress(HOST_PORT, OsConstants.VMADDR_CID_HOST)); final byte[] handshake = createOpenHandshake(); - Os.write(fd, handshake, 0, handshake.length); - mPipe = fd; - return true; + writeFully(fd, handshake, 0, handshake.length); + return fd; } catch (ErrnoException | SocketException | InterruptedIOException e) { Os.close(fd); } } catch (ErrnoException e) { } - return false; + return null; } - private synchronized void closePipe() { - try { - final FileDescriptor fd = mPipe; - mPipe = null; - if (fd != null) { - Os.close(fd); - } - } catch (ErrnoException ignore) { + private static FileDescriptor openPipe() throws InterruptedException { + FileDescriptor fd = openPipeImpl(); + + // There's no guarantee that QEMU pipes will be ready at the moment + // this method is invoked. We simply try to get the pipe open and + // retry on failure indefinitely. + while (fd == null) { + Thread.sleep(100); + fd = openPipeImpl(); } + + return fd; } - private byte[] receiveMessage() throws ErrnoException, InterruptedIOException, EOFException { + private static byte[] receiveMessage(final FileDescriptor fd) throws ErrnoException, + InterruptedIOException, EOFException { final byte[] lengthBits = new byte[4]; - readFully(mPipe, lengthBits, 0, lengthBits.length); + readFully(fd, lengthBits, 0, lengthBits.length); final ByteBuffer bb = ByteBuffer.wrap(lengthBits); bb.order(ByteOrder.LITTLE_ENDIAN); final int msgLen = bb.getInt(); final byte[] msg = new byte[msgLen]; - readFully(mPipe, msg, 0, msg.length); + readFully(fd, msg, 0, msg.length); return msg; } @@ -123,16 +126,16 @@ class EmulatorClipboardMonitor implements Consumer<ClipData> { EmulatorClipboardMonitor(final Consumer<ClipData> setAndroidClipboard) { this.mHostMonitorThread = new Thread(() -> { + FileDescriptor fd = null; + while (!Thread.interrupted()) { try { - // There's no guarantee that QEMU pipes will be ready at the moment - // this method is invoked. We simply try to get the pipe open and - // retry on failure indefinitely. - while (!openPipe()) { - Thread.sleep(100); + if (fd == null) { + fd = openPipe(); + setPipeFD(fd); } - final byte[] receivedData = receiveMessage(); + final byte[] receivedData = receiveMessage(fd); final String str = new String(receivedData); final ClipData clip = new ClipData("host clipboard", @@ -146,9 +149,17 @@ class EmulatorClipboardMonitor implements Consumer<ClipData> { Slog.i(TAG, "Setting the guest clipboard to '" + str + "'"); } setAndroidClipboard.accept(clip); - } catch (ErrnoException | EOFException | InterruptedIOException e) { - closePipe(); - } catch (InterruptedException | IllegalArgumentException e) { + } catch (ErrnoException | EOFException | InterruptedIOException + | InterruptedException e) { + setPipeFD(null); + + try { + Os.close(fd); + } catch (ErrnoException e2) { + // ignore + } + + fd = null; } } }); @@ -158,34 +169,43 @@ class EmulatorClipboardMonitor implements Consumer<ClipData> { @Override public void accept(final @Nullable ClipData clip) { - if (clip == null) { - setHostClipboardImpl(""); - } else if (clip.getItemCount() > 0) { - final CharSequence text = clip.getItemAt(0).getText(); - if (text != null) { - setHostClipboardImpl(text.toString()); - } + final FileDescriptor fd = getPipeFD(); + if (fd != null) { + setHostClipboard(fd, getClipString(clip)); } } - private void setHostClipboardImpl(final String value) { - final FileDescriptor pipeFD = getPipeFD(); + private String getClipString(final @Nullable ClipData clip) { + if (clip == null) { + return ""; + } - if (pipeFD != null) { - Thread t = new Thread(() -> { - if (LOG_CLIBOARD_ACCESS) { - Slog.i(TAG, "Setting the host clipboard to '" + value + "'"); - } + if (clip.getItemCount() == 0) { + return ""; + } - try { - sendMessage(pipeFD, value.getBytes()); - } catch (ErrnoException | InterruptedIOException e) { - Slog.e(TAG, "Failed to set host clipboard " + e.getMessage()); - } catch (IllegalArgumentException e) { - } - }); - t.start(); + final CharSequence text = clip.getItemAt(0).getText(); + if (text == null) { + return ""; } + + return text.toString(); + } + + private static void setHostClipboard(final FileDescriptor fd, final String value) { + Thread t = new Thread(() -> { + if (LOG_CLIBOARD_ACCESS) { + Slog.i(TAG, "Setting the host clipboard to '" + value + "'"); + } + + try { + sendMessage(fd, value.getBytes()); + } catch (ErrnoException | InterruptedIOException e) { + Slog.e(TAG, "Failed to set host clipboard " + e.getMessage()); + } catch (IllegalArgumentException e) { + } + }); + t.start(); } private static void readFully(final FileDescriptor fd, diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java index d07f151f25bd..f0f187098bc5 100644 --- a/services/core/java/com/android/server/connectivity/Vpn.java +++ b/services/core/java/com/android/server/connectivity/Vpn.java @@ -1621,11 +1621,19 @@ public class Vpn { } // Note: Return type guarantees results are deduped and sorted, which callers require. + // This method also adds the SDK sandbox UIDs corresponding to the applications by default, + // since apps are generally not aware of them, yet they should follow the VPN configuration + // of the app they belong to. private SortedSet<Integer> getAppsUids(List<String> packageNames, int userId) { SortedSet<Integer> uids = new TreeSet<>(); for (String app : packageNames) { int uid = getAppUid(app, userId); if (uid != -1) uids.add(uid); + // TODO(b/230548427): Remove SDK check once VPN related stuff are decoupled from + // ConnectivityServiceTest. + if (Process.isApplicationUid(uid) && SdkLevel.isAtLeastT()) { + uids.add(Process.toSdkSandboxUid(uid)); + } } return uids; } diff --git a/telephony/java/android/telephony/DataFailCause.java b/telephony/java/android/telephony/DataFailCause.java index fa6de1ad2864..ac1f376cf6b5 100644 --- a/telephony/java/android/telephony/DataFailCause.java +++ b/telephony/java/android/telephony/DataFailCause.java @@ -1673,4 +1673,9 @@ public final class DataFailCause { return UNKNOWN; } } + + /** @hide */ + public static boolean isFailCauseExisting(@DataFailureCause int failCause) { + return sFailCauseMap.containsKey(failCause); + } } diff --git a/telephony/java/android/telephony/PhysicalChannelConfig.java b/telephony/java/android/telephony/PhysicalChannelConfig.java index d91134e33ef3..d978f5701eca 100644 --- a/telephony/java/android/telephony/PhysicalChannelConfig.java +++ b/telephony/java/android/telephony/PhysicalChannelConfig.java @@ -23,16 +23,12 @@ import android.os.Parcel; import android.os.Parcelable; import android.telephony.Annotation.NetworkType; -import com.android.telephony.Rlog; - import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.Arrays; import java.util.Objects; public final class PhysicalChannelConfig implements Parcelable { - static final String TAG = "PhysicalChannelConfig"; - // TODO(b/72993578) consolidate these enums in a central location. /** @hide */ @Retention(RetentionPolicy.SOURCE) @@ -571,21 +567,19 @@ public final class PhysicalChannelConfig implements Parcelable { public @NonNull Builder setNetworkType(@NetworkType int networkType) { if (!TelephonyManager.isNetworkTypeValid(networkType)) { - Rlog.e(TAG, "Builder.setNetworkType: Network type " + networkType + " is invalid."); - } else { - mNetworkType = networkType; + throw new IllegalArgumentException("Network type " + networkType + " is invalid."); } + mNetworkType = networkType; return this; } public @NonNull Builder setFrequencyRange(int frequencyRange) { if (!ServiceState.isFrequencyRangeValid(frequencyRange) && frequencyRange != ServiceState.FREQUENCY_RANGE_UNKNOWN) { - Rlog.e(TAG, "Builder.setFrequencyRange: Frequency range " + frequencyRange + throw new IllegalArgumentException("Frequency range " + frequencyRange + " is invalid."); - } else { - mFrequencyRange = frequencyRange; } + mFrequencyRange = frequencyRange; return this; } @@ -601,21 +595,19 @@ public final class PhysicalChannelConfig implements Parcelable { public @NonNull Builder setCellBandwidthDownlinkKhz(int cellBandwidthDownlinkKhz) { if (cellBandwidthDownlinkKhz < CELL_BANDWIDTH_UNKNOWN) { - Rlog.e(TAG, "Builder.setCellBandwidthDownlinkKhz: Cell downlink bandwidth(kHz) " + throw new IllegalArgumentException("Cell downlink bandwidth(kHz) " + cellBandwidthDownlinkKhz + " is invalid."); - } else { - mCellBandwidthDownlinkKhz = cellBandwidthDownlinkKhz; } + mCellBandwidthDownlinkKhz = cellBandwidthDownlinkKhz; return this; } public @NonNull Builder setCellBandwidthUplinkKhz(int cellBandwidthUplinkKhz) { if (cellBandwidthUplinkKhz < CELL_BANDWIDTH_UNKNOWN) { - Rlog.e(TAG, "Builder.setCellBandwidthUplinkKhz: Cell uplink bandwidth(kHz) " + throw new IllegalArgumentException("Cell uplink bandwidth(kHz) " + cellBandwidthUplinkKhz + " is invalid."); - } else { - mCellBandwidthUplinkKhz = cellBandwidthUplinkKhz; } + mCellBandwidthUplinkKhz = cellBandwidthUplinkKhz; return this; } @@ -632,20 +624,18 @@ public final class PhysicalChannelConfig implements Parcelable { public @NonNull Builder setPhysicalCellId(int physicalCellId) { if (physicalCellId > PHYSICAL_CELL_ID_MAXIMUM_VALUE) { - Rlog.e(TAG, "Builder.setPhysicalCellId: Physical cell ID " + physicalCellId + throw new IllegalArgumentException("Physical cell ID " + physicalCellId + " is over limit."); - } else { - mPhysicalCellId = physicalCellId; } + mPhysicalCellId = physicalCellId; return this; } public @NonNull Builder setBand(int band) { if (band <= BAND_UNKNOWN) { - Rlog.e(TAG, "Builder.setBand: Band " + band + " is invalid."); - } else { - mBand = band; + throw new IllegalArgumentException("Band " + band + " is invalid."); } + mBand = band; return this; } } diff --git a/telephony/java/android/telephony/SmsManager.java b/telephony/java/android/telephony/SmsManager.java index 6d0f269fe909..7df06b09c6bb 100644 --- a/telephony/java/android/telephony/SmsManager.java +++ b/telephony/java/android/telephony/SmsManager.java @@ -2636,6 +2636,19 @@ public final class SmsManager { * sending the message. * @param sentIntent if not NULL this <code>PendingIntent</code> is * broadcast when the message is successfully sent, or failed + * The result code will be <code>Activity.RESULT_OK</code> for success + * or one of these errors:<br> + * <code>MMS_ERROR_UNSPECIFIED</code><br> + * <code>MMS_ERROR_INVALID_APN</code><br> + * <code>MMS_ERROR_UNABLE_CONNECT_MMS</code><br> + * <code>MMS_ERROR_HTTP_FAILURE</code><br> + * <code>MMS_ERROR_IO_ERROR</code><br> + * <code>MMS_ERROR_RETRY</code><br> + * <code>MMS_ERROR_CONFIGURATION_ERROR</code><br> + * <code>MMS_ERROR_NO_DATA_NETWORK</code><br> + * <code>MMS_ERROR_INVALID_SUBSCRIPTION_ID</code><br> + * <code>MMS_ERROR_INACTIVE_SUBSCRIPTION</code><br> + * <code>MMS_ERROR_DATA_DISABLED</code><br> * @throws IllegalArgumentException if contentUri is empty */ public void sendMultimediaMessage(Context context, Uri contentUri, String locationUrl, @@ -2664,6 +2677,19 @@ public final class SmsManager { * sending the message. * @param sentIntent if not NULL this <code>PendingIntent</code> is * broadcast when the message is successfully sent, or failed + * The result code will be <code>Activity.RESULT_OK</code> for success + * or one of these errors:<br> + * <code>MMS_ERROR_UNSPECIFIED</code><br> + * <code>MMS_ERROR_INVALID_APN</code><br> + * <code>MMS_ERROR_UNABLE_CONNECT_MMS</code><br> + * <code>MMS_ERROR_HTTP_FAILURE</code><br> + * <code>MMS_ERROR_IO_ERROR</code><br> + * <code>MMS_ERROR_RETRY</code><br> + * <code>MMS_ERROR_CONFIGURATION_ERROR</code><br> + * <code>MMS_ERROR_NO_DATA_NETWORK</code><br> + * <code>MMS_ERROR_INVALID_SUBSCRIPTION_ID</code><br> + * <code>MMS_ERROR_INACTIVE_SUBSCRIPTION</code><br> + * <code>MMS_ERROR_DATA_DISABLED</code><br> * @param messageId an id that uniquely identifies the message requested to be sent. * Used for logging and diagnostics purposes. The id may be 0. * @throws IllegalArgumentException if contentUri is empty @@ -2710,6 +2736,19 @@ public final class SmsManager { * downloading the message. * @param downloadedIntent if not NULL this <code>PendingIntent</code> is * broadcast when the message is downloaded, or the download is failed + * The result code will be <code>Activity.RESULT_OK</code> for success + * or one of these errors:<br> + * <code>MMS_ERROR_UNSPECIFIED</code><br> + * <code>MMS_ERROR_INVALID_APN</code><br> + * <code>MMS_ERROR_UNABLE_CONNECT_MMS</code><br> + * <code>MMS_ERROR_HTTP_FAILURE</code><br> + * <code>MMS_ERROR_IO_ERROR</code><br> + * <code>MMS_ERROR_RETRY</code><br> + * <code>MMS_ERROR_CONFIGURATION_ERROR</code><br> + * <code>MMS_ERROR_NO_DATA_NETWORK</code><br> + * <code>MMS_ERROR_INVALID_SUBSCRIPTION_ID</code><br> + * <code>MMS_ERROR_INACTIVE_SUBSCRIPTION</code><br> + * <code>MMS_ERROR_DATA_DISABLED</code><br> * @throws IllegalArgumentException if locationUrl or contentUri is empty */ public void downloadMultimediaMessage(Context context, String locationUrl, Uri contentUri, @@ -2740,6 +2779,19 @@ public final class SmsManager { * downloading the message. * @param downloadedIntent if not NULL this <code>PendingIntent</code> is * broadcast when the message is downloaded, or the download is failed + * The result code will be <code>Activity.RESULT_OK</code> for success + * or one of these errors:<br> + * <code>MMS_ERROR_UNSPECIFIED</code><br> + * <code>MMS_ERROR_INVALID_APN</code><br> + * <code>MMS_ERROR_UNABLE_CONNECT_MMS</code><br> + * <code>MMS_ERROR_HTTP_FAILURE</code><br> + * <code>MMS_ERROR_IO_ERROR</code><br> + * <code>MMS_ERROR_RETRY</code><br> + * <code>MMS_ERROR_CONFIGURATION_ERROR</code><br> + * <code>MMS_ERROR_NO_DATA_NETWORK</code><br> + * <code>MMS_ERROR_INVALID_SUBSCRIPTION_ID</code><br> + * <code>MMS_ERROR_INACTIVE_SUBSCRIPTION</code><br> + * <code>MMS_ERROR_DATA_DISABLED</code><br> * @param messageId an id that uniquely identifies the message requested to be downloaded. * Used for logging and diagnostics purposes. The id may be 0. * @throws IllegalArgumentException if locationUrl or contentUri is empty @@ -2771,15 +2823,62 @@ public final class SmsManager { } // MMS send/download failure result codes + + /** + * Unspecific MMS error occurred during send/download. + */ public static final int MMS_ERROR_UNSPECIFIED = 1; + + /** + * ApnException occurred during MMS network setup. + */ public static final int MMS_ERROR_INVALID_APN = 2; + + /** + * An error occurred during the MMS connection setup. + */ public static final int MMS_ERROR_UNABLE_CONNECT_MMS = 3; + + /** + * An error occurred during the HTTP client setup. + */ public static final int MMS_ERROR_HTTP_FAILURE = 4; + + /** + * An I/O error occurred reading the PDU. + */ public static final int MMS_ERROR_IO_ERROR = 5; + + /** + * An error occurred while retrying sending/downloading the MMS. + */ public static final int MMS_ERROR_RETRY = 6; + + /** + * The carrier-dependent configuration values could not be loaded. + */ public static final int MMS_ERROR_CONFIGURATION_ERROR = 7; + + /** + * There is no data network. + */ public static final int MMS_ERROR_NO_DATA_NETWORK = 8; + /** + * The subscription id for the send/download is invalid. + */ + public static final int MMS_ERROR_INVALID_SUBSCRIPTION_ID = 9; + + /** + * The subscription id for the send/download is inactive. + */ + public static final int MMS_ERROR_INACTIVE_SUBSCRIPTION = 10; + + /** + * Data is disabled for the MMS APN. + */ + public static final int MMS_ERROR_DATA_DISABLED = 11; + /** Intent extra name for MMS sending result data in byte array type */ public static final String EXTRA_MMS_DATA = "android.telephony.extra.MMS_DATA"; /** Intent extra name for HTTP status code for MMS HTTP failure in integer type */ |