Revert "Revert "Adding getModelState API to sound trigger""

This reverts commit 5ac2672ce38540b55fc8ba2aa53e1e2936faf711.

Reason for revert: rolling forward with fix

Change-Id: Ib7d321f06c94f06a22e962542c9a4c8744702134
diff --git a/include/hardware/sound_trigger.h b/include/hardware/sound_trigger.h
index d7828ac..696b634 100644
--- a/include/hardware/sound_trigger.h
+++ b/include/hardware/sound_trigger.h
@@ -40,7 +40,8 @@
 
 #define SOUND_TRIGGER_DEVICE_API_VERSION_1_0 HARDWARE_DEVICE_API_VERSION(1, 0)
 #define SOUND_TRIGGER_DEVICE_API_VERSION_1_1 HARDWARE_DEVICE_API_VERSION(1, 1)
-#define SOUND_TRIGGER_DEVICE_API_VERSION_CURRENT SOUND_TRIGGER_DEVICE_API_VERSION_1_1
+#define SOUND_TRIGGER_DEVICE_API_VERSION_1_2 HARDWARE_DEVICE_API_VERSION(1, 2)
+#define SOUND_TRIGGER_DEVICE_API_VERSION_CURRENT SOUND_TRIGGER_DEVICE_API_VERSION_1_2
 
 /**
  * List of known sound trigger HAL modules. This is the base name of the sound_trigger HAL
@@ -114,6 +115,15 @@
      * If no implementation is provided, stop_recognition will be called for each running model.
      */
     int (*stop_all_recognitions)(const struct sound_trigger_hw_device* dev);
+
+    /* Get the current state of a given model.
+     * The state is returned as a recognition event, or null if not implemented or on error.
+     * Caller takes ownership of the returned event memory.
+     * Only supported for device api versions SOUND_TRIGGER_DEVICE_API_VERSION_1_2 or above.
+     */
+    struct sound_trigger_recognition_event* (*get_model_state)(
+        const struct sound_trigger_hw_device *dev,
+        sound_model_handle_t sound_model_handle);
 };
 
 typedef struct sound_trigger_hw_device sound_trigger_hw_device_t;
diff --git a/modules/soundtrigger/sound_trigger_hw.c b/modules/soundtrigger/sound_trigger_hw.c
index 0089f98..25d4813 100644
--- a/modules/soundtrigger/sound_trigger_hw.c
+++ b/modules/soundtrigger/sound_trigger_hw.c
@@ -811,6 +811,39 @@
     return 0;
 }
 
+// Caller is responsible for freeing the memory
+static struct sound_trigger_recognition_event * stdev_get_model_state(
+            const struct sound_trigger_hw_device *dev,
+            sound_model_handle_t handle) {
+    struct stub_sound_trigger_device *stdev = (struct stub_sound_trigger_device *)dev;
+    ALOGI("%s", __func__);
+    pthread_mutex_lock(&stdev->lock);
+
+    struct recognition_context *model_context = get_model_context(stdev, handle);
+    if (!model_context) {
+        ALOGW("Can't find sound model handle %d in registered list", handle);
+        pthread_mutex_unlock(&stdev->lock);
+        return NULL;
+    }
+
+    struct sound_trigger_recognition_event *event = NULL;
+    if (model_context->model_type == SOUND_MODEL_TYPE_GENERIC) {
+      // TODO(mdooley): define a new status for this use case?
+      int status = RECOGNITION_STATUS_SUCCESS;
+      event = (struct sound_trigger_recognition_event *)
+              sound_trigger_generic_event_alloc(model_context->model_handle,
+                                                model_context->config, status);
+    } else {
+      ALOGI("Unsupported sound model type: %d, state not available.",
+            model_context->model_type);
+    }
+
+    pthread_mutex_unlock(&stdev->lock);
+    ALOGI("%s done for handle %d", __func__, handle);
+
+    return event;
+}
+
 __attribute__ ((visibility ("default")))
 int sound_trigger_open_for_streaming() {
     int ret = 0;
@@ -863,6 +896,7 @@
     stdev->device.start_recognition = stdev_start_recognition;
     stdev->device.stop_recognition = stdev_stop_recognition;
     stdev->device.stop_all_recognitions = stdev_stop_all_recognitions;
+    stdev->device.get_model_state = stdev_get_model_state;
 
     pthread_mutex_init(&stdev->lock, (const pthread_mutexattr_t *) NULL);
 
@@ -890,4 +924,3 @@
         .methods = &hal_module_methods,
     },
 };
-