diff --git a/hal/audio_extn/audio_extn.c b/hal/audio_extn/audio_extn.c index f4574627..43c63570 100644 --- a/hal/audio_extn/audio_extn.c +++ b/hal/audio_extn/audio_extn.c @@ -5748,6 +5748,7 @@ int audio_extn_auto_hal_init(struct audio_device *adev) auto_hal_init_config.fp_adev_get_active_input = adev_get_active_input; auto_hal_init_config.fp_platform_set_echo_reference = platform_set_echo_reference; auto_hal_init_config.fp_platform_get_eccarstate = platform_get_eccarstate; + auto_hal_init_config.fp_generate_patch_handle = generate_patch_handle; return auto_hal_init(adev, auto_hal_init_config); } else diff --git a/hal/audio_extn/audio_extn.h b/hal/audio_extn/audio_extn.h index 82a4b256..dc6efe17 100644 --- a/hal/audio_extn/audio_extn.h +++ b/hal/audio_extn/audio_extn.h @@ -1346,6 +1346,7 @@ typedef streams_output_ctxt_t* (*fp_out_get_stream_t)(struct audio_device*, audi typedef size_t (*fp_get_output_period_size_t)(uint32_t, audio_format_t, int, int); typedef int (*fp_audio_extn_ext_hw_plugin_set_audio_gain_t)(void*, struct audio_usecase*, uint32_t); typedef struct stream_in* (*fp_adev_get_active_input_t)(const struct audio_device*); +typedef audio_patch_handle_t (*fp_generate_patch_handle_t)(void); typedef struct auto_hal_init_config { fp_in_get_stream_t fp_in_get_stream; @@ -1361,6 +1362,7 @@ typedef struct auto_hal_init_config { fp_adev_get_active_input_t fp_adev_get_active_input; fp_platform_set_echo_reference_t fp_platform_set_echo_reference; fp_platform_get_eccarstate_t fp_platform_get_eccarstate; + fp_generate_patch_handle_t fp_generate_patch_handle; } auto_hal_init_config_t; // END: AUTO_HAL FEATURE ================================================== diff --git a/hal/audio_extn/auto_hal.c b/hal/audio_extn/auto_hal.c index 795a2896..0331aab6 100644 --- a/hal/audio_extn/auto_hal.c +++ b/hal/audio_extn/auto_hal.c @@ -60,6 +60,7 @@ static fp_disable_snd_device_t fp_disable_snd_device; static fp_adev_get_active_input_t fp_adev_get_active_input; static fp_platform_set_echo_reference_t fp_platform_set_echo_reference; static fp_platform_get_eccarstate_t fp_platform_get_eccarstate; +static fp_generate_patch_handle_t fp_generate_patch_handle; /* Auto hal module struct */ static struct auto_hal_module *auto_hal = NULL; @@ -91,14 +92,9 @@ int auto_hal_create_audio_patch(struct audio_hw_device *dev, { struct audio_device *adev = (struct audio_device *)dev; int ret = 0; - char *str = NULL; - struct str_parms *parms = NULL; - char *address = NULL; struct audio_usecase *uc_info = NULL; struct audio_patch_record *patch_record = NULL; audio_usecase_t usecase = USECASE_INVALID; - audio_io_handle_t input_io_handle = AUDIO_IO_HANDLE_NONE; - audio_io_handle_t output_io_handle = AUDIO_IO_HANDLE_NONE; ALOGV("%s: enter", __func__); @@ -115,17 +111,6 @@ int auto_hal_create_audio_patch(struct audio_hw_device *dev, return -EINVAL; } - /* Release patch if valid handle */ - if (*handle != AUDIO_PATCH_HANDLE_NONE) { - ret = auto_hal_release_audio_patch(dev, - *handle); - if (ret) { - ALOGE("%s: failed to release audio patch 0x%x", __func__, *handle); - return ret; - } - *handle = AUDIO_PATCH_HANDLE_NONE; - } - /* No validation on num of sources and sinks to allow patch with * multiple sinks being created, but only the first source and * sink are used to create patch. @@ -138,84 +123,12 @@ int auto_hal_create_audio_patch(struct audio_hw_device *dev, * Playback: MIX -> DEVICE * For DEVICE -> DEVICE patch type, it refers to routing from/to external * codec/amplifier and allow Android streams to be mixed at the H/W level. + * + * Auto extension here is to act on Device to Device patch only as playback + * and capture patches as well as the book-keeeping information are already + * being handled at audio_hw entry. */ if ((sources->type == AUDIO_PORT_TYPE_DEVICE) && - (sinks->type == AUDIO_PORT_TYPE_MIX)) { - pthread_mutex_lock(&adev->lock); - streams_input_ctxt_t *in_ctxt = fp_in_get_stream(adev, - sinks->ext.mix.handle); - if (!in_ctxt) { - ALOGE("%s, failed to find input stream", __func__); - ret = -EINVAL; - } - pthread_mutex_unlock(&adev->lock); - if(ret) - return ret; - input_io_handle = sinks->ext.mix.handle; - - if (strcmp(sources->ext.device.address, "") != 0) { - address = audio_device_address_to_parameter( - sources->ext.device.type, - sources->ext.device.address); - } else { - address = (char *)calloc(1, 1); - } - if (address == NULL) { - ALOGE("%s: failed to get address",__func__); - ret = -EFAULT; - goto exit; - } - parms = str_parms_create_str(address); - if (!parms) { - ALOGE("%s: failed to allocate mem for parms", __func__); - ret = -ENOMEM; - goto exit; - } - str_parms_add_int(parms, AUDIO_PARAMETER_STREAM_ROUTING, - (int)sources->ext.device.type); - str_parms_add_int(parms, AUDIO_PARAMETER_STREAM_INPUT_SOURCE, - (int)sinks->ext.mix.usecase.source); - str = str_parms_to_str(parms); - in_ctxt->input->stream.common.set_parameters( - (struct audio_stream *)in_ctxt->input, str); - } else if ((sources->type == AUDIO_PORT_TYPE_MIX) && - (sinks->type == AUDIO_PORT_TYPE_DEVICE)) { - pthread_mutex_lock(&adev->lock); - streams_output_ctxt_t *out_ctxt = fp_out_get_stream(adev, - sources->ext.mix.handle); - if (!out_ctxt) { - ALOGE("%s, failed to find output stream", __func__); - ret = -EINVAL; - } - pthread_mutex_unlock(&adev->lock); - if(ret) - return ret; - output_io_handle = sources->ext.mix.handle; - - if (strcmp(sinks->ext.device.address, "") != 0) { - address = audio_device_address_to_parameter( - sinks->ext.device.type, - sinks->ext.device.address); - } else { - address = (char *)calloc(1, 1); - } - if (address == NULL) { - ALOGE("%s: failed to get address",__func__); - ret = -EFAULT; - goto exit; - } - parms = str_parms_create_str(address); - if (!parms) { - ALOGE("%s: failed to allocate mem for parms", __func__); - ret = -ENOMEM; - goto exit; - } - str_parms_add_int(parms, AUDIO_PARAMETER_STREAM_ROUTING, - (int)sinks->ext.device.type); - str = str_parms_to_str(parms); - out_ctxt->output->stream.common.set_parameters( - (struct audio_stream *)out_ctxt->output, str); - } else if ((sources->type == AUDIO_PORT_TYPE_DEVICE) && (sinks->type == AUDIO_PORT_TYPE_DEVICE)) { /* allocate use case and call to plugin driver*/ uc_info = (struct audio_usecase *)calloc(1, sizeof(struct audio_usecase)); @@ -257,8 +170,8 @@ int auto_hal_create_audio_patch(struct audio_hw_device *dev, list_add_tail(&adev->usecase_list, &uc_info->list); pthread_mutex_unlock(&adev->lock); } else { - ALOGW("%s: audio patch not supported",__func__); - return -EINVAL; + ALOGV("%s: audio patch not supported", __func__); + goto exit; } /* patch created success, add to patch record list */ @@ -273,31 +186,29 @@ int auto_hal_create_audio_patch(struct audio_hw_device *dev, } pthread_mutex_lock(&adev->lock); - adev->audio_patch_index++; - patch_record->handle = adev->audio_patch_index; + if (*handle == AUDIO_PATCH_HANDLE_NONE) { + ALOGD("%s: audio patch handle not allocated 0x%x", __func__, *handle); + *handle = fp_generate_patch_handle(); + } + patch_record->handle = *handle; patch_record->usecase = usecase; - patch_record->input_io_handle = input_io_handle; - patch_record->output_io_handle = output_io_handle; - memcpy((void *)&patch_record->source, (void *)sources, - sizeof(struct audio_port_config)); - memcpy((void *)&patch_record->sink, (void *)sinks, - sizeof(struct audio_port_config)); + patch_record->patch.id = *handle; + patch_record->patch.num_sources = num_sources; + patch_record->patch.num_sinks = num_sinks; + for (int i = 0; i < num_sources; i++) + patch_record->patch.sources[i] = sources[i]; + for (int i = 0; i < num_sinks; i++) + patch_record->patch.sinks[i] = sinks[i]; + list_add_tail(&adev->audio_patch_record_list, &patch_record->list); pthread_mutex_unlock(&adev->lock); - *handle = patch_record->handle; goto exit; error: if(uc_info) free(uc_info); exit: - if (parms) - str_parms_destroy(parms); - if (str) - free(str); - if (address) - free(address); ALOGV("%s: exit: handle 0x%x", __func__, *handle); return ret; } @@ -309,10 +220,6 @@ int auto_hal_release_audio_patch(struct audio_hw_device *dev, struct audio_device *adev = (struct audio_device *)dev; struct audio_usecase *uc_info = NULL; struct audio_patch_record *patch_record = NULL; - streams_input_ctxt_t *in_ctxt = NULL; - streams_output_ctxt_t *out_ctxt = NULL; - char *str = NULL; - struct str_parms *parms = NULL; ALOGV("%s: enter: handle 0x%x", __func__, handle); @@ -338,42 +245,6 @@ int auto_hal_release_audio_patch(struct audio_hw_device *dev, if(ret) goto exit; - if (patch_record->input_io_handle) { - pthread_mutex_lock(&adev->lock); - in_ctxt = fp_in_get_stream(adev, patch_record->input_io_handle); - if (!in_ctxt) { - ALOGE("%s, Could not find input stream", __func__); - ret = -EINVAL; - } - pthread_mutex_unlock(&adev->lock); - if(ret) - goto exit; - - parms = str_parms_create(); - str_parms_add_int(parms, AUDIO_PARAMETER_STREAM_ROUTING, 0); - str = str_parms_to_str(parms); - in_ctxt->input->stream.common.set_parameters( - (struct audio_stream *)in_ctxt->input, str); - } - - if (patch_record->output_io_handle) { - pthread_mutex_lock(&adev->lock); - out_ctxt = fp_out_get_stream(adev, patch_record->output_io_handle); - if (!out_ctxt) { - ALOGE("%s, Could not find output stream", __func__); - ret = -EINVAL; - } - pthread_mutex_unlock(&adev->lock); - if(ret) - goto exit; - - parms = str_parms_create(); - str_parms_add_int(parms, AUDIO_PARAMETER_STREAM_ROUTING, 0); - str = str_parms_to_str(parms); - out_ctxt->output->stream.common.set_parameters( - (struct audio_stream *)out_ctxt->output, str); - } - if (patch_record->usecase != USECASE_INVALID) { pthread_mutex_lock(&adev->lock); uc_info = fp_get_usecase_from_list(adev, patch_record->usecase); @@ -401,10 +272,6 @@ int auto_hal_release_audio_patch(struct audio_hw_device *dev, list_remove(&patch_record->list); pthread_mutex_unlock(&adev->lock); free(patch_record); - if (parms) - str_parms_destroy(parms); - if (str) - free(str); exit: ALOGV("%s: exit", __func__); @@ -637,15 +504,15 @@ int auto_hal_set_audio_port_config(struct audio_hw_device *dev, struct audio_patch_record, list); /* limit audio gain support for device -> bus device patch */ - if (patch_record->source.type == AUDIO_PORT_TYPE_DEVICE && - patch_record->sink.type == AUDIO_PORT_TYPE_DEVICE && - patch_record->sink.role == AUDIO_PORT_ROLE_SINK && - patch_record->sink.ext.device.type == AUDIO_DEVICE_OUT_BUS && - patch_record->sink.ext.device.type == config->ext.device.type && - strcmp(patch_record->sink.ext.device.address, + if (patch_record->patch.sources[0].type == AUDIO_PORT_TYPE_DEVICE && + patch_record->patch.sinks[0].type == AUDIO_PORT_TYPE_DEVICE && + patch_record->patch.sinks[0].role == AUDIO_PORT_ROLE_SINK && + patch_record->patch.sinks[0].ext.device.type == AUDIO_DEVICE_OUT_BUS && + patch_record->patch.sinks[0].ext.device.type == config->ext.device.type && + strcmp(patch_record->patch.sinks[0].ext.device.address, config->ext.device.address) == 0) { /* cache audio port configuration for sink */ - memcpy((void *)&patch_record->sink, (void *)config, + memcpy((void *)&patch_record->patch.sinks[0], (void *)config, sizeof(struct audio_port_config)); struct audio_usecase *uc_info = fp_get_usecase_from_list(adev, @@ -990,6 +857,7 @@ int auto_hal_init(struct audio_device *adev, auto_hal_init_config_t init_config) fp_adev_get_active_input = init_config.fp_adev_get_active_input; fp_platform_set_echo_reference = init_config.fp_platform_set_echo_reference; fp_platform_get_eccarstate = init_config.fp_platform_get_eccarstate; + fp_generate_patch_handle = init_config.fp_generate_patch_handle; return ret; } diff --git a/hal/audio_hw.c b/hal/audio_hw.c index 29b17acb..fde99e1b 100644 --- a/hal/audio_hw.c +++ b/hal/audio_hw.c @@ -10209,7 +10209,6 @@ static int adev_open(const hw_module_t *module, const char *name, list_init(&adev->active_inputs_list); list_init(&adev->active_outputs_list); list_init(&adev->audio_patch_record_list); - adev->audio_patch_index = 0; adev->io_streams_map = hashmapCreate(AUDIO_IO_PORTS_MAX, audio_extn_utils_hash_fn, audio_extn_utils_hash_eq); if (!adev->io_streams_map) { diff --git a/hal/audio_hw.h b/hal/audio_hw.h index 1a7979e8..2718ed54 100644 --- a/hal/audio_hw.h +++ b/hal/audio_hw.h @@ -715,7 +715,6 @@ struct audio_device { int camera_orientation; /* CAMERA_BACK_LANDSCAPE ... CAMERA_FRONT_PORTRAIT */ bool adm_routing_changed; struct listnode audio_patch_record_list; - unsigned int audio_patch_index; Hashmap *patch_map; Hashmap *io_streams_map; }; @@ -724,10 +723,7 @@ struct audio_patch_record { struct listnode list; audio_patch_handle_t handle; audio_usecase_t usecase; - audio_io_handle_t input_io_handle; - audio_io_handle_t output_io_handle; - struct audio_port_config source; - struct audio_port_config sink; + struct audio_patch patch; }; int select_devices(struct audio_device *adev, @@ -801,6 +797,8 @@ int route_input_stream(struct stream_in *stream, struct listnode *devices, audio_source_t source); +audio_patch_handle_t generate_patch_handle(); + /* * NOTE: when multiple mutexes have to be acquired, always take the * stream_in or stream_out mutex first, followed by the audio_device mutex.