am 40d48e17: Merge "Stop using stlport."

* commit '40d48e177f243c6093a45301db122a0475cc1124':
  Stop using stlport.
diff --git a/include/hardware/audio.h b/include/hardware/audio.h
index 763ca58..8d5b2f0 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
@@ -136,9 +140,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/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/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/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/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..5c4edd1 100644
--- a/modules/usbaudio/alsa_device_profile.c
+++ b/modules/usbaudio/alsa_device_profile.c
@@ -275,28 +275,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 +450,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 +459,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 +477,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 664a753..0346408 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)
@@ -808,7 +798,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;
@@ -960,19 +950,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 58763de..8dcc2a2 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 2742466..b92d8cc 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);
     }