diff options
7 files changed, 171 insertions, 17 deletions
diff --git a/core/java/android/bluetooth/BluetoothLeAudio.java b/core/java/android/bluetooth/BluetoothLeAudio.java index 3ea865bfd6ec..c30c933b6ef8 100644 --- a/core/java/android/bluetooth/BluetoothLeAudio.java +++ b/core/java/android/bluetooth/BluetoothLeAudio.java @@ -199,11 +199,8 @@ public final class BluetoothLeAudio implements BluetoothProfile, AutoCloseable { * * <p> * <ul> - * <li> {@link #GROUP_STATUS_IDLE} </li> - * <li> {@link #GROUP_STATUS_STREAMING} </li> - * <li> {@link #GROUP_STATUS_SUSPENDED} </li> - * <li> {@link #GROUP_STATUS_RECONFIGURED} </li> - * <li> {@link #GROUP_STATUS_DESTROYED} </li> + * <li> {@link #GROUP_STATUS_ACTIVE} </li> + * <li> {@link #GROUP_STATUS_INACTIVE} </li> * </ul> * <p> * @hide @@ -241,6 +238,19 @@ public final class BluetoothLeAudio implements BluetoothProfile, AutoCloseable { private final BluetoothAdapter mAdapter; private final AttributionSource mAttributionSource; + /** + * Indicating that group is Active ( Audio device is available ) + * @hide + */ + public static final int GROUP_STATUS_ACTIVE = IBluetoothLeAudio.GROUP_STATUS_ACTIVE; + + /** + * Indicating that group is Inactive ( Audio device is not available ) + * @hide + */ + public static final int GROUP_STATUS_INACTIVE = IBluetoothLeAudio.GROUP_STATUS_INACTIVE; + + private final BluetoothProfileConnector<IBluetoothLeAudio> mProfileConnector = new BluetoothProfileConnector(this, BluetoothProfile.LE_AUDIO, "BluetoothLeAudio", IBluetoothLeAudio.class.getName()) { @@ -433,7 +443,7 @@ public final class BluetoothLeAudio implements BluetoothProfile, AutoCloseable { * <p> This API returns false in scenarios like the profile on the * device is not connected or Bluetooth is not turned on. * When this API returns true, it is guaranteed that the - * {@link #ACTION_LEAUDIO_ACTIVE_DEVICE_CHANGED} intent will be broadcasted + * {@link #ACTION_LE_AUDIO_ACTIVE_DEVICE_CHANGED} intent will be broadcasted * with the active device. * * @@ -512,6 +522,30 @@ public final class BluetoothLeAudio implements BluetoothProfile, AutoCloseable { } /** + * Set volume for the streaming devices + * + * @param volume volume to set + * @hide + */ + @RequiresBluetoothConnectPermission + @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) + public void setVolume(int volume) { + if (VDBG) log("setVolume(vol: " + volume + " )"); + try { + final IBluetoothLeAudio service = getService(); + if (service != null && mAdapter.isEnabled()) { + service.setVolume(volume, mAttributionSource); + return; + } + if (service == null) Log.w(TAG, "Proxy not attached to service"); + return; + } catch (RemoteException e) { + Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); + return; + } + } + + /** * Set connection policy of the profile * * <p> The device should already be paired. diff --git a/core/java/android/bluetooth/BluetoothUuid.java b/core/java/android/bluetooth/BluetoothUuid.java index 67b725221206..325a77107255 100644 --- a/core/java/android/bluetooth/BluetoothUuid.java +++ b/core/java/android/bluetooth/BluetoothUuid.java @@ -155,12 +155,11 @@ public final class BluetoothUuid { @SystemApi public static final ParcelUuid HEARING_AID = ParcelUuid.fromString("0000FDF0-0000-1000-8000-00805f9b34fb"); - /** Placeholder until specification is released - * @hide */ + /** @hide */ @NonNull @SystemApi public static final ParcelUuid LE_AUDIO = - ParcelUuid.fromString("EEEEEEEE-EEEE-EEEE-EEEE-EEEEEEEEEEEE"); + ParcelUuid.fromString("0000184E-0000-1000-8000-00805F9B34FB"); /** @hide */ @NonNull @SystemApi diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreKey.java b/keystore/java/android/security/keystore2/AndroidKeyStoreKey.java index b24a22dbc0ec..16f732f63bf7 100644 --- a/keystore/java/android/security/keystore2/AndroidKeyStoreKey.java +++ b/keystore/java/android/security/keystore2/AndroidKeyStoreKey.java @@ -22,6 +22,8 @@ import android.system.keystore2.Authorization; import android.system.keystore2.Domain; import android.system.keystore2.KeyDescriptor; +import com.android.internal.annotations.VisibleForTesting; + import java.security.Key; /** @@ -46,7 +48,11 @@ public class AndroidKeyStoreKey implements Key { // We do not include this member in comparisons. private final KeyStoreSecurityLevel mSecurityLevel; - AndroidKeyStoreKey(@NonNull KeyDescriptor descriptor, + /** + * @hide + */ + @VisibleForTesting + public AndroidKeyStoreKey(@NonNull KeyDescriptor descriptor, long keyId, @NonNull Authorization[] authorizations, @NonNull String algorithm, diff --git a/keystore/java/android/security/keystore2/AndroidKeyStorePublicKey.java b/keystore/java/android/security/keystore2/AndroidKeyStorePublicKey.java index 4842984e8c6a..0b3be327b521 100644 --- a/keystore/java/android/security/keystore2/AndroidKeyStorePublicKey.java +++ b/keystore/java/android/security/keystore2/AndroidKeyStorePublicKey.java @@ -23,7 +23,7 @@ import android.system.keystore2.KeyDescriptor; import android.system.keystore2.KeyMetadata; import java.security.PublicKey; -import java.util.Objects; +import java.util.Arrays; /** * {@link PublicKey} backed by Android Keystore. @@ -62,8 +62,8 @@ public abstract class AndroidKeyStorePublicKey extends AndroidKeyStoreKey implem int result = 1; result = prime * result + super.hashCode(); - result = prime * result + ((mCertificate == null) ? 0 : mCertificate.hashCode()); - result = prime * result + ((mCertificateChain == null) ? 0 : mCertificateChain.hashCode()); + result = prime * result + Arrays.hashCode(mCertificate); + result = prime * result + Arrays.hashCode(mCertificateChain); return result; } @@ -83,7 +83,7 @@ public abstract class AndroidKeyStorePublicKey extends AndroidKeyStoreKey implem */ final AndroidKeyStorePublicKey other = (AndroidKeyStorePublicKey) obj; - return Objects.equals(mCertificate, other.mCertificate) && Objects.equals(mCertificateChain, + return Arrays.equals(mCertificate, other.mCertificate) && Arrays.equals(mCertificateChain, other.mCertificateChain); } } diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java b/keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java index 67358c4f3255..33411e1ec5b9 100644 --- a/keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java +++ b/keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java @@ -601,8 +601,6 @@ public class AndroidKeyStoreSpi extends KeyStoreSpi { } KeyProtection params = (KeyProtection) param; - @SecurityLevel int securityLevel = params.isStrongBoxBacked() ? SecurityLevel.STRONGBOX : - SecurityLevel.TRUSTED_ENVIRONMENT; @Domain int targetDomain = (getTargetDomain()); if (key instanceof AndroidKeyStoreSecretKey) { @@ -794,6 +792,9 @@ public class AndroidKeyStoreSpi extends KeyStoreSpi { flags |= IKeystoreSecurityLevel.KEY_FLAG_AUTH_BOUND_WITHOUT_CRYPTOGRAPHIC_LSKF_BINDING; } + @SecurityLevel int securityLevel = params.isStrongBoxBacked() ? SecurityLevel.STRONGBOX : + SecurityLevel.TRUSTED_ENVIRONMENT; + try { KeyStoreSecurityLevel securityLevelInterface = mKeyStore.getSecurityLevel( securityLevel); diff --git a/keystore/tests/src/android/security/keystore2/AndroidKeyStoreSpiTest.java b/keystore/tests/src/android/security/keystore2/AndroidKeyStoreSpiTest.java index 1bd3069f483a..f96c39c879fd 100644 --- a/keystore/tests/src/android/security/keystore2/AndroidKeyStoreSpiTest.java +++ b/keystore/tests/src/android/security/keystore2/AndroidKeyStoreSpiTest.java @@ -24,7 +24,13 @@ import static org.mockito.Mockito.when; import android.security.KeyStore2; import android.security.KeyStoreException; +import android.security.KeyStoreSecurityLevel; +import android.system.keystore2.Authorization; +import android.system.keystore2.Domain; +import android.system.keystore2.KeyDescriptor; +import android.system.keystore2.KeyMetadata; +import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.mockito.Mock; @@ -52,4 +58,112 @@ public class AndroidKeyStoreSpiTest { verify(mKeystore2).list(anyInt(), anyLong()); } + @Mock + private KeyStoreSecurityLevel mKeystoreSecurityLevel; + + private static KeyDescriptor descriptor() { + final KeyDescriptor keyDescriptor = new KeyDescriptor(); + keyDescriptor.alias = "key"; + keyDescriptor.blob = null; + keyDescriptor.domain = Domain.APP; + keyDescriptor.nspace = -1; + return keyDescriptor; + } + + private static KeyMetadata metadata(byte[] cert, byte[] certChain) { + KeyMetadata metadata = new KeyMetadata(); + metadata.authorizations = new Authorization[0]; + metadata.certificate = cert; + metadata.certificateChain = certChain; + metadata.key = descriptor(); + metadata.modificationTimeMs = 0; + metadata.keySecurityLevel = 1; + return metadata; + } + + private static byte[] bytes(String string) { + return string.getBytes(); + } + + class MyPublicKey extends AndroidKeyStorePublicKey { + MyPublicKey(String cert, String chain, KeyStoreSecurityLevel securityLevel) { + super(descriptor(), metadata(cert.getBytes(), chain.getBytes()), "N/A".getBytes(), + "RSA", securityLevel); + } + + @Override + AndroidKeyStorePrivateKey getPrivateKey() { + return null; + } + } + + private AndroidKeyStorePublicKey makePrivateKeyObject(String cert, String chain) { + return new MyPublicKey(cert, chain, mKeystoreSecurityLevel); + } + + @Test + public void testKeystoreKeysAdhereToContractBetweenEqualsAndHashCode() throws Exception { + AndroidKeyStoreKey key1 = new AndroidKeyStoreKey(descriptor(), 1, new Authorization[0], + "RSA", mKeystoreSecurityLevel); + AndroidKeyStoreKey key2 = new AndroidKeyStoreKey(descriptor(), 2, new Authorization[0], + "RSA", mKeystoreSecurityLevel); + AndroidKeyStoreKey key1_clone = new AndroidKeyStoreKey(descriptor(), 1, + new Authorization[0], "RSA", mKeystoreSecurityLevel); + + assertThat("Identity should yield true", key1.equals(key1)); + Assert.assertEquals("Identity should yield same hash codes", + key1.hashCode(), key1.hashCode()); + assertThat("Identity should yield true", key2.equals(key2)); + Assert.assertEquals("Identity should yield same hash codes", + key2.hashCode(), key2.hashCode()); + assertThat("Different keys should differ", !key1.equals(key2)); + Assert.assertNotEquals("Different keys should have different hash codes", + key1.hashCode(), key2.hashCode()); + + assertThat("Same keys should yield true", key1.equals(key1_clone)); + assertThat("Same keys should yield true", key1_clone.equals(key1)); + Assert.assertEquals("Same keys should yield same hash codes", + key1.hashCode(), key1_clone.hashCode()); + + assertThat("anything.equal(null) should yield false", !key1.equals(null)); + assertThat("anything.equal(null) should yield false", !key2.equals(null)); + assertThat("anything.equal(null) should yield false", !key1_clone.equals(null)); + } + + @Test + public void testKeystorePublicKeysAdhereToContractBetweenEqualsAndHashCode() throws Exception { + AndroidKeyStorePublicKey key1 = makePrivateKeyObject("myCert1", "myChain1"); + AndroidKeyStorePublicKey key2 = makePrivateKeyObject("myCert2", "myChain1"); + AndroidKeyStorePublicKey key3 = makePrivateKeyObject("myCert1", "myChain3"); + AndroidKeyStorePublicKey key1_clone = makePrivateKeyObject("myCert1", "myChain1"); + + assertThat("Identity should yield true", key1.equals(key1)); + Assert.assertEquals("Identity should yield same hash codes", + key1.hashCode(), key1.hashCode()); + assertThat("Identity should yield true", key2.equals(key2)); + Assert.assertEquals("Identity should yield same hash codes", + key2.hashCode(), key2.hashCode()); + assertThat("Identity should yield true", key3.equals(key3)); + Assert.assertEquals("Identity should yield same hash codes", + key3.hashCode(), key3.hashCode()); + assertThat("Different keys should differ", !key1.equals(key2)); + Assert.assertNotEquals("Different keys should have different hash codes", + key1.hashCode(), key2.hashCode()); + assertThat("Different keys should differ", !key1.equals(key3)); + Assert.assertNotEquals("Different keys should have different hash codes", + key1.hashCode(), key3.hashCode()); + assertThat("Different keys should differ", !key2.equals(key3)); + Assert.assertNotEquals("Different keys should have different hash codes", + key2.hashCode(), key3.hashCode()); + + assertThat("Same keys should yield true", key1.equals(key1_clone)); + assertThat("Same keys should yield true", key1_clone.equals(key1)); + Assert.assertEquals("Same keys should yield same hash codes", + key1.hashCode(), key1_clone.hashCode()); + + assertThat("anything.equal(null) should yield false", !key1.equals(null)); + assertThat("anything.equal(null) should yield false", !key2.equals(null)); + assertThat("anything.equal(null) should yield false", !key3.equals(null)); + assertThat("anything.equal(null) should yield false", !key1_clone.equals(null)); + } } diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java index f859857b8a2a..846e6f3c5800 100644 --- a/telephony/java/android/telephony/ServiceState.java +++ b/telephony/java/android/telephony/ServiceState.java @@ -612,7 +612,7 @@ public class ServiceState implements Parcelable { /** * Get the channel number of the current primary serving cell, or -1 if unknown * - * <p>This is EARFCN for LTE, UARFCN for UMTS, and ARFCN for GSM. + * <p>This is NRARFCN for NR, EARFCN for LTE, UARFCN for UMTS, and ARFCN for GSM. * * @return Channel number of primary serving cell */ |