hal: Remove storage of audio device on bitfields
Audio devices were stored in HAL on variables with
type audio_devices_t. This change removes the storage
of multiple devices on a bitfield. Device comparisons,
assigments, removal have been updated. Helper functions
have been introduced for device operations.
Change-Id: I9ce8b0f9bdc542c386cbfe45b685158cc51d47b6
diff --git a/hal/audio_extn/Android.mk b/hal/audio_extn/Android.mk
index b5c32cd..b889212 100644
--- a/hal/audio_extn/Android.mk
+++ b/hal/audio_extn/Android.mk
@@ -136,7 +136,8 @@
MULTIPLE_HW_VARIANTS_ENABLED := true
endif
-LOCAL_SRC_FILES:= ssr.c
+LOCAL_SRC_FILES:= ssr.c \
+ device_utils.c
LOCAL_CFLAGS += \
-Wall \
@@ -383,7 +384,8 @@
endif
LOCAL_SRC_FILES:= \
- a2dp.c
+ a2dp.c \
+ device_utils.c
LOCAL_CFLAGS += \
-Wall \
@@ -514,7 +516,8 @@
endif
LOCAL_SRC_FILES:= \
- hfp.c
+ hfp.c \
+ device_utils.c
LOCAL_CFLAGS += \
-Wall \
@@ -577,7 +580,8 @@
endif
LOCAL_SRC_FILES:= \
- passthru.c
+ passthru.c \
+ device_utils.c
LOCAL_CFLAGS += \
-Wall \
@@ -779,7 +783,8 @@
endif
LOCAL_SRC_FILES:= \
- maxxaudio.c
+ maxxaudio.c \
+ device_utils.c
LOCAL_CFLAGS += \
-Wall \
@@ -840,7 +845,8 @@
endif
LOCAL_SRC_FILES:= \
- audiozoom.c
+ audiozoom.c \
+ device_utils.c
LOCAL_CFLAGS += \
-Wall \
@@ -904,7 +910,8 @@
endif
LOCAL_SRC_FILES:= \
- auto_hal.c
+ auto_hal.c \
+ device_utils.c
LOCAL_CFLAGS += \
-Wall \
diff --git a/hal/audio_extn/a2dp.c b/hal/audio_extn/a2dp.c
index bffa3fd..e0aebf0 100644
--- a/hal/audio_extn/a2dp.c
+++ b/hal/audio_extn/a2dp.c
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2015-2019, The Linux Foundation. All rights reserved.
+* Copyright (c) 2015-2020, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -2786,7 +2786,7 @@
list_for_each(node, &a2dp.adev->usecase_list) {
uc_info = node_to_item(node, struct audio_usecase, list);
if (uc_info->stream.out && uc_info->type == PCM_PLAYBACK &&
- (uc_info->stream.out->devices & AUDIO_DEVICE_OUT_ALL_A2DP)) {
+ is_a2dp_out_device_type(&uc_info->stream.out->device_list)) {
pthread_mutex_unlock(&a2dp.adev->lock);
fp_check_a2dp_restore(a2dp.adev, uc_info->stream.out, false);
pthread_mutex_lock(&a2dp.adev->lock);
@@ -2827,7 +2827,7 @@
list_for_each(node, &a2dp.adev->usecase_list) {
uc_info = node_to_item(node, struct audio_usecase, list);
if (uc_info->stream.out && uc_info->type == PCM_PLAYBACK &&
- (uc_info->stream.out->devices & AUDIO_DEVICE_OUT_ALL_A2DP)) {
+ is_a2dp_out_device_type(&uc_info->stream.out->device_list)) {
pthread_mutex_unlock(&a2dp.adev->lock);
fp_check_a2dp_restore(a2dp.adev, uc_info->stream.out, true);
pthread_mutex_lock(&a2dp.adev->lock);
diff --git a/hal/audio_extn/audio_extn.c b/hal/audio_extn/audio_extn.c
index 45da9b5..620e7c6 100644
--- a/hal/audio_extn/audio_extn.c
+++ b/hal/audio_extn/audio_extn.c
@@ -1247,12 +1247,12 @@
list_for_each(node, &adev->usecase_list) {
usecase = node_to_item(node, struct audio_usecase, list);
if (usecase->stream.out && usecase->type != PCM_CAPTURE) {
- if (usecase->stream.out->devices == \
- AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
- usecase->stream.out->devices == \
- AUDIO_DEVICE_OUT_WIRED_HEADSET ||
- usecase->stream.out->devices == \
- AUDIO_DEVICE_OUT_EARPIECE) {
+ if (is_single_device_type_equal(&usecase->stream.out->device_list,
+ AUDIO_DEVICE_OUT_WIRED_HEADPHONE) ||
+ is_single_device_type_equal(&usecase->stream.out->device_list,
+ AUDIO_DEVICE_OUT_WIRED_HEADSET) ||
+ is_single_device_type_equal(&usecase->stream.out->device_list,
+ AUDIO_DEVICE_OUT_EARPIECE)) {
select_devices(adev, usecase->id);
ALOGV("%s: switching device completed", __func__);
break;
@@ -3387,7 +3387,7 @@
/* validate input params. Avoid updated channel mask if loopback device */
if ((channel_count == 6) &&
(in->format == AUDIO_FORMAT_PCM_16_BIT) &&
- (!is_loopback_input_device(in->device))) {
+ (!is_loopback_input_device(get_device_types(&in->device_list)))) {
switch (max_mic_count) {
case 4:
config->channel_mask = AUDIO_CHANNEL_INDEX_MASK_4;
@@ -3662,13 +3662,13 @@
adev_device_cfg_ptr = adev->device_cfg_params;
/* Create an out stream to get snd device from audio device */
- out.devices = device_cfg_params->device;
+ reassign_device_list(&out.device_list, device_cfg_params->device, "");
out.sample_rate = device_cfg_params->sample_rate;
snd_device = platform_get_output_snd_device(adev->platform, &out);
backend_idx = platform_get_backend_index(snd_device);
ALOGV("%s:: device %d sample_rate %d snd_device %d backend_idx %d",
- __func__, out.devices, out.sample_rate, snd_device, backend_idx);
+ __func__, get_device_types(&out.device_list), out.sample_rate, snd_device, backend_idx);
ALOGV("%s:: Device Config Params from Client samplerate %d channels %d"
" bit_width %d format %d device %d channel_map[0] %d channel_map[1] %d"
diff --git a/hal/audio_extn/audio_extn.h b/hal/audio_extn/audio_extn.h
index 986e24a..b01915a 100644
--- a/hal/audio_extn/audio_extn.h
+++ b/hal/audio_extn/audio_extn.h
@@ -680,7 +680,7 @@
typedef int (*fp_platform_set_mic_mute_t)(void *, bool);
//typedef int (*fp_platform_get_pcm_device_id_t)(audio_usecase_t, int);
typedef void (*fp_platform_set_echo_reference_t)(struct audio_device *, bool,
- audio_devices_t);
+ struct listnode *);
typedef int (*fp_select_devices_t)(struct audio_device *, audio_usecase_t);
typedef int (*fp_audio_extn_ext_hw_plugin_usecase_start_t)(void *,
struct audio_usecase *);
@@ -795,7 +795,7 @@
struct listnode *streams_input_cfg_list);
void audio_extn_utils_update_stream_output_app_type_cfg(void *platform,
struct listnode *streams_output_cfg_list,
- audio_devices_t devices,
+ struct listnode *devices,
audio_output_flags_t flags,
audio_format_t format,
uint32_t sample_rate,
@@ -805,7 +805,7 @@
struct stream_app_type_cfg *app_type_cfg);
void audio_extn_utils_update_stream_input_app_type_cfg(void *platform,
struct listnode *streams_input_cfg_list,
- audio_devices_t devices,
+ struct listnode *devices,
audio_input_flags_t flags,
audio_format_t format,
uint32_t sample_rate,
@@ -1063,7 +1063,7 @@
void audio_extn_gef_init(struct audio_device *adev);
void audio_extn_gef_deinit(struct audio_device *adev);
-void audio_extn_gef_notify_device_config(audio_devices_t audio_device,
+void audio_extn_gef_notify_device_config(struct listnode *audio_devices,
audio_channel_mask_t channel_mask, int sample_rate, int acdb_id, int app_type);
#ifndef INSTANCE_ID_ENABLED
int audio_extn_gef_send_audio_cal(void* adev, int acdb_dev_id, int acdb_device_type,
@@ -1126,7 +1126,8 @@
void audio_extn_fm_set_parameters(struct audio_device *adev,
struct str_parms *parms);
void audio_extn_fm_get_parameters(struct str_parms *query, struct str_parms *reply);
-void audio_extn_fm_route_on_selected_device(struct audio_device *adev, audio_devices_t device);
+void audio_extn_fm_route_on_selected_device(struct audio_device *adev,
+ struct listnode *devices);
#ifndef APTX_DECODER_ENABLED
#define audio_extn_aptx_dec_set_license(adev); (0)
diff --git a/hal/audio_extn/audiozoom.c b/hal/audio_extn/audiozoom.c
index 9958cc4..e2bde0f 100644
--- a/hal/audio_extn/audiozoom.c
+++ b/hal/audio_extn/audiozoom.c
@@ -203,7 +203,7 @@
qdsp_audiozoom.zoom_param_id == 0)
return -ENOSYS;
- str_parms_add_int(parms, "cal_devid", in->device);
+ str_parms_add_int(parms, "cal_devid", get_device_types(&in->device_list));
str_parms_add_int(parms, "cal_apptype", in->app_type_cfg.app_type);
str_parms_add_int(parms, "cal_topoid", qdsp_audiozoom.topo_id);
str_parms_add_int(parms, "cal_moduleid", qdsp_audiozoom.module_id);
diff --git a/hal/audio_extn/auto_hal.c b/hal/audio_extn/auto_hal.c
index 41b3762..580d446 100644
--- a/hal/audio_extn/auto_hal.c
+++ b/hal/audio_extn/auto_hal.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -230,7 +230,8 @@
ALOGV("Creating audio patch for external FM tuner");
uc_info->id = USECASE_AUDIO_FM_TUNER_EXT;
uc_info->type = PCM_PASSTHROUGH;
- uc_info->devices = AUDIO_DEVICE_IN_FM_TUNER;
+ reassign_device_list(&uc_info->device_list, AUDIO_DEVICE_IN_FM_TUNER,
+ sources->ext.device.address);
uc_info->in_snd_device = SND_DEVICE_IN_CAPTURE_FM;
uc_info->out_snd_device = SND_DEVICE_OUT_BUS_MEDIA;
break;
@@ -599,8 +600,10 @@
streams_output_ctxt_t,
list);
/* limit audio gain support for bus device only */
- if (out_ctxt->output->devices == AUDIO_DEVICE_OUT_BUS &&
- out_ctxt->output->devices == config->ext.device.type &&
+ if (is_single_device_type_equal(
+ &out_ctxt->output->device_list, AUDIO_DEVICE_OUT_BUS) &&
+ is_single_device_type_equal(&out_ctxt->output->device_list,
+ config->ext.device.type) &&
strcmp(out_ctxt->output->address,
config->ext.device.address) == 0) {
/* millibel = 1/100 dB = 1/1000 bel
@@ -710,7 +713,7 @@
uc_downlink_info->type = PCM_HFP_CALL;
uc_downlink_info->stream.out = adev->primary_output;
- uc_downlink_info->devices = adev->primary_output->devices;
+ assign_devices(&uc_downlink_info->device_list, &adev->primary_output->device_list);
uc_downlink_info->in_snd_device = SND_DEVICE_NONE;
uc_downlink_info->out_snd_device = SND_DEVICE_NONE;
@@ -790,12 +793,16 @@
audio_usecase_t uc_id)
{
snd_device_t snd_device = SND_DEVICE_NONE;
- audio_devices_t out_device = AUDIO_DEVICE_NONE;
+ struct listnode out_devices;
struct audio_usecase *usecase = NULL;
struct stream_in *in = fp_adev_get_active_input(adev);
- audio_devices_t in_device = ((in == NULL) ?
- AUDIO_DEVICE_NONE : in->device)
- & ~AUDIO_DEVICE_BIT_IN;
+ struct listnode in_devices;
+ struct listnode *node;
+ struct audio_device_info *item = NULL;
+
+ list_init(&in_devices);
+ if (in != NULL)
+ assign_devices(&in_devices, &in->device_list);
if (uc_id == USECASE_INVALID) {
ALOGE("%s: Invalid usecase (%d)", __func__, uc_id);
@@ -813,17 +820,18 @@
return -EINVAL;
}
- out_device = usecase->stream.out->devices;
- if (out_device == AUDIO_DEVICE_NONE ||
- out_device & AUDIO_DEVICE_BIT_IN) {
- ALOGE("%s: Invalid output devices (%#x)", __func__, out_device);
+ list_init(&out_devices);
+ assign_devices(&out_devices, &usecase->stream.out->device_list);
+ if (list_empty(&out_devices) ||
+ compare_device_type(&out_devices, AUDIO_DEVICE_BIT_IN)) {
+ ALOGE("%s: Invalid output devices (%#x)", __func__, get_device_types(&out_devices));
return -EINVAL;
}
ALOGV("%s: output device(%#x), input device(%#x), usecase(%d)",
- __func__, out_device, in_device, uc_id);
+ __func__, get_device_types(&out_devices), get_device_types(&in_devices), uc_id);
- if (out_device & AUDIO_DEVICE_OUT_BUS) {
+ if (compare_device_type(&out_devices, AUDIO_DEVICE_OUT_BUS)) {
/* usecase->id is token as judgement for HFP calls */
switch (usecase->id) {
case USECASE_AUDIO_HFP_SCO:
@@ -834,7 +842,7 @@
snd_device = SND_DEVICE_IN_VOICE_SPEAKER_MIC_HFP;
}
if (adev->enable_hfp)
- fp_platform_set_echo_reference(adev, true, out_device);
+ fp_platform_set_echo_reference(adev, false, &out_devices);
break;
case USECASE_AUDIO_HFP_SCO_DOWNLINK:
snd_device = SND_DEVICE_IN_BT_SCO_MIC;
@@ -850,7 +858,7 @@
return -EINVAL;
}
} else {
- ALOGE("%s: Output devices (%#x) not supported", __func__, out_device);
+ ALOGE("%s: Output devices (%#x) not supported", __func__, get_device_types(&out_devices));
return -EINVAL;
}
@@ -861,7 +869,7 @@
audio_usecase_t uc_id)
{
snd_device_t snd_device = SND_DEVICE_NONE;
- audio_devices_t devices = AUDIO_DEVICE_NONE;
+ struct listnode devices;
struct audio_usecase *usecase = NULL;
if (uc_id == USECASE_INVALID) {
@@ -880,16 +888,18 @@
return -EINVAL;
}
- devices = usecase->stream.out->devices;
- if (devices == AUDIO_DEVICE_NONE ||
- devices & AUDIO_DEVICE_BIT_IN) {
- ALOGE("%s: Invalid output devices (%#x)", __func__, devices);
+ list_init(&devices);
+ assign_devices(&devices, &usecase->stream.out->device_list);
+ if (list_empty(&devices) ||
+ compare_device_type(&devices, AUDIO_DEVICE_BIT_IN)) {
+ ALOGE("%s: Invalid output devices (%#x)", __func__, get_device_types(&devices));
return -EINVAL;
}
- ALOGV("%s: output devices(%#x), usecase(%d)", __func__, devices, uc_id);
+ ALOGV("%s: output devices(%#x), usecase(%d)", __func__,
+ get_device_types(&devices), uc_id);
- if (devices & AUDIO_DEVICE_OUT_BUS) {
+ if (compare_device_type(&devices, AUDIO_DEVICE_OUT_BUS)) {
/* usecase->id is token as judgement for HFP calls */
switch (usecase->id) {
case USECASE_AUDIO_HFP_SCO:
@@ -937,7 +947,7 @@
return -EINVAL;
}
} else {
- ALOGE("%s: Output devices (%#x) not supported", __func__, devices);
+ ALOGE("%s: Output devices (%#x) not supported", __func__, get_device_types(&devices));
return -EINVAL;
}
diff --git a/hal/audio_extn/device_utils.c b/hal/audio_extn/device_utils.c
new file mode 100644
index 0000000..e67676d
--- /dev/null
+++ b/hal/audio_extn/device_utils.c
@@ -0,0 +1,601 @@
+/*
+ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#define LOG_TAG "device_utils"
+/*#define LOG_NDEBUG 0*/
+#define LOG_NDDEBUG 0
+
+#include <errno.h>
+#include <stdlib.h>
+#include <hardware/audio.h>
+#include <cutils/list.h>
+#include <log/log.h>
+
+#include "device_utils.h"
+
+/*
+ * Below are the devices for which is back end is same, SLIMBUS_0_RX.
+ * All these devices are handled by the internal HW codec. We can
+ * enable any one of these devices at any time. An exception here is
+ * 44.1k headphone which uses different backend. This is filtered
+ * as different hal internal device in the code but remains same
+ * as standard android device AUDIO_DEVICE_OUT_WIRED_HEADPHONE
+ * for other layers.
+ */
+static const uint32_t AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND_ARRAY[] = {
+ AUDIO_DEVICE_OUT_EARPIECE,
+ AUDIO_DEVICE_OUT_SPEAKER,
+ AUDIO_DEVICE_OUT_WIRED_HEADSET,
+ AUDIO_DEVICE_OUT_WIRED_HEADPHONE,
+ AUDIO_DEVICE_OUT_LINE,
+ AUDIO_DEVICE_OUT_SPEAKER_SAFE,
+};
+
+/*
+ * Below are the input devices for which back end is same, SLIMBUS_0_TX.
+ * All these devices are handled by the internal HW codec. We can
+ * enable any one of these devices at any time
+ */
+static const uint32_t AUDIO_DEVICE_IN_ALL_CODEC_BACKEND_ARRAY[] = {
+ AUDIO_DEVICE_IN_BUILTIN_MIC,
+ AUDIO_DEVICE_IN_WIRED_HEADSET,
+ AUDIO_DEVICE_IN_VOICE_CALL,
+ AUDIO_DEVICE_IN_BACK_MIC,
+};
+
+static const uint32_t AUDIO_DEVICE_OUT_CODEC_BACKEND_CNT =
+ AUDIO_ARRAY_SIZE(AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND_ARRAY);
+static const uint32_t AUDIO_DEVICE_IN_CODEC_BACKEND_CNT =
+ AUDIO_ARRAY_SIZE(AUDIO_DEVICE_IN_ALL_CODEC_BACKEND_ARRAY);
+
+
+int list_length(struct listnode *list)
+{
+ struct listnode *node;
+ int length = 0;
+
+ if (list == NULL)
+ goto done;
+
+ for (node = list->next; node != list; node = node->next)
+ ++length;
+done:
+ return length;
+}
+
+/*
+ * Returns true if devices list contains input device type.
+ */
+bool is_audio_in_device_type(struct listnode *devices)
+{
+ struct listnode *node;
+ struct audio_device_info *item = NULL;
+
+ if (devices == NULL)
+ return false;
+
+ list_for_each (node, devices) {
+ item = node_to_item(node, struct audio_device_info, list);
+ if (item != NULL && audio_is_input_device(item->type)) {
+ ALOGV("%s: in device %#x", __func__, item->type);
+ return true;
+ }
+ }
+ return false;
+}
+
+/*
+ * Returns true if devices list contains output device type.
+ */
+bool is_audio_out_device_type(struct listnode *devices)
+{
+ struct listnode *node;
+ struct audio_device_info *item = NULL;
+
+ if (devices == NULL)
+ return false;
+
+ list_for_each (node, devices) {
+ item = node_to_item(node, struct audio_device_info, list);
+ if (item != NULL && audio_is_output_device(item->type)) {
+ ALOGV("%s: out device %#x", __func__, item->type);
+ return true;
+ }
+ }
+ return false;
+}
+
+/*
+ * Returns true if devices list contains codec backend
+ * input device type.
+ */
+bool is_codec_backend_in_device_type(struct listnode *devices)
+{
+ struct listnode *node;
+ struct audio_device_info *item = NULL;
+
+ if (devices == NULL)
+ return false;
+
+ list_for_each (node, devices) {
+ item = node_to_item(node, struct audio_device_info, list);
+ if (item == NULL)
+ return false;
+ for (int i = 0; i < AUDIO_DEVICE_IN_CODEC_BACKEND_CNT; i++) {
+ if (item->type == AUDIO_DEVICE_IN_ALL_CODEC_BACKEND_ARRAY[i]) {
+ ALOGV("%s: codec backend in device %#x", __func__, item->type);
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+/*
+ * Returns true if devices list contains codec backend
+ * output device type.
+ */
+bool is_codec_backend_out_device_type(struct listnode *devices)
+{
+ struct listnode *node;
+ struct audio_device_info *item = NULL;
+
+ if (devices == NULL)
+ return false;
+
+ list_for_each (node, devices) {
+ item = node_to_item(node, struct audio_device_info, list);
+ if (item == NULL)
+ return false;
+ for (int i = 0; i < AUDIO_DEVICE_OUT_CODEC_BACKEND_CNT; i++) {
+ if (item->type == AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND_ARRAY[i]) {
+ ALOGV("%s: codec backend out device %#x", __func__, item->type);
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+/* Returns true if USB input device is found in passed devices list */
+bool is_usb_in_device_type(struct listnode *devices)
+{
+ struct listnode *node;
+ struct audio_device_info *item = NULL;
+
+ if (devices == NULL)
+ return false;
+
+ list_for_each (node, devices) {
+ item = node_to_item(node, struct audio_device_info, list);
+ if (item != NULL && audio_is_usb_in_device(item->type)) {
+ ALOGV("%s: USB in device %#x", __func__, item->type);
+ return true;
+ }
+ }
+ return false;
+}
+
+/*
+ * Returns true if USB output device is found in passed devices list
+ */
+bool is_usb_out_device_type(struct listnode *devices)
+{
+ struct listnode *node;
+ struct audio_device_info *item = NULL;
+
+ list_for_each (node, devices) {
+ item = node_to_item(node, struct audio_device_info, list);
+ if (item != NULL && audio_is_usb_out_device(item->type)) {
+ ALOGV("%s: USB out device %#x address %s", __func__,
+ item->type, item->address);
+ return true;
+ }
+ }
+ return false;
+}
+
+/*
+ * Returns USB device address information (card, device)
+ */
+const char *get_usb_device_address(struct listnode *devices)
+{
+ struct listnode *node;
+ struct audio_device_info *item = NULL;
+
+ if (devices == NULL)
+ return false;
+
+ list_for_each (node, devices) {
+ item = node_to_item(node, struct audio_device_info, list);
+ if (item != NULL && (audio_is_usb_out_device(item->type) ||
+ audio_is_usb_in_device(item->type))) {
+ ALOGV("%s: USB device %#x address %s", __func__,
+ item->type, item->address);
+ return (const char *)&item->address[0];
+ }
+ }
+ return "";
+}
+
+/*
+ * Returns true if SCO output device is found in passed devices list
+ */
+bool is_sco_in_device_type(struct listnode *devices)
+{
+ struct listnode *node;
+ struct audio_device_info *item = NULL;
+
+ if (devices == NULL)
+ return false;
+
+ list_for_each (node, devices) {
+ item = node_to_item(node, struct audio_device_info, list);
+ if (item != NULL &&
+ audio_is_bluetooth_in_sco_device(item->type)) {
+ ALOGV("%s: SCO in device %#x", __func__, item->type);
+ return true;
+ }
+ }
+ return false;
+}
+
+/*
+ * Returns true if SCO output device is found in passed devices list
+ */
+bool is_sco_out_device_type(struct listnode *devices)
+{
+ struct listnode *node;
+ struct audio_device_info *item = NULL;
+
+ if (devices == NULL)
+ return false;
+
+ list_for_each (node, devices) {
+ item = node_to_item(node, struct audio_device_info, list);
+ if (item != NULL &&
+ audio_is_bluetooth_out_sco_device(item->type)) {
+ ALOGV("%s: SCO out device %#x", __func__, item->type);
+ return true;
+ }
+ }
+ return false;
+}
+
+/*
+ * Returns true if A2DP input device is found in passed devices list
+ */
+bool is_a2dp_in_device_type(struct listnode *devices)
+{
+ struct listnode *node;
+ struct audio_device_info *item = NULL;
+
+ if (devices == NULL)
+ return false;
+
+ list_for_each (node, devices) {
+ item = node_to_item(node, struct audio_device_info, list);
+ if (item != NULL && audio_is_a2dp_in_device(item->type)) {
+ ALOGV("%s: A2DP in device %#x", __func__, item->type);
+ return true;
+ }
+ }
+ return false;
+}
+
+/*
+ * Returns true if A2DP output device is found in passed devices list
+ */
+bool is_a2dp_out_device_type(struct listnode *devices)
+{
+ struct listnode *node;
+ struct audio_device_info *item = NULL;
+
+ if (devices == NULL)
+ return false;
+
+ list_for_each (node, devices) {
+ item = node_to_item(node, struct audio_device_info, list);
+ if (item != NULL && audio_is_a2dp_out_device(item->type)) {
+ ALOGV("%s: A2DP out device %#x", __func__, item->type);
+ return true;
+ }
+ }
+ return false;
+}
+
+/*
+ * Clear device list
+ * Operation: devices = {};
+ */
+
+int clear_devices(struct listnode *devices)
+{
+ struct listnode *node;
+ struct audio_device_info *item = NULL;
+
+ if (devices == NULL)
+ return 0;
+
+ list_for_each (node, devices) {
+ item = node_to_item(node, struct audio_device_info, list);
+ if (item != NULL) {
+ list_remove(&item->list);
+ free(item);
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * Check if a device with given type is present in devices list
+ */
+bool compare_device_type(struct listnode *devices, audio_devices_t device_type)
+{
+ struct listnode *node;
+ struct audio_device_info *item = NULL;
+
+ if (devices == NULL)
+ return false;
+
+ list_for_each (node, devices) {
+ item = node_to_item(node, struct audio_device_info, list);
+ if (item != NULL && (item->type == device_type)) {
+ ALOGV("%s: device types %d match", __func__, device_type);
+ return true;
+ }
+ }
+ return false;
+}
+
+/*
+ * Returns true if intersection of d1 and d2 is not NULL
+ */
+bool compare_devices_for_any_match(struct listnode *d1, struct listnode *d2)
+{
+ struct listnode *node;
+ struct audio_device_info *item = NULL;
+
+ if (d1 == NULL || d2 == NULL)
+ return false;
+
+ list_for_each (node, d1) {
+ item = node_to_item(node, struct audio_device_info, list);
+ if (item != NULL && compare_device_type(d2, item->type))
+ return true;
+ }
+ return false;
+}
+
+/*
+ * Returns all device types from list in bitfield
+ * ToDo: Use of this function is not recommended.
+ * It has been introduced for compatability with legacy functions.
+ * This can be removed once audio HAL switches to device
+ * list usage for all audio extensions.
+ */
+audio_devices_t get_device_types(struct listnode *devices)
+{
+ struct listnode *node;
+ struct audio_device_info *item = NULL;
+ audio_devices_t device_type = AUDIO_DEVICE_NONE;
+
+ if (devices == NULL)
+ return false;
+
+ list_for_each (node, devices) {
+ item = node_to_item(node, struct audio_device_info, list);
+ if (item != NULL)
+ device_type |= item->type;
+ }
+ return device_type;
+}
+
+/*
+ * If single device in devices list is equal to passed type
+ * type should represent a single device.
+ */
+bool is_single_device_type_equal(struct listnode *devices,
+ audio_devices_t type)
+{
+ struct listnode *node = devices;
+ struct audio_device_info *item = NULL;
+
+ if (devices == NULL)
+ return false;
+
+ if (list_length(devices) == 1) {
+ item = node_to_item(node, struct audio_device_info, list);
+ if (item != NULL && (item->type == type))
+ return true;
+ }
+ return false;
+}
+
+/*
+ * Returns true if lists are equal in terms of device type
+ * ToDO: Check if device addresses are also equal in the future
+ */
+bool compare_devices(struct listnode *d1, struct listnode *d2)
+{
+ struct listnode *node;
+ struct audio_device_info *item = NULL;
+
+ if (d1 == NULL && d2 == NULL)
+ return true;
+
+ if (d1 == NULL || d2 == NULL ||
+ (list_length(d1) != list_length(d2)))
+ return false;
+
+ list_for_each (node, d1) {
+ item = node_to_item(node, struct audio_device_info, list);
+ if (item != NULL && !compare_device_type(d2, item->type))
+ return false;
+ }
+ return true;
+}
+
+/*
+ * Add or remove device from list denoted by head
+ */
+int update_device_list(struct listnode *head, audio_devices_t type,
+ const char* address, bool add_device)
+{
+ struct listnode *node;
+ struct audio_device_info *item = NULL;
+ struct audio_device_info *device = NULL;
+ int ret = 0;
+
+ if (head == NULL)
+ goto done;
+
+ if (type == AUDIO_DEVICE_NONE) {
+ ALOGE("%s: Invalid device: %#x", __func__, type);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ list_for_each (node, head) {
+ item = node_to_item(node, struct audio_device_info, list);
+ if (item != NULL && (item->type == type)) {
+ device = item;
+ break;
+ }
+ }
+
+ if (add_device) {
+ if (device == NULL) {
+ device = (struct audio_device_info *)
+ calloc (1, sizeof(struct audio_device_info));
+ if (!device) {
+ ALOGE("%s: Cannot allocate memory for device_info", __func__);
+ ret = -ENOMEM;
+ goto done;
+ }
+ device->type = type;
+ list_add_tail(head, &device->list);
+ }
+ strlcpy(device->address, address, AUDIO_DEVICE_MAX_ADDRESS_LEN);
+ ALOGV("%s: Added device type %#x, address %s", __func__, type, address);
+ } else {
+ if (device != NULL) {
+ list_remove(&device->list);
+ free(device);
+ ALOGV("%s: Removed device type %#x, address %s", __func__, type, address);
+ }
+ }
+done:
+ return ret;
+}
+
+/*
+ * Assign source device list to destination device list
+ * Operation: dest list = source list
+ */
+int assign_devices(struct listnode *dest, const struct listnode *source)
+{
+ struct listnode *node;
+ struct audio_device_info *item = NULL;
+ int ret = 0;
+
+ if (source == NULL || dest == NULL)
+ return ret;
+
+ if (!list_empty(dest))
+ clear_devices(dest);
+
+ list_for_each (node, source) {
+ item = node_to_item(node, struct audio_device_info, list);
+ if (item != NULL)
+ ret = update_device_list(dest, item->type, item->address, true);
+ }
+ return ret;
+}
+
+/*
+ * Assign output devices from source device list to destination device list
+ * Operation: dest devices = source output devices
+ */
+int assign_output_devices(struct listnode *dest, const struct listnode *source)
+{
+ struct listnode *node;
+ struct audio_device_info *item = NULL;
+ int ret = 0;
+
+ if (source == NULL || dest == NULL)
+ return ret;
+
+ if (!list_empty(dest))
+ clear_devices(dest);
+
+ list_for_each (node, source) {
+ item = node_to_item(node, struct audio_device_info, list);
+ if (item != NULL && audio_is_output_device(item->type))
+ ret = update_device_list(dest, item->type, item->address, true);
+ }
+ return ret;
+}
+
+/*
+ * Clear device list and replace it with single device
+ */
+int reassign_device_list(struct listnode *device_list,
+ audio_devices_t type, char *address)
+{
+ if (device_list == NULL)
+ return 0;
+
+ if (!list_empty(device_list))
+ clear_devices(device_list);
+
+ return update_device_list(device_list, type, address, true);
+}
+
+/*
+ * Append source devices to destination devices
+ * Operation: dest devices |= source devices
+ */
+int append_devices(struct listnode *dest, const struct listnode *source)
+{
+ struct listnode *node;
+ struct audio_device_info *item = NULL;
+ int ret = 0;
+
+ if (source == NULL || dest == NULL)
+ return ret;
+
+ list_for_each (node, source) {
+ item = node_to_item(node, struct audio_device_info, list);
+ if (item != NULL)
+ ret = update_device_list(dest, item->type, item->address, true);
+ }
+ return ret;
+}
diff --git a/hal/audio_extn/device_utils.h b/hal/audio_extn/device_utils.h
new file mode 100644
index 0000000..b6d4c9b
--- /dev/null
+++ b/hal/audio_extn/device_utils.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef AUDIO_HW_EXTN_DEVICE_UTILS_H
+#define AUDIO_HW_EXTN_DEVICE_UTILS_H
+
+struct audio_device_info {
+ struct listnode list;
+ audio_devices_t type;
+ char address[AUDIO_DEVICE_MAX_ADDRESS_LEN];
+};
+
+int list_length(struct listnode *list);
+bool is_audio_in_device_type(struct listnode *devices);
+bool is_audio_out_device_type(struct listnode *devices);
+bool is_codec_backend_in_device_type(struct listnode *devices);
+bool is_codec_backend_out_device_type(struct listnode *devices);
+bool is_usb_in_device_type(struct listnode *devices);
+bool is_usb_out_device_type(struct listnode *devices);
+const char *get_usb_device_address(struct listnode *devices);
+bool is_sco_in_device_type(struct listnode *devices);
+bool is_sco_out_device_type(struct listnode *devices);
+bool is_a2dp_in_device_type(struct listnode *devices);
+bool is_a2dp_out_device_type(struct listnode *devices);
+int clear_devices(struct listnode *devices);
+bool compare_device_type(struct listnode *devices, audio_devices_t device_type);
+bool compare_devices_for_any_match(struct listnode *d1, struct listnode *d2);
+audio_devices_t get_device_types(struct listnode *devices);
+bool is_single_device_type_equal(struct listnode *devices,
+ audio_devices_t type);
+bool compare_devices(struct listnode *d1, struct listnode *d2);
+int update_device_list(struct listnode *head, audio_devices_t type,
+ const char* address, bool add_device);
+int assign_devices(struct listnode *dest, const struct listnode *source);
+int assign_output_devices(struct listnode *dest, const struct listnode *source);
+int reassign_device_list(struct listnode *device_list,
+ audio_devices_t type, char *address);
+int append_devices(struct listnode *dest, const struct listnode *source);
+
+#endif
diff --git a/hal/audio_extn/dolby.c b/hal/audio_extn/dolby.c
index 335cfbd..f4a1a97 100644
--- a/hal/audio_extn/dolby.c
+++ b/hal/audio_extn/dolby.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2017, 2020, The Linux Foundation. All rights reserved.
* Not a Contribution.
*
* Copyright (C) 2010 The Android Open Source Project
@@ -246,7 +246,7 @@
list_for_each(node, &adev->usecase_list) {
usecase = node_to_item(node, struct audio_usecase, list);
if (usecase->stream.out && (usecase->type == PCM_PLAYBACK) &&
- (usecase->devices & ddp_dev) &&
+ (compare_device_type(&usecase->device_list, ddp_dev)) &&
(usecase->stream.out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) &&
((usecase->stream.out->format == AUDIO_FORMAT_AC3) ||
(usecase->stream.out->format == AUDIO_FORMAT_E_AC3) ||
@@ -264,7 +264,7 @@
list_for_each(node, &adev->usecase_list) {
usecase = node_to_item(node, struct audio_usecase, list);
if (usecase->stream.out && (usecase->type == PCM_PLAYBACK) &&
- (usecase->devices & AUDIO_DEVICE_OUT_ALL) &&
+ is_audio_out_device_type(&usecase->device_list) &&
(usecase->stream.out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) &&
((usecase->stream.out->format == AUDIO_FORMAT_AC3) ||
(usecase->stream.out->format == AUDIO_FORMAT_E_AC3) ||
@@ -273,11 +273,14 @@
* Use wfd /hdmi sink channel cap for dolby params if device is wfd
* or hdmi. Otherwise use stereo configuration
*/
- int channel_cap = usecase->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL ?
+ int channel_cap = compare_device_type(&usecase->device_list,
+ AUDIO_DEVICE_OUT_AUX_DIGITAL) ?
adev->cur_hdmi_channels :
- usecase->devices & AUDIO_DEVICE_OUT_PROXY ?
+ compare_device_type(&usecase->device_list,
+ AUDIO_DEVICE_OUT_PROXY) ?
adev->cur_wfd_channels : 2;
- send_ddp_endp_params_stream(usecase->stream.out, usecase->devices,
+ send_ddp_endp_params_stream(usecase->stream.out,
+ get_device_types(&usecase->device_list),
channel_cap, false /* set cache */);
}
}
@@ -302,7 +305,7 @@
sizeof(value));
if (ret >= 0) {
ddp_dev = atoi(value);
- if (!(AUDIO_DEVICE_OUT_ALL & ddp_dev))
+ if (!audio_is_output_device(ddp_dev))
return;
} else
return;
@@ -376,7 +379,7 @@
usecase = node_to_item(node, struct audio_usecase, list);
if ((usecase->type == PCM_PLAYBACK) &&
(usecase->id != USECASE_AUDIO_PLAYBACK_LOW_LATENCY)) {
- endpoint |= usecase->devices & AUDIO_DEVICE_OUT_ALL;
+ endpoint |= is_audio_out_device_type(&usecase->device_list);
send = true;
}
}
@@ -528,7 +531,7 @@
usecase = node_to_item(node, struct audio_usecase, list);
if ((usecase->type == PCM_PLAYBACK) &&
(usecase->id != USECASE_AUDIO_PLAYBACK_LOW_LATENCY)) {
- endpoint |= usecase->devices & AUDIO_DEVICE_OUT_ALL;
+ endpoint |= is_audio_out_device_type(&usecase->device_list);
send = true;
}
}
diff --git a/hal/audio_extn/ffv.c b/hal/audio_extn/ffv.c
index b97eedc..fe6ffa6 100644
--- a/hal/audio_extn/ffv.c
+++ b/hal/audio_extn/ffv.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -365,13 +365,13 @@
bool audio_extn_ffv_check_usecase(struct stream_in *in) {
int ret = false;
int channel_count = audio_channel_count_from_in_mask(in->channel_mask);
- audio_devices_t devices = in->device;
audio_source_t source = in->source;
if ((audio_extn_ffv_get_enabled()) &&
(channel_count == 1) &&
(AUDIO_SOURCE_MIC == source) &&
- ((AUDIO_DEVICE_IN_BUILTIN_MIC == devices) || (AUDIO_DEVICE_IN_BACK_MIC == devices)) &&
+ (is_single_device_type_equal(&in->device_list, AUDIO_DEVICE_IN_BUILTIN_MIC) ||
+ is_single_device_type_equal(&in->device_list, AUDIO_DEVICE_IN_BACK_MIC)) &&
(in->format == AUDIO_FORMAT_PCM_16_BIT) &&
(in->sample_rate == FFV_SAMPLING_RATE_16000)) {
in->config.channels = channel_count;
diff --git a/hal/audio_extn/fm.c b/hal/audio_extn/fm.c
index 435c377..a0c2410 100644
--- a/hal/audio_extn/fm.c
+++ b/hal/audio_extn/fm.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2020, The Linux Foundation. All rights reserved.
* Not a Contribution.
*
* Copyright (C) 2013 The Android Open Source Project
@@ -182,7 +182,7 @@
fm_out->format = AUDIO_FORMAT_PCM_16_BIT;
fm_out->usecase = USECASE_AUDIO_PLAYBACK_FM;
fm_out->config = pcm_config_fm;
- fm_out->devices = outputDevices;
+ reassign_device_list(&fm_out->device_list, outputDevices, "");
fmmod.is_fm_running = true;
uc_info = (struct audio_usecase *)calloc(1, sizeof(struct audio_usecase));
@@ -195,7 +195,7 @@
uc_info->id = USECASE_AUDIO_PLAYBACK_FM;
uc_info->type = PCM_PLAYBACK;
uc_info->stream.out = fm_out;
- uc_info->devices = outputDevices;
+ reassign_device_list(&uc_info->device_list, outputDevices, "");
uc_info->in_snd_device = SND_DEVICE_NONE;
uc_info->out_snd_device = SND_DEVICE_NONE;
@@ -240,7 +240,7 @@
pcm_start(fmmod.fm_pcm_rx);
pcm_start(fmmod.fm_pcm_tx);
- fmmod.fm_device = fm_out->devices;
+ fmmod.fm_device = get_device_types(&fm_out->device_list);
ALOGD("%s: exit: status(%d)", __func__, ret);
return 0;
@@ -388,7 +388,8 @@
ALOGV("%s: exit", __func__);
}
-void audio_extn_fm_route_on_selected_device(struct audio_device *adev, audio_devices_t device)
+void audio_extn_fm_route_on_selected_device(struct audio_device *adev,
+ struct listnode *devices)
{
struct listnode *node;
struct audio_usecase *usecase;
@@ -397,10 +398,10 @@
list_for_each(node, &adev->usecase_list) {
usecase = node_to_item(node, struct audio_usecase, list);
if (usecase->id == USECASE_AUDIO_PLAYBACK_FM) {
- if (fmmod.fm_device != device) {
+ if (fmmod.fm_device != get_device_types(devices)) {
ALOGV("%s selected routing device %x current device %x"
"are different, reroute on selected device", __func__,
- fmmod.fm_device, device);
+ fmmod.fm_device, get_device_types(devices));
select_devices(adev, usecase->id);
}
}
diff --git a/hal/audio_extn/gef.c b/hal/audio_extn/gef.c
index 83e9d45..69b1e41 100644
--- a/hal/audio_extn/gef.c
+++ b/hal/audio_extn/gef.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -427,15 +427,15 @@
#endif
//this will be called from HAL to notify GEF of new device configuration
-void audio_extn_gef_notify_device_config(audio_devices_t audio_device,
+void audio_extn_gef_notify_device_config(struct listnode *audio_devices,
audio_channel_mask_t channel_mask, int sample_rate, int acdb_id, int app_type)
{
ALOGV("%s: Enter", __func__);
//call into GEF to share channel mask and device info
if (gef_hal_handle.handle && gef_hal_handle.device_config_cb) {
- gef_hal_handle.device_config_cb(gef_hal_handle.gef_ptr, audio_device, channel_mask,
- sample_rate, acdb_id, app_type);
+ gef_hal_handle.device_config_cb(gef_hal_handle.gef_ptr, get_device_types(audio_devices),
+ channel_mask, sample_rate, acdb_id, app_type);
}
ALOGV("%s: Exit", __func__);
diff --git a/hal/audio_extn/hfp.c b/hal/audio_extn/hfp.c
index e646bc1..2b63277 100644
--- a/hal/audio_extn/hfp.c
+++ b/hal/audio_extn/hfp.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
@@ -309,7 +309,7 @@
uc_info->id = hfpmod.ucid;
uc_info->type = PCM_HFP_CALL;
uc_info->stream.out = adev->primary_output;
- uc_info->devices = adev->primary_output->devices;
+ assign_devices(&uc_info->device_list, &adev->primary_output->device_list);
uc_info->in_snd_device = SND_DEVICE_NONE;
uc_info->out_snd_device = SND_DEVICE_NONE;
@@ -440,6 +440,8 @@
{
int32_t ret = 0;
struct audio_usecase *uc_info;
+ struct listnode *node;
+ struct audio_device_info *item = NULL;
ALOGD("%s: enter", __func__);
hfpmod.is_hfp_running = false;
@@ -484,7 +486,7 @@
}
/* 2. Disable echo reference while stopping hfp */
- fp_platform_set_echo_reference(adev, false, uc_info->devices);
+ fp_platform_set_echo_reference(adev, false, &uc_info->device_list);
/* 3. Get and set stream specific mixer controls */
fp_disable_audio_route(adev, uc_info);
diff --git a/hal/audio_extn/hw_loopback.c b/hal/audio_extn/hw_loopback.c
index afc029b..0b81fde 100644
--- a/hal/audio_extn/hw_loopback.c
+++ b/hal/audio_extn/hw_loopback.c
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -496,7 +496,8 @@
uc_info_rx->id = USECASE_AUDIO_TRANSCODE_LOOPBACK_RX;
uc_info_rx->type = audio_loopback_mod->uc_type_rx;
uc_info_rx->stream.inout = &active_loopback_patch->patch_stream;
- uc_info_rx->devices = active_loopback_patch->patch_stream.out_config.devices;
+ assign_devices(&uc_info_rx->device_list,
+ &active_loopback_patch->patch_stream.out_config.device_list);
uc_info_rx->in_snd_device = SND_DEVICE_NONE;
uc_info_rx->out_snd_device = SND_DEVICE_NONE;
@@ -504,7 +505,8 @@
uc_info_tx->id = USECASE_AUDIO_TRANSCODE_LOOPBACK_TX;
uc_info_tx->type = audio_loopback_mod->uc_type_tx;
uc_info_tx->stream.inout = &active_loopback_patch->patch_stream;
- uc_info_tx->devices = active_loopback_patch->patch_stream.in_config.devices;
+ assign_devices(&uc_info_tx->device_list,
+ &active_loopback_patch->patch_stream.in_config.device_list);
uc_info_tx->in_snd_device = SND_DEVICE_NONE;
uc_info_tx->out_snd_device = SND_DEVICE_NONE;
@@ -678,7 +680,7 @@
stream_cfg->sample_rate = port_cfg->sample_rate;
stream_cfg->channel_mask = port_cfg->channel_mask;
stream_cfg->format = port_cfg->format;
- stream_cfg->devices = port_cfg->ext.device.type;
+ reassign_device_list(&stream_cfg->device_list, port_cfg->ext.device.type, "");
stream_cfg->bit_width = format_to_bitwidth(port_cfg->format);
}
/* API to create audio patch */
diff --git a/hal/audio_extn/keep_alive.c b/hal/audio_extn/keep_alive.c
index 79f2bb0..15725b2 100644
--- a/hal/audio_extn/keep_alive.c
+++ b/hal/audio_extn/keep_alive.c
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
+* Copyright (c) 2014-2018, 2020, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -72,7 +72,7 @@
ka_mode_t prev_mode;
bool done;
void * userdata;
- audio_devices_t active_devices;
+ struct listnode active_devices;
} keep_alive_t;
struct keep_alive_cmd {
@@ -128,7 +128,7 @@
}
ka.done = false;
ka.prev_mode = KEEP_ALIVE_OUT_NONE;
- ka.active_devices = AUDIO_DEVICE_NONE;
+ list_init(&ka.active_devices);
pthread_mutex_init(&ka.lock, (const pthread_mutexattr_t *) NULL);
pthread_cond_init(&ka.cond, (const pthread_condattr_t *) NULL);
@@ -164,38 +164,38 @@
ALOGV("%s deinit done", __func__);
}
-audio_devices_t get_device_id_from_mode(ka_mode_t ka_mode)
+void get_device_id_from_mode(ka_mode_t ka_mode,
+ struct listnode *out_devices)
{
struct audio_device * adev = (struct audio_device *)ka.userdata;
- audio_devices_t out_device = AUDIO_DEVICE_NONE;
+
switch (ka_mode)
{
case KEEP_ALIVE_OUT_PRIMARY:
if (adev->primary_output) {
- if (adev->primary_output->devices & AUDIO_DEVICE_OUT_ALL)
- out_device = adev->primary_output->devices & AUDIO_DEVICE_OUT_ALL;
+ if (is_audio_out_device_type(&adev->primary_output->device_list))
+ assign_output_devices(out_devices, &adev->primary_output->device_list);
else
- out_device = AUDIO_DEVICE_OUT_SPEAKER;
+ reassign_device_list(out_devices, AUDIO_DEVICE_OUT_SPEAKER, "");
}
else {
- out_device = AUDIO_DEVICE_OUT_SPEAKER;
+ reassign_device_list(out_devices, AUDIO_DEVICE_OUT_SPEAKER, "");
}
break;
case KEEP_ALIVE_OUT_HDMI:
- out_device = AUDIO_DEVICE_OUT_AUX_DIGITAL;
+ reassign_device_list(out_devices, AUDIO_DEVICE_OUT_AUX_DIGITAL, "");
break;
-
+ case KEEP_ALIVE_OUT_NONE:
default:
- out_device = AUDIO_DEVICE_NONE;
+ break;
}
- return out_device;
}
void keep_alive_start(ka_mode_t ka_mode)
{
struct audio_device * adev = (struct audio_device *)ka.userdata;
- audio_devices_t out_devices = AUDIO_DEVICE_NONE;
+ struct listnode out_devices;
pthread_mutex_lock(&ka.lock);
ALOGV("%s: mode %x", __func__, ka_mode);
@@ -204,27 +204,32 @@
goto exit;
}
- out_devices = get_device_id_from_mode(ka_mode);
- if ((out_devices == ka.active_devices) && (ka.state == STATE_ACTIVE)) {
- ALOGV(" %s : Already feeding silence to device %x",__func__, out_devices);
+ list_init(&out_devices);
+ get_device_id_from_mode(ka_mode, &out_devices);
+ if (compare_devices(&out_devices, &ka.active_devices) &&
+ (ka.state == STATE_ACTIVE)) {
+ ALOGV(" %s : Already feeding silence to device %x",__func__,
+ get_device_types(&out_devices));
ka.prev_mode |= ka_mode;
goto exit;
}
- ALOGV(" %s : active devices %x, new device %x",__func__, ka.active_devices, out_devices);
+ ALOGV(" %s : active devices %x, new device %x",__func__,
+ get_device_types(&ka.active_devices), get_device_types(&out_devices));
- if (out_devices == AUDIO_DEVICE_NONE)
+ if (list_empty(&out_devices))
goto exit;
if (audio_extn_passthru_is_active()) {
- ka.active_devices &= ~AUDIO_DEVICE_OUT_AUX_DIGITAL;
- if(ka.active_devices == AUDIO_DEVICE_NONE)
+ update_device_list(&ka.active_devices, AUDIO_DEVICE_OUT_AUX_DIGITAL,
+ "", false);
+ if (list_empty(&ka.active_devices))
goto exit;
}
- ka.active_devices |= out_devices;
+ append_devices(&ka.active_devices, &out_devices);
ka.prev_mode |= ka_mode;
if (ka.state == STATE_ACTIVE) {
- ka.out->devices = ka.active_devices;
+ assign_devices(&ka.out->device_list, &ka.active_devices);
select_devices(adev, USECASE_AUDIO_PLAYBACK_SILENCE);
} else if (ka.state == STATE_IDLE) {
keep_alive_start_l();
@@ -263,7 +268,7 @@
}
ka.out->flags = 0;
- ka.out->devices = ka.active_devices;
+ assign_devices(&ka.out->device_list, &ka.active_devices);
ka.out->dev = adev;
ka.out->format = AUDIO_FORMAT_PCM_16_BIT;
ka.out->sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
@@ -274,6 +279,7 @@
usecase->stream.out = ka.out;
usecase->type = PCM_PLAYBACK;
usecase->id = USECASE_AUDIO_PLAYBACK_SILENCE;
+ list_init(&usecase->device_list);
usecase->out_snd_device = SND_DEVICE_NONE;
usecase->in_snd_device = SND_DEVICE_NONE;
@@ -304,7 +310,7 @@
void keep_alive_stop(ka_mode_t ka_mode)
{
struct audio_device * adev = (struct audio_device *)ka.userdata;
- audio_devices_t out_devices;
+ struct listnode out_devices;
if (ka.state == STATE_DISABLED)
return;
@@ -312,21 +318,23 @@
ALOGV("%s: mode %x", __func__, ka_mode);
if (ka_mode && (ka.state != STATE_ACTIVE)) {
+ get_device_id_from_mode(ka_mode, &out_devices);
ALOGV(" %s : Can't stop, keep_alive",__func__);
- ALOGV(" %s : keep_alive is not running on device %x",__func__, get_device_id_from_mode(ka_mode));
+ ALOGV(" %s : keep_alive is not running on device %x",__func__,
+ get_device_types(&out_devices));
ka.prev_mode |= ka_mode;
goto exit;
}
- out_devices = get_device_id_from_mode(ka_mode);
+ get_device_id_from_mode(ka_mode, &out_devices);
if (ka.prev_mode & ka_mode) {
ka.prev_mode &= ~ka_mode;
- ka.active_devices = get_device_id_from_mode(ka.prev_mode);
+ get_device_id_from_mode(ka.prev_mode, &ka.active_devices);
}
- if (ka.active_devices == AUDIO_DEVICE_NONE) {
+ if (list_empty(&ka.active_devices)) {
keep_alive_cleanup();
- } else if (ka.out->devices != ka.active_devices){
- ka.out->devices = ka.active_devices;
+ } else if (!compare_devices(&ka.out->device_list, &ka.active_devices)) {
+ assign_devices(&ka.out->device_list, &ka.active_devices);
select_devices(adev, USECASE_AUDIO_PLAYBACK_SILENCE);
}
exit:
@@ -362,7 +370,7 @@
}
pcm_close(ka.pcm);
ka.pcm = NULL;
- ka.active_devices = KEEP_ALIVE_OUT_NONE;
+ clear_devices(&ka.active_devices);
return 0;
}
diff --git a/hal/audio_extn/maxxaudio.c b/hal/audio_extn/maxxaudio.c
index a8f09fc..88de2f2 100644
--- a/hal/audio_extn/maxxaudio.c
+++ b/hal/audio_extn/maxxaudio.c
@@ -100,7 +100,7 @@
typedef struct ma_audio_cal_common_settings {
unsigned int app_type;
- unsigned int device;
+ struct listnode devices;
} ma_audio_cal_common_settings_t;
struct ma_audio_cal_settings {
@@ -237,16 +237,16 @@
(usecase->id == USECASE_AUDIO_PLAYBACK_LOW_LATENCY) ||
(usecase->id == USECASE_AUDIO_PLAYBACK_OFFLOAD)) &&
/* support devices */
- ((usecase->devices & AUDIO_DEVICE_OUT_SPEAKER) ||
- (usecase->devices & AUDIO_DEVICE_OUT_SPEAKER_SAFE) ||
- (audio_is_usb_out_device(usecase->devices) &&
+ (compare_device_type(&usecase->device_list, AUDIO_DEVICE_OUT_SPEAKER) ||
+ compare_device_type(&usecase->device_list, AUDIO_DEVICE_OUT_SPEAKER_SAFE) ||
+ (is_usb_out_device_type(&usecase->device_list) &&
ma_supported_usb())))
/* TODO: enable A2DP when it is ready */
return true;
ALOGV("%s: not support type %d usecase %d device %d",
- __func__, usecase->type, usecase->id, usecase->devices);
+ __func__, usecase->type, usecase->id, get_device_types(&usecase->device_list));
return false;
}
@@ -268,7 +268,9 @@
ma_cal->version.major = AUDIO_CAL_SETTINGS_VERSION_MAJOR_DEFAULT;
ma_cal->version.minor = AUDIO_CAL_SETTINGS_VERSION_MINOR_DEFAULT;
ma_cal->common.app_type = APP_TYPE_DEFAULT;
- ma_cal->common.device = DEVICE_DEFAULT;
+ list_init(&ma_cal->common.devices);
+ update_device_list(&ma_cal->common.devices, DEVICE_DEFAULT,
+ "", true);
ma_cal->effect_scope_flag = EFFECTIVE_SCOPE_ALL;
}
@@ -286,10 +288,10 @@
usecase = node_to_item(node, struct audio_usecase, list);
if (usecase->stream.out && valid_usecase(usecase)) {
ma_cal.common.app_type = usecase->stream.out->app_type_cfg.app_type;
- ma_cal.common.device = usecase->stream.out->devices;
+ assign_devices(&ma_cal.common.devices, &usecase->stream.out->device_list);
ALOGV("%s: send usecase(%d) app_type(%d) device(%d)",
__func__, usecase->id, ma_cal.common.app_type,
- ma_cal.common.device);
+ get_device_types(&ma_cal.common.devices));
switch (cmd) {
case MA_CMD_VOL:
@@ -304,7 +306,8 @@
case MA_CMD_SWAP_ENABLE:
/* lr swap only enable for speaker path */
- if (ma_cal.common.device & AUDIO_DEVICE_OUT_SPEAKER) {
+ if (compare_device_type(&ma_cal.common.devices,
+ AUDIO_DEVICE_OUT_SPEAKER)) {
ret = ma_set_lr_swap_l(&ma_cal, true);
if (ret)
ALOGV("ma_set_lr_swap_l enable returned with success.");
@@ -322,7 +325,8 @@
break;
case MA_CMD_ROTATE_ENABLE:
- if (ma_cal.common.device & AUDIO_DEVICE_OUT_SPEAKER) {
+ if (compare_device_type(&ma_cal.common.devices,
+ AUDIO_DEVICE_OUT_SPEAKER)) {
ret = ma_set_orientation_l(&ma_cal, my_data->dispaly_orientation);
if (ret)
ALOGV("ma_set_orientation_l %d returned with success.",
@@ -692,16 +696,17 @@
/* update audio_cal and send it */
ma_cal.common.app_type = usecase->stream.out->app_type_cfg.app_type;
- ma_cal.common.device = usecase->stream.out->devices;
+ assign_devices(&ma_cal.common.devices, &usecase->stream.out->device_list);
ALOGV("%s: send usecase(%d) app_type(%d) device(%d)",
__func__, usecase->id, ma_cal.common.app_type,
- ma_cal.common.device);
+ get_device_types(&ma_cal.common.devices));
pthread_mutex_lock(&my_data->lock);
if (is_active()) {
- if (ma_cal.common.device & AUDIO_DEVICE_OUT_SPEAKER) {
+ if (compare_device_type(&ma_cal.common.devices,
+ AUDIO_DEVICE_OUT_SPEAKER)) {
if (my_data->orientation_used)
ma_set_rotation_l(usecase->stream.out->dev,
my_data->dispaly_orientation);
diff --git a/hal/audio_extn/passthru.c b/hal/audio_extn/passthru.c
index 78a5b7f..293ffac 100644
--- a/hal/audio_extn/passthru.c
+++ b/hal/audio_extn/passthru.c
@@ -256,7 +256,7 @@
#else
compr_passthr = out->compr_config.codec->compr_passthr;
#endif
- if ((out->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) &&
+ if (compare_device_type(&out->device_list, AUDIO_DEVICE_OUT_AUX_DIGITAL) &&
(((out->format & AUDIO_FORMAT_MAIN_MASK) == AUDIO_FORMAT_PCM) ||
((out->compr_config.codec != NULL) && (compr_passthr == LEGACY_PCM)))) {
if (android_atomic_acquire_load(&compress_passthru_active) > 0) {
@@ -292,7 +292,7 @@
list_for_each(node, &adev->usecase_list) {
usecase = node_to_item(node, struct audio_usecase, list);
if (usecase->stream.out && usecase->type == PCM_PLAYBACK &&
- usecase->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
+ compare_device_type(&usecase->device_list, AUDIO_DEVICE_OUT_AUX_DIGITAL)) {
o = usecase->stream.out;
temp = o->config.period_size * 1000000LL / o->sample_rate;
if (temp > max_period_us)
@@ -321,7 +321,7 @@
android_atomic_dec(&compress_passthru_active);
}
- if (out->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
+ if (compare_device_type(&out->device_list, AUDIO_DEVICE_OUT_AUX_DIGITAL)) {
ALOGD("%s: passthru on aux digital, start keep alive", __func__);
fp_audio_extn_keep_alive_start(KEEP_ALIVE_OUT_HDMI);
}
@@ -502,7 +502,7 @@
}
//check supported device, currently only on HDMI.
- if (out->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
+ if (compare_device_type(&out->device_list, AUDIO_DEVICE_OUT_AUX_DIGITAL)) {
//passthrough flag
if (out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_PASSTHROUGH)
return true;
diff --git a/hal/audio_extn/qaf.c b/hal/audio_extn/qaf.c
index 4ec524e..46e625d 100644
--- a/hal/audio_extn/qaf.c
+++ b/hal/audio_extn/qaf.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -464,7 +464,9 @@
}
if ((p_qaf->qaf_mod[i].stream_out[QAF_OUT_OFFLOAD])
- && (p_qaf->qaf_mod[i].stream_out[QAF_OUT_OFFLOAD]->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL)) {
+ && compare_device_type(
+ &p_qaf->qaf_mod[i].stream_out[QAF_OUT_OFFLOAD]->device_list,
+ AUDIO_DEVICE_OUT_AUX_DIGITAL)) {
adev_close_output_stream((struct audio_hw_device *)p_qaf->adev,
(struct audio_stream_out *)(p_qaf->qaf_mod[i].stream_out[QAF_OUT_OFFLOAD]));
p_qaf->qaf_mod[i].stream_out[QAF_OUT_OFFLOAD] = NULL;
@@ -525,7 +527,7 @@
config.offload_info.channel_mask = config.channel_mask = out->channel_mask;
//Device is copied from the QAF passthrough input stream.
- devices = out->devices;
+ devices = get_device_types(&out->device_list);
flags = out->flags;
ret = adev_open_output_stream((struct audio_hw_device *)p_qaf->adev,
@@ -711,7 +713,7 @@
ALOGD("%s: enter: stream(%p)usecase(%d: %s) devices(%#x)",
__func__, &out->stream, out->usecase, use_case_table[out->usecase],
- out->devices);
+ get_device_types(&out->device_list));
if (CARD_STATUS_OFFLINE == out->card_status ||
CARD_STATUS_OFFLINE == adev->card_status) {
@@ -781,7 +783,8 @@
}
}
- if ((adev->is_channel_status_set == false) && (out->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL)) {
+ if ((adev->is_channel_status_set == false) &&
+ compare_device_type(&out->device_list, AUDIO_DEVICE_OUT_AUX_DIGITAL)) {
audio_utils_set_hdmi_channel_status(out, (char *)buffer, bytes);
adev->is_channel_status_set = true;
}
@@ -1637,9 +1640,9 @@
audio_devices_t devices;
if (qaf_mod->stream_in[QAF_IN_MAIN])
- devices = qaf_mod->stream_in[QAF_IN_MAIN]->devices;
+ devices = get_device_types(&qaf_mod->stream_in[QAF_IN_MAIN]->device_list);
else
- devices = qaf_mod->stream_in[QAF_IN_PCM]->devices;
+ devices = get_device_types(&qaf_mod->stream_in[QAF_IN_PCM]->device_list);
//If multi channel pcm or passthrough is already enabled then remove the hdmi flag from device.
if (p_qaf->mch_pcm_hdmi_enabled || p_qaf->passthrough_enabled) {
@@ -2348,7 +2351,7 @@
/* Setting new device information to the mm module input streams.
* This is needed if QAF module output streams are not created yet.
*/
- out->devices = val;
+ reassign_device_list(&out->device_list, val, "");
#ifndef A2DP_OFFLOAD_ENABLED
if (val == AUDIO_DEVICE_OUT_BLUETOOTH_A2DP) {
diff --git a/hal/audio_extn/qap.c b/hal/audio_extn/qap.c
index 0625737..30ebe6d 100644
--- a/hal/audio_extn/qap.c
+++ b/hal/audio_extn/qap.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -431,7 +431,9 @@
}
if ((p_qap->qap_mod[i].stream_out[QAP_OUT_OFFLOAD])
- && (p_qap->qap_mod[i].stream_out[QAP_OUT_OFFLOAD]->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL)) {
+ && compare_device_type(
+ &p_qap->qap_mod[i].stream_out[QAP_OUT_OFFLOAD]->device_list,
+ AUDIO_DEVICE_OUT_AUX_DIGITAL)) {
adev_close_output_stream((struct audio_hw_device *)p_qap->adev,
(struct audio_stream_out *)(p_qap->qap_mod[i].stream_out[QAP_OUT_OFFLOAD]));
p_qap->qap_mod[i].stream_out[QAP_OUT_OFFLOAD] = NULL;
@@ -492,7 +494,7 @@
config.offload_info.channel_mask = config.channel_mask = out->channel_mask;
//Device is copied from the QAP passthrough input stream.
- devices = out->devices;
+ devices = get_device_types(&out->device_list);
flags = out->flags;
ret = adev_open_output_stream((struct audio_hw_device *)p_qap->adev,
@@ -870,7 +872,7 @@
ALOGD("%s: enter: stream(%p)usecase(%d: %s) devices(%#x)",
__func__, &out->stream, out->usecase, use_case_table[out->usecase],
- out->devices);
+ get_device_types(&out->device_list));
if (CARD_STATUS_OFFLINE == out->card_status ||
CARD_STATUS_OFFLINE == adev->card_status) {
@@ -959,7 +961,8 @@
}
}
- if ((adev->is_channel_status_set == false) && (out->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL)) {
+ if ((adev->is_channel_status_set == false) &&
+ compare_device_type(&out->device_list, AUDIO_DEVICE_OUT_AUX_DIGITAL)) {
audio_utils_set_hdmi_channel_status(out, (char *)buffer, bytes);
adev->is_channel_status_set = true;
}
@@ -1759,9 +1762,9 @@
audio_devices_t devices;
if (qap_mod->stream_in[QAP_IN_MAIN])
- devices = qap_mod->stream_in[QAP_IN_MAIN]->devices;
+ devices = get_device_types(&qap_mod->stream_in[QAP_IN_MAIN]->device_list);
else
- devices = qap_mod->stream_in[QAP_IN_PCM]->devices;
+ devices = get_device_types(&qap_mod->stream_in[QAP_IN_PCM]->device_list);
//If multi channel pcm or passthrough is already enabled then remove the hdmi flag from device.
if (p_qap->mch_pcm_hdmi_enabled || p_qap->passthrough_enabled) {
@@ -2595,6 +2598,7 @@
int ret = 0;
int err = 0;
struct qap_module *qap_mod = NULL;
+ char *address = "";
DEBUG_MSG("usecase(%d: %s) kvpairs: %s", out->usecase, use_case_table[out->usecase], kvpairs);
@@ -2612,7 +2616,7 @@
/* Setting new device information to the mm module input streams.
* This is needed if QAP module output streams are not created yet.
*/
- out->devices = val;
+ reassign_device_list(&out->device_list, val, address);
#ifndef SPLIT_A2DP_ENABLED
if (val == AUDIO_DEVICE_OUT_BLUETOOTH_A2DP) {
diff --git a/hal/audio_extn/soundtrigger.c b/hal/audio_extn/soundtrigger.c
index a175b83..4ef3581 100644
--- a/hal/audio_extn/soundtrigger.c
+++ b/hal/audio_extn/soundtrigger.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2014, 2016-2019 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2014, 2016-2020, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -53,9 +53,8 @@
#define MINOR_VERSION(ver) ((ver) & 0x00ff)
/* Proprietary interface version used for compatibility with STHAL */
-#define STHAL_PROP_API_VERSION_1_0 MAKE_HAL_VERSION(1, 0)
-#define STHAL_PROP_API_VERSION_1_1 MAKE_HAL_VERSION(1, 1)
-#define STHAL_PROP_API_CURRENT_VERSION STHAL_PROP_API_VERSION_1_1
+#define STHAL_PROP_API_VERSION_2_0 MAKE_HAL_VERSION(2, 0)
+#define STHAL_PROP_API_CURRENT_VERSION STHAL_PROP_API_VERSION_2_0
#define ST_EVENT_CONFIG_MAX_STR_VALUE 32
#define ST_DEVICE_HANDSET_MIC 1
@@ -129,7 +128,7 @@
typedef struct sound_trigger_event_info sound_trigger_event_info_t;
struct sound_trigger_device_info {
- int device;
+ struct listnode devices;
};
struct sound_trigger_get_param_data {
@@ -571,7 +570,7 @@
struct audio_event_info ev_info;
audio_event_type_t ev;
/*Initialize to invalid device*/
- ev_info.device_info.device = -1;
+ list_init(&ev_info.device_info.devices);
if (!st_dev)
return;
@@ -581,14 +580,10 @@
return;
}
- if ((st_dev->sthal_prop_api_version < STHAL_PROP_API_VERSION_1_0) &&
- (uc_info->type != PCM_PLAYBACK))
- return;
-
if ((uc_info->in_snd_device >= SND_DEVICE_IN_BEGIN &&
uc_info->in_snd_device < SND_DEVICE_IN_END)) {
if (is_same_as_st_device(uc_info->in_snd_device))
- ev_info.device_info.device = ST_DEVICE_HANDSET_MIC;
+ update_device_list(&ev_info.device_info.devices, ST_DEVICE_HANDSET_MIC, "", true);
} else {
ALOGE("%s: invalid input device 0x%x, for event %d",
__func__, uc_info->in_snd_device, event);
@@ -599,9 +594,10 @@
if (raise_event) {
if (uc_info->type == PCM_PLAYBACK) {
if (uc_info->stream.out)
- ev_info.device_info.device = uc_info->stream.out->devices;
+ assign_devices(&ev_info.device_info.devices, &uc_info->stream.out->device_list);
else
- ev_info.device_info.device = AUDIO_DEVICE_OUT_SPEAKER;
+ reassign_device_list(&ev_info.device_info.devices,
+ AUDIO_DEVICE_OUT_SPEAKER, "");
switch(event) {
case ST_EVENT_STREAM_FREE:
st_dev->st_callback(AUDIO_EVENT_PLAYBACK_STREAM_INACTIVE, &ev_info);
@@ -629,9 +625,9 @@
void audio_extn_sound_trigger_update_battery_status(bool charging)
{
- struct audio_event_info ev_info;
+ struct audio_event_info ev_info = {{0}, {0}};
- if (!st_dev || st_dev->sthal_prop_api_version < STHAL_PROP_API_VERSION_1_0)
+ if (!st_dev)
return;
ev_info.u.value = charging;
diff --git a/hal/audio_extn/source_track.c b/hal/audio_extn/source_track.c
index 064fad8..9705d55 100644
--- a/hal/audio_extn/source_track.c
+++ b/hal/audio_extn/source_track.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -230,7 +230,7 @@
if (usecase && (usecase->id != USECASE_AUDIO_SPKR_CALIB_TX)) {
if (is_stt_supported_snd_device(usecase->in_snd_device)) {
- in_device = get_input_audio_device(usecase->devices);
+ in_device = get_input_audio_device(get_device_types(&usecase->device_list));
ret = add_audio_intf_name_to_mixer_ctl(in_device, mixer_ctl_name,
audio_device_to_interface_table, audio_device_to_interface_table_len);
} else {
diff --git a/hal/audio_extn/ssr.c b/hal/audio_extn/ssr.c
index d83b508..8cb7b4e 100644
--- a/hal/audio_extn/ssr.c
+++ b/hal/audio_extn/ssr.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2018, 2020, The Linux Foundation. All rights reserved.
* Not a Contribution.
*
* Copyright (C) 2013 The Android Open Source Project
@@ -339,7 +339,7 @@
bool ssr_check_usecase(struct stream_in *in) {
int ret = false;
int channel_count = audio_channel_count_from_in_mask(in->channel_mask);
- audio_devices_t devices = in->device;
+ audio_devices_t devices = get_device_types(&in->device_list);
audio_source_t source = in->source;
if ((ssr_get_enabled()) &&
diff --git a/hal/audio_extn/usb.c b/hal/audio_extn/usb.c
index a2d559d..531c4b2 100644
--- a/hal/audio_extn/usb.c
+++ b/hal/audio_extn/usb.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2016-2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013, 2016-2020, The Linux Foundation. All rights reserved.
* Not a Contribution.
*
* Copyright (C) 2013 The Android Open Source Project
@@ -1472,7 +1472,7 @@
list_for_each(node, &adev->usecase_list) {
usecase = node_to_item(node, struct audio_usecase, list);
if (usecase->type == PCM_PLAYBACK &&
- audio_is_usb_out_device(usecase->devices & AUDIO_DEVICE_OUT_ALL_USB )) {
+ is_usb_out_device_type(&usecase->device_list)) {
switch (usecase->id) {
case USECASE_AUDIO_PLAYBACK_MMAP:
case USECASE_AUDIO_PLAYBACK_ULL:
diff --git a/hal/audio_extn/utils.c b/hal/audio_extn/utils.c
index 92887f0..e56fee3 100644
--- a/hal/audio_extn/utils.c
+++ b/hal/audio_extn/utils.c
@@ -672,7 +672,7 @@
void audio_extn_utils_update_stream_input_app_type_cfg(void *platform,
struct listnode *streams_input_cfg_list,
- audio_devices_t devices __unused,
+ struct listnode *devices __unused,
audio_input_flags_t flags,
audio_format_t format,
uint32_t sample_rate,
@@ -710,7 +710,7 @@
void audio_extn_utils_update_stream_output_app_type_cfg(void *platform,
struct listnode *streams_output_cfg_list,
- audio_devices_t devices,
+ struct listnode *devices,
audio_output_flags_t flags,
audio_format_t format,
uint32_t sample_rate,
@@ -724,7 +724,7 @@
struct stream_format *sf_info;
char value[PROPERTY_VALUE_MAX] = {0};
- if (devices & AUDIO_DEVICE_OUT_SPEAKER) {
+ if (compare_device_type(devices, AUDIO_DEVICE_OUT_SPEAKER)) {
int bw = platform_get_snd_device_bit_width(SND_DEVICE_OUT_SPEAKER);
if ((-ENOSYS != bw) && (bit_width > (uint32_t)bw))
bit_width = (uint32_t)bw;
@@ -866,7 +866,7 @@
case PCM_PLAYBACK:
audio_extn_utils_update_stream_output_app_type_cfg(adev->platform,
&adev->streams_output_cfg_list,
- usecase->stream.out->devices,
+ &usecase->stream.out->device_list,
usecase->stream.out->flags,
usecase->stream.out->hal_op_format,
usecase->stream.out->sample_rate,
@@ -882,7 +882,7 @@
else
audio_extn_utils_update_stream_input_app_type_cfg(adev->platform,
&adev->streams_input_cfg_list,
- usecase->stream.in->device,
+ &usecase->stream.in->device_list,
usecase->stream.in->flags,
usecase->stream.in->format,
usecase->stream.in->sample_rate,
@@ -894,7 +894,7 @@
case TRANSCODE_LOOPBACK_RX :
audio_extn_utils_update_stream_output_app_type_cfg(adev->platform,
&adev->streams_output_cfg_list,
- usecase->stream.inout->out_config.devices,
+ &usecase->stream.inout->out_config.device_list,
0,
usecase->stream.inout->out_config.format,
usecase->stream.inout->out_config.sample_rate,
@@ -1012,7 +1012,7 @@
goto exit_send_app_type_cfg;
}
- if (usecase->devices & AUDIO_DEVICE_OUT_BUS)
+ if (compare_device_type(&usecase->device_list, AUDIO_DEVICE_OUT_BUS))
is_bus_dev_usecase = true;
snd_device = usecase->out_snd_device;
@@ -1118,7 +1118,8 @@
if (usecase->id == USECASE_AUDIO_PLAYBACK_VOIP) {
usecase->stream.out->app_type_cfg.sample_rate = usecase->stream.out->sample_rate;
- } else if (usecase->stream.out->devices & AUDIO_DEVICE_OUT_SPEAKER) {
+ } else if (compare_device_type(&usecase->stream.out->device_list,
+ AUDIO_DEVICE_OUT_SPEAKER)) {
usecase->stream.out->app_type_cfg.sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
} else if ((snd_device == SND_DEVICE_OUT_HDMI ||
snd_device == SND_DEVICE_OUT_USB_HEADSET ||
@@ -1138,7 +1139,7 @@
(usecase->stream.out->sample_rate < OUTPUT_SAMPLING_RATE_44100)) {
/* Reset to default if no native stream is active*/
usecase->stream.out->app_type_cfg.sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
- } else if (usecase->stream.out->devices & AUDIO_DEVICE_OUT_ALL_A2DP) {
+ } else if (is_a2dp_out_device_type(&usecase->stream.out->device_list)) {
/*
* For a2dp playback get encoder sampling rate and set copp sampling rate,
* for bit width use the stream param only.
@@ -2101,7 +2102,7 @@
backend = platform_get_snd_device_backend_interface(usecase->out_snd_device);
if (!backend) {
ALOGE("%s: Unsupported device %d", __func__,
- usecase->stream.out->devices);
+ get_device_types(&usecase->stream.out->device_list));
ret = -EINVAL;
goto done;
}