hal: add Waves command interface

Waves tuning console needs this interface to set/get parameters.

Test: set/get command successfully
Bug: 145973032

Change-Id: Ib11c1a688f73e9cef388e09180abcd85e1720bcb
Signed-off-by: justinweng <justinweng@google.com>
(cherry picked from commit e912bd5bf142732c1c8ec421ce003106113a4556)
diff --git a/hal/audio_extn/audio_extn.c b/hal/audio_extn/audio_extn.c
index 786b7181..24dd068 100644
--- a/hal/audio_extn/audio_extn.c
+++ b/hal/audio_extn/audio_extn.c
@@ -5485,6 +5485,11 @@
                                   struct str_parms *);
 static maxxaudio_set_parameters_t maxxaudio_set_parameters;
 
+typedef void (*maxxaudio_get_parameters_t)(struct audio_device *,
+                                  struct str_parms *,
+                                  struct str_parms *);
+static maxxaudio_get_parameters_t maxxaudio_get_parameters;
+
 typedef bool (*maxxaudio_supported_usb_t)();
 static maxxaudio_supported_usb_t maxxaudio_supported_usb;
 
@@ -5512,6 +5517,8 @@
                  (maxxaudio_set_device_t)dlsym(maxxaudio_lib_handle, "ma_set_device")) ||
             !(maxxaudio_set_parameters =
                  (maxxaudio_set_parameters_t)dlsym(maxxaudio_lib_handle, "ma_set_parameters")) ||
+            !(maxxaudio_get_parameters =
+                 (maxxaudio_get_parameters_t)dlsym(maxxaudio_lib_handle, "ma_get_parameters")) ||
             !(maxxaudio_supported_usb =
                  (maxxaudio_supported_usb_t)dlsym(
                                     maxxaudio_lib_handle, "ma_supported_usb"))) {
@@ -5533,6 +5540,7 @@
     maxxaudio_set_state = NULL;
     maxxaudio_set_device = NULL;
     maxxaudio_set_parameters = NULL;
+    maxxaudio_get_parameters = NULL;
     maxxaudio_supported_usb = NULL;
     ALOGW(":: %s: ---- Feature MAXX_AUDIO is disabled ----", __func__);
     return -ENOSYS;
@@ -5580,6 +5588,14 @@
         maxxaudio_set_parameters(adev, parms);
 }
 
+void audio_extn_ma_get_parameters(struct audio_device *adev,
+                                  struct str_parms *query,
+                                  struct str_parms *reply)
+{
+    if (maxxaudio_get_parameters)
+        maxxaudio_get_parameters(adev, query, reply);
+}
+
 bool audio_extn_ma_supported_usb()
 {
     return (maxxaudio_supported_usb ? maxxaudio_supported_usb(): false);
diff --git a/hal/audio_extn/audio_extn.h b/hal/audio_extn/audio_extn.h
index c71fbc3..c01954d 100644
--- a/hal/audio_extn/audio_extn.h
+++ b/hal/audio_extn/audio_extn.h
@@ -361,6 +361,9 @@
 void audio_extn_ma_set_device(struct audio_usecase *usecase);
 void audio_extn_ma_set_parameters(struct audio_device *adev,
                                   struct str_parms *parms);
+void audio_extn_ma_get_parameters(struct audio_device *adev,
+                                  struct str_parms *query,
+                                  struct str_parms *reply);
 bool audio_extn_ma_supported_usb();
 bool audio_extn_is_maxx_audio_enabled();
 // --- Function pointers from audio_extn needed by MAXX_AUDIO
diff --git a/hal/audio_extn/maxxaudio.c b/hal/audio_extn/maxxaudio.c
index 88de2f2..f1393f6 100644
--- a/hal/audio_extn/maxxaudio.c
+++ b/hal/audio_extn/maxxaudio.c
@@ -50,10 +50,14 @@
 #define MA_QDSP_SET_VOL         "maxxaudio_qdsp_set_volume"
 #define MA_QDSP_SET_VOLT        "maxxaudio_qdsp_set_volume_table"
 #define MA_QDSP_SET_PARAM       "maxxaudio_qdsp_set_parameter"
+#define MA_QDSP_SET_COMMAND     "maxxaudio_qdsp_set_command"
+#define MA_QDSP_GET_COMMAND     "maxxaudio_qdsp_get_command"
 
 #define SUPPORT_DEV "18d1:5033" // Blackbird usbid
 #define SUPPORTED_USB 0x01
 
+#define WAVES_COMMAND_SIZE 10240
+
 typedef unsigned int effective_scope_flag_t;
 const effective_scope_flag_t EFFECTIVE_SCOPE_RTC = 1 << 0;   /* RTC  */
 const effective_scope_flag_t EFFECTIVE_SCOPE_ACDB = 1 << 1;  /* ACDB */
@@ -145,6 +149,16 @@
                                const struct ma_audio_cal_settings *,
                                unsigned int, double);
 
