Merge "hwcomposer: Allow display configuration selection"
diff --git a/include/hardware/audio.h b/include/hardware/audio.h
index 6558dda..7ff5b78 100644
--- a/include/hardware/audio.h
+++ b/include/hardware/audio.h
@@ -428,7 +428,10 @@
 
 /**
  * return the frame size (number of bytes per sample).
+ *
+ * Deprecated: use audio_stream_out_frame_size() or audio_stream_in_frame_size() instead.
  */
+__attribute__((__deprecated__))
 static inline size_t audio_stream_frame_size(const struct audio_stream *s)
 {
     size_t chan_samp_sz;
@@ -442,6 +445,37 @@
     return sizeof(int8_t);
 }
 
+/**
+ * return the frame size (number of bytes per sample) of an output stream.
+ */
+static inline size_t audio_stream_out_frame_size(const struct audio_stream_out *s)
+{
+    size_t chan_samp_sz;
+    audio_format_t format = s->common.get_format(&s->common);
+
+    if (audio_is_linear_pcm(format)) {
+        chan_samp_sz = audio_bytes_per_sample(format);
+        return audio_channel_count_from_out_mask(s->common.get_channels(&s->common)) * chan_samp_sz;
+    }
+
+    return sizeof(int8_t);
+}
+
+/**
+ * return the frame size (number of bytes per sample) of an input stream.
+ */
+static inline size_t audio_stream_in_frame_size(const struct audio_stream_in *s)
+{
+    size_t chan_samp_sz;
+    audio_format_t format = s->common.get_format(&s->common);
+
+    if (audio_is_linear_pcm(format)) {
+        chan_samp_sz = audio_bytes_per_sample(format);
+        return audio_channel_count_from_in_mask(s->common.get_channels(&s->common)) * chan_samp_sz;
+    }
+
+    return sizeof(int8_t);
+}
 
 /**********************************************************************/
 
diff --git a/include/hardware/bluetooth.h b/include/hardware/bluetooth.h
index a074f4f..4d38ff7 100644
--- a/include/hardware/bluetooth.h
+++ b/include/hardware/bluetooth.h
@@ -45,6 +45,7 @@
 #define BT_PROFILE_SOCKETS_ID "socket"
 #define BT_PROFILE_HIDHOST_ID "hidhost"
 #define BT_PROFILE_PAN_ID "pan"
+#define BT_PROFILE_MAP_CLIENT_ID "map_client"
 
 #define BT_PROFILE_GATT_ID "gatt"
 #define BT_PROFILE_AV_RC_ID "avrcp"
diff --git a/include/hardware/bt_mce.h b/include/hardware/bt_mce.h
new file mode 100644
index 0000000..5d159b3
--- /dev/null
+++ b/include/hardware/bt_mce.h
@@ -0,0 +1,54 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_INCLUDE_BT_MCE_H
+#define ANDROID_INCLUDE_BT_MCE_H
+
+__BEGIN_DECLS
+
+/** MAS instance description */
+typedef struct
+{
+    int  id;
+    int  scn;
+    int  msg_types;
+    char *p_name;
+} btmce_mas_instance_t;
+
+/** callback for get_remote_mas_instances */
+typedef void (*btmce_remote_mas_instances_callback)(bt_status_t status, bt_bdaddr_t *bd_addr,
+                                                    int num_instances, btmce_mas_instance_t *instances);
+
+typedef struct {
+    /** set to sizeof(btmce_callbacks_t) */
+    size_t      size;
+    btmce_remote_mas_instances_callback  remote_mas_instances_cb;
+} btmce_callbacks_t;
+
+typedef struct {
+    /** set to size of this struct */
+    size_t size;
+
+    /** register BT MCE callbacks */
+    bt_status_t (*init)(btmce_callbacks_t *callbacks);
+
+    /** search for MAS instances on remote device */
+    bt_status_t (*get_remote_mas_instances)(bt_bdaddr_t *bd_addr);
+} btmce_interface_t;
+
+__END_DECLS
+
+#endif /* ANDROID_INCLUDE_BT_MCE_H */
diff --git a/include/hardware/camera3.h b/include/hardware/camera3.h
index 07d19a6..b024090 100644
--- a/include/hardware/camera3.h
+++ b/include/hardware/camera3.h
@@ -1123,11 +1123,13 @@
  *        a request at some future point.
  *
  *   For ZSL use case, the pixel format for bidirectional stream will be
- *   HAL_PIXEL_FORMAT_RAW_OPAQUE if it is listed in
- *   android.scaler.availableInputOutputFormatsMap.  A configuration stream list
- *   that has BIDIRECTIONAL stream used as input, will usually also have a
- *   distinct OUTPUT stream to get the reprocessing data. For example, for the
- *   ZSL use case, the stream list might be configured with the following:
+ *   HAL_PIXEL_FORMAT_RAW_OPAQUE or HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED if it
+ *   is listed in android.scaler.availableInputOutputFormatsMap. When
+ *   HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED is used, the gralloc
+ *   usage flags for the consumer endpoint will be set to GRALLOC_USAGE_HW_CAMERA_ZSL.
+ *   A configuration stream list that has BIDIRECTIONAL stream used as input, will
+ *   usually also have a distinct OUTPUT stream to get the reprocessing data. For example,
+ *   for the ZSL use case, the stream list might be configured with the following:
  *
  *     - A HAL_PIXEL_FORMAT_RAW_OPAQUE bidirectional stream is used
  *       as input.
@@ -1950,7 +1952,8 @@
      * less than the buffer count in the capture request, at least one more call
      * to process_capture_result with the same frame_number must be made, to
      * return the remaining output buffers to the framework. This may only be
-     * zero if the structure includes valid result metadata.
+     * zero if the structure includes valid result metadata or an input buffer
+     * is returned in this result.
      */
     uint32_t num_output_buffers;
 
diff --git a/include/hardware/gps.h b/include/hardware/gps.h
index 7244738..3cb006b 100644
--- a/include/hardware/gps.h
+++ b/include/hardware/gps.h
@@ -22,6 +22,7 @@
 #include <sys/types.h>
 #include <pthread.h>
 #include <sys/socket.h>
+#include <stdbool.h>
 
 #include <hardware/hardware.h>
 
@@ -39,6 +40,9 @@
 /** Maximum number of SVs for gps_sv_status_callback(). */
 #define GPS_MAX_SVS 32
 
+/** Maximum number of Measurements in gps_measurement_callback(). */
+#define GPS_MAX_MEASUREMENT   32
+
 /** Requested operational mode for GPS operation. */
 typedef uint32_t GpsPositionMode;
 // IMPORTANT: Note that the following values must match
@@ -213,6 +217,102 @@
 #define AGPS_RIL_NETWORK_TTYPE_WIMAX        6
 
 /**
+ * Flags to indicate what fields in GpsClock are valid.
+ */
+typedef uint16_t GpsClockFlags;
+/** A valid 'leap second' is stored in the data structure. */
+#define GPS_CLOCK_HAS_LEAP_SECOND               (1<<0)
+/** A valid 'time uncertainty' is stored in the data structure. */
+#define GPS_CLOCK_HAS_TIME_UNCERTAINTY          (1<<1)
+/** A valid 'bias' is stored in the data structure. */
+#define GPS_CLOCK_HAS_BIAS                      (1<<2)
+/** A valid 'bias uncertainty' is stored in the data structure. */
+#define GPS_CLOCK_HAS_BIAS_UNCERTAINTY          (1<<3)
+/** A valid 'drift' is stored in the data structure. */
+#define GPS_CLOCK_HAS_DRIFT                     (1<<4)
+/** A valid 'drift uncertainty' is stored in the data structure. */
+#define GPS_CLOCK_HAS_DRIFT_UNCERTAINTY         (1<<5)
+
+/**
+ * Flags to indicate what fields in GpsMeasurement are valid.
+ */
+typedef uint32_t GpsMeasurementFlags;
+/** A valid 'snr' is stored in the data structure. */
+#define GPS_MEASUREMENT_HAS_SNR                               (1<<0)
+/** A valid 'elevation' is stored in the data structure. */
+#define GPS_MEASUREMENT_HAS_ELEVATION                         (1<<1)
+/** A valid 'elevation uncertainty' is stored in the data structure. */
+#define GPS_MEASUREMENT_HAS_ELEVATION_UNCERTAINTY             (1<<2)
+/** A valid 'azimuth' is stored in the data structure. */
+#define GPS_MEASUREMENT_HAS_AZIMUTH                           (1<<3)
+/** A valid 'azimuth uncertainty' is stored in the data structure. */
+#define GPS_MEASUREMENT_HAS_AZIMUTH_UNCERTAINTY               (1<<4)
+/** A valid 'pseudorange' is stored in the data structure. */
+#define GPS_MEASUREMENT_HAS_PSEUDORANGE                       (1<<5)
+/** A valid 'pseudorange uncertainty' is stored in the data structure. */
+#define GPS_MEASUREMENT_HAS_PSEUDORANGE_UNCERTAINTY           (1<<6)
+/** A valid 'code phase' is stored in the data structure. */
+#define GPS_MEASUREMENT_HAS_CODE_PHASE                        (1<<7)
+/** A valid 'code phase uncertainty' is stored in the data structure. */
+#define GPS_MEASUREMENT_HAS_CODE_PHASE_UNCERTAINTY            (1<<8)
+/** A valid 'carrier frequency' is stored in the data structure. */
+#define GPS_MEASUREMENT_HAS_CARRIER_FREQUENCY                 (1<<9)
+/** A valid 'carrier cycles' is stored in the data structure. */
+#define GPS_MEASUREMENT_HAS_CARRIER_CYCLES                    (1<<10)
+/** A valid 'carrier phase' is stored in the data structure. */
+#define GPS_MEASUREMENT_HAS_CARRIER_PHASE                     (1<<11)
+/** A valid 'carrier phase uncertainty' is stored in the data structure. */
+#define GPS_MEASUREMENT_HAS_CARRIER_PHASE_UNCERTAINTY         (1<<12)
+/** A valid 'bit number' is stored in the data structure. */
+#define GPS_MEASUREMENT_HAS_BIT_NUMBER                        (1<<13)
+/** A valid 'time from last bit' is stored in the data structure. */
+#define GPS_MEASUREMENT_HAS_TIME_FROM_LAST_BIT                (1<<14)
+/** A valid 'doppler shift' is stored in the data structure. */
+#define GPS_MEASUREMENT_HAS_DOPPLER_SHIFT                     (1<<15)
+/** A valid 'doppler shift uncertainty' is stored in the data structure. */
+#define GPS_MEASUREMENT_HAS_DOPPLER_SHIFT_UNCERTAINTY         (1<<16)
+/** A valid 'used in fix' flag is stored in the data structure. */
+#define GPS_MEASUREMENT_HAS_USED_IN_FIX                       (1<<17)
+
+/**
+ * Flags that indicate the available values for the GPS Measurement's loss of lock.
+ */
+typedef uint8_t GpsLossOfLock;
+/** The indicator is not available or it is unknown. */
+#define GPS_LOSS_OF_LOCK_UNKNOWN                            0
+/** The measurement does not present any indication of loss of lock. */
+#define GPS_LOSS_OF_LOCK_OK                                 1
+/** Loss of lock between previous and current observation: cycle slip possible. */
+#define GPS_LOSS_OF_LOCK_CYCLE_SLIP                         2
+
+/**
+ * Flags that indicate the available values for the GPS Measurement's multipath indicator.
+ */
+typedef uint8_t GpsMultipathIndicator;
+/** The indicator is not available or unknown. */
+#define GPS_MULTIPATH_INDICATOR_UNKNOWN                 0
+/** The measurement has been indicated to use multipath. */
+#define GPS_MULTIPATH_INDICATOR_DETECTED                1
+/** The measurement has been indicated Not to use multipath. */
+#define GPS_MULTIPATH_INDICATOR_NOT_USED                2
+
+/**
+ * Flags to indicate the available GPS Natigation message types.
+ */
+typedef uint8_t GpsNavigationMessageType;
+/** The message type is unknown. */
+#define GPS_NAVIGATION_MESSAGE_TYPE_UNKNOWN         0
+/** L1 C/A message contained in the structure.  */
+#define GPS_NAVIGATION_MESSAGE_TYPE_L1CA            1
+/** L2-CNAV message contained in the structure. */
+#define GPS_NAVIGATION_MESSAGE_TYPE_L2CNAV          2
+/** L5-CNAV message contained in the structure. */
+#define GPS_NAVIGATION_MESSAGE_TYPE_L5CNAV          3
+/** CNAV-2 message contained in the structure. */
+#define GPS_NAVIGATION_MESSAGE_TYPE_CNAV2           4
+
+
+/**
  * Name for the GPS XTRA interface.
  */
 #define GPS_XTRA_INTERFACE      "gps-xtra"
