Merge "HWC 1.5: Add per-layer damage region"
diff --git a/include/hardware/audio.h b/include/hardware/audio.h
index 763ca58..2389c09 100644
--- a/include/hardware/audio.h
+++ b/include/hardware/audio.h
@@ -112,6 +112,10 @@
 /* Bluetooth SCO wideband */
 #define AUDIO_PARAMETER_KEY_BT_SCO_WB "bt_wbs"
 
+/* Get a new HW synchronization source identifier.
+ * Return a valid source (positive integer) or AUDIO_HW_SYNC_INVALID if an error occurs
+ * or no HW sync is available. */
+#define AUDIO_PARAMETER_HW_AV_SYNC "hw_av_sync"
 
 /**
  *  audio stream parameters
@@ -124,6 +128,7 @@
 #define AUDIO_PARAMETER_STREAM_INPUT_SOURCE "input_source"   /* audio_source_t */
 #define AUDIO_PARAMETER_STREAM_SAMPLING_RATE "sampling_rate" /* uint32_t */
 
+#define AUDIO_PARAMETER_DEVICE_CONNECT "connect"            /* audio_devices_t */
 #define AUDIO_PARAMETER_DEVICE_DISCONNECT "disconnect"      /* audio_devices_t */
 
 /* Query supported formats. The response is a '|' separated list of strings from
@@ -136,9 +141,7 @@
  * "sup_sampling_rates=44100|48000" */
 #define AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES "sup_sampling_rates"
 
-/* Get the HW synchronization source used for an output stream.
- * Return a valid source (positive integer) or AUDIO_HW_SYNC_INVALID if an error occurs
- * or no HW sync source is used. */
+/* Set the HW synchronization source for an output stream. */
 #define AUDIO_PARAMETER_STREAM_HW_AV_SYNC "hw_av_sync"
 
 /**
diff --git a/include/hardware/bt_gatt_server.h b/include/hardware/bt_gatt_server.h
index 2b1de27..0d6cc1e 100644
--- a/include/hardware/bt_gatt_server.h
+++ b/include/hardware/bt_gatt_server.h
@@ -117,6 +117,9 @@
  */
 typedef void (*congestion_callback)(int conn_id, bool congested);
 
+/** Callback invoked when the MTU for a given connection changes */
+typedef void (*mtu_changed_callback)(int conn_id, int mtu);
+
 typedef struct {
     register_server_callback        register_server_cb;
     connection_callback             connection_cb;
@@ -133,6 +136,7 @@
     response_confirmation_callback  response_confirmation_cb;
     indication_sent_callback        indication_sent_cb;
     congestion_callback             congestion_cb;
+    mtu_changed_callback            mtu_changed_cb;
 } btgatt_server_callbacks_t;
 
 /** Represents the standard BT-GATT server interface. */
diff --git a/include/hardware/camera3.h b/include/hardware/camera3.h
index b705103..2bb3ba1 100644
--- a/include/hardware/camera3.h
+++ b/include/hardware/camera3.h
@@ -1073,34 +1073,7 @@
  *
  * This includes some typical use case examples the camera HAL may support.
  *
- * S8.1 Zero Shutter Lag (ZSL) with CAMERA3_STREAM_INPUT stream.
- *
- *   When Zero Shutter Lag (ZSL) is supported by the camera device, the INPUT stream
- *   can be used for application/framework implemented ZSL use case. This kind of stream
- *   will be used by the framework as follows:
- *
- *   1. Framework configures an opaque raw format output stream that is used to
- *      produce the ZSL output buffers. The stream pixel format will be
- *      HAL_PIXEL_FORMAT_RAW_OPAQUE.
- *
- *   2. Framework configures an opaque raw format input stream that is used to
- *      send the reprocess ZSL buffers to the HAL. The stream pixel format will
- *      also be HAL_PIXEL_FORMAT_RAW_OPAQUE.
- *
- *   3. Framework configures a YUV/JPEG output stream that is used to receive the
- *      reprocessed data. The stream pixel format will be YCbCr_420/HAL_PIXEL_FORMAT_BLOB.
- *
- *   4. Framework picks a ZSL buffer from the output stream when a ZSL capture is
- *      issued by the application, and sends the data back as an input buffer in a
- *      reprocessing request, then sends to the HAL for reprocessing.
- *
- *   5. The HAL sends back the output JPEG result to framework.
- *
- *   The HAL can select the actual raw buffer format and configure the ISP pipeline
- *   appropriately based on the HAL_PIXEL_FORMAT_RAW_OPAQUE format. See this format
- *   definition for more details.
- *
- * S8.2 Zero Shutter Lag (ZSL) with CAMERA3_STREAM_BIDIRECTIONAL stream.
+ * S8.1 Zero Shutter Lag (ZSL) with CAMERA3_STREAM_BIDIRECTIONAL stream.
  *
  *   For this use case, the bidirectional stream will be used by the framework as follows:
  *
@@ -1211,8 +1184,6 @@
      * quality images (that otherwise would cause a frame rate performance
      * loss), or to do off-line reprocessing.
      *
-     * A typical use case is Zero Shutter Lag (ZSL), see S8.1 for more details.
-     *
      */
     CAMERA3_STREAM_INPUT = 1,
 
@@ -1223,7 +1194,7 @@
      *
      * This kind of stream is meant generally for Zero Shutter Lag (ZSL)
      * features, where copying the captured image from the output buffer to the
-     * reprocessing input buffer would be expensive. See S8.2 for more details.
+     * reprocessing input buffer would be expensive. See S8.1 for more details.
      *
      * Note that the HAL will always be reprocessing data it produced.
      *
diff --git a/include/hardware/gps.h b/include/hardware/gps.h
index fff6402..e264cf5 100644
--- a/include/hardware/gps.h
+++ b/include/hardware/gps.h
@@ -318,6 +318,12 @@
 
 /**
  * Flags indicating the GPS measurement state.
+ * The expected behavior here is for GPS HAL to set all the flags that applies. For
+ * example, if the state for a satellite is only C/A code locked and bit synchronized,
+ * and there is still millisecond ambiguity, the state should be set as:
+ * GPS_MEASUREMENT_STATE_CODE_LOCK|GPS_MEASUREMENT_STATE_BIT_SYNC|GPS_MEASUREMENT_STATE_MSEC_AMBIGUOUS
+ * If GPS is still searching for a satellite, the corresponding state should be set to
+ * GPS_MEASUREMENT_STATE_UNKNOWN(0).
  */
 typedef uint16_t GpsMeasurementState;
 #define GPS_MEASUREMENT_STATE_UNKNOWN                   0
@@ -325,6 +331,7 @@
 #define GPS_MEASUREMENT_STATE_BIT_SYNC              (1<<1)
 #define GPS_MEASUREMENT_STATE_SUBFRAME_SYNC         (1<<2)
 #define GPS_MEASUREMENT_STATE_TOW_DECODED           (1<<3)
+#define GPS_MEASUREMENT_STATE_MSEC_AMBIGUOUS        (1<<4)
 
 /**
  * Flags indicating the Accumulated Delta Range's states.
@@ -336,7 +343,7 @@
 #define GPS_ADR_STATE_CYCLE_SLIP                (1<<2)
 
 /**
- * Enumeration of available values to indicate the available GPS Natigation message types.
+ * Enumeration of available values to indicate the available GPS Navigation message types.
  */
 typedef uint8_t GpsNavigationMessageType;
 /** The message type is unknown. */
@@ -350,6 +357,19 @@
 /** CNAV-2 message contained in the structure. */
 #define GPS_NAVIGATION_MESSAGE_TYPE_CNAV2           4
 
+/**
+ * Status of Navigation Message
+ * When a message is received properly without any parity error in its navigation words, the
+ * status should be set to NAV_MESSAGE_STATUS_PARITY_PASSED. But if a message is received
+ * with words that failed parity check, but GPS is able to correct those words, the status
+ * should be set to NAV_MESSAGE_STATUS_PARITY_REBUILT.
+ * No need to send any navigation message that contains words with parity error and cannot be
+ * corrected.
+ */
+typedef uint16_t NavigationMessageStatus;
+#define NAV_MESSAGE_STATUS_UNKONW              0
+#define NAV_MESSAGE_STATUS_PARITY_PASSED   (1<<0)
+#define NAV_MESSAGE_STATUS_PARITY_REBUILT  (1<<1)
 
 /**
  * Name for the GPS XTRA interface.
@@ -1386,12 +1406,16 @@
      * Received GPS Time-of-Week at the measurement time, in nanoseconds.
      * The value is relative to the beginning of the current GPS week.
      *
-     * Given the sync state of GPS receiver, per each satellite, valid range for this field can be:
-     *      Searching           : [ 0       ]   : GPS_MEASUREMENT_STATE_UNKNOWN
-     *      Ranging code lock   : [ 0   1ms ]   : GPS_MEASUREMENT_STATE_CODE_LOCK is set
-     *      Bit sync            : [ 0  20ms ]   : GPS_MEASUREMENT_STATE_BIT_SYNC is set
-     *      Subframe sync       : [ 0   6ms ]   : GPS_MEASUREMENT_STATE_SUBFRAME_SYNC is set
-     *      TOW decoded         : [ 0 1week ]   : GPS_MEASUREMENT_STATE_TOW_DECODED is set
+     * Given the highest sync state that can be achieved, per each satellite, valid range for
+     * this field can be:
+     *     Searching       : [ 0       ]   : GPS_MEASUREMENT_STATE_UNKNOWN
+     *     C/A code lock   : [ 0   1ms ]   : GPS_MEASUREMENT_STATE_CODE_LOCK is set
+     *     Bit sync        : [ 0  20ms ]   : GPS_MEASUREMENT_STATE_BIT_SYNC is set
+     *     Subframe sync   : [ 0    6s ]   : GPS_MEASUREMENT_STATE_SUBFRAME_SYNC is set
+     *     TOW decoded     : [ 0 1week ]   : GPS_MEASUREMENT_STATE_TOW_DECODED is set
+     *
+     * However, if there is any ambiguity in integer millisecond,
+     * GPS_MEASUREMENT_STATE_MSEC_AMBIGUOUS should be set accordingly, in the 'state' field.
      */
     int64_t received_gps_tow_ns;
 
@@ -1681,6 +1705,13 @@
     GpsNavigationMessageType type;
 
     /**
+     * The status of the received navigation message.
+     * No need to send any navigation message that contains words with parity error and cannot be
+     * corrected.
+     */
+    NavigationMessageStatus status;
+
+    /**
      * Message identifier.
      * It provides an index so the complete Navigation Message can be assembled. i.e. fo L1 C/A
      * subframe 4 and 5, this value corresponds to the 'frame id' of the navigation message.
diff --git a/include/hardware/gralloc.h b/include/hardware/gralloc.h
index 91e2f69..7d00114 100644
--- a/include/hardware/gralloc.h
+++ b/include/hardware/gralloc.h
@@ -237,8 +237,17 @@
      * difference that it fills a struct ycbcr with a description of the buffer
      * layout, and zeroes out the reserved fields.
      *
-     * This will only work on buffers with HAL_PIXEL_FORMAT_YCbCr_*_888, and
-     * will return -EINVAL on any other buffer formats.
+     * If the buffer format is not compatible with a flexible YUV format (e.g.
+     * the buffer layout cannot be represented with the ycbcr struct), it
+     * will return -EINVAL.
+     *
+     * This method must work on buffers with HAL_PIXEL_FORMAT_YCbCr_*_888
+     * if supported by the device, as well as with any other format that is
+     * requested by the multimedia codecs when they are configured with a
+     * flexible-YUV-compatible color-format with android native buffers.
+     *
+     * Note that this method may also be called on buffers of other formats,
+     * including non-YUV formats.
      *
      * Added in GRALLOC_MODULE_API_VERSION_0_2.
      */
diff --git a/include/hardware/hdmi_cec.h b/include/hardware/hdmi_cec.h
index 95c0c4e..ab70f92 100644
--- a/include/hardware/hdmi_cec.h
+++ b/include/hardware/hdmi_cec.h
@@ -212,6 +212,15 @@
      * False by default.
      */
     HDMI_OPTION_SYSTEM_CEC_CONTROL = 3,
+
+    /* Option 4 not used */
+
+    /* Passes the updated language information of Android system.
+     * Contains 3-byte ASCII code as defined in ISO/FDIS 639-2. Can be
+     * used for HAL to respond to <Get Menu Language> while in standby mode.
+     * English(eng), for example, is converted to 0x656e67.
+     */
+    HDMI_OPTION_SET_LANG = 5,
 };
 
 /*
@@ -390,7 +399,7 @@
      *
      * Returns 0 on success or -errno on error.
      */
-    void (*set_audio_return_channel)(const struct hdmi_cec_device* dev, int flag);
+    void (*set_audio_return_channel)(const struct hdmi_cec_device* dev, int port_id, int flag);
 
     /*
      * (*is_connected)() returns the connection status of the specified port.
diff --git a/include/hardware/hw_auth_token.h b/include/hardware/hw_auth_token.h
new file mode 100644
index 0000000..40283cb
--- /dev/null
+++ b/include/hardware/hw_auth_token.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdint.h>
+
+#ifndef ANDROID_HARDWARE_HW_AUTH_TOKEN_H
+#define ANDROID_HARDWARE_HW_AUTH_TOKEN_H
+
+#ifndef __cplusplus
+extern "C" {
+#endif  // __cplusplus
+
+const uint8_t HW_AUTH_TOKEN_VERSION = 0;
+
+typedef enum {
+    HW_AUTH_NONE = 0,
+    HW_AUTH_PASSWORD = 1 << 0,
+    HW_AUTH_FINGERPRINT = 1 << 1,
+    // Additional entries should be powers of 2.
+    HW_AUTH_ANY = UINT32_MAX,
+} hw_authenticator_type_t;
+
+/**
+ * Data format for an authentication record used to prove successful authentication.
+ */
+typedef struct __attribute__((__packed__)) {
+    uint8_t version;  // Current version is 0
+    uint64_t challenge;
+    uint64_t user_id;             // secure user ID, not Android user ID
+    uint64_t authenticator_id;    // secure authenticator ID
+    uint32_t authenticator_type;  // hw_authenticator_type_t, in network order
+    uint64_t timestamp;           // in network order
+    uint8_t hmac[32];
+} hw_auth_token_t;
+
+#ifndef __cplusplus
+}  // extern "C"
+#endif  // __cplusplus
+
+#endif  // ANDROID_HARDWARE_HW_AUTH_TOKEN_H
diff --git a/include/hardware/keymaster0.h b/include/hardware/keymaster0.h
new file mode 100644
index 0000000..f020e5b
--- /dev/null
+++ b/include/hardware/keymaster0.h
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_KEYMASTER_0_H
+#define ANDROID_HARDWARE_KEYMASTER_0_H
+
+#include <hardware/keymaster_common.h>
+
+__BEGIN_DECLS
+
+/**
+ * Keymaster0 device definition.
+ */
+struct keymaster0_device {
+    /**
+     * Common methods of the keymaster device.  This *must* be the first member of
+     * keymaster0_device as users of this structure will cast a hw_device_t to
+     * keymaster0_device pointer in contexts where it's known the hw_device_t references a
+     * keymaster0_device.
+     */
+    struct hw_device_t common;
+
+    /**
+     * THIS IS DEPRECATED. Use the new "module_api_version" and "hal_api_version"
+     * fields in the keymaster_module initialization instead.
+     */
+    uint32_t client_version;
+
+    /**
+     * See flags defined for keymaster0_device::flags in keymaster_common.h
+     */
+    uint32_t flags;
+
+    void* context;
+
+    /**
+     * Generates a public and private key. The key-blob returned is opaque
+     * and must subsequently provided for signing and verification.
+     *
+     * Returns: 0 on success or an error code less than 0.
+     */
+    int (*generate_keypair)(const struct keymaster0_device* dev,
+            const keymaster_keypair_t key_type, const void* key_params,
+            uint8_t** key_blob, size_t* key_blob_length);
+
+    /**
+     * Imports a public and private key pair. The imported keys will be in
+     * PKCS#8 format with DER encoding (Java standard). The key-blob
+     * returned is opaque and will be subsequently provided for signing
+     * and verification.
+     *
+     * Returns: 0 on success or an error code less than 0.
+     */
+    int (*import_keypair)(const struct keymaster0_device* dev,
+            const uint8_t* key, const size_t key_length,
+            uint8_t** key_blob, size_t* key_blob_length);
+
+    /**
+     * Gets the public key part of a key pair. The public key must be in
+     * X.509 format (Java standard) encoded byte array.
+     *
+     * Returns: 0 on success or an error code less than 0.
+     * On error, x509_data should not be allocated.
+     */
+    int (*get_keypair_public)(const struct keymaster0_device* dev,
+            const uint8_t* key_blob, const size_t key_blob_length,
+            uint8_t** x509_data, size_t* x509_data_length);
+
+    /**
+     * Deletes the key pair associated with the key blob.
+     *
+     * This function is optional and should be set to NULL if it is not
+     * implemented.
+     *
+     * Returns 0 on success or an error code less than 0.
+     */
+    int (*delete_keypair)(const struct keymaster0_device* dev,
+            const uint8_t* key_blob, const size_t key_blob_length);
+
+    /**
+     * Deletes all keys in the hardware keystore. Used when keystore is
+     * reset completely.
+     *
+     * This function is optional and should be set to NULL if it is not
+     * implemented.
+     *
+     * Returns 0 on success or an error code less than 0.
+     */
+    int (*delete_all)(const struct keymaster0_device* dev);
+
+    /**
+     * Signs data using a key-blob generated before. This can use either
+     * an asymmetric key or a secret key.
+     *
+     * Returns: 0 on success or an error code less than 0.
+     */
+    int (*sign_data)(const struct keymaster0_device* dev,
+            const void* signing_params,
+            const uint8_t* key_blob, const size_t key_blob_length,
+            const uint8_t* data, const size_t data_length,
+            uint8_t** signed_data, size_t* signed_data_length);
+
+    /**
+     * Verifies data signed with a key-blob. This can use either
+     * an asymmetric key or a secret key.
+     *
+     * Returns: 0 on successful verification or an error code less than 0.
+     */
+    int (*verify_data)(const struct keymaster0_device* dev,
+            const void* signing_params,
+            const uint8_t* key_blob, const size_t key_blob_length,
+            const uint8_t* signed_data, const size_t signed_data_length,
+            const uint8_t* signature, const size_t signature_length);
+};
+typedef struct keymaster0_device keymaster0_device_t;
+
+
+/* Convenience API for opening and closing keymaster devices */
+
+static inline int keymaster0_open(const struct hw_module_t* module,
+        keymaster0_device_t** device)
+{
+    int rc = module->methods->open(module, KEYSTORE_KEYMASTER,
+            (struct hw_device_t**) device);
+
+    return rc;
+}
+
+static inline int keymaster0_close(keymaster0_device_t* device)
+{
+    return device->common.close(&device->common);
+}
+
+__END_DECLS
+
+#endif  // ANDROID_HARDWARE_KEYMASTER_0_H
diff --git a/include/hardware/keymaster.h b/include/hardware/keymaster1.h
similarity index 88%
rename from include/hardware/keymaster.h
rename to include/hardware/keymaster1.h
index db66a74..4227f57 100644
--- a/include/hardware/keymaster.h
+++ b/include/hardware/keymaster1.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011 The Android Open Source Project
+ * Copyright (C) 2015 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.
@@ -14,57 +14,18 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_HARDWARE_KEYMASTER_H
-#define ANDROID_HARDWARE_KEYMASTER_H
+#ifndef ANDROID_HARDWARE_KEYMASTER1_H
+#define ANDROID_HARDWARE_KEYMASTER1_H
 
