Merge "Optimized the memory consumption and renamed PRN" into nyc-dev
diff --git a/include/hardware/audio.h b/include/hardware/audio.h
index 29b695c..49cc0fe 100644
--- a/include/hardware/audio.h
+++ b/include/hardware/audio.h
@@ -431,6 +431,23 @@
* Unit: the number of input audio frames
*/
uint32_t (*get_input_frames_lost)(struct audio_stream_in *stream);
+
+ /**
+ * Return a recent count of the number of audio frames received and
+ * the clock time associated with that frame count.
+ *
+ * frames is the total frame count received. This should be as early in
+ * the capture pipeline as possible. In general,
+ * frames should be non-negative and should not go "backwards".
+ *
+ * time is the clock MONOTONIC time when frames was measured. In general,
+ * time should be a positive quantity and should not go "backwards".
+ *
+ * The status returned is 0 on success, -ENOSYS if the device is not
+ * ready/available, or -EINVAL if the arguments are null or otherwise invalid.
+ */
+ int (*get_capture_position)(const struct audio_stream_in *stream,
+ int64_t *frames, int64_t *time);
};
typedef struct audio_stream_in audio_stream_in_t;
diff --git a/include/hardware/context_hub.h b/include/hardware/context_hub.h
index 01d2377..f026b08 100644
--- a/include/hardware/context_hub.h
+++ b/include/hardware/context_hub.h
@@ -262,7 +262,7 @@
/**
* Enumerate all available hubs.The list is returned in "list".
- * @return result : 0 if successful, error code otherwise
+ * @return result : number of hubs in list or error (negative)
*
* This method shall be called at device bootup.
*/
diff --git a/include/hardware/keymaster_defs.h b/include/hardware/keymaster_defs.h
index 80b2318..d59f3cb 100644
--- a/include/hardware/keymaster_defs.h
+++ b/include/hardware/keymaster_defs.h
@@ -126,14 +126,15 @@
* Semantically unenforceable tags, either because they have no specific meaning or because
* they're informational only.
*/
- KM_TAG_APPLICATION_DATA = KM_BYTES | 700, /* Data provided by authorized application. */
- KM_TAG_CREATION_DATETIME = KM_DATE | 701, /* Key creation time */
- KM_TAG_ORIGIN = KM_ENUM | 702, /* keymaster_key_origin_t. */
- KM_TAG_ROLLBACK_RESISTANT = KM_BOOL | 703, /* Whether key is rollback-resistant. */
- KM_TAG_ROOT_OF_TRUST = KM_BYTES | 704, /* Root of trust ID. */
- KM_TAG_OS_VERSION = KM_UINT | 705, /* Version of system (keymaster2) */
- KM_TAG_OS_PATCHLEVEL = KM_UINT | 706, /* Patch level of system (keymaster2) */
- KM_TAG_UNIQUE_ID = KM_BYTES | 707, /* Used to provide unique ID in attestation */
+ KM_TAG_APPLICATION_DATA = KM_BYTES | 700, /* Data provided by authorized application. */
+ KM_TAG_CREATION_DATETIME = KM_DATE | 701, /* Key creation time */
+ KM_TAG_ORIGIN = KM_ENUM | 702, /* keymaster_key_origin_t. */
+ KM_TAG_ROLLBACK_RESISTANT = KM_BOOL | 703, /* Whether key is rollback-resistant. */
+ KM_TAG_ROOT_OF_TRUST = KM_BYTES | 704, /* Root of trust ID. */
+ KM_TAG_OS_VERSION = KM_UINT | 705, /* Version of system (keymaster2) */
+ KM_TAG_OS_PATCHLEVEL = KM_UINT | 706, /* Patch level of system (keymaster2) */
+ KM_TAG_UNIQUE_ID = KM_BYTES | 707, /* Used to provide unique ID in attestation */
+ KM_TAG_ATTESTATION_CHALLENGE = KM_BYTES | 708, /* Used to provide challenge in attestation */
/* Tags used only to provide data to or receive data from operations */
KM_TAG_ASSOCIATED_DATA = KM_BYTES | 1000, /* Used to provide associated data for AEAD modes. */
@@ -400,6 +401,7 @@
KM_ERROR_UNSUPPORTED_KDF = -60,
KM_ERROR_UNSUPPORTED_EC_CURVE = -61,
KM_ERROR_KEY_REQUIRES_UPGRADE = -62,
+ KM_ERROR_ATTESTATION_CHALLENGE_MISSING = -63,
KM_ERROR_UNIMPLEMENTED = -100,
KM_ERROR_VERSION_MISMATCH = -101,
diff --git a/include/hardware/nvram.h b/include/hardware/nvram.h
index 535a95b..a1868b5 100644
--- a/include/hardware/nvram.h
+++ b/include/hardware/nvram.h
@@ -197,9 +197,9 @@
*/
nvram_result_t (*create_space)(const struct nvram_device* device,
uint32_t index, uint64_t size_in_bytes,
- nvram_control_t* control_list,
+ const nvram_control_t* control_list,
uint32_t list_size,
- uint8_t* authorization_value,
+ const uint8_t* authorization_value,
uint32_t authorization_value_size);
/**
@@ -216,7 +216,8 @@
* |authorization_value|.
*/
nvram_result_t (*delete_space)(const struct nvram_device* device,
- uint32_t index, uint8_t* authorization_value,
+ uint32_t index,
+ const uint8_t* authorization_value,
uint32_t authorization_value_size);
/**
@@ -251,7 +252,7 @@
nvram_result_t (*write_space)(const struct nvram_device* device,
uint32_t index, const uint8_t* buffer,
uint64_t buffer_size,
- uint8_t* authorization_value,
+ const uint8_t* authorization_value,
uint32_t authorization_value_size);
/**
@@ -281,7 +282,7 @@
*/
nvram_result_t (*read_space)(const struct nvram_device* device,
uint32_t index, uint64_t num_bytes_to_read,
- uint8_t* authorization_value,
+ const uint8_t* authorization_value,
uint32_t authorization_value_size,
uint8_t* buffer, uint64_t* bytes_read);
@@ -303,7 +304,7 @@
*/
nvram_result_t (*enable_write_lock)(const struct nvram_device* device,
uint32_t index,
- uint8_t* authorization_value,
+ const uint8_t* authorization_value,
uint32_t authorization_value_size);
/**
@@ -326,7 +327,7 @@
*/
nvram_result_t (*enable_read_lock)(const struct nvram_device* device,
uint32_t index,
- uint8_t* authorization_value,
+ const uint8_t* authorization_value,
uint32_t authorization_value_size);
};
diff --git a/include/hardware/vehicle.h b/include/hardware/vehicle.h
index 14fb7aa..71c57bc 100644
--- a/include/hardware/vehicle.h
+++ b/include/hardware/vehicle.h
@@ -73,6 +73,7 @@
* @config_string: Explains the usage of config_string in vehicle_prop_config. Property with
* this annotation is expected to have additional information in config_string
* for that property to work.
+ * @zone_type type of zoned used. defined for zoned property
* @range_start, @range_end : define range of specific property values.
*/
//===== Vehicle Information ====
@@ -258,6 +259,7 @@
* @access VEHICLE_PROP_ACCESS_READ_WRITE
* @config_flags Supported zones
* @data_member hvac.fan_speed
+ * @zone_type VEHICLE_ZONE
* @data_enum TODO
*/
#define VEHICLE_PROPERTY_HVAC_FAN_SPEED (0x00000500)
@@ -269,6 +271,7 @@
* @access VEHICLE_PROP_ACCESS_READ_WRITE
* @config_flags Supported zones
* @data_member hvac.fan_direction
+ * @zone_type VEHICLE_ZONE
* @data_enum TODO
*/
#define VEHICLE_PROPERTY_HVAC_FAN_DIRECTION (0x00000501)
@@ -288,6 +291,7 @@
* @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE|VEHICLE_PROP_CHANGE_MODE_CONTINUOUS
* @access VEHICLE_PROP_ACCESS_READ_WRITE
* @config_flags Supported zones
+ * @zone_type VEHICLE_ZONE
* @data_member hvac.temperature_current
*/
#define VEHICLE_PROPERTY_HVAC_TEMPERATURE_CURRENT (0x00000502)
@@ -298,6 +302,7 @@
* @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE|VEHICLE_PROP_CHANGE_MODE_CONTINUOUS
* @config_flags Supported zones
* @access VEHICLE_PROP_ACCESS_READ_WRITE
+ * @zone_type VEHICLE_ZONE
* @data_member hvac.temperature_set
*/
#define VEHICLE_PROPERTY_HVAC_TEMPERATURE_SET (0x00000503)
@@ -318,6 +323,7 @@
* @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE
* @access VEHICLE_PROP_ACCESS_READ_WRITE
* @config_flags Supported zones
+ * @zone_type VEHICLE_ZONE
* @data_member hvac.ac_on
*/
#define VEHICLE_PROPERTY_HVAC_AC_ON (0x00000505)
@@ -366,7 +372,18 @@
* @data_member outside_temperature
* @unit VEHICLE_UNIT_TYPE_CELCIUS
*/
-#define VEHICLE_PROPERTY_ENV_OUTSIDE_TEMP (0x00000703)
+#define VEHICLE_PROPERTY_ENV_OUTSIDE_TEMPERATURE (0x00000703)
+
+
+/**
+ * Cabin temperature
+ * @value_type VEHICLE_VALUE_TYPE_FLOAT
+ * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE|VEHICLE_PROP_CHANGE_MODE_CONTINUOUS
+ * @access VEHICLE_PROP_ACCESS_READ
+ * @data_member cabin_temperature
+ * @unit VEHICLE_UNIT_TYPE_CELCIUS
+ */
+#define VEHICLE_PROPERTY_ENV_CABIN_TEMPERATURE (0x00000704)
/*
@@ -453,7 +470,13 @@
VEHICLE_AUDIO_FOCUS_REQUEST_GAIN = 0x1,
VEHICLE_AUDIO_FOCUS_REQUEST_GAIN_TRANSIENT = 0x2,
VEHICLE_AUDIO_FOCUS_REQUEST_GAIN_TRANSIENT_MAY_DUCK = 0x3,
- VEHICLE_AUDIO_FOCUS_REQUEST_RELEASE = 0x4,
+ /**
+ * This is for the case where android side plays sound like UI feedback
+ * and car side does not need to duck existing playback as long as
+ * requested stream is available.
+ */
+ VEHICLE_AUDIO_FOCUS_REQUEST_GAIN_TRANSIENT_NO_DUCK = 0x4,
+ VEHICLE_AUDIO_FOCUS_REQUEST_RELEASE = 0x5,
};
enum vehicle_audio_focus_state {
@@ -706,6 +729,8 @@
VEHICLE_AUDIO_CONTEXT_CD_ROM = 0x100,
/** Aux audio input is played */
VEHICLE_AUDIO_CONTEXT_AUX_AUDIO = 0x200,
+ /** system sound like UI feedback */
+ VEHICLE_AUDIO_CONTEXT_SYSTEM_SOUND = 0x400,
};
/**
@@ -881,6 +906,36 @@
VEHICLE_AP_POWER_BOOTUP_REASON_TIMER = 2,
};
+
+/**
+ * Property to feed H/W input events to android
+ *
+ * int32_array[0] : action defined by vehicle_hw_key_input_action
+ * int32_array[1] : key code, should use standard android key code
+ * int32_array[2] : target display defined in vehicle_display. Events not tied
+ * to specific display should be sent to DISPLAY_MAIN.
+ * int32_array[3] : reserved for now. should be zero
+ * @value_type VEHICLE_VALUE_TYPE_INT32_VEC4
+ * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE
+ * @access VEHICLE_PROP_ACCESS_READ
+ * @config_flags
+ * @data_member int32_array
+ */
+#define VEHICLE_PROPERTY_HW_KEY_INPUT (0x00000A10)
+
+enum vehicle_hw_key_input_action {
+ /** Key down */
+ VEHICLE_HW_KEY_INPUT_ACTION_DOWN = 0,
+ /** Key up */
+ VEHICLE_HW_KEY_INPUT_ACTION_UP = 1,
+};
+
+enum vehicle_display {
+ /** center console */
+ VEHICLE_DISPLAY_MAIN = 0,
+ VEHICLE_DISPLAY_INSTRUMENT_CLUSTER = 1,
+};
+
/**
* H/W specific, non-standard property can be added as necessary. Such property should use
* property number in range of [VEHICLE_PROPERTY_CUSTOM_START, VEHICLE_PROPERTY_CUSTOM_END].
@@ -1133,6 +1188,22 @@
VEHICLE_WINDOW_ROW_3_RIGHT = 0x2000,
};
+enum vehicle_door {
+ VEHICLE_DOOR_ROW_1_LEFT = 0x00000001,
+ VEHICLE_DOOR_ROW_1_RIGHT = 0x00000004,
+ VEHICLE_DOOR_ROW_2_LEFT = 0x00000010,
+ VEHICLE_DOOR_ROW_2_RIGHT = 0x00000040,
+ VEHICLE_DOOR_ROW_3_LEFT = 0x00000100,
+ VEHICLE_DOOR_ROW_3_RIGHT = 0x00000400,
+ VEHICLE_DOOR_HOOD = 0x10000000,
+ VEHICLE_DOOR_REAR = 0x20000000,
+};
+
+enum vehicle_mirror {
+ VEHICLE_MIRROR_DRIVER_LEFT = 0x00000001,
+ VEHICLE_MIRROR_DRIVER_RIGHT = 0x00000002,
+ VEHICLE_MIRROR_DRIVER_CENTER = 0x00000004,
+};
enum vehicle_turn_signal {
VEHICLE_SIGNAL_NONE = 0x00,
VEHICLE_SIGNAL_RIGHT = 0x01,
@@ -1451,6 +1522,8 @@
vehicle_hvac_t hvac;
float outside_temperature;
+ float cabin_temperature;
+
} vehicle_value_t;
/*
diff --git a/include/hardware/vehicle_rvc.h b/include/hardware/vehicle_rvc.h
new file mode 100644
index 0000000..05d57e4
--- /dev/null
+++ b/include/hardware/vehicle_rvc.h
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_VEHICLE_RVC_INTERFACE_H
+#define ANDROID_VEHICLE_RVC_INTERFACE_H
+
+#include <stdint.h>
+#include <sys/cdefs.h>
+#include <sys/types.h>
+#include <errno.h>
+
+#include <hardware/hardware.h>
+#include <cutils/native_handle.h>
+
+__BEGIN_DECLS
+
+/*****************************************************************************/
+
+#define VEHICLE_RVC_HEADER_VERSION 1
+#define VEHICLE_RVC_MODULE_API_VERSION_1_0 HARDWARE_MODULE_API_VERSION(1, 0)
+#define VEHICLE_RVC_DEVICE_API_VERSION_1_0 HARDWARE_DEVICE_API_VERSION_2(1, 0, VEHICLE_RVC_HEADER_VERSION)
+
+/**
+ * Vehicle Rearview Camera to provide interfaces for controlling
+ * the RVC.
+ */
+
+/**
+ * The id of this module
+ */
+#define VEHICLE_RVC_HARDWARE_MODULE_ID "vehicle_rvc"
+
+/**
+ * Name of the vehicle device to open
+ */
+#define VEHICLE_RVC_HARDWARE_DEVICE "vehicle_rvc_hw_device"
+
+/**
+ * Describes the current state of RVC module
+ */
+typedef struct {
+ uint32_t overlay_on;
+ uint32_t rvc_on;
+} vehicle_rvc_state_t;
+
+/**
+ * Describes a rectangle for cropping and positioning objects
+ * uint32_t left Position of left border of rectangle
+ * uint32_t top Position of top border of rectangle
+ * uint32_t width Width of rectangle
+ * uint32_t height Height of rectangle
+ */
+typedef struct {
+ uint32_t left;
+ uint32_t top;
+ uint32_t width;
+ uint32_t height;
+} vehicle_rvc_rect_t;
+
+/**
+ * Bitmask of features supported by RVC module
+ */
+enum vehicle_rvc_config_flag {
+ ANDROID_OVERLAY_SUPPORT_FLAG = 0x1,
+ CAMERA_CROP_SUPPORT_FLAG = 0x2,
+ CAMERA_POSITIONING_SUPPORT_FLAG = 0x4
+};
+
+typedef struct {
+ uint32_t capabilites_flags;
+ uint32_t camera_width;
+ uint32_t camera_height;
+ uint32_t display_width;
+ uint32_t display_height;
+} vehicle_rvc_cap_t;
+
+/************************************************************************************/
+
+/**
+ * Every hardware module must have a data structure named HAL_MODULE_INFO_SYM
+ * and the fields of this data structure must begin with hw_module_t
+ * followed by module specific information.
+ */
+typedef struct {
+ struct hw_module_t common;
+} vehicle_rvc_module_t;
+
+
+typedef struct vehicle_rvc_device_t {
+ struct hw_device_t common;
+
+ /**
+ * Returns the capabilities of this RVC.
+ * @param device
+ * @return
+ */
+ int (*get_capabilities)(struct vehicle_rvc_device_t *device, vehicle_rvc_cap_t *cap);
+ /**
+ * Gets the current RVC crop settings.
+ * @param device
+ * @return
+ */
+ int (*get_rvc_crop)(struct vehicle_rvc_device_t *device, vehicle_rvc_rect_t *rect);
+ /**
+ * Sets the RVC crop.
+ * @param device
+ * @param rect Area of RVC camera input to crop
+ * @return
+ */
+ int (*set_rvc_crop)(struct vehicle_rvc_device_t *device, const vehicle_rvc_rect_t *rect);
+ /**
+ * Gets position of the RVC on the dispaly.
+ * @param device
+ * @param rect Area of display the RVC will appear when on
+ * @return
+ */
+ int (*get_rvc_position)(struct vehicle_rvc_device_t *device, vehicle_rvc_rect_t *rect);
+ /**
+ * Sets position of the RVC on the display.
+ * @param device
+ * @param rect
+ * @return
+ */
+ int (*set_rvc_position)(struct vehicle_rvc_device_t *device, const vehicle_rvc_rect_t *rect);
+ /**
+ * Gets the current camera state.
+ * @param device
+ * @return
+ */
+ int (*get_camera_state)(struct vehicle_rvc_device_t *device, vehicle_rvc_state_t *state);
+ /**
+ * Sets the camera state. Calling this function will generate a
+ * callback notifying the user that the camera state has
+ * changed.
+ * @param device
+ * @return
+ */
+ int (*set_camera_state)(struct vehicle_rvc_device_t *device, const vehicle_rvc_state_t *state);
+} vehicle_rvc_device_t;
+
+__END_DECLS
+
+#endif // ANDROID_VEHICLE_RVC_INTERFACE_H
diff --git a/modules/soundtrigger/sound_trigger_hw.c b/modules/soundtrigger/sound_trigger_hw.c
index 2c1cc9c..8083b1f 100644
--- a/modules/soundtrigger/sound_trigger_hw.c
+++ b/modules/soundtrigger/sound_trigger_hw.c
@@ -30,7 +30,7 @@
*/
#define LOG_TAG "sound_trigger_hw_default"
-/*#define LOG_NDEBUG 0*/
+#define LOG_NDEBUG 1
#include <errno.h>
#include <stdio.h>
@@ -51,10 +51,6 @@
#include <system/sound_trigger.h>
#include <hardware/sound_trigger.h>
-/* Although max_sound_models is specified in sound_trigger_properties, having a maximum maximum
-allows a dramatic simplification of data structures in this file */
-#define MAX_MAX_SOUND_MODELS 5
-
static const struct sound_trigger_properties hw_properties = {
"The Android Open Source Project", // implementor
"Sound Trigger stub HAL", // description
@@ -72,15 +68,19 @@
};
struct recognition_context {
- /* Sound Model Information Modified On Load */
- sound_model_handle_t loaded_sound_model;
- sound_model_callback_t sound_model_callback;
- void *sound_model_cookie;
+ // Sound Model information, added in method load_sound_model
+ sound_model_handle_t model_handle;
+ sound_trigger_sound_model_type_t model_type;
+ sound_model_callback_t model_callback;
+ void *model_cookie;
- /* Sound Model Information Modified On Recognition Start */
+ // Sound Model information, added in start_recognition
struct sound_trigger_recognition_config *config;
recognition_callback_t recognition_callback;
void *recognition_cookie;
+
+ // Next recognition_context in the linked list
+ struct recognition_context *next;
};
struct stub_sound_trigger_device {
@@ -88,7 +88,8 @@
pthread_mutex_t lock;
pthread_t callback_thread;
- struct recognition_context model_context[MAX_MAX_SOUND_MODELS];
+ // Recognition contexts are stored as a linked list
+ struct recognition_context *root_model_context;
int next_sound_model_id;
};
@@ -104,57 +105,94 @@
return new_id;
}
-static char *sound_trigger_event_alloc(struct stub_sound_trigger_device *stdev,
- sound_model_handle_t handle) {
- struct sound_trigger_phrase_recognition_event *event;
+static char *sound_trigger_event_alloc(sound_model_handle_t handle,
+ sound_trigger_sound_model_type_t model_type,
+ struct sound_trigger_recognition_config *config) {
char *data;
- data = (char *)calloc(1, sizeof(struct sound_trigger_phrase_recognition_event));
- if (!data)
- return NULL;
+ if (model_type == SOUND_MODEL_TYPE_KEYPHRASE) {
+ struct sound_trigger_phrase_recognition_event *event;
+ data = (char *)calloc(1, sizeof(struct sound_trigger_phrase_recognition_event));
+ if (!data)
+ return NULL;
+ event = (struct sound_trigger_phrase_recognition_event *)data;
+ event->common.status = RECOGNITION_STATUS_SUCCESS;
+ event->common.type = SOUND_MODEL_TYPE_KEYPHRASE;
+ event->common.model = handle;
- unsigned int model_index;
- bool found = false;
- for(model_index = 0; model_index < hw_properties.max_sound_models; model_index++) {
- if (stdev->model_context[model_index].loaded_sound_model == handle) {
- found = true;
- break;
+ if (config) {
+ unsigned int i;
+
+ event->num_phrases = config->num_phrases;
+ if (event->num_phrases > SOUND_TRIGGER_MAX_PHRASES)
+ event->num_phrases = SOUND_TRIGGER_MAX_PHRASES;
+ for (i=0; i < event->num_phrases; i++)
+ memcpy(&event->phrase_extras[i],
+ &config->phrases[i],
+ sizeof(struct sound_trigger_phrase_recognition_extra));
}
- }
- if (found == false) {
- ALOGW("Can't find model");
+
+ event->num_phrases = 1;
+ event->phrase_extras[0].confidence_level = 100;
+ event->phrase_extras[0].num_levels = 1;
+ event->phrase_extras[0].levels[0].level = 100;
+ event->phrase_extras[0].levels[0].user_id = 0;
+ // Signify that all the data is comming through streaming, not through the buffer.
+ event->common.capture_available = true;
+ event->common.audio_config = AUDIO_CONFIG_INITIALIZER;
+ event->common.audio_config.sample_rate = 16000;
+ event->common.audio_config.channel_mask = AUDIO_CHANNEL_IN_MONO;
+ event->common.audio_config.format = AUDIO_FORMAT_PCM_16_BIT;
+ } else if (model_type == SOUND_MODEL_TYPE_GENERIC) {
+ struct sound_trigger_generic_recognition_event *event;
+ data = (char *)calloc(1, sizeof(struct sound_trigger_generic_recognition_event));
+ if (!data)
+ return NULL;
+ event = (struct sound_trigger_generic_recognition_event *)data;
+ event->common.status = RECOGNITION_STATUS_SUCCESS;
+ event->common.type = SOUND_MODEL_TYPE_GENERIC;
+ event->common.model = handle;
+
+ // Signify that all the data is comming through streaming, not through the buffer.
+ event->common.capture_available = true;
+ event->common.audio_config = AUDIO_CONFIG_INITIALIZER;
+ event->common.audio_config.sample_rate = 16000;
+ event->common.audio_config.channel_mask = AUDIO_CHANNEL_IN_MONO;
+ event->common.audio_config.format = AUDIO_FORMAT_PCM_16_BIT;
+ } else {
+ ALOGW("No Valid Event Type Known");
return NULL;
}
+ return data;
+}
- event = (struct sound_trigger_phrase_recognition_event *)data;
- event->common.status = RECOGNITION_STATUS_SUCCESS;
- event->common.type = SOUND_MODEL_TYPE_KEYPHRASE;
- event->common.model = handle;
-
- if (stdev->model_context[model_index].config) {
- unsigned int i;
-
- event->num_phrases = stdev->model_context[model_index].config->num_phrases;
- if (event->num_phrases > SOUND_TRIGGER_MAX_PHRASES)
- event->num_phrases = SOUND_TRIGGER_MAX_PHRASES;
- for (i=0; i < event->num_phrases; i++)
- memcpy(&event->phrase_extras[i], &stdev->model_context[model_index].config->phrases[i],
- sizeof(struct sound_trigger_phrase_recognition_extra));
+static void send_recognition_event(sound_model_handle_t model_handle,
+ sound_trigger_sound_model_type_t model_type,
+ recognition_callback_t recognition_callback, void *recognition_cookie,
+ struct sound_trigger_recognition_config *config) {
+ if (recognition_callback == NULL) {
+ ALOGI("%s No matching callback for handle %d", __func__, model_handle);
+ return;
}
- event->num_phrases = 1;
- event->phrase_extras[0].confidence_level = 100;
- event->phrase_extras[0].num_levels = 1;
- event->phrase_extras[0].levels[0].level = 100;
- event->phrase_extras[0].levels[0].user_id = 0;
- // Signify that all the data is comming through streaming, not through the buffer.
- event->common.capture_available = true;
-
- event->common.audio_config = AUDIO_CONFIG_INITIALIZER;
- event->common.audio_config.sample_rate = 16000;
- event->common.audio_config.channel_mask = AUDIO_CHANNEL_IN_MONO;
- event->common.audio_config.format = AUDIO_FORMAT_PCM_16_BIT;
-
- return data;
+ if (model_type == SOUND_MODEL_TYPE_KEYPHRASE) {
+ struct sound_trigger_phrase_recognition_event *event;
+ event = (struct sound_trigger_phrase_recognition_event *)
+ sound_trigger_event_alloc(model_handle, model_type, config);
+ if (event) {
+ recognition_callback(&event->common, recognition_cookie);
+ free(event);
+ }
+ } else if (model_type == SOUND_MODEL_TYPE_GENERIC) {
+ struct sound_trigger_generic_recognition_event *event;
+ event = (struct sound_trigger_generic_recognition_event *)
+ sound_trigger_event_alloc(model_handle, model_type, config);
+ if (event) {
+ recognition_callback(&event->common, recognition_cookie);
+ free(event);
+ }
+ } else {
+ ALOGI("Unknown Sound Model Type, No Event to Send");
+ }
}
static void *callback_thread_loop(void *context) {
@@ -215,26 +253,26 @@
ALOGI("Received kill signal: stop listening to incoming server messages");
exit = true;
} else if (index < hw_properties.max_sound_models) {
- ALOGI("Going to send trigger for model #%d", index );
- if (stdev->model_context[index].recognition_callback != NULL) {
- sound_model_handle_t handle = stdev->model_context[index].loaded_sound_model;
- if (handle == 0) {
- ALOGW("This trigger is not loaded");
- } else {
- struct sound_trigger_phrase_recognition_event *event;
- event = (struct sound_trigger_phrase_recognition_event *)
- sound_trigger_event_alloc(stdev, handle);
- if (event) {
- ALOGI("%s send callback model %d", __func__, index);
- stdev->model_context[index].recognition_callback(&event->common,
- stdev->model_context[index].recognition_cookie);
- free(event);
- stdev->model_context[index].recognition_callback = NULL;
- }
- exit = true;
+ ALOGI("Going to send trigger for model index #%d", index );
+ struct recognition_context *model_context = NULL;
+ struct recognition_context *last_model_context = stdev->root_model_context;
+ int model_index = 0;
+ while(last_model_context) {
+ if (model_index == index) {
+ model_context = last_model_context;
+ break;
}
+ last_model_context = last_model_context->next;
+ model_index++;
+ }
+ if (model_context) {
+ send_recognition_event(model_context->model_handle,
+ model_context->model_type,
+ model_context->recognition_callback,
+ model_context->recognition_cookie,
+ model_context->config);
} else {
- ALOGI("%s No matching callback for %d", __func__, index);
+ ALOGI("Sound Model Does Not Exist at this Index: %d", index);
}
} else {
ALOGI("Data is not recognized: %d", index);
@@ -302,29 +340,46 @@
return -EINVAL;
}
- /* Find if there is space for this sound model */
- unsigned int model_index;
- bool found = false;
- for(model_index = 0; model_index < hw_properties.max_sound_models; model_index++) {
- if (stdev->model_context[model_index].loaded_sound_model == 0) {
- found = true;
- break;
- }
- }
- if (found == false) {
- ALOGW("Can't load model: reached max sound model limit");
+ struct recognition_context *model_context;
+ model_context = malloc(sizeof(struct recognition_context));
+ if(!model_context) {
+ ALOGW("Could not allocate recognition_context");
pthread_mutex_unlock(&stdev->lock);
return -ENOSYS;
}
- stdev->model_context[model_index].loaded_sound_model = generate_sound_model_id(dev);
- *handle = stdev->model_context[model_index].loaded_sound_model;
+ // Add the new model context to the recognition_context linked list
+ if (stdev->root_model_context) {
+ // Find the tail
+ struct recognition_context *last_model_context = stdev->root_model_context;
+ int model_count = 0;
+ while(last_model_context->next) {
+ last_model_context = last_model_context->next;
+ model_count++;
+ if (model_count >= hw_properties.max_sound_models) {
+ ALOGW("Can't load model: reached max sound model limit");
+ free(model_context);
+ pthread_mutex_unlock(&stdev->lock);
+ return -ENOSYS;
+ }
+ }
+ last_model_context->next = model_context;
+ } else {
+ stdev->root_model_context = model_context;
+ }
+
+ model_context->model_handle = generate_sound_model_id(dev);
+ *handle = model_context->model_handle;
+ model_context->model_type = sound_model->type;
char *data = (char *)sound_model + sound_model->data_offset;
ALOGI("%s data size %d data %d - %d", __func__,
sound_model->data_size, data[0], data[sound_model->data_size - 1]);
- stdev->model_context[model_index].sound_model_callback = callback;
- stdev->model_context[model_index].sound_model_cookie = cookie;
+ model_context->model_callback = callback;
+ model_context->model_cookie = cookie;
+ model_context->config = NULL;
+ model_context->recognition_callback = NULL;
+ model_context->recognition_cookie = NULL;
pthread_mutex_unlock(&stdev->lock);
return status;
@@ -337,35 +392,46 @@
ALOGI("unload_sound_model");
pthread_mutex_lock(&stdev->lock);
- unsigned int i;
- unsigned int model_index;
- bool found = false;
- bool other_callbacks_found = false;
- for(i = 0; i < hw_properties.max_sound_models; i++) {
- if (stdev->model_context[i].loaded_sound_model == handle) {
- found = true;
- model_index = i;
- break;
- } else if (stdev->model_context[i].recognition_callback != NULL) {
- other_callbacks_found = true;
+
+ struct recognition_context *model_context = NULL;
+ struct recognition_context *previous_model_context = NULL;
+ if (stdev->root_model_context) {
+ struct recognition_context *last_model_context = stdev->root_model_context;
+ while(last_model_context) {
+ if (last_model_context->model_handle == handle) {
+ model_context = last_model_context;
+ break;
+ }
+ previous_model_context = last_model_context;
+ last_model_context = last_model_context->next;
}
}
- if (found == false) {
- ALOGW("Can't sound model %d in registered list", handle);
+ if (!model_context) {
+ ALOGW("Can't find sound model handle %d in registered list", handle);
pthread_mutex_unlock(&stdev->lock);
return -ENOSYS;
}
- stdev->model_context[i].loaded_sound_model = 0;
- stdev->model_context[i].sound_model_callback = NULL;
- stdev->model_context[i].sound_model_cookie = NULL;
-
- free(stdev->model_context[i].config);
- stdev->model_context[i].config = NULL;
- stdev->model_context[i].recognition_callback = NULL;
- stdev->model_context[i].recognition_cookie = NULL;
+ if(previous_model_context) {
+ previous_model_context->next = model_context->next;
+ } else {
+ stdev->root_model_context = model_context->next;
+ }
+ free(model_context->config);
+ free(model_context);
/* If no more models running with callbacks, stop trigger thread */
+ bool other_callbacks_found = false;
+ if (stdev->root_model_context) {
+ struct recognition_context *last_model_context = stdev->root_model_context;
+ while(last_model_context) {
+ if (last_model_context->recognition_callback != NULL) {
+ other_callbacks_found = true;
+ break;
+ }
+ last_model_context = last_model_context->next;
+ }
+ }
if (!other_callbacks_found) {
send_loop_kill_signal();
pthread_mutex_unlock(&stdev->lock);
@@ -385,32 +451,36 @@
ALOGI("%s", __func__);
struct stub_sound_trigger_device *stdev = (struct stub_sound_trigger_device *)dev;
pthread_mutex_lock(&stdev->lock);
- unsigned int i;
- bool found = false;
- for(i = 0; i < hw_properties.max_sound_models; i++) {
- if (stdev->model_context[i].loaded_sound_model == handle) {
- found = true;
- break;
+
+ struct recognition_context *model_context = NULL;
+ if (stdev->root_model_context) {
+ struct recognition_context *last_model_context = stdev->root_model_context;
+ while(last_model_context) {
+ if (last_model_context->model_handle == handle) {
+ model_context = last_model_context;
+ break;
+ }
+ last_model_context = last_model_context->next;
}
}
- if (found == false) {
- ALOGW("Can't sound model %d in registered list", handle);
+ if (!model_context) {
+ ALOGW("Can't find sound model handle %d in registered list", handle);
pthread_mutex_unlock(&stdev->lock);
return -ENOSYS;
}
- free(stdev->model_context[i].config);
- stdev->model_context[i].config = NULL;
+ free(model_context->config);
+ model_context->config = NULL;
if (config) {
- stdev->model_context[i].config = malloc(sizeof(*config));
- if (!stdev->model_context[i].config) {
+ model_context->config = malloc(sizeof(*config));
+ if (!model_context->config) {
pthread_mutex_unlock(&stdev->lock);
return -ENOMEM;
}
- memcpy(stdev->model_context[i].config, config, sizeof(*config));
+ memcpy(model_context->config, config, sizeof(*config));
}
- stdev->model_context[i].recognition_callback = callback;
- stdev->model_context[i].recognition_cookie = cookie;
+ model_context->recognition_callback = callback;
+ model_context->recognition_cookie = cookie;
pthread_create(&stdev->callback_thread, (const pthread_attr_t *) NULL,
callback_thread_loop, stdev);
@@ -424,48 +494,56 @@
ALOGI("%s", __func__);
pthread_mutex_lock(&stdev->lock);
- unsigned int i;
- bool found = false;
- for(i = 0; i < hw_properties.max_sound_models; i++) {
- if (stdev->model_context[i].loaded_sound_model == handle) {
- found = true;
- break;
+ struct recognition_context *model_context = NULL;
+ bool other_callbacks_found = false;
+ if (stdev->root_model_context) {
+ struct recognition_context *last_model_context = stdev->root_model_context;
+ while(last_model_context) {
+ if (last_model_context->model_handle == handle) {
+ model_context = last_model_context;
+ } else if (last_model_context->recognition_callback != NULL) {
+ other_callbacks_found = true;
+ }
+ last_model_context = last_model_context->next;
}
}
- if (found == false) {
- ALOGW("Can't sound model %d in registered list", handle);
+ if (!model_context) {
+ ALOGW("Can't find sound model handle %d in registered list", handle);
pthread_mutex_unlock(&stdev->lock);
return -ENOSYS;
}
- free(stdev->model_context[i].config);
- stdev->model_context[i].config = NULL;
- stdev->model_context[i].recognition_callback = NULL;
- stdev->model_context[i].recognition_cookie = NULL;
+ free(model_context->config);
+ model_context->config = NULL;
+ model_context->recognition_callback = NULL;
+ model_context->recognition_cookie = NULL;
- send_loop_kill_signal();
- pthread_mutex_unlock(&stdev->lock);
- pthread_join(stdev->callback_thread, (void **) NULL);
+ /* If no more models running with callbacks, stop trigger thread */
+ if (!other_callbacks_found) {
+ send_loop_kill_signal();
+ pthread_mutex_unlock(&stdev->lock);
+ pthread_join(stdev->callback_thread, (void **)NULL);
+ } else {
+ pthread_mutex_unlock(&stdev->lock);
+ }
+
return 0;
}
__attribute__ ((visibility ("default")))
-int sound_trigger_open_for_streaming()
-{
+int sound_trigger_open_for_streaming() {
int ret = 0;
return ret;
}
__attribute__ ((visibility ("default")))
-size_t sound_trigger_read_samples(int audio_handle, void *buffer, size_t buffer_len)
-{
+size_t sound_trigger_read_samples(int audio_handle, void *buffer, size_t buffer_len) {
size_t ret = 0;
return ret;
}
__attribute__ ((visibility ("default")))
-int sound_trigger_close_for_streaming(int audio_handle __unused)
-{
+int sound_trigger_close_for_streaming(int audio_handle __unused) {
return 0;
}
@@ -486,21 +564,7 @@
if (!stdev)
return -ENOMEM;
- if (MAX_MAX_SOUND_MODELS < hw_properties.max_sound_models) {
- ALOGW("max_sound_models is greater than the allowed %d", MAX_MAX_SOUND_MODELS);
- return -EINVAL;
- }
-
stdev->next_sound_model_id = 1;
- unsigned int i;
- for(i = 0; i < hw_properties.max_sound_models; i++) {
- stdev->model_context[i].loaded_sound_model = 0;
- stdev->model_context[i].sound_model_callback = NULL;
- stdev->model_context[i].sound_model_cookie = NULL;
- stdev->model_context[i].config = NULL;
- stdev->model_context[i].recognition_callback = NULL;
- stdev->model_context[i].recognition_cookie = NULL;
- }
stdev->device.common.tag = HARDWARE_DEVICE_TAG;
stdev->device.common.version = SOUND_TRIGGER_DEVICE_API_VERSION_1_0;
@@ -534,3 +598,4 @@
.methods = &hal_module_methods,
},
};
+