@@ -247,6 +347,16 @@
  */
 #define GPS_GEOFENCING_INTERFACE   "gps_geofencing"
 
+/**
+ * Name of the GPS Measurements interface.
+ */
+#define GPS_MEASUREMENT_INTERFACE   "gps_measurement"
+
+/**
+ * Name of the GPS navigation message interface.
+ */
+ #define GPS_NAVIGATION_MESSAGE_INTERFACE     "gps_navigation_message"
+
 
 /** Represents a location. */
 typedef struct {
@@ -320,6 +430,7 @@
     uint32_t    used_in_fix_mask;
 } GpsSvStatus;
 
+
 /* 2G and 3G */
 /* In 3G lac is discarded */
 typedef struct {
@@ -353,8 +464,9 @@
  */
 typedef void (* gps_status_callback)(GpsStatus* status);
 
-/** Callback with SV status information.
- *  Can only be called from a thread created by create_thread_cb.
+/**
+ * Callback with SV status information.
+ * Can only be called from a thread created by create_thread_cb.
  */
 typedef void (* gps_sv_status_callback)(GpsSvStatus* sv_info);
 
@@ -406,7 +518,7 @@
     size_t          size;
     /**
      * Opens the interface and provides the callback routines
-     * to the implemenation of this interface.
+     * to the implementation of this interface.
      */
     int   (*init)( GpsCallbacks* callbacks );
 
@@ -467,7 +579,7 @@
     size_t          size;
     /**
      * Opens the XTRA interface and provides the callback routines
-     * to the implemenation of this interface.
+     * to the implementation of this interface.
      */
     int  (*init)( GpsXtraCallbacks* callbacks );
     /** Injects XTRA data into the GPS. */
@@ -547,7 +659,7 @@
 
     /**
      * Opens the AGPS interface and provides the callback routines
-     * to the implemenation of this interface.
+     * to the implementation of this interface.
      */
     void  (*init)( AGpsCallbacks* callbacks );
     /**
@@ -631,7 +743,7 @@
     u_char data[20];
 } Sha1CertificateFingerprint;
 
-/** AGPS Inteface to handle SUPL certificate operations */
+/** AGPS Interface to handle SUPL certificate operations */
 typedef struct {
     /** set to sizeof(SuplCertificateInterface) */
     size_t size;
@@ -803,7 +915,7 @@
     size_t          size;
     /**
      * Opens the AGPS interface and provides the callback routines
-     * to the implemenation of this interface.
+     * to the implementation of this interface.
      */
     void  (*init)( AGpsRilCallbacks* callbacks );
 
@@ -942,7 +1054,7 @@
         int32_t transition, GpsUtcTime timestamp);
 
 /**
- * The callback associated with the availablity of the GPS system for geofencing
+ * The callback associated with the availability of the GPS system for geofencing
  * monitoring. If the GPS system determines that it cannot monitor geofences
  * because of lack of reliability or unavailability of the GPS signals, it will
  * call this callback with GPS_GEOFENCE_UNAVAILABLE parameter.
@@ -1020,7 +1132,7 @@
 
    /**
     * Opens the geofence interface and provides the callback routines
-    * to the implemenation of this interface.
+    * to the implementation of this interface.
     */
    void  (*init)( GpsGeofenceCallbacks* callbacks );
 
@@ -1050,14 +1162,12 @@
     *       sampling the GPS for power-saving reasons; thus the rate of
     *       sampling may be faster or slower than this.
     *    unknown_timer_ms - The time limit after which the UNCERTAIN transition
-    *       should be triggered. This paramter is defined in milliseconds.
+    *       should be triggered. This parameter is defined in milliseconds.
     *       See above for a detailed explanation.
     */
-   void (*add_geofence_area) (int32_t geofence_id, double latitude,
-                                double longitude, double radius_meters,
-                                int last_transition, int monitor_transitions,
-                                int notification_responsiveness_ms,
-                                int unknown_timer_ms);
+   void (*add_geofence_area) (int32_t geofence_id, double latitude, double longitude,
+       double radius_meters, int last_transition, int monitor_transitions,
+       int notification_responsiveness_ms, int unknown_timer_ms);
 
    /**
     * Pause monitoring a particular geofence.
@@ -1086,6 +1196,471 @@
     */
    void (*remove_geofence_area) (int32_t geofence_id);
 } GpsGeofencingInterface;
