Add AudioDeviceAttributes as argument to AudioManager API
NoNonSdkCheck: This CL changes the arguments of an existing API that was annotated already. Bug: 199846845 Test: atest AidlConversionUnitTests Change-Id: I90a24c0428d9c77ccd45dff65bbdad198aa81fb2
This commit is contained in:
parent
4e27963e60
commit
517a1327ca
@ -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},
|
||||
|
@ -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<>();
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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(
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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*/);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
@ -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) */
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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*/);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user