-#include <stdint.h>
-#include <sys/cdefs.h>
-#include <sys/types.h>
-
-#include <hardware/hardware.h>
+#include <hardware/keymaster_common.h>
 #include <hardware/keymaster_defs.h>
 
 __BEGIN_DECLS
 
 /**
- * The id of this module
+ * Keymaster1 device definition
  */
-#define KEYSTORE_HARDWARE_MODULE_ID "keystore"
-
-#define KEYSTORE_KEYMASTER "keymaster"
-
-/**
- * Settings for "module_api_version" and "hal_api_version"
- * fields in the keymaster_module initialization.
- */
-#define KEYMASTER_HEADER_VERSION 4
-
-#define KEYMASTER_MODULE_API_VERSION_0_2 HARDWARE_MODULE_API_VERSION(0, 2)
-#define KEYMASTER_DEVICE_API_VERSION_0_2 \
-    HARDWARE_DEVICE_API_VERSION_2(0, 2, KEYMASTER_HEADER_VERSION)
-
-#define KEYMASTER_MODULE_API_VERSION_0_3 HARDWARE_MODULE_API_VERSION(0, 3)
-#define KEYMASTER_DEVICE_API_VERSION_0_3 \
-    HARDWARE_DEVICE_API_VERSION_2(0, 3, KEYMASTER_HEADER_VERSION)
-
-#define KEYMASTER_MODULE_API_VERSION_0_4 HARDWARE_MODULE_API_VERSION(0, 4)
-#define KEYMASTER_DEVICE_API_VERSION_0_4 \
-    HARDWARE_DEVICE_API_VERSION_2(0, 4, KEYMASTER_HEADER_VERSION)
-
-struct keystore_module {
-    /**
-     * Common methods of the keystore module.  This *must* be the first member of
-     * keystore_module as users of this structure will cast a hw_module_t to
-     * keystore_module pointer in contexts where it's known the hw_module_t references a
-     * keystore_module.
-     */
-    hw_module_t common;
-};
-
-/**
- * The parameters that can be set for a given keymaster implementation.
- */
-struct keymaster_device {
+struct keymaster1_device {
     /**
      * Common methods of the keymaster device.  This *must* be the first member of
      * keymaster_device as users of this structure will cast a hw_device_t to
@@ -80,7 +41,7 @@
     uint32_t client_version;
 
     /**
-     * See flags defined for keymaster_device::flags above.
+     * See flags defined for keymaster0_devices::flags in keymaster_common.h
      */
     uint32_t flags;
 
@@ -92,7 +53,7 @@
      *
      * Returns: 0 on success or an error code less than 0.
      */
-    int (*generate_keypair)(const struct keymaster_device* dev, const keymaster_keypair_t key_type,
+    int (*generate_keypair)(const struct keymaster1_device* dev, const keymaster_keypair_t key_type,
                             const void* key_params, uint8_t** key_blob, size_t* key_blob_length);
 
     /**
@@ -102,7 +63,7 @@
      *
      * Returns: 0 on success or an error code less than 0.
      */
-    int (*import_keypair)(const struct keymaster_device* dev, const uint8_t* key,
+    int (*import_keypair)(const struct keymaster1_device* dev, const uint8_t* key,
                           const size_t key_length, uint8_t** key_blob, size_t* key_blob_length);
 
     /**
@@ -112,7 +73,7 @@
      * Returns: 0 on success or an error code less than 0.  On error, x509_data
      * should not be allocated.
      */
-    int (*get_keypair_public)(const struct keymaster_device* dev, const uint8_t* key_blob,
+    int (*get_keypair_public)(const struct keymaster1_device* dev, const uint8_t* key_blob,
                               const size_t key_blob_length, uint8_t** x509_data,
                               size_t* x509_data_length);
 
@@ -124,7 +85,7 @@
      *
      * Returns 0 on success or an error code less than 0.
      */
-    int (*delete_keypair)(const struct keymaster_device* dev, const uint8_t* key_blob,
+    int (*delete_keypair)(const struct keymaster1_device* dev, const uint8_t* key_blob,
                           const size_t key_blob_length);
 
     /**
@@ -136,7 +97,7 @@
      *
      * Returns 0 on success or an error code less than 0.
      */
-    int (*delete_all)(const struct keymaster_device* dev);
+    int (*delete_all)(const struct keymaster1_device* dev);
 
     /**
      * \deprecated Signs data using a key-blob generated before. This can use either an asymmetric
@@ -144,7 +105,7 @@
      *
      * Returns: 0 on success or an error code less than 0.
      */
-    int (*sign_data)(const struct keymaster_device* dev, const void* signing_params,
+    int (*sign_data)(const struct keymaster1_device* dev, const void* signing_params,
                      const uint8_t* key_blob, const size_t key_blob_length, const uint8_t* data,
                      const size_t data_length, uint8_t** signed_data, size_t* signed_data_length);
 
@@ -154,7 +115,7 @@
      *
      * Returns: 0 on successful verification or an error code less than 0.
      */
-    int (*verify_data)(const struct keymaster_device* dev, const void* signing_params,
+    int (*verify_data)(const struct keymaster1_device* dev, const void* signing_params,
                        const uint8_t* key_blob, const size_t key_blob_length,
                        const uint8_t* signed_data, const size_t signed_data_length,
                        const uint8_t* signature, const size_t signature_length);
@@ -169,7 +130,7 @@
      *
      * \param[out] algorithms_length Length of \p algorithms.
      */
-    keymaster_error_t (*get_supported_algorithms)(const struct keymaster_device* dev,
+    keymaster_error_t (*get_supported_algorithms)(const struct keymaster1_device* dev,
                                                   keymaster_algorithm_t** algorithms,
                                                   size_t* algorithms_length);
 
@@ -185,7 +146,7 @@
      *
      * \param[out] modes_length Length of \p modes.
      */
-    keymaster_error_t (*get_supported_block_modes)(const struct keymaster_device* dev,
+    keymaster_error_t (*get_supported_block_modes)(const struct keymaster1_device* dev,
                                                    keymaster_algorithm_t algorithm,
                                                    keymaster_purpose_t purpose,
                                                    keymaster_block_mode_t** modes,
@@ -204,7 +165,7 @@
      *
      * \param[out] modes_length Length of \p modes.
      */
-    keymaster_error_t (*get_supported_padding_modes)(const struct keymaster_device* dev,
+    keymaster_error_t (*get_supported_padding_modes)(const struct keymaster1_device* dev,
                                                      keymaster_algorithm_t algorithm,
                                                      keymaster_purpose_t purpose,
                                                      keymaster_padding_t** modes,
@@ -223,7 +184,7 @@
      *
      * \param[out] digests_length Length of \p digests.
      */
-    keymaster_error_t (*get_supported_digests)(const struct keymaster_device* dev,
+    keymaster_error_t (*get_supported_digests)(const struct keymaster1_device* dev,
                                                keymaster_algorithm_t algorithm,
                                                keymaster_purpose_t purpose,
                                                keymaster_digest_t** digests,
@@ -242,7 +203,7 @@
      *
      * \param[out] formats_length Length of \p formats.
      */
-    keymaster_error_t (*get_supported_import_formats)(const struct keymaster_device* dev,
+    keymaster_error_t (*get_supported_import_formats)(const struct keymaster1_device* dev,
                                                       keymaster_algorithm_t algorithm,
                                                       keymaster_key_format_t** formats,
                                                       size_t* formats_length);
@@ -260,7 +221,7 @@
      *
      * \param[out] formats_length Length of \p formats.
      */
-    keymaster_error_t (*get_supported_export_formats)(const struct keymaster_device* dev,
+    keymaster_error_t (*get_supported_export_formats)(const struct keymaster1_device* dev,
                                                       keymaster_algorithm_t algorithm,
                                                       keymaster_key_format_t** formats,
                                                       size_t* formats_length);
@@ -278,7 +239,7 @@
      *
      * \param[in] data_length Length of \p data.
      */
-    keymaster_error_t (*add_rng_entropy)(const struct keymaster_device* dev, const uint8_t* data,
+    keymaster_error_t (*add_rng_entropy)(const struct keymaster1_device* dev, const uint8_t* data,
                                          size_t data_length);
 
     /**
@@ -336,7 +297,7 @@
      * keymaster_free_characteristics().  Note that KM_TAG_ROOT_OF_TRUST, KM_TAG_APPLICATION_ID and
      * KM_TAG_APPLICATION_DATA are never returned.
      */
-    keymaster_error_t (*generate_key)(const struct keymaster_device* dev,
+    keymaster_error_t (*generate_key)(const struct keymaster1_device* dev,
                                       const keymaster_key_param_t* params, size_t params_count,
                                       keymaster_key_blob_t* key_blob,
                                       keymaster_key_characteristics_t** characteristics);
@@ -361,7 +322,7 @@
      *
      * \param[out] characteristics The key characteristics.
      */
-    keymaster_error_t (*get_key_characteristics)(const struct keymaster_device* dev,
+    keymaster_error_t (*get_key_characteristics)(const struct keymaster1_device* dev,
                                                  const keymaster_key_blob_t* key_blob,
                                                  const keymaster_blob_t* client_id,
                                                  const keymaster_blob_t* app_data,
@@ -396,7 +357,7 @@
      * hw_enforced and sw_enforced lists.  The caller takes ownership and must call
      * keymaster_free_characteristics() to free.
      */
-    keymaster_error_t (*rescope)(const struct keymaster_device* dev,
+    keymaster_error_t (*rescope)(const struct keymaster1_device* dev,
                                  const keymaster_key_param_t* new_params, size_t new_params_count,
                                  const keymaster_key_blob_t* key_blob,
                                  const keymaster_blob_t* client_id,
@@ -456,7 +417,7 @@
      * NULL, in which case no characteristics will be returned.  If non-NULL, the caller assumes
      * ownership and must deallocate with keymaster_free_characteristics().
      */
-    keymaster_error_t (*import_key)(const struct keymaster_device* dev,
+    keymaster_error_t (*import_key)(const struct keymaster1_device* dev,
                                     const keymaster_key_param_t* params, size_t params_count,
                                     keymaster_key_format_t key_format, const uint8_t* key_data,
                                     size_t key_data_length, keymaster_key_blob_t* key_blob,
@@ -475,7 +436,7 @@
      *
      * \param[out] export_data_length The length of \p export_data.
      */
-    keymaster_error_t (*export_key)(const struct keymaster_device* dev,
+    keymaster_error_t (*export_key)(const struct keymaster1_device* dev,
                                     keymaster_key_format_t export_format,
                                     const keymaster_key_blob_t* key_to_export,
                                     const keymaster_blob_t* client_id,
@@ -494,7 +455,7 @@
      *
      * \param[in] key The key to be deleted.
      */
-    keymaster_error_t (*delete_key)(const struct keymaster_device* dev,
+    keymaster_error_t (*delete_key)(const struct keymaster1_device* dev,
                                     const keymaster_key_blob_t* key);
 
     /**
@@ -505,10 +466,8 @@
      * This function is optional and should be set to NULL if it is not implemented.
      *
      * \param[in] dev The keymaster device structure.
-     *
-     * Returns 0 on success or an error code less than 0.
      */
-    int (*delete_all_keys)(const struct keymaster_device* dev);
+    keymaster_error_t (*delete_all_keys)(const struct keymaster1_device* dev);
 
     /**
      * Begins a cryptographic operation using the specified key.  If all is well, begin() will
@@ -549,7 +508,7 @@
      * \param[out] operation_handle The newly-created operation handle which must be passed to
      * update(), finish() or abort().
      */
-    keymaster_error_t (*begin)(const struct keymaster_device* dev, keymaster_purpose_t purpose,
+    keymaster_error_t (*begin)(const struct keymaster1_device* dev, keymaster_purpose_t purpose,
                                const keymaster_key_blob_t* key, const keymaster_key_param_t* params,
                                size_t params_count, keymaster_key_param_t** out_params,
                                size_t* out_params_count,
@@ -593,7 +552,7 @@
      * Note that update() may not provide any output, in which case *output_length will be zero, and
      * *output may be either NULL or zero-length (so the caller should always free() it).
      */
-    keymaster_error_t (*update)(const struct keymaster_device* dev,
+    keymaster_error_t (*update)(const struct keymaster1_device* dev,
                                 keymaster_operation_handle_t operation_handle,
                                 const keymaster_key_param_t* params, size_t params_count,
                                 const uint8_t* input, size_t input_length, size_t* input_consumed,
@@ -626,7 +585,7 @@
      * If the operation being finished is a signature verification or an AEAD-mode decryption and
      * verification fails then finish() will return KM_ERROR_VERIFICATION_FAILED.
      */
-    keymaster_error_t (*finish)(const struct keymaster_device* dev,
+    keymaster_error_t (*finish)(const struct keymaster1_device* dev,
                                 keymaster_operation_handle_t operation_handle,
                                 const keymaster_key_param_t* params, size_t params_count,
                                 const uint8_t* signature, size_t signature_length, uint8_t** output,
@@ -636,21 +595,21 @@
      * Aborts a cryptographic operation begun with begin(), freeing all internal resources and
      * invalidating operation_handle.
      */
-    keymaster_error_t (*abort)(const struct keymaster_device* dev,
+    keymaster_error_t (*abort)(const struct keymaster1_device* dev,
                                keymaster_operation_handle_t operation_handle);
 };
-typedef struct keymaster_device keymaster_device_t;
+typedef struct keymaster1_device keymaster1_device_t;
 
 /* Convenience API for opening and closing keymaster devices */
 
-static inline int keymaster_open(const struct hw_module_t* module, keymaster_device_t** device) {
+static inline int keymaster1_open(const struct hw_module_t* module, keymaster1_device_t** device) {
     return module->methods->open(module, KEYSTORE_KEYMASTER, (struct hw_device_t**)device);
 }
 
-static inline int keymaster_close(keymaster_device_t* device) {
+static inline int keymaster1_close(keymaster1_device_t* device) {
     return device->common.close(&device->common);
 }
 
 __END_DECLS
 
-#endif  // ANDROID_HARDWARE_KEYMASTER_H
+#endif  // ANDROID_HARDWARE_KEYMASTER1_H
diff --git a/include/hardware/keymaster_common.h b/include/hardware/keymaster_common.h
new file mode 100644
index 0000000..772d7e4
--- /dev/null
+++ b/include/hardware/keymaster_common.h
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2015 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_HARDWARE_KEYMASTER_COMMON_H
+#define ANDROID_HARDWARE_KEYMASTER_COMMON_H
+
+#include <stdint.h>
+#include <sys/cdefs.h>
+#include <sys/types.h>
+
+#include <hardware/hardware.h>
+
+__BEGIN_DECLS
+
+/**
+ * The id of this module
+ */
+#define KEYSTORE_HARDWARE_MODULE_ID "keystore"
+
+#define KEYSTORE_KEYMASTER "keymaster"
+
+
+/**
+ * Settings for "module_api_version" and "hal_api_version"
+ * fields in the keymaster_module initialization.
+ */
+
+/**
+ * Keymaster 0.X module version provide the same APIs, but later versions add more options
+ * for algorithms and flags.
+ */
+#define KEYMASTER_MODULE_API_VERSION_0_2 HARDWARE_MODULE_API_VERSION(0, 2)
+#define KEYMASTER_DEVICE_API_VERSION_0_2 HARDWARE_DEVICE_API_VERSION(0, 2)
+
+#define KEYMASTER_MODULE_API_VERSION_0_3 HARDWARE_MODULE_API_VERSION(0, 3)
+#define KEYMASTER_DEVICE_API_VERSION_0_3 HARDWARE_DEVICE_API_VERSION(0, 3)
+
+/**
+ * Keymaster 1.0 module version provides a completely different API, incompatible with 0.X.
+ */
+#define KEYMASTER_MODULE_API_VERSION_1_0 HARDWARE_MODULE_API_VERSION(1, 0)
+#define KEYMASTER_DEVICE_API_VERSION_1_0 HARDWARE_DEVICE_API_VERSION(1, 0)
+
+struct keystore_module {
+    /**
+     * Common methods of the keystore module.  This *must* be the first member of keystore_module as
+     * users of this structure will cast a hw_module_t to keystore_module pointer in contexts where
+     * it's known the hw_module_t references a keystore_module.
+     */
+    hw_module_t common;
+
+    /* There are no keystore module methods other than the common ones. */
+};
+
+/**
+ * Flags for keymaster0_device::flags
+ */
+enum {
+    /*
+     * Indicates this keymaster implementation does not have hardware that
+     * keeps private keys out of user space.
+     *
+     * This should not be implemented on anything other than the default
+     * implementation.
+     */
+    KEYMASTER_SOFTWARE_ONLY = 1 << 0,
+
+    /*
+     * This indicates that the key blobs returned via all the primitives
+     * are sufficient to operate on their own without the trusted OS
+     * querying userspace to retrieve some other data. Key blobs of
+     * this type are normally returned encrypted with a
+     * Key Encryption Key (KEK).
+     *
+     * This is currently used by "vold" to know whether the whole disk
+     * encryption secret can be unwrapped without having some external
+     * service started up beforehand since the "/data" partition will
+     * be unavailable at that point.
+     */
+    KEYMASTER_BLOBS_ARE_STANDALONE = 1 << 1,
+
+    /*
+     * Indicates that the keymaster module supports DSA keys.
+     */
+    KEYMASTER_SUPPORTS_DSA = 1 << 2,
+
+    /*
+     * Indicates that the keymaster module supports EC keys.
+     */
+    KEYMASTER_SUPPORTS_EC = 1 << 3,
+};
+
+/**
+ * Asymmetric key pair types.
+ */
+typedef enum {
+    TYPE_RSA = 1,
+    TYPE_DSA = 2,
+    TYPE_EC = 3,
+} keymaster_keypair_t;
+
+/**
+ * Parameters needed to generate an RSA key.
+ */
+typedef struct {
+    uint32_t modulus_size;
+    uint64_t public_exponent;
+} keymaster_rsa_keygen_params_t;
+
+/**
+ * Parameters needed to generate a DSA key.
+ */
+typedef struct {
+    uint32_t key_size;
+    uint32_t generator_len;
+    uint32_t prime_p_len;
+    uint32_t prime_q_len;
+    const uint8_t* generator;
+    const uint8_t* prime_p;
+    const uint8_t* prime_q;
+} keymaster_dsa_keygen_params_t;
+
+/**
+ * Parameters needed to generate an EC key.
+ *
+ * Field size is the only parameter in version 2. The sizes correspond to these required curves:
+ *
+ * 192 = NIST P-192
+ * 224 = NIST P-224
+ * 256 = NIST P-256
+ * 384 = NIST P-384
+ * 521 = NIST P-521
+ *
+ * The parameters for these curves are available at: http://www.nsa.gov/ia/_files/nist-routines.pdf
+ * in Chapter 4.
+ */
+typedef struct {
+    uint32_t field_size;
+} keymaster_ec_keygen_params_t;
+
+
+/**
+ * Digest type.
+ */
+typedef enum {
+    DIGEST_NONE,
+} keymaster_digest_algorithm_t;
+
+/**
+ * Type of padding used for RSA operations.
+ */
+typedef enum {
+    PADDING_NONE,
+} keymaster_rsa_padding_t;
+
+
+typedef struct {
+    keymaster_digest_algorithm_t digest_type;
+} keymaster_dsa_sign_params_t;
+
+typedef struct {
+    keymaster_digest_algorithm_t digest_type;
+} keymaster_ec_sign_params_t;
+
+typedef struct {
+    keymaster_digest_algorithm_t digest_type;
+    keymaster_rsa_padding_t padding_type;
+} keymaster_rsa_sign_params_t;
+
+__END_DECLS
+
+#endif  // ANDROID_HARDWARE_KEYMASTER_COMMON_H
diff --git a/include/hardware/keymaster_defs.h b/include/hardware/keymaster_defs.h
index f8e90b6..2b43f2c 100644
--- a/include/hardware/keymaster_defs.h
+++ b/include/hardware/keymaster_defs.h
@@ -21,60 +21,9 @@
 #include <stdlib.h>
 #include <string.h>
 
-#if defined(__cplusplus)
+#ifndef __cplusplus
 extern "C" {
-#endif  // defined(__cplusplus)
-
-/*!
- * \deprecated Flags for keymaster_device::flags
- *
- * keymaster_device::flags is deprecated and will be removed in the
- * next version of the API in favor of the more detailed information
- * available from TODO:
- */
-enum {
-    /*
-     * Indicates this keymaster implementation does not have hardware that
-     * keeps private keys out of user space.
-     *
-     * This should not be implemented on anything other than the default
-     * implementation.
-     */
-    KEYMASTER_SOFTWARE_ONLY = 1 << 0,
-
-    /*
-     * This indicates that the key blobs returned via all the primitives
-     * are sufficient to operate on their own without the trusted OS
-     * querying userspace to retrieve some other data. Key blobs of
-     * this type are normally returned encrypted with a
-     * Key Encryption Key (KEK).
-     *
-     * This is currently used by "vold" to know whether the whole disk
-     * encryption secret can be unwrapped without having some external
-     * service started up beforehand since the "/data" partition will
-     * be unavailable at that point.
-     */
-    KEYMASTER_BLOBS_ARE_STANDALONE = 1 << 1,
-
-    /*
-     * Indicates that the keymaster module supports DSA keys.
-     */
-    KEYMASTER_SUPPORTS_DSA = 1 << 2,
-
-    /*
-     * Indicates that the keymaster module supports EC keys.
-     */
-    KEYMASTER_SUPPORTS_EC = 1 << 3,
-};
-
-/**
- * \deprecated Asymmetric key pair types.
- */
-typedef enum {
-    TYPE_RSA = 1,
-    TYPE_DSA = 2,
-    TYPE_EC = 3,
-} keymaster_keypair_t;
+#endif  // __cplusplus
 
 /**
  * Authorization tags each have an associated type.  This enumeration facilitates tagging each with
@@ -92,6 +41,7 @@
     KM_BOOL = 7 << 28,
     KM_BIGNUM = 8 << 28,
     KM_BYTES = 9 << 28,
+    KM_LONG_REP = 10 << 28, /* Repeatable long value */
 } keymaster_tag_type_t;
 
 typedef enum {
@@ -105,13 +55,12 @@
     KM_TAG_PURPOSE = KM_ENUM_REP | 1,     /* keymaster_purpose_t. */
     KM_TAG_ALGORITHM = KM_ENUM | 2,       /* keymaster_algorithm_t. */
     KM_TAG_KEY_SIZE = KM_INT | 3,         /* Key size in bits. */
-    KM_TAG_BLOCK_MODE = KM_ENUM | 4,      /* keymaster_block_mode_t. */
-    KM_TAG_DIGEST = KM_ENUM | 5,          /* keymaster_digest_t. */
-    KM_TAG_MAC_LENGTH = KM_INT | 6,       /* MAC or AEAD authentication tag length in bits. */
-    KM_TAG_PADDING = KM_ENUM | 7,         /* keymaster_padding_t. */
-    KM_TAG_RETURN_UNAUTHED = KM_BOOL | 8, /* Allow AEAD decryption to return plaintext before it has
+    KM_TAG_BLOCK_MODE = KM_ENUM_REP | 4,  /* keymaster_block_mode_t. */
+    KM_TAG_DIGEST = KM_ENUM_REP | 5,      /* keymaster_digest_t. */
+    KM_TAG_PADDING = KM_ENUM_REP | 6,     /* keymaster_padding_t. */
+    KM_TAG_RETURN_UNAUTHED = KM_BOOL | 7, /* Allow AEAD decryption to return plaintext before it has
                                              been authenticated.  WARNING: Not recommended. */
-    KM_TAG_CALLER_NONCE = KM_BOOL | 9,    /* Allow caller to specify nonce or IV. */
+    KM_TAG_CALLER_NONCE = KM_BOOL | 8,    /* Allow caller to specify nonce or IV. */
 
     /* Other hardware-enforced. */
     KM_TAG_RESCOPING_ADD = KM_ENUM_REP | 101, /* Tags authorized for addition via rescoping. */
@@ -120,11 +69,6 @@
 
     /* Algorithm-specific. */
     KM_TAG_RSA_PUBLIC_EXPONENT = KM_LONG | 200, /* Defaults to 2^16+1 */
-    KM_TAG_DSA_GENERATOR = KM_BIGNUM | 201,
-    KM_TAG_DSA_P = KM_BIGNUM | 202,
-    KM_TAG_DSA_Q = KM_BIGNUM | 203,
-    /* Note there are no EC-specific params.  Field size is defined by KM_TAG_KEY_SIZE, and the
-       curve is chosen from NIST recommendations for field size */
 
     /*
      * Tags that should be semantically enforced by hardware if possible and will otherwise be
@@ -143,20 +87,23 @@
                                                            boot. */
 
     /* User authentication */
-    KM_TAG_ALL_USERS = KM_BOOL | 500,        /* If key is usable by all users. */
-    KM_TAG_USER_ID = KM_INT | 501,           /* ID of authorized user.  Disallowed if
-                                                KM_TAG_ALL_USERS is present. */
-    KM_TAG_NO_AUTH_REQUIRED = KM_BOOL | 502, /* If key is usable without authentication. */
-    KM_TAG_USER_AUTH_ID = KM_INT_REP | 503,  /* ID of the authenticator to use (e.g. password,
-                                                fingerprint, etc.).  Repeatable to support
-                                                multi-factor auth.  Disallowed if
-                                                KM_TAG_NO_AUTH_REQUIRED is present. */
-    KM_TAG_AUTH_TIMEOUT = KM_INT | 504,      /* Required freshness of user authentication for
-                                                private/secret key operations, in seconds.
-                                                Public key operations require no authentication.
-                                                If absent, authentication is required for every
-                                                use.  Authentication state is lost when the
-                                                device is powered off. */
+    KM_TAG_ALL_USERS = KM_BOOL | 500,          /* If key is usable by all users. */
+    KM_TAG_USER_ID = KM_INT | 501,             /* ID of authorized user.  Disallowed if
+                                                  KM_TAG_ALL_USERS is present. */
+    KM_TAG_USER_SECURE_ID = KM_LONG_REP | 502, /* Secure ID of authorized user or authenticator(s).
+                                                  Disallowed if KM_TAG_ALL_USERS or
+                                                  KM_TAG_NO_AUTH_REQUIRED is present. */
+    KM_TAG_NO_AUTH_REQUIRED = KM_BOOL | 503,   /* If key is usable without authentication. */
+    KM_TAG_USER_AUTH_TYPE = KM_ENUM | 504,     /* Bitmask of authenticator types allowed when
+                                                * KM_TAG_USER_SECURE_ID contains a secure user ID,
+                                                * rather than a secure authenticator ID.  Defined in
+                                                * hw_authenticator_type_t in hw_auth_token.h. */
+    KM_TAG_AUTH_TIMEOUT = KM_INT | 505,        /* Required freshness of user authentication for
+                                                  private/secret key operations, in seconds.
+                                                  Public key operations require no authentication.
+                                                  If absent, authentication is required for every
+                                                  use.  Authentication state is lost when the
+                                                  device is powered off. */
 
     /* Application access control */
     KM_TAG_ALL_APPLICATIONS = KM_BOOL | 600, /* If key is usable by all applications. */
@@ -179,70 +126,47 @@
     KM_TAG_NONCE = KM_BYTES | 1001,           /* Nonce or Initialization Vector */
     KM_TAG_CHUNK_LENGTH = KM_INT | 1002,      /* AEAD mode chunk size, in bytes.  0 means no limit,
                                                  which requires KM_TAG_RETURN_UNAUTHED. */
+    KM_TAG_AUTH_TOKEN = KM_BYTES | 1003,      /* Authentication token that proves secure user
+                                                 authentication has been performed.  Structure
+                                                 defined in hw_auth_token_t in hw_auth_token.h. */
+    KM_TAG_MAC_LENGTH = KM_INT | 1004,        /* MAC or AEAD authentication tag length in bits. */
 } keymaster_tag_t;
 
 /**
  * Algorithms that may be provided by keymaster implementations.  Those that must be provided by all
- * implementations are tagged as "required".  Note that where the values in this enumeration overlap
- * with the values for the deprecated keymaster_keypair_t, the same algorithm must be
- * specified. This type is new in 0_4 and replaces the deprecated keymaster_keypair_t.
+ * implementations are tagged as "required".
  */
 typedef enum {
     /* Asymmetric algorithms. */
-    KM_ALGORITHM_RSA = 1,   /* required */
-    KM_ALGORITHM_DSA = 2,
-    KM_ALGORITHM_ECDSA = 3, /* required */
-    KM_ALGORITHM_ECIES = 4,
-    /* FIPS Approved Ciphers */
-    KM_ALGORITHM_AES = 32, /* required */
-    KM_ALGORITHM_3DES = 33,
-    KM_ALGORITHM_SKIPJACK = 34,
-    /* AES Finalists */
-    KM_ALGORITHM_MARS = 48,
-    KM_ALGORITHM_RC6 = 49,
-    KM_ALGORITHM_SERPENT = 50,
-    KM_ALGORITHM_TWOFISH = 51,
-    /* Other common block ciphers */
-    KM_ALGORITHM_IDEA = 52,
-    KM_ALGORITHM_RC5 = 53,
-    KM_ALGORITHM_CAST5 = 54,
-    KM_ALGORITHM_BLOWFISH = 55,
-    /* Common stream ciphers */
-    KM_ALGORITHM_RC4 = 64,
-    KM_ALGORITHM_CHACHA20 = 65,
+    KM_ALGORITHM_RSA = 1,
+    // KM_ALGORITHM_DSA = 2, -- Removed, do not re-use value 2.
+    KM_ALGORITHM_EC = 3,
+
+    /* Block ciphers algorithms */
+    KM_ALGORITHM_AES = 32,
+
     /* MAC algorithms */
-    KM_ALGORITHM_HMAC = 128, /* required */
+    KM_ALGORITHM_HMAC = 128,
 } keymaster_algorithm_t;
 
 /**
- * Symmetric block cipher modes that may be provided by keymaster implementations.  Those that must
- * be provided by all implementations are tagged as "required".  This type is new in 0_4.
+ * Symmetric block cipher modes provided by keymaster implementations.
  *
- * KM_MODE_FIRST_UNAUTHENTICATED, KM_MODE_FIRST_AUTHENTICATED and KM_MODE_FIRST_MAC are not modes,
- * but markers used to separate the available modes into classes.
+ * KM_MODE_FIRST_UNAUTHENTICATED and KM_MODE_FIRST_AUTHENTICATED are not modes but markers used to
+ * separate the available modes into classes.
  */
 typedef enum {
     /* Unauthenticated modes, usable only for encryption/decryption and not generally recommended
      * except for compatibility with existing other protocols. */
     KM_MODE_FIRST_UNAUTHENTICATED = 1,
-    KM_MODE_ECB = KM_MODE_FIRST_UNAUTHENTICATED, /* required */
-    KM_MODE_CBC = 2,                             /* required */
-    KM_MODE_CBC_CTS = 3,                         /* recommended */
-    KM_MODE_CTR = 4,                             /* recommended */
-    KM_MODE_OFB = 5,
-    KM_MODE_CFB = 6,
-    KM_MODE_XTS = 7, /* Note: requires double-length keys */
+    KM_MODE_ECB = KM_MODE_FIRST_UNAUTHENTICATED,
+    KM_MODE_CBC = 2,
+    KM_MODE_CTR = 4,
+
     /* Authenticated modes, usable for encryption/decryption and signing/verification.  Recommended
-     * over unauthenticated modes for all purposes.  One of KM_MODE_GCM and KM_MODE_OCB is
-     * required. */
+     * over unauthenticated modes for all purposes. */
     KM_MODE_FIRST_AUTHENTICATED = 32,
     KM_MODE_GCM = KM_MODE_FIRST_AUTHENTICATED,
-    KM_MODE_OCB = 33,
-    KM_MODE_CCM = 34,
-    /* MAC modes -- only for signing/verification */
-    KM_MODE_FIRST_MAC = 128,
-    KM_MODE_CMAC = KM_MODE_FIRST_MAC,
-    KM_MODE_POLY1305 = 129,
 } keymaster_block_mode_t;
 
 /**
@@ -252,45 +176,41 @@
  * cryptographically-appropriate pairs.
  */
 typedef enum {
-    KM_PAD_NONE = 1,     /* required, deprecated */
-    KM_PAD_RSA_OAEP = 2, /* required */
-    KM_PAD_RSA_PSS = 3,  /* required */
+    KM_PAD_NONE = 1, /* deprecated */
+    KM_PAD_RSA_OAEP = 2,
+    KM_PAD_RSA_PSS = 3,
     KM_PAD_RSA_PKCS1_1_5_ENCRYPT = 4,
     KM_PAD_RSA_PKCS1_1_5_SIGN = 5,
-    KM_PAD_ANSI_X923 = 32,
-    KM_PAD_ISO_10126 = 33,
-    KM_PAD_ZERO = 64,  /* required */
-    KM_PAD_PKCS7 = 65, /* required */
-    KM_PAD_ISO_7816_4 = 66,
+    KM_PAD_PKCS7 = 64,
 } keymaster_padding_t;
 
 /**
- * Digests that may be provided by keymaster implementations.  Those that must be provided by all
- * implementations are tagged as "required".  Those that have been added since version 0_2 of the
- * API are tagged as "new".
+ * Digests provided by keymaster implementations.
  */
 typedef enum {
-    KM_DIGEST_NONE = 0,           /* new, required */
-    DIGEST_NONE = KM_DIGEST_NONE, /* For 0_2 compatibility */
-    KM_DIGEST_MD5 = 1,            /* new, for compatibility with old protocols only */
-    KM_DIGEST_SHA1 = 2,           /* new */
-    KM_DIGEST_SHA_2_224 = 3,      /* new */
-    KM_DIGEST_SHA_2_256 = 4,      /* new, required */
-    KM_DIGEST_SHA_2_384 = 5,      /* new, recommended */
-    KM_DIGEST_SHA_2_512 = 6,      /* new, recommended */
-    KM_DIGEST_SHA_3_256 = 7,      /* new */
-    KM_DIGEST_SHA_3_384 = 8,      /* new */
-    KM_DIGEST_SHA_3_512 = 9,      /* new */
+    KM_DIGEST_NONE = 0,
+    KM_DIGEST_MD5 = 1, /* Optional, may not be implemented in hardware, will be handled in software
+                        * if needed. */
+    KM_DIGEST_SHA1 = 2,
+    KM_DIGEST_SHA_2_224 = 3,
+    KM_DIGEST_SHA_2_256 = 4,
+    KM_DIGEST_SHA_2_384 = 5,
+    KM_DIGEST_SHA_2_512 = 6,
 } keymaster_digest_t;
 
 /**
- * The origin of a key (or pair), i.e. where it was generated.  Origin and can be used together to
- * determine whether a key may have existed outside of secure hardware.  This type is new in 0_4.
+ * The origin of a key (or pair), i.e. where it was generated.  Note that KM_TAG_ORIGIN can be found
+ * in either the hardware-enforced or software-enforced list for a key, indicating whether the key
+ * is hardware or software-based.  Specifically, a key with KM_ORIGIN_GENERATED in the
+ * hardware-enforced list is guaranteed never to have existed outide the secure hardware.
  */
 typedef enum {
-    KM_ORIGIN_HARDWARE = 0, /* Generated in secure hardware */
-    KM_ORIGIN_SOFTWARE = 1, /* Generated in non-secure software */
-    KM_ORIGIN_IMPORTED = 2, /* Imported, origin unknown */
+    KM_ORIGIN_GENERATED = 0, /* Generated in keymaster */
+    KM_ORIGIN_IMPORTED = 2,  /* Imported, origin unknown */
+    KM_ORIGIN_UNKNOWN = 3,   /* Keymaster did not record origin.  This value can only be seen on
+                              * keys in a keymaster0 implementation.  The keymaster0 adapter uses
+                              * this value to document the fact that it is unkown whether the key
+                              * was generated inside or imported into keymaster. */
 } keymaster_key_origin_t;
 
 /**
@@ -359,10 +279,9 @@
  * In the future this list will expand greatly to accommodate asymmetric key import/export.
  */
 typedef enum {
-    KM_KEY_FORMAT_X509 = 0,   /* for public key export, required */
-    KM_KEY_FORMAT_PKCS8 = 1,  /* for asymmetric key pair import, required */
-    KM_KEY_FORMAT_PKCS12 = 2, /* for asymmetric key pair import, not required */
-    KM_KEY_FORMAT_RAW = 3,    /* for symmetric key import, required */
+    KM_KEY_FORMAT_X509 = 0,   /* for public key export */
+    KM_KEY_FORMAT_PKCS8 = 1,  /* for asymmetric key pair import */
+    KM_KEY_FORMAT_RAW = 3,    /* for symmetric key import */
 } keymaster_key_format_t;
 
 /**
@@ -417,7 +336,6 @@
     KM_ERROR_INVALID_TAG = -40,
     KM_ERROR_MEMORY_ALLOCATION_FAILED = -41,
     KM_ERROR_INVALID_RESCOPING = -42,
-    KM_ERROR_INVALID_DSA_PARAMS = -43,
     KM_ERROR_IMPORT_PARAMETER_MISMATCH = -44,
     KM_ERROR_SECURE_HW_ACCESS_DENIED = -45,
     KM_ERROR_OPERATION_CANCELLED = -46,
@@ -425,6 +343,11 @@
     KM_ERROR_SECURE_HW_BUSY = -48,
     KM_ERROR_SECURE_HW_COMMUNICATION_FAILED = -49,
     KM_ERROR_UNSUPPORTED_EC_FIELD = -50,
+    KM_ERROR_MISSING_NONCE = -51,
+    KM_ERROR_INVALID_NONCE = -52,
+    KM_ERROR_UNSUPPORTED_CHUNK_LENGTH = -53,
+    KM_ERROR_RESCOPABLE_KEY_NOT_USABLE = -54,
+
     KM_ERROR_UNIMPLEMENTED = -100,
     KM_ERROR_VERSION_MISMATCH = -101,
 
@@ -433,68 +356,6 @@
     KM_ERROR_UNKNOWN_ERROR = -1000,
 } keymaster_error_t;
 
-/**
- * \deprecated Parameters needed to generate an RSA key.
- */
-typedef struct {
-    uint32_t modulus_size; /* bits */
-    uint64_t public_exponent;
-} keymaster_rsa_keygen_params_t;
-
-/**
- * \deprecated Parameters needed to generate a DSA key.
- */
-typedef struct {
-    uint32_t key_size; /* bits */
-    uint32_t generator_len;
-    uint32_t prime_p_len;
-    uint32_t prime_q_len;
-    const uint8_t* generator;
-    const uint8_t* prime_p;
-    const uint8_t* prime_q;
-} keymaster_dsa_keygen_params_t;
-
-/**
- * \deprecated Parameters needed to generate an EC key.
- *
- * Field size is the only parameter in version 4. The sizes correspond to these required curves:
- *
- * 192 = NIST P-192
- * 224 = NIST P-224
- * 256 = NIST P-256
- * 384 = NIST P-384
- * 521 = NIST P-521
- *
- * The parameters for these curves are available at: http://www.nsa.gov/ia/_files/nist-routines.pdf
- * in Chapter 4.
- */
-typedef struct { uint32_t field_size; /* bits */ } keymaster_ec_keygen_params_t;
-
-/**
- * \deprecated Type of padding used for RSA operations.
- */
-typedef enum {
-    PADDING_NONE,
-} keymaster_rsa_padding_t;
-
-/**
- * \deprecated
- */
-typedef struct { keymaster_digest_t digest_type; } keymaster_dsa_sign_params_t;
-
-/**
- * \deprecated
- */
-typedef struct { keymaster_digest_t digest_type; } keymaster_ec_sign_params_t;
-
-/**
- *\deprecated
- */
-typedef struct {
-    keymaster_digest_t digest_type;
-    keymaster_rsa_padding_t padding_type;
-} keymaster_rsa_sign_params_t;
-
 /* Convenience functions for manipulating keymaster tag types */
 
 static inline keymaster_tag_type_t keymaster_tag_get_type(keymaster_tag_t tag) {
@@ -577,6 +438,55 @@
     return param;
 }
 
+#define KEYMASTER_SIMPLE_COMPARE(a, b) (a < b) ? -1 : ((a > b) ? 1 : 0)
+inline int keymaster_param_compare(const keymaster_key_param_t* a, const keymaster_key_param_t* b) {
+    int retval = KEYMASTER_SIMPLE_COMPARE(a->tag, b->tag);
+    if (retval != 0)
+        return retval;
+
+    switch (keymaster_tag_get_type(a->tag)) {
+    case KM_INVALID:
+    case KM_BOOL:
+        return 0;
+    case KM_ENUM:
+    case KM_ENUM_REP:
+        return KEYMASTER_SIMPLE_COMPARE(a->enumerated, b->enumerated);
+    case KM_INT:
+    case KM_INT_REP:
+        return KEYMASTER_SIMPLE_COMPARE(a->integer, b->integer);
+    case KM_LONG:
+    case KM_LONG_REP:
+        return KEYMASTER_SIMPLE_COMPARE(a->long_integer, b->long_integer);
+    case KM_DATE:
+        return KEYMASTER_SIMPLE_COMPARE(a->date_time, b->date_time);
+    case KM_BIGNUM:
+    case KM_BYTES:
+        // Handle the empty cases.
+        if (a->blob.data_length != 0 && b->blob.data_length == 0)
+            return -1;
+        if (a->blob.data_length == 0 && b->blob.data_length == 0)
+            return 0;
+        if (a->blob.data_length == 0 && b->blob.data_length > 0)
+            return 1;
+
+        retval = memcmp(a->blob.data, b->blob.data, a->blob.data_length < b->blob.data_length
+                                                        ? a->blob.data_length
+                                                        : b->blob.data_length);
+        if (retval != 0)
+            return retval;
+        else if (a->blob.data_length != b->blob.data_length) {
+            // Equal up to the common length; longer one is larger.
+            if (a->blob.data_length < b->blob.data_length)
+                return -1;
+            if (a->blob.data_length > b->blob.data_length)
+                return 1;
+        };
+    }
+
+    return 0;
+}
+#undef KEYMASTER_SIMPLE_COMPARE
+
 inline void keymaster_free_param_values(keymaster_key_param_t* param, size_t param_count) {
     while (param_count-- > 0) {
         switch (keymaster_tag_get_type(param->tag)) {
@@ -608,8 +518,8 @@
     }
 }
 
-#if defined(__cplusplus)
+#ifndef __cplusplus
 }  // extern "C"
-#endif  // defined(__cplusplus)
+#endif  // __cplusplus
 
 #endif  // ANDROID_HARDWARE_KEYMASTER_DEFS_H
diff --git a/include/hardware/power.h b/include/hardware/power.h
index dc33705..af7799e 100644
--- a/include/hardware/power.h
+++ b/include/hardware/power.h
@@ -27,6 +27,7 @@
 
 #define POWER_MODULE_API_VERSION_0_1  HARDWARE_MODULE_API_VERSION(0, 1)
 #define POWER_MODULE_API_VERSION_0_2  HARDWARE_MODULE_API_VERSION(0, 2)
+#define POWER_MODULE_API_VERSION_0_3  HARDWARE_MODULE_API_VERSION(0, 3)
 
 /**
  * The id of this module
@@ -48,6 +49,10 @@
     POWER_HINT_LOW_POWER = 0x00000005
 } power_hint_t;
 
+typedef enum {
+    POWER_FEATURE_DOUBLE_TAP_TO_WAKE = 0x00000001
+} feature_t;
+
 /**
  * Every hardware module must have a data structure named HAL_MODULE_INFO_SYM
  * and the fields of this data structure must begin with hw_module_t
@@ -127,6 +132,21 @@
      */
     void (*powerHint)(struct power_module *module, power_hint_t hint,
                       void *data);
+
+    /*
+     * (*setFeature) is called to turn on or off a particular feature
+     * depending on the state parameter. The possible features are:
+     *
+     * FEATURE_DOUBLE_TAP_TO_WAKE
+     *
+     *    Enabling/Disabling this feature will allow/disallow the system
+     *    to wake up by tapping the screen twice.
+     *
+     * availability: version 0.3
+     *
+     */
+    void (*setFeature)(struct power_module *module, feature_t feature, int state);
+
 } power_module_t;
 
 
diff --git a/include/hardware/sensors.h b/include/hardware/sensors.h
index f0773d5..e917c0a 100644
--- a/include/hardware/sensors.h
+++ b/include/hardware/sensors.h
@@ -602,6 +602,22 @@
 #define SENSOR_TYPE_PICK_UP_GESTURE                            (25)
 #define SENSOR_STRING_TYPE_PICK_UP_GESTURE                     "android.sensor.pick_up_gesture"
 
+/*
+ * SENSOR_TYPE_WRIST_TILT_GESTURE
+ * trigger-mode: special
+ * wake-up sensor: yes
+ *
+ * A sensor of this type triggers an event each time a tilt of the wrist-worn
+ * device is detected.
+ *
+ * This sensor must be low power, as it is likely to be activated 24/7.
+ * The only allowed value to return is 1.0.
+ *
+ * Implement only the wake-up version of this sensor.
+ */
+#define SENSOR_TYPE_WRIST_TILT_GESTURE                         (26)
+#define SENSOR_STRING_TYPE_WRIST_TILT_GESTURE                  "android.sensor.wrist_tilt_gesture"
+
 /**
  * Values returned by the accelerometer in various locations in the universe.
  * all values are in SI units (m/s^2)
diff --git a/include/hardware/tv_input.h b/include/hardware/tv_input.h
index a94e4ea..ed3fafb 100644
--- a/include/hardware/tv_input.h
+++ b/include/hardware/tv_input.h
@@ -110,29 +110,78 @@
     int32_t reserved[16];
 } tv_input_device_info_t;
 
+/* See tv_input_event_t for more details. */
 enum {
     /*
      * Hardware notifies the framework that a device is available.
+     *
+     * Note that DEVICE_AVAILABLE and DEVICE_UNAVAILABLE events do not represent
+     * hotplug events (i.e. plugging cable into or out of the physical port).
+     * These events notify the framework whether the port is available or not.
+     * For a concrete example, when a user plugs in or pulls out the HDMI cable
+     * from a HDMI port, it does not generate DEVICE_AVAILABLE and/or
+     * DEVICE_UNAVAILABLE events. However, if a user inserts a pluggable USB
+     * tuner into the Android device, it will generate a DEVICE_AVAILABLE event
+     * and when the port is removed, it should generate a DEVICE_UNAVAILABLE
+     * event.
+     *
+     * For hotplug events, please see STREAM_CONFIGURATION_CHANGED for more
+     * details.
+     *
+     * HAL implementation should register devices by using this event when the
+     * device boots up. The framework will recognize device reported via this
+     * event only. In addition, the implementation could use this event to
+     * notify the framework that a removable TV input device (such as USB tuner
+     * as stated in the example above) is attached.
      */
     TV_INPUT_EVENT_DEVICE_AVAILABLE = 1,
     /*
      * Hardware notifies the framework that a device is unavailable.
+     *
+     * HAL implementation should generate this event when a device registered
+     * by TV_INPUT_EVENT_DEVICE_AVAILABLE is no longer available. For example,
+     * the event can indicate that a USB tuner is plugged out from the Android
+     * device.
+     *
+     * Note that this event is not for indicating cable plugged out of the port;
+     * for that purpose, the implementation should use
+     * STREAM_CONFIGURATION_CHANGED event. This event represents the port itself
+     * being no longer available.
      */
     TV_INPUT_EVENT_DEVICE_UNAVAILABLE = 2,
     /*
      * Stream configurations are changed. Client should regard all open streams
      * at the specific device are closed, and should call
      * get_stream_configurations() again, opening some of them if necessary.
+     *
+     * HAL implementation should generate this event when the available stream
+     * configurations change for any reason. A typical use case of this event
+     * would be to notify the framework that the input signal has changed
+     * resolution, or that the cable is plugged out so that the number of
+     * available streams is 0.
+     *
+     * The implementation may use this event to indicate hotplug status of the
+     * port. the framework regards input devices with no available streams as
+     * disconnected, so the implementation can generate this event with no
+     * available streams to indicate that this device is disconnected, and vice
+     * versa.
      */
     TV_INPUT_EVENT_STREAM_CONFIGURATIONS_CHANGED = 3,
     /*
      * Hardware is done with capture request with the buffer. Client can assume
      * ownership of the buffer again.
+     *
+     * HAL implementation should generate this event after request_capture() if
+     * it succeeded. The event shall have the buffer with the captured image.
      */
     TV_INPUT_EVENT_CAPTURE_SUCCEEDED = 4,
     /*
      * Hardware met a failure while processing a capture request or client
      * canceled the request. Client can assume ownership of the buffer again.
+     *
+     * The event is similar to TV_INPUT_EVENT_CAPTURE_SUCCEEDED, but HAL
+     * implementation generates this event upon a failure to process
+     * request_capture(), or a request cancellation.
      */
     TV_INPUT_EVENT_CAPTURE_FAILED = 5,
 };
diff --git a/modules/audio_remote_submix/audio_hw.cpp b/modules/audio_remote_submix/audio_hw.cpp
index 8fed8e4..b9dcf7a 100644
--- a/modules/audio_remote_submix/audio_hw.cpp
+++ b/modules/audio_remote_submix/audio_hw.cpp
@@ -140,11 +140,10 @@
     size_t buffer_period_size_frames;
 };
 
-struct submix_audio_device {
-    struct audio_hw_device device;
-    bool input_standby;
-    bool output_standby;
-    submix_config config;
+#define MAX_ROUTES 10
+typedef struct route_config {
+    struct submix_config config;
+    char address[AUDIO_DEVICE_MAX_ADDRESS_LEN];
     // Pipe variables: they handle the ring buffer that "pipes" audio:
     //  - from the submix virtual audio output == what needs to be played
     //    remotely, seen as an output for AudioFlinger
@@ -155,17 +154,20 @@
     // TV with Wifi Display capabilities), or to a wireless audio player.
     sp<MonoPipe> rsxSink;
     sp<MonoPipeReader> rsxSource;
+    // Pointers to the current input and output stream instances.  rsxSink and rsxSource are
+    // destroyed if both and input and output streams are destroyed.
+    struct submix_stream_out *output;
+    struct submix_stream_in *input;
 #if ENABLE_RESAMPLING
     // Buffer used as temporary storage for resampled data prior to returning data to the output
     // stream.
     int16_t resampler_buffer[DEFAULT_PIPE_SIZE_IN_FRAMES];
 #endif // ENABLE_RESAMPLING
+} route_config_t;
 
-    // Pointers to the current input and output stream instances.  rsxSink and rsxSource are
-    // destroyed if both and input and output streams are destroyed.
-    struct submix_stream_out *output;
-    struct submix_stream_in *input;
-
+struct submix_audio_device {
+    struct audio_hw_device device;
+    route_config_t routes[MAX_ROUTES];
     // Device lock, also used to protect access to submix_audio_device from the input and output
     // streams.
     pthread_mutex_t lock;
@@ -174,6 +176,8 @@
 struct submix_stream_out {
     struct audio_stream_out stream;
     struct submix_audio_device *dev;
+    int route_handle;
+    bool output_standby;
 #if LOG_STREAMS_TO_FILES
     int log_fd;
 #endif // LOG_STREAMS_TO_FILES
@@ -182,7 +186,9 @@
 struct submix_stream_in {
     struct audio_stream_in stream;
     struct submix_audio_device *dev;
-    bool output_standby; // output standby state as seen from record thread
+    int route_handle;
+    bool input_standby;
+    bool output_standby_rec_thr; // output standby state as seen from record thread
 
     // wall clock when recording starts
     struct timespec record_start_time;
@@ -346,40 +352,53 @@
 
 // If one doesn't exist, create a pipe for the submix audio device rsxadev of size
 // buffer_size_frames and optionally associate "in" or "out" with the submix audio device.
-static void submix_audio_device_create_pipe(struct submix_audio_device * const rsxadev,
+// Must be called with lock held on the submix_audio_device
+static void submix_audio_device_create_pipe_l(struct submix_audio_device * const rsxadev,
                                             const struct audio_config * const config,
                                             const size_t buffer_size_frames,
                                             const uint32_t buffer_period_count,
                                             struct submix_stream_in * const in,
-                                            struct submix_stream_out * const out)
+                                            struct submix_stream_out * const out,
+                                            const char *address,
+                                            int route_idx)
 {
     ALOG_ASSERT(in || out);
-    ALOGD("submix_audio_device_create_pipe()");
-    pthread_mutex_lock(&rsxadev->lock);
+    ALOG_ASSERT(route_idx > -1);
+    ALOG_ASSERT(route_idx < MAX_ROUTES);
+    ALOGD("submix_audio_device_create_pipe_l(addr=%s, idx=%d)", address, route_idx);
+
     // Save a reference to the specified input or output stream and the associated channel
     // mask.
     if (in) {
-        rsxadev->input = in;
-        rsxadev->config.input_channel_mask = config->channel_mask;
+        in->route_handle = route_idx;
+        rsxadev->routes[route_idx].input = in;
+        rsxadev->routes[route_idx].config.input_channel_mask = config->channel_mask;
 #if ENABLE_RESAMPLING
-        rsxadev->config.input_sample_rate = config->sample_rate;
+        rsxadev->routes[route_idx].config.input_sample_rate = config->sample_rate;
         // If the output isn't configured yet, set the output sample rate to the maximum supported
-        // sample rate such that the smallest possible input buffer is created.
-        if (!rsxadev->output) {
-            rsxadev->config.output_sample_rate = 48000;
+        // sample rate such that the smallest possible input buffer is created, and put a default
+        // value for channel count
+        if (!rsxadev->routes[route_idx].output) {
+            rsxadev->routes[route_idx].config.output_sample_rate = 48000;
+            rsxadev->routes[route_idx].config.output_channel_mask = AUDIO_CHANNEL_OUT_STEREO;
         }
 #endif // ENABLE_RESAMPLING
     }
     if (out) {
-        rsxadev->output = out;
-        rsxadev->config.output_channel_mask = config->channel_mask;
+        out->route_handle = route_idx;
+        rsxadev->routes[route_idx].output = out;
+        rsxadev->routes[route_idx].config.output_channel_mask = config->channel_mask;
 #if ENABLE_RESAMPLING
-        rsxadev->config.output_sample_rate = config->sample_rate;
+        rsxadev->routes[route_idx].config.output_sample_rate = config->sample_rate;
 #endif // ENABLE_RESAMPLING
     }
+    // Save the address
+    strncpy(rsxadev->routes[route_idx].address, address, AUDIO_DEVICE_MAX_ADDRESS_LEN);
+    ALOGD("  now using address %s for route %d", rsxadev->routes[route_idx].address, route_idx);
     // 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;
+    if (rsxadev->routes[route_idx].rsxSink == NULL || rsxadev->routes[route_idx].rsxSource == NULL)
+    {
+        struct submix_config * const device_config = &rsxadev->routes[route_idx].config;
         uint32_t channel_count;
         if (out)
             channel_count = audio_channel_count_from_out_mask(config->channel_mask);
@@ -407,13 +426,13 @@
         numCounterOffers = 0;
         index = source->negotiate(offers, 1, NULL, numCounterOffers);
         ALOG_ASSERT(index == 0);
-        ALOGV("submix_audio_device_create_pipe(): created pipe");
+        ALOGV("submix_audio_device_create_pipe_l(): created pipe");
 
         // Save references to the source and sink.
-        ALOG_ASSERT(rsxadev->rsxSink == NULL);
-        ALOG_ASSERT(rsxadev->rsxSource == NULL);
-        rsxadev->rsxSink = sink;
-        rsxadev->rsxSource = source;
+        ALOG_ASSERT(rsxadev->routes[route_idx].rsxSink == NULL);
+        ALOG_ASSERT(rsxadev->routes[route_idx].rsxSource == NULL);
+        rsxadev->routes[route_idx].rsxSink = sink;
+        rsxadev->routes[route_idx].rsxSource = source;
         // Store the sanitized audio format in the device so that it's possible to determine
         // the format of the pipe source when opening the input device.
         memcpy(&device_config->common, config, sizeof(device_config->common));
@@ -427,51 +446,71 @@
         device_config->pipe_frame_size = (device_config->pipe_frame_size * pipe_channel_count) /
                 channel_count;
 #endif // ENABLE_CHANNEL_CONVERSION
-        SUBMIX_ALOGV("submix_audio_device_create_pipe(): pipe frame size %zd, pipe size %zd, "
+        SUBMIX_ALOGV("submix_audio_device_create_pipe_l(): pipe frame size %zd, pipe size %zd, "
                      "period size %zd", device_config->pipe_frame_size,
                      device_config->buffer_size_frames, device_config->buffer_period_size_frames);
     }
-    pthread_mutex_unlock(&rsxadev->lock);
 }
 
 // Release references to the sink and source.  Input and output threads may maintain references
 // to these objects via StrongPointer (sp<MonoPipe> and sp<MonoPipeReader>) which they can use
 // before they shutdown.
-static void submix_audio_device_release_pipe(struct submix_audio_device * const rsxadev)
+// Must be called with lock held on the submix_audio_device
+static void submix_audio_device_release_pipe_l(struct submix_audio_device * const rsxadev,
+        int route_idx)
 {
-    ALOGD("submix_audio_device_release_pipe()");
-    rsxadev->rsxSink.clear();
-    rsxadev->rsxSource.clear();
+    ALOG_ASSERT(route_idx > -1);
+    ALOG_ASSERT(route_idx < MAX_ROUTES);
+    ALOGD("submix_audio_device_release_pipe_l(idx=%d) addr=%s", route_idx,
+            rsxadev->routes[route_idx].address);
+    if (rsxadev->routes[route_idx].rsxSink != 0) {
+        rsxadev->routes[route_idx].rsxSink.clear();
+        rsxadev->routes[route_idx].rsxSink = 0;
+    }
+    if (rsxadev->routes[route_idx].rsxSource != 0) {
+        rsxadev->routes[route_idx].rsxSource.clear();
+        rsxadev->routes[route_idx].rsxSource = 0;
+    }
+    memset(rsxadev->routes[route_idx].address, 0, AUDIO_DEVICE_MAX_ADDRESS_LEN);
+#ifdef ENABLE_RESAMPLING
+    memset(rsxadev->routes[route_idx].resampler_buffer, 0,
+            sizeof(int16_t) * DEFAULT_PIPE_SIZE_IN_FRAMES);
+#endif
 }
 
 // Remove references to the specified input and output streams.  When the device no longer
 // references input and output streams destroy the associated pipe.
-static void submix_audio_device_destroy_pipe(struct submix_audio_device * const rsxadev,
+// Must be called with lock held on the submix_audio_device
+static void submix_audio_device_destroy_pipe_l(struct submix_audio_device * const rsxadev,
                                              const struct submix_stream_in * const in,
                                              const struct submix_stream_out * const out)
 {
     MonoPipe* sink;
-    pthread_mutex_lock(&rsxadev->lock);
-    ALOGV("submix_audio_device_destroy_pipe()");
-    ALOG_ASSERT(in == NULL || rsxadev->input == in);
-    ALOG_ASSERT(out == NULL || rsxadev->output == out);
+    ALOGV("submix_audio_device_destroy_pipe_l()");
+    int route_idx = -1;
     if (in != NULL) {
 #if ENABLE_LEGACY_INPUT_OPEN
         const_cast<struct submix_stream_in*>(in)->ref_count--;
+        route_idx = in->route_handle;
+        ALOG_ASSERT(rsxadev->routes[route_idx].input == in);
         if (in->ref_count == 0) {
-            rsxadev->input = NULL;
+            rsxadev->routes[route_idx].input = NULL;
         }
-        ALOGV("submix_audio_device_destroy_pipe(): input ref_count %d", in->ref_count);
+        ALOGV("submix_audio_device_destroy_pipe_l(): input ref_count %d", in->ref_count);
 #else
         rsxadev->input = NULL;
 #endif // ENABLE_LEGACY_INPUT_OPEN
     }
-    if (out != NULL) rsxadev->output = NULL;
-    if (rsxadev->input == NULL && rsxadev->output == NULL) {
-        submix_audio_device_release_pipe(rsxadev);
-        ALOGD("submix_audio_device_destroy_pipe(): pipe destroyed");
+    if (out != NULL) {
+        route_idx = out->route_handle;
+        ALOG_ASSERT(rsxadev->routes[route_idx].output == out);
+        rsxadev->routes[route_idx].output = NULL;
     }
-    pthread_mutex_unlock(&rsxadev->lock);
+    if (route_idx != -1 &&
+            rsxadev->routes[route_idx].input == NULL && rsxadev->routes[route_idx].output == NULL) {
+        submix_audio_device_release_pipe_l(rsxadev, route_idx);
+        ALOGD("submix_audio_device_destroy_pipe_l(): pipe destroyed");
+    }
 }
 
 // Sanitize the user specified audio config for a submix input / output stream.
@@ -484,8 +523,9 @@
 }
 
 // Verify a submix input or output stream can be opened.
-static bool submix_open_validate(const struct submix_audio_device * const rsxadev,
-                                 pthread_mutex_t * const lock,
+// Must be called with lock held on the submix_audio_device
+static bool submix_open_validate_l(const struct submix_audio_device * const rsxadev,
+                                 int route_idx,
                                  const struct audio_config * const config,
                                  const bool opening_input)
 {
@@ -494,20 +534,18 @@
     audio_config pipe_config;
 
     // Query the device for the current audio config and whether input and output streams are open.
-    pthread_mutex_lock(lock);
-    output_open = rsxadev->output != NULL;
-    input_open = rsxadev->input != NULL;
-    memcpy(&pipe_config, &rsxadev->config.common, sizeof(pipe_config));
-    pthread_mutex_unlock(lock);
+    output_open = rsxadev->routes[route_idx].output != NULL;
+    input_open = rsxadev->routes[route_idx].input != NULL;
+    memcpy(&pipe_config, &rsxadev->routes[route_idx].config.common, sizeof(pipe_config));
 
     // If the stream is already open, don't open it again.
     if (opening_input ? !ENABLE_LEGACY_INPUT_OPEN && input_open : output_open) {
-        ALOGE("submix_open_validate(): %s stream already open.", opening_input ? "Input" :
+        ALOGE("submix_open_validate_l(): %s stream already open.", opening_input ? "Input" :
                 "Output");
         return false;
     }
 
-    SUBMIX_ALOGV("submix_open_validate(): sample rate=%d format=%x "
+    SUBMIX_ALOGV("submix_open_validate_l(): sample rate=%d format=%x "
                  "%s_channel_mask=%x", config->sample_rate, config->format,
                  opening_input ? "in" : "out", config->channel_mask);
 
@@ -518,16 +556,46 @@
         const audio_config * const output_config = opening_input ? &pipe_config : config;
         // Get the channel mask of the open device.
         pipe_config.channel_mask =
-            opening_input ? rsxadev->config.output_channel_mask :
-                rsxadev->config.input_channel_mask;
+            opening_input ? rsxadev->routes[route_idx].config.output_channel_mask :
+                rsxadev->routes[route_idx].config.input_channel_mask;
         if (!audio_config_compare(input_config, output_config)) {
-            ALOGE("submix_open_validate(): Unsupported format.");
+            ALOGE("submix_open_validate_l(): Unsupported format.");
             return false;
         }
     }
     return true;
 }
 
+// Must be called with lock held on the submix_audio_device
+static status_t submix_get_route_idx_for_address_l(const struct submix_audio_device * const rsxadev,
+                                                 const char* address, /*in*/
+                                                 int *idx /*out*/)
+{
+    // Do we already have a route for this address
+    int route_idx = -1;
+    int route_empty_idx = -1; // index of an empty route slot that can be used if needed
+    for (int i=0 ; i < MAX_ROUTES ; i++) {
+        if (strcmp(rsxadev->routes[i].address, "") == 0) {
+            route_empty_idx = i;
+        }
+        if (strncmp(rsxadev->routes[i].address, address, AUDIO_DEVICE_MAX_ADDRESS_LEN) == 0) {
+            route_idx = i;
+            break;
+        }
+    }
+
+    if ((route_idx == -1) && (route_empty_idx == -1)) {
+        ALOGE("Cannot create new route for address %s, max number of routes reached", address);
+        return -ENOMEM;
+    }
+    if (route_idx == -1) {
+        route_idx = route_empty_idx;
+    }
+    *idx = route_idx;
+    return OK;
+}
+
+
 // 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,
@@ -546,11 +614,12 @@
     const struct submix_stream_out * const out = audio_stream_get_submix_stream_out(
             const_cast<struct audio_stream *>(stream));
 #if ENABLE_RESAMPLING
-    const uint32_t out_rate = out->dev->config.output_sample_rate;
+    const uint32_t out_rate = out->dev->routes[out->route_handle].config.output_sample_rate;
 #else
-    const uint32_t out_rate = out->dev->config.common.sample_rate;
+    const uint32_t out_rate = out->dev->routes[out->route_handle].config.common.sample_rate;
 #endif // ENABLE_RESAMPLING
-    SUBMIX_ALOGV("out_get_sample_rate() returns %u", out_rate);
+    SUBMIX_ALOGV("out_get_sample_rate() returns %u for addr %s",
+            out_rate, out->dev->routes[out->route_handle].address);
     return out_rate;
 }
 
@@ -560,9 +629,11 @@
 #if ENABLE_RESAMPLING
     // 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) {
+    if (rate != out->dev->routes[out->route_handle].config.output_sample_rate) {
         ALOGE("out_set_sample_rate() resampling enabled can't change sample rate from "
-              "%u to %u", out->dev->config.output_sample_rate, rate);
+              "%u to %u for addr %s",
+              out->dev->routes[out->route_handle].config.output_sample_rate, rate,
+              out->dev->routes[out->route_handle].address);
         return -ENOSYS;
     }
 #endif // ENABLE_RESAMPLING
@@ -571,7 +642,7 @@
         return -ENOSYS;
     }
     SUBMIX_ALOGV("out_set_sample_rate(rate=%u)", rate);
-    out->dev->config.common.sample_rate = rate;
+    out->dev->routes[out->route_handle].config.common.sample_rate = rate;
     return 0;
 }
 
@@ -579,7 +650,7 @@
 {
     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 struct submix_config * const config = &out->dev->routes[out->route_handle].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(
@@ -594,7 +665,7 @@
 {
     const struct submix_stream_out * const out = audio_stream_get_submix_stream_out(
             const_cast<struct audio_stream *>(stream));
-    uint32_t channel_mask = out->dev->config.output_channel_mask;
+    uint32_t channel_mask = out->dev->routes[out->route_handle].config.output_channel_mask;
     SUBMIX_ALOGV("out_get_channels() returns %08x", channel_mask);
     return channel_mask;
 }
@@ -603,7 +674,7 @@
 {
     const struct submix_stream_out * const out = audio_stream_get_submix_stream_out(
             const_cast<struct audio_stream *>(stream));
-    const audio_format_t format = out->dev->config.common.format;
+    const audio_format_t format = out->dev->routes[out->route_handle].config.common.format;
     SUBMIX_ALOGV("out_get_format() returns %x", format);
     return format;
 }
@@ -611,7 +682,7 @@
 static int out_set_format(struct audio_stream *stream, audio_format_t format)
 {
     const struct submix_stream_out * const out = audio_stream_get_submix_stream_out(stream);
-    if (format != out->dev->config.common.format) {
+    if (format != out->dev->routes[out->route_handle].config.common.format) {
         ALOGE("out_set_format(format=%x) format unsupported", format);
         return -ENOSYS;
     }
@@ -621,12 +692,13 @@
 
 static int out_standby(struct audio_stream *stream)
 {
-    struct submix_audio_device * const rsxadev = audio_stream_get_submix_stream_out(stream)->dev;
     ALOGI("out_standby()");
+    struct submix_stream_out * const out = audio_stream_get_submix_stream_out(stream);
+    struct submix_audio_device * const rsxadev = out->dev;
 
     pthread_mutex_lock(&rsxadev->lock);
 
-    rsxadev->output_standby = true;
+    out->output_standby = true;
 
     pthread_mutex_unlock(&rsxadev->lock);
 
@@ -653,7 +725,9 @@
                 audio_stream_get_submix_stream_out(stream)->dev;
         pthread_mutex_lock(&rsxadev->lock);
         { // using the sink
-            sp<MonoPipe> sink = rsxadev->rsxSink;
+            sp<MonoPipe> sink =
+                    rsxadev->routes[audio_stream_get_submix_stream_out(stream)->route_handle]
+                                    .rsxSink;
             if (sink == NULL) {
                 pthread_mutex_unlock(&rsxadev->lock);
                 return 0;
@@ -678,7 +752,7 @@
 {
     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 struct submix_config * const config = &out->dev->routes[out->route_handle].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(
@@ -711,9 +785,9 @@
 
     pthread_mutex_lock(&rsxadev->lock);
 
-    rsxadev->output_standby = false;
+    out->output_standby = false;
 
-    sp<MonoPipe> sink = rsxadev->rsxSink;
+    sp<MonoPipe> sink = rsxadev->routes[out->route_handle].rsxSink;
     if (sink != NULL) {
         if (sink->isShutdown()) {
             sink.clear();
@@ -735,8 +809,8 @@
     // from the pipe to make space to write the most recent data.
     {
         const size_t availableToWrite = sink->availableToWrite();
-        sp<MonoPipeReader> source = rsxadev->rsxSource;
-        if (rsxadev->input == NULL && availableToWrite < frames) {
+        sp<MonoPipeReader> source = rsxadev->routes[out->route_handle].rsxSource;
+        if (rsxadev->routes[out->route_handle].input == NULL && availableToWrite < frames) {
             static uint8_t flush_buffer[64];
             const size_t flushBufferSizeFrames = sizeof(flush_buffer) / frame_size;
             size_t frames_to_flush_from_source = frames - availableToWrite;
@@ -745,6 +819,7 @@
             while (frames_to_flush_from_source) {
                 const size_t flush_size = min(frames_to_flush_from_source, flushBufferSizeFrames);
                 frames_to_flush_from_source -= flush_size;
+                // read does not block
                 source->read(flush_buffer, flush_size, AudioBufferProvider::kInvalidPTS);
             }
         }
@@ -824,9 +899,9 @@
     const struct submix_stream_in * const in = audio_stream_get_submix_stream_in(
         const_cast<struct audio_stream*>(stream));
 #if ENABLE_RESAMPLING
-    const uint32_t rate = in->dev->config.input_sample_rate;
+    const uint32_t rate = in->dev->routes[in->route_handle].config.input_sample_rate;
 #else
-    const uint32_t rate = in->dev->config.common.sample_rate;
+    const uint32_t rate = in->dev->routes[in->route_handle].config.common.sample_rate;
 #endif // ENABLE_RESAMPLING
     SUBMIX_ALOGV("in_get_sample_rate() returns %u", rate);
     return rate;
@@ -838,9 +913,9 @@
 #if ENABLE_RESAMPLING
     // 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) {
+    if (rate != in->dev->routes[in->route_handle].config.input_sample_rate) {
         ALOGE("in_set_sample_rate() resampling enabled can't change sample rate from "
-              "%u to %u", in->dev->config.input_sample_rate, rate);
+              "%u to %u", in->dev->routes[in->route_handle].config.input_sample_rate, rate);
         return -ENOSYS;
     }
 #endif // ENABLE_RESAMPLING
@@ -848,7 +923,7 @@
         ALOGE("in_set_sample_rate(rate=%u) rate unsupported", rate);
         return -ENOSYS;
     }
-    in->dev->config.common.sample_rate = rate;
+    in->dev->routes[in->route_handle].config.common.sample_rate = rate;
     SUBMIX_ALOGV("in_set_sample_rate() set %u", rate);
     return 0;
 }
@@ -857,7 +932,7 @@
 {
     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 struct submix_config * const config = &in->dev->routes[in->route_handle].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(
@@ -879,7 +954,8 @@
 {
     const struct submix_stream_in * const in = audio_stream_get_submix_stream_in(
             const_cast<struct audio_stream*>(stream));
-    const audio_channel_mask_t channel_mask = in->dev->config.input_channel_mask;
+    const audio_channel_mask_t channel_mask =
+            in->dev->routes[in->route_handle].config.input_channel_mask;
     SUBMIX_ALOGV("in_get_channels() returns %x", channel_mask);
     return channel_mask;
 }
@@ -888,7 +964,7 @@
 {
     const struct submix_stream_in * const in = audio_stream_get_submix_stream_in(
             const_cast<struct audio_stream*>(stream));
-    const audio_format_t format = in->dev->config.common.format;
+    const audio_format_t format = in->dev->routes[in->route_handle].config.common.format;
     SUBMIX_ALOGV("in_get_format() returns %x", format);
     return format;
 }
@@ -896,7 +972,7 @@
 static int in_set_format(struct audio_stream *stream, audio_format_t format)
 {
     const struct submix_stream_in * const in = audio_stream_get_submix_stream_in(stream);
-    if (format != in->dev->config.common.format) {
+    if (format != in->dev->routes[in->route_handle].config.common.format) {
         ALOGE("in_set_format(format=%x) format unsupported", format);
         return -ENOSYS;
     }
@@ -906,12 +982,13 @@
 
 static int in_standby(struct audio_stream *stream)
 {
-    struct submix_audio_device * const rsxadev = audio_stream_get_submix_stream_in(stream)->dev;
     ALOGI("in_standby()");
+    struct submix_stream_in * const in = audio_stream_get_submix_stream_in(stream);
+    struct submix_audio_device * const rsxadev = in->dev;
 
     pthread_mutex_lock(&rsxadev->lock);
 
-    rsxadev->input_standby = true;
+    in->input_standby = true;
 
     pthread_mutex_unlock(&rsxadev->lock);
 
@@ -959,11 +1036,13 @@
     SUBMIX_ALOGV("in_read bytes=%zu", bytes);
     pthread_mutex_lock(&rsxadev->lock);
 
-    const bool output_standby_transition = (in->output_standby != in->dev->output_standby);
-    in->output_standby = rsxadev->output_standby;
+    const bool output_standby = rsxadev->routes[in->route_handle].output == NULL
+            ? true : rsxadev->routes[in->route_handle].output->output_standby;
+    const bool output_standby_transition = (in->output_standby_rec_thr != output_standby);
+    in->output_standby_rec_thr = output_standby;
 
-    if (rsxadev->input_standby || output_standby_transition) {
-        rsxadev->input_standby = false;
+    if (in->input_standby || output_standby_transition) {
+        in->input_standby = false;
         // keep track of when we exit input standby (== first read == start "real recording")
         // or when we start recording silence, and reset projected time
         int rc = clock_gettime(CLOCK_MONOTONIC, &in->record_start_time);
@@ -977,7 +1056,7 @@
 
     {
         // about to read from audio source
-        sp<MonoPipeReader> source = rsxadev->rsxSource;
+        sp<MonoPipeReader> source = rsxadev->routes[in->route_handle].rsxSource;
         if (source == NULL) {
             in->read_error_count++;// ok if it rolls over
             ALOGE_IF(in->read_error_count < MAX_READ_ERROR_LOGS,
@@ -996,14 +1075,15 @@
 #if ENABLE_CHANNEL_CONVERSION
         // Determine whether channel conversion is required.
         const uint32_t input_channels = audio_channel_count_from_in_mask(
-            rsxadev->config.input_channel_mask);
+            rsxadev->routes[in->route_handle].config.input_channel_mask);
         const uint32_t output_channels = audio_channel_count_from_out_mask(
-            rsxadev->config.output_channel_mask);
+            rsxadev->routes[in->route_handle].config.output_channel_mask);
         if (input_channels != output_channels) {
             SUBMIX_ALOGV("in_read(): %d output channels will be converted to %d "
                          "input channels", output_channels, input_channels);
             // Only support 16-bit PCM channel conversion from mono to stereo or stereo to mono.
-            ALOG_ASSERT(rsxadev->config.common.format == AUDIO_FORMAT_PCM_16_BIT);
+            ALOG_ASSERT(rsxadev->routes[in->route_handle].config.common.format ==
+                    AUDIO_FORMAT_PCM_16_BIT);
             ALOG_ASSERT((input_channels == 1 && output_channels == 2) ||
                         (input_channels == 2 && output_channels == 1));
         }
@@ -1011,17 +1091,21 @@
 
 #if ENABLE_RESAMPLING
         const uint32_t input_sample_rate = in_get_sample_rate(&stream->common);
-        const uint32_t output_sample_rate = rsxadev->config.output_sample_rate;
+        const uint32_t output_sample_rate =
+                rsxadev->routes[in->route_handle].config.output_sample_rate;
         const size_t resampler_buffer_size_frames =
-            sizeof(rsxadev->resampler_buffer) / sizeof(rsxadev->resampler_buffer[0]);
+            sizeof(rsxadev->routes[in->route_handle].resampler_buffer) /
+                sizeof(rsxadev->routes[in->route_handle].resampler_buffer[0]);
         float resampler_ratio = 1.0f;
         // Determine whether resampling is required.
         if (input_sample_rate != output_sample_rate) {
             resampler_ratio = (float)output_sample_rate / (float)input_sample_rate;
             // 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(audio_channel_count_from_in_mask(rsxadev->config.input_channel_mask) == 1);
+            ALOG_ASSERT(rsxadev->routes[in->route_handle].config.common.format ==
+                    AUDIO_FORMAT_PCM_16_BIT);
+            ALOG_ASSERT(audio_channel_count_from_in_mask(
+                    rsxadev->routes[in->route_handle].config.input_channel_mask) == 1);
         }
 #endif // ENABLE_RESAMPLING
 
@@ -1037,7 +1121,7 @@
                     (float)read_frames * (float)resampler_ratio);
                 read_frames = min(frames_required_for_resampler, resampler_buffer_size_frames);
                 // Read into the resampler buffer.
-                buff = (char*)rsxadev->resampler_buffer;
+                buff = (char*)rsxadev->routes[in->route_handle].resampler_buffer;
             }
 #endif // ENABLE_RESAMPLING
 #if ENABLE_CHANNEL_CONVERSION
@@ -1195,10 +1279,10 @@
                                    audio_output_flags_t flags,
                                    struct audio_config *config,
                                    struct audio_stream_out **stream_out,
-                                   const char *address __unused)
+                                   const char *address)
 {
     struct submix_audio_device * const rsxadev = audio_hw_device_get_submix_audio_device(dev);
-    ALOGD("adev_open_output_stream()");
+    ALOGD("adev_open_output_stream(address=%s)", address);
     struct submix_stream_out *out;
     bool force_pipe_creation = false;
     (void)handle;
@@ -1209,13 +1293,29 @@
 
     // Make sure it's possible to open the device given the current audio config.
     submix_sanitize_config(config, false);
-    if (!submix_open_validate(rsxadev, &rsxadev->lock, config, false)) {
-        ALOGE("adev_open_output_stream(): Unable to open output stream.");
+
+    int route_idx = -1;
+
+    pthread_mutex_lock(&rsxadev->lock);
+
+    status_t res = submix_get_route_idx_for_address_l(rsxadev, address, &route_idx);
+    if (res != OK) {
+        ALOGE("Error %d looking for address=%s in adev_open_output_stream", res, address);
+        pthread_mutex_unlock(&rsxadev->lock);
+        return res;
+    }
+
+    if (!submix_open_validate_l(rsxadev, route_idx, config, false)) {
+        ALOGE("adev_open_output_stream(): Unable to open output stream for address %s", address);
+        pthread_mutex_unlock(&rsxadev->lock);
         return -EINVAL;
     }
 
     out = (struct submix_stream_out *)calloc(1, sizeof(struct submix_stream_out));
-    if (!out) return -ENOMEM;
+    if (!out) {
+        pthread_mutex_unlock(&rsxadev->lock);
+        return -ENOMEM;
+    }
 
     // Initialize the function pointer tables (v-tables).
     out->stream.common.get_sample_rate = out_get_sample_rate;
@@ -1239,23 +1339,23 @@
 #if ENABLE_RESAMPLING
     // Recreate the pipe with the correct sample rate so that MonoPipe.write() rate limits
     // writes correctly.
-    force_pipe_creation = rsxadev->config.common.sample_rate != config->sample_rate;
+    force_pipe_creation = rsxadev->routes[route_idx].config.common.sample_rate
+            != config->sample_rate;
 #endif // ENABLE_RESAMPLING
 
     // If the sink has been shutdown or pipe recreation is forced (see above), delete the pipe so
     // that it's recreated.
-    pthread_mutex_lock(&rsxadev->lock);
-    if ((rsxadev->rsxSink != NULL && rsxadev->rsxSink->isShutdown()) || force_pipe_creation) {
-        submix_audio_device_release_pipe(rsxadev);
+    if ((rsxadev->routes[route_idx].rsxSink != NULL
+            && rsxadev->routes[route_idx].rsxSink->isShutdown()) || force_pipe_creation) {
+        submix_audio_device_release_pipe_l(rsxadev, route_idx);
     }
-    pthread_mutex_unlock(&rsxadev->lock);
 
     // Store a pointer to the device from the output stream.
     out->dev = rsxadev;
     // Initialize the pipe.
-    ALOGV("adev_open_output_stream(): about to create pipe");
-    submix_audio_device_create_pipe(rsxadev, config, DEFAULT_PIPE_SIZE_IN_FRAMES,
-                                    DEFAULT_PIPE_PERIOD_COUNT, NULL, out);
+    ALOGV("adev_open_output_stream(): about to create pipe at index %d", route_idx);
+    submix_audio_device_create_pipe_l(rsxadev, config, DEFAULT_PIPE_SIZE_IN_FRAMES,
+            DEFAULT_PIPE_PERIOD_COUNT, NULL, out, address, route_idx);
 #if LOG_STREAMS_TO_FILES
     out->log_fd = open(LOG_STREAM_OUT_FILENAME, O_CREAT | O_TRUNC | O_WRONLY,
                        LOG_STREAM_FILE_PERMISSIONS);
@@ -1266,18 +1366,25 @@
     // Return the output stream.
     *stream_out = &out->stream;
 
+    pthread_mutex_unlock(&rsxadev->lock);
     return 0;
 }
 
 static void adev_close_output_stream(struct audio_hw_device *dev,
                                      struct audio_stream_out *stream)
 {
+    struct submix_audio_device * rsxadev = audio_hw_device_get_submix_audio_device(
+                    const_cast<struct audio_hw_device*>(dev));
     struct submix_stream_out * const out = audio_stream_out_get_submix_stream_out(stream);
-    ALOGD("adev_close_output_stream()");
-    submix_audio_device_destroy_pipe(audio_hw_device_get_submix_audio_device(dev), NULL, out);
+
+    pthread_mutex_lock(&rsxadev->lock);
+    ALOGD("adev_close_output_stream() addr = %s", rsxadev->routes[out->route_handle].address);
+    submix_audio_device_destroy_pipe_l(audio_hw_device_get_submix_audio_device(dev), NULL, out);
 #if LOG_STREAMS_TO_FILES
     if (out->log_fd >= 0) close(out->log_fd);
 #endif // LOG_STREAMS_TO_FILES
+
+    pthread_mutex_unlock(&rsxadev->lock);
     free(out);
 }
 
@@ -1363,12 +1470,19 @@
                                          const struct audio_config *config)
 {
     if (audio_is_linear_pcm(config->format)) {
-        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;
+        size_t max_buffer_period_size_frames = 0;
+        struct submix_audio_device * rsxadev = audio_hw_device_get_submix_audio_device(
+                const_cast<struct audio_hw_device*>(dev));
+        // look for the largest buffer period size
+        for (int i = 0 ; i < MAX_ROUTES ; i++) {
+            if (rsxadev->routes[i].config.buffer_period_size_frames > max_buffer_period_size_frames)
+            {
+                max_buffer_period_size_frames = rsxadev->routes[i].config.buffer_period_size_frames;
+            }
+        }
         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;
+        const size_t buffer_size = max_buffer_period_size_frames * frame_size_in_bytes;
         SUBMIX_ALOGV("adev_get_input_buffer_size() returns %zu bytes, %zu frames",
                  buffer_size, buffer_period_size_frames);
         return buffer_size;
@@ -1382,37 +1496,49 @@
                                   struct audio_config *config,
                                   struct audio_stream_in **stream_in,
                                   audio_input_flags_t flags __unused,
-                                  const char *address __unused,
+                                  const char *address,
                                   audio_source_t source __unused)
 {
     struct submix_audio_device *rsxadev = audio_hw_device_get_submix_audio_device(dev);
     struct submix_stream_in *in;
-    ALOGD("adev_open_input_stream()");
+    ALOGD("adev_open_input_stream(addr=%s)", address);
     (void)handle;
     (void)devices;
 
     *stream_in = NULL;
 
+    // Do we already have a route for this address
+    int route_idx = -1;
+
+    pthread_mutex_lock(&rsxadev->lock);
+
+    status_t res = submix_get_route_idx_for_address_l(rsxadev, address, &route_idx);
+    if (res != OK) {
+        ALOGE("Error %d looking for address=%s in adev_open_output_stream", res, address);
+        pthread_mutex_unlock(&rsxadev->lock);
+        return res;
+    }
+
     // Make sure it's possible to open the device given the current audio config.
     submix_sanitize_config(config, true);
-    if (!submix_open_validate(rsxadev, &rsxadev->lock, config, true)) {
+    if (!submix_open_validate_l(rsxadev, route_idx, config, true)) {
         ALOGE("adev_open_input_stream(): Unable to open input stream.");
+        pthread_mutex_unlock(&rsxadev->lock);
         return -EINVAL;
     }
 
 #if ENABLE_LEGACY_INPUT_OPEN
-    pthread_mutex_lock(&rsxadev->lock);
-    in = rsxadev->input;
+    in = rsxadev->routes[route_idx].input;
     if (in) {
         in->ref_count++;
-        sp<MonoPipe> sink = rsxadev->rsxSink;
+        sp<MonoPipe> sink = rsxadev->routes[route_idx].rsxSink;
         ALOG_ASSERT(sink != NULL);
         // If the sink has been shutdown, delete the pipe.
         if (sink != NULL) {
             if (sink->isShutdown()) {
                 ALOGD(" Non-NULL shut down sink when opening input stream, releasing, refcount=%d",
                         in->ref_count);
-                submix_audio_device_release_pipe(rsxadev);
+                submix_audio_device_release_pipe_l(rsxadev, in->route_handle);
             } else {
                 ALOGD(" Non-NULL sink when opening input stream, refcount=%d", in->ref_count);
             }
@@ -1420,7 +1546,6 @@
             ALOGE("NULL sink when opening input stream, refcount=%d", in->ref_count);
         }
     }
-    pthread_mutex_unlock(&rsxadev->lock);
 #else
     in = NULL;
 #endif // ENABLE_LEGACY_INPUT_OPEN
@@ -1446,18 +1571,29 @@
         in->stream.set_gain = in_set_gain;
         in->stream.read = in_read;
         in->stream.get_input_frames_lost = in_get_input_frames_lost;
+
+        in->dev = rsxadev;
+#if LOG_STREAMS_TO_FILES
+        in->log_fd = -1;
+#endif
     }
 
     // Initialize the input stream.
     in->read_counter_frames = 0;
-    in->output_standby = rsxadev->output_standby;
-    in->dev = rsxadev;
+    in->input_standby = true;
+    if (rsxadev->routes[route_idx].output != NULL) {
+        in->output_standby_rec_thr = rsxadev->routes[route_idx].output->output_standby;
+    } else {
+        in->output_standby_rec_thr = true;
+    }
+
     in->read_error_count = 0;
     // Initialize the pipe.
     ALOGV("adev_open_input_stream(): about to create pipe");
-    submix_audio_device_create_pipe(rsxadev, config, DEFAULT_PIPE_SIZE_IN_FRAMES,
-                                    DEFAULT_PIPE_PERIOD_COUNT, in, NULL);
+    submix_audio_device_create_pipe_l(rsxadev, config, DEFAULT_PIPE_SIZE_IN_FRAMES,
+                                    DEFAULT_PIPE_PERIOD_COUNT, in, NULL, address, route_idx);
 #if LOG_STREAMS_TO_FILES
+    if (in->log_fd >= 0) close(in->log_fd);
     in->log_fd = open(LOG_STREAM_IN_FILENAME, O_CREAT | O_TRUNC | O_WRONLY,
                       LOG_STREAM_FILE_PERMISSIONS);
     ALOGE_IF(in->log_fd < 0, "adev_open_input_stream(): log file open failed %s",
@@ -1467,15 +1603,19 @@
     // Return the input stream.
     *stream_in = &in->stream;
 
+    pthread_mutex_unlock(&rsxadev->lock);
     return 0;
 }
 
 static void adev_close_input_stream(struct audio_hw_device *dev,
                                     struct audio_stream_in *stream)
 {
+    struct submix_audio_device * const rsxadev = audio_hw_device_get_submix_audio_device(dev);
+
     struct submix_stream_in * const in = audio_stream_in_get_submix_stream_in(stream);
     ALOGD("adev_close_input_stream()");
-    submix_audio_device_destroy_pipe(audio_hw_device_get_submix_audio_device(dev), in, NULL);
+    pthread_mutex_lock(&rsxadev->lock);
+    submix_audio_device_destroy_pipe_l(rsxadev, in, NULL);
 #if LOG_STREAMS_TO_FILES
     if (in->log_fd >= 0) close(in->log_fd);
 #endif // LOG_STREAMS_TO_FILES
@@ -1484,12 +1624,26 @@
 #else
     free(in);
 #endif // ENABLE_LEGACY_INPUT_OPEN
+
+    pthread_mutex_unlock(&rsxadev->lock);
 }
 
 static int adev_dump(const audio_hw_device_t *device, int fd)
 {
-    (void)device;
-    (void)fd;
+    const struct submix_audio_device * rsxadev = //audio_hw_device_get_submix_audio_device(device);
+            reinterpret_cast<const struct submix_audio_device *>(
+                    reinterpret_cast<const uint8_t *>(device) -
+                            offsetof(struct submix_audio_device, device));
+    char msg[100];
+    int n = sprintf(msg, "\nReroute submix audio module:\n");
+    write(fd, &msg, n);
+    for (int i=0 ; i < MAX_ROUTES ; i++) {
+        n = sprintf(msg, " route[%d] rate in=%d out=%d, addr=[%s]\n", i,
+                rsxadev->routes[i].config.input_sample_rate,
+                rsxadev->routes[i].config.output_sample_rate,
+                rsxadev->routes[i].address);
+        write(fd, &msg, n);
+    }
     return 0;
 }
 
@@ -1536,8 +1690,10 @@
     rsxadev->device.close_input_stream = adev_close_input_stream;
     rsxadev->device.dump = adev_dump;
 
-    rsxadev->input_standby = true;
-    rsxadev->output_standby = true;
+    for (int i=0 ; i < MAX_ROUTES ; i++) {
+            memset(&rsxadev->routes[i], 0, sizeof(route_config));
+            strcpy(rsxadev->routes[i].address, "");
+        }
 
     *device = &rsxadev->device.common;
 
diff --git a/modules/sensors/multihal.cpp b/modules/sensors/multihal.cpp
index 76ec161..cd67f6d 100644
--- a/modules/sensors/multihal.cpp
+++ b/modules/sensors/multihal.cpp
@@ -28,6 +28,7 @@
 
 #include <vector>
 #include <map>
+#include <string>
 
 #include <stdio.h>
 #include <dlfcn.h>
@@ -250,13 +251,41 @@
     }
 }
 
+// Android L requires sensor HALs to be either 1_0 or 1_3 compliant
+#define HAL_VERSION_IS_COMPLIANT(version)  \
+    (version == SENSORS_DEVICE_API_VERSION_1_0 || version >= SENSORS_DEVICE_API_VERSION_1_3)
+
+// Returns true if HAL is compliant, false if HAL is not compliant or if handle is invalid
+static bool halIsCompliant(sensors_poll_context_t *ctx, int handle) {
+    int version = ctx->get_device_version_by_handle(handle);
+    return version != -1 && HAL_VERSION_IS_COMPLIANT(version);
+}
+
+const char *apiNumToStr(int version) {
+    switch(version) {
+    case SENSORS_DEVICE_API_VERSION_1_0:
+        return "SENSORS_DEVICE_API_VERSION_1_0";
+    case SENSORS_DEVICE_API_VERSION_1_1:
+        return "SENSORS_DEVICE_API_VERSION_1_1";
+    case SENSORS_DEVICE_API_VERSION_1_2:
+        return "SENSORS_DEVICE_API_VERSION_1_2";
+    case SENSORS_DEVICE_API_VERSION_1_3:
+        return "SENSORS_DEVICE_API_VERSION_1_3";
+    default:
+        return "UNKNOWN";
+    }
+}
+
 int sensors_poll_context_t::activate(int handle, int enabled) {
     int retval = -EINVAL;
     ALOGV("activate");
     int local_handle = get_local_handle(handle);
     sensors_poll_device_t* v0 = this->get_v0_device_by_handle(handle);
-    if (local_handle >= 0 && v0) {
+    if (halIsCompliant(this, handle) && local_handle >= 0 && v0) {
         retval = v0->activate(v0, local_handle, enabled);
+    } else {
+        ALOGE("IGNORING activate(enable %d) call to non-API-compliant sensor handle=%d !",
+                enabled, handle);
     }
     ALOGV("retval %d", retval);
     return retval;
@@ -267,8 +296,10 @@
     ALOGV("setDelay");
     int local_handle = get_local_handle(handle);
     sensors_poll_device_t* v0 = this->get_v0_device_by_handle(handle);
-    if (local_handle >= 0 && v0) {
+    if (halIsCompliant(this, handle) && local_handle >= 0 && v0) {
         retval = v0->setDelay(v0, local_handle, ns);
+    } else {
+        ALOGE("IGNORING setDelay() call for non-API-compliant sensor handle=%d !", handle);
     }
     ALOGV("retval %d", retval);
     return retval;
@@ -341,11 +372,12 @@
 int sensors_poll_context_t::batch(int handle, int flags, int64_t period_ns, int64_t timeout) {
     ALOGV("batch");
     int retval = -EINVAL;
-    int version = this->get_device_version_by_handle(handle);
     int local_handle = get_local_handle(handle);
     sensors_poll_device_1_t* v1 = this->get_v1_device_by_handle(handle);
-    if (version >= SENSORS_DEVICE_API_VERSION_1_0 && local_handle >= 0 && v1) {
+    if (halIsCompliant(this, handle) && local_handle >= 0 && v1) {
         retval = v1->batch(v1, local_handle, flags, period_ns, timeout);
+    } else {
+        ALOGE("IGNORING batch() call to non-API-compliant sensor handle=%d !", handle);
     }
     ALOGV("retval %d", retval);
     return retval;
@@ -354,11 +386,12 @@
 int sensors_poll_context_t::flush(int handle) {
     ALOGV("flush");
     int retval = -EINVAL;
-    int version = this->get_device_version_by_handle(handle);
     int local_handle = get_local_handle(handle);
     sensors_poll_device_1_t* v1 = this->get_v1_device_by_handle(handle);
-    if (version >= SENSORS_DEVICE_API_VERSION_1_0 && local_handle >= 0 && v1) {
+    if (halIsCompliant(this, handle) && local_handle >= 0 && v1) {
         retval = v1->flush(v1, local_handle);
+    } else {
+        ALOGE("IGNORING flush() call to non-API-compliant sensor handle=%d !", handle);
     }
     ALOGV("retval %d", retval);
     return retval;
@@ -577,7 +610,7 @@
     ALOGV("end lazy_init_sensors_list");
 }
 
-static int module__get_sensors_list(struct sensors_module_t* module,
+static int module__get_sensors_list(__unused struct sensors_module_t* module,
         struct sensor_t const** list) {
     ALOGV("module__get_sensors_list start");
     lazy_init_sensors_list();
@@ -618,7 +651,7 @@
     sensors_poll_context_t *dev = new sensors_poll_context_t();
     memset(dev, 0, sizeof(sensors_poll_device_1_t));
     dev->proxy_device.common.tag = HARDWARE_DEVICE_TAG;
-    dev->proxy_device.common.version = SENSORS_DEVICE_API_VERSION_1_1;
+    dev->proxy_device.common.version = SENSORS_DEVICE_API_VERSION_1_3;
     dev->proxy_device.common.module = const_cast<hw_module_t*>(hw_module);
     dev->proxy_device.common.close = device__close;
     dev->proxy_device.activate = device__activate;
@@ -635,8 +668,15 @@
         sensors_module_t *sensors_module = (sensors_module_t*) *it;
         struct hw_device_t* sub_hw_device;
         int sub_open_result = sensors_module->common.methods->open(*it, name, &sub_hw_device);
-        if (!sub_open_result)
+        if (!sub_open_result) {
+            if (!HAL_VERSION_IS_COMPLIANT(sub_hw_device->version)) {
+                ALOGE("SENSORS_DEVICE_API_VERSION_1_3 is required for all sensor HALs");
+                ALOGE("This HAL reports non-compliant API level : %s",
+                        apiNumToStr(sub_hw_device->version));
+                ALOGE("Sensors belonging to this HAL will get ignored !");
+            }
             dev->addSubHwDevice(sub_hw_device);
+        }
     }
 
     // Prepare the output param and return
diff --git a/modules/usbaudio/alsa_device_profile.c b/modules/usbaudio/alsa_device_profile.c
index c7df00c..8e84471 100644
--- a/modules/usbaudio/alsa_device_profile.c
+++ b/modules/usbaudio/alsa_device_profile.c
@@ -58,10 +58,9 @@
 static const unsigned std_sample_rates[] =
     {48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000};
 
-void profile_init(alsa_device_profile* profile, int direction)
+static void profile_reset(alsa_device_profile* profile)
 {
     profile->card = profile->device = -1;
-    profile->direction = direction;
 
     /* Fill the attribute arrays with invalid values */
     size_t index;
@@ -83,6 +82,12 @@
     profile->is_valid = false;
 }
 
+void profile_init(alsa_device_profile* profile, int direction)
+{
+    profile->direction = direction;
+    profile_reset(profile);
+}
+
 bool profile_is_initialized(alsa_device_profile* profile)
 {
     return profile->card >= 0 && profile->device >= 0;
@@ -97,7 +102,7 @@
 }
 
 void profile_decache(alsa_device_profile* profile) {
-    profile->card = profile->device = -1;
+    profile_reset(profile);
 }
 
 /*
@@ -275,28 +280,19 @@
 
 static unsigned profile_enum_channel_counts(alsa_device_profile* profile, unsigned min, unsigned max)
 {
-    // TODO: Don't return MONO even if the device supports it. This causes problems
-    // in AudioPolicyManager. Revisit.
-    static const unsigned std_out_channel_counts[] = {8, 4, 2/*, 1*/};
-    static const unsigned std_in_channel_counts[] = {8, 4, 2, 1};
-
-    unsigned * channel_counts =
-        profile->direction == PCM_OUT ? std_out_channel_counts : std_in_channel_counts;
-    unsigned num_channel_counts =
-        profile->direction == PCM_OUT
-            ? ARRAY_SIZE(std_out_channel_counts) : ARRAY_SIZE(std_in_channel_counts);
+    static const unsigned std_channel_counts[] = {8, 4, 2, 1};
 
     unsigned num_counts = 0;
     unsigned index;
     /* TODO write a profile_test_channel_count() */
     /* Ensure there is at least one invalid channel count to terminate the channel counts array */
-    for (index = 0; index < num_channel_counts &&
+    for (index = 0; index < ARRAY_SIZE(std_channel_counts) &&
                     num_counts < ARRAY_SIZE(profile->channel_counts) - 1;
          index++) {
         /* TODO Do we want a channel counts test? */
-        if (channel_counts[index] >= min && channel_counts[index] <= max /* &&
+        if (std_channel_counts[index] >= min && std_channel_counts[index] <= max /* &&
             profile_test_channel_count(profile, channel_counts[index])*/) {
-            profile->channel_counts[num_counts++] = channel_counts[index];
+            profile->channel_counts[num_counts++] = std_channel_counts[index];
         }
     }
 
@@ -459,6 +455,7 @@
     };
 
     const bool isOutProfile = profile->direction == PCM_OUT;
+
     const char * const * const names_array = isOutProfile ? out_chans_strs : in_chans_strs;
     const size_t names_size = isOutProfile ? ARRAY_SIZE(out_chans_strs)
             : ARRAY_SIZE(in_chans_strs);
@@ -467,12 +464,17 @@
     buffer[0] = '\0';
     const int buffer_size = ARRAY_SIZE(buffer);
     int num_entries = 0;
-    bool stereo_allowed = false;
+    /* We currently support MONO and STEREO, and always report STEREO but some (many)
+     * USB Audio Devices may only announce support for MONO (a headset mic for example), or
+     * The total number of output channels. SO, if the device itself doesn't explicitly
+     * support STEREO, append to the channel config strings we are generating.
+     */
+    bool stereo_present = false;
     unsigned index;
     unsigned channel_count;
 
     for (index = 0; (channel_count = profile->channel_counts[index]) != 0; index++) {
-        stereo_allowed = stereo_allowed || channel_count == 2;
+        stereo_present = stereo_present || channel_count == 2;
         if (channel_count < names_size && names_array[channel_count] != NULL) {
             if (num_entries++ != 0) {
                 strncat(buffer, "|", buffer_size);
@@ -480,14 +482,16 @@
             strncat(buffer, names_array[channel_count], buffer_size);
         }
     }
+
     /* emulated modes:
      * always expose stereo as we can emulate it for PCM_OUT
      */
-    if (!stereo_allowed && isOutProfile) {
+    if (!stereo_present) {
         if (num_entries++ != 0) {
             strncat(buffer, "|", buffer_size);
         }
         strncat(buffer, names_array[2], buffer_size); /* stereo */
     }
+
     return strdup(buffer);
 }
diff --git a/modules/usbaudio/audio_hw.c b/modules/usbaudio/audio_hw.c
index 78fa7c5..ad01833 100644
--- a/modules/usbaudio/audio_hw.c
+++ b/modules/usbaudio/audio_hw.c
@@ -104,9 +104,11 @@
     alsa_device_profile * profile;
     alsa_device_proxy proxy;            /* state of the stream */
 
-    // not used?
-    // struct audio_config hal_pcm_config;
-
+    unsigned hal_channel_count;         /* channel count exposed to AudioFlinger.
+                                         * This may differ from the device channel count when
+                                         * the device is not compatible with AudioFlinger
+                                         * capabilities, e.g. exposes too many channels or
+                                         * too few channels. */
     /* We may need to read more data from the device in order to data reduce to 16bit, 4chan */
     void * conversion_buffer;           /* any conversions are put into here
                                          * they could come from here too if
@@ -623,25 +625,13 @@
 static size_t in_get_buffer_size(const struct audio_stream *stream)
 {
     const struct stream_in * in = ((const struct stream_in*)stream);
-    size_t buffer_size =
-        proxy_get_period_size(&in->proxy) * audio_stream_in_frame_size(&(in->stream));
-    ALOGV("in_get_buffer_size() = %zd", buffer_size);
-
-    return buffer_size;
+    return proxy_get_period_size(&in->proxy) * audio_stream_in_frame_size(&(in->stream));
 }
 
 static uint32_t in_get_channels(const struct audio_stream *stream)
 {
-    /* TODO Here is the code we need when we support arbitrary channel counts
-     * alsa_device_proxy * proxy = ((struct stream_in*)stream)->proxy;
-     * unsigned channel_count = proxy_get_channel_count(proxy);
-     * uint32_t channel_mask = audio_channel_in_mask_from_count(channel_count);
-     * ALOGV("in_get_channels() = 0x%X count:%d", channel_mask, channel_count);
-     * return channel_mask;
-     */
-    /* TODO When AudioPolicyManager & AudioFlinger supports arbitrary channels
-     rewrite this to return the ACTUAL channel format */
-    return AUDIO_CHANNEL_IN_STEREO;
+    const struct stream_in *in = (const struct stream_in*)stream;
+    return audio_channel_in_mask_from_count(in->hal_channel_count);
 }
 
 static audio_format_t in_get_format(const struct audio_stream *stream)
@@ -785,6 +775,7 @@
     size_t num_read_buff_bytes = 0;
     void * read_buff = buffer;
     void * out_buff = buffer;
+    int ret = 0;
 
     struct stream_in * in = (struct stream_in *)stream;
 
@@ -808,7 +799,7 @@
      */
     num_read_buff_bytes = bytes;
     int num_device_channels = proxy_get_channel_count(&in->proxy);
-    int num_req_channels = 2; /* always, for now */
+    int num_req_channels = in->hal_channel_count;
 
     if (num_device_channels != num_req_channels) {
         num_read_buff_bytes = (num_device_channels * num_read_buff_bytes) / num_req_channels;
@@ -834,7 +825,8 @@
         read_buff = in->conversion_buffer;
     }
 
-    if (proxy_read(&in->proxy, read_buff, num_read_buff_bytes) == 0) {
+    ret = proxy_read(&in->proxy, read_buff, num_read_buff_bytes);
+    if (ret == 0) {
         /*
          * 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.
@@ -878,7 +870,7 @@
         if (num_read_buff_bytes > 0 && in->dev->mic_muted)
             memset(buffer, 0, num_read_buff_bytes);
     } else {
-        num_read_buff_bytes = 0;
+        num_read_buff_bytes = 0; // reset the value after USB headset is unplugged
     }
 
 err:
@@ -964,19 +956,18 @@
         ret = -EINVAL;
     }
 
-    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;
+    /* Channels */
+    unsigned proposed_channel_count = profile_get_default_channel_count(in->profile);
+    if (k_force_channels) {
+        proposed_channel_count = k_force_channels;
+    } else if (config->channel_mask != AUDIO_CHANNEL_NONE) {
+        proposed_channel_count = audio_channel_count_from_in_mask(config->channel_mask);
     }
-    // proxy_config.channels = 0;  /* don't change */
-    proxy_config.channels = profile_get_default_channel_count(in->profile);
 
+    /* we can expose any channel count mask, and emulate internally. */
+    config->channel_mask = audio_channel_in_mask_from_count(proposed_channel_count);
+    in->hal_channel_count = proposed_channel_count;
+    proxy_config.channels = profile_get_default_channel_count(in->profile);
     proxy_prepare(&in->proxy, in->profile, &proxy_config);
 
     in->standby = true;
diff --git a/tests/camera2/CameraBurstTests.cpp b/tests/camera2/CameraBurstTests.cpp
index 560fca5..198c0c1 100644
--- a/tests/camera2/CameraBurstTests.cpp
+++ b/tests/camera2/CameraBurstTests.cpp
@@ -311,8 +311,7 @@
  *   $ setenv CAMERA2_TEST_VARIABLE_BURST_DUMP_FRAMES 1
  *   $ /data/nativetest/camera2_test/camera2_test --gtest_filter="*VariableBurst"
  */
-// Disable this test for now, as we need cleanup the usage of the deprecated tag quite a bit.
-TEST_F(CameraBurstTest, DISABLED_VariableBurst) {
+TEST_F(CameraBurstTest, VariableBurst) {
 
     TEST_EXTENSION_FORKING_INIT;
 
@@ -413,34 +412,38 @@
     dout << std::endl;
 
     {
-        camera_metadata_ro_entry availableProcessedSizes =
-                GetStaticEntry(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES);
+        if (getDeviceVersion() < CAMERA_DEVICE_API_VERSION_3_2) {
+            camera_metadata_ro_entry availableProcessedSizes =
+                    GetStaticEntry(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES);
 
-        camera_metadata_ro_entry availableProcessedMinFrameDurations =
-                GetStaticEntry(ANDROID_SCALER_AVAILABLE_PROCESSED_MIN_DURATIONS);
+            camera_metadata_ro_entry availableProcessedMinFrameDurations =
+                    GetStaticEntry(ANDROID_SCALER_AVAILABLE_PROCESSED_MIN_DURATIONS);
 
-        EXPECT_EQ(availableProcessedSizes.count,
-                availableProcessedMinFrameDurations.count * 2) <<
-                "The number of minimum frame durations doesn't match the number of "
-                "available sizes. Using fallback values";
+            EXPECT_EQ(availableProcessedSizes.count,
+                    availableProcessedMinFrameDurations.count * 2) <<
+                    "The number of minimum frame durations doesn't match the number of "
+                    "available sizes. Using fallback values";
 
-        if (availableProcessedSizes.count ==
-                availableProcessedMinFrameDurations.count * 2) {
-            bool gotSize = false;
-            for (size_t i = 0; i < availableProcessedSizes.count; i += 2) {
-                if (availableProcessedSizes.data.i32[i] == mWidth &&
-                        availableProcessedSizes.data.i32[i+1] == mHeight) {
-                    gotSize = true;
-                    minDuration = availableProcessedMinFrameDurations.data.i64[i/2];
+            if (availableProcessedSizes.count ==
+                    availableProcessedMinFrameDurations.count * 2) {
+                bool gotSize = false;
+                for (size_t i = 0; i < availableProcessedSizes.count; i += 2) {
+                    if (availableProcessedSizes.data.i32[i] == mWidth &&
+                            availableProcessedSizes.data.i32[i+1] == mHeight) {
+                        gotSize = true;
+                        minDuration = availableProcessedMinFrameDurations.data.i64[i/2];
+                    }
                 }
+                EXPECT_TRUE(gotSize) << "Can't find stream size in list of "
+                        "available sizes: " << mWidth << ", " << mHeight;
             }
-            EXPECT_TRUE(gotSize) << "Can't find stream size in list of "
-                    "available sizes: " << mWidth << ", " << mHeight;
+            if (minDuration == 0) {
+                minDuration = 1 * SEC / 30; // Fall back to 30 fps as minimum duration
+            }
+        } else {
+            minDuration = getMinFrameDurationFor(
+                    HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, mWidth, mHeight);
         }
-        if (minDuration == 0) {
-            minDuration = 1 * SEC / 30; // Fall back to 30 fps as minimum duration
-        }
-
         ASSERT_LT(0, minDuration);
 
         camera_metadata_ro_entry maxFrameDuration =
diff --git a/tests/camera2/CameraMetadataTests.cpp b/tests/camera2/CameraMetadataTests.cpp
index eddc593..94fa911 100644
--- a/tests/camera2/CameraMetadataTests.cpp
+++ b/tests/camera2/CameraMetadataTests.cpp
@@ -162,27 +162,34 @@
 TEST_F(CameraMetadataTest, SaneResolutions) {
     TEST_EXTENSION_FORKING_INIT;
 
-    // Iff there are listed raw resolutions, the format should be available
-    int rawResolutionsCount =
-            GetEntryCountFromStaticTag(ANDROID_SCALER_AVAILABLE_RAW_SIZES);
-    if (rawResolutionsCount > 0) {
-        EXPECT_TRUE(
-            HasElementInArrayFromStaticTag(ANDROID_SCALER_AVAILABLE_FORMATS,
-                    HAL_PIXEL_FORMAT_RAW_SENSOR));
+    if (getDeviceVersion() < CAMERA_DEVICE_API_VERSION_3_2) {
+        // Iff there are listed raw resolutions, the format should be available
+        int rawResolutionsCount =
+                GetEntryCountFromStaticTag(ANDROID_SCALER_AVAILABLE_RAW_SIZES);
+        if (rawResolutionsCount > 0) {
+            EXPECT_TRUE(
+                HasElementInArrayFromStaticTag(ANDROID_SCALER_AVAILABLE_FORMATS,
+                        HAL_PIXEL_FORMAT_RAW_SENSOR));
+        }
+
+        // Required processed sizes.
+        int processedSizeCount =
+               GetEntryCountFromStaticTag(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES);
+        EXPECT_NE(0, processedSizeCount);
+        EXPECT_EQ(0, processedSizeCount % 2); // multiple of 2 (w,h)
+
+        // Required JPEG sizes
+        int jpegSizeCount =
+                GetEntryCountFromStaticTag(ANDROID_SCALER_AVAILABLE_JPEG_SIZES);
+        EXPECT_NE(0, jpegSizeCount);
+        EXPECT_EQ(0, jpegSizeCount % 2); // multiple of 2 (w,h)
+    } else {
+        int strmConfigCount =
+                GetEntryCountFromStaticTag(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS);
+        EXPECT_NE(0, strmConfigCount);
+        EXPECT_EQ(0, strmConfigCount % 4); // multiple of 4 (format,w,h,output?)
     }
 
-    // Required processed sizes.
-    int processedSizeCount =
-           GetEntryCountFromStaticTag(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES);
-    EXPECT_NE(0, processedSizeCount);
-    EXPECT_EQ(0, processedSizeCount % 2); // multiple of 2 (w,h)
-
-    // Required JPEG sizes
-    int jpegSizeCount =
-            GetEntryCountFromStaticTag(ANDROID_SCALER_AVAILABLE_JPEG_SIZES);
-    EXPECT_NE(0, jpegSizeCount);
-    EXPECT_EQ(0, jpegSizeCount % 2); // multiple of 2 (w,h)
-
 }
 
 }
diff --git a/tests/camera2/CameraMultiStreamTests.cpp b/tests/camera2/CameraMultiStreamTests.cpp
index 89af91d..df8e623 100644
--- a/tests/camera2/CameraMultiStreamTests.cpp
+++ b/tests/camera2/CameraMultiStreamTests.cpp
@@ -472,19 +472,42 @@
 
     TEST_EXTENSION_FORKING_INIT;
 
-    camera_metadata_ro_entry availableProcessedSizes =
-        GetStaticEntry(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES);
-    ASSERT_EQ(0u, availableProcessedSizes.count % 2);
-    ASSERT_GE(availableProcessedSizes.count, 2u);
-    camera_metadata_ro_entry availableProcessedMinFrameDurations =
-        GetStaticEntry(ANDROID_SCALER_AVAILABLE_PROCESSED_MIN_DURATIONS);
-    EXPECT_EQ(availableProcessedSizes.count,
-        availableProcessedMinFrameDurations.count * 2);
+    const int32_t* implDefData;
+    size_t implDefCount;
+    const int32_t* jpegData;
+    size_t jpegCount;
+    if (getDeviceVersion() < CAMERA_DEVICE_API_VERSION_3_2) {
+        camera_metadata_ro_entry availableProcessedSizes =
+            GetStaticEntry(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES);
+        ASSERT_EQ(0u, availableProcessedSizes.count % 2);
+        ASSERT_GE(availableProcessedSizes.count, 2u);
+        camera_metadata_ro_entry availableProcessedMinFrameDurations =
+            GetStaticEntry(ANDROID_SCALER_AVAILABLE_PROCESSED_MIN_DURATIONS);
+        EXPECT_EQ(availableProcessedSizes.count,
+            availableProcessedMinFrameDurations.count * 2);
 
-    camera_metadata_ro_entry availableJpegSizes =
-        GetStaticEntry(ANDROID_SCALER_AVAILABLE_JPEG_SIZES);
-    ASSERT_EQ(0u, availableJpegSizes.count % 2);
-    ASSERT_GE(availableJpegSizes.count, 2u);
+        camera_metadata_ro_entry availableJpegSizes =
+            GetStaticEntry(ANDROID_SCALER_AVAILABLE_JPEG_SIZES);
+        ASSERT_EQ(0u, availableJpegSizes.count % 2);
+        ASSERT_GE(availableJpegSizes.count, 2u);
+        implDefData = availableProcessedSizes.data.i32;
+        implDefCount = availableProcessedSizes.count;
+        jpegData = availableJpegSizes.data.i32;
+        jpegCount = availableJpegSizes.count;
+    } else {
+        const int32_t *implDefResolutions;
+        size_t   implDefResolutionsCount;
+
+        getResolutionList(HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, &implDefData, &implDefCount);
+        ASSERT_NE(0u, implDefCount)
+            << "Missing implementation defined sizes";
+        ASSERT_EQ(0u, implDefCount % 2);
+        ASSERT_GE(implDefCount, 2u);
+
+        getResolutionList(HAL_PIXEL_FORMAT_BLOB, &jpegData, &jpegCount);
+        ASSERT_EQ(0u, jpegCount % 2);
+        ASSERT_GE(jpegCount, 2u);
+    }
 
     camera_metadata_ro_entry hardwareLevel =
         GetStaticEntry(ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL);
@@ -504,23 +527,25 @@
     }
 
     // Find the right sizes for preview, metering, and capture streams
-    // assumes at least 2 entries in availableProcessedSizes.
     int64_t minFrameDuration = DEFAULT_FRAME_DURATION;
     Size processedMinSize, processedMaxSize, jpegMaxSize;
-    const int32_t* data = availableProcessedSizes.data.i32;
-    size_t count = availableProcessedSizes.count;
 
     int32_t minIdx, maxIdx;
-    GetMinSize(data, count, &processedMinSize, &minIdx);
-    GetMaxSize(data, count, &processedMaxSize, &maxIdx);
+    GetMinSize(implDefData, implDefCount, &processedMinSize, &minIdx);
+    GetMaxSize(implDefData, implDefCount, &processedMaxSize, &maxIdx);
     ALOGV("Found processed max size: %dx%d, min size = %dx%d",
             processedMaxSize.width, processedMaxSize.height,
             processedMinSize.width, processedMinSize.height);
 
-    if (availableProcessedSizes.count ==
-        availableProcessedMinFrameDurations.count * 2) {
+    if (getDeviceVersion() < CAMERA_DEVICE_API_VERSION_3_2) {
+        camera_metadata_ro_entry availableProcessedMinFrameDurations =
+            GetStaticEntry(ANDROID_SCALER_AVAILABLE_PROCESSED_MIN_DURATIONS);
         minFrameDuration =
             availableProcessedMinFrameDurations.data.i64[maxIdx / 2];
+    } else {
+        minFrameDuration = getMinFrameDurationFor(
+                HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED,
+                processedMaxSize.width, processedMaxSize.height);
     }
 
     EXPECT_GT(minFrameDuration, 0);
@@ -531,9 +556,7 @@
 
     ALOGV("targeted minimal frame duration is: %" PRId64 "ns", minFrameDuration);
 
-    data = &(availableJpegSizes.data.i32[0]);
-    count = availableJpegSizes.count;
-    GetMaxSize(data, count, &jpegMaxSize, &maxIdx);
+    GetMaxSize(jpegData, jpegCount, &jpegMaxSize, &maxIdx);
     ALOGV("Found Jpeg size max idx = %d", maxIdx);
 
     // Max Jpeg size should be available in processed sizes. Use it for
@@ -627,7 +650,7 @@
     // purely by analog gain if possible.
     Vector<int32_t> sensitivities;
     Vector<int64_t> exposures;
-    count = (maxAnalogSensitivity - minSensitivity + 99) / 100;
+    size_t count = (maxAnalogSensitivity - minSensitivity + 99) / 100;
     sensitivities.push_back(minSensitivity);
     for (size_t i = 1; i < count; i++) {
         sensitivities.push_back(minSensitivity + i * 100);
diff --git a/tests/camera2/CameraStreamFixture.h b/tests/camera2/CameraStreamFixture.h
index f56daf0..cc13169 100644
--- a/tests/camera2/CameraStreamFixture.h
+++ b/tests/camera2/CameraStreamFixture.h
@@ -96,7 +96,7 @@
         sp<CameraDeviceBase> device = mDevice;
 
         /* use an arbitrary w,h */
-        {
+        if (getDeviceVersion() < CAMERA_DEVICE_API_VERSION_3_2) {
             const int tag = ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES;
 
             const CameraMetadata& staticInfo = device->info();
@@ -106,9 +106,22 @@
 
             ASSERT_LE(2u, entry.count);
             /* this seems like it would always be the smallest w,h
-               but we actually make no contract that it's sorted asc */;
+               but we actually make no contract that it's sorted asc */
             mWidth = entry.data.i32[0];
             mHeight = entry.data.i32[1];
+        } else {
+            buildOutputResolutions();
+            const int32_t *implDefResolutions;
+            size_t   implDefResolutionsCount;
+
+            int format = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
+
+            getResolutionList(format,
+                    &implDefResolutions, &implDefResolutionsCount);
+            ASSERT_NE(0u, implDefResolutionsCount)
+                << "Missing implementation defined sizes";
+            mWidth = implDefResolutions[0];
+            mHeight = implDefResolutions[1];
         }
     }
     void TearDown() {
@@ -117,12 +130,82 @@
         // important: shut down HAL before releasing streams
         CameraModuleFixture::TearDown();
 
+        deleteOutputResolutions();
         mNativeWindow.clear();
         mCpuConsumer.clear();
         mFrameListener.clear();
     }
 
 protected:
+
+    int64_t getMinFrameDurationFor(int32_t format, int32_t width, int32_t height) {
+        int64_t minFrameDuration = -1L;
+        const int tag = ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS;
+        sp<CameraDeviceBase> device = mDevice;
+        const CameraMetadata& staticInfo = device->info();
+        camera_metadata_ro_entry_t availableMinDurations = staticInfo.find(tag);
+        for (uint32_t i = 0; i < availableMinDurations.count; i += 4) {
+            if (format == availableMinDurations.data.i64[i] &&
+                    width == availableMinDurations.data.i64[i + 1] &&
+                    height == availableMinDurations.data.i64[i + 2]) {
+                minFrameDuration = availableMinDurations.data.i64[i + 3];
+                break;
+            }
+        }
+        return minFrameDuration;
+    }
+
+    void buildOutputResolutions() {
+        if (getDeviceVersion() < CAMERA_DEVICE_API_VERSION_3_2) {
+            return;
+        }
+        if (mOutputResolutions.isEmpty()) {
+            const int tag = ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS;
+            const CameraMetadata& staticInfo = mDevice->info();
+            camera_metadata_ro_entry_t availableStrmConfigs = staticInfo.find(tag);
+            ASSERT_EQ(0u, availableStrmConfigs.count % 4);
+            for (uint32_t i = 0; i < availableStrmConfigs.count; i += 4) {
+                int32_t format = availableStrmConfigs.data.i32[i];
+                int32_t width = availableStrmConfigs.data.i32[i + 1];
+                int32_t height = availableStrmConfigs.data.i32[i + 2];
+                int32_t inOrOut = availableStrmConfigs.data.i32[i + 3];
+                if (inOrOut == ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT) {
+                    int index = mOutputResolutions.indexOfKey(format);
+                    if (index < 0) {
+                        index = mOutputResolutions.add(format, new Vector<int32_t>());
+                        ASSERT_TRUE(index >= 0);
+                    }
+                    Vector<int32_t> *resolutions = mOutputResolutions.editValueAt(index);
+                    resolutions->add(width);
+                    resolutions->add(height);
+                }
+            }
+        }
+    }
+
+    void getResolutionList(int32_t format,
+            const int32_t **list,
+            size_t *count) {
+        status_t res;
+        ALOGV("Getting resolutions for format %x", format);
+        if (getDeviceVersion() < CAMERA_DEVICE_API_VERSION_3_2) {
+            return;
+        }
+        int index = mOutputResolutions.indexOfKey(format);
+        ASSERT_TRUE(index >= 0);
+        Vector<int32_t>* resolutions = mOutputResolutions.valueAt(index);
+        *list = resolutions->array();
+        *count = resolutions->size();
+    }
+
+    void deleteOutputResolutions() {
+        for (uint32_t i = 0; i < mOutputResolutions.size(); i++) {
+            Vector<int32_t>* resolutions = mOutputResolutions.editValueAt(i);
+            delete resolutions;
+        }
+        mOutputResolutions.clear();
+    }
+
     struct FrameListener : public ConsumerBase::FrameAvailableListener {
 
         FrameListener() {
@@ -130,7 +213,7 @@
         }
 
         // CpuConsumer::FrameAvailableListener implementation
-        virtual void onFrameAvailable() {
+        virtual void onFrameAvailable(const BufferItem& /* item */) {
             ALOGV("Frame now available (start)");
 
             Mutex::Autolock lock(mMutex);
@@ -280,7 +363,7 @@
     android::sp<FrameListener>       mFrameListener;
     android::sp<CpuConsumer>         mCpuConsumer;
     android::sp<ANativeWindow>       mNativeWindow;
-
+    KeyedVector<int32_t, Vector<int32_t>* > mOutputResolutions;
 
 private:
     CameraStreamParams mParam;
diff --git a/tests/camera2/camera2.cpp b/tests/camera2/camera2.cpp
index e3e7d9a..72b7b61 100644
--- a/tests/camera2/camera2.cpp
+++ b/tests/camera2/camera2.cpp
@@ -23,6 +23,7 @@
 #include <fstream>
 
 #include <utils/Vector.h>
+#include <utils/KeyedVector.h>
 #include <gui/CpuConsumer.h>
 #include <ui/PixelFormat.h>
 #include <system/camera_metadata.h>
@@ -202,7 +203,9 @@
         res = sCameraModule->get_camera_info(id, &info);
         ASSERT_EQ(OK, res);
 
+        mDeviceVersion = info.device_version;
         mStaticInfo = info.static_camera_characteristics;
+        buildOutputResolutions();
 
         res = configureCameraDevice(mDevice,
                 mRequests,
@@ -241,44 +244,91 @@
         ASSERT_GT(mStreams.size(), i) << "Stream id not found:" << id;
     }
 
+    void buildOutputResolutions() {
+        status_t res;
+        if (mDeviceVersion < CAMERA_DEVICE_API_VERSION_3_2) {
+            return;
+        }
+        if (mOutputResolutions.isEmpty()) {
+            camera_metadata_ro_entry_t availableStrmConfigs;
+            res = find_camera_metadata_ro_entry(mStaticInfo,
+                    ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
+                    &availableStrmConfigs);
+            ASSERT_EQ(OK, res);
+            ASSERT_EQ(0u, availableStrmConfigs.count % 4);
+            for (uint32_t i = 0; i < availableStrmConfigs.count; i += 4) {
+                int32_t format = availableStrmConfigs.data.i32[i];
+                int32_t width = availableStrmConfigs.data.i32[i + 1];
+                int32_t height = availableStrmConfigs.data.i32[i + 2];
+                int32_t inOrOut = availableStrmConfigs.data.i32[i + 3];
+                if (inOrOut == ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT) {
+                    int index = mOutputResolutions.indexOfKey(format);
+                    if (index < 0) {
+                        index = mOutputResolutions.add(format, new Vector<int32_t>());
+                        ASSERT_TRUE(index >= 0);
+                    }
+                    Vector<int32_t> *resolutions = mOutputResolutions.editValueAt(index);
+                    resolutions->add(width);
+                    resolutions->add(height);
+                }
+            }
+        }
+    }
+
+    void deleteOutputResolutions() {
+        for (uint32_t i = 0; i < mOutputResolutions.size(); i++) {
+            Vector<int32_t>* resolutions = mOutputResolutions.editValueAt(i);
+            delete resolutions;
+        }
+        mOutputResolutions.clear();
+    }
+
     void getResolutionList(int32_t format,
             const int32_t **list,
             size_t *count) {
-        ALOGV("Getting resolutions for format %x", format);
         status_t res;
-        if (format != HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
-            camera_metadata_ro_entry_t availableFormats;
-            res = find_camera_metadata_ro_entry(mStaticInfo,
-                    ANDROID_SCALER_AVAILABLE_FORMATS,
-                    &availableFormats);
+        ALOGV("Getting resolutions for format %x", format);
+        if (mDeviceVersion < CAMERA_DEVICE_API_VERSION_3_2) {
+            if (format != HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
+                camera_metadata_ro_entry_t availableFormats;
+                res = find_camera_metadata_ro_entry(mStaticInfo,
+                        ANDROID_SCALER_AVAILABLE_FORMATS,
+                        &availableFormats);
+                ASSERT_EQ(OK, res);
+
+                uint32_t formatIdx;
+                for (formatIdx=0; formatIdx < availableFormats.count; formatIdx++) {
+                    if (availableFormats.data.i32[formatIdx] == format) break;
+                }
+                ASSERT_NE(availableFormats.count, formatIdx)
+                    << "No support found for format 0x" << std::hex << format;
+            }
+
+            camera_metadata_ro_entry_t availableSizes;
+            if (format == HAL_PIXEL_FORMAT_RAW_SENSOR) {
+                res = find_camera_metadata_ro_entry(mStaticInfo,
+                        ANDROID_SCALER_AVAILABLE_RAW_SIZES,
+                        &availableSizes);
+            } else if (format == HAL_PIXEL_FORMAT_BLOB) {
+                res = find_camera_metadata_ro_entry(mStaticInfo,
+                        ANDROID_SCALER_AVAILABLE_JPEG_SIZES,
+                        &availableSizes);
+            } else {
+                res = find_camera_metadata_ro_entry(mStaticInfo,
+                        ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES,
+                        &availableSizes);
+            }
             ASSERT_EQ(OK, res);
 
-            uint32_t formatIdx;
-            for (formatIdx=0; formatIdx < availableFormats.count; formatIdx++) {
-                if (availableFormats.data.i32[formatIdx] == format) break;
-            }
-            ASSERT_NE(availableFormats.count, formatIdx)
-                << "No support found for format 0x" << std::hex << format;
-        }
-
-        camera_metadata_ro_entry_t availableSizes;
-        if (format == HAL_PIXEL_FORMAT_RAW_SENSOR) {
-            res = find_camera_metadata_ro_entry(mStaticInfo,
-                    ANDROID_SCALER_AVAILABLE_RAW_SIZES,
-                    &availableSizes);
-        } else if (format == HAL_PIXEL_FORMAT_BLOB) {
-            res = find_camera_metadata_ro_entry(mStaticInfo,
-                    ANDROID_SCALER_AVAILABLE_JPEG_SIZES,
-                    &availableSizes);
+            *list = availableSizes.data.i32;
+            *count = availableSizes.count;
         } else {
-            res = find_camera_metadata_ro_entry(mStaticInfo,
-                    ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES,
-                    &availableSizes);
+            int index = mOutputResolutions.indexOfKey(format);
+            ASSERT_TRUE(index >= 0);
+            Vector<int32_t>* resolutions = mOutputResolutions.valueAt(index);
+            *list = resolutions->array();
+            *count = resolutions->size();
         }
-        ASSERT_EQ(OK, res);
-
-        *list = availableSizes.data.i32;
-        *count = availableSizes.count;
     }
 
     status_t waitUntilDrained() {
@@ -325,11 +375,13 @@
             closeCameraDevice(&mDevice);
         }
 
+        deleteOutputResolutions();
         TearDownModule();
     }
 
     int mId;
     camera2_device    *mDevice;
+    uint32_t mDeviceVersion;
     const camera_metadata_t *mStaticInfo;
 
     MetadataQueue    mRequests;
@@ -337,11 +389,13 @@
     NotifierListener mNotifications;
 
     Vector<StreamAdapter*> mStreams;
+    KeyedVector<int32_t, Vector<int32_t>* > mOutputResolutions;
 
   private:
     static camera_module_t *sCameraModule;
     static int              sNumCameras;
     static bool            *sCameraSupportsHal2;
+
 };
 
 camera_module_t *Camera2Test::sCameraModule = NULL;
diff --git a/tests/camera2/camera2_utils.cpp b/tests/camera2/camera2_utils.cpp
index 3c0767a..9cc6c90 100644
--- a/tests/camera2/camera2_utils.cpp
+++ b/tests/camera2/camera2_utils.cpp
@@ -574,7 +574,7 @@
     return OK;
 }
 
-void FrameWaiter::onFrameAvailable() {
+void FrameWaiter::onFrameAvailable(const BufferItem& /* item */) {
     Mutex::Autolock lock(mMutex);
     mPendingFrames++;
     mCondition.signal();
diff --git a/tests/camera2/camera2_utils.h b/tests/camera2/camera2_utils.h
index 0cdf4a3..c1d1e72 100644
--- a/tests/camera2/camera2_utils.h
+++ b/tests/camera2/camera2_utils.h
@@ -231,7 +231,7 @@
      */
     status_t waitForFrame(nsecs_t timeout);
 
-    virtual void onFrameAvailable();
+    virtual void onFrameAvailable(const BufferItem& item);
 
     int mPendingFrames;
     Mutex mMutex;
diff --git a/tests/camera3/camera3test_fixtures.h b/tests/camera3/camera3test_fixtures.h
index 81d1997..17e3d45 100644
--- a/tests/camera3/camera3test_fixtures.h
+++ b/tests/camera3/camera3test_fixtures.h
@@ -68,7 +68,7 @@
                 << "Can't open camera device";
         ASSERT_TRUE(NULL != device)
                     << "Camera open() returned a NULL device";
-        ASSERT_EQ(kVersion3_0, device->version)
+        ASSERT_LE(kVersion3_0, device->version)
                     << "The device does not support HAL3";
         cam_device_ = reinterpret_cast<camera3_device_t*>(device);
     }
diff --git a/tests/keymaster/keymaster_test.cpp b/tests/keymaster/keymaster_test.cpp
index 6b76ccb..e5e1dfd 100644
--- a/tests/keymaster/keymaster_test.cpp
+++ b/tests/keymaster/keymaster_test.cpp
@@ -35,7 +35,7 @@
 
 #include <UniquePtr.h>
 
-#include <hardware/keymaster.h>
+#include <hardware/keymaster0.h>
 
 namespace android {
 
@@ -92,13 +92,13 @@
 
 class UniqueKey : public UniqueBlob {
 public:
-    UniqueKey(keymaster_device_t** dev, uint8_t* bytes, size_t length) :
+    UniqueKey(keymaster0_device_t** dev, uint8_t* bytes, size_t length) :
             UniqueBlob(bytes, length), mDevice(dev) {
     }
 
     ~UniqueKey() {
         if (mDevice != NULL && *mDevice != NULL) {
-            keymaster_device_t* dev = *mDevice;
+            keymaster0_device_t* dev = *mDevice;
             if (dev->delete_keypair != NULL) {
                 dev->delete_keypair(dev, get(), length());
             }
@@ -106,7 +106,7 @@
     }
 
 private:
-    keymaster_device_t** mDevice;
+    keymaster0_device_t** mDevice;
 };
 
 class UniqueReadOnlyBlob {
@@ -341,7 +341,7 @@
 
         std::cout << "Using keymaster module: " << mod->name << std::endl;
 
-        ASSERT_EQ(0, keymaster_open(mod, &sDevice))
+        ASSERT_EQ(0, keymaster0_open(mod, &sDevice))
                 << "Should be able to open the keymaster device";
 
         ASSERT_EQ(KEYMASTER_MODULE_API_VERSION_0_2, mod->module_api_version)
@@ -364,14 +364,14 @@
     }
 
     static void TearDownTestCase() {
-        ASSERT_EQ(0, keymaster_close(sDevice));
+        ASSERT_EQ(0, keymaster0_close(sDevice));
     }
 
 protected:
-    static keymaster_device_t* sDevice;
+    static keymaster0_device_t* sDevice;
 };
 
-keymaster_device_t* KeymasterBaseTest::sDevice = NULL;
+keymaster0_device_t* KeymasterBaseTest::sDevice = NULL;
 
 class KeymasterTest : public KeymasterBaseTest {
 };