+
+
+/**
+ * Represents an estimate of the GPS clock time.
+ */
+typedef struct {
+    /** set to sizeof(GpsClock) */
+    size_t size;
+
+    /** A set of flags indicating the validity of the fields in this data structure. */
+    GpsClockFlags flags;
+
+    /**
+     * Leap second data.
+     * If the data is available 'flags' must contain GPS_CLOCK_HAS_LEAP_SECOND.
+     */
+    int16_t leap_second;
+
+    /**
+     * The receiver's GPS time since 0000Z, January 6, 1980 in nanoseconds.
+     * It is referenced using the uncorrected receiver's clock ('bias_ns' included).
+     * The current precision allows a range that spans approximately to the end of the year 2272.
+     *
+     * Sub-nanosecond accuracy can be provided for each individual measurement using the field
+     * GpsMeasurement::time_offset_ns.
+     *
+     * The value contains the 'time uncertainty' in it.
+     * This is a Mandatory field.
+     */
+    int64_t time_ns;
+
+    /**
+     * 1-Sigma uncertainty associated with the clock's time in nanoseconds.
+     * The uncertainty is represented as an absolute (single sided) value.
+     *
+     * If the data is available 'flags' must contain GPS_CLOCK_HAS_TIME_UNCERTAINTY.
+     */
+    double time_uncertainty_ns;
+
+    /**
+     * The clock's bias in nanoseconds.
+     * The sign of the value is defined by the following equation:
+     *    true time = time - bias.
+     *
+     * The value contains the 'bias uncertainty' in it.
+     * If the data is available 'flags' must contain GPS_CLOCK_HAS_BIAS.
+     */
+    double bias_ns;
+
+    /**
+     * 1-Sigma uncertainty associated with the clock's bias in nanoseconds.
+     * The uncertainty is represented as an absolute (single sided) value.
+     *
+     * If the data is available 'flags' must contain GPS_CLOCK_HAS_BIAS_UNCERTAINTY.
+     */
+    double bias_uncertainty_ns;
+
+    /**
+     * The clock's drift in nanoseconds (per second).
+     * A positive value means that the frequency is higher than the nominal frequency.
+     *
+     * The value contains the 'drift uncertainty' in it.
+     * If the data is available 'flags' must contain GPS_CLOCK_HAS_DRIFT.
+     */
+    double drift_nsps;
+
+    /**
+     * 1-Sigma uncertainty associated with the clock's drift in nanoseconds (per second).
+     * The uncertainty is represented as an absolute (single sided) value.
+     *
+     * If the data is available 'flags' must contain GPS_CLOCK_HAS_DRIFT_UNCERTAINTY.
+     */
+    double drift_uncertainty_nsps;
+} GpsClock;
+
+/**
+ * Represents a GPS Measurement, it contains raw and computed information.
+ */
+typedef struct {
+    /** set to sizeof(GpsMeasurement) */
+    size_t size;
+
+    /** A set of flags indicating the validity of the fields in this data structure. */
+    GpsMeasurementFlags flags;
+
+    /**
+     * Pseudo-random number in the range of [1, 32]
+     * This is a Mandatory value.
+     */
+    int8_t prn;
+
+    /**
+     * Local hardware time offset at which the measurement was taken in nanoseconds.
+     * The reference receiver's time is specified by GpsData::clock.
+     * The sign of time_offset_ns is given by the following equation:
+     *      measurement time = GpsClock::time_ns + time_offset_ns
+     *
+     * It provides an individual time-stamp for the measurement, and allows sub-nanosecond accuracy.
+     * This is a Mandatory value.
+     */
+    int64_t time_offset_ns;
+
+    /**
+     * Received GPS Time-of-Week in nanoseconds.
+     * The value is relative to the beginning of the current GPS week.
+     *
+     * This is a Mandatory value.
+     */
+    int64_t received_gps_tow_ns;
+
+    /**
+     * Carrier-to-noise density in dB-Hz, in the range [0, 63].
+     * It contains the measured C/N0 value for the signal at the antenna input.
+     *
+     * This is a Mandatory value.
+     */
+    double c_n0_dbhz;
+
+    /**
+     * Pseudorange rate at the timestamp in m/s.
+     * The value also includes the effects of the receiver clock frequency and satellite clock
+     * frequency errors.
+     *
+     * The value includes the 'pseudorange rate uncertainty' in it.
+     * A positive value indicates that the pseudorange is getting larger.
+     *
+     * This is a Mandatory value.
+     */
+    double pseudorange_rate_mpersec;
+
+    /**
+     * 1-Sigma uncertainty of the pseudurange rate in m/s.
+     * The uncertainty is represented as an absolute (single sided) value.
+     *
+     * This is a Mandatory value.
+     */
+    double pseudorange_rate_uncertainty_mpersec;
+
+    /**
+     * Accumulated delta range since the last channel reset in meters.
+     *
+     * This is a Mandatory value.
+     */
+    double accumulated_delta_range_m;
+
+    /**
+     * 1-Sigma uncertainty of the accumulated delta range in meters.
+     *
+     * This is a Mandatory value.
+     */
+    double accumulated_delta_range_uncertainty_m;
+
+    /**
+     * Best derived Pseudorange by the chip-set, in meters.
+     * The value contains the 'pseudorange uncertainty' in it.
+     *
+     * If the data is available, 'flags' must contain GPS_MEASUREMENT_HAS_PSEUDORANGE.
+     */
+    double pseudorange_m;
+
+    /**
+     * 1-Sigma uncertainty of the pseudorange in meters.
+     * The value contains the 'pseudorange' and 'clock' uncertainty in it.
+     * The uncertainty is represented as an absolute (single sided) value.
+     *
+     * If the data is available, 'flags' must contain GPS_MEASUREMENT_HAS_PSEUDORANGE_UNCERTAINTY.
+     */
+    double pseudorange_uncertainty_m;
+
+    /**
+     * A fraction of the current C/A code cycle, in the range [0.0, 1023.0]
+     * This value contains the time (in Chip units) since the last C/A code cycle (GPS Msec epoch).
+     *
+     * The reference frequency is given by the field 'carrier_frequency_hz'.
+     * The value contains the 'code-phase uncertainty' in it.
+     *
+     * If the data is available, 'flags' must contain GPS_MEASUREMENT_HAS_CODE_PHASE.
+     */
+    double code_phase_chips;
+
+    /**
+     * 1-Sigma uncertainty of the code-phase, in a fraction of chips.
+     * The uncertainty is represented as an absolute (single sided) value.
+     *
+     * If the data is available, 'flags' must contain GPS_MEASUREMENT_HAS_CODE_PHASE_UNCERTAINTY.
+     */
+    double code_phase_uncertainty_chips;
+
+    /**
+     * Carrier frequency at which codes and messages are modulated, it can be L1 or L2.
+     * If the field is not set, the carrier frequency is assumed to be L1.
+     *
+     * If the data is available, 'flags' must contain GPS_MEASUREMENT_HAS_CARRIER_FREQUENCY.
+     */
+    float carrier_frequency_hz;
+
+    /**
+     * The number of full carrier cycles between the satellite and the receiver.
+     * The reference frequency is given by the field 'carrier_frequency_hz'.
+     *
+     * If the data is available, 'flags' must contain GPS_MEASUREMENT_HAS_CARRIER_CYCLES.
+     */
+    int64_t carrier_cycles;
+
+    /**
+     * The RF phase detected by the receiver, in the range [0.0, 1.0].
+     * This is usually the fractional part of the complete carrier phase measurement.
+     *
+     * The reference frequency is given by the field 'carrier_frequency_hz'.
+     * The value contains the 'carrier-phase uncertainty' in it.
+     *
+     * If the data is available, 'flags' must contain GPS_MEASUREMENT_HAS_CARRIER_PHASE.
+     */
+    double carrier_phase;
+
+    /**
+     * 1-Sigma uncertainty of the carrier-phase.
+     * If the data is available, 'flags' must contain GPS_MEASUREMENT_HAS_CARRIER_PHASE_UNCERTAINTY.
+     */
+    double carrier_phase_uncertainty;
+
+    /**
+     * An enumeration that indicates the 'loss of lock' state of the event.
+     */
+    GpsLossOfLock loss_of_lock;
+
+    /**
+     * The number of GPS bits transmitted since Sat-Sun midnight (GPS week).
+     * If the data is available, 'flags' must contain GPS_MEASUREMENT_HAS_BIT_NUMBER.
+     */
+    int16_t bit_number;
+
+    /**
+     * The elapsed time since the last received bit in nanoseconds, in the range [0, 20,000,000]
+     * If the data is available, 'flags' must contain GPS_MEASUREMENT_HAS_TIME_FROM_LAST_BIT.
+     */
+    int64_t time_from_last_bit_ns;
+
+    /**
+     * Doppler shift in Hz.
+     * A positive value indicates that the SV is moving toward the receiver.
+     *
+     * The reference frequency is given by the field 'carrier_frequency_hz'.
+     * The value contains the 'doppler shift uncertainty' in it.
+     *
+     * If the data is available, 'flags' must contain GPS_MEASUREMENT_HAS_DOPPLER_SHIFT.
+     */
+    double doppler_shift_hz;
+
+    /**
+     * 1-Sigma uncertainty of the doppler shift in Hz.
+     * If the data is available, 'flags' must contain GPS_MEASUREMENT_HAS_DOPPLER_SHIFT_UNCERTAINTY.
+     */
+    double doppler_shift_uncertainty_hz;
+
+    /**
+     * An enumeration that indicates the 'multipath' state of the event.
+     */
+    GpsMultipathIndicator multipath_indicator;
+
+    /**
+     * Signal-to-noise ratio in dB.
+     * If the data is available, 'flags' must contain GPS_MEASUREMENT_HAS_SNR.
+     */
+    double snr_db;
+
+    /**
+     * Elevation in degrees, the valid range is [-90, 90].
+     * The value contains the 'elevation uncertainty' in it.
+     * If the data is available, 'flags' must contain GPS_MEASUREMENT_HAS_ELEVATION.
+     */
+    double elevation_deg;
+
+    /**
+     * 1-Sigma uncertainty of the elevation in degrees, the valid range is [0, 90].
+     * The uncertainty is represented as the absolute (single sided) value.
+     *
+     * If the data is available, 'flags' must contain GPS_MEASUREMENT_HAS_ELEVATION_UNCERTAINTY.
+     */
+    double elevation_uncertainty_deg;
+
+    /**
+     * Azimuth in degrees, in the range [0, 360).
+     * The value contains the 'azimuth uncertainty' in it.
+     * If the data is available, 'flags' must contain GPS_MEASUREMENT_HAS_AZIMUTH.
+     *  */
+    double azimuth_deg;
+
+    /**
+     * 1-Sigma uncertainty of the azimuth in degrees, the valid range is [0, 180].
+     * The uncertainty is represented as an absolute (single sided) value.
+     *
+     * If the data is available, 'flags' must contain GPS_MEASUREMENT_HAS_AZIMUTH_UNCERTAINTY.
+     */
+    double azimuth_uncertainty_deg;
+
+    /**
+     * Whether the GPS represented by the measurement was used for computing the most recent fix.
+     * If the data is available, 'flags' must contain GPS_MEASUREMENT_HAS_USED_IN_FIX.
+     */
+    bool used_in_fix;
+} GpsMeasurement;
+
+/** Represents a reading of GPS measurements. */
+typedef struct {
+    /** set to sizeof(GpsData) */
+    size_t size;
+
+    /** Number of measurements. */
+    size_t measurement_count;
+
+    /** The array of measurements. */
+    GpsMeasurement measurements[GPS_MAX_MEASUREMENT];
+
+    /** The GPS clock time reading. */
+    GpsClock clock;
+} GpsData;
+
+/**
+ * The callback for to report measurements from the HAL.
+ *
+ * Parameters:
+ *    data - A data structure containing the measurements.
+ */
+typedef void (*gps_measurement_callback) (GpsData* data);
+
+typedef struct {
+    /** set to sizeof(GpsMeasurementCallbacks) */
+    size_t size;
+    gps_measurement_callback measurement_callback;
+} GpsMeasurementCallbacks;
+
+#define GPS_MEASUREMENT_OPERATION_SUCCESS          0
+#define GPS_MEASUREMENT_ERROR_ALREADY_INIT      -100
+#define GPS_MEASUREMENT_ERROR_GENERIC           -101
+
+/**
+ * Extended interface for GPS Measurements support.
+ */
+typedef struct {
+    /** Set to sizeof(GpsMeasurementInterface) */
+    size_t size;
+
+    /**
+     * Initializes the interface and registers the callback routines with the HAL.
+     * After a successful call to 'init' the HAL must begin to provide updates at its own phase.
+     *
+     * Status:
+     *    GPS_MEASUREMENT_OPERATION_SUCCESS
+     *    GPS_MEASUREMENT_ERROR_ALREADY_INIT - if a callback has already been registered without a
+     *              corresponding call to 'close'
+     *    GPS_MEASUREMENT_ERROR_GENERIC - if any other error occurred, it is expected that the HAL
+     *              will not generate any updates upon returning this error code.
+     */
+    int (*init) (GpsMeasurementCallbacks* callbacks);
+
+    /**
+     * Stops updates from the HAL, and unregisters the callback routines.
+     * After a call to stop, the previously registered callbacks must be considered invalid by the
+     * HAL.
+     * If stop is invoked without a previous 'init', this function should perform no work.
+     */
+    void (*close) ();
+
+} GpsMeasurementInterface;
+
+
+/** Represents a GPS navigation message (or a fragment of it). */
+typedef struct {
+    /** set to sizeof(GpsNavigationMessage) */
+    size_t size;
+
+    /**
+     * Pseudo-random number in the range of [1, 32]
+     * This is a Mandatory value.
+     */
+    int8_t prn;
+
+    /**
+     * The type of message contained in the structure.
+     * This is a Mandatory value.
+     */
+    GpsNavigationMessageType type;
+
+    /**
+     * Message identifier.
+     * It provides an index so the complete Navigation Message can be assembled.
+     * i.e. for L1 C/A the message id corresponds to the frame id of the navigation message.
+     */
+    int16_t message_id;
+
+    /**
+     * Sub-message identifier.
+     * If required by the message 'type', this value contains a sub-index within the current
+     * message (or frame) that is being transmitted.
+     * i.e. for L1 C/A the submessage id corresponds to the sub-frame id of the navigation message.
+     */
+    int16_t submessage_id;
+
+    /**
+     * The length of the data (in bytes) contained in the current message.
+     * If this value is different from zero, 'data' must point to an array of the same size.
+     * i.e. for L1 C/A the size of the sub-frame will be 40 bytes (10 words).
+     *
+     * This is a Mandatory value.
+     */
+    size_t data_length;
+
+    /**
+     * The data of the reported GPS message.
+     * The bytes (or words) specified using big endian format (MSB first).
+     */
+    uint8_t* data;
+
+} GpsNavigationMessage;
+
+/**
+ * The callback to report an available fragment of a GPS navigation messages from the HAL.
+ *
+ * Parameters:
+ *      message - The GPS navigation submessage/subframe representation.
+ */
+typedef void (*gps_navigation_message_callback) (GpsNavigationMessage* message);
+
+typedef struct {
+    /** set to sizeof(GpsNavigationMessageCallbacks) */
+    size_t size;
+    gps_navigation_message_callback navigation_message_callback;
+} GpsNavigationMessageCallbacks;
+
+#define GPS_NAVIGATION_MESSAGE_OPERATION_SUCCESS             0
+#define GPS_NAVIGATION_MESSAGE_ERROR_ALREADY_INIT         -100
+#define GPS_NAVIGATION_MESSAGE_ERROR_GENERIC              -101
+
+/**
+ * Extended interface for GPS navigation message reporting support.
+ */
+typedef struct {
+    /** Set to sizeof(GpsNavigationMessageInterface) */
+    size_t size;
+
+    /**
+     * Initializes the interface and registers the callback routines with the HAL.
+     * After a successful call to 'init' the HAL must begin to provide updates as they become
+     * available.
+     *
+     * Status:
+     *      GPS_NAVIGATION_MESSAGE_OPERATION_SUCCESS
+     *      GPS_NAVIGATION_MESSAGE_ERROR_ALREADY_INIT - if a callback has already been registered
+     *              without a corresponding call to 'close'.
+     *      GPS_NAVIGATION_MESSAGE_ERROR_GENERIC - if any other error occurred, it is expected that
+     *              the HAL will not generate any updates upon returning this error code.
+     */
+    int (*init) (GpsNavigationMessageCallbacks* callbacks);
+
+    /**
+     * Stops updates from the HAL, and unregisters the callback routines.
+     * After a call to stop, the previously registered callbacks must be considered invalid by the
+     * HAL.
+     * If stop is invoked without a previous 'init', this function should perform no work.
+     */
+    void (*close) ();
+
+} GpsNavigationMessageInterface;
+
 __END_DECLS
 
 #endif /* ANDROID_INCLUDE_HARDWARE_GPS_H */
