diff --git a/tests/camera2/CameraMultiStreamTests.cpp b/tests/camera2/CameraMultiStreamTests.cpp
new file mode 100644
index 0000000..679ff4e
--- /dev/null
+++ b/tests/camera2/CameraMultiStreamTests.cpp
@@ -0,0 +1,651 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "CameraMultiStreamTest"
+//#define LOG_NDEBUG 0
+#include "CameraStreamFixture.h"
+#include "TestExtensions.h"
+
+#include <gtest/gtest.h>
+#include <utils/Log.h>
+#include <utils/StrongPointer.h>
+#include <common/CameraDeviceBase.h>
+#include <hardware/hardware.h>
+#include <hardware/camera2.h>
+#include <gui/SurfaceComposerClient.h>
+#include <gui/Surface.h>
+
+#define DEFAULT_FRAME_DURATION 33000000LL // 33ms
+#define CAMERA_HEAP_COUNT       1
+#define CAMERA_EXPOSURE_FORMAT CAMERA_STREAM_AUTO_CPU_FORMAT
+#define CAMERA_DISPLAY_FORMAT HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED
+#define CAMERA_MULTI_STREAM_DEBUGGING  0
+#define CAMERA_FRAME_TIMEOUT    1000000000LL // nsecs (1 secs)
+#define PREVIEW_RENDERING_TIME_INTERVAL 200000 // in unit of us, 200ms
+/* constants for display */
+#define DISPLAY_BUFFER_HEIGHT 1024
+#define DISPLAY_BUFFER_WIDTH 1024
+#define DISPLAY_BUFFER_FORMAT PIXEL_FORMAT_RGB_888
+
+// This test intends to test large preview size but less than 1080p.
+#define PREVIEW_WIDTH_CAP   1920
+#define PREVIEW_HEIGHT_CAP  1080
+// This test intends to test small metering burst size that is less than 640x480
+#define METERING_WIDTH_CAP  640
+#define METERING_HEIGHT_CAP 480
+
+#define EXP_WAIT_MULTIPLIER 2
+
+namespace android {
+namespace camera2 {
+namespace tests {
+
+static const CameraStreamParams DEFAULT_STREAM_PARAMETERS = {
+    /*mFormat*/     CAMERA_EXPOSURE_FORMAT,
+    /*mHeapCount*/  CAMERA_HEAP_COUNT
+};
+
+static const CameraStreamParams DISPLAY_STREAM_PARAMETERS = {
+    /*mFormat*/     CAMERA_DISPLAY_FORMAT,
+    /*mHeapCount*/  CAMERA_HEAP_COUNT
+};
+
+class CameraMultiStreamTest
+    : public ::testing::Test,
+      public CameraStreamFixture {
+
+public:
+    CameraMultiStreamTest() : CameraStreamFixture(DEFAULT_STREAM_PARAMETERS) {
+        TEST_EXTENSION_FORKING_CONSTRUCTOR;
+
+        if (HasFatalFailure()) {
+            return;
+        }
+        /**
+         * Don't create default stream, each test is in charge of creating
+         * its own streams.
+         */
+    }
+
+    ~CameraMultiStreamTest() {
+        TEST_EXTENSION_FORKING_DESTRUCTOR;
+    }
+
+    sp<SurfaceComposerClient> mComposerClient;
+    sp<SurfaceControl> mSurfaceControl;
+
+    void CreateOnScreenSurface(sp<ANativeWindow>& surface) {
+        mComposerClient = new SurfaceComposerClient;
+        ASSERT_EQ(NO_ERROR, mComposerClient->initCheck());
+
+        mSurfaceControl = mComposerClient->createSurface(
+                String8("CameraMultiStreamTest StreamingImage Surface"),
+                DISPLAY_BUFFER_HEIGHT, DISPLAY_BUFFER_WIDTH,
+                DISPLAY_BUFFER_FORMAT, 0);
+
+        ASSERT_NE((void*)NULL, mSurfaceControl.get());
+        ASSERT_TRUE(mSurfaceControl->isValid());
+
+        SurfaceComposerClient::openGlobalTransaction();
+        ASSERT_EQ(NO_ERROR, mSurfaceControl->setLayer(0x7FFFFFFF));
+        ASSERT_EQ(NO_ERROR, mSurfaceControl->show());
+        SurfaceComposerClient::closeGlobalTransaction();
+
+        surface = mSurfaceControl->getSurface();
+
+        ASSERT_NE((void*)NULL, surface.get());
+    }
+
+    struct Size {
+        int32_t width;
+        int32_t height;
+    };
+
+    // Select minimal size by number of pixels.
+    void GetMinSize(const int32_t* data, size_t count,
+            Size* min, int32_t* idx) {
+        ASSERT_NE((int32_t*)NULL, data);
+        int32_t minIdx = 0;
+        int32_t minSize = INT_MAX, tempSize;
+        for (size_t i = 0; i < count; i+=2) {
+            tempSize = data[i] * data[i+1];
+            if (minSize > tempSize) {
+                minSize = tempSize;
+                minIdx = i;
+            }
+        }
+        min->width = data[minIdx];
+        min->height = data[minIdx + 1];
+        *idx = minIdx;
+    }
+
+    // Select maximal size by number of pixels.
+    void GetMaxSize(const int32_t* data, size_t count,
+            Size* max, int32_t* idx) {
+        ASSERT_NE((int32_t*)NULL, data);
+        int32_t maxIdx = 0;
+        int32_t maxSize = INT_MIN, tempSize;
+        for (size_t i = 0; i < count; i+=2) {
+            tempSize = data[i] * data[i+1];
+            if (maxSize < tempSize) {
+                maxSize = tempSize;
+                maxIdx = i;
+            }
+        }
+        max->width = data[maxIdx];
+        max->height = data[maxIdx + 1];
+        *idx = maxIdx;
+    }
+
+    // Cap size by number of pixels.
+    Size CapSize(Size cap, Size input) {
+        if (input.width * input.height > cap.width * cap.height) {
+            return cap;
+        }
+        return input;
+    }
+
+    struct CameraStream : public RefBase {
+
+    public:
+        /**
+         * Only initialize the variables here, do the ASSERT check in
+         * SetUp function. To make this stream useful, the SetUp must
+         * be called before using it.
+         */
+        CameraStream(
+                int width,
+                int height,
+                const sp<CameraDeviceBase>& device,
+                CameraStreamParams param, sp<ANativeWindow> surface,
+                bool useCpuConsumer)
+            : mDevice(device),
+              mWidth(width),
+              mHeight(height) {
+            mFormat = param.mFormat;
+            if (useCpuConsumer) {
+                sp<BufferQueue> bq = new BufferQueue();
+                mCpuConsumer = new CpuConsumer(bq, param.mHeapCount);
+                mCpuConsumer->setName(String8(
+                        "CameraMultiStreamTest::mCpuConsumer"));
+                mNativeWindow = new Surface(bq);
+            } else {
+                // Render the stream to screen.
+                mCpuConsumer = NULL;
+                mNativeWindow = surface;
+            }
+
+            mFrameListener = new FrameListener();
+            if (mCpuConsumer != 0) {
+                mCpuConsumer->setFrameAvailableListener(mFrameListener);
+            }
+        }
+
+        /**
+         * Finally create camera stream, and do the ASSERT check, since we
+         * can not do it in ctor.
+         */
+        void SetUp() {
+            ASSERT_EQ(OK,
+                mDevice->createStream(mNativeWindow,
+                    mWidth, mHeight, mFormat, /*size (for jpegs)*/0,
+                    &mStreamId));
+
+            ASSERT_NE(-1, mStreamId);
+        }
+
+        int GetStreamId() { return mStreamId; }
+        sp<CpuConsumer> GetConsumer() { return mCpuConsumer; }
+        sp<FrameListener> GetFrameListener() { return mFrameListener; }
+
+    protected:
+        ~CameraStream() {
+            if (mDevice.get()) {
+                mDevice->waitUntilDrained();
+                mDevice->deleteStream(mStreamId);
+            }
+            // Clear producer before consumer.
+            mNativeWindow.clear();
+            mCpuConsumer.clear();
+        }
+
+    private:
+        sp<FrameListener>       mFrameListener;
+        sp<CpuConsumer>         mCpuConsumer;
+        sp<ANativeWindow>       mNativeWindow;
+        sp<CameraDeviceBase>    mDevice;
+        int                     mStreamId;
+        int                     mWidth;
+        int                     mHeight;
+        int                     mFormat;
+    };
+
+    int64_t GetExposureValue(const CameraMetadata& metaData) {
+        camera_metadata_ro_entry_t entry =
+                metaData.find(ANDROID_SENSOR_EXPOSURE_TIME);
+        EXPECT_EQ(1u, entry.count);
+        if (entry.count == 1) {
+            return entry.data.i64[0];
+        }
+        return -1;
+    }
+
+    int32_t GetSensitivity(const CameraMetadata& metaData) {
+        camera_metadata_ro_entry_t entry =
+                metaData.find(ANDROID_SENSOR_SENSITIVITY);
+        EXPECT_EQ(1u, entry.count);
+        if (entry.count == 1) {
+            return entry.data.i32[0];
+        }
+        return -1;
+    }
+
+    int64_t GetFrameDuration(const CameraMetadata& metaData) {
+        camera_metadata_ro_entry_t entry =
+                metaData.find(ANDROID_SENSOR_FRAME_DURATION);
+        EXPECT_EQ(1u, entry.count);
+        if (entry.count == 1) {
+            return entry.data.i64[0];
+        }
+        return -1;
+    }
+
+    void CreateRequests(CameraMetadata& previewRequest,
+            CameraMetadata& meteringRequest,
+            CameraMetadata& captureRequest,
+            int previewStreamId,
+            int meteringStreamId,
+            int captureStreamId) {
+    int32_t requestId = 1;
+    Vector<uint8_t> previewStreamIds;
+    previewStreamIds.push(previewStreamId);
+    ASSERT_EQ(OK, mDevice->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
+            &previewRequest));
+    ASSERT_EQ(OK, previewRequest.update(ANDROID_REQUEST_OUTPUT_STREAMS,
+            previewStreamIds));
+    ASSERT_EQ(OK, previewRequest.update(ANDROID_REQUEST_ID,
+            &requestId, 1));
+
+    // Create metering request, manual settings
+    // Manual control: Disable 3A, noise reduction, edge sharping
+    uint8_t cmOff = static_cast<uint8_t>(ANDROID_CONTROL_MODE_OFF);
+    uint8_t nrOff = static_cast<uint8_t>(ANDROID_NOISE_REDUCTION_MODE_OFF);
+    uint8_t sharpOff = static_cast<uint8_t>(ANDROID_EDGE_MODE_OFF);
+    Vector<uint8_t> meteringStreamIds;
+    meteringStreamIds.push(meteringStreamId);
+    ASSERT_EQ(OK, mDevice->createDefaultRequest(
+            CAMERA2_TEMPLATE_PREVIEW,
+            &meteringRequest));
+    ASSERT_EQ(OK, meteringRequest.update(
+            ANDROID_REQUEST_OUTPUT_STREAMS,
+            meteringStreamIds));
+    ASSERT_EQ(OK, meteringRequest.update(
+            ANDROID_REQUEST_ID,
+            &requestId, 1));
+    ASSERT_EQ(OK, meteringRequest.update(
+            ANDROID_CONTROL_MODE,
+            &cmOff, 1));
+    ASSERT_EQ(OK, meteringRequest.update(
+            ANDROID_NOISE_REDUCTION_MODE,
+            &nrOff, 1));
+    ASSERT_EQ(OK, meteringRequest.update(
+            ANDROID_EDGE_MODE,
+            &sharpOff, 1));
+
+    // Create capture request, manual settings
+    requestId++;
+    Vector<uint8_t> captureStreamIds;
+    captureStreamIds.push(captureStreamId);
+    ASSERT_EQ(OK, mDevice->createDefaultRequest(
+            CAMERA2_TEMPLATE_PREVIEW,
+            &captureRequest));
+    ASSERT_EQ(OK, captureRequest.update(
+            ANDROID_REQUEST_OUTPUT_STREAMS,
+            captureStreamIds));
+    ASSERT_EQ(OK, captureRequest.update(
+            ANDROID_REQUEST_ID,
+            &requestId, 1));
+    ASSERT_EQ(OK, captureRequest.update(
+            ANDROID_CONTROL_MODE,
+            &cmOff, 1));
+    ASSERT_EQ(OK, captureRequest.update(
+            ANDROID_NOISE_REDUCTION_MODE,
+            &nrOff, 1));
+    ASSERT_EQ(OK, captureRequest.update(
+            ANDROID_EDGE_MODE,
+            &sharpOff, 1));
+    }
+
+    sp<CameraStream> CreateStream(
+            int width,
+            int height,
+            const sp<CameraDeviceBase>& device,
+            CameraStreamParams param = DEFAULT_STREAM_PARAMETERS,
+            sp<ANativeWindow> surface = NULL,
+            bool useCpuConsumer = true) {
+        param.mFormat = MapAutoFormat(param.mFormat);
+        return new CameraStream(width, height, device,
+                param, surface, useCpuConsumer);
+    }
+
+    void CaptureBurst(CameraMetadata& request, size_t requestCount,
+            const Vector<int64_t>& exposures,
+            const Vector<int32_t>& sensitivities,
+            const sp<CameraStream>& stream,
+            int64_t minFrameDuration) {
+        ASSERT_EQ(OK, request.update(ANDROID_SENSOR_FRAME_DURATION,
+                &minFrameDuration, 1));
+        // Submit a series of requests with the specified exposure/gain values.
+        for (size_t i = 0; i < requestCount; i++) {
+            ASSERT_EQ(OK, request.update(ANDROID_SENSOR_EXPOSURE_TIME,
+                    &exposures[i], 1));
+            ASSERT_EQ(OK, request.update(ANDROID_SENSOR_SENSITIVITY,
+                    &sensitivities[i], 1));
+            ASSERT_EQ(OK, mDevice->capture(request));
+            ALOGV("Submitting capture %d with exposure %lld, sensitivity %d",
+                    i, exposures[i], sensitivities[i]);
+            if (CAMERA_MULTI_STREAM_DEBUGGING) {
+                request.dump(STDOUT_FILENO);
+            }
+        }
+        // Get capture burst results.
+        Vector<nsecs_t> captureBurstTimes;
+        sp<CpuConsumer> consumer = stream->GetConsumer();
+        sp<FrameListener> listener = stream->GetFrameListener();
+
+        // Set wait limit based on expected frame duration.
+        int64_t waitLimit = CAMERA_FRAME_TIMEOUT;
+        for (size_t i = 0; i < requestCount; i++) {
+            ALOGV("Reading request result %d", i);
+
+            /**
+             * Raise the timeout to be at least twice as long as the exposure
+             * time. to avoid a false positive when the timeout is too short.
+             */
+            if ((exposures[i] * EXP_WAIT_MULTIPLIER) > waitLimit) {
+                waitLimit = exposures[i] * EXP_WAIT_MULTIPLIER;
+            }
+
+            ASSERT_EQ(OK, mDevice->waitForNextFrame(waitLimit));
+            CameraMetadata frameMetadata;
+            ASSERT_EQ(OK, mDevice->getNextFrame(&frameMetadata));
+            ALOGV("Got capture burst result for request %d", i);
+            // Validate capture result
+            if (CAMERA_MULTI_STREAM_DEBUGGING) {
+                frameMetadata.dump(STDOUT_FILENO);
+            }
+
+            // TODO: Need revisit it to figure out an accurate margin.
+            EXPECT_EQ(sensitivities[i], GetSensitivity(frameMetadata));
+            EXPECT_EQ(exposures[i], GetExposureValue(frameMetadata));
+
+            ASSERT_EQ(OK, listener->waitForFrame(waitLimit));
+            captureBurstTimes.push_back(systemTime());
+            CpuConsumer::LockedBuffer imgBuffer;
+            ASSERT_EQ(OK, consumer->lockNextBuffer(&imgBuffer));
+            ALOGV("Got capture buffer for request %d", i);
+
+            /**
+             * TODO: Validate capture buffer. Current brightness calculation
+             * is too slow, it also doesn't account for saturation effects,
+             * which is quite common since we are going over a significant
+             * range of EVs. we need figure out some reliable way to validate
+             * buffer data.
+             */
+
+            ASSERT_EQ(OK, consumer->unlockBuffer(imgBuffer));
+            if (i > 0) {
+                nsecs_t timeDelta =
+                        captureBurstTimes[i] - captureBurstTimes[i-1];
+                EXPECT_GE(timeDelta, exposures[i]);
+            }
+        }
+    }
+
+    /**
+     * Intentionally shadow default CreateStream function from base class,
+     * because we don't want any test in this class to use the default
+     * stream creation function.
+     */
+    void CreateStream() {
+    }
+};
+
+/**
+ * This test adds multiple stream use case test, basically, test 3
+ * streams:
+ *
+ * 1. Preview stream, with large size that is no bigger than 1080p
+ * we render this stream to display and vary the exposure time for
+ * for certain amount of time for visualization purpose.
+ *
+ * 2. Metering stream, with small size that is no bigger than VGA size.
+ * a burst is issued for different exposure times and analog gains
+ * (or analog gain implemented sensitivities) then check if the capture
+ * result metadata matches the request.
+ *
+ * 3. Capture stream, this is basically similar as meterting stream, but
+ * has large size, which is the largest supported JPEG capture size.
+ *
+ * This multiple stream test is to test if HAL supports:
+ *
+ * 1. Multiple streams like above, HAL should support at least 3 streams
+ * concurrently: one preview stream, 2 other YUV stream.
+ *
+ * 2. Manual control(gain/exposure) of mutiple burst capture.
+ */
+TEST_F(CameraMultiStreamTest, MultiBurst) {
+
+    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);
+
+    camera_metadata_ro_entry availableJpegSizes =
+        GetStaticEntry(ANDROID_SCALER_AVAILABLE_JPEG_SIZES);
+    ASSERT_EQ(0u, availableJpegSizes.count % 2);
+    ASSERT_GE(availableJpegSizes.count, 2u);
+
+    // 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);
+    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) {
+        minFrameDuration =
+            availableProcessedMinFrameDurations.data.i64[maxIdx / 2];
+    }
+
+    EXPECT_GT(minFrameDuration, 0);
+
+    if (minFrameDuration <= 0) {
+        minFrameDuration = DEFAULT_FRAME_DURATION;
+    }
+
+    ALOGV("targeted minimal frame duration is: %lldns", minFrameDuration);
+
+    data = &(availableJpegSizes.data.i32[0]);
+    count = availableJpegSizes.count;
+    GetMaxSize(data, count, &jpegMaxSize, &maxIdx);
+    ALOGV("Found Jpeg size max idx = %d", maxIdx);
+
+    // Max Jpeg size should be available in processed sizes. Use it for
+    // YUV capture anyway.
+    EXPECT_EQ(processedMaxSize.width, jpegMaxSize.width);
+    EXPECT_EQ(processedMaxSize.height, jpegMaxSize.height);
+
+    // Cap preview size.
+    Size previewLimit = { PREVIEW_WIDTH_CAP, PREVIEW_HEIGHT_CAP };
+    // FIXME: need make sure the previewLimit is supported by HAL.
+    Size previewSize = CapSize(previewLimit, processedMaxSize);
+    // Cap Metering size.
+    Size meteringLimit = { METERING_WIDTH_CAP, METERING_HEIGHT_CAP };
+    // Cap metering size to VGA (VGA is mandatory by CDD)
+    Size meteringSize = CapSize(meteringLimit, processedMinSize);
+    // Capture stream should be the max size of jpeg sizes.
+    ALOGV("preview size: %dx%d, metering size: %dx%d, capture size: %dx%d",
+            previewSize.width, previewSize.height,
+            meteringSize.width, meteringSize.height,
+            jpegMaxSize.width, jpegMaxSize.height);
+
+    // Create streams
+    // Preview stream: small resolution, render on the screen.
+    sp<CameraStream> previewStream;
+    {
+        sp<ANativeWindow> surface;
+        ASSERT_NO_FATAL_FAILURE(CreateOnScreenSurface(/*out*/surface));
+        previewStream = CreateStream(
+                previewSize.width,
+                previewSize.height,
+                mDevice,
+                DISPLAY_STREAM_PARAMETERS,
+                surface,
+                false);
+        ASSERT_NE((void*)NULL, previewStream.get());
+        ASSERT_NO_FATAL_FAILURE(previewStream->SetUp());
+    }
+    // Metering burst stream: small resolution yuv stream
+    sp<CameraStream> meteringStream =
+            CreateStream(
+                    meteringSize.width,
+                    meteringSize.height,
+                    mDevice);
+    ASSERT_NE((void*)NULL, meteringStream.get());
+    ASSERT_NO_FATAL_FAILURE(meteringStream->SetUp());
+    // Capture burst stream: full resolution yuv stream
+    sp<CameraStream> captureStream =
+            CreateStream(
+                    jpegMaxSize.width,
+                    jpegMaxSize.height,
+                    mDevice);
+    ASSERT_NE((void*)NULL, captureStream.get());
+    ASSERT_NO_FATAL_FAILURE(captureStream->SetUp());
+
+    // Create Preview request.
+    CameraMetadata previewRequest, meteringRequest, captureRequest;
+    ASSERT_NO_FATAL_FAILURE(CreateRequests(previewRequest, meteringRequest,
+            captureRequest, previewStream->GetStreamId(),
+            meteringStream->GetStreamId(), captureStream->GetStreamId()));
+
+    // Start preview
+    if (CAMERA_MULTI_STREAM_DEBUGGING) {
+        previewRequest.dump(STDOUT_FILENO);
+    }
+
+    // Generate exposure and sensitivity lists
+    camera_metadata_ro_entry exposureTimeRange =
+        GetStaticEntry(ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE);
+    ASSERT_EQ(exposureTimeRange.count, 2u);
+    int64_t minExp = exposureTimeRange.data.i64[0];
+    int64_t maxExp = exposureTimeRange.data.i64[1];
+    ASSERT_GT(maxExp, minExp);
+
+    camera_metadata_ro_entry sensivityRange =
+        GetStaticEntry(ANDROID_SENSOR_INFO_SENSITIVITY_RANGE);
+    ASSERT_EQ(2u, sensivityRange.count);
+    int32_t minSensitivity = sensivityRange.data.i32[0];
+    int32_t maxSensitivity = sensivityRange.data.i32[1];
+    camera_metadata_ro_entry maxAnalogSenEntry =
+            GetStaticEntry(ANDROID_SENSOR_MAX_ANALOG_SENSITIVITY);
+    EXPECT_EQ(1u, maxAnalogSenEntry.count);
+    int32_t maxAnalogSensitivity = maxAnalogSenEntry.data.i32[0];
+    EXPECT_LE(maxAnalogSensitivity, maxSensitivity);
+    // Only test the sensitivity implemented by analog gain.
+    if (maxAnalogSensitivity > maxSensitivity) {
+        // Fallback to maxSensitity
+        maxAnalogSensitivity = maxSensitivity;
+    }
+
+    // sensitivity list, only include the sensitivities that are implemented
+    // purely by analog gain if possible.
+    Vector<int32_t> sensitivities;
+    Vector<int64_t> exposures;
+    count = (maxAnalogSensitivity - minSensitivity + 99) / 100;
+    sensitivities.push_back(minSensitivity);
+    for (size_t i = 1; i < count; i++) {
+        sensitivities.push_back(minSensitivity + i * 100);
+    }
+    sensitivities.push_back(maxAnalogSensitivity);
+    ALOGV("Sensitivity Range: min=%d, max=%d", minSensitivity,
+            maxAnalogSensitivity);
+    int64_t exp = minExp;
+    while (exp < maxExp) {
+        exposures.push_back(exp);
+        exp *= 2;
+    }
+    // Sweep the exposure value for preview, just for visual inspection purpose.
+    uint8_t cmOff = static_cast<uint8_t>(ANDROID_CONTROL_MODE_OFF);
+    for (size_t i = 0; i < exposures.size(); i++) {
+        ASSERT_EQ(OK, previewRequest.update(
+                ANDROID_CONTROL_MODE,
+                &cmOff, 1));
+        ASSERT_EQ(OK, previewRequest.update(
+                ANDROID_SENSOR_EXPOSURE_TIME,
+                &exposures[i], 1));
+        ALOGV("Submitting preview request %d with exposure %lld",
+                i, exposures[i]);
+
+        ASSERT_EQ(OK, mDevice->setStreamingRequest(previewRequest));
+
+        // Let preview run 200ms on screen for each exposure time.
+        usleep(PREVIEW_RENDERING_TIME_INTERVAL);
+    }
+
+    size_t requestCount = sensitivities.size();
+    if (requestCount > exposures.size()) {
+        requestCount = exposures.size();
+    }
+
+    /**
+     * Submit metering request, set default frame duration to minimal possible
+     * value, we want the capture to run as fast as possible. HAL should adjust
+     * the frame duration to minimal necessary value to support the requested
+     * exposure value if exposure is larger than frame duration.
+     */
+    CaptureBurst(meteringRequest, requestCount, exposures, sensitivities,
+            meteringStream, minFrameDuration);
+
+    /**
+     * Submit capture request, set default frame duration to minimal possible
+     * value, we want the capture to run as fast as possible. HAL should adjust
+     * the frame duration to minimal necessary value to support the requested
+     * exposure value if exposure is larger than frame duration.
+     */
+    CaptureBurst(captureRequest, requestCount, exposures, sensitivities,
+            captureStream, minFrameDuration);
+
+    ASSERT_EQ(OK, mDevice->clearStreamingRequest());
+}
+
+}
+}
+}