+typedef bool (*ma_set_cmd_t)(ma_audio_cal_handle_t handle,
+                             const struct ma_audio_cal_settings *,
+                             const char*);
+
+typedef bool (*ma_get_cmd_t)(ma_audio_cal_handle_t handle,
+                             const struct ma_audio_cal_settings *,
+                             const char *,
+                             char *,
+                             uint32_t);
+
 struct ma_platform_data {
     void *waves_handle;
     void *platform;
@@ -158,6 +172,8 @@
     ma_set_volume_t          ma_set_volume;
     ma_set_volume_table_t    ma_set_volume_table;
     ma_set_param_t           ma_set_param;
+    ma_set_cmd_t             ma_set_cmd;
+    ma_get_cmd_t             ma_get_cmd;
     bool speaker_lr_swap;
     bool orientation_used;
     int dispaly_orientation;
@@ -167,6 +183,9 @@
 static uint16_t g_supported_dev = 0;
 static struct ma_state ma_cur_state_table[STREAM_MAX_TYPES];
 static struct ma_platform_data *my_data = NULL;
+static char ma_command_data[WAVES_COMMAND_SIZE];
+static char ma_reply_data[WAVES_COMMAND_SIZE];
+
 // --- external function dependency ---
 fp_platform_set_parameters_t fp_platform_set_parameters;
 fp_audio_extn_get_snd_card_split_t fp_audio_extn_get_snd_card_split;
@@ -276,7 +295,6 @@
 
 static bool check_and_send_all_audio_cal(struct audio_device *adev, ma_cmd_t cmd)
 {
-    int i = 0;
     bool ret = false;
     struct listnode *node;
     struct audio_usecase *usecase;
@@ -476,71 +494,78 @@
 
     my_data->waves_handle = dlopen(lib_path, RTLD_NOW);
     if (my_data->waves_handle == NULL) {
-         ALOGE("%s: DLOPEN failed for %s, %s", __func__, LIB_MA_PARAM, dlerror());
-         goto error;
+        ALOGE("%s: DLOPEN failed for %s, %s", __func__, LIB_MA_PARAM, dlerror());
+        goto error;
     } else {
-         ALOGV("%s: DLOPEN successful for %s", __func__, LIB_MA_PARAM);
+        ALOGV("%s: DLOPEN successful for %s", __func__, LIB_MA_PARAM);
 
-         my_data->ma_param_init = (ma_param_init_t)dlsym(my_data->waves_handle,
-                                   MA_QDSP_PARAM_INIT);
-         if (!my_data->ma_param_init) {
-             ALOGE("%s: dlsym error %s for ma_param_init", __func__, dlerror());
-             goto error;
-         }
+        my_data->ma_param_init = (ma_param_init_t)dlsym(my_data->waves_handle, MA_QDSP_PARAM_INIT);
+        if (!my_data->ma_param_init) {
+            ALOGE("%s: dlsym error %s for ma_param_init", __func__, dlerror());
+            goto error;
+        }
 
-         my_data->ma_param_deinit = (ma_param_deinit_t)dlsym(
-                                     my_data->waves_handle, MA_QDSP_PARAM_DEINIT);
-         if (!my_data->ma_param_deinit) {
-             ALOGE("%s: dlsym error %s for ma_param_deinit", __func__, dlerror());
-             goto error;
-         }
+        my_data->ma_param_deinit = (ma_param_deinit_t)dlsym(my_data->waves_handle,
+                                                            MA_QDSP_PARAM_DEINIT);
+        if (!my_data->ma_param_deinit) {
+            ALOGE("%s: dlsym error %s for ma_param_deinit", __func__, dlerror());
+            goto error;
+        }
 
         my_data->ma_is_feature_used = (ma_is_feature_used_t)dlsym(my_data->waves_handle,
-                                    MA_QDSP_IS_FEATURE_USED);
+                                                                  MA_QDSP_IS_FEATURE_USED);
         if (!my_data->ma_is_feature_used) {
             ALOGV("%s: dlsym error %s for ma_is_feature_used", __func__, dlerror());
         }
 
         my_data->ma_set_orientation = (ma_set_orientation_t)dlsym(my_data->waves_handle,
-                                        MA_QDSP_SET_ORIENTATION);
+                                                                  MA_QDSP_SET_ORIENTATION);
         if (!my_data->ma_set_orientation) {
             ALOGV("%s: dlsym error %s for ma_set_orientation", __func__, dlerror());
         }
 
-         my_data->ma_set_lr_swap = (ma_set_lr_swap_t)dlsym(my_data->waves_handle,
-                                    MA_QDSP_SET_LR_SWAP);
-         if (!my_data->ma_set_lr_swap) {
-             ALOGE("%s: dlsym error %s for ma_set_lr_swap", __func__, dlerror());
-             goto error;
-         }
+        my_data->ma_set_lr_swap = (ma_set_lr_swap_t)dlsym(my_data->waves_handle,
+                                                          MA_QDSP_SET_LR_SWAP);
+        if (!my_data->ma_set_lr_swap) {
+            ALOGE("%s: dlsym error %s for ma_set_lr_swap", __func__, dlerror());
+            goto error;
+        }
 
-         my_data->ma_set_sound_mode = (ma_set_sound_mode_t)dlsym(
-                                       my_data->waves_handle, MA_QDSP_SET_MODE);
-         if (!my_data->ma_set_sound_mode) {
-             ALOGE("%s: dlsym error %s for ma_set_sound_mode", __func__, dlerror());
-             goto error;
-         }
+        my_data->ma_set_sound_mode = (ma_set_sound_mode_t)dlsym(my_data->waves_handle,
+                                                                MA_QDSP_SET_MODE);
+        if (!my_data->ma_set_sound_mode) {
+            ALOGE("%s: dlsym error %s for ma_set_sound_mode", __func__, dlerror());
+            goto error;
+        }
 
-         my_data->ma_set_volume = (ma_set_volume_t)dlsym(my_data->waves_handle,
-                                   MA_QDSP_SET_VOL);
-         if (!my_data->ma_set_volume) {
-             ALOGE("%s: dlsym error %s for ma_set_volume", __func__, dlerror());
-             goto error;
-         }
+        my_data->ma_set_volume = (ma_set_volume_t)dlsym(my_data->waves_handle, MA_QDSP_SET_VOL);
+        if (!my_data->ma_set_volume) {
+            ALOGE("%s: dlsym error %s for ma_set_volume", __func__, dlerror());
+            goto error;
+        }
 
-         my_data->ma_set_volume_table = (ma_set_volume_table_t)dlsym(
-                                         my_data->waves_handle, MA_QDSP_SET_VOLT);
-         if (!my_data->ma_set_volume_table) {
-             ALOGE("%s: dlsym error %s for ma_set_volume_table", __func__, dlerror());
-             goto error;
-         }
+        my_data->ma_set_volume_table = (ma_set_volume_table_t)dlsym(my_data->waves_handle,
+                                                                    MA_QDSP_SET_VOLT);
+        if (!my_data->ma_set_volume_table) {
+            ALOGE("%s: dlsym error %s for ma_set_volume_table", __func__, dlerror());
+            goto error;
+        }
 
-         my_data->ma_set_param = (ma_set_param_t)dlsym(
-                                  my_data->waves_handle, MA_QDSP_SET_PARAM);
-         if (!my_data->ma_set_param) {
-             ALOGE("%s: dlsym error %s for ma_set_param", __func__, dlerror());
-             goto error;
-         }
+        my_data->ma_set_param = (ma_set_param_t)dlsym(my_data->waves_handle, MA_QDSP_SET_PARAM);
+        if (!my_data->ma_set_param) {
+            ALOGE("%s: dlsym error %s for ma_set_param", __func__, dlerror());
+            goto error;
+        }
+
+        my_data->ma_set_cmd = (ma_set_cmd_t)dlsym(my_data->waves_handle, MA_QDSP_SET_COMMAND);
+        if (!my_data->ma_set_cmd) {
+            ALOGE("%s: dlsym error %s for ma_set_cmd", __func__, dlerror());
+        }
+
+        my_data->ma_get_cmd = (ma_get_cmd_t)dlsym(my_data->waves_handle, MA_QDSP_GET_COMMAND);
+        if (!my_data->ma_get_cmd) {
+            ALOGE("%s: dlsym error %s for ma_get_cmd", __func__, dlerror());
+        }
     }
 
     /* get preset table */