diff --git a/include/hardware/hdmi_cec.h b/include/hardware/hdmi_cec.h
index 46294ae..95c0c4e 100644
--- a/include/hardware/hdmi_cec.h
+++ b/include/hardware/hdmi_cec.h
@@ -156,7 +156,6 @@
 enum {
     HDMI_EVENT_CEC_MESSAGE = 1,
     HDMI_EVENT_HOT_PLUG = 2,
-    HDMI_EVENT_TX_STATUS = 3,
 };
 
 /*
@@ -169,21 +168,13 @@
 };
 
 /*
- * TX result type. Used when the event type is HDMI_EVENT_TX_STATUS.
- */
-enum {
-    HDMI_TX_STATUS_SUCCESS = 0,
-    HDMI_TX_STATUS_TIMEDOUT = 1, /* failed on wait */
-    HDMI_TX_STATUS_NOCONN = 2    /* connection problem */
-};
-
-/*
  * error code used for send_message.
  */
 enum {
     HDMI_RESULT_SUCCESS = 0,
     HDMI_RESULT_NACK = 1,        /* not acknowledged */
-    HDMI_RESULT_BUSY = 2         /* bus is busy */
+    HDMI_RESULT_BUSY = 2,        /* bus is busy */
+    HDMI_RESULT_FAIL = 3,
 };
 
 /*
@@ -246,7 +237,7 @@
      * true if the cable is connected; otherwise false.
      */
     int connected;
-    int port;
+    int port_id;
 } hotplug_event_t;
 
 typedef struct tx_status_event {
@@ -263,7 +254,6 @@
     union {
         cec_message_t cec;
         hotplug_event_t hotplug;
-        tx_status_event_t tx_status;
     };
 } hdmi_event_t;
 
@@ -272,7 +262,8 @@
  */
 typedef struct hdmi_port_info {
     hdmi_port_type_t type;
-    int port_num;
+    // Port ID should start from 1 which corresponds to HDMI "port 1".
+    int port_id;
     int cec_supported;
     int arc_supported;
     uint16_t physical_address;
@@ -348,8 +339,7 @@
      * some reason. HAL implementation should take the situation into account
      * so as not to wait forever for the message to get sent out.
      *
-     * It should try retransmission at least once as specified in the standard,
-     * and later should report the transmission result via tx_status_event_t.
+     * It should try retransmission at least once as specified in the standard.
      *
      * Returns error code. See HDMI_RESULT_SUCCESS, HDMI_RESULT_NACK, and
      * HDMI_RESULT_BUSY.
@@ -407,7 +397,7 @@
      * Returns HDMI_CONNECTED if a device is connected, otherwise HDMI_NOT_CONNECTED.
      * The HAL should watch for +5V power signal to determine the status.
      */
-    int (*is_connected)(const struct hdmi_cec_device* dev, int port);
+    int (*is_connected)(const struct hdmi_cec_device* dev, int port_id);
 
     /* Reserved for future use to maximum 16 functions. Must be NULL. */
     void* reserved[16 - 11];
diff --git a/include/hardware/sound_trigger.h b/include/hardware/sound_trigger.h
index fc3ac47..2a8db87 100644
--- a/include/hardware/sound_trigger.h
+++ b/include/hardware/sound_trigger.h
@@ -98,12 +98,9 @@
      */
     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,
+                             const struct sound_trigger_recognition_config *config,
                              recognition_callback_t callback,
-                             void *cookie,
-                             unsigned int data_size,
-                             char *data);
+                             void *cookie);
 
     /* Stop recognition on a given model.
      * The implementation does not have to call the callback when stopped via this method.
diff --git a/modules/audio/audio_hw.c b/modules/audio/audio_hw.c
index 3051519..2f44d95 100644
--- a/modules/audio/audio_hw.c
+++ b/modules/audio/audio_hw.c
@@ -105,7 +105,7 @@
                          size_t bytes)
 {
     /* XXX: fake timing for audio output */
-    usleep(bytes * 1000000 / audio_stream_frame_size(&stream->common) /
+    usleep(bytes * 1000000 / audio_stream_out_frame_size(stream) /
            out_get_sample_rate(&stream->common));
     return bytes;
 }
@@ -193,7 +193,7 @@
                        size_t bytes)
 {
     /* XXX: fake timing for audio input */
-    usleep(bytes * 1000000 / audio_stream_frame_size(&stream->common) /
+    usleep(bytes * 1000000 / audio_stream_in_frame_size(stream) /
            in_get_sample_rate(&stream->common));
     return bytes;
 }
diff --git a/modules/audio_remote_submix/audio_hw.cpp b/modules/audio_remote_submix/audio_hw.cpp
index 51a5a29..c7e4305 100644
--- a/modules/audio_remote_submix/audio_hw.cpp
+++ b/modules/audio_remote_submix/audio_hw.cpp
@@ -307,26 +307,14 @@
         offsetof(struct submix_audio_device, device));
 }
 
-// Get the number of channels referenced by the specified channel_mask.  The channel_mask can
-// reference either input or output channels.
-uint32_t get_channel_count_from_mask(const audio_channel_mask_t channel_mask) {
-    if (audio_is_input_channel(channel_mask)) {
-        return popcount(channel_mask & AUDIO_CHANNEL_IN_ALL);
-    } else if (audio_is_output_channel(channel_mask)) {
-        return popcount(channel_mask & AUDIO_CHANNEL_OUT_ALL);
-    }
-    ALOGE("get_channel_count(): No channels specified in channel mask %x", channel_mask);
-    return 0;
-}
-
 // Compare an audio_config with input channel mask and an audio_config with output channel mask
 // returning false if they do *not* match, true otherwise.
 static bool audio_config_compare(const audio_config * const input_config,
         const audio_config * const output_config)
 {
 #if !ENABLE_CHANNEL_CONVERSION
-    const uint32_t input_channels = get_channel_count_from_mask(input_config->channel_mask);
-    const uint32_t output_channels = get_channel_count_from_mask(output_config->channel_mask);
+    const uint32_t input_channels = audio_channel_count_from_in_mask(input_config->channel_mask);
+    const uint32_t output_channels = audio_channel_count_from_out_mask(output_config->channel_mask);
     if (input_channels != output_channels) {
         ALOGE("audio_config_compare() channel count mismatch input=%d vs. output=%d",
               input_channels, output_channels);
@@ -335,7 +323,7 @@
 #endif // !ENABLE_CHANNEL_CONVERSION
 #if ENABLE_RESAMPLING
     if (input_config->sample_rate != output_config->sample_rate &&
-        get_channel_count_from_mask(input_config->channel_mask) != 1) {
+            audio_channel_count_from_in_mask(input_config->channel_mask) != 1) {
 #else
     if (input_config->sample_rate != output_config->sample_rate) {
 #endif // ENABLE_RESAMPLING
@@ -388,7 +376,11 @@
     // 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 uint32_t channel_count = get_channel_count_from_mask(config->channel_mask);
+        uint32_t channel_count;
+        if (out)
+            channel_count = audio_channel_count_from_out_mask(config->channel_mask);
+        else
+            channel_count = audio_channel_count_from_in_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
@@ -424,8 +416,8 @@
         device_config->buffer_size_frames = sink->maxFrames();
         device_config->buffer_period_size_frames = device_config->buffer_size_frames /
                 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 (in) device_config->pipe_frame_size = audio_stream_in_frame_size(&in->stream);
+        if (out) device_config->pipe_frame_size = audio_stream_out_frame_size(&out->stream);
 #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) /
@@ -535,9 +527,9 @@
 // Calculate the maximum size of the pipe buffer in frames for the specified stream.
 static size_t calculate_stream_pipe_size_in_frames(const struct audio_stream *stream,
                                                    const struct submix_config *config,
-                                                   const size_t pipe_frames)
+                                                   const size_t pipe_frames,
+                                                   const size_t stream_frame_size)
 {
-    const size_t stream_frame_size = audio_stream_frame_size(stream);
     const size_t pipe_frame_size = config->pipe_frame_size;
     const size_t max_frame_size = max(stream_frame_size, pipe_frame_size);
     return (pipe_frames * config->pipe_frame_size) / max_frame_size;
@@ -565,7 +557,7 @@
     // The sample rate of the stream can't be changed once it's set since this would change the
     // output buffer size and hence break playback to the shared pipe.
     if (rate != out->dev->config.output_sample_rate) {
-        ALOGE("out_set_sample_rate(rate=%u) resampling enabled can't change sample rate from "
+        ALOGE("out_set_sample_rate() resampling enabled can't change sample rate from "
               "%u to %u", out->dev->config.output_sample_rate, rate);
         return -ENOSYS;
     }
@@ -584,9 +576,11 @@
     const struct submix_stream_out * const out = audio_stream_get_submix_stream_out(
             const_cast<struct audio_stream *>(stream));
     const struct submix_config * const config = &out->dev->config;
+    const size_t stream_frame_size =
+                            audio_stream_out_frame_size((const struct audio_stream_out *)stream);
     const size_t buffer_size_frames = calculate_stream_pipe_size_in_frames(
-        stream, config, config->buffer_period_size_frames);
-    const size_t buffer_size_bytes = buffer_size_frames * audio_stream_frame_size(stream);
+        stream, config, config->buffer_period_size_frames, stream_frame_size);
+    const size_t buffer_size_bytes = buffer_size_frames * stream_frame_size;
     SUBMIX_ALOGV("out_get_buffer_size() returns %zu bytes, %zu frames",
                  buffer_size_bytes, buffer_size_frames);
     return buffer_size_bytes;
@@ -681,8 +675,10 @@
     const struct submix_stream_out * const out = audio_stream_out_get_submix_stream_out(
             const_cast<struct audio_stream_out *>(stream));
     const struct submix_config * const config = &out->dev->config;
+    const size_t stream_frame_size =
+                            audio_stream_out_frame_size(stream);
     const size_t buffer_size_frames = calculate_stream_pipe_size_in_frames(
-            &stream->common, config, config->buffer_size_frames);
+            &stream->common, config, config->buffer_size_frames, stream_frame_size);
     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",
@@ -704,7 +700,7 @@
 {
     SUBMIX_ALOGV("out_write(bytes=%zd)", bytes);
     ssize_t written_frames = 0;
-    const size_t frame_size = audio_stream_frame_size(&stream->common);
+    const size_t frame_size = audio_stream_out_frame_size(stream);
     struct submix_stream_out * const out = audio_stream_out_get_submix_stream_out(stream);
     struct submix_audio_device * const rsxadev = out->dev;
     const size_t frames = bytes / frame_size;
@@ -839,7 +835,7 @@
     // The sample rate of the stream can't be changed once it's set since this would change the
     // input buffer size and hence break recording from the shared pipe.
     if (rate != in->dev->config.input_sample_rate) {
-        ALOGE("in_set_sample_rate(rate=%u) resampling enabled can't change sample rate from "
+        ALOGE("in_set_sample_rate() resampling enabled can't change sample rate from "
               "%u to %u", in->dev->config.input_sample_rate, rate);
         return -ENOSYS;
     }
@@ -858,8 +854,10 @@
     const struct submix_stream_in * const in = audio_stream_get_submix_stream_in(
             const_cast<struct audio_stream*>(stream));
     const struct submix_config * const config = &in->dev->config;
+    const size_t stream_frame_size =
+                            audio_stream_in_frame_size((const struct audio_stream_in *)stream);
     size_t buffer_size_frames = calculate_stream_pipe_size_in_frames(
-        stream, config, config->buffer_period_size_frames);
+        stream, config, config->buffer_period_size_frames, stream_frame_size);
 #if ENABLE_RESAMPLING
     // Scale the size of the buffer based upon the maximum number of frames that could be returned
     // given the ratio of output to input sample rate.
@@ -867,7 +865,7 @@
                                    (float)config->input_sample_rate) /
                                   (float)config->output_sample_rate);
 #endif // ENABLE_RESAMPLING
-    const size_t buffer_size_bytes = buffer_size_frames * audio_stream_frame_size(stream);
+    const size_t buffer_size_bytes = buffer_size_frames * stream_frame_size;
     SUBMIX_ALOGV("in_get_buffer_size() returns %zu bytes, %zu frames", buffer_size_bytes,
                  buffer_size_frames);
     return buffer_size_bytes;
@@ -951,7 +949,7 @@
     struct submix_stream_in * const in = audio_stream_in_get_submix_stream_in(stream);
     struct submix_audio_device * const rsxadev = in->dev;
     struct audio_config *format;
-    const size_t frame_size = audio_stream_frame_size(&stream->common);
+    const size_t frame_size = audio_stream_in_frame_size(stream);
     const size_t frames_to_read = bytes / frame_size;
 
     SUBMIX_ALOGV("in_read bytes=%zu", bytes);
@@ -991,9 +989,9 @@
         char* buff = (char*)buffer;
 #if ENABLE_CHANNEL_CONVERSION
         // Determine whether channel conversion is required.
-        const uint32_t input_channels = get_channel_count_from_mask(
+        const uint32_t input_channels = audio_channel_count_from_in_mask(
             rsxadev->config.input_channel_mask);
-        const uint32_t output_channels = get_channel_count_from_mask(
+        const uint32_t output_channels = audio_channel_count_from_out_mask(
             rsxadev->config.output_channel_mask);
         if (input_channels != output_channels) {
             SUBMIX_ALOGV("in_read(): %d output channels will be converted to %d "
@@ -1017,7 +1015,7 @@
             // Only support 16-bit PCM mono resampling.
             // NOTE: Resampling is performed after the channel conversion step.
             ALOG_ASSERT(rsxadev->config.common.format == AUDIO_FORMAT_PCM_16_BIT);
-            ALOG_ASSERT(get_channel_count_from_mask(rsxadev->config.input_channel_mask) == 1);
+            ALOG_ASSERT(audio_channel_count_from_in_mask(rsxadev->config.input_channel_mask) == 1);
         }
 #endif // ENABLE_RESAMPLING
 
@@ -1361,7 +1359,7 @@
         const size_t buffer_period_size_frames =
             audio_hw_device_get_submix_audio_device(const_cast<struct audio_hw_device*>(dev))->
                 config.buffer_period_size_frames;
-        const size_t frame_size_in_bytes = get_channel_count_from_mask(config->channel_mask) *
+        const size_t frame_size_in_bytes = audio_channel_count_from_in_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("adev_get_input_buffer_size() returns %zu bytes, %zu frames",
diff --git a/modules/gralloc/Android.mk b/modules/gralloc/Android.mk
index a4ffd20..092e851 100644
--- a/modules/gralloc/Android.mk
+++ b/modules/gralloc/Android.mk
@@ -29,5 +29,8 @@
 
 LOCAL_MODULE := gralloc.default
 LOCAL_CFLAGS:= -DLOG_TAG=\"gralloc\" -Wno-missing-field-initializers
+ifeq ($(TARGET_USE_PAN_DISPLAY),true)
+LOCAL_CFLAGS += -DUSE_PAN_DISPLAY=1
+endif
 
 include $(BUILD_SHARED_LIBRARY)
diff --git a/modules/gralloc/framebuffer.cpp b/modules/gralloc/framebuffer.cpp
index 9d8513a..486e27a 100644
--- a/modules/gralloc/framebuffer.cpp
+++ b/modules/gralloc/framebuffer.cpp
@@ -42,6 +42,13 @@
 
 /*****************************************************************************/
 
+// Set TARGET_USE_PAN_DISPLAY to true at compile time if the
+// board uses FBIOPAN_DISPLAY to setup page flipping, otherwise
+// default ioctl to do page-flipping is FBIOPUT_VSCREENINFO.
+#ifndef USE_PAN_DISPLAY
+#define USE_PAN_DISPLAY 0
+#endif
+
 // numbers of buffers for page flipping
 #define NUM_BUFFERS 2
 
@@ -178,10 +185,15 @@
 
 
     uint32_t flags = PAGE_FLIP;
+#if USE_PAN_DISPLAY
+    if (ioctl(fd, FBIOPAN_DISPLAY, &info) == -1) {
+        ALOGW("FBIOPAN_DISPLAY failed, page flipping not supported");
+#else
     if (ioctl(fd, FBIOPUT_VSCREENINFO, &info) == -1) {
+        ALOGW("FBIOPUT_VSCREENINFO failed, page flipping not supported");
+#endif
         info.yres_virtual = info.yres;
         flags &= ~PAGE_FLIP;
-        ALOGW("FBIOPUT_VSCREENINFO failed, page flipping not supported");
     }
 
     if (info.yres_virtual < info.yres * 2) {
diff --git a/modules/soundtrigger/sound_trigger_hw.c b/modules/soundtrigger/sound_trigger_hw.c
index 8347d02..b78a0d1 100644
--- a/modules/soundtrigger/sound_trigger_hw.c
+++ b/modules/soundtrigger/sound_trigger_hw.c
@@ -81,8 +81,9 @@
         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->phrase_extras[0].num_levels = 1;
+        event->phrase_extras[0].levels[0].level = 100;
+        event->phrase_extras[0].levels[0].user_id = 0;
         event->common.data_offset = sizeof(struct sound_trigger_phrase_recognition_event);
         event->common.data_size = 1;
         data[event->common.data_offset] = 8;
@@ -183,12 +184,9 @@
 
 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,
+                                   const struct sound_trigger_recognition_config *config,
                                    recognition_callback_t callback,
-                                   void *cookie,
-                                   unsigned int data_size,
-                                   char *data)
+                                   void *cookie)
 {
     struct stub_sound_trigger_device *stdev = (struct stub_sound_trigger_device *)dev;
     int status = 0;
@@ -202,13 +200,10 @@
         status = -ENOSYS;
         goto exit;
     }
-    if (data_size != 0 && data == NULL) {
-        status = -EINVAL;
-        goto exit;
-    }
-    if (data_size != 0) {
+    if (config->data_size != 0) {
+        char *data = (char *)config + config->data_offset;
         ALOGI("%s data size %d data %d - %d", __func__,
-              data_size, data[0], data[data_size - 1]);
+              config->data_size, data[0], data[config->data_size - 1]);
     }
 
     stdev->recognition_callback = callback;
diff --git a/modules/usbaudio/audio_hw.c b/modules/usbaudio/audio_hw.c
index 7b65014..b2005c6 100644
--- a/modules/usbaudio/audio_hw.c
+++ b/modules/usbaudio/audio_hw.c
@@ -16,6 +16,7 @@
 
 #define LOG_TAG "usb_audio_hw"
 /*#define LOG_NDEBUG 0*/
+/*#define LOG_PCM_PARAMS 0*/
 
 #include <errno.h>
 #include <inttypes.h>
@@ -36,6 +37,8 @@
 
 #include <tinyalsa/asoundlib.h>
 
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
+
 /* This is the default configuration to hand to The Framework on the initial
  * adev_open_output_stream(). Actual device attributes will be used on the subsequent
  * adev_open_output_stream() after the card and device number have been set in out_set_parameters()
@@ -69,18 +72,22 @@
     .stop_threshold = (IN_PERIOD_SIZE * IN_PERIOD_COUNT),
 };
 
+struct audio_device_profile {
+    int card;
+    int device;
+    int direction; /* PCM_OUT or PCM_IN */
+};
+
 struct audio_device {
     struct audio_hw_device hw_device;
 
     pthread_mutex_t lock; /* see note below on mutex acquisition order */
 
     /* output */
-    int out_card;
-    int out_device;
+    struct audio_device_profile out_profile;
 
     /* input */
-    int in_card;
-    int in_device;
+    struct audio_device_profile in_profile;
 
     bool standby;
 };
@@ -93,6 +100,7 @@
     bool standby;
 
     struct audio_device *dev;           /* hardware information */
+    struct audio_device_profile * profile;
 
     void * conversion_buffer;           /* any conversions are put into here
                                          * they could come from here too if
@@ -102,8 +110,7 @@
 
 /*
  * Output Configuration Cache
- * FIXME(pmclean) This is not reentrant. Should probably be moved into the stream structure
- * but that will involve changes in The Framework.
+ * FIXME(pmclean) This is not reentrant. Should probably be moved into the stream structure.
  */
 static struct pcm_config cached_output_hardware_config;
 static bool output_hardware_config_is_cached = false;
@@ -117,8 +124,15 @@
 
     struct audio_device *dev;
 
+    struct audio_device_profile * profile;
+
     struct audio_config hal_pcm_config;
 
+    /* this is the format the framework thinks it's using. We may need to convert from the actual
+     * (24-bit, 32-bit?) format to this theoretical (framework, probably 16-bit)
+     * format in in_read() */
+    enum pcm_format input_framework_format;
+
 //    struct resampler_itfe *resampler;
 //    struct resampler_buffer_provider buf_provider;
 
@@ -155,7 +169,6 @@
  * We are doing this since we *always* present to The Framework as A PCM16LE device, but need to
  * support PCM24_3LE (24-bit, packed).
  * NOTE:
- *   We're just filling the low-order byte of the PCM24LE samples with 0.
  *   This conversion is safe to do in-place (in_buff == out_buff).
  * TODO Move this to a utilities module.
  */
@@ -181,6 +194,37 @@
 }
 
 /*
+ * Convert a buffer of packed (3-byte) PCM32 samples to PCM16LE samples.
+ *   in_buff points to the buffer of PCM32 samples
+ *   num_in_samples size of input buffer in SAMPLES
+ *   out_buff points to the buffer to receive converted PCM16LE LE samples.
+ * returns
+ *   the number of BYTES of output data.
+ * We are doing this since we *always* present to The Framework as A PCM16LE device, but need to
+ * support PCM_FORMAT_S32_LE (32-bit).
+ * NOTE:
+ *   This conversion is safe to do in-place (in_buff == out_buff).
+ * TODO Move this to a utilities module.
+ */
+static size_t convert_32_to_16(const int32_t * 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
+     */
+
+    short * dst_ptr = out_buff;
+    const int32_t* src_ptr = in_buff;
+    size_t src_smpl_index;
+    for (src_smpl_index = 0; src_smpl_index < num_in_samples; src_smpl_index++) {
+        *dst_ptr++ = *src_ptr++ >> 16;
+    }
+
+    /* return number of *bytes* generated: */
+    return num_in_samples * 2;
+}
+
+/*
  * Convert a buffer of N-channel, interleaved PCM16 samples to M-channel PCM16 channels
  * (where N < M).
  *   in_buff points to the buffer of PCM16 samples
@@ -373,14 +417,14 @@
 /*
  * Maps from bit position in pcm_mask to AUDIO_ format constants.
  */
-static int const format_value_map[] = {
+static audio_format_t const format_value_map[] = {
     AUDIO_FORMAT_PCM_8_BIT,           /* 00 - SNDRV_PCM_FORMAT_S8 */
     AUDIO_FORMAT_PCM_8_BIT,           /* 01 - SNDRV_PCM_FORMAT_U8 */
     AUDIO_FORMAT_PCM_16_BIT,          /* 02 - SNDRV_PCM_FORMAT_S16_LE */
     AUDIO_FORMAT_INVALID,             /* 03 - SNDRV_PCM_FORMAT_S16_BE */
     AUDIO_FORMAT_INVALID,             /* 04 - SNDRV_PCM_FORMAT_U16_LE */
     AUDIO_FORMAT_INVALID,             /* 05 - SNDRV_PCM_FORMAT_U16_BE */
-    AUDIO_FORMAT_PCM_24_BIT_PACKED,   /* 06 - SNDRV_PCM_FORMAT_S24_LE */
+    AUDIO_FORMAT_INVALID,             /* 06 - SNDRV_PCM_FORMAT_S24_LE */
     AUDIO_FORMAT_INVALID,             /* 07 - SNDRV_PCM_FORMAT_S24_BE */
     AUDIO_FORMAT_INVALID,             /* 08 - SNDRV_PCM_FORMAT_U24_LE */
     AUDIO_FORMAT_INVALID,             /* 09 - SNDRV_PCM_FORMAT_U24_BE */
@@ -406,7 +450,7 @@
     AUDIO_FORMAT_INVALID,
     AUDIO_FORMAT_INVALID,
     AUDIO_FORMAT_INVALID,             /* 31 - SNDRV_PCM_FORMAT_SPECIAL */
-    AUDIO_FORMAT_PCM_24_BIT_PACKED,   /* 32 - SNDRV_PCM_FORMAT_S24_3LE */ /* ??? */
+    AUDIO_FORMAT_PCM_24_BIT_PACKED,   /* 32 - SNDRV_PCM_FORMAT_S24_3LE */
     AUDIO_FORMAT_INVALID,             /* 33 - SNDRV_PCM_FORMAT_S24_3BE */
     AUDIO_FORMAT_INVALID,             /* 34 - SNDRV_PCM_FORMAT_U24_3LE */
     AUDIO_FORMAT_INVALID,             /* 35 - SNDRV_PCM_FORMAT_U24_3BE */
@@ -426,6 +470,13 @@
     AUDIO_FORMAT_INVALID              /* 49 - SNDRV_PCM_FORMAT_DSD_U16_LE */
 };
 
+/*
+ * Returns true if mask indicates support for PCM_16.
+ */
+static bool mask_has_pcm_16(struct pcm_mask* mask) {
+    return (mask->bits[0] & 0x0004) != 0;
+}
+
 static int get_format_for_mask(struct pcm_mask* mask)
 {
     int num_slots = sizeof(mask->bits)/ sizeof(mask->bits[0]);
@@ -525,7 +576,7 @@
                 /* just return the first one */
                 return table_index < table_size
                            ? pcm_format_value_map[table_index]
-                           : AUDIO_FORMAT_INVALID;
+                           : (int)AUDIO_FORMAT_INVALID;
             }
             bit_mask <<= 1;
             table_index++;
@@ -535,6 +586,54 @@
     return 0; // is this right?
 }
 
+static bool test_out_sample_rate(struct audio_device_profile* dev_profile, unsigned rate) {
+    struct pcm_config local_config = cached_output_hardware_config;
+    local_config.rate = rate;
+
+    bool works = false; /* let's be pessimistic */
+    struct pcm * pcm =
+        pcm_open(dev_profile->card, dev_profile->device, dev_profile->direction, &local_config);
+
+    if (pcm != NULL) {
+        works = pcm_is_ready(pcm);
+        pcm_close(pcm);
+    }
+
+    return works;
+}
+
+/* sort these highest -> lowest */
+static const unsigned std_sample_rates[] =
+    {48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000};
+
+static char* enum_std_sample_rates(struct audio_device_profile* dev_profile,
+                                   unsigned min, unsigned max)
+{
+    char buffer[128];
+    buffer[0] = '\0';
+    int buffSize = ARRAY_SIZE(buffer);
+
+    char numBuffer[32];
+
+    int numEntries = 0;
+    unsigned index;
+    for(index = 0; index < ARRAY_SIZE(std_sample_rates); index++) {
+        if (std_sample_rates[index] >= min && std_sample_rates[index] <= max &&
+            test_out_sample_rate(dev_profile, std_sample_rates[index])) {
+            if (numEntries++ != 0) {
+                strncat(buffer, "|", buffSize);
+            }
+            snprintf(numBuffer, sizeof(numBuffer), "%u", std_sample_rates[index]);
+            strncat(buffer, numBuffer, buffSize);
+        }
+    }
+
+    return strdup(buffer);
+}
+
+/*
+ * Logging
+ */
 static void log_pcm_mask(const char* mask_name, struct pcm_mask* mask) {
     char buff[512];
     char bit_buff[32];
@@ -624,15 +723,18 @@
 /*
  * Reads and decodes configuration info from the specified ALSA card/device
  */
-static int read_alsa_device_config(int card, int device, int io_type, struct pcm_config * config)
+static int read_alsa_device_config(struct audio_device_profile * dev_profile,
+                                   struct pcm_config * config)
 {
-    ALOGV("usb:audio_hw - read_alsa_device_config(c:%d d:%d t:0x%X)",card, device, io_type);
+    ALOGV("usb:audio_hw - read_alsa_device_config(c:%d d:%d t:0x%X)",
+          dev_profile->card, dev_profile->device, dev_profile->direction);
 
-    if (card < 0 || device < 0) {
+    if (dev_profile->card < 0 || dev_profile->device < 0) {
         return -EINVAL;
     }
 
-    struct pcm_params * alsa_hw_params = pcm_params_get(card, device, io_type);
+    struct pcm_params * alsa_hw_params =
+        pcm_params_get(dev_profile->card, dev_profile->device, dev_profile->direction);
     if (alsa_hw_params == NULL) {
         return -EINVAL;
     }
@@ -640,7 +742,9 @@
     /*
      * This Logging will be useful when testing new USB devices.
      */
-    /* log_pcm_params(alsa_hw_params); */
+#ifdef LOG_PCM_PARAMS
+    log_pcm_params(alsa_hw_params);
+#endif
 
     config->channels = pcm_params_get_min(alsa_hw_params, PCM_PARAM_CHANNELS);
     config->rate = pcm_params_get_min(alsa_hw_params, PCM_PARAM_RATE);
@@ -655,6 +759,9 @@
     config->period_count = pcm_params_get_min(alsa_hw_params, PCM_PARAM_PERIODS);
 
     config->format = get_pcm_format_for_mask(pcm_params_get_mask(alsa_hw_params, PCM_PARAM_FORMAT));
+
+    pcm_params_free(alsa_hw_params);
+
     return 0;
 }
 
@@ -679,7 +786,8 @@
 
 static size_t out_get_buffer_size(const struct audio_stream *stream)
 {
-    return cached_output_hardware_config.period_size * audio_stream_frame_size(stream);
+    return cached_output_hardware_config.period_size *
+                audio_stream_out_frame_size((const struct audio_stream_out *)stream);
 }
 
 static uint32_t out_get_channels(const struct audio_stream *stream)
@@ -730,7 +838,6 @@
     ALOGV("usb:audio_hw::out out_set_parameters() keys:%s", kvpairs);
 
     struct stream_out *out = (struct stream_out *)stream;
-    struct audio_device *adev = out->dev;
     struct str_parms *parms;
     char value[32];
     int param_val;
@@ -738,45 +845,41 @@
     int ret_value = 0;
 
     parms = str_parms_create_str(kvpairs);
-    pthread_mutex_lock(&adev->lock);
+    pthread_mutex_lock(&out->dev->lock);
+    pthread_mutex_lock(&out->lock);
 
     bool recache_device_params = false;
     param_val = str_parms_get_str(parms, "card", value, sizeof(value));
     if (param_val >= 0) {
-        adev->out_card = atoi(value);
+        out->profile->card = atoi(value);
         recache_device_params = true;
     }
 
     param_val = str_parms_get_str(parms, "device", value, sizeof(value));
     if (param_val >= 0) {
-        adev->out_device = atoi(value);
+        out->profile->device = atoi(value);
         recache_device_params = true;
     }
 
-    if (recache_device_params && adev->out_card >= 0 && adev->out_device >= 0) {
-        ret_value = read_alsa_device_config(adev->out_card, adev->out_device, PCM_OUT,
-                                            &cached_output_hardware_config);
+    if (recache_device_params && out->profile->card >= 0 && out->profile->device >= 0) {
+        ret_value = read_alsa_device_config(out->profile, &cached_output_hardware_config);
         output_hardware_config_is_cached = (ret_value == 0);
     }
 
-    pthread_mutex_unlock(&adev->lock);
+    pthread_mutex_unlock(&out->lock);
+    pthread_mutex_unlock(&out->dev->lock);
     str_parms_destroy(parms);
 
     return ret_value;
 }
 
-/*TODO it seems like both out_get_parameters() and in_get_parameters()
-  could be written in terms of a get_device_parameters(io_type) */
-
-static char * out_get_parameters(const struct audio_stream *stream, const char *keys)
+static char * device_get_parameters(struct audio_device_profile * dev_profile, const char *keys)
 {
-    ALOGV("usb:audio_hw::out out_get_parameters() keys:%s", keys);
+    ALOGV("usb:audio_hw::device_get_parameters() keys:%s", keys);
 
-    struct stream_out *out = (struct stream_out *) stream;
-    struct audio_device *adev = out->dev;
-
-    if (adev->out_card < 0 || adev->out_device < 0)
+    if (dev_profile->card < 0 || dev_profile->device < 0) {
         return strdup("");
+    }
 
     unsigned min, max;
 
@@ -788,58 +891,74 @@
     int buffer_size = sizeof(buffer) / sizeof(buffer[0]);
     char* result_str = NULL;
 
-    struct pcm_params * alsa_hw_params = pcm_params_get(adev->out_card, adev->out_device, PCM_OUT);
+    struct pcm_params * alsa_hw_params =
+        pcm_params_get(dev_profile->card, dev_profile->device, dev_profile->direction);
 
     // These keys are from hardware/libhardware/include/audio.h
     // supported sample rates
     if (str_parms_has_key(query, AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES)) {
-        // pcm_hw_params doesn't have a list of supported samples rates, just a min and a max, so
-        // 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, "%u", min);
-        if (min != max) {
-            snprintf(buffer + num_written, buffer_size - num_written, "|%u", max);
-        }
-        str_parms_add_str(result, AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES,
-                          buffer);
+
+        char* rates_list = enum_std_sample_rates(dev_profile, min, max);
+        str_parms_add_str(result, AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES, rates_list);
+        free(rates_list);
     }  // AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES
 
     // supported channel counts
     if (str_parms_has_key(query, AUDIO_PARAMETER_STREAM_SUP_CHANNELS)) {
-        // Similarly for output channels count
-        /* TODO - This is wrong, we need format strings, not numbers (another CL) */
-        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, "%u", min);
-        if (min != max) {
-            snprintf(buffer + num_written, buffer_size - num_written, "|%u", max);
-        }
-        str_parms_add_str(result, AUDIO_PARAMETER_STREAM_SUP_CHANNELS, buffer);
+        // TODO remove this hack when it is superceeded by proper multi-channel support
+        str_parms_add_str(result, AUDIO_PARAMETER_STREAM_SUP_CHANNELS,
+                          dev_profile->direction == PCM_OUT
+                                          ? "AUDIO_CHANNEL_OUT_STEREO"
+                                          : "AUDIO_CHANNEL_IN_STEREO");
     }  // AUDIO_PARAMETER_STREAM_SUP_CHANNELS
 
     // supported sample formats
     if (str_parms_has_key(query, AUDIO_PARAMETER_STREAM_SUP_FORMATS)) {
-        char * format_params =
-            get_format_str_for_mask(pcm_params_get_mask(alsa_hw_params, PCM_PARAM_FORMAT));
-        str_parms_add_str(result, AUDIO_PARAMETER_STREAM_SUP_FORMATS, format_params);
-        free(format_params);
+        // TODO remove this hack when we have support for input in non PCM16 formats
+        if (dev_profile->direction == PCM_IN) {
+            str_parms_add_str(result, AUDIO_PARAMETER_STREAM_SUP_FORMATS, "AUDIO_FORMAT_PCM_16_BIT");
+        } else {
+            struct pcm_mask * format_mask = pcm_params_get_mask(alsa_hw_params, PCM_PARAM_FORMAT);
+            char * format_params = get_format_str_for_mask(format_mask);
+            str_parms_add_str(result, AUDIO_PARAMETER_STREAM_SUP_FORMATS, format_params);
+            free(format_params);
+        }
     }  // AUDIO_PARAMETER_STREAM_SUP_FORMATS
 
+    pcm_params_free(alsa_hw_params);
+
     result_str = str_parms_to_str(result);
 
     // done with these...
     str_parms_destroy(query);
     str_parms_destroy(result);
 
-    ALOGV("usb:audio_hw::out out_get_parameters() = %s", result_str);
+    ALOGV("usb:audio_hw::device_get_parameters = %s", result_str);
 
     return result_str;
 }
 
+static char * out_get_parameters(const struct audio_stream *stream, const char *keys)
+{
+    ALOGV("usb:audio_hw::out out_get_parameters() keys:%s", keys);
+
+    struct stream_out *out = (struct stream_out *) stream;
+    pthread_mutex_lock(&out->dev->lock);
+    pthread_mutex_lock(&out->lock);
+
+    char * params_str =  device_get_parameters(out->profile, keys);
+
+    pthread_mutex_unlock(&out->lock);
+    pthread_mutex_unlock(&out->dev->lock);
+
+    return params_str;
+}
+
 static uint32_t out_get_latency(const struct audio_stream_out *stream)
 {
-    struct stream_out *out = (struct stream_out *) stream;
+    // struct stream_out *out = (struct stream_out *) stream;
 
     /*TODO Do we need a term here for the USB latency (as reported in the USB descriptors)? */
     uint32_t latency = (cached_output_hardware_config.period_size
@@ -856,13 +975,13 @@
 /* must be called with hw device and output stream mutexes locked */
 static int start_output_stream(struct stream_out *out)
 {
-    struct audio_device *adev = out->dev;
     int return_val = 0;
 
     ALOGV("usb:audio_hw::out start_output_stream(card:%d device:%d)",
-          adev->out_card, adev->out_device);
+          out->profile->card, out->profile->device);
 
-    out->pcm = pcm_open(adev->out_card, adev->out_device, PCM_OUT, &cached_output_hardware_config);
+    out->pcm = pcm_open(out->profile->card, out->profile->device, PCM_OUT,
+                        &cached_output_hardware_config);
 
     if (out->pcm == NULL) {
         return -ENOMEM;
@@ -933,7 +1052,7 @@
     pthread_mutex_unlock(&out->lock);
     pthread_mutex_unlock(&out->dev->lock);
     if (ret != 0) {
-        usleep(bytes * 1000000 / audio_stream_frame_size(&stream->common) /
+        usleep(bytes * 1000000 / audio_stream_out_frame_size(stream) /
                out_get_sample_rate(&stream->common));
     }
 
@@ -999,6 +1118,9 @@
 
     out->dev = adev;
 
+    out->profile = &(adev->out_profile);
+    out->profile->direction = PCM_OUT;
+
     if (output_hardware_config_is_cached) {
         config->sample_rate = cached_output_hardware_config.rate;
 
@@ -1109,9 +1231,10 @@
 
 static size_t in_get_buffer_size(const struct audio_stream *stream)
 {
-    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);
+    size_t buffer_size = cached_input_hardware_config.period_size *
+                            audio_stream_in_frame_size((const struct audio_stream_in *)stream);
+    ALOGV("usb: in_get_buffer_size() = %zu", buffer_size);
+    return buffer_size;
 }
 
 static uint32_t in_get_channels(const struct audio_stream *stream)
@@ -1122,7 +1245,12 @@
 
 static audio_format_t in_get_format(const struct audio_stream *stream)
 {
-    return audio_format_from_pcm_format(cached_input_hardware_config.format);
+    const struct stream_in * in_stream = (const struct stream_in *)stream;
+
+    ALOGV("in_get_format() = %d -> %d", in_stream->input_framework_format,
+          audio_format_from_pcm_format(in_stream->input_framework_format));
+    /* return audio_format_from_pcm_format(cached_input_hardware_config.format); */
+    return audio_format_from_pcm_format(in_stream->input_framework_format);
 }
 
 static int in_set_format(struct audio_stream *stream, audio_format_t format)
@@ -1159,7 +1287,6 @@
     ALOGV("usb: audio_hw::in in_set_parameters() keys:%s", kvpairs);
 
     struct stream_in *in = (struct stream_in *)stream;
-    struct audio_device *adev = in->dev;
     struct str_parms *parms;
     char value[32];
     int param_val;
@@ -1167,108 +1294,49 @@
     int ret_value = 0;
 
     parms = str_parms_create_str(kvpairs);
-    pthread_mutex_lock(&adev->lock);
+    pthread_mutex_lock(&in->dev->lock);
+    pthread_mutex_lock(&in->lock);
 
     bool recache_device_params = false;
 
     // Card/Device
     param_val = str_parms_get_str(parms, "card", value, sizeof(value));
     if (param_val >= 0) {
-        adev->in_card = atoi(value);
+        in->profile->card = atoi(value);
         recache_device_params = true;
     }
 
     param_val = str_parms_get_str(parms, "device", value, sizeof(value));
     if (param_val >= 0) {
-        adev->in_device = atoi(value);
+        in->profile->device = atoi(value);
         recache_device_params = true;
     }
 
-    if (recache_device_params && adev->in_card >= 0 && adev->in_device >= 0) {
-        ret_value = read_alsa_device_config(adev->in_card, adev->in_device,
-                                            PCM_IN, &(cached_input_hardware_config));
+    if (recache_device_params && in->profile->card >= 0 && in->profile->device >= 0) {
+        ret_value = read_alsa_device_config(in->profile, &cached_input_hardware_config);
         input_hardware_config_is_cached = (ret_value == 0);
     }
 
-    pthread_mutex_unlock(&adev->lock);
+    pthread_mutex_unlock(&in->lock);
+    pthread_mutex_unlock(&in->dev->lock);
     str_parms_destroy(parms);
 
     return ret_value;
 }
 
-/*TODO it seems like both out_get_parameters() and in_get_parameters()
-   could be written in terms of a get_device_parameters(io_type) */
-
 static char * in_get_parameters(const struct audio_stream *stream, const char *keys) {
     ALOGV("usb:audio_hw::in in_get_parameters() keys:%s", keys);
 
     struct stream_in *in = (struct stream_in *)stream;
-    struct audio_device *adev = in->dev;
+    pthread_mutex_lock(&in->dev->lock);
+    pthread_mutex_lock(&in->lock);
 
-    if (adev->in_card < 0 || adev->in_device < 0)
-        return strdup("");
+    char * params_str  = device_get_parameters(in->profile, keys);
 
-    struct pcm_params * alsa_hw_params = pcm_params_get(adev->in_card, adev->in_device, PCM_IN);
-    if (alsa_hw_params == NULL)
-        return strdup("");
+    pthread_mutex_unlock(&in->lock);
+    pthread_mutex_unlock(&in->dev->lock);
 
-    struct str_parms *query = str_parms_create_str(keys);
-    struct str_parms *result = str_parms_create();
-
-    int num_written = 0;
-    char buffer[256];
-    int buffer_size = sizeof(buffer) / sizeof(buffer[0]);
-    char* result_str = NULL;
-
-    unsigned min, max;
-
-    // These keys are from hardware/libhardware/include/audio.h
-    // supported sample rates
-    if (str_parms_has_key(query, AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES)) {
-        // pcm_hw_params doesn't have a list of supported samples rates, just a min and a max, so
-        // 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, "%u", min);
-        if (min != 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
-
-    // supported channel counts
-    if (str_parms_has_key(query, AUDIO_PARAMETER_STREAM_SUP_CHANNELS)) {
-        // Similarly for output channels count
-        // TODO This is wrong, we need format strings, not numbers (another CL)
-        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, "%u", min);
-        if (min != 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
-
-    // supported sample formats
-    if (str_parms_has_key(query, AUDIO_PARAMETER_STREAM_SUP_FORMATS)) {
-        /*TODO This is wrong.  It needs to return AUDIO_ format constants (as strings)
-          as in audio_policy.conf */
-        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, "%u", min);
-        if (min != 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
-
-    result_str = str_parms_to_str(result);
-
-    // done with these...
-    str_parms_destroy(query);
-    str_parms_destroy(result);
-
-    return result_str;
+    return params_str;
 }
 
 static int in_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
@@ -1288,13 +1356,13 @@
 
 /* must be called with hw device and output stream mutexes locked */
 static int start_input_stream(struct stream_in *in) {
-    struct audio_device *adev = in->dev;
     int return_val = 0;
 
     ALOGV("usb:audio_hw::start_input_stream(card:%d device:%d)",
-          adev->in_card, adev->in_device);
+          in->profile->card, in->profile->device);
 
-    in->pcm = pcm_open(adev->in_card, adev->in_device, PCM_IN, &cached_input_hardware_config);
+    in->pcm = pcm_open(in->profile->card, in->profile->device, PCM_IN,
+                       &cached_input_hardware_config);
     if (in->pcm == NULL) {
         ALOGE("usb:audio_hw pcm_open() in->pcm == NULL");
         return -ENOMEM;
@@ -1338,8 +1406,13 @@
         num_read_buff_bytes = (num_device_channels * num_read_buff_bytes) / num_req_channels;
     }
 
+    /* Assume (for now) that in->input_framework_format == PCM_FORMAT_S16_LE */
     if (cached_input_hardware_config.format == PCM_FORMAT_S24_3LE) {
+        /* 24-bit USB device */
         num_read_buff_bytes = (3 * num_read_buff_bytes) / 2;
+    } else if (cached_input_hardware_config.format == PCM_FORMAT_S32_LE) {
+        /* 32-bit USB device */
+        num_read_buff_bytes = num_read_buff_bytes * 2;
     }
 
     // Setup/Realloc the conversion buffer (if necessary).
@@ -1358,14 +1431,22 @@
          * Do any conversions necessary to send the data in the format specified to/by the HAL
          * (but different from the ALSA format), such as 24bit ->16bit, or 4chan -> 2chan.
          */
-        if (cached_input_hardware_config.format == PCM_FORMAT_S24_3LE) {
+        if (cached_input_hardware_config.format != PCM_FORMAT_S16_LE) {
+            // we need to convert
             if (num_device_channels != num_req_channels) {
                 out_buff = read_buff;
             }
 
-            /* Bit Format Conversion */
-            num_read_buff_bytes =
-                convert_24_3_to_16(read_buff, num_read_buff_bytes / 3, out_buff);
+            if (cached_input_hardware_config.format == PCM_FORMAT_S24_3LE) {
+                num_read_buff_bytes =
+                    convert_24_3_to_16(read_buff, num_read_buff_bytes / 3, out_buff);
+            } else if (cached_input_hardware_config.format == PCM_FORMAT_S32_LE) {
+                num_read_buff_bytes =
+                    convert_32_to_16(read_buff, num_read_buff_bytes / 4, out_buff);
+            }
+            else {
+                goto err;
+            }
         }
 
         if (num_device_channels != num_req_channels) {
@@ -1430,36 +1511,53 @@
     in->stream.read = in_read;
     in->stream.get_input_frames_lost = in_get_input_frames_lost;
 
+    in->input_framework_format = PCM_FORMAT_S16_LE;
+
     in->dev = (struct audio_device *)dev;
 
-    if (config->channel_mask != AUDIO_CHANNEL_IN_STEREO)
-        ret = -EINVAL;
+    in->profile = &(in->dev->in_profile);
+    in->profile->direction = PCM_IN;
 
-    if (input_hardware_config_is_cached) {
-        config->sample_rate = cached_input_hardware_config.rate;
-
-        config->format = audio_format_from_pcm_format(cached_input_hardware_config.format);
-        if (config->format != AUDIO_FORMAT_PCM_16_BIT) {
-            // Always report PCM16 for now. AudioPolicyManagerBase/AudioFlinger dont' understand
-            // formats with more other format, so we won't get chosen (say with a 24bit DAC).
-            /* TODO Remove this when the above restriction is removed. */
-            config->format = AUDIO_FORMAT_PCM_16_BIT;
-        }
-
-        config->channel_mask = audio_channel_in_mask_from_count(
-                cached_input_hardware_config.channels);
-        if (config->channel_mask != AUDIO_CHANNEL_IN_STEREO) {
-            // Always report STEREO for now.  AudioPolicyManagerBase/AudioFlinger dont' understand
-            // formats with more channels, so we won't get chosen (say with a 4-channel DAC).
-            /* TODO Remove this when the above restriction is removed. */
-            config->channel_mask = AUDIO_CHANNEL_IN_STEREO;
-        }
-    } else {
+    if (!input_hardware_config_is_cached) {
+        // just return defaults until we can actually query the device.
         cached_input_hardware_config = default_alsa_in_config;
+    }
 
-        config->format = in_get_format(&in->stream.common);
-        config->channel_mask = in_get_channels(&in->stream.common);
-        config->sample_rate = in_get_sample_rate(&in->stream.common);
+    /* Rate */
+    /* TODO Check that the requested rate is valid for the connected device */
+    if (config->sample_rate == 0) {
+        config->sample_rate = cached_input_hardware_config.rate;
+    } else {
+        cached_input_hardware_config.rate = config->sample_rate;
+    }
+
+    /* Format */
+    /* until the framework supports format conversion, just take what it asks for
+     * i.e. AUDIO_FORMAT_PCM_16_BIT */
+    /* config->format = audio_format_from_pcm_format(cached_input_hardware_config.format); */
+    if (config->format == AUDIO_FORMAT_DEFAULT) {
+        /* just return AUDIO_FORMAT_PCM_16_BIT until the framework supports other input
+         * formats */
+        config->format = AUDIO_FORMAT_PCM_16_BIT;
+    } else if (config->format == AUDIO_FORMAT_PCM_16_BIT) {
+        /* Always accept AUDIO_FORMAT_PCM_16_BIT until the framework supports other input
+         * formats */
+    } else {
+        /* When the framework support other formats, validate here */
+        config->format = AUDIO_FORMAT_PCM_16_BIT;
+        ret = -EINVAL;
+    }
+
+    /* don't change the cached_input_hardware_config, we will open it as what it is and
+     * convert as necessary */
+    if (config->channel_mask == AUDIO_CHANNEL_NONE) {
+        /* just return AUDIO_CHANNEL_IN_STEREO until the framework supports other input
+         * formats */
+        config->channel_mask = AUDIO_CHANNEL_IN_STEREO;
+    } else if (config->channel_mask != AUDIO_CHANNEL_IN_STEREO) {
+        /* allow only stereo capture for now */
+        config->channel_mask = AUDIO_CHANNEL_IN_STEREO;
+        ret = -EINVAL;
     }
 
     in->standby = true;