summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apct-tests/perftests/core/src/android/libcore/ZipFilePerfTest.java3
-rw-r--r--apct-tests/perftests/core/src/android/libcore/regression/ExpensiveObjectsPerfTest.java9
-rw-r--r--apct-tests/perftests/core/src/android/libcore/regression/HostnameVerifierPerfTest.java192
-rw-r--r--apct-tests/perftests/core/src/android/libcore/regression/NumberFormatTrivialFormatLongPerfTest.java49
-rw-r--r--core/api/current.txt4
-rw-r--r--core/res/res/values/config_telephony.xml2
-rw-r--r--keystore/java/android/security/keystore2/AndroidKeyStoreBCWorkaroundProvider.java2
-rw-r--r--keystore/java/android/security/keystore2/AndroidKeyStoreECDSASignatureSpi.java24
-rw-r--r--keystore/java/android/security/keystore2/AndroidKeyStoreKeyAgreementSpi.java11
-rw-r--r--keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java5
-rw-r--r--keystore/java/android/security/keystore2/AndroidKeyStoreXDHPrivateKey.java47
-rw-r--r--keystore/java/android/security/keystore2/AndroidKeyStoreXDHPublicKey.java120
-rw-r--r--media/java/android/media/MediaFormat.java5
-rw-r--r--packages/SettingsLib/ActionBarShadow/Android.bp4
-rw-r--r--packages/SettingsLib/AppPreference/Android.bp4
-rw-r--r--packages/SettingsLib/BarChartPreference/Android.bp4
-rw-r--r--packages/SettingsLib/HelpUtils/Android.bp4
-rw-r--r--packages/SettingsLib/LayoutPreference/Android.bp6
-rw-r--r--packages/SettingsLib/ProgressBar/Android.bp4
-rw-r--r--packages/SettingsLib/RestrictedLockUtils/Android.bp4
-rw-r--r--packages/SettingsLib/SearchWidget/Android.bp4
-rw-r--r--packages/SettingsLib/SettingsTheme/Android.bp5
-rw-r--r--services/core/java/com/android/server/clipboard/EmulatorClipboardMonitor.java120
-rw-r--r--services/core/java/com/android/server/connectivity/Vpn.java8
-rw-r--r--telephony/java/android/telephony/DataFailCause.java5
-rw-r--r--telephony/java/android/telephony/PhysicalChannelConfig.java34
-rw-r--r--telephony/java/android/telephony/SmsManager.java99
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 */