@@ -679,7 +704,6 @@
 
 void ma_set_device(struct audio_usecase *usecase)
 {
-    int i = 0;
     struct ma_audio_cal_settings ma_cal;
 
     if (!my_data) {
@@ -731,8 +755,101 @@
     pthread_mutex_unlock(&my_data->lock);
 }
 
-void ma_set_parameters(struct audio_device *adev,
-                                  struct str_parms *parms)
+static bool ma_set_command(struct ma_audio_cal_settings *audio_cal_settings, char *cmd_data)
+{
+    if (my_data->ma_set_cmd)
+        return my_data->ma_set_cmd(g_ma_audio_cal_handle, audio_cal_settings, cmd_data);
+    return false;
+}
+
+static bool ma_get_command(struct ma_audio_cal_settings *audio_cal_settings, char *cmd_data,
+                           char *reply_data, uint32_t reply_size)
+{
+    if (my_data->ma_get_cmd)
+        return my_data->ma_get_cmd(g_ma_audio_cal_handle, audio_cal_settings, cmd_data, reply_data,
+                                   reply_size);
+    return false;
+}
+
+static bool ma_fill_apptype_and_device_from_params(struct str_parms *parms, uint32_t *app_type,
+                                                   struct listnode *devices)
+{
+    int ret;
+    char value[128];
+
+    ret = str_parms_get_str(parms, "cal_apptype", value, sizeof(value));
+
+    if (ret >= 0) {
+        *app_type = (uint32_t)atoi(value);
+        ret = str_parms_get_str(parms, "cal_devid", value, sizeof(value));
+        if (ret >= 0) {
+            update_device_list(devices, (uint32_t)atoi(value), "", true);
+            return true;
+        }
+    }
+    return false;
+}
+
+static bool ma_add_apptype_and_device_to_params(struct str_parms *parms, uint32_t app_type,
+                                                struct listnode *devices)
+{
+    if (0 <= str_parms_add_int(parms, "cal_apptype", app_type)) {
+        if (0 <= str_parms_add_int(parms, "cal_devid", get_device_types(devices))) {
+            return true;
+        }
+    }
+    return false;
+}
+
+static bool ma_get_command_parameters(struct str_parms *query, struct str_parms *reply)
+{
+    struct ma_audio_cal_settings ma_cal;
+    int ret;
+
+    ret = str_parms_get_str(query, "waves_data", ma_command_data, sizeof(ma_command_data));
+    if (ret >= 0) {
+        ma_cal_init(&ma_cal);
+        if (ma_fill_apptype_and_device_from_params(query, &ma_cal.common.app_type,
+                &ma_cal.common.devices)) {
+            ma_add_apptype_and_device_to_params(reply, ma_cal.common.app_type,
+                                                &ma_cal.common.devices);
+            ALOGV("%s: before - command=%s", __func__, (char *)ma_command_data);
+            if (ma_get_command(&ma_cal, ma_command_data, ma_reply_data, sizeof(ma_reply_data))) {
+                str_parms_add_str(reply, "waves_data", ma_reply_data);
+                ALOGV("%s: after - command=%s", __func__, (char *)ma_reply_data);
+                return true;
+            } else {
+                str_parms_add_str(reply, "waves_data", "");
+            }
+        }
+    }
+    return false;
+}
+
+static bool ma_set_command_parameters(struct str_parms *parms)
+{
+    struct ma_audio_cal_settings ma_cal;
+    int ret;
+
+    ret = str_parms_get_str(parms, "waves_data", ma_command_data, sizeof(ma_command_data));
+    if (ret >= 0) {
+        ma_cal_init(&ma_cal);
+        if (ma_fill_apptype_and_device_from_params(parms, &ma_cal.common.app_type,
+                &ma_cal.common.devices)) {
+            return ma_set_command(&ma_cal, ma_command_data);
+        }
+    }
+    return false;
+}
+
+void ma_get_parameters(struct audio_device *adev, struct str_parms *query,
+                       struct str_parms *reply)
+{
+    (void)adev;
+    ma_get_command_parameters(query, reply);
+}
+
+void ma_set_parameters(struct audio_device *adev, struct str_parms *parms)
 {
     int ret;
     int val;
@@ -791,6 +908,8 @@
             }
         }
     }
+
+    ma_set_command_parameters(parms);
 }
 
 bool ma_supported_usb()
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index ec5e452..bdc6971 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -8767,6 +8767,7 @@
     voice_get_parameters(adev, query, reply);
     audio_extn_a2dp_get_parameters(query, reply);
     platform_get_parameters(adev->platform, query, reply);
+    audio_extn_ma_get_parameters(adev, query, reply);
     pthread_mutex_unlock(&adev->lock);
 
 exit: