summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/jni/android_media_AudioSystem.cpp51
-rw-r--r--media/java/android/media/AudioDeviceAttributes.java13
-rw-r--r--media/java/android/media/AudioManager.java25
-rw-r--r--media/java/android/media/AudioSystem.java23
-rwxr-xr-xmedia/java/android/media/IAudioService.aidl3
-rw-r--r--media/java/android/media/audio/common/AidlConversion.java350
-rw-r--r--media/tests/aidltests/src/com/android/media/AidlConversionUnitTests.java107
-rw-r--r--services/core/java/com/android/server/audio/AudioDeviceBroker.java13
-rw-r--r--services/core/java/com/android/server/audio/AudioDeviceInventory.java130
-rw-r--r--services/core/java/com/android/server/audio/AudioService.java14
-rw-r--r--services/core/java/com/android/server/audio/AudioServiceEvents.java7
-rw-r--r--services/core/java/com/android/server/audio/AudioSystemAdapter.java13
-rw-r--r--services/core/java/com/android/server/audio/BtHelper.java15
-rw-r--r--services/tests/servicestests/src/com/android/server/audio/AudioDeviceBrokerTest.java12
-rw-r--r--services/tests/servicestests/src/com/android/server/audio/NoOpAudioSystemAdapter.java9
-rw-r--r--services/usb/java/com/android/server/usb/UsbAlsaDevice.java16
16 files changed, 657 insertions, 144 deletions
diff --git a/core/jni/android_media_AudioSystem.cpp b/core/jni/android_media_AudioSystem.cpp
index 3e2b25853a6a..e439e49acf71 100644
--- a/core/jni/android_media_AudioSystem.cpp
+++ b/core/jni/android_media_AudioSystem.cpp
@@ -18,25 +18,25 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "AudioSystem-JNI"
-#include <utils/Log.h>
-
-#include <sstream>
-#include <vector>
-#include <jni.h>
-#include <nativehelper/JNIHelp.h>
-#include "core_jni_helpers.h"
-
#include <android/media/AudioVibratorInfo.h>
#include <android/media/INativeSpatializerCallback.h>
#include <android/media/ISpatializer.h>
+#include <android_os_Parcel.h>
#include <audiomanager/AudioManager.h>
+#include <jni.h>
#include <media/AudioContainers.h>
#include <media/AudioPolicy.h>
#include <media/AudioSystem.h>
#include <media/MicrophoneInfo.h>
+#include <nativehelper/JNIHelp.h>
#include <nativehelper/ScopedLocalRef.h>
#include <system/audio.h>
#include <system/audio_policy.h>
+#include <utils/Log.h>
+
+#include <sstream>
+#include <vector>
+
#include "android_media_AudioAttributes.h"
#include "android_media_AudioDescriptor.h"
#include "android_media_AudioDeviceAttributes.h"
@@ -46,6 +46,7 @@
#include "android_media_AudioProfile.h"
#include "android_media_MicrophoneInfo.h"
#include "android_util_Binder.h"
+#include "core_jni_helpers.h"
// ----------------------------------------------------------------------------
@@ -578,18 +579,26 @@ android_media_AudioSystem_routing_callback()
env->DeleteLocalRef(clazz);
}
-static jint
-android_media_AudioSystem_setDeviceConnectionState(JNIEnv *env, jobject thiz, jint device, jint state, jstring device_address, jstring device_name,
- jint codec)
-{
- const char *c_address = env->GetStringUTFChars(device_address, NULL);
- const char *c_name = env->GetStringUTFChars(device_name, NULL);
- int status = check_AudioSystem_Command(AudioSystem::setDeviceConnectionState(static_cast <audio_devices_t>(device),
- static_cast <audio_policy_dev_state_t>(state),
- c_address, c_name,
- static_cast <audio_format_t>(codec)));
- env->ReleaseStringUTFChars(device_address, c_address);
- env->ReleaseStringUTFChars(device_name, c_name);
+static jint android_media_AudioSystem_setDeviceConnectionState(JNIEnv *env, jobject thiz,
+ jint state, jobject jParcel,
+ jint codec) {
+ int status;
+ if (Parcel *parcel = parcelForJavaObject(env, jParcel); parcel != nullptr) {
+ android::media::audio::common::AudioPort port{};
+ if (status_t statusOfParcel = port.readFromParcel(parcel); statusOfParcel == OK) {
+ status = check_AudioSystem_Command(
+ AudioSystem::setDeviceConnectionState(static_cast<audio_policy_dev_state_t>(
+ state),
+ port,
+ static_cast<audio_format_t>(codec)));
+ } else {
+ ALOGE("Failed to read from parcel: %s", statusToString(statusOfParcel).c_str());
+ status = kAudioStatusError;
+ }
+ } else {
+ ALOGE("Failed to retrieve the native parcel from Java parcel");
+ status = kAudioStatusError;
+ }
return (jint) status;
}
@@ -2830,7 +2839,7 @@ static const JNINativeMethod gMethods[] =
{"newAudioSessionId", "()I", (void *)android_media_AudioSystem_newAudioSessionId},
{"newAudioPlayerId", "()I", (void *)android_media_AudioSystem_newAudioPlayerId},
{"newAudioRecorderId", "()I", (void *)android_media_AudioSystem_newAudioRecorderId},
- {"setDeviceConnectionState", "(IILjava/lang/String;Ljava/lang/String;I)I",
+ {"setDeviceConnectionState", "(ILandroid/os/Parcel;I)I",
(void *)android_media_AudioSystem_setDeviceConnectionState},
{"getDeviceConnectionState", "(ILjava/lang/String;)I",
(void *)android_media_AudioSystem_getDeviceConnectionState},
diff --git a/media/java/android/media/AudioDeviceAttributes.java b/media/java/android/media/AudioDeviceAttributes.java
index 4ce0440944a8..af3c295b8d6c 100644
--- a/media/java/android/media/AudioDeviceAttributes.java
+++ b/media/java/android/media/AudioDeviceAttributes.java
@@ -166,10 +166,21 @@ public final class AudioDeviceAttributes implements Parcelable {
* @param address the address of the device, or an empty string for devices without one
*/
public AudioDeviceAttributes(int nativeType, @NonNull String address) {
+ this(nativeType, address, "");
+ }
+
+ /**
+ * @hide
+ * Constructor called from BtHelper to connect or disconnect a Bluetooth device.
+ * @param nativeType the internal device type, as defined in {@link AudioSystem}
+ * @param address the address of the device, or an empty string for devices without one
+ * @param name the name of the device, or an empty string for devices without one
+ */
+ public AudioDeviceAttributes(int nativeType, @NonNull String address, @NonNull String name) {
mRole = (nativeType & AudioSystem.DEVICE_BIT_IN) != 0 ? ROLE_INPUT : ROLE_OUTPUT;
mType = AudioDeviceInfo.convertInternalDeviceToDeviceType(nativeType);
mAddress = address;
- mName = "";
+ mName = name;
mNativeType = nativeType;
mAudioProfiles = new ArrayList<>();
mAudioDescriptors = new ArrayList<>();
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 68e5d94f7559..bae045562767 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -5851,7 +5851,7 @@ public class AudioManager {
return false;
}
- /**
+ /**
* Indicate wired accessory connection state change.
* @param device type of device connected/disconnected (AudioManager.DEVICE_OUT_xxx)
* @param state new connection state: 1 connected, 0 disconnected
@@ -5860,10 +5860,29 @@ public class AudioManager {
*/
@UnsupportedAppUsage
@RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
- public void setWiredDeviceConnectionState(int type, int state, String address, String name) {
+ public void setWiredDeviceConnectionState(int device, int state, String address,
+ String name) {
+ final IAudioService service = getService();
+ int role = isOutputDevice(device)
+ ? AudioDeviceAttributes.ROLE_OUTPUT : AudioDeviceAttributes.ROLE_INPUT;
+ AudioDeviceAttributes attributes = new AudioDeviceAttributes(
+ role, AudioDeviceInfo.convertInternalDeviceToDeviceType(device), address,
+ name, new ArrayList<>()/*mAudioProfiles*/, new ArrayList<>()/*mAudioDescriptors*/);
+ setWiredDeviceConnectionState(attributes, state);
+ }
+
+ /**
+ * Indicate wired accessory connection state change and attributes.
+ * @param state new connection state: 1 connected, 0 disconnected
+ * @param attributes attributes of the connected device
+ * {@hide}
+ */
+ @UnsupportedAppUsage
+ @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
+ public void setWiredDeviceConnectionState(AudioDeviceAttributes attributes, int state) {
final IAudioService service = getService();
try {
- service.setWiredDeviceConnectionState(type, state, address, name,
+ service.setWiredDeviceConnectionState(attributes, state,
mApplicationContext.getOpPackageName());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java
index af5a3da5f3e2..31ccba5b4d02 100644
--- a/media/java/android/media/AudioSystem.java
+++ b/media/java/android/media/AudioSystem.java
@@ -26,10 +26,12 @@ import android.bluetooth.BluetoothLeAudioCodecConfig;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.content.pm.PackageManager;
+import android.media.audio.common.AidlConversion;
import android.media.audiofx.AudioEffect;
import android.media.audiopolicy.AudioMix;
import android.os.Build;
import android.os.IBinder;
+import android.os.Parcel;
import android.os.Vibrator;
import android.telephony.TelephonyManager;
import android.util.Log;
@@ -1542,9 +1544,24 @@ public class AudioSystem
* {@link #AUDIO_STATUS_ERROR} or {@link #AUDIO_STATUS_SERVER_DIED}
*/
@UnsupportedAppUsage
- public static native int setDeviceConnectionState(int device, int state,
- String device_address, String device_name,
- int codecFormat);
+ public static int setDeviceConnectionState(AudioDeviceAttributes attributes, int state,
+ int codecFormat) {
+ android.media.audio.common.AudioPort port =
+ AidlConversion.api2aidl_AudioDeviceAttributes_AudioPort(attributes);
+ Parcel parcel = Parcel.obtain();
+ port.writeToParcel(parcel, 0);
+ parcel.setDataPosition(0);
+ try {
+ return setDeviceConnectionState(state, parcel, codecFormat);
+ } finally {
+ parcel.recycle();
+ }
+ }
+ /**
+ * @hide
+ */
+ @UnsupportedAppUsage
+ public static native int setDeviceConnectionState(int state, Parcel parcel, int codecFormat);
/** @hide */
@UnsupportedAppUsage
public static native int getDeviceConnectionState(int device, String device_address);
diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl
index 96199a988704..a43f90a1a503 100755
--- a/media/java/android/media/IAudioService.aidl
+++ b/media/java/android/media/IAudioService.aidl
@@ -215,8 +215,7 @@ interface IAudioService {
IRingtonePlayer getRingtonePlayer();
int getUiSoundsStreamType();
- void setWiredDeviceConnectionState(int type, int state, String address, String name,
- String caller);
+ void setWiredDeviceConnectionState(in AudioDeviceAttributes aa, int state, String caller);
@UnsupportedAppUsage
AudioRoutesInfo startWatchingRoutes(in IAudioRoutesObserver observer);
diff --git a/media/java/android/media/audio/common/AidlConversion.java b/media/java/android/media/audio/common/AidlConversion.java
index 1053fb717fda..f17189dedcba 100644
--- a/media/java/android/media/audio/common/AidlConversion.java
+++ b/media/java/android/media/audio/common/AidlConversion.java
@@ -17,12 +17,17 @@
package android.media.audio.common;
import android.annotation.NonNull;
+import android.media.AudioDescriptor;
+import android.media.AudioDeviceAttributes;
import android.media.AudioFormat;
+import android.media.AudioSystem;
import android.media.MediaFormat;
import android.os.Parcel;
import com.android.internal.annotations.VisibleForTesting;
+import java.util.stream.Collectors;
+
/**
* This class provides utility functions for converting between
* the AIDL types defined in 'android.media.audio.common' and:
@@ -525,6 +530,351 @@ public class AidlConversion {
}
}
+ /**
+ * Convert from SDK AudioDeviceAttributes to AIDL AudioPort.
+ */
+ public static AudioPort api2aidl_AudioDeviceAttributes_AudioPort(
+ @NonNull AudioDeviceAttributes attributes) {
+ AudioPort port = new AudioPort();
+ port.name = attributes.getName();
+ // TO DO: b/211611504 Convert attributes.getAudioProfiles() to AIDL as well.
+ port.profiles = new AudioProfile[]{};
+ port.extraAudioDescriptors = attributes.getAudioDescriptors().stream()
+ .map(descriptor -> api2aidl_AudioDescriptor_ExtraAudioDescriptor(descriptor))
+ .collect(Collectors.toList()).toArray(ExtraAudioDescriptor[]::new);
+ port.flags = new AudioIoFlags();
+ port.gains = new AudioGain[]{};
+ AudioPortDeviceExt deviceExt = new AudioPortDeviceExt();
+ deviceExt.device = new AudioDevice();
+ deviceExt.encodedFormats = new AudioFormatDescription[]{};
+ deviceExt.device.type =
+ api2aidl_NativeType_AudioDeviceDescription(attributes.getInternalType());
+ deviceExt.device.address = AudioDeviceAddress.id(attributes.getAddress());
+ port.ext = AudioPortExt.device(deviceExt);
+ return port;
+ }
+
+ /**
+ * Convert from SDK AudioDescriptor to AIDL ExtraAudioDescriptor.
+ */
+ public static ExtraAudioDescriptor api2aidl_AudioDescriptor_ExtraAudioDescriptor(
+ @NonNull AudioDescriptor descriptor) {
+ ExtraAudioDescriptor extraDescriptor = new ExtraAudioDescriptor();
+ extraDescriptor.standard =
+ api2aidl_AudioDescriptorStandard_AudioStandard(descriptor.getStandard());
+ extraDescriptor.audioDescriptor = descriptor.getDescriptor();
+ extraDescriptor.encapsulationType =
+ api2aidl_AudioProfileEncapsulationType_AudioEncapsulationType(
+ descriptor.getEncapsulationType());
+ return extraDescriptor;
+ }
+
+ /**
+ * Convert from SDK AudioDescriptor to AIDL ExtraAudioDescriptor.
+ */
+ public static @NonNull AudioDescriptor aidl2api_ExtraAudioDescriptor_AudioDescriptor(
+ @NonNull ExtraAudioDescriptor extraDescriptor) {
+ AudioDescriptor descriptor = new AudioDescriptor(
+ aidl2api_AudioStandard_AudioDescriptorStandard(extraDescriptor.standard),
+ aidl2api_AudioEncapsulationType_AudioProfileEncapsulationType(
+ extraDescriptor.encapsulationType),
+ extraDescriptor.audioDescriptor);
+ return descriptor;
+ }
+
+ /**
+ * Convert from SDK AudioDescriptor#mStandard to AIDL AudioStandard
+ */
+ @AudioStandard
+ public static int api2aidl_AudioDescriptorStandard_AudioStandard(
+ @AudioDescriptor.AudioDescriptorStandard int standard) {
+ switch (standard) {
+ case AudioDescriptor.STANDARD_EDID:
+ return AudioStandard.EDID;
+ case AudioDescriptor.STANDARD_NONE:
+ default:
+ return AudioStandard.NONE;
+ }
+ }
+
+ /**
+ * Convert from AIDL AudioStandard to SDK AudioDescriptor#mStandard
+ */
+ @AudioDescriptor.AudioDescriptorStandard
+ public static int aidl2api_AudioStandard_AudioDescriptorStandard(@AudioStandard int standard) {
+ switch (standard) {
+ case AudioStandard.EDID:
+ return AudioDescriptor.STANDARD_EDID;
+ case AudioStandard.NONE:
+ default:
+ return AudioDescriptor.STANDARD_NONE;
+ }
+ }
+
+ /**
+ * Convert from SDK AudioProfile.EncapsulationType to AIDL AudioEncapsulationType
+ */
+ @AudioEncapsulationType
+ public static int api2aidl_AudioProfileEncapsulationType_AudioEncapsulationType(
+ @android.media.AudioProfile.EncapsulationType int type) {
+ switch (type) {
+ case android.media.AudioProfile.AUDIO_ENCAPSULATION_TYPE_IEC61937:
+ return AudioEncapsulationType.IEC61937;
+ case android.media.AudioProfile.AUDIO_ENCAPSULATION_TYPE_NONE:
+ default:
+ return AudioEncapsulationType.NONE;
+ }
+ }
+
+ /**
+ * Convert from AIDL AudioEncapsulationType to SDK AudioProfile.EncapsulationType
+ */
+ @android.media.AudioProfile.EncapsulationType
+ public static int aidl2api_AudioEncapsulationType_AudioProfileEncapsulationType(
+ @AudioEncapsulationType int type) {
+ switch (type) {
+ case AudioEncapsulationType.IEC61937:
+ return android.media.AudioProfile.AUDIO_ENCAPSULATION_TYPE_IEC61937;
+ case AudioEncapsulationType.NONE:
+ default:
+ return android.media.AudioProfile.AUDIO_ENCAPSULATION_TYPE_NONE;
+ }
+ }
+
+ /**
+ * Convert from SDK native type to AIDL AudioDeviceDescription
+ */
+ public static AudioDeviceDescription api2aidl_NativeType_AudioDeviceDescription(
+ int nativeType) {
+ AudioDeviceDescription aidl = new AudioDeviceDescription();
+ aidl.connection = "";
+ switch (nativeType) {
+ case AudioSystem.DEVICE_OUT_EARPIECE:
+ aidl.type = AudioDeviceType.OUT_SPEAKER_EARPIECE;
+ break;
+ case AudioSystem.DEVICE_OUT_SPEAKER:
+ aidl.type = AudioDeviceType.OUT_SPEAKER;
+ break;
+ case AudioSystem.DEVICE_OUT_WIRED_HEADPHONE:
+ aidl.type = AudioDeviceType.OUT_HEADPHONE;
+ aidl.connection = AudioDeviceDescription.CONNECTION_ANALOG;
+ break;
+ case AudioSystem.DEVICE_OUT_BLUETOOTH_SCO:
+ aidl.type = AudioDeviceType.OUT_DEVICE;
+ aidl.connection = AudioDeviceDescription.CONNECTION_BT_SCO;
+ break;
+ case AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_CARKIT:
+ aidl.type = AudioDeviceType.OUT_CARKIT;
+ aidl.connection = AudioDeviceDescription.CONNECTION_BT_SCO;
+ break;
+ case AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES:
+ aidl.type = AudioDeviceType.OUT_HEADPHONE;
+ aidl.connection = AudioDeviceDescription.CONNECTION_BT_A2DP;
+ break;
+ case AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER:
+ aidl.type = AudioDeviceType.OUT_SPEAKER;
+ aidl.connection = AudioDeviceDescription.CONNECTION_BT_A2DP;
+ break;
+ case AudioSystem.DEVICE_OUT_TELEPHONY_TX:
+ aidl.type = AudioDeviceType.OUT_TELEPHONY_TX;
+ break;
+ case AudioSystem.DEVICE_OUT_AUX_LINE:
+ aidl.type = AudioDeviceType.OUT_LINE_AUX;
+ break;
+ case AudioSystem.DEVICE_OUT_SPEAKER_SAFE:
+ aidl.type = AudioDeviceType.OUT_SPEAKER_SAFE;
+ break;
+ case AudioSystem.DEVICE_OUT_HEARING_AID:
+ aidl.type = AudioDeviceType.OUT_HEARING_AID;
+ aidl.connection = AudioDeviceDescription.CONNECTION_WIRELESS;
+ break;
+ case AudioSystem.DEVICE_OUT_ECHO_CANCELLER:
+ aidl.type = AudioDeviceType.OUT_ECHO_CANCELLER;
+ break;
+ case AudioSystem.DEVICE_OUT_BLE_SPEAKER:
+ aidl.type = AudioDeviceType.OUT_SPEAKER;
+ aidl.connection = AudioDeviceDescription.CONNECTION_BT_LE;
+ break;
+ case AudioSystem.DEVICE_IN_BUILTIN_MIC:
+ aidl.type = AudioDeviceType.IN_MICROPHONE;
+ break;
+ case AudioSystem.DEVICE_IN_BACK_MIC:
+ aidl.type = AudioDeviceType.IN_MICROPHONE_BACK;
+ break;
+ case AudioSystem.DEVICE_IN_TELEPHONY_RX:
+ aidl.type = AudioDeviceType.IN_TELEPHONY_RX;
+ break;
+ case AudioSystem.DEVICE_IN_TV_TUNER:
+ aidl.type = AudioDeviceType.IN_TV_TUNER;
+ break;
+ case AudioSystem.DEVICE_IN_LOOPBACK:
+ aidl.type = AudioDeviceType.IN_LOOPBACK;
+ break;
+ case AudioSystem.DEVICE_IN_BLUETOOTH_BLE:
+ aidl.type = AudioDeviceType.IN_DEVICE;
+ aidl.connection = AudioDeviceDescription.CONNECTION_BT_LE;
+ break;
+ case AudioSystem.DEVICE_IN_ECHO_REFERENCE:
+ aidl.type = AudioDeviceType.IN_ECHO_REFERENCE;
+ break;
+ case AudioSystem.DEVICE_IN_WIRED_HEADSET:
+ aidl.type = AudioDeviceType.IN_HEADSET;
+ aidl.connection = AudioDeviceDescription.CONNECTION_ANALOG;
+ break;
+ case AudioSystem.DEVICE_OUT_WIRED_HEADSET:
+ aidl.type = AudioDeviceType.OUT_HEADSET;
+ aidl.connection = AudioDeviceDescription.CONNECTION_ANALOG;
+ break;
+ case AudioSystem.DEVICE_IN_BLUETOOTH_SCO_HEADSET:
+ aidl.type = AudioDeviceType.IN_HEADSET;
+ aidl.connection = AudioDeviceDescription.CONNECTION_BT_SCO;
+ break;
+ case AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_HEADSET:
+ aidl.type = AudioDeviceType.OUT_HEADSET;
+ aidl.connection = AudioDeviceDescription.CONNECTION_BT_SCO;
+ break;
+ case AudioSystem.DEVICE_IN_HDMI:
+ aidl.type = AudioDeviceType.IN_DEVICE;
+ aidl.connection = AudioDeviceDescription.CONNECTION_HDMI;
+ break;
+ case AudioSystem.DEVICE_OUT_HDMI:
+ aidl.type = AudioDeviceType.OUT_DEVICE;
+ aidl.connection = AudioDeviceDescription.CONNECTION_HDMI;
+ break;
+ case AudioSystem.DEVICE_IN_REMOTE_SUBMIX:
+ aidl.type = AudioDeviceType.IN_SUBMIX;
+ break;
+ case AudioSystem.DEVICE_OUT_REMOTE_SUBMIX:
+ aidl.type = AudioDeviceType.OUT_SUBMIX;
+ break;
+ case AudioSystem.DEVICE_IN_ANLG_DOCK_HEADSET:
+ aidl.type = AudioDeviceType.IN_DOCK;
+ aidl.connection = AudioDeviceDescription.CONNECTION_ANALOG;
+ break;
+ case AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET:
+ aidl.type = AudioDeviceType.OUT_DOCK;
+ aidl.connection = AudioDeviceDescription.CONNECTION_ANALOG;
+ break;
+ case AudioSystem.DEVICE_IN_DGTL_DOCK_HEADSET:
+ aidl.type = AudioDeviceType.IN_DOCK;
+ aidl.connection = AudioDeviceDescription.CONNECTION_USB;
+ break;
+ case AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET:
+ aidl.type = AudioDeviceType.OUT_DOCK;
+ aidl.connection = AudioDeviceDescription.CONNECTION_USB;
+ break;
+ case AudioSystem.DEVICE_IN_USB_ACCESSORY:
+ aidl.type = AudioDeviceType.IN_ACCESSORY;
+ aidl.connection = AudioDeviceDescription.CONNECTION_USB;
+ break;
+ case AudioSystem.DEVICE_OUT_USB_ACCESSORY:
+ aidl.type = AudioDeviceType.OUT_ACCESSORY;
+ aidl.connection = AudioDeviceDescription.CONNECTION_USB;
+ break;
+ case AudioSystem.DEVICE_IN_USB_DEVICE:
+ aidl.type = AudioDeviceType.IN_DEVICE;
+ aidl.connection = AudioDeviceDescription.CONNECTION_USB;
+ break;
+ case AudioSystem.DEVICE_OUT_USB_DEVICE:
+ aidl.type = AudioDeviceType.OUT_DEVICE;
+ aidl.connection = AudioDeviceDescription.CONNECTION_USB;
+ break;
+ case AudioSystem.DEVICE_IN_FM_TUNER:
+ aidl.type = AudioDeviceType.IN_FM_TUNER;
+ break;
+ case AudioSystem.DEVICE_OUT_FM:
+ aidl.type = AudioDeviceType.OUT_FM;
+ break;
+ case AudioSystem.DEVICE_IN_LINE:
+ aidl.type = AudioDeviceType.IN_DEVICE;
+ aidl.connection = AudioDeviceDescription.CONNECTION_ANALOG;
+ break;
+ case AudioSystem.DEVICE_OUT_LINE:
+ aidl.type = AudioDeviceType.OUT_DEVICE;
+ aidl.connection = AudioDeviceDescription.CONNECTION_ANALOG;
+ break;
+ case AudioSystem.DEVICE_IN_SPDIF:
+ aidl.type = AudioDeviceType.IN_DEVICE;
+ aidl.connection = AudioDeviceDescription.CONNECTION_SPDIF;
+ break;
+ case AudioSystem.DEVICE_OUT_SPDIF:
+ aidl.type = AudioDeviceType.OUT_DEVICE;
+ aidl.connection = AudioDeviceDescription.CONNECTION_SPDIF;
+ break;
+ case AudioSystem.DEVICE_IN_BLUETOOTH_A2DP:
+ aidl.type = AudioDeviceType.IN_DEVICE;
+ aidl.connection = AudioDeviceDescription.CONNECTION_BT_A2DP;
+ break;
+ case AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP:
+ aidl.type = AudioDeviceType.OUT_DEVICE;
+ aidl.connection = AudioDeviceDescription.CONNECTION_BT_A2DP;
+ break;
+ case AudioSystem.DEVICE_IN_IP:
+ aidl.type = AudioDeviceType.IN_DEVICE;
+ aidl.connection = AudioDeviceDescription.CONNECTION_IP_V4;
+ break;
+ case AudioSystem.DEVICE_OUT_IP:
+ aidl.type = AudioDeviceType.OUT_DEVICE;
+ aidl.connection = AudioDeviceDescription.CONNECTION_IP_V4;
+ break;
+ case AudioSystem.DEVICE_IN_BUS:
+ aidl.type = AudioDeviceType.IN_DEVICE;
+ aidl.connection = AudioDeviceDescription.CONNECTION_BUS;
+ break;
+ case AudioSystem.DEVICE_OUT_BUS:
+ aidl.type = AudioDeviceType.OUT_DEVICE;
+ aidl.connection = AudioDeviceDescription.CONNECTION_BUS;
+ break;
+ case AudioSystem.DEVICE_IN_PROXY:
+ aidl.type = AudioDeviceType.IN_AFE_PROXY;
+ break;
+ case AudioSystem.DEVICE_OUT_PROXY:
+ aidl.type = AudioDeviceType.OUT_AFE_PROXY;
+ break;
+ case AudioSystem.DEVICE_IN_USB_HEADSET:
+ aidl.type = AudioDeviceType.IN_HEADSET;
+ aidl.connection = AudioDeviceDescription.CONNECTION_USB;
+ break;
+ case AudioSystem.DEVICE_OUT_USB_HEADSET:
+ aidl.type = AudioDeviceType.OUT_HEADSET;
+ aidl.connection = AudioDeviceDescription.CONNECTION_USB;
+ break;
+ case AudioSystem.DEVICE_IN_HDMI_ARC:
+ aidl.type = AudioDeviceType.IN_DEVICE;
+ aidl.connection = AudioDeviceDescription.CONNECTION_HDMI_ARC;
+ break;
+ case AudioSystem.DEVICE_OUT_HDMI_ARC:
+ aidl.type = AudioDeviceType.OUT_DEVICE;
+ aidl.connection = AudioDeviceDescription.CONNECTION_HDMI_ARC;
+ break;
+ case AudioSystem.DEVICE_IN_HDMI_EARC:
+ aidl.type = AudioDeviceType.IN_DEVICE;
+ aidl.connection = AudioDeviceDescription.CONNECTION_HDMI_EARC;
+ break;
+ case AudioSystem.DEVICE_OUT_HDMI_EARC:
+ aidl.type = AudioDeviceType.OUT_DEVICE;
+ aidl.connection = AudioDeviceDescription.CONNECTION_HDMI_EARC;
+ break;
+ case AudioSystem.DEVICE_IN_BLE_HEADSET:
+ aidl.type = AudioDeviceType.IN_HEADSET;
+ aidl.connection = AudioDeviceDescription.CONNECTION_BT_LE;
+ break;
+ case AudioSystem.DEVICE_OUT_BLE_HEADSET:
+ aidl.type = AudioDeviceType.OUT_HEADSET;
+ aidl.connection = AudioDeviceDescription.CONNECTION_BT_LE;
+ break;
+ case AudioSystem.DEVICE_IN_DEFAULT:
+ aidl.type = AudioDeviceType.IN_DEFAULT;
+ break;
+ case AudioSystem.DEVICE_OUT_DEFAULT:
+ aidl.type = AudioDeviceType.OUT_DEFAULT;
+ break;
+ default:
+ aidl.type = AudioDeviceType.NONE;
+ }
+ return aidl;
+ }
+
private static native int aidl2legacy_AudioChannelLayout_Parcel_audio_channel_mask_t(
Parcel aidl, boolean isInput);
private static native Parcel legacy2aidl_audio_channel_mask_t_AudioChannelLayout_Parcel(
diff --git a/media/tests/aidltests/src/com/android/media/AidlConversionUnitTests.java b/media/tests/aidltests/src/com/android/media/AidlConversionUnitTests.java
index 414de89f8218..09573909c288 100644
--- a/media/tests/aidltests/src/com/android/media/AidlConversionUnitTests.java
+++ b/media/tests/aidltests/src/com/android/media/AidlConversionUnitTests.java
@@ -16,8 +16,18 @@
package android.media.audio.common;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertThrows;
+import static org.junit.Assert.assertTrue;
+
import android.media.AudioAttributes;
+import android.media.AudioDescriptor;
+import android.media.AudioDeviceAttributes;
+import android.media.AudioDeviceInfo;
import android.media.AudioFormat;
+import android.media.AudioProfile;
import android.media.AudioSystem;
import android.media.AudioTrack;
import android.media.MediaFormat;
@@ -25,11 +35,12 @@ import android.platform.test.annotations.Presubmit;
import androidx.test.runner.AndroidJUnit4;
-import static org.junit.Assert.*;
-
import org.junit.Test;
import org.junit.runner.RunWith;
+import java.util.ArrayList;
+import java.util.Arrays;
+
/**
* Unit tests for AidlConversion utilities.
*
@@ -417,10 +428,102 @@ public final class AidlConversionUnitTests {
() -> AidlConversion.legacy2aidl_audio_usage_t_AudioUsage(sInvalidValue));
}
+ @Test
+ public void testAudioDescriptorConversion_Default() {
+ ExtraAudioDescriptor aidl = createDefaultDescriptor();
+ AudioDescriptor audioDescriptor =
+ AidlConversion.aidl2api_ExtraAudioDescriptor_AudioDescriptor(aidl);
+ assertEquals(AudioDescriptor.STANDARD_NONE, audioDescriptor.getStandard());
+ assertEquals(
+ AudioProfile.AUDIO_ENCAPSULATION_TYPE_NONE, audioDescriptor.getEncapsulationType());
+ assertTrue(Arrays.equals(new byte[]{}, audioDescriptor.getDescriptor()));
+
+ ExtraAudioDescriptor reconstructedExtraDescriptor =
+ AidlConversion.api2aidl_AudioDescriptor_ExtraAudioDescriptor(audioDescriptor);
+ assertEquals(aidl, reconstructedExtraDescriptor);
+ }
+
+ @Test
+ public void testAudioDescriptorConversion() {
+ ExtraAudioDescriptor aidl = createEncapsulationDescriptor(new byte[]{0x05, 0x18, 0x4A});
+ AudioDescriptor audioDescriptor =
+ AidlConversion.aidl2api_ExtraAudioDescriptor_AudioDescriptor(aidl);
+ assertEquals(AudioDescriptor.STANDARD_EDID, audioDescriptor.getStandard());
+ assertEquals(AudioProfile.AUDIO_ENCAPSULATION_TYPE_IEC61937,
+ audioDescriptor.getEncapsulationType());
+ assertTrue(Arrays.equals(new byte[]{0x05, 0x18, 0x4A}, audioDescriptor.getDescriptor()));
+
+ ExtraAudioDescriptor reconstructedExtraDescriptor =
+ AidlConversion.api2aidl_AudioDescriptor_ExtraAudioDescriptor(audioDescriptor);
+ assertEquals(aidl, reconstructedExtraDescriptor);
+ }
+
+ @Test
+ public void testAudioDeviceAttributesConversion_Default() {
+ AudioDeviceAttributes attributes =
+ new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_DEFAULT, "myAddress");
+ AudioPort port = AidlConversion.api2aidl_AudioDeviceAttributes_AudioPort(attributes);
+ assertEquals("", port.name);
+ assertEquals(0, port.extraAudioDescriptors.length);
+ assertEquals("myAddress", port.ext.getDevice().device.address.getId());
+ assertEquals("", port.ext.getDevice().device.type.connection);
+ assertEquals(AudioDeviceType.OUT_DEFAULT, port.ext.getDevice().device.type.type);
+ }
+
+ @Test
+ public void testAudioDeviceAttributesConversion() {
+ AudioDescriptor audioDescriptor1 =
+ AidlConversion.aidl2api_ExtraAudioDescriptor_AudioDescriptor(
+ createEncapsulationDescriptor(new byte[]{0x05, 0x18, 0x4A}));
+
+ AudioDescriptor audioDescriptor2 =
+ AidlConversion.aidl2api_ExtraAudioDescriptor_AudioDescriptor(
+ createDefaultDescriptor());
+
+ AudioDeviceAttributes attributes =
+ new AudioDeviceAttributes(AudioDeviceAttributes.ROLE_OUTPUT,
+ AudioDeviceInfo.TYPE_HDMI_ARC, "myAddress", "myName", new ArrayList<>(),
+ new ArrayList<>(Arrays.asList(audioDescriptor1, audioDescriptor2)));
+ AudioPort port = AidlConversion.api2aidl_AudioDeviceAttributes_AudioPort(
+ attributes);
+ assertEquals("myName", port.name);
+ assertEquals(2, port.extraAudioDescriptors.length);
+ assertEquals(AudioStandard.EDID, port.extraAudioDescriptors[0].standard);
+ assertEquals(AudioEncapsulationType.IEC61937,
+ port.extraAudioDescriptors[0].encapsulationType);
+ assertTrue(Arrays.equals(new byte[]{0x05, 0x18, 0x4A},
+ port.extraAudioDescriptors[0].audioDescriptor));
+ assertEquals(AudioStandard.NONE, port.extraAudioDescriptors[1].standard);
+ assertEquals(AudioEncapsulationType.NONE,
+ port.extraAudioDescriptors[1].encapsulationType);
+ assertTrue(Arrays.equals(new byte[]{},
+ port.extraAudioDescriptors[1].audioDescriptor));
+ assertEquals("myAddress", port.ext.getDevice().device.address.getId());
+ assertEquals(AudioDeviceDescription.CONNECTION_HDMI_ARC,
+ port.ext.getDevice().device.type.connection);
+ assertEquals(AudioDeviceType.OUT_DEVICE, port.ext.getDevice().device.type.type);
+ }
+
private static AudioFormatDescription createPcm16FormatAidl() {
final AudioFormatDescription aidl = new AudioFormatDescription();
aidl.type = AudioFormatType.PCM;
aidl.pcm = PcmType.INT_16_BIT;
return aidl;
}
+
+ private static ExtraAudioDescriptor createDefaultDescriptor() {
+ ExtraAudioDescriptor extraDescriptor = new ExtraAudioDescriptor();
+ extraDescriptor.standard = AudioStandard.NONE;
+ extraDescriptor.encapsulationType = AudioEncapsulationType.NONE;
+ extraDescriptor.audioDescriptor = new byte[]{};
+ return extraDescriptor;
+ }
+
+ private static ExtraAudioDescriptor createEncapsulationDescriptor(byte[] audioDescriptor) {
+ ExtraAudioDescriptor extraDescriptor = new ExtraAudioDescriptor();
+ extraDescriptor.standard = AudioStandard.EDID;
+ extraDescriptor.encapsulationType = AudioEncapsulationType.IEC61937;
+ extraDescriptor.audioDescriptor = audioDescriptor;
+ return extraDescriptor;
+ }
}
diff --git a/services/core/java/com/android/server/audio/AudioDeviceBroker.java b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
index 2fcdd6145a64..b855763299ae 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceBroker.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
@@ -499,12 +499,11 @@ import java.util.concurrent.atomic.AtomicBoolean;
}
}
- /*package*/ void setWiredDeviceConnectionState(int type,
- @AudioService.ConnectionState int state, String address, String name,
- String caller) {
+ /*package*/ void setWiredDeviceConnectionState(AudioDeviceAttributes attributes,
+ @AudioService.ConnectionState int state, String caller) {
//TODO move logging here just like in setBluetooth* methods
synchronized (mDeviceStateLock) {
- mDeviceInventory.setWiredDeviceConnectionState(type, state, address, name, caller);
+ mDeviceInventory.setWiredDeviceConnectionState(attributes, state, caller);
}
}
@@ -1012,11 +1011,9 @@ import java.util.concurrent.atomic.AtomicBoolean;
}
}
- /*package*/ boolean handleDeviceConnection(boolean connect, int device, String address,
- String deviceName) {
+ /*package*/ boolean handleDeviceConnection(AudioDeviceAttributes attributes, boolean connect) {
synchronized (mDeviceStateLock) {
- return mDeviceInventory.handleDeviceConnection(connect, device, address, deviceName,
- false /*for test*/);
+ return mDeviceInventory.handleDeviceConnection(attributes, connect, false /*for test*/);
}
}
diff --git a/services/core/java/com/android/server/audio/AudioDeviceInventory.java b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
index 0961fcb31ace..43860161bb1c 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceInventory.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
@@ -219,19 +219,15 @@ public class AudioDeviceInventory {
* A class just for packaging up a set of connection parameters.
*/
/*package*/ class WiredDeviceConnectionState {
- public final int mType;
+ public final AudioDeviceAttributes mAttributes;
public final @AudioService.ConnectionState int mState;
- public final String mAddress;
- public final String mName;
public final String mCaller;
public boolean mForTest = false;
- /*package*/ WiredDeviceConnectionState(int type, @AudioService.ConnectionState int state,
- String address, String name, String caller) {
- mType = type;
+ /*package*/ WiredDeviceConnectionState(AudioDeviceAttributes attributes,
+ @AudioService.ConnectionState int state, String caller) {
+ mAttributes = attributes;
mState = state;
- mAddress = address;
- mName = name;
mCaller = caller;
}
}
@@ -269,11 +265,10 @@ public class AudioDeviceInventory {
synchronized (mDevicesLock) {
//TODO iterate on mApmConnectedDevices instead once it handles all device types
for (DeviceInfo di : mConnectedDevices.values()) {
- mAudioSystem.setDeviceConnectionState(
- di.mDeviceType,
- AudioSystem.DEVICE_STATE_AVAILABLE,
+ mAudioSystem.setDeviceConnectionState(new AudioDeviceAttributes(di.mDeviceType,
di.mDeviceAddress,
- di.mDeviceName,
+ di.mDeviceName),
+ AudioSystem.DEVICE_STATE_AVAILABLE,
di.mDeviceCodecFormat);
}
}
@@ -508,41 +503,45 @@ public class AudioDeviceInventory {
/*package*/ void onSetWiredDeviceConnectionState(
AudioDeviceInventory.WiredDeviceConnectionState wdcs) {
+ int type = wdcs.mAttributes.getInternalType();
+
AudioService.sDeviceLogger.log(new AudioServiceEvents.WiredDevConnectEvent(wdcs));
MediaMetrics.Item mmi = new MediaMetrics.Item(mMetricsId
+ "onSetWiredDeviceConnectionState")
- .set(MediaMetrics.Property.ADDRESS, wdcs.mAddress)
- .set(MediaMetrics.Property.DEVICE, AudioSystem.getDeviceName(wdcs.mType))
+ .set(MediaMetrics.Property.ADDRESS, wdcs.mAttributes.getAddress())
+ .set(MediaMetrics.Property.DEVICE,
+ AudioSystem.getDeviceName(type))
.set(MediaMetrics.Property.STATE,
wdcs.mState == AudioService.CONNECTION_STATE_DISCONNECTED
? MediaMetrics.Value.DISCONNECTED : MediaMetrics.Value.CONNECTED);
synchronized (mDevicesLock) {
if ((wdcs.mState == AudioService.CONNECTION_STATE_DISCONNECTED)
- && DEVICE_OVERRIDE_A2DP_ROUTE_ON_PLUG_SET.contains(wdcs.mType)) {
+ && DEVICE_OVERRIDE_A2DP_ROUTE_ON_PLUG_SET.contains(type)) {
mDeviceBroker.setBluetoothA2dpOnInt(true, false /*fromA2dp*/,
"onSetWiredDeviceConnectionState state DISCONNECTED");
}
- if (!handleDeviceConnection(wdcs.mState == AudioService.CONNECTION_STATE_CONNECTED,
- wdcs.mType, wdcs.mAddress, wdcs.mName, wdcs.mForTest)) {
+ if (!handleDeviceConnection(wdcs.mAttributes,
+ wdcs.mState == AudioService.CONNECTION_STATE_CONNECTED, wdcs.mForTest)) {
// change of connection state failed, bailout
mmi.set(MediaMetrics.Property.EARLY_RETURN, "change of connection state failed")
.record();
return;
}
if (wdcs.mState != AudioService.CONNECTION_STATE_DISCONNECTED) {
- if (DEVICE_OVERRIDE_A2DP_ROUTE_ON_PLUG_SET.contains(wdcs.mType)) {
+ if (DEVICE_OVERRIDE_A2DP_ROUTE_ON_PLUG_SET.contains(type)) {
mDeviceBroker.setBluetoothA2dpOnInt(false, false /*fromA2dp*/,
"onSetWiredDeviceConnectionState state not DISCONNECTED");
}
- mDeviceBroker.checkMusicActive(wdcs.mType, wdcs.mCaller);
+ mDeviceBroker.checkMusicActive(type, wdcs.mCaller);
}
- if (wdcs.mType == AudioSystem.DEVICE_OUT_HDMI) {
+ if (type == AudioSystem.DEVICE_OUT_HDMI) {
mDeviceBroker.checkVolumeCecOnHdmiConnection(wdcs.mState, wdcs.mCaller);
}
- sendDeviceConnectionIntent(wdcs.mType, wdcs.mState, wdcs.mAddress, wdcs.mName);
- updateAudioRoutes(wdcs.mType, wdcs.mState);
+ sendDeviceConnectionIntent(type, wdcs.mState,
+ wdcs.mAttributes.getAddress(), wdcs.mAttributes.getName());
+ updateAudioRoutes(type, wdcs.mState);
}
mmi.record();
}
@@ -561,12 +560,12 @@ public class AudioDeviceInventory {
return;
}
// Toggle HDMI to retrigger broadcast with proper formats.
- setWiredDeviceConnectionState(AudioSystem.DEVICE_OUT_HDMI,
- AudioSystem.DEVICE_STATE_UNAVAILABLE, "", "",
- "android"); // disconnect
- setWiredDeviceConnectionState(AudioSystem.DEVICE_OUT_HDMI,
- AudioSystem.DEVICE_STATE_AVAILABLE, "", "",
- "android"); // reconnect
+ setWiredDeviceConnectionState(
+ new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_HDMI, ""),
+ AudioSystem.DEVICE_STATE_UNAVAILABLE, "android"); // disconnect
+ setWiredDeviceConnectionState(
+ new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_HDMI, ""),
+ AudioSystem.DEVICE_STATE_AVAILABLE, "android"); // reconnect
}
mmi.record();
}
@@ -696,16 +695,17 @@ public class AudioDeviceInventory {
/**
* Implements the communication with AudioSystem to (dis)connect a device in the native layers
+ * @param attributes the attributes of the device
* @param connect true if connection
- * @param device the device type
- * @param address the address of the device
- * @param deviceName human-readable name of device
* @param isForTesting if true, not calling AudioSystem for the connection as this is
* just for testing
* @return false if an error was reported by AudioSystem
*/
- /*package*/ boolean handleDeviceConnection(boolean connect, int device, String address,
- String deviceName, boolean isForTesting) {
+ /*package*/ boolean handleDeviceConnection(AudioDeviceAttributes attributes, boolean connect,
+ boolean isForTesting) {
+ int device = attributes.getInternalType();
+ String address = attributes.getAddress();
+ String deviceName = attributes.getName();
if (AudioService.DEBUG_DEVICES) {
Slog.i(TAG, "handleDeviceConnection(" + connect + " dev:"
+ Integer.toHexString(device) + " address:" + address
@@ -732,9 +732,8 @@ public class AudioDeviceInventory {
if (isForTesting) {
res = AudioSystem.AUDIO_STATUS_OK;
} else {
- res = mAudioSystem.setDeviceConnectionState(device,
- AudioSystem.DEVICE_STATE_AVAILABLE, address, deviceName,
- AudioSystem.AUDIO_FORMAT_DEFAULT);
+ res = mAudioSystem.setDeviceConnectionState(attributes,
+ AudioSystem.DEVICE_STATE_AVAILABLE, AudioSystem.AUDIO_FORMAT_DEFAULT);
}
if (res != AudioSystem.AUDIO_STATUS_OK) {
final String reason = "not connecting device 0x" + Integer.toHexString(device)
@@ -751,9 +750,8 @@ public class AudioDeviceInventory {
mmi.set(MediaMetrics.Property.STATE, MediaMetrics.Value.CONNECTED).record();
return true;
} else if (!connect && isConnected) {
- mAudioSystem.setDeviceConnectionState(device,
- AudioSystem.DEVICE_STATE_UNAVAILABLE, address, deviceName,
- AudioSystem.AUDIO_FORMAT_DEFAULT);
+ mAudioSystem.setDeviceConnectionState(attributes,
+ AudioSystem.DEVICE_STATE_UNAVAILABLE, AudioSystem.AUDIO_FORMAT_DEFAULT);
// always remove even if disconnection failed
mConnectedDevices.remove(deviceKey);
mmi.set(MediaMetrics.Property.STATE, MediaMetrics.Value.CONNECTED).record();
@@ -930,13 +928,13 @@ public class AudioDeviceInventory {
return delay;
}
- /*package*/ int setWiredDeviceConnectionState(int type, @AudioService.ConnectionState int state,
- String address, String name, String caller) {
+ /*package*/ int setWiredDeviceConnectionState(AudioDeviceAttributes attributes,
+ @AudioService.ConnectionState int state, String caller) {
synchronized (mDevicesLock) {
- int delay = checkSendBecomingNoisyIntentInt(type, state, AudioSystem.DEVICE_NONE);
+ int delay = checkSendBecomingNoisyIntentInt(
+ attributes.getInternalType(), state, AudioSystem.DEVICE_NONE);
mDeviceBroker.postSetWiredDeviceConnectionState(
- new WiredDeviceConnectionState(type, state, address, name, caller),
- delay);
+ new WiredDeviceConnectionState(attributes, state, caller), delay);
return delay;
}
}
@@ -944,8 +942,7 @@ public class AudioDeviceInventory {
/*package*/ void setTestDeviceConnectionState(@NonNull AudioDeviceAttributes device,
@AudioService.ConnectionState int state) {
final WiredDeviceConnectionState connection = new WiredDeviceConnectionState(
- device.getInternalType(), state, device.getAddress(),
- "test device", "com.android.server.audio");
+ device, state, "com.android.server.audio");
connection.mForTest = true;
onSetWiredDeviceConnectionState(connection);
}
@@ -961,8 +958,9 @@ public class AudioDeviceInventory {
mDeviceBroker.setBluetoothA2dpOnInt(true, true /*fromA2dp*/, eventSource);
// at this point there could be another A2DP device already connected in APM, but it
// doesn't matter as this new one will overwrite the previous one
- final int res = mAudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP,
- AudioSystem.DEVICE_STATE_AVAILABLE, address, name, a2dpCodec);
+ final int res = mAudioSystem.setDeviceConnectionState(new AudioDeviceAttributes(
+ AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, address, name),
+ AudioSystem.DEVICE_STATE_AVAILABLE, a2dpCodec);
// TODO: log in MediaMetrics once distinction between connection failure and
// double connection is made.
@@ -1019,8 +1017,9 @@ public class AudioDeviceInventory {
// device to remove was visible by APM, update APM
mDeviceBroker.clearAvrcpAbsoluteVolumeSupported();
- final int res = mAudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP,
- AudioSystem.DEVICE_STATE_UNAVAILABLE, address, "", a2dpCodec);
+ final int res = mAudioSystem.setDeviceConnectionState(new AudioDeviceAttributes(
+ AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, address),
+ AudioSystem.DEVICE_STATE_UNAVAILABLE, a2dpCodec);
if (res != AudioSystem.AUDIO_STATUS_OK) {
AudioService.sDeviceLogger.log(new AudioEventLogger.StringEvent(
@@ -1058,8 +1057,9 @@ public class AudioDeviceInventory {
@GuardedBy("mDevicesLock")
private void makeA2dpSrcAvailable(String address) {
- mAudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP,
- AudioSystem.DEVICE_STATE_AVAILABLE, address, "",
+ mAudioSystem.setDeviceConnectionState(new AudioDeviceAttributes(
+ AudioSystem.DEVICE_IN_BLUETOOTH_A2DP, address),
+ AudioSystem.DEVICE_STATE_AVAILABLE,
AudioSystem.AUDIO_FORMAT_DEFAULT);
mConnectedDevices.put(
DeviceInfo.makeDeviceListKey(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP, address),
@@ -1069,8 +1069,9 @@ public class AudioDeviceInventory {
@GuardedBy("mDevicesLock")
private void makeA2dpSrcUnavailable(String address) {
- mAudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP,
- AudioSystem.DEVICE_STATE_UNAVAILABLE, address, "",
+ mAudioSystem.setDeviceConnectionState(new AudioDeviceAttributes(
+ AudioSystem.DEVICE_IN_BLUETOOTH_A2DP, address),
+ AudioSystem.DEVICE_STATE_UNAVAILABLE,
AudioSystem.AUDIO_FORMAT_DEFAULT);
mConnectedDevices.remove(
DeviceInfo.makeDeviceListKey(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP, address));
@@ -1083,8 +1084,9 @@ public class AudioDeviceInventory {
AudioSystem.DEVICE_OUT_HEARING_AID);
mDeviceBroker.postSetHearingAidVolumeIndex(hearingAidVolIndex, streamType);
- mAudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_HEARING_AID,
- AudioSystem.DEVICE_STATE_AVAILABLE, address, name,
+ mAudioSystem.setDeviceConnectionState(new AudioDeviceAttributes(
+ AudioSystem.DEVICE_OUT_HEARING_AID, address, name),
+ AudioSystem.DEVICE_STATE_AVAILABLE,
AudioSystem.AUDIO_FORMAT_DEFAULT);
mConnectedDevices.put(
DeviceInfo.makeDeviceListKey(AudioSystem.DEVICE_OUT_HEARING_AID, address),
@@ -1106,8 +1108,9 @@ public class AudioDeviceInventory {
@GuardedBy("mDevicesLock")
private void makeHearingAidDeviceUnavailable(String address) {
- mAudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_HEARING_AID,
- AudioSystem.DEVICE_STATE_UNAVAILABLE, address, "",
+ mAudioSystem.setDeviceConnectionState(new AudioDeviceAttributes(
+ AudioSystem.DEVICE_OUT_HEARING_AID, address),
+ AudioSystem.DEVICE_STATE_UNAVAILABLE,
AudioSystem.AUDIO_FORMAT_DEFAULT);
mConnectedDevices.remove(
DeviceInfo.makeDeviceListKey(AudioSystem.DEVICE_OUT_HEARING_AID, address));
@@ -1124,14 +1127,14 @@ public class AudioDeviceInventory {
private void makeLeAudioDeviceAvailable(String address, String name, int streamType, int device,
String eventSource) {
if (device != AudioSystem.DEVICE_NONE) {
-
/* Audio Policy sees Le Audio similar to A2DP. Let's make sure
* AUDIO_POLICY_FORCE_NO_BT_A2DP is not set
*/
mDeviceBroker.setBluetoothA2dpOnInt(true, false /*fromA2dp*/, eventSource);
- AudioSystem.setDeviceConnectionState(device, AudioSystem.DEVICE_STATE_AVAILABLE,
- address, name, AudioSystem.AUDIO_FORMAT_DEFAULT);
+ AudioSystem.setDeviceConnectionState(new AudioDeviceAttributes(device, address, name),
+ AudioSystem.DEVICE_STATE_AVAILABLE,
+ AudioSystem.AUDIO_FORMAT_DEFAULT);
mConnectedDevices.put(DeviceInfo.makeDeviceListKey(device, address),
new DeviceInfo(device, name, address, AudioSystem.AUDIO_FORMAT_DEFAULT));
mDeviceBroker.postAccessoryPlugMediaUnmute(device);
@@ -1152,8 +1155,9 @@ public class AudioDeviceInventory {
@GuardedBy("mDevicesLock")
private void makeLeAudioDeviceUnavailable(String address, int device) {
if (device != AudioSystem.DEVICE_NONE) {
- AudioSystem.setDeviceConnectionState(device, AudioSystem.DEVICE_STATE_UNAVAILABLE,
- address, "", AudioSystem.AUDIO_FORMAT_DEFAULT);
+ AudioSystem.setDeviceConnectionState(new AudioDeviceAttributes(device, address),
+ AudioSystem.DEVICE_STATE_UNAVAILABLE,
+ AudioSystem.AUDIO_FORMAT_DEFAULT);
mConnectedDevices.remove(DeviceInfo.makeDeviceListKey(device, address));
}
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 346ae0fed2e1..c51e967bd859 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -6377,23 +6377,23 @@ public class AudioService extends IAudioService.Stub
/**
* see AudioManager.setWiredDeviceConnectionState()
*/
- public void setWiredDeviceConnectionState(int type,
- @ConnectionState int state, String address, String name,
- String caller) {
+ public void setWiredDeviceConnectionState(AudioDeviceAttributes attributes,
+ @ConnectionState int state, String caller) {
enforceModifyAudioRoutingPermission();
if (state != CONNECTION_STATE_CONNECTED
&& state != CONNECTION_STATE_DISCONNECTED) {
throw new IllegalArgumentException("Invalid state " + state);
}
new MediaMetrics.Item(mMetricsId + "setWiredDeviceConnectionState")
- .set(MediaMetrics.Property.ADDRESS, address)
+ .set(MediaMetrics.Property.ADDRESS, attributes.getAddress())
.set(MediaMetrics.Property.CLIENT_NAME, caller)
- .set(MediaMetrics.Property.DEVICE, AudioSystem.getDeviceName(type))
- .set(MediaMetrics.Property.NAME, name)
+ .set(MediaMetrics.Property.DEVICE,
+ AudioSystem.getDeviceName(attributes.getInternalType()))
+ .set(MediaMetrics.Property.NAME, attributes.getName())
.set(MediaMetrics.Property.STATE,
state == CONNECTION_STATE_CONNECTED ? "connected" : "disconnected")
.record();
- mDeviceBroker.setWiredDeviceConnectionState(type, state, address, name, caller);
+ mDeviceBroker.setWiredDeviceConnectionState(attributes, state, caller);
}
/** @see AudioManager#setTestDeviceConnectionState(AudioDeviceAttributes, boolean) */
diff --git a/services/core/java/com/android/server/audio/AudioServiceEvents.java b/services/core/java/com/android/server/audio/AudioServiceEvents.java
index 3137fa5784d2..3225274a8a9b 100644
--- a/services/core/java/com/android/server/audio/AudioServiceEvents.java
+++ b/services/core/java/com/android/server/audio/AudioServiceEvents.java
@@ -116,10 +116,11 @@ public class AudioServiceEvents {
@Override
public String eventToString() {
return new StringBuilder("setWiredDeviceConnectionState(")
- .append(" type:").append(Integer.toHexString(mState.mType))
+ .append(" type:").append(
+ Integer.toHexString(mState.mAttributes.getInternalType()))
.append(" state:").append(AudioSystem.deviceStateToString(mState.mState))
- .append(" addr:").append(mState.mAddress)
- .append(" name:").append(mState.mName)
+ .append(" addr:").append(mState.mAttributes.getAddress())
+ .append(" name:").append(mState.mAttributes.getName())
.append(") from ").append(mState.mCaller).toString();
}
}
diff --git a/services/core/java/com/android/server/audio/AudioSystemAdapter.java b/services/core/java/com/android/server/audio/AudioSystemAdapter.java
index a2ba76b6fd6a..f572261c09e5 100644
--- a/services/core/java/com/android/server/audio/AudioSystemAdapter.java
+++ b/services/core/java/com/android/server/audio/AudioSystemAdapter.java
@@ -258,19 +258,16 @@ public class AudioSystemAdapter implements AudioSystem.RoutingUpdateCallback {
}
/**
- * Same as {@link AudioSystem#setDeviceConnectionState(int, int, String, String, int)}
- * @param device
+ * Same as {@link AudioSystem#setDeviceConnectionState(AudioDeviceAttributes, int, int)}
+ * @param attributes
* @param state
- * @param deviceAddress
- * @param deviceName
* @param codecFormat
* @return
*/
- public int setDeviceConnectionState(int device, int state, String deviceAddress,
- String deviceName, int codecFormat) {
+ public int setDeviceConnectionState(AudioDeviceAttributes attributes, int state,
+ int codecFormat) {
invalidateRoutingCache();
- return AudioSystem.setDeviceConnectionState(device, state, deviceAddress, deviceName,
- codecFormat);
+ return AudioSystem.setDeviceConnectionState(attributes, state, codecFormat);
}
/**
diff --git a/services/core/java/com/android/server/audio/BtHelper.java b/services/core/java/com/android/server/audio/BtHelper.java
index 6ec983620698..30b5c3c16069 100644
--- a/services/core/java/com/android/server/audio/BtHelper.java
+++ b/services/core/java/com/android/server/audio/BtHelper.java
@@ -586,8 +586,9 @@ public class BtHelper {
String btDeviceName = getName(btDevice);
boolean result = false;
if (isActive) {
- result |= mDeviceBroker.handleDeviceConnection(isActive, audioDevice.getInternalType(),
- audioDevice.getAddress(), btDeviceName);
+ result |= mDeviceBroker.handleDeviceConnection(new AudioDeviceAttributes(
+ audioDevice.getInternalType(), audioDevice.getAddress(), btDeviceName),
+ isActive);
} else {
int[] outDeviceTypes = {
AudioSystem.DEVICE_OUT_BLUETOOTH_SCO,
@@ -595,13 +596,15 @@ public class BtHelper {
AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_CARKIT
};
for (int outDeviceType : outDeviceTypes) {
- result |= mDeviceBroker.handleDeviceConnection(
- isActive, outDeviceType, audioDevice.getAddress(), btDeviceName);
+ result |= mDeviceBroker.handleDeviceConnection(new AudioDeviceAttributes(
+ outDeviceType, audioDevice.getAddress(), btDeviceName),
+ isActive);
}
}
// handleDeviceConnection() && result to make sure the method get executed
- result = mDeviceBroker.handleDeviceConnection(
- isActive, inDevice, audioDevice.getAddress(), btDeviceName) && result;
+ result = mDeviceBroker.handleDeviceConnection(new AudioDeviceAttributes(
+ inDevice, audioDevice.getAddress(), btDeviceName),
+ isActive) && result;
return result;
}
diff --git a/services/tests/servicestests/src/com/android/server/audio/AudioDeviceBrokerTest.java b/services/tests/servicestests/src/com/android/server/audio/AudioDeviceBrokerTest.java
index 9e1445cf589d..2294a60ba4bc 100644
--- a/services/tests/servicestests/src/com/android/server/audio/AudioDeviceBrokerTest.java
+++ b/services/tests/servicestests/src/com/android/server/audio/AudioDeviceBrokerTest.java
@@ -28,6 +28,7 @@ import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.content.Intent;
+import android.media.AudioDeviceAttributes;
import android.media.AudioManager;
import android.media.AudioSystem;
import android.media.BtProfileConnectionInfo;
@@ -186,8 +187,9 @@ public class AudioDeviceBrokerTest {
doNothing().when(mSpySystemServer).broadcastStickyIntentToCurrentProfileGroup(
any(Intent.class));
- mSpyDevInventory.setWiredDeviceConnectionState(AudioSystem.DEVICE_OUT_WIRED_HEADSET,
- AudioService.CONNECTION_STATE_CONNECTED, address, name, caller);
+ mSpyDevInventory.setWiredDeviceConnectionState(new AudioDeviceAttributes(
+ AudioSystem.DEVICE_OUT_WIRED_HEADSET, address, name),
+ AudioService.CONNECTION_STATE_CONNECTED, caller);
Thread.sleep(MAX_MESSAGE_HANDLING_DELAY_MS);
// Verify that the sticky intent is broadcasted
@@ -246,11 +248,11 @@ public class AudioDeviceBrokerTest {
*/
private void checkSingleSystemConnection(BluetoothDevice btDevice) throws Exception {
final String expectedName = btDevice.getName() == null ? "" : btDevice.getName();
+ AudioDeviceAttributes expected = new AudioDeviceAttributes(
+ AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, btDevice.getAddress(), expectedName);
verify(mSpyAudioSystem, times(1)).setDeviceConnectionState(
- ArgumentMatchers.eq(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP),
+ ArgumentMatchers.argThat(x -> x.equalTypeAddress(expected)),
ArgumentMatchers.eq(AudioSystem.DEVICE_STATE_AVAILABLE),
- ArgumentMatchers.eq(btDevice.getAddress()),
- ArgumentMatchers.eq(expectedName),
anyInt() /*codec*/);
}
}
diff --git a/services/tests/servicestests/src/com/android/server/audio/NoOpAudioSystemAdapter.java b/services/tests/servicestests/src/com/android/server/audio/NoOpAudioSystemAdapter.java
index 8d706cb960e9..1f355b096335 100644
--- a/services/tests/servicestests/src/com/android/server/audio/NoOpAudioSystemAdapter.java
+++ b/services/tests/servicestests/src/com/android/server/audio/NoOpAudioSystemAdapter.java
@@ -48,11 +48,10 @@ public class NoOpAudioSystemAdapter extends AudioSystemAdapter {
//-----------------------------------------------------------------
// Overrides of AudioSystemAdapter
@Override
- public int setDeviceConnectionState(int device, int state, String deviceAddress,
- String deviceName, int codecFormat) {
- Log.i(TAG, String.format("setDeviceConnectionState(0x%s, %d, %s, %s, 0x%s",
- Integer.toHexString(device), state, deviceAddress, deviceName,
- Integer.toHexString(codecFormat)));
+ public int setDeviceConnectionState(AudioDeviceAttributes attributes, int state,
+ int codecFormat) {
+ Log.i(TAG, String.format("setDeviceConnectionState(0x%s, %d, 0x%s",
+ attributes.toString(), state, Integer.toHexString(codecFormat)));
return AudioSystem.AUDIO_STATUS_OK;
}
diff --git a/services/usb/java/com/android/server/usb/UsbAlsaDevice.java b/services/usb/java/com/android/server/usb/UsbAlsaDevice.java
index 9d4db003a297..7d8d240cd8e0 100644
--- a/services/usb/java/com/android/server/usb/UsbAlsaDevice.java
+++ b/services/usb/java/com/android/server/usb/UsbAlsaDevice.java
@@ -17,6 +17,7 @@
package com.android.server.usb;
import android.annotation.NonNull;
+import android.media.AudioDeviceAttributes;
import android.media.AudioSystem;
import android.media.IAudioService;
import android.os.RemoteException;
@@ -203,24 +204,25 @@ public final class UsbAlsaDevice {
int outputState = (enable && connected) ? 1 : 0;
if (outputState != mOutputState) {
mOutputState = outputState;
- mAudioService.setWiredDeviceConnectionState(device, outputState,
- alsaCardDeviceString,
- mDeviceName, TAG);
+ AudioDeviceAttributes attributes = new AudioDeviceAttributes(device,
+ alsaCardDeviceString, mDeviceName);
+ mAudioService.setWiredDeviceConnectionState(attributes, outputState, TAG);
}
}
// Input Device
if (mHasInput) {
- int device = mIsInputHeadset ? AudioSystem.DEVICE_IN_USB_HEADSET
+ int device = mIsInputHeadset
+ ? AudioSystem.DEVICE_IN_USB_HEADSET
: AudioSystem.DEVICE_IN_USB_DEVICE;
boolean connected = isInputJackConnected();
Slog.i(TAG, "INPUT JACK connected: " + connected);
int inputState = (enable && connected) ? 1 : 0;
if (inputState != mInputState) {
mInputState = inputState;
- mAudioService.setWiredDeviceConnectionState(
- device, inputState, alsaCardDeviceString,
- mDeviceName, TAG);
+ AudioDeviceAttributes attributes = new AudioDeviceAttributes(device,
+ alsaCardDeviceString, mDeviceName);
+ mAudioService.setWiredDeviceConnectionState(attributes, inputState, TAG);
}
}
} catch (RemoteException e) {