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,
+    },
+};