Merge "Add symbol AUDIO_PARAMETER_KEY_BT_SCO_WB"
diff --git a/include/hardware/activity_recognition.h b/include/hardware/activity_recognition.h
new file mode 100644
index 0000000..3d3c1bd
--- /dev/null
+++ b/include/hardware/activity_recognition.h
@@ -0,0 +1,186 @@
+/*
+ * 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.
+ */
+
+/*
+ * Activity Recognition HAL. The goal is to provide low power, low latency, always-on activity
+ * recognition implemented in hardware (i.e. these activity recognition algorithms/classifers
+ * should NOT be run on the AP). By low power we mean that this may be activated 24/7 without
+ * impacting the battery drain speed (goal in order of 1mW including the power for sensors).
+ * This HAL does not specify the input sources that are used towards detecting these activities.
+ * It has one monitor interface which can be used to batch activities for always-on
+ * activity_recognition and if the latency is zero, the same interface can be used for low latency
+ * detection.
+ */
+
+#ifndef ANDROID_ACTIVITY_RECOGNITION_INTERFACE_H
+#define ANDROID_ACTIVITY_RECOGNITION_INTERFACE_H
+
+#include <hardware/hardware.h>
+
+__BEGIN_DECLS
+
+#define ACTIVITY_RECOGNITION_HEADER_VERSION   1
+#define ACTIVITY_RECOGNITION_API_VERSION_0_1  HARDWARE_DEVICE_API_VERSION_2(0, 1, ACTIVITY_RECOGNITION_HEADER_VERSION)
+
+#define ACTIVITY_RECOGNITION_HARDWARE_MODULE_ID "activity_recognition"
+#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.
+ */
+
+/* Reserved. get_supported_activities_list() should not return this activity. */
+#define DETECTED_ACTIVITY_RESERVED          (0)
+
+#define DETECTED_ACTIVITY_IN_VEHICLE        (1)
+
+#define DETECTED_ACTIVITY_ON_BICYCLE        (2)
+
+#define DETECTED_ACTIVITY_WALKING           (3)
+
+#define DETECTED_ACTIVITY_RUNNING           (4)
+
+#define DETECTED_ACTIVITY_STILL             (5)
+
+#define DETECTED_ACTIVITY_TILTING           (6)
+
+/* Values for activity_event.event_types. */
+enum {
+    /*
+     * A flush_complete event which indicates that a flush() has been successfully completed. This
+     * does not correspond to any activity/event. An event of this type should be added to the end
+     * of a batch FIFO and it indicates that all the events in the batch FIFO have been successfully
+     * reported to the framework. An event of this type should be generated only if flush() has been
+     * explicitly called and if the FIFO is empty at the time flush() is called it should trivially
+     * 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.detected_activity = DETECTED_ACTIVITY_RESERVED
+     * activity_event_t.timestamp = 0
+     * activity_event_t.reserved = 0
+     * See (*flush)() for more details.
+     */
+    ACTIVITY_EVENT_TYPE_FLUSH_COMPLETE = 0,
+
+    /* Signifies entering an activity. */
+    ACTIVITY_EVENT_TYPE_ENTER = 1,
+
+    /* Signifies exiting an activity. */
+    ACTIVITY_EVENT_TYPE_EXIT  = 2
+};
+
+/*
+ * Each event is a separate activity with event_type indicating whether this activity has started
+ * or ended. Eg event: (event_type="enter", detected_activity="ON_FOOT", timestamp)
+ */
+typedef struct activity_event {
+    /* One of the ACTIVITY_EVENT_TYPE_* constants defined above. */
+    uint32_t event_type;
+
+    /* Detected Activity. One of DETECTED_ACTIVITY_TYPE_* constants defined above. */
+    int32_t detected_activity;
+
+    /* Time at which the transition/event has occurred in nanoseconds using elapsedRealTimeNano. */
+    int64_t timestamp;
+
+    /* Set to zero. */
+    int32_t reserved[4];
+} activity_event_t;
+
+typedef struct activity_recognition_module {
+    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 DETECTED_ACTIVITY_* constants defined above. Return
+     * value is the size of this list.
+     */
+    int (*get_supported_activities_list)(struct activity_recognition_module* module,
+            int** activity_list);
+} activity_recognition_module_t;
+
+struct activity_recognition_device;
+
+typedef struct activity_recognition_callback_procs {
+    // Callback for activity_data. This is guaranteed to not invoke any HAL methods.
+    // Memory allocated for the events can be reused after this method returns.
+    //    events - Array of activity_event_t s that are reported.
+    //    count  - size of the array.
+    void (*activity_callback)(const struct activity_recognition_device* dev,
+            const activity_event_t* events, int count);
+} activity_recognition_callback_procs_t;
+
+typedef struct activity_recognition_device {
+    hw_device_t common;
+
+    /*
+     * Sets the callback to invoke when there are events to report. This call overwrites the
+     * previously registered callback (if any).
+     */
+    void (*register_activity_callback)(const struct activity_recognition_device* dev,
+            const activity_recognition_callback_procs_t* callback);
+
+    /*
+     * Activates and deactivates monitoring of activity transitions. Activities need not be reported
+     * as soon as they are detected. The detected activities are stored in a FIFO and reported in
+     * batches when the "max_batch_report_latency" expires or when the batch FIFO is full. The
+     * implementation should allow the AP to go into suspend mode while the activities are detected
+     * and stored in the batch FIFO. Whenever events need to be reported (like when the FIFO is full
+     * or when the max_batch_report_latency has expired for an activity, event pair), it should
+     * wake_up the AP so that no events are lost. Activities are stored as transitions and they are
+     * allowed to overlap with each other.
+     * detected_activity - The specific activity that needs to be monitored.
+     * event_type    - Specific transition of the activity that needs to be monitored.
+     * enabled       - Enable/Disable detection of an (detected_activity, event_type) pair. Each
+     *                 pair can be activated or deactivated independently of the other. The HAL
+     *                 implementation needs to keep track of which pairs are currently active
+     *                 and needs to detect only those activities.
+     * max_batch_report_latency - a transition can be delayed by at most
+     *                            “max_batch_report_latency” nanoseconds.
+     * Return 0 on success, negative errno code otherwise.
+     */
+    int (*monitor_activity_event)(const struct activity_recognition_device* dev,
+            int32_t detected_activity, int32_t event_type, int64_t max_batch_report_latency_ns,
+            int32_t enabled);
+
+    /*
+     * 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.
+     * Return 0 on success, negative errno code otherwise.
+     */
+    int (*flush)(const struct activity_recognition_device* dev);
+
+    // Must be set to NULL.
+    void (*reserved_procs[4])(void);
+} activity_recognition_device_t;
+
+static inline int activity_recognition_open(const hw_module_t* module,
+        activity_recognition_device_t** device) {
+    return module->methods->open(module,
+            ACTIVITY_RECOGNITION_HARDWARE_INTERFACE, (hw_device_t**)device);
+}
+
+static inline int activity_recognition_close(activity_recognition_device_t* device) {
+    return device->common.close(&device->common);
+}
+
+__END_DECLS
+
+#endif // ANDROID_ACTIVITY_RECOGNITION_INTERFACE_H
diff --git a/include/hardware/camera3.h b/include/hardware/camera3.h
index 4503885..6623dc7 100644
--- a/include/hardware/camera3.h
+++ b/include/hardware/camera3.h
@@ -1535,17 +1535,18 @@
  * Transport header for compressed JPEG buffers in output streams.
  *
  * To capture JPEG images, a stream is created using the pixel format
- * HAL_PIXEL_FORMAT_BLOB, and the static metadata field android.jpeg.maxSize is
- * used as the buffer size. Since compressed JPEG images are of variable size,
- * the HAL needs to include the final size of the compressed image using this
- * structure inside the output stream buffer. The JPEG blob ID field must be set
- * to CAMERA3_JPEG_BLOB_ID.
+ * HAL_PIXEL_FORMAT_BLOB. The buffer size for the stream is calculated by the
+ * framework, based on the static metadata field android.jpeg.maxSize. Since
+ * compressed JPEG images are of variable size, the HAL needs to include the
+ * final size of the compressed image using this structure inside the output
+ * stream buffer. The JPEG blob ID field must be set to CAMERA3_JPEG_BLOB_ID.
  *
- * Transport header should be at the end of the JPEG output stream buffer.  That
- * means the jpeg_blob_id must start at byte[android.jpeg.maxSize -
- * sizeof(camera3_jpeg_blob)].  Any HAL using this transport header must
- * account for it in android.jpeg.maxSize.  The JPEG data itself starts at
- * the beginning of the buffer and should be jpeg_size bytes long.
+ * Transport header should be at the end of the JPEG output stream buffer. That
+ * means the jpeg_blob_id must start at byte[buffer_size -
+ * sizeof(camera3_jpeg_blob)], where the buffer_size is the size of gralloc buffer.
+ * Any HAL using this transport header must account for it in android.jpeg.maxSize
+ * The JPEG data itself starts at the beginning of the buffer and should be
+ * jpeg_size bytes long.
  */
 typedef struct camera3_jpeg_blob {
     uint16_t jpeg_blob_id;
diff --git a/modules/usbaudio/audio_hw.c b/modules/usbaudio/audio_hw.c
index 4cb0071..7b2a4f1 100644
--- a/modules/usbaudio/audio_hw.c
+++ b/modules/usbaudio/audio_hw.c
@@ -15,15 +15,16 @@
  */
 
 #define LOG_TAG "usb_audio_hw"
-/* #define LOG_NDEBUG 0 */
+/*#define LOG_NDEBUG 0*/
 
 #include <errno.h>
+#include <inttypes.h>
 #include <pthread.h>
 #include <stdint.h>
-#include <sys/time.h>
 #include <stdlib.h>
+#include <sys/time.h>
 
-#include <cutils/log.h>
+#include <log/log.h>
 #include <cutils/str_parms.h>
 #include <cutils/properties.h>
 
@@ -180,7 +181,7 @@
  *   This conversion is safe to do in-place (in_buff == out_buff).
  * TODO(pmclean, hung) Move this to a utilities module.
  */
-static size_t convert_16_to_24_3(short * in_buff, size_t num_in_samples, unsigned char * out_buff) {
+static size_t convert_16_to_24_3(const short * in_buff, size_t num_in_samples, unsigned char * out_buff) {
     /*
      * Move from back to front so that the conversion can be done in-place
      * i.e. in_buff == out_buff
@@ -190,7 +191,7 @@
     int out_buff_size_in_bytes = ((3 * in_buff_size_in_bytes) / 2);
     unsigned char* dst_ptr = out_buff + out_buff_size_in_bytes - 1;
     size_t src_smpl_index;
-    unsigned char* src_ptr = ((unsigned char *)in_buff) + in_buff_size_in_bytes - 1;
+    const unsigned char* src_ptr = ((const unsigned char *)in_buff) + in_buff_size_in_bytes - 1;
     for (src_smpl_index = 0; src_smpl_index < num_in_samples; src_smpl_index++) {
         *dst_ptr-- = *src_ptr--; /* hi-byte */
         *dst_ptr-- = *src_ptr--; /* low-byte */
@@ -216,14 +217,14 @@
  *   This conversion is safe to do in-place (in_buff == out_buff).
  * TODO(pmclean, hung) Move this to a utilities module.
  */
-static size_t convert_24_3_to_16(unsigned char * in_buff, size_t num_in_samples, short * out_buff) {
+static size_t convert_24_3_to_16(const unsigned char * in_buff, size_t num_in_samples, short * out_buff) {
     /*
      * Move from front to back so that the conversion can be done in-place
      * i.e. in_buff == out_buff
      */
     /* we need 2 bytes in the output for every 3 bytes in the input */
     unsigned char* dst_ptr = (unsigned char*)out_buff;
-    unsigned char* src_ptr = in_buff;
+    const unsigned char* src_ptr = in_buff;
     size_t src_smpl_index;
     for (src_smpl_index = 0; src_smpl_index < num_in_samples; src_smpl_index++) {
         src_ptr++;               /* lowest-(skip)-byte */
@@ -252,7 +253,7 @@
  * support 4-channel devices.
  * TODO(pmclean, hung) Move this to a utilities module.
  */
-static size_t expand_channels_16(short* in_buff, int in_buff_chans,
+static size_t expand_channels_16(const short* in_buff, int in_buff_chans,
                                  short* out_buff, int out_buff_chans,
                                  size_t num_in_samples) {
     /*
@@ -263,8 +264,8 @@
     int num_out_samples = (num_in_samples * out_buff_chans)/in_buff_chans;
 
     short* dst_ptr = out_buff + num_out_samples - 1;
-    int src_index;
-    short* src_ptr = in_buff + num_in_samples - 1;
+    size_t src_index;
+    const short* src_ptr = in_buff + num_in_samples - 1;
     int num_zero_chans = out_buff_chans - in_buff_chans;
     for (src_index = 0; src_index < num_in_samples; src_index += in_buff_chans) {
         int dst_offset;
@@ -311,7 +312,7 @@
 
     short* dst_ptr = out_buff;
     short* src_ptr = in_buff;
-    int src_index;
+    size_t src_index;
     for (src_index = 0; src_index < num_in_samples; src_index += in_buff_chans) {
         int dst_offset;
         for(dst_offset = 0; dst_offset < out_buff_chans; dst_offset++) {
@@ -331,7 +332,7 @@
  * gets the ALSA bit-format flag from a bits-per-sample value.
  * TODO(pmclean, hung) Move this to a utilities module.
  */
-static int bits_to_alsa_format(int bits_per_sample, int default_format)
+static int bits_to_alsa_format(unsigned int bits_per_sample, int default_format)
 {
     enum pcm_format format;
     for (format = PCM_FORMAT_S16_LE; format < PCM_FORMAT_MAX; format++) {
@@ -342,6 +343,45 @@
     return default_format;
 }
 
+static void log_pcm_params(struct pcm_params * alsa_hw_params) {
+    ALOGV("usb:audio_hw - PCM_PARAM_SAMPLE_BITS min:%u, max:%u",
+          pcm_params_get_min(alsa_hw_params, PCM_PARAM_SAMPLE_BITS),
+          pcm_params_get_max(alsa_hw_params, PCM_PARAM_SAMPLE_BITS));
+    ALOGV("usb:audio_hw - PCM_PARAM_FRAME_BITS min:%u, max:%u",
+          pcm_params_get_min(alsa_hw_params, PCM_PARAM_FRAME_BITS),
+          pcm_params_get_max(alsa_hw_params, PCM_PARAM_FRAME_BITS));
+    ALOGV("usb:audio_hw - PCM_PARAM_CHANNELS min:%u, max:%u",
+          pcm_params_get_min(alsa_hw_params, PCM_PARAM_CHANNELS),
+          pcm_params_get_max(alsa_hw_params, PCM_PARAM_CHANNELS));
+    ALOGV("usb:audio_hw - PCM_PARAM_RATE min:%u, max:%u",
+          pcm_params_get_min(alsa_hw_params, PCM_PARAM_RATE),
+          pcm_params_get_max(alsa_hw_params, PCM_PARAM_RATE));
+    ALOGV("usb:audio_hw - PCM_PARAM_PERIOD_TIME min:%u, max:%u",
+          pcm_params_get_min(alsa_hw_params, PCM_PARAM_PERIOD_TIME),
+          pcm_params_get_max(alsa_hw_params, PCM_PARAM_PERIOD_TIME));
+    ALOGV("usb:audio_hw - PCM_PARAM_PERIOD_SIZE min:%u, max:%u",
+          pcm_params_get_min(alsa_hw_params, PCM_PARAM_PERIOD_SIZE),
+          pcm_params_get_max(alsa_hw_params, PCM_PARAM_PERIOD_SIZE));
+    ALOGV("usb:audio_hw - PCM_PARAM_PERIOD_BYTES min:%u, max:%u",
+          pcm_params_get_min(alsa_hw_params, PCM_PARAM_PERIOD_BYTES),
+          pcm_params_get_max(alsa_hw_params, PCM_PARAM_PERIOD_BYTES));
+    ALOGV("usb:audio_hw - PCM_PARAM_PERIODS min:%u, max:%u",
+          pcm_params_get_min(alsa_hw_params, PCM_PARAM_PERIODS),
+          pcm_params_get_max(alsa_hw_params, PCM_PARAM_PERIODS));
+    ALOGV("usb:audio_hw - PCM_PARAM_BUFFER_TIME min:%u, max:%u",
+          pcm_params_get_min(alsa_hw_params, PCM_PARAM_BUFFER_TIME),
+          pcm_params_get_max(alsa_hw_params, PCM_PARAM_BUFFER_TIME));
+    ALOGV("usb:audio_hw - PCM_PARAM_BUFFER_SIZE min:%u, max:%u",
+          pcm_params_get_min(alsa_hw_params, PCM_PARAM_BUFFER_SIZE),
+          pcm_params_get_max(alsa_hw_params, PCM_PARAM_BUFFER_SIZE));
+    ALOGV("usb:audio_hw - PCM_PARAM_BUFFER_BYTES min:%u, max:%u",
+          pcm_params_get_min(alsa_hw_params, PCM_PARAM_BUFFER_BYTES),
+          pcm_params_get_max(alsa_hw_params, PCM_PARAM_BUFFER_BYTES));
+    ALOGV("usb:audio_hw - PCM_PARAM_TICK_TIME min:%u, max:%u",
+          pcm_params_get_min(alsa_hw_params, PCM_PARAM_TICK_TIME),
+          pcm_params_get_max(alsa_hw_params, PCM_PARAM_TICK_TIME));
+}
+
 /*
  * Reads and decodes configuration info from the specified ALSA card/device
  */
@@ -361,25 +401,14 @@
     /*
      * This Logging will be useful when testing new USB devices.
      */
-    /* ALOGV("usb:audio_hw - PCM_PARAM_SAMPLE_BITS min:%d, max:%d", pcm_params_get_min(alsa_hw_params, PCM_PARAM_SAMPLE_BITS), pcm_params_get_max(alsa_hw_params, PCM_PARAM_SAMPLE_BITS)); */
-    /* ALOGV("usb:audio_hw - PCM_PARAM_FRAME_BITS min:%d, max:%d", pcm_params_get_min(alsa_hw_params, PCM_PARAM_FRAME_BITS), pcm_params_get_max(alsa_hw_params, PCM_PARAM_FRAME_BITS)); */
-    /* ALOGV("usb:audio_hw - PCM_PARAM_CHANNELS min:%d, max:%d", pcm_params_get_min(alsa_hw_params, PCM_PARAM_CHANNELS), pcm_params_get_max(alsa_hw_params, PCM_PARAM_CHANNELS)); */
-    /* ALOGV("usb:audio_hw - PCM_PARAM_RATE min:%d, max:%d", pcm_params_get_min(alsa_hw_params, PCM_PARAM_RATE), pcm_params_get_max(alsa_hw_params, PCM_PARAM_RATE)); */
-    /* ALOGV("usb:audio_hw - PCM_PARAM_PERIOD_TIME min:%d, max:%d", pcm_params_get_min(alsa_hw_params, PCM_PARAM_PERIOD_TIME), pcm_params_get_max(alsa_hw_params, PCM_PARAM_PERIOD_TIME)); */
-    /* ALOGV("usb:audio_hw - PCM_PARAM_PERIOD_SIZE min:%d, max:%d", pcm_params_get_min(alsa_hw_params, PCM_PARAM_PERIOD_SIZE), pcm_params_get_max(alsa_hw_params, PCM_PARAM_PERIOD_SIZE)); */
-    /* ALOGV("usb:audio_hw - PCM_PARAM_PERIOD_BYTES min:%d, max:%d", pcm_params_get_min(alsa_hw_params, PCM_PARAM_PERIOD_BYTES), pcm_params_get_max(alsa_hw_params, PCM_PARAM_PERIOD_BYTES)); */
-    /* ALOGV("usb:audio_hw - PCM_PARAM_PERIODS min:%d, max:%d", pcm_params_get_min(alsa_hw_params, PCM_PARAM_PERIODS), pcm_params_get_max(alsa_hw_params, PCM_PARAM_PERIODS)); */
-    /* ALOGV("usb:audio_hw - PCM_PARAM_BUFFER_TIME min:%d, max:%d", pcm_params_get_min(alsa_hw_params, PCM_PARAM_BUFFER_TIME), pcm_params_get_max(alsa_hw_params, PCM_PARAM_BUFFER_TIME)); */
-    /* ALOGV("usb:audio_hw - PCM_PARAM_BUFFER_SIZE min:%d, max:%d", pcm_params_get_min(alsa_hw_params, PCM_PARAM_BUFFER_SIZE), pcm_params_get_max(alsa_hw_params, PCM_PARAM_BUFFER_SIZE)); */
-    /* ALOGV("usb:audio_hw - PCM_PARAM_BUFFER_BYTES min:%d, max:%d", pcm_params_get_min(alsa_hw_params, PCM_PARAM_BUFFER_BYTES), pcm_params_get_max(alsa_hw_params, PCM_PARAM_BUFFER_BYTES)); */
-    /* ALOGV("usb:audio_hw - PCM_PARAM_TICK_TIME min:%d, max:%d", pcm_params_get_min(alsa_hw_params, PCM_PARAM_TICK_TIME), pcm_params_get_max(alsa_hw_params, PCM_PARAM_TICK_TIME)); */
+    /* log_pcm_params(alsa_hw_params); */
 
     config->channels = pcm_params_get_min(alsa_hw_params, PCM_PARAM_CHANNELS);
     config->rate = pcm_params_get_min(alsa_hw_params, PCM_PARAM_RATE);
     config->period_size = pcm_params_get_max(alsa_hw_params, PCM_PARAM_PERIODS);
     config->period_count = pcm_params_get_min(alsa_hw_params, PCM_PARAM_PERIODS);
 
-    int bits_per_sample = pcm_params_get_min(alsa_hw_params, PCM_PARAM_SAMPLE_BITS);
+    unsigned int bits_per_sample = pcm_params_get_min(alsa_hw_params, PCM_PARAM_SAMPLE_BITS);
     config->format = bits_to_alsa_format(bits_per_sample, PCM_FORMAT_S16_LE);
 
     return 0;
@@ -526,9 +555,9 @@
         // if they are different, return a list containing those two values, otherwise just the one.
         min = pcm_params_get_min(alsa_hw_params, PCM_PARAM_RATE);
         max = pcm_params_get_max(alsa_hw_params, PCM_PARAM_RATE);
-        num_written = snprintf(buffer, buffer_size, "%d", min);
+        num_written = snprintf(buffer, buffer_size, "%u", min);
         if (min != max) {
-            snprintf(buffer + num_written, buffer_size - num_written, "|%d", max);
+            snprintf(buffer + num_written, buffer_size - num_written, "|%u", max);
         }
         str_parms_add_str(result, AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES,
                           buffer);
@@ -539,9 +568,9 @@
         // Similarly for output channels count
         min = pcm_params_get_min(alsa_hw_params, PCM_PARAM_CHANNELS);
         max = pcm_params_get_max(alsa_hw_params, PCM_PARAM_CHANNELS);
-        num_written = snprintf(buffer, buffer_size, "%d", min);
+        num_written = snprintf(buffer, buffer_size, "%u", min);
         if (min != max) {
-            snprintf(buffer + num_written, buffer_size - num_written, "|%d", max);
+            snprintf(buffer + num_written, buffer_size - num_written, "|%u", max);
         }
         str_parms_add_str(result, AUDIO_PARAMETER_STREAM_SUP_CHANNELS, buffer);
     }  // AUDIO_PARAMETER_STREAM_SUP_CHANNELS
@@ -552,9 +581,9 @@
         //TODO(pmclean): this is wrong.
         min = pcm_params_get_min(alsa_hw_params, PCM_PARAM_SAMPLE_BITS);
         max = pcm_params_get_max(alsa_hw_params, PCM_PARAM_SAMPLE_BITS);
-        num_written = snprintf(buffer, buffer_size, "%d", min);
+        num_written = snprintf(buffer, buffer_size, "%u", min);
         if (min != max) {
-            snprintf(buffer + num_written, buffer_size - num_written, "|%d", max);
+            snprintf(buffer + num_written, buffer_size - num_written, "|%u", max);
         }
         str_parms_add_str(result, AUDIO_PARAMETER_STREAM_SUP_FORMATS, buffer);
     }  // AUDIO_PARAMETER_STREAM_SUP_FORMATS
@@ -626,7 +655,7 @@
     // compute maximum potential buffer size.
     // * 2 for stereo -> quad conversion
     // * 3/2 for 16bit -> 24 bit conversion
-    int required_conversion_buffer_size = (bytes * 3 * 2) / 2;
+    size_t required_conversion_buffer_size = (bytes * 3 * 2) / 2;
     if (required_conversion_buffer_size > out->conversion_buffer_size) {
         //TODO(pmclean) - remove this when AudioPolicyManger/AudioFlinger support arbitrary formats
         // (and do these conversions themselves)
@@ -634,7 +663,7 @@
         out->conversion_buffer = realloc(out->conversion_buffer, out->conversion_buffer_size);
     }
 
-    void * write_buff = buffer;
+    const void * write_buff = buffer;
     int num_write_buff_bytes = bytes;
 
     /*
@@ -868,7 +897,7 @@
 
 static size_t in_get_buffer_size(const struct audio_stream *stream)
 {
-    ALOGV("usb: in_get_buffer_size() = %d",
+    ALOGV("usb: in_get_buffer_size() = %zu",
           cached_input_hardware_config.period_size * audio_stream_frame_size(stream));
     return cached_input_hardware_config.period_size * audio_stream_frame_size(stream);
 
@@ -990,9 +1019,9 @@
         // if they are different, return a list containing those two values, otherwise just the one.
         min = pcm_params_get_min(alsa_hw_params, PCM_PARAM_RATE);
         max = pcm_params_get_max(alsa_hw_params, PCM_PARAM_RATE);
-        num_written = snprintf(buffer, buffer_size, "%d", min);
+        num_written = snprintf(buffer, buffer_size, "%u", min);
         if (min != max) {
-            snprintf(buffer + num_written, buffer_size - num_written, "|%d", max);
+            snprintf(buffer + num_written, buffer_size - num_written, "|%u", max);
         }
         str_parms_add_str(result, AUDIO_PARAMETER_STREAM_SAMPLING_RATE, buffer);
     }  // AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES
@@ -1002,9 +1031,9 @@
         // Similarly for output channels count
         min = pcm_params_get_min(alsa_hw_params, PCM_PARAM_CHANNELS);
         max = pcm_params_get_max(alsa_hw_params, PCM_PARAM_CHANNELS);
-        num_written = snprintf(buffer, buffer_size, "%d", min);
+        num_written = snprintf(buffer, buffer_size, "%u", min);
         if (min != max) {
-            snprintf(buffer + num_written, buffer_size - num_written, "|%d", max);
+            snprintf(buffer + num_written, buffer_size - num_written, "|%u", max);
         }
         str_parms_add_str(result, AUDIO_PARAMETER_STREAM_CHANNELS, buffer);
     }  // AUDIO_PARAMETER_STREAM_SUP_CHANNELS
@@ -1014,9 +1043,9 @@
         //TODO(pmclean): this is wrong.
         min = pcm_params_get_min(alsa_hw_params, PCM_PARAM_SAMPLE_BITS);
         max = pcm_params_get_max(alsa_hw_params, PCM_PARAM_SAMPLE_BITS);
-        num_written = snprintf(buffer, buffer_size, "%d", min);
+        num_written = snprintf(buffer, buffer_size, "%u", min);
         if (min != max) {
-            snprintf(buffer + num_written, buffer_size - num_written, "|%d", max);
+            snprintf(buffer + num_written, buffer_size - num_written, "|%u", max);
         }
         str_parms_add_str(result, AUDIO_PARAMETER_STREAM_SUP_FORMATS, buffer);
     }  // AUDIO_PARAMETER_STREAM_SUP_FORMATS
@@ -1071,12 +1100,14 @@
 //TODO(pmclean) mutex stuff here (see out_write)
 static ssize_t in_read(struct audio_stream_in *stream, void* buffer, size_t bytes)
 {
-    int num_read_buff_bytes = 0;
+    size_t num_read_buff_bytes = 0;
     void * read_buff = buffer;
     void * out_buff = buffer;
 
     struct stream_in * in = (struct stream_in *) stream;
 
+    ALOGV("usb: in_read(%d)", bytes);
+
     pthread_mutex_lock(&in->dev->lock);
     pthread_mutex_lock(&in->lock);
 
@@ -1094,7 +1125,7 @@
     int num_req_channels = 2; /* always, for now */
 
     if (num_device_channels != num_req_channels) {
-        num_read_buff_bytes *= num_device_channels/num_req_channels;
+        num_read_buff_bytes = (num_device_channels * num_read_buff_bytes) / num_req_channels;
     }
 
     if (cached_output_hardware_config.format == PCM_FORMAT_S24_3LE) {
@@ -1130,10 +1161,17 @@
         if (num_device_channels != num_req_channels) {
             out_buff = buffer;
             /* Num Channels conversion */
-            num_read_buff_bytes =
-                contract_channels_16(read_buff, num_device_channels,
-                                     out_buff, num_req_channels,
-                                     num_read_buff_bytes / sizeof(short));
+            if (num_device_channels < num_req_channels) {
+                num_read_buff_bytes =
+                    contract_channels_16(read_buff, num_device_channels,
+                                         out_buff, num_req_channels,
+                                         num_read_buff_bytes / sizeof(short));
+            } else {
+                num_read_buff_bytes =
+                    expand_channels_16(read_buff, num_device_channels,
+                                       out_buff, num_req_channels,
+                                       num_read_buff_bytes / sizeof(short));
+            }
         }
     }
 
@@ -1155,7 +1193,7 @@
                                   struct audio_config *config,
                                   struct audio_stream_in **stream_in)
 {
-    ALOGV("usb: in adev_open_input_stream() rate:%d, chanMask:0x%X, fmt:%d",
+    ALOGV("usb: in adev_open_input_stream() rate:%" PRIu32 ", chanMask:0x%" PRIX32 ", fmt:%" PRIu8,
           config->sample_rate, config->channel_mask, config->format);
 
     struct stream_in *in = (struct stream_in *)calloc(1, sizeof(struct stream_in));