Merge "hal: update audio patch handling in auto hal"
diff --git a/hal/audio_extn/audio_extn.c b/hal/audio_extn/audio_extn.c
index f457462..43c6357 100644
--- a/hal/audio_extn/audio_extn.c
+++ b/hal/audio_extn/audio_extn.c
@@ -5748,6 +5748,7 @@
         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 82a4b25..dc6efe1 100644
--- a/hal/audio_extn/audio_extn.h
+++ b/hal/audio_extn/audio_extn.h
@@ -1346,6 +1346,7 @@
 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 @@
     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 85dbd20..3802199 100644
--- a/hal/audio_extn/auto_hal.c
+++ b/hal/audio_extn/auto_hal.c
@@ -60,6 +60,7 @@
 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 @@
 {
     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 @@
          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 @@
      *   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));
@@ -258,8 +171,8 @@
         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 */
@@ -274,31 +187,29 @@
     }
 
     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;
 }
@@ -310,10 +221,6 @@
     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);
 
@@ -339,42 +246,6 @@
     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);
@@ -402,10 +273,6 @@
     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__);
@@ -638,15 +505,15 @@
                                                     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,
@@ -992,6 +859,7 @@
     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 0bb9918..9b8f29d 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -10228,7 +10228,6 @@
     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 52abbaa..ce82145 100644
--- a/hal/audio_hw.h
+++ b/hal/audio_hw.h
@@ -715,7 +715,6 @@
     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 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,
@@ -816,6 +812,8 @@
                        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.