Merge "hwcomposer: Add function pointer for setPowerMode() callback"
diff --git a/include/hardware/activity_recognition.h b/include/hardware/activity_recognition.h
index 6ae90b7..8f99459 100644
--- a/include/hardware/activity_recognition.h
+++ b/include/hardware/activity_recognition.h
@@ -39,24 +39,39 @@
#define ACTIVITY_RECOGNITION_HARDWARE_INTERFACE "activity_recognition_hw_if"
/*
- * Define constants for various activity types. Multiple activities may be active at the same time
- * and sometimes none of these activities may be active.
+ * Define types for various activities. Multiple activities may be active at the same time and
+ * sometimes none of these activities may be active.
+ *
+ * Each activity has a corresponding type. Only activities that are defined here should use
+ * android.activity_recognition.* prefix. OEM defined activities should not use this prefix.
+ * Activity type of OEM-defined activities should start with the reverse domain name of the entity
+ * defining the activity.
+ *
+ * When android introduces a new activity type that can potentially replace an OEM-defined activity
+ * type, the OEM must use the official activity type on versions of the HAL that support this new
+ * official activity type.
+ *
+ * Example (made up): Suppose Google's Glass team wants to detect nodding activity.
+ * - Such an activity is not officially supported in android L
+ * - Glass devices launching on L can implement a custom activity with
+ * type = "com.google.glass.nodding"
+ * - In M android release, if android decides to define ACITIVITY_TYPE_NODDING, those types
+ * should replace the Glass-team-specific types in all future launches.
+ * - When launching glass on the M release, Google should now use the official activity type
+ * - This way, other applications can use this activity.
*/
-/* Reserved. get_supported_activities_list() should not return this activity. */
-#define ACTIVITY_RESERVED (0)
+#define ACTIVITY_TYPE_IN_VEHICLE "android.activity_recognition.in_vehicle"
-#define ACTIVITY_IN_VEHICLE (1)
+#define ACTIVITY_TYPE_ON_BICYCLE "android.activity_recognition.on_bicycle"
-#define ACTIVITY_ON_BICYCLE (2)
+#define ACTIVITY_TYPE_WALKING "android.activity_recognition.walking"
-#define ACTIVITY_WALKING (3)
+#define ACTIVITY_TYPE_RUNNING "android.activity_recognition.running"
-#define ACTIVITY_RUNNING (4)
+#define ACTIVITY_TYPE_STILL "android.activity_recognition.still"
-#define ACTIVITY_STILL (5)
-
-#define ACTIVITY_TILTING (6)
+#define ACTIVITY_TYPE_TILTING "android.activity_recognition.tilting"
/* Values for activity_event.event_types. */
enum {
@@ -69,19 +84,19 @@
* return a flush_complete_event to indicate that the FIFO is empty.
*
* A flush complete event should have the following parameters set.
- * activity_event_t.event_type = ACTIVITY_EVENT_TYPE_FLUSH_COMPLETE
- * activity_event_t.activity = ACTIVITY_RESERVED
+ * activity_event_t.event_type = ACTIVITY_EVENT_FLUSH_COMPLETE
+ * activity_event_t.activity = 0
* activity_event_t.timestamp = 0
* activity_event_t.reserved = 0
* See (*flush)() for more details.
*/
- ACTIVITY_EVENT_TYPE_FLUSH_COMPLETE = 0,
+ ACTIVITY_EVENT_FLUSH_COMPLETE = 0,
/* Signifies entering an activity. */
- ACTIVITY_EVENT_TYPE_ENTER = 1,
+ ACTIVITY_EVENT_ENTER = 1,
/* Signifies exiting an activity. */
- ACTIVITY_EVENT_TYPE_EXIT = 2
+ ACTIVITY_EVENT_EXIT = 2
};
/*
@@ -89,10 +104,13 @@
* or ended. Eg event: (event_type="enter", activity="ON_FOOT", timestamp)
*/
typedef struct activity_event {
- /* One of the ACTIVITY_EVENT_TYPE_* constants defined above. */
+ /* One of the ACTIVITY_EVENT_* constants defined above. */
uint32_t event_type;
- /* One of ACTIVITY_* constants defined above. */
+ /*
+ * Index of the activity in the list returned by get_supported_activities_list. If this event
+ * is a flush complete event, this should be set to zero.
+ */
uint32_t activity;
/* Time at which the transition/event has occurred in nanoseconds using elapsedRealTimeNano. */
@@ -112,12 +130,14 @@
hw_module_t common;
/*
- * List of all activities supported by this module. Each activity is represented as an integer.
- * Each value in the list is one of the ACTIVITY_* constants defined above. Return
- * value is the size of this list.
+ * List of all activities supported by this module including OEM defined activities. Each
+ * activity is represented using a string defined above. Each string should be null terminated.
+ * The index of the activity in this array is used as a "handle" for enabling/disabling and
+ * event delivery.
+ * Return value is the size of this list.
*/
int (*get_supported_activities_list)(struct activity_recognition_module* module,
- int** activity_list);
+ char const* const* *activity_list);
} activity_recognition_module_t;
struct activity_recognition_device;
@@ -159,26 +179,27 @@
* independently of the other. The HAL implementation needs to keep track of which pairs are
* currently active and needs to detect only those pairs.
*
- * activity - The specific activity that needs to be detected.
+ * activity_handle - Index of the specific activity that needs to be detected in the list
+ * returned by get_supported_activities_list.
* event_type - Specific transition of the activity that needs to be detected.
* max_batch_report_latency_ns - a transition can be delayed by at most
* “max_batch_report_latency” nanoseconds.
* Return 0 on success, negative errno code otherwise.
*/
int (*enable_activity_event)(const struct activity_recognition_device* dev,
- uint32_t activity, uint32_t event_type, int64_t max_batch_report_latency_ns);
+ uint32_t activity_handle, uint32_t event_type, int64_t max_batch_report_latency_ns);
/*
* Disables detection of a specific (activity, event_type) pair.
*/
int (*disable_activity_event)(const struct activity_recognition_device* dev,
- uint32_t activity, uint32_t event_type);
+ uint32_t activity_handle, uint32_t event_type);
/*
* Flush all the batch FIFOs. Report all the activities that were stored in the FIFO so far as
* if max_batch_report_latency had expired. This shouldn't change the latency in any way. Add
* a flush_complete_event to indicate the end of the FIFO after all events are delivered.
- * See ACTIVITY_EVENT_TYPE_FLUSH_COMPLETE for more details.
+ * See ACTIVITY_EVENT_FLUSH_COMPLETE for more details.
* Return 0 on success, negative errno code otherwise.
*/
int (*flush)(const struct activity_recognition_device* dev);
diff --git a/include/hardware/bluetooth.h b/include/hardware/bluetooth.h
index c00a8f7..41a1167 100644
--- a/include/hardware/bluetooth.h
+++ b/include/hardware/bluetooth.h
@@ -126,6 +126,16 @@
int manufacturer;
} bt_remote_version_t;
+typedef struct
+{
+ uint8_t local_privacy_enabled;
+ uint8_t max_adv_instance;
+ uint8_t rpa_offload_supported;
+ uint8_t max_irk_list_size;
+ uint8_t max_adv_filter_supported;
+ uint8_t scan_result_storage_size;
+}bt_local_le_features_t;
+
/* Bluetooth Adapter and Remote Device property types */
typedef enum {
/* Properties common to both adapter and remote device */
@@ -208,6 +218,13 @@
BT_PROPERTY_REMOTE_VERSION_INFO,
+ /**
+ * Description - Local LE features
+ * Access mode - GET.
+ * Data type - bt_local_le_features_t.
+ */
+ BT_PROPERTY_LOCAL_LE_FEATURES,
+
BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP = 0xFF,
} bt_property_type_t;
@@ -219,6 +236,7 @@
void *val;
} bt_property_t;
+
/** Bluetooth Device Type */
typedef enum {
BT_DEVICE_DEVTYPE_BREDR = 0x1,
diff --git a/include/hardware/fingerprint.h b/include/hardware/fingerprint.h
index 7f6fa28..91ba45b 100644
--- a/include/hardware/fingerprint.h
+++ b/include/hardware/fingerprint.h
@@ -22,18 +22,28 @@
typedef enum fingerprint_msg_type {
FINGERPRINT_ERROR = -1,
- FINGERPRINT_SCANNED = 1,
- FINGERPRINT_TEMPLATE_ENROLLING = 2,
+ FINGERPRINT_ACQUIRED = 1,
+ FINGERPRINT_PROCESSED = 2,
+ FINGERPRINT_TEMPLATE_ENROLLING = 3,
FINGERPRINT_TEMPLATE_REMOVED = 4
} fingerprint_msg_type_t;
typedef enum fingerprint_error {
FINGERPRINT_ERROR_HW_UNAVAILABLE = 1,
- FINGERPRINT_ERROR_BAD_CAPTURE = 2,
+ FINGERPRINT_ERROR_UNABLE_TO_PROCESS = 2,
FINGERPRINT_ERROR_TIMEOUT = 3,
FINGERPRINT_ERROR_NO_SPACE = 4 /* No space available to store a template */
} fingerprint_error_t;
+typedef enum fingerprint_scan_info {
+ FINGERPRINT_SCAN_GOOD = 0,
+ FINGERPRINT_SCAN_PARTIAL = 1,
+ FINGERPRINT_SCAN_INSUFFICIENT = 2,
+ FINGERPRINT_SCAN_IMAGER_DIRTY = 4,
+ FINGERPRINT_SCAN_TOO_SLOW = 8,
+ FINGERPRINT_SCAN_TOO_FAST = 16
+} fingerprint_scan_info_t;
+
typedef struct fingerprint_enroll {
uint32_t id;
/* samples_remaining goes from N (no data collected, but N scans needed)
@@ -61,9 +71,13 @@
uint32_t id;
} fingerprint_removed_t;
-typedef struct fingerprint_scanned {
+typedef struct fingerprint_acquired {
+ fingerprint_scan_info_t scan_info; /* information about the image */
+} fingerprint_acquired_t;
+
+typedef struct fingerprint_processed {
uint32_t id; /* 0 is a special id and means no match */
-} fingerprint_scanned_t;
+} fingerprint_processed_t;
typedef struct fingerprint_msg {
fingerprint_msg_type_t type;
@@ -72,7 +86,8 @@
fingerprint_error_t error;
fingerprint_enroll_t enroll;
fingerprint_removed_t removed;
- fingerprint_scanned_t scan;
+ fingerprint_acquired_t acquired;
+ fingerprint_processed_t processed;
} data;
} fingerprint_msg_t;
@@ -82,10 +97,10 @@
/* Synchronous operation */
typedef struct fingerprint_device {
/**
- * Common methods of the fingerprint device. This *must* be the first member of
- * fingerprint_device as users of this structure will cast a hw_device_t to
- * fingerprint_device pointer in contexts where it's known the hw_device_t references a
- * fingerprint_device.
+ * Common methods of the fingerprint device. This *must* be the first member
+ * of fingerprint_device as users of this structure will cast a hw_device_t
+ * to fingerprint_device pointer in contexts where it's known
+ * the hw_device_t references a fingerprint_device.
*/
struct hw_device_t common;
@@ -152,10 +167,10 @@
typedef struct fingerprint_module {
/**
- * Common methods of the fingerprint module. This *must* be the first member of
- * fingerprint_module as users of this structure will cast a hw_module_t to
- * fingerprint_module pointer in contexts where it's known the hw_module_t references a
- * fingerprint_module.
+ * Common methods of the fingerprint module. This *must* be the first member
+ * of fingerprint_module as users of this structure will cast a hw_module_t
+ * to fingerprint_module pointer in contexts where it's known
+ * the hw_module_t references a fingerprint_module.
*/
struct hw_module_t common;
} fingerprint_module_t;
diff --git a/include/hardware/gps.h b/include/hardware/gps.h
index 4167793..7244738 100644
--- a/include/hardware/gps.h
+++ b/include/hardware/gps.h
@@ -21,6 +21,7 @@
#include <sys/cdefs.h>
#include <sys/types.h>
#include <pthread.h>
+#include <sys/socket.h>
#include <hardware/hardware.h>
@@ -135,6 +136,12 @@
#define AGPS_SETID_TYPE_IMSI 1
#define AGPS_SETID_TYPE_MSISDN 2
+typedef uint16_t ApnIpType;
+#define APN_IP_INVALID 0
+#define APN_IP_IPV4 1
+#define APN_IP_IPV6 2
+#define APN_IP_IPV4V6 3
+
/**
* String length constants
*/
@@ -481,13 +488,45 @@
/** Represents the status of AGPS. */
typedef struct {
- /** set to sizeof(AGpsStatus) */
+ /** set to sizeof(AGpsStatus_v1) */
+ size_t size;
+
+ AGpsType type;
+ AGpsStatusValue status;
+} AGpsStatus_v1;
+
+/** Represents the status of AGPS augmented with a IPv4 address field. */
+typedef struct {
+ /** set to sizeof(AGpsStatus_v2) */
size_t size;
AGpsType type;
AGpsStatusValue status;
uint32_t ipaddr;
-} AGpsStatus;
+} AGpsStatus_v2;
+
+/* Represents the status of AGPS augmented to support IPv4 and IPv6. */
+typedef struct {
+ /** set to sizeof(AGpsStatus_v3) */
+ size_t size;
+
+ AGpsType type;
+ AGpsStatusValue status;
+
+ /**
+ * Must be set to a valid IPv4 address if the field 'addr' contains an IPv4
+ * address, or set to INADDR_NONE otherwise.
+ */
+ uint32_t ipaddr;
+
+ /**
+ * Must contain the IPv4 (AF_INET) or IPv6 (AF_INET6) address to report.
+ * Any other value of addr.ss_family will be rejected.
+ * */
+ struct sockaddr_storage addr;
+} AGpsStatus_v3;
+
+typedef AGpsStatus_v3 AGpsStatus;
/** Callback with AGPS status information.
* Can only be called from a thread created by create_thread_cb.
@@ -503,7 +542,7 @@
/** Extended interface for AGPS support. */
typedef struct {
- /** set to sizeof(AGpsInterface) */
+ /** set to sizeof(AGpsInterface_v1) */
size_t size;
/**
@@ -528,7 +567,50 @@
* Sets the hostname and port for the AGPS server.
*/
int (*set_server)( AGpsType type, const char* hostname, int port );
-} AGpsInterface;
+} AGpsInterface_v1;
+
+/**
+ * Extended interface for AGPS support, it is augmented to enable to pass
+ * extra APN data.
+ */
+typedef struct {
+ /** set to sizeof(AGpsInterface_v2) */
+ size_t size;
+
+ /**
+ * Opens the AGPS interface and provides the callback routines to the
+ * implementation of this interface.
+ */
+ void (*init)(AGpsCallbacks* callbacks);
+ /**
+ * Deprecated.
+ * If the HAL supports AGpsInterface_v2 this API will not be used, see
+ * data_conn_open_with_apn_ip_type for more information.
+ */
+ int (*data_conn_open)(const char* apn);
+ /**
+ * Notifies that the AGPS data connection has been closed.
+ */
+ int (*data_conn_closed)();
+ /**
+ * Notifies that a data connection is not available for AGPS.
+ */
+ int (*data_conn_failed)();
+ /**
+ * Sets the hostname and port for the AGPS server.
+ */
+ int (*set_server)(AGpsType type, const char* hostname, int port);
+
+ /**
+ * Notifies that a data connection is available and sets the name of the
+ * APN, and its IP type, to be used for SUPL connections.
+ */
+ int (*data_conn_open_with_apn_ip_type)(
+ const char* apn,
+ ApnIpType apnIpType);
+} AGpsInterface_v2;
+
+typedef AGpsInterface_v2 AGpsInterface;
/** Error codes associated with certificate operations */
#define AGPS_CERTIFICATE_OPERATION_SUCCESS 0
diff --git a/include/hardware/hwcomposer.h b/include/hardware/hwcomposer.h
index 67dc3c7..f647ab3 100644
--- a/include/hardware/hwcomposer.h
+++ b/include/hardware/hwcomposer.h
@@ -297,10 +297,19 @@
};
};
- /* Allow for expansion w/o breaking binary compatibility.
- * Pad layer to 96 bytes, assuming 32-bit pointers.
+#ifdef __LP64__
+ /*
+ * For 64-bit mode, this struct is 120 bytes (and 8-byte aligned), and needs
+ * to be padded as such to maintain binary compatibility.
*/
- int32_t reserved[24 - 19];
+ uint8_t reserved[120 - 96];
+#else
+ /*
+ * For 32-bit mode, this struct is 96 bytes, and needs to be padded as such
+ * to maintain binary compatibility.
+ */
+ uint8_t reserved[96 - 76];
+#endif
} hwc_layer_1_t;
diff --git a/include/hardware/sound_trigger.h b/include/hardware/sound_trigger.h
new file mode 100644
index 0000000..fc3ac47
--- /dev/null
+++ b/include/hardware/sound_trigger.h
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include <system/audio.h>
+#include <system/sound_trigger.h>
+#include <hardware/hardware.h>
+
+#ifndef ANDROID_SOUND_TRIGGER_HAL_H
+#define ANDROID_SOUND_TRIGGER_HAL_H
+
+
+__BEGIN_DECLS
+
+/**
+ * The id of this module
+ */
+#define SOUND_TRIGGER_HARDWARE_MODULE_ID "sound_trigger"
+
+/**
+ * Name of the audio devices to open
+ */
+#define SOUND_TRIGGER_HARDWARE_INTERFACE "sound_trigger_hw_if"
+
+#define SOUND_TRIGGER_MODULE_API_VERSION_1_0 HARDWARE_MODULE_API_VERSION(1, 0)
+#define SOUND_TRIGGER_MODULE_API_VERSION_CURRENT SOUND_TRIGGER_MODULE_API_VERSION_1_0
+
+
+#define SOUND_TRIGGER_DEVICE_API_VERSION_1_0 HARDWARE_DEVICE_API_VERSION(1, 0)
+#define SOUND_TRIGGER_DEVICE_API_VERSION_CURRENT SOUND_TRIGGER_DEVICE_API_VERSION_1_0
+
+/**
+ * List of known sound trigger HAL modules. This is the base name of the sound_trigger HAL
+ * library composed of the "sound_trigger." prefix, one of the base names below and
+ * a suffix specific to the device.
+ * e.g: sondtrigger.primary.goldfish.so or sound_trigger.primary.default.so
+ */
+
+#define SOUND_TRIGGER_HARDWARE_MODULE_ID_PRIMARY "primary"
+
+
+/**
+ * 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.
+ */
+struct sound_trigger_module {
+ struct hw_module_t common;
+};
+
+typedef void (*recognition_callback_t)(struct sound_trigger_recognition_event *event, void *cookie);
+typedef void (*sound_model_callback_t)(struct sound_trigger_model_event *event, void *cookie);
+
+struct sound_trigger_hw_device {
+ struct hw_device_t common;
+
+ /*
+ * Retrieve implementation properties.
+ */
+ int (*get_properties)(const struct sound_trigger_hw_device *dev,
+ struct sound_trigger_properties *properties);
+
+ /*
+ * Load a sound model. Once loaded, recognition of this model can be started and stopped.
+ * Only one active recognition per model at a time. The SoundTrigger service will handle
+ * concurrent recognition requests by different users/applications on the same model.
+ * The implementation returns a unique handle used by other functions (unload_sound_model(),
+ * start_recognition(), etc...
+ */
+ int (*load_sound_model)(const struct sound_trigger_hw_device *dev,
+ struct sound_trigger_sound_model *sound_model,
+ sound_model_callback_t callback,
+ void *cookie,
+ sound_model_handle_t *handle);
+
+ /*
+ * Unload a sound model. A sound model can be unloaded to make room for a new one to overcome
+ * implementation limitations.
+ */
+ int (*unload_sound_model)(const struct sound_trigger_hw_device *dev,
+ sound_model_handle_t handle);
+
+ /* Start recognition on a given model. Only one recognition active at a time per model.
+ * Once recognition succeeds of fails, the callback is called.
+ * TODO: group recognition configuration parameters into one struct and add key phrase options.
+ */
+ int (*start_recognition)(const struct sound_trigger_hw_device *dev,
+ sound_model_handle_t sound_model_handle,
+ audio_io_handle_t capture_handle,
+ audio_devices_t capture_device,
+ recognition_callback_t callback,
+ void *cookie,
+ unsigned int data_size,
+ char *data);
+
+ /* Stop recognition on a given model.
+ * The implementation does not have to call the callback when stopped via this method.
+ */
+ int (*stop_recognition)(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;
+
+/** convenience API for opening and closing a supported device */
+
+static inline int sound_trigger_hw_device_open(const struct hw_module_t* module,
+ struct sound_trigger_hw_device** device)
+{
+ return module->methods->open(module, SOUND_TRIGGER_HARDWARE_INTERFACE,
+ (struct hw_device_t**)device);
+}
+
+static inline int sound_trigger_hw_device_close(struct sound_trigger_hw_device* device)
+{
+ return device->common.close(&device->common);
+}
+
+__END_DECLS
+
+#endif // ANDROID_SOUND_TRIGGER_HAL_H
diff --git a/modules/audio_remote_submix/audio_hw.cpp b/modules/audio_remote_submix/audio_hw.cpp
index f11b207..51a5a29 100644
--- a/modules/audio_remote_submix/audio_hw.cpp
+++ b/modules/audio_remote_submix/audio_hw.cpp
@@ -388,8 +388,17 @@
// If a pipe isn't associated with the device, create one.
if (rsxadev->rsxSink == NULL || rsxadev->rsxSource == NULL) {
struct submix_config * const device_config = &rsxadev->config;
- const NBAIO_Format format = Format_from_SR_C(config->sample_rate,
- get_channel_count_from_mask(config->channel_mask), config->format);
+ const uint32_t channel_count = get_channel_count_from_mask(config->channel_mask);
+#if ENABLE_CHANNEL_CONVERSION
+ // If channel conversion is enabled, allocate enough space for the maximum number of
+ // possible channels stored in the pipe for the situation when the number of channels in
+ // the output stream don't match the number in the input stream.
+ const uint32_t pipe_channel_count = max(channel_count, 2);
+#else
+ const uint32_t pipe_channel_count = channel_count;
+#endif // ENABLE_CHANNEL_CONVERSION
+ const NBAIO_Format format = Format_from_SR_C(config->sample_rate, pipe_channel_count,
+ config->format);
const NBAIO_Format offers[1] = {format};
size_t numCounterOffers = 0;
// Create a MonoPipe with optional blocking set to true.
@@ -417,6 +426,11 @@
buffer_period_count;
if (in) device_config->pipe_frame_size = audio_stream_frame_size(&in->stream.common);
if (out) device_config->pipe_frame_size = audio_stream_frame_size(&out->stream.common);
+#if ENABLE_CHANNEL_CONVERSION
+ // Calculate the pipe frame size based upon the number of channels.
+ device_config->pipe_frame_size = (device_config->pipe_frame_size * pipe_channel_count) /
+ channel_count;
+#endif // ENABLE_CHANNEL_CONVERSION
SUBMIX_ALOGV("submix_audio_device_create_pipe(): pipe frame size %zd, pipe size %zd, "
"period size %zd", device_config->pipe_frame_size,
device_config->buffer_size_frames, device_config->buffer_period_size_frames);
@@ -669,15 +683,10 @@
const struct submix_config * const config = &out->dev->config;
const size_t buffer_size_frames = calculate_stream_pipe_size_in_frames(
&stream->common, config, config->buffer_size_frames);
-#if ENABLE_RESAMPLING
- // Sample rate conversion occurs when data is read from the input so data in the buffer is
- // at output_sample_rate Hz.
- const uint32_t latency_ms = (buffer_size_frames * 1000) / config->output_sample_rate;
-#else
- const uint32_t latency_ms = (buffer_size_frames * 1000) / config->common.sample_rate;
-#endif // ENABLE_RESAMPLING
+ const uint32_t sample_rate = out_get_sample_rate(&stream->common);
+ const uint32_t latency_ms = (buffer_size_frames * 1000) / sample_rate;
SUBMIX_ALOGV("out_get_latency() returns %u ms, size in frames %zu, sample rate %u",
- latency_ms, buffer_size_frames, config->common.sample_rate);
+ latency_ms, buffer_size_frames, sample_rate);
return latency_ms;
}
@@ -1114,7 +1123,7 @@
if (remaining_frames > 0) {
const size_t remaining_bytes = remaining_frames * frame_size;
- SUBMIX_ALOGV(" remaining_frames = %zu", remaining_frames);
+ SUBMIX_ALOGV(" clearing remaining_frames = %zu", remaining_frames);
memset(((char*)buffer)+ bytes - remaining_bytes, 0, remaining_bytes);
}
@@ -1186,6 +1195,7 @@
struct submix_audio_device * const rsxadev = audio_hw_device_get_submix_audio_device(dev);
ALOGV("adev_open_output_stream()");
struct submix_stream_out *out;
+ bool force_pipe_creation = false;
(void)handle;
(void)devices;
(void)flags;
@@ -1221,9 +1231,16 @@
out->stream.get_render_position = out_get_render_position;
out->stream.get_next_write_timestamp = out_get_next_write_timestamp;
- // If the sink has been shutdown, delete the pipe so that it's recreated.
+#if ENABLE_RESAMPLING
+ // Recreate the pipe with the correct sample rate so that MonoPipe.write() rate limits
+ // writes correctly.
+ force_pipe_creation = rsxadev->config.common.sample_rate != config->sample_rate;
+#endif // ENABLE_RESAMPLING
+
+ // If the sink has been shutdown or pipe recreation is forced (see above), delete the pipe so
+ // that it's recreated.
pthread_mutex_lock(&rsxadev->lock);
- if (rsxadev->rsxSink != NULL && rsxadev->rsxSink->isShutdown()) {
+ if ((rsxadev->rsxSink != NULL && rsxadev->rsxSink->isShutdown()) || force_pipe_creation) {
submix_audio_device_release_pipe(rsxadev);
}
pthread_mutex_unlock(&rsxadev->lock);
@@ -1347,7 +1364,7 @@
const size_t frame_size_in_bytes = get_channel_count_from_mask(config->channel_mask) *
audio_bytes_per_sample(config->format);
const size_t buffer_size = buffer_period_size_frames * frame_size_in_bytes;
- SUBMIX_ALOGV("out_get_buffer_size() returns %zu bytes, %zu frames",
+ SUBMIX_ALOGV("adev_get_input_buffer_size() returns %zu bytes, %zu frames",
buffer_size, buffer_period_size_frames);
return buffer_size;
}
diff --git a/modules/sensors/multihal.cpp b/modules/sensors/multihal.cpp
index 5fd500a..76ec161 100644
--- a/modules/sensors/multihal.cpp
+++ b/modules/sensors/multihal.cpp
@@ -299,10 +299,11 @@
int sensors_poll_context_t::poll(sensors_event_t *data, int maxReads) {
ALOGV("poll");
int empties = 0;
- int queueCount = (int)this->queues.size();
+ int queueCount = 0;
int eventsRead = 0;
pthread_mutex_lock(&queue_mutex);
+ queueCount = (int)this->queues.size();
while (eventsRead == 0) {
while (empties < queueCount && eventsRead < maxReads) {
SensorEventQueue* queue = this->queues.at(this->nextReadIndex);
@@ -311,7 +312,13 @@
empties++;
} else {
empties = 0;
- this->copy_event_remap_handle(&data[eventsRead++], event, nextReadIndex);
+ this->copy_event_remap_handle(&data[eventsRead], event, nextReadIndex);
+ if (data[eventsRead].sensor == -1) {
+ // Bad handle, do not pass corrupted event upstream !
+ ALOGW("Dropping bad local handle event packet on the floor");
+ } else {
+ eventsRead++;
+ }
queue->dequeue();
}
this->nextReadIndex = (this->nextReadIndex + 1) % queueCount;
diff --git a/modules/soundtrigger/Android.mk b/modules/soundtrigger/Android.mk
new file mode 100644
index 0000000..325980c
--- /dev/null
+++ b/modules/soundtrigger/Android.mk
@@ -0,0 +1,27 @@
+# Copyright (C) 2011 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.
+
+LOCAL_PATH := $(call my-dir)
+
+# Stub sound_trigger HAL module, used for tests
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := sound_trigger.stub.default
+LOCAL_MODULE_RELATIVE_PATH := hw
+LOCAL_SRC_FILES := sound_trigger_hw.c
+LOCAL_SHARED_LIBRARIES := liblog libcutils
+LOCAL_MODULE_TAGS := optional
+LOCAL_32_BIT_ONLY := true
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/modules/soundtrigger/sound_trigger_hw.c b/modules/soundtrigger/sound_trigger_hw.c
new file mode 100644
index 0000000..8347d02
--- /dev/null
+++ b/modules/soundtrigger/sound_trigger_hw.c
@@ -0,0 +1,301 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#define LOG_TAG "sound_trigger_hw_default"
+/*#define LOG_NDEBUG 0*/
+
+#include <errno.h>
+#include <pthread.h>
+#include <sys/prctl.h>
+#include <cutils/log.h>
+
+#include <hardware/hardware.h>
+#include <system/sound_trigger.h>
+#include <hardware/sound_trigger.h>
+
+static const struct sound_trigger_properties hw_properties = {
+ "The Android Open Source Project", // implementor
+ "Sound Trigger stub HAL", // description
+ 1, // version
+ { 0xed7a7d60, 0xc65e, 0x11e3, 0x9be4, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } }, // uuid
+ 1, // max_sound_models
+ 1, // max_key_phrases
+ 1, // max_users
+ RECOGNITION_MODE_VOICE_TRIGGER, // recognition_modes
+ false, // capture_transition
+ 0, // max_buffer_ms
+ false, // concurrent_capture
+ 0 // power_consumption_mw
+};
+
+struct stub_sound_trigger_device {
+ struct sound_trigger_hw_device device;
+ sound_model_handle_t model_handle;
+ recognition_callback_t recognition_callback;
+ void *recognition_cookie;
+ sound_model_callback_t sound_model_callback;
+ void *sound_model_cookie;
+ pthread_t callback_thread;
+ pthread_mutex_t lock;
+ pthread_cond_t cond;
+
+};
+
+
+static void *callback_thread_loop(void *context)
+{
+ struct stub_sound_trigger_device *stdev = (struct stub_sound_trigger_device *)context;
+ ALOGI("%s", __func__);
+
+ prctl(PR_SET_NAME, (unsigned long)"sound trigger callback", 0, 0, 0);
+
+ pthread_mutex_lock(&stdev->lock);
+ if (stdev->recognition_callback == NULL) {
+ goto exit;
+ }
+ struct timespec ts;
+ clock_gettime(CLOCK_REALTIME, &ts);
+ ts.tv_sec += 3;
+ ALOGI("%s wait 3 sec", __func__);
+ int rc = pthread_cond_timedwait(&stdev->cond, &stdev->lock, &ts);
+ if (rc == ETIMEDOUT && stdev->recognition_callback != NULL) {
+ char *data = (char *)calloc(1, sizeof(struct sound_trigger_phrase_recognition_event) + 1);
+ struct sound_trigger_phrase_recognition_event *event =
+ (struct sound_trigger_phrase_recognition_event *)data;
+ event->common.status = RECOGNITION_STATUS_SUCCESS;
+ event->common.type = SOUND_MODEL_TYPE_KEYPHRASE;
+ event->common.model = stdev->model_handle;
+ event->key_phrase_in_capture = false;
+ event->num_phrases = 1;
+ event->phrase_extras[0].recognition_modes = RECOGNITION_MODE_VOICE_TRIGGER;
+ event->phrase_extras[0].num_users = 1;
+ event->phrase_extras[0].confidence_levels[0] = 100;
+ event->common.data_offset = sizeof(struct sound_trigger_phrase_recognition_event);
+ event->common.data_size = 1;
+ data[event->common.data_offset] = 8;
+ ALOGI("%s send callback model %d", __func__, stdev->model_handle);
+ stdev->recognition_callback(&event->common, stdev->recognition_cookie);
+ free(data);
+ } else {
+ ALOGI("%s abort recognition model %d", __func__, stdev->model_handle);
+ }
+ stdev->recognition_callback = NULL;
+
+exit:
+ pthread_mutex_unlock(&stdev->lock);
+
+ return NULL;
+}
+
+static int stdev_get_properties(const struct sound_trigger_hw_device *dev,
+ struct sound_trigger_properties *properties)
+{
+ struct stub_sound_trigger_device *stdev = (struct stub_sound_trigger_device *)dev;
+
+ ALOGI("%s", __func__);
+ if (properties == NULL)
+ return -EINVAL;
+ memcpy(properties, &hw_properties, sizeof(struct sound_trigger_properties));
+ return 0;
+}
+
+static int stdev_load_sound_model(const struct sound_trigger_hw_device *dev,
+ struct sound_trigger_sound_model *sound_model,
+ sound_model_callback_t callback,
+ void *cookie,
+ sound_model_handle_t *handle)
+{
+ struct stub_sound_trigger_device *stdev = (struct stub_sound_trigger_device *)dev;
+ int status = 0;
+
+ ALOGI("%s stdev %p", __func__, stdev);
+ pthread_mutex_lock(&stdev->lock);
+ if (handle == NULL || sound_model == NULL) {
+ status = -EINVAL;
+ goto exit;
+ }
+ if (sound_model->data_size == 0 ||
+ sound_model->data_offset < sizeof(struct sound_trigger_sound_model)) {
+ status = -EINVAL;
+ goto exit;
+ }
+
+ if (stdev->model_handle == 1) {
+ status = -ENOSYS;
+ goto exit;
+ }
+ 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_handle = 1;
+ stdev->sound_model_callback = callback;
+ stdev->sound_model_cookie = cookie;
+
+ *handle = stdev->model_handle;
+
+exit:
+ pthread_mutex_unlock(&stdev->lock);
+ return status;
+}
+
+static int stdev_unload_sound_model(const struct sound_trigger_hw_device *dev,
+ sound_model_handle_t handle)
+{
+ struct stub_sound_trigger_device *stdev = (struct stub_sound_trigger_device *)dev;
+ int status = 0;
+
+ ALOGI("%s handle %d", __func__, handle);
+ pthread_mutex_lock(&stdev->lock);
+ if (handle != 1) {
+ status = -EINVAL;
+ goto exit;
+ }
+ if (stdev->model_handle == 0) {
+ status = -ENOSYS;
+ goto exit;
+ }
+ stdev->model_handle = 0;
+ if (stdev->recognition_callback != NULL) {
+ stdev->recognition_callback = NULL;
+ pthread_cond_signal(&stdev->cond);
+ pthread_mutex_unlock(&stdev->lock);
+ pthread_join(stdev->callback_thread, (void **) NULL);
+ pthread_mutex_lock(&stdev->lock);
+ }
+
+exit:
+ pthread_mutex_unlock(&stdev->lock);
+ return status;
+}
+
+static int stdev_start_recognition(const struct sound_trigger_hw_device *dev,
+ sound_model_handle_t sound_model_handle,
+ audio_io_handle_t capture_handle __unused,
+ audio_devices_t capture_device __unused,
+ recognition_callback_t callback,
+ void *cookie,
+ unsigned int data_size,
+ char *data)
+{
+ struct stub_sound_trigger_device *stdev = (struct stub_sound_trigger_device *)dev;
+ int status = 0;
+ ALOGI("%s sound model %d", __func__, sound_model_handle);
+ pthread_mutex_lock(&stdev->lock);
+ if (stdev->model_handle != sound_model_handle) {
+ status = -ENOSYS;
+ goto exit;
+ }
+ if (stdev->recognition_callback != NULL) {
+ status = -ENOSYS;
+ goto exit;
+ }
+ if (data_size != 0 && data == NULL) {
+ status = -EINVAL;
+ goto exit;
+ }
+ if (data_size != 0) {
+ ALOGI("%s data size %d data %d - %d", __func__,
+ data_size, data[0], data[data_size - 1]);
+ }
+
+ stdev->recognition_callback = callback;
+ stdev->recognition_cookie = cookie;
+ pthread_create(&stdev->callback_thread, (const pthread_attr_t *) NULL,
+ callback_thread_loop, stdev);
+exit:
+ pthread_mutex_unlock(&stdev->lock);
+ return status;
+}
+
+static int stdev_stop_recognition(const struct sound_trigger_hw_device *dev,
+ sound_model_handle_t sound_model_handle)
+{
+ struct stub_sound_trigger_device *stdev = (struct stub_sound_trigger_device *)dev;
+ int status = 0;
+ ALOGI("%s sound model %d", __func__, sound_model_handle);
+ pthread_mutex_lock(&stdev->lock);
+ if (stdev->model_handle != sound_model_handle) {
+ status = -ENOSYS;
+ goto exit;
+ }
+ if (stdev->recognition_callback == NULL) {
+ status = -ENOSYS;
+ goto exit;
+ }
+ stdev->recognition_callback = NULL;
+ pthread_cond_signal(&stdev->cond);
+ pthread_mutex_unlock(&stdev->lock);
+ pthread_join(stdev->callback_thread, (void **) NULL);
+ pthread_mutex_lock(&stdev->lock);
+
+exit:
+ pthread_mutex_unlock(&stdev->lock);
+ return status;
+}
+
+
+static int stdev_close(hw_device_t *device)
+{
+ free(device);
+ return 0;
+}
+
+static int stdev_open(const hw_module_t* module, const char* name,
+ hw_device_t** device)
+{
+ struct stub_sound_trigger_device *stdev;
+ int ret;
+
+ if (strcmp(name, SOUND_TRIGGER_HARDWARE_INTERFACE) != 0)
+ return -EINVAL;
+
+ stdev = calloc(1, sizeof(struct stub_sound_trigger_device));
+ if (!stdev)
+ return -ENOMEM;
+
+ stdev->device.common.tag = HARDWARE_DEVICE_TAG;
+ stdev->device.common.version = SOUND_TRIGGER_DEVICE_API_VERSION_1_0;
+ stdev->device.common.module = (struct hw_module_t *) module;
+ stdev->device.common.close = stdev_close;
+ stdev->device.get_properties = stdev_get_properties;
+ stdev->device.load_sound_model = stdev_load_sound_model;
+ stdev->device.unload_sound_model = stdev_unload_sound_model;
+ stdev->device.start_recognition = stdev_start_recognition;
+ stdev->device.stop_recognition = stdev_stop_recognition;
+
+ pthread_mutex_init(&stdev->lock, (const pthread_mutexattr_t *) NULL);
+ pthread_cond_init(&stdev->cond, (const pthread_condattr_t *) NULL);
+
+ *device = &stdev->device.common;
+
+ return 0;
+}
+
+static struct hw_module_methods_t hal_module_methods = {
+ .open = stdev_open,
+};
+
+struct sound_trigger_module HAL_MODULE_INFO_SYM = {
+ .common = {
+ .tag = HARDWARE_MODULE_TAG,
+ .module_api_version = SOUND_TRIGGER_MODULE_API_VERSION_1_0,
+ .hal_api_version = HARDWARE_HAL_API_VERSION,
+ .id = SOUND_TRIGGER_HARDWARE_MODULE_ID,
+ .name = "Default sound trigger HAL",
+ .author = "The Android Open Source Project",
+ .methods = &hal_module_methods,
+ },
+};