18ef0144a52df7edfb754efce597e078bc185c57dZhijun He/*
28ef0144a52df7edfb754efce597e078bc185c57dZhijun He * Copyright (C) 2013 The Android Open Source Project
38ef0144a52df7edfb754efce597e078bc185c57dZhijun He *
48ef0144a52df7edfb754efce597e078bc185c57dZhijun He * Licensed under the Apache License, Version 2.0 (the "License");
58ef0144a52df7edfb754efce597e078bc185c57dZhijun He * you may not use this file except in compliance with the License.
68ef0144a52df7edfb754efce597e078bc185c57dZhijun He * You may obtain a copy of the License at
78ef0144a52df7edfb754efce597e078bc185c57dZhijun He *
88ef0144a52df7edfb754efce597e078bc185c57dZhijun He *      http://www.apache.org/licenses/LICENSE-2.0
98ef0144a52df7edfb754efce597e078bc185c57dZhijun He *
108ef0144a52df7edfb754efce597e078bc185c57dZhijun He * Unless required by applicable law or agreed to in writing, software
118ef0144a52df7edfb754efce597e078bc185c57dZhijun He * distributed under the License is distributed on an "AS IS" BASIS,
128ef0144a52df7edfb754efce597e078bc185c57dZhijun He * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138ef0144a52df7edfb754efce597e078bc185c57dZhijun He * See the License for the specific language governing permissions and
148ef0144a52df7edfb754efce597e078bc185c57dZhijun He * limitations under the License.
158ef0144a52df7edfb754efce597e078bc185c57dZhijun He */
168ef0144a52df7edfb754efce597e078bc185c57dZhijun He
170ab4c96ab8889127955971bbf5c157b7191cd1eaSasha Levitskiy#include <inttypes.h>
188ef0144a52df7edfb754efce597e078bc185c57dZhijun He#define LOG_TAG "CameraMultiStreamTest"
198ef0144a52df7edfb754efce597e078bc185c57dZhijun He//#define LOG_NDEBUG 0
208ef0144a52df7edfb754efce597e078bc185c57dZhijun He#include "CameraStreamFixture.h"
218ef0144a52df7edfb754efce597e078bc185c57dZhijun He#include "TestExtensions.h"
228ef0144a52df7edfb754efce597e078bc185c57dZhijun He
238ef0144a52df7edfb754efce597e078bc185c57dZhijun He#include <gtest/gtest.h>
248ef0144a52df7edfb754efce597e078bc185c57dZhijun He#include <utils/Log.h>
258ef0144a52df7edfb754efce597e078bc185c57dZhijun He#include <utils/StrongPointer.h>
268ef0144a52df7edfb754efce597e078bc185c57dZhijun He#include <common/CameraDeviceBase.h>
278ef0144a52df7edfb754efce597e078bc185c57dZhijun He#include <hardware/hardware.h>
288ef0144a52df7edfb754efce597e078bc185c57dZhijun He#include <hardware/camera2.h>
298ef0144a52df7edfb754efce597e078bc185c57dZhijun He#include <gui/SurfaceComposerClient.h>
308ef0144a52df7edfb754efce597e078bc185c57dZhijun He#include <gui/Surface.h>
318ef0144a52df7edfb754efce597e078bc185c57dZhijun He
328ef0144a52df7edfb754efce597e078bc185c57dZhijun He#define DEFAULT_FRAME_DURATION 33000000LL // 33ms
338ef0144a52df7edfb754efce597e078bc185c57dZhijun He#define CAMERA_HEAP_COUNT       1
348ef0144a52df7edfb754efce597e078bc185c57dZhijun He#define CAMERA_EXPOSURE_FORMAT CAMERA_STREAM_AUTO_CPU_FORMAT
358ef0144a52df7edfb754efce597e078bc185c57dZhijun He#define CAMERA_DISPLAY_FORMAT HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED
368ef0144a52df7edfb754efce597e078bc185c57dZhijun He#define CAMERA_MULTI_STREAM_DEBUGGING  0
378ef0144a52df7edfb754efce597e078bc185c57dZhijun He#define CAMERA_FRAME_TIMEOUT    1000000000LL // nsecs (1 secs)
388ef0144a52df7edfb754efce597e078bc185c57dZhijun He#define PREVIEW_RENDERING_TIME_INTERVAL 200000 // in unit of us, 200ms
39a1bef2b9a66c92d6a1aae32c0b2d7c66fb5305abGaurav Batra// 1% tolerance margin for exposure sanity check against metadata
40a1bef2b9a66c92d6a1aae32c0b2d7c66fb5305abGaurav Batra#define TOLERANCE_MARGIN_METADATA 0.01
41a1bef2b9a66c92d6a1aae32c0b2d7c66fb5305abGaurav Batra// 5% tolerance margin for exposure sanity check against capture times
42a1bef2b9a66c92d6a1aae32c0b2d7c66fb5305abGaurav Batra#define TOLERANCE_MARGIN_CAPTURE 0.05
438ef0144a52df7edfb754efce597e078bc185c57dZhijun He/* constants for display */
448ef0144a52df7edfb754efce597e078bc185c57dZhijun He#define DISPLAY_BUFFER_HEIGHT 1024
458ef0144a52df7edfb754efce597e078bc185c57dZhijun He#define DISPLAY_BUFFER_WIDTH 1024
468ef0144a52df7edfb754efce597e078bc185c57dZhijun He#define DISPLAY_BUFFER_FORMAT PIXEL_FORMAT_RGB_888
478ef0144a52df7edfb754efce597e078bc185c57dZhijun He
488ef0144a52df7edfb754efce597e078bc185c57dZhijun He// This test intends to test large preview size but less than 1080p.
498ef0144a52df7edfb754efce597e078bc185c57dZhijun He#define PREVIEW_WIDTH_CAP   1920
508ef0144a52df7edfb754efce597e078bc185c57dZhijun He#define PREVIEW_HEIGHT_CAP  1080
518ef0144a52df7edfb754efce597e078bc185c57dZhijun He// This test intends to test small metering burst size that is less than 640x480
528ef0144a52df7edfb754efce597e078bc185c57dZhijun He#define METERING_WIDTH_CAP  640
538ef0144a52df7edfb754efce597e078bc185c57dZhijun He#define METERING_HEIGHT_CAP 480
548ef0144a52df7edfb754efce597e078bc185c57dZhijun He
558ef0144a52df7edfb754efce597e078bc185c57dZhijun He#define EXP_WAIT_MULTIPLIER 2
568ef0144a52df7edfb754efce597e078bc185c57dZhijun He
578ef0144a52df7edfb754efce597e078bc185c57dZhijun Henamespace android {
588ef0144a52df7edfb754efce597e078bc185c57dZhijun Henamespace camera2 {
598ef0144a52df7edfb754efce597e078bc185c57dZhijun Henamespace tests {
608ef0144a52df7edfb754efce597e078bc185c57dZhijun He
618ef0144a52df7edfb754efce597e078bc185c57dZhijun Hestatic const CameraStreamParams DEFAULT_STREAM_PARAMETERS = {
628ef0144a52df7edfb754efce597e078bc185c57dZhijun He    /*mFormat*/     CAMERA_EXPOSURE_FORMAT,
638ef0144a52df7edfb754efce597e078bc185c57dZhijun He    /*mHeapCount*/  CAMERA_HEAP_COUNT
648ef0144a52df7edfb754efce597e078bc185c57dZhijun He};
658ef0144a52df7edfb754efce597e078bc185c57dZhijun He
668ef0144a52df7edfb754efce597e078bc185c57dZhijun Hestatic const CameraStreamParams DISPLAY_STREAM_PARAMETERS = {
678ef0144a52df7edfb754efce597e078bc185c57dZhijun He    /*mFormat*/     CAMERA_DISPLAY_FORMAT,
688ef0144a52df7edfb754efce597e078bc185c57dZhijun He    /*mHeapCount*/  CAMERA_HEAP_COUNT
698ef0144a52df7edfb754efce597e078bc185c57dZhijun He};
708ef0144a52df7edfb754efce597e078bc185c57dZhijun He
718ef0144a52df7edfb754efce597e078bc185c57dZhijun Heclass CameraMultiStreamTest
728ef0144a52df7edfb754efce597e078bc185c57dZhijun He    : public ::testing::Test,
738ef0144a52df7edfb754efce597e078bc185c57dZhijun He      public CameraStreamFixture {
748ef0144a52df7edfb754efce597e078bc185c57dZhijun He
758ef0144a52df7edfb754efce597e078bc185c57dZhijun Hepublic:
768ef0144a52df7edfb754efce597e078bc185c57dZhijun He    CameraMultiStreamTest() : CameraStreamFixture(DEFAULT_STREAM_PARAMETERS) {
778ef0144a52df7edfb754efce597e078bc185c57dZhijun He        TEST_EXTENSION_FORKING_CONSTRUCTOR;
788ef0144a52df7edfb754efce597e078bc185c57dZhijun He
798ef0144a52df7edfb754efce597e078bc185c57dZhijun He        if (HasFatalFailure()) {
808ef0144a52df7edfb754efce597e078bc185c57dZhijun He            return;
818ef0144a52df7edfb754efce597e078bc185c57dZhijun He        }
828ef0144a52df7edfb754efce597e078bc185c57dZhijun He        /**
838ef0144a52df7edfb754efce597e078bc185c57dZhijun He         * Don't create default stream, each test is in charge of creating
848ef0144a52df7edfb754efce597e078bc185c57dZhijun He         * its own streams.
858ef0144a52df7edfb754efce597e078bc185c57dZhijun He         */
868ef0144a52df7edfb754efce597e078bc185c57dZhijun He    }
878ef0144a52df7edfb754efce597e078bc185c57dZhijun He
888ef0144a52df7edfb754efce597e078bc185c57dZhijun He    ~CameraMultiStreamTest() {
898ef0144a52df7edfb754efce597e078bc185c57dZhijun He        TEST_EXTENSION_FORKING_DESTRUCTOR;
908ef0144a52df7edfb754efce597e078bc185c57dZhijun He    }
918ef0144a52df7edfb754efce597e078bc185c57dZhijun He
928ef0144a52df7edfb754efce597e078bc185c57dZhijun He    sp<SurfaceComposerClient> mComposerClient;
938ef0144a52df7edfb754efce597e078bc185c57dZhijun He    sp<SurfaceControl> mSurfaceControl;
948ef0144a52df7edfb754efce597e078bc185c57dZhijun He
958ef0144a52df7edfb754efce597e078bc185c57dZhijun He    void CreateOnScreenSurface(sp<ANativeWindow>& surface) {
968ef0144a52df7edfb754efce597e078bc185c57dZhijun He        mComposerClient = new SurfaceComposerClient;
978ef0144a52df7edfb754efce597e078bc185c57dZhijun He        ASSERT_EQ(NO_ERROR, mComposerClient->initCheck());
988ef0144a52df7edfb754efce597e078bc185c57dZhijun He
998ef0144a52df7edfb754efce597e078bc185c57dZhijun He        mSurfaceControl = mComposerClient->createSurface(
1008ef0144a52df7edfb754efce597e078bc185c57dZhijun He                String8("CameraMultiStreamTest StreamingImage Surface"),
1018ef0144a52df7edfb754efce597e078bc185c57dZhijun He                DISPLAY_BUFFER_HEIGHT, DISPLAY_BUFFER_WIDTH,
1028ef0144a52df7edfb754efce597e078bc185c57dZhijun He                DISPLAY_BUFFER_FORMAT, 0);
1038ef0144a52df7edfb754efce597e078bc185c57dZhijun He
1048ef0144a52df7edfb754efce597e078bc185c57dZhijun He        ASSERT_NE((void*)NULL, mSurfaceControl.get());
1058ef0144a52df7edfb754efce597e078bc185c57dZhijun He        ASSERT_TRUE(mSurfaceControl->isValid());
1068ef0144a52df7edfb754efce597e078bc185c57dZhijun He
1078ef0144a52df7edfb754efce597e078bc185c57dZhijun He        SurfaceComposerClient::openGlobalTransaction();
1088ef0144a52df7edfb754efce597e078bc185c57dZhijun He        ASSERT_EQ(NO_ERROR, mSurfaceControl->setLayer(0x7FFFFFFF));
1098ef0144a52df7edfb754efce597e078bc185c57dZhijun He        ASSERT_EQ(NO_ERROR, mSurfaceControl->show());
1108ef0144a52df7edfb754efce597e078bc185c57dZhijun He        SurfaceComposerClient::closeGlobalTransaction();
1118ef0144a52df7edfb754efce597e078bc185c57dZhijun He
1128ef0144a52df7edfb754efce597e078bc185c57dZhijun He        surface = mSurfaceControl->getSurface();
1138ef0144a52df7edfb754efce597e078bc185c57dZhijun He
1148ef0144a52df7edfb754efce597e078bc185c57dZhijun He        ASSERT_NE((void*)NULL, surface.get());
1158ef0144a52df7edfb754efce597e078bc185c57dZhijun He    }
1168ef0144a52df7edfb754efce597e078bc185c57dZhijun He
1178ef0144a52df7edfb754efce597e078bc185c57dZhijun He    struct Size {
1188ef0144a52df7edfb754efce597e078bc185c57dZhijun He        int32_t width;
1198ef0144a52df7edfb754efce597e078bc185c57dZhijun He        int32_t height;
1208ef0144a52df7edfb754efce597e078bc185c57dZhijun He    };
1218ef0144a52df7edfb754efce597e078bc185c57dZhijun He
1228ef0144a52df7edfb754efce597e078bc185c57dZhijun He    // Select minimal size by number of pixels.
1238ef0144a52df7edfb754efce597e078bc185c57dZhijun He    void GetMinSize(const int32_t* data, size_t count,
1248ef0144a52df7edfb754efce597e078bc185c57dZhijun He            Size* min, int32_t* idx) {
1258ef0144a52df7edfb754efce597e078bc185c57dZhijun He        ASSERT_NE((int32_t*)NULL, data);
1268ef0144a52df7edfb754efce597e078bc185c57dZhijun He        int32_t minIdx = 0;
1278ef0144a52df7edfb754efce597e078bc185c57dZhijun He        int32_t minSize = INT_MAX, tempSize;
1288ef0144a52df7edfb754efce597e078bc185c57dZhijun He        for (size_t i = 0; i < count; i+=2) {
1298ef0144a52df7edfb754efce597e078bc185c57dZhijun He            tempSize = data[i] * data[i+1];
1308ef0144a52df7edfb754efce597e078bc185c57dZhijun He            if (minSize > tempSize) {
1318ef0144a52df7edfb754efce597e078bc185c57dZhijun He                minSize = tempSize;
1328ef0144a52df7edfb754efce597e078bc185c57dZhijun He                minIdx = i;
1338ef0144a52df7edfb754efce597e078bc185c57dZhijun He            }
1348ef0144a52df7edfb754efce597e078bc185c57dZhijun He        }
1358ef0144a52df7edfb754efce597e078bc185c57dZhijun He        min->width = data[minIdx];
1368ef0144a52df7edfb754efce597e078bc185c57dZhijun He        min->height = data[minIdx + 1];
1378ef0144a52df7edfb754efce597e078bc185c57dZhijun He        *idx = minIdx;
1388ef0144a52df7edfb754efce597e078bc185c57dZhijun He    }
1398ef0144a52df7edfb754efce597e078bc185c57dZhijun He
1408ef0144a52df7edfb754efce597e078bc185c57dZhijun He    // Select maximal size by number of pixels.
1418ef0144a52df7edfb754efce597e078bc185c57dZhijun He    void GetMaxSize(const int32_t* data, size_t count,
1428ef0144a52df7edfb754efce597e078bc185c57dZhijun He            Size* max, int32_t* idx) {
1438ef0144a52df7edfb754efce597e078bc185c57dZhijun He        ASSERT_NE((int32_t*)NULL, data);
1448ef0144a52df7edfb754efce597e078bc185c57dZhijun He        int32_t maxIdx = 0;
1458ef0144a52df7edfb754efce597e078bc185c57dZhijun He        int32_t maxSize = INT_MIN, tempSize;
1468ef0144a52df7edfb754efce597e078bc185c57dZhijun He        for (size_t i = 0; i < count; i+=2) {
1478ef0144a52df7edfb754efce597e078bc185c57dZhijun He            tempSize = data[i] * data[i+1];
1488ef0144a52df7edfb754efce597e078bc185c57dZhijun He            if (maxSize < tempSize) {
1498ef0144a52df7edfb754efce597e078bc185c57dZhijun He                maxSize = tempSize;
1508ef0144a52df7edfb754efce597e078bc185c57dZhijun He                maxIdx = i;
1518ef0144a52df7edfb754efce597e078bc185c57dZhijun He            }
1528ef0144a52df7edfb754efce597e078bc185c57dZhijun He        }
1538ef0144a52df7edfb754efce597e078bc185c57dZhijun He        max->width = data[maxIdx];
1548ef0144a52df7edfb754efce597e078bc185c57dZhijun He        max->height = data[maxIdx + 1];
1558ef0144a52df7edfb754efce597e078bc185c57dZhijun He        *idx = maxIdx;
1568ef0144a52df7edfb754efce597e078bc185c57dZhijun He    }
1578ef0144a52df7edfb754efce597e078bc185c57dZhijun He
1588ef0144a52df7edfb754efce597e078bc185c57dZhijun He    // Cap size by number of pixels.
1598ef0144a52df7edfb754efce597e078bc185c57dZhijun He    Size CapSize(Size cap, Size input) {
1608ef0144a52df7edfb754efce597e078bc185c57dZhijun He        if (input.width * input.height > cap.width * cap.height) {
1618ef0144a52df7edfb754efce597e078bc185c57dZhijun He            return cap;
1628ef0144a52df7edfb754efce597e078bc185c57dZhijun He        }
1638ef0144a52df7edfb754efce597e078bc185c57dZhijun He        return input;
1648ef0144a52df7edfb754efce597e078bc185c57dZhijun He    }
1658ef0144a52df7edfb754efce597e078bc185c57dZhijun He
1668ef0144a52df7edfb754efce597e078bc185c57dZhijun He    struct CameraStream : public RefBase {
1678ef0144a52df7edfb754efce597e078bc185c57dZhijun He
1688ef0144a52df7edfb754efce597e078bc185c57dZhijun He    public:
1698ef0144a52df7edfb754efce597e078bc185c57dZhijun He        /**
1708ef0144a52df7edfb754efce597e078bc185c57dZhijun He         * Only initialize the variables here, do the ASSERT check in
1718ef0144a52df7edfb754efce597e078bc185c57dZhijun He         * SetUp function. To make this stream useful, the SetUp must
1728ef0144a52df7edfb754efce597e078bc185c57dZhijun He         * be called before using it.
1738ef0144a52df7edfb754efce597e078bc185c57dZhijun He         */
1748ef0144a52df7edfb754efce597e078bc185c57dZhijun He        CameraStream(
1758ef0144a52df7edfb754efce597e078bc185c57dZhijun He                int width,
1768ef0144a52df7edfb754efce597e078bc185c57dZhijun He                int height,
1778ef0144a52df7edfb754efce597e078bc185c57dZhijun He                const sp<CameraDeviceBase>& device,
1788ef0144a52df7edfb754efce597e078bc185c57dZhijun He                CameraStreamParams param, sp<ANativeWindow> surface,
1798ef0144a52df7edfb754efce597e078bc185c57dZhijun He                bool useCpuConsumer)
1808ef0144a52df7edfb754efce597e078bc185c57dZhijun He            : mDevice(device),
1818ef0144a52df7edfb754efce597e078bc185c57dZhijun He              mWidth(width),
1828ef0144a52df7edfb754efce597e078bc185c57dZhijun He              mHeight(height) {
1838ef0144a52df7edfb754efce597e078bc185c57dZhijun He            mFormat = param.mFormat;
1848ef0144a52df7edfb754efce597e078bc185c57dZhijun He            if (useCpuConsumer) {
1855dce9e4f26a2f227eeb4607128e3c3a92a277ae6Dan Stoza                sp<IGraphicBufferProducer> producer;
1865dce9e4f26a2f227eeb4607128e3c3a92a277ae6Dan Stoza                sp<IGraphicBufferConsumer> consumer;
1875dce9e4f26a2f227eeb4607128e3c3a92a277ae6Dan Stoza                BufferQueue::createBufferQueue(&producer, &consumer);
1885dce9e4f26a2f227eeb4607128e3c3a92a277ae6Dan Stoza                mCpuConsumer = new CpuConsumer(consumer, param.mHeapCount);
1898ef0144a52df7edfb754efce597e078bc185c57dZhijun He                mCpuConsumer->setName(String8(
1908ef0144a52df7edfb754efce597e078bc185c57dZhijun He                        "CameraMultiStreamTest::mCpuConsumer"));
1915dce9e4f26a2f227eeb4607128e3c3a92a277ae6Dan Stoza                mNativeWindow = new Surface(producer);
1928ef0144a52df7edfb754efce597e078bc185c57dZhijun He            } else {
1938ef0144a52df7edfb754efce597e078bc185c57dZhijun He                // Render the stream to screen.
1948ef0144a52df7edfb754efce597e078bc185c57dZhijun He                mCpuConsumer = NULL;
1958ef0144a52df7edfb754efce597e078bc185c57dZhijun He                mNativeWindow = surface;
1968ef0144a52df7edfb754efce597e078bc185c57dZhijun He            }
1978ef0144a52df7edfb754efce597e078bc185c57dZhijun He
1988ef0144a52df7edfb754efce597e078bc185c57dZhijun He            mFrameListener = new FrameListener();
1998ef0144a52df7edfb754efce597e078bc185c57dZhijun He            if (mCpuConsumer != 0) {
2008ef0144a52df7edfb754efce597e078bc185c57dZhijun He                mCpuConsumer->setFrameAvailableListener(mFrameListener);
2018ef0144a52df7edfb754efce597e078bc185c57dZhijun He            }
2028ef0144a52df7edfb754efce597e078bc185c57dZhijun He        }
2038ef0144a52df7edfb754efce597e078bc185c57dZhijun He
2048ef0144a52df7edfb754efce597e078bc185c57dZhijun He        /**
2058ef0144a52df7edfb754efce597e078bc185c57dZhijun He         * Finally create camera stream, and do the ASSERT check, since we
2068ef0144a52df7edfb754efce597e078bc185c57dZhijun He         * can not do it in ctor.
2078ef0144a52df7edfb754efce597e078bc185c57dZhijun He         */
2088ef0144a52df7edfb754efce597e078bc185c57dZhijun He        void SetUp() {
2098ef0144a52df7edfb754efce597e078bc185c57dZhijun He            ASSERT_EQ(OK,
2108ef0144a52df7edfb754efce597e078bc185c57dZhijun He                mDevice->createStream(mNativeWindow,
2111c3e65731a8582d4da24e0ca4e136c372aec9e94Zhijun He                    mWidth, mHeight, mFormat,
2128ef0144a52df7edfb754efce597e078bc185c57dZhijun He                    &mStreamId));
2138ef0144a52df7edfb754efce597e078bc185c57dZhijun He
2148ef0144a52df7edfb754efce597e078bc185c57dZhijun He            ASSERT_NE(-1, mStreamId);
2158ef0144a52df7edfb754efce597e078bc185c57dZhijun He        }
2168ef0144a52df7edfb754efce597e078bc185c57dZhijun He
2178ef0144a52df7edfb754efce597e078bc185c57dZhijun He        int GetStreamId() { return mStreamId; }
2188ef0144a52df7edfb754efce597e078bc185c57dZhijun He        sp<CpuConsumer> GetConsumer() { return mCpuConsumer; }
2198ef0144a52df7edfb754efce597e078bc185c57dZhijun He        sp<FrameListener> GetFrameListener() { return mFrameListener; }
2208ef0144a52df7edfb754efce597e078bc185c57dZhijun He
2218ef0144a52df7edfb754efce597e078bc185c57dZhijun He    protected:
2228ef0144a52df7edfb754efce597e078bc185c57dZhijun He        ~CameraStream() {
2238ef0144a52df7edfb754efce597e078bc185c57dZhijun He            if (mDevice.get()) {
2248ef0144a52df7edfb754efce597e078bc185c57dZhijun He                mDevice->waitUntilDrained();
2258ef0144a52df7edfb754efce597e078bc185c57dZhijun He                mDevice->deleteStream(mStreamId);
2268ef0144a52df7edfb754efce597e078bc185c57dZhijun He            }
2278ef0144a52df7edfb754efce597e078bc185c57dZhijun He            // Clear producer before consumer.
2288ef0144a52df7edfb754efce597e078bc185c57dZhijun He            mNativeWindow.clear();
2298ef0144a52df7edfb754efce597e078bc185c57dZhijun He            mCpuConsumer.clear();
2308ef0144a52df7edfb754efce597e078bc185c57dZhijun He        }
2318ef0144a52df7edfb754efce597e078bc185c57dZhijun He
2328ef0144a52df7edfb754efce597e078bc185c57dZhijun He    private:
2338ef0144a52df7edfb754efce597e078bc185c57dZhijun He        sp<FrameListener>       mFrameListener;
2348ef0144a52df7edfb754efce597e078bc185c57dZhijun He        sp<CpuConsumer>         mCpuConsumer;
2358ef0144a52df7edfb754efce597e078bc185c57dZhijun He        sp<ANativeWindow>       mNativeWindow;
2368ef0144a52df7edfb754efce597e078bc185c57dZhijun He        sp<CameraDeviceBase>    mDevice;
2378ef0144a52df7edfb754efce597e078bc185c57dZhijun He        int                     mStreamId;
2388ef0144a52df7edfb754efce597e078bc185c57dZhijun He        int                     mWidth;
2398ef0144a52df7edfb754efce597e078bc185c57dZhijun He        int                     mHeight;
2408ef0144a52df7edfb754efce597e078bc185c57dZhijun He        int                     mFormat;
2418ef0144a52df7edfb754efce597e078bc185c57dZhijun He    };
2428ef0144a52df7edfb754efce597e078bc185c57dZhijun He
2438ef0144a52df7edfb754efce597e078bc185c57dZhijun He    int64_t GetExposureValue(const CameraMetadata& metaData) {
2448ef0144a52df7edfb754efce597e078bc185c57dZhijun He        camera_metadata_ro_entry_t entry =
2458ef0144a52df7edfb754efce597e078bc185c57dZhijun He                metaData.find(ANDROID_SENSOR_EXPOSURE_TIME);
2468ef0144a52df7edfb754efce597e078bc185c57dZhijun He        EXPECT_EQ(1u, entry.count);
2478ef0144a52df7edfb754efce597e078bc185c57dZhijun He        if (entry.count == 1) {
2488ef0144a52df7edfb754efce597e078bc185c57dZhijun He            return entry.data.i64[0];
2498ef0144a52df7edfb754efce597e078bc185c57dZhijun He        }
2508ef0144a52df7edfb754efce597e078bc185c57dZhijun He        return -1;
2518ef0144a52df7edfb754efce597e078bc185c57dZhijun He    }
2528ef0144a52df7edfb754efce597e078bc185c57dZhijun He
2538ef0144a52df7edfb754efce597e078bc185c57dZhijun He    int32_t GetSensitivity(const CameraMetadata& metaData) {
2548ef0144a52df7edfb754efce597e078bc185c57dZhijun He        camera_metadata_ro_entry_t entry =
2558ef0144a52df7edfb754efce597e078bc185c57dZhijun He                metaData.find(ANDROID_SENSOR_SENSITIVITY);
2568ef0144a52df7edfb754efce597e078bc185c57dZhijun He        EXPECT_EQ(1u, entry.count);
2578ef0144a52df7edfb754efce597e078bc185c57dZhijun He        if (entry.count == 1) {
2588ef0144a52df7edfb754efce597e078bc185c57dZhijun He            return entry.data.i32[0];
2598ef0144a52df7edfb754efce597e078bc185c57dZhijun He        }
2608ef0144a52df7edfb754efce597e078bc185c57dZhijun He        return -1;
2618ef0144a52df7edfb754efce597e078bc185c57dZhijun He    }
2628ef0144a52df7edfb754efce597e078bc185c57dZhijun He
2638ef0144a52df7edfb754efce597e078bc185c57dZhijun He    int64_t GetFrameDuration(const CameraMetadata& metaData) {
2648ef0144a52df7edfb754efce597e078bc185c57dZhijun He        camera_metadata_ro_entry_t entry =
2658ef0144a52df7edfb754efce597e078bc185c57dZhijun He                metaData.find(ANDROID_SENSOR_FRAME_DURATION);
2668ef0144a52df7edfb754efce597e078bc185c57dZhijun He        EXPECT_EQ(1u, entry.count);
2678ef0144a52df7edfb754efce597e078bc185c57dZhijun He        if (entry.count == 1) {
2688ef0144a52df7edfb754efce597e078bc185c57dZhijun He            return entry.data.i64[0];
2698ef0144a52df7edfb754efce597e078bc185c57dZhijun He        }
2708ef0144a52df7edfb754efce597e078bc185c57dZhijun He        return -1;
2718ef0144a52df7edfb754efce597e078bc185c57dZhijun He    }
2728ef0144a52df7edfb754efce597e078bc185c57dZhijun He
2738ef0144a52df7edfb754efce597e078bc185c57dZhijun He    void CreateRequests(CameraMetadata& previewRequest,
2748ef0144a52df7edfb754efce597e078bc185c57dZhijun He            CameraMetadata& meteringRequest,
2758ef0144a52df7edfb754efce597e078bc185c57dZhijun He            CameraMetadata& captureRequest,
2768ef0144a52df7edfb754efce597e078bc185c57dZhijun He            int previewStreamId,
2778ef0144a52df7edfb754efce597e078bc185c57dZhijun He            int meteringStreamId,
2788ef0144a52df7edfb754efce597e078bc185c57dZhijun He            int captureStreamId) {
279914226ce7607ed991d7e0e0477d0575e6fc02d37Zhijun He        int32_t requestId = 0;
280914226ce7607ed991d7e0e0477d0575e6fc02d37Zhijun He        Vector<int32_t> previewStreamIds;
281914226ce7607ed991d7e0e0477d0575e6fc02d37Zhijun He        previewStreamIds.push(previewStreamId);
282914226ce7607ed991d7e0e0477d0575e6fc02d37Zhijun He        ASSERT_EQ(OK, mDevice->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
283914226ce7607ed991d7e0e0477d0575e6fc02d37Zhijun He                &previewRequest));
284914226ce7607ed991d7e0e0477d0575e6fc02d37Zhijun He        ASSERT_EQ(OK, previewRequest.update(ANDROID_REQUEST_OUTPUT_STREAMS,
285914226ce7607ed991d7e0e0477d0575e6fc02d37Zhijun He                previewStreamIds));
286914226ce7607ed991d7e0e0477d0575e6fc02d37Zhijun He        ASSERT_EQ(OK, previewRequest.update(ANDROID_REQUEST_ID,
287914226ce7607ed991d7e0e0477d0575e6fc02d37Zhijun He                &requestId, 1));
288914226ce7607ed991d7e0e0477d0575e6fc02d37Zhijun He
289914226ce7607ed991d7e0e0477d0575e6fc02d37Zhijun He        // Create metering request, manual settings
290914226ce7607ed991d7e0e0477d0575e6fc02d37Zhijun He        // Manual control: Disable 3A, noise reduction, edge sharping
291914226ce7607ed991d7e0e0477d0575e6fc02d37Zhijun He        uint8_t cmOff = static_cast<uint8_t>(ANDROID_CONTROL_MODE_OFF);
292914226ce7607ed991d7e0e0477d0575e6fc02d37Zhijun He        uint8_t nrOff = static_cast<uint8_t>(ANDROID_NOISE_REDUCTION_MODE_OFF);
293914226ce7607ed991d7e0e0477d0575e6fc02d37Zhijun He        uint8_t sharpOff = static_cast<uint8_t>(ANDROID_EDGE_MODE_OFF);
294914226ce7607ed991d7e0e0477d0575e6fc02d37Zhijun He        Vector<int32_t> meteringStreamIds;
295914226ce7607ed991d7e0e0477d0575e6fc02d37Zhijun He        meteringStreamIds.push(meteringStreamId);
296914226ce7607ed991d7e0e0477d0575e6fc02d37Zhijun He        ASSERT_EQ(OK, mDevice->createDefaultRequest(
297914226ce7607ed991d7e0e0477d0575e6fc02d37Zhijun He                CAMERA2_TEMPLATE_PREVIEW,
298914226ce7607ed991d7e0e0477d0575e6fc02d37Zhijun He                &meteringRequest));
299914226ce7607ed991d7e0e0477d0575e6fc02d37Zhijun He        ASSERT_EQ(OK, meteringRequest.update(
300914226ce7607ed991d7e0e0477d0575e6fc02d37Zhijun He                ANDROID_REQUEST_OUTPUT_STREAMS,
301914226ce7607ed991d7e0e0477d0575e6fc02d37Zhijun He                meteringStreamIds));
302914226ce7607ed991d7e0e0477d0575e6fc02d37Zhijun He        ASSERT_EQ(OK, meteringRequest.update(
303914226ce7607ed991d7e0e0477d0575e6fc02d37Zhijun He                ANDROID_CONTROL_MODE,
304914226ce7607ed991d7e0e0477d0575e6fc02d37Zhijun He                &cmOff, 1));
305914226ce7607ed991d7e0e0477d0575e6fc02d37Zhijun He        ASSERT_EQ(OK, meteringRequest.update(
306914226ce7607ed991d7e0e0477d0575e6fc02d37Zhijun He                ANDROID_NOISE_REDUCTION_MODE,
307914226ce7607ed991d7e0e0477d0575e6fc02d37Zhijun He                &nrOff, 1));
308914226ce7607ed991d7e0e0477d0575e6fc02d37Zhijun He        ASSERT_EQ(OK, meteringRequest.update(
309914226ce7607ed991d7e0e0477d0575e6fc02d37Zhijun He                ANDROID_EDGE_MODE,
310914226ce7607ed991d7e0e0477d0575e6fc02d37Zhijun He                &sharpOff, 1));
311914226ce7607ed991d7e0e0477d0575e6fc02d37Zhijun He
312914226ce7607ed991d7e0e0477d0575e6fc02d37Zhijun He        // Create capture request, manual settings
313914226ce7607ed991d7e0e0477d0575e6fc02d37Zhijun He        Vector<int32_t> captureStreamIds;
314914226ce7607ed991d7e0e0477d0575e6fc02d37Zhijun He        captureStreamIds.push(captureStreamId);
315914226ce7607ed991d7e0e0477d0575e6fc02d37Zhijun He        ASSERT_EQ(OK, mDevice->createDefaultRequest(
316914226ce7607ed991d7e0e0477d0575e6fc02d37Zhijun He                CAMERA2_TEMPLATE_PREVIEW,
317914226ce7607ed991d7e0e0477d0575e6fc02d37Zhijun He                &captureRequest));
318914226ce7607ed991d7e0e0477d0575e6fc02d37Zhijun He        ASSERT_EQ(OK, captureRequest.update(
319914226ce7607ed991d7e0e0477d0575e6fc02d37Zhijun He                ANDROID_REQUEST_OUTPUT_STREAMS,
320914226ce7607ed991d7e0e0477d0575e6fc02d37Zhijun He                captureStreamIds));
321914226ce7607ed991d7e0e0477d0575e6fc02d37Zhijun He        ASSERT_EQ(OK, captureRequest.update(
322914226ce7607ed991d7e0e0477d0575e6fc02d37Zhijun He                ANDROID_CONTROL_MODE,
323914226ce7607ed991d7e0e0477d0575e6fc02d37Zhijun He                &cmOff, 1));
324914226ce7607ed991d7e0e0477d0575e6fc02d37Zhijun He        ASSERT_EQ(OK, captureRequest.update(
325914226ce7607ed991d7e0e0477d0575e6fc02d37Zhijun He                ANDROID_NOISE_REDUCTION_MODE,
326914226ce7607ed991d7e0e0477d0575e6fc02d37Zhijun He                &nrOff, 1));
327914226ce7607ed991d7e0e0477d0575e6fc02d37Zhijun He        ASSERT_EQ(OK, captureRequest.update(
328914226ce7607ed991d7e0e0477d0575e6fc02d37Zhijun He                ANDROID_EDGE_MODE,
329914226ce7607ed991d7e0e0477d0575e6fc02d37Zhijun He                &sharpOff, 1));
3308ef0144a52df7edfb754efce597e078bc185c57dZhijun He    }
3318ef0144a52df7edfb754efce597e078bc185c57dZhijun He
3328ef0144a52df7edfb754efce597e078bc185c57dZhijun He    sp<CameraStream> CreateStream(
3338ef0144a52df7edfb754efce597e078bc185c57dZhijun He            int width,
3348ef0144a52df7edfb754efce597e078bc185c57dZhijun He            int height,
3358ef0144a52df7edfb754efce597e078bc185c57dZhijun He            const sp<CameraDeviceBase>& device,
3368ef0144a52df7edfb754efce597e078bc185c57dZhijun He            CameraStreamParams param = DEFAULT_STREAM_PARAMETERS,
3378ef0144a52df7edfb754efce597e078bc185c57dZhijun He            sp<ANativeWindow> surface = NULL,
3388ef0144a52df7edfb754efce597e078bc185c57dZhijun He            bool useCpuConsumer = true) {
3398ef0144a52df7edfb754efce597e078bc185c57dZhijun He        param.mFormat = MapAutoFormat(param.mFormat);
3408ef0144a52df7edfb754efce597e078bc185c57dZhijun He        return new CameraStream(width, height, device,
3418ef0144a52df7edfb754efce597e078bc185c57dZhijun He                param, surface, useCpuConsumer);
3428ef0144a52df7edfb754efce597e078bc185c57dZhijun He    }
3438ef0144a52df7edfb754efce597e078bc185c57dZhijun He
3448ef0144a52df7edfb754efce597e078bc185c57dZhijun He    void CaptureBurst(CameraMetadata& request, size_t requestCount,
3458ef0144a52df7edfb754efce597e078bc185c57dZhijun He            const Vector<int64_t>& exposures,
3468ef0144a52df7edfb754efce597e078bc185c57dZhijun He            const Vector<int32_t>& sensitivities,
3478ef0144a52df7edfb754efce597e078bc185c57dZhijun He            const sp<CameraStream>& stream,
348914226ce7607ed991d7e0e0477d0575e6fc02d37Zhijun He            int64_t minFrameDuration,
349914226ce7607ed991d7e0e0477d0575e6fc02d37Zhijun He            int32_t* requestIdStart) {
3508ef0144a52df7edfb754efce597e078bc185c57dZhijun He        ASSERT_EQ(OK, request.update(ANDROID_SENSOR_FRAME_DURATION,
3518ef0144a52df7edfb754efce597e078bc185c57dZhijun He                &minFrameDuration, 1));
3528ef0144a52df7edfb754efce597e078bc185c57dZhijun He        // Submit a series of requests with the specified exposure/gain values.
353914226ce7607ed991d7e0e0477d0575e6fc02d37Zhijun He        int32_t targetRequestId = *requestIdStart;
3548ef0144a52df7edfb754efce597e078bc185c57dZhijun He        for (size_t i = 0; i < requestCount; i++) {
355914226ce7607ed991d7e0e0477d0575e6fc02d37Zhijun He            ASSERT_EQ(OK, request.update(ANDROID_REQUEST_ID, requestIdStart, 1));
356914226ce7607ed991d7e0e0477d0575e6fc02d37Zhijun He            ASSERT_EQ(OK, request.update(ANDROID_SENSOR_EXPOSURE_TIME, &exposures[i], 1));
357914226ce7607ed991d7e0e0477d0575e6fc02d37Zhijun He            ASSERT_EQ(OK, request.update(ANDROID_SENSOR_SENSITIVITY, &sensitivities[i], 1));
3588ef0144a52df7edfb754efce597e078bc185c57dZhijun He            ASSERT_EQ(OK, mDevice->capture(request));
3590ab4c96ab8889127955971bbf5c157b7191cd1eaSasha Levitskiy            ALOGV("Submitting request with: id %d with exposure %"PRId64", sensitivity %d",
360914226ce7607ed991d7e0e0477d0575e6fc02d37Zhijun He                    *requestIdStart, exposures[i], sensitivities[i]);
3618ef0144a52df7edfb754efce597e078bc185c57dZhijun He            if (CAMERA_MULTI_STREAM_DEBUGGING) {
3628ef0144a52df7edfb754efce597e078bc185c57dZhijun He                request.dump(STDOUT_FILENO);
3638ef0144a52df7edfb754efce597e078bc185c57dZhijun He            }
364914226ce7607ed991d7e0e0477d0575e6fc02d37Zhijun He            (*requestIdStart)++;
3658ef0144a52df7edfb754efce597e078bc185c57dZhijun He        }
3668ef0144a52df7edfb754efce597e078bc185c57dZhijun He        // Get capture burst results.
3678ef0144a52df7edfb754efce597e078bc185c57dZhijun He        Vector<nsecs_t> captureBurstTimes;
3688ef0144a52df7edfb754efce597e078bc185c57dZhijun He        sp<CpuConsumer> consumer = stream->GetConsumer();
3698ef0144a52df7edfb754efce597e078bc185c57dZhijun He        sp<FrameListener> listener = stream->GetFrameListener();
3708ef0144a52df7edfb754efce597e078bc185c57dZhijun He
3718ef0144a52df7edfb754efce597e078bc185c57dZhijun He        // Set wait limit based on expected frame duration.
3728ef0144a52df7edfb754efce597e078bc185c57dZhijun He        int64_t waitLimit = CAMERA_FRAME_TIMEOUT;
3738ef0144a52df7edfb754efce597e078bc185c57dZhijun He        for (size_t i = 0; i < requestCount; i++) {
3740ab4c96ab8889127955971bbf5c157b7191cd1eaSasha Levitskiy            ALOGV("Reading request result %zu", i);
3758ef0144a52df7edfb754efce597e078bc185c57dZhijun He
3768ef0144a52df7edfb754efce597e078bc185c57dZhijun He            /**
3778ef0144a52df7edfb754efce597e078bc185c57dZhijun He             * Raise the timeout to be at least twice as long as the exposure
3788ef0144a52df7edfb754efce597e078bc185c57dZhijun He             * time. to avoid a false positive when the timeout is too short.
3798ef0144a52df7edfb754efce597e078bc185c57dZhijun He             */
3808ef0144a52df7edfb754efce597e078bc185c57dZhijun He            if ((exposures[i] * EXP_WAIT_MULTIPLIER) > waitLimit) {
3818ef0144a52df7edfb754efce597e078bc185c57dZhijun He                waitLimit = exposures[i] * EXP_WAIT_MULTIPLIER;
3828ef0144a52df7edfb754efce597e078bc185c57dZhijun He            }
3838ef0144a52df7edfb754efce597e078bc185c57dZhijun He
384f816eea8f1604841866e530453f956063af624bdJianing Wei            CaptureResult result;
3858ef0144a52df7edfb754efce597e078bc185c57dZhijun He            CameraMetadata frameMetadata;
386914226ce7607ed991d7e0e0477d0575e6fc02d37Zhijun He            int32_t resultRequestId;
387914226ce7607ed991d7e0e0477d0575e6fc02d37Zhijun He            do {
388914226ce7607ed991d7e0e0477d0575e6fc02d37Zhijun He                ASSERT_EQ(OK, mDevice->waitForNextFrame(waitLimit));
389f816eea8f1604841866e530453f956063af624bdJianing Wei                ASSERT_EQ(OK, mDevice->getNextResult(&result));
390f816eea8f1604841866e530453f956063af624bdJianing Wei                frameMetadata = result.mMetadata;
391914226ce7607ed991d7e0e0477d0575e6fc02d37Zhijun He
392914226ce7607ed991d7e0e0477d0575e6fc02d37Zhijun He                camera_metadata_entry_t resultEntry = frameMetadata.find(ANDROID_REQUEST_ID);
393914226ce7607ed991d7e0e0477d0575e6fc02d37Zhijun He                ASSERT_EQ(1u, resultEntry.count);
394914226ce7607ed991d7e0e0477d0575e6fc02d37Zhijun He                resultRequestId = resultEntry.data.i32[0];
395914226ce7607ed991d7e0e0477d0575e6fc02d37Zhijun He                if (CAMERA_MULTI_STREAM_DEBUGGING) {
396914226ce7607ed991d7e0e0477d0575e6fc02d37Zhijun He                    std::cout << "capture result req id: " << resultRequestId << std::endl;
397914226ce7607ed991d7e0e0477d0575e6fc02d37Zhijun He                }
398914226ce7607ed991d7e0e0477d0575e6fc02d37Zhijun He            } while (resultRequestId != targetRequestId);
399914226ce7607ed991d7e0e0477d0575e6fc02d37Zhijun He            targetRequestId++;
4000ab4c96ab8889127955971bbf5c157b7191cd1eaSasha Levitskiy            ALOGV("Got capture burst result for request %zu", i);
401914226ce7607ed991d7e0e0477d0575e6fc02d37Zhijun He
4028ef0144a52df7edfb754efce597e078bc185c57dZhijun He            // Validate capture result
4038ef0144a52df7edfb754efce597e078bc185c57dZhijun He            if (CAMERA_MULTI_STREAM_DEBUGGING) {
4048ef0144a52df7edfb754efce597e078bc185c57dZhijun He                frameMetadata.dump(STDOUT_FILENO);
4058ef0144a52df7edfb754efce597e078bc185c57dZhijun He            }
4068ef0144a52df7edfb754efce597e078bc185c57dZhijun He
4078ef0144a52df7edfb754efce597e078bc185c57dZhijun He            // TODO: Need revisit it to figure out an accurate margin.
408914226ce7607ed991d7e0e0477d0575e6fc02d37Zhijun He            int64_t resultExposure = GetExposureValue(frameMetadata);
409914226ce7607ed991d7e0e0477d0575e6fc02d37Zhijun He            int32_t resultSensitivity = GetSensitivity(frameMetadata);
410a1bef2b9a66c92d6a1aae32c0b2d7c66fb5305abGaurav Batra            EXPECT_LE(sensitivities[i] * (1.0 - TOLERANCE_MARGIN_METADATA), resultSensitivity);
411a1bef2b9a66c92d6a1aae32c0b2d7c66fb5305abGaurav Batra            EXPECT_GE(sensitivities[i] * (1.0 + TOLERANCE_MARGIN_METADATA), resultSensitivity);
412a1bef2b9a66c92d6a1aae32c0b2d7c66fb5305abGaurav Batra            EXPECT_LE(exposures[i] * (1.0 - TOLERANCE_MARGIN_METADATA), resultExposure);
413a1bef2b9a66c92d6a1aae32c0b2d7c66fb5305abGaurav Batra            EXPECT_GE(exposures[i] * (1.0 + TOLERANCE_MARGIN_METADATA), resultExposure);
4148ef0144a52df7edfb754efce597e078bc185c57dZhijun He
4158ef0144a52df7edfb754efce597e078bc185c57dZhijun He            ASSERT_EQ(OK, listener->waitForFrame(waitLimit));
4168ef0144a52df7edfb754efce597e078bc185c57dZhijun He            captureBurstTimes.push_back(systemTime());
4178ef0144a52df7edfb754efce597e078bc185c57dZhijun He            CpuConsumer::LockedBuffer imgBuffer;
4188ef0144a52df7edfb754efce597e078bc185c57dZhijun He            ASSERT_EQ(OK, consumer->lockNextBuffer(&imgBuffer));
4190ab4c96ab8889127955971bbf5c157b7191cd1eaSasha Levitskiy            ALOGV("Got capture buffer for request %zu", i);
4208ef0144a52df7edfb754efce597e078bc185c57dZhijun He
4218ef0144a52df7edfb754efce597e078bc185c57dZhijun He            /**
4228ef0144a52df7edfb754efce597e078bc185c57dZhijun He             * TODO: Validate capture buffer. Current brightness calculation
4238ef0144a52df7edfb754efce597e078bc185c57dZhijun He             * is too slow, it also doesn't account for saturation effects,
4248ef0144a52df7edfb754efce597e078bc185c57dZhijun He             * which is quite common since we are going over a significant
4258ef0144a52df7edfb754efce597e078bc185c57dZhijun He             * range of EVs. we need figure out some reliable way to validate
4268ef0144a52df7edfb754efce597e078bc185c57dZhijun He             * buffer data.
4278ef0144a52df7edfb754efce597e078bc185c57dZhijun He             */
4288ef0144a52df7edfb754efce597e078bc185c57dZhijun He
4298ef0144a52df7edfb754efce597e078bc185c57dZhijun He            ASSERT_EQ(OK, consumer->unlockBuffer(imgBuffer));
4308ef0144a52df7edfb754efce597e078bc185c57dZhijun He            if (i > 0) {
4318ef0144a52df7edfb754efce597e078bc185c57dZhijun He                nsecs_t timeDelta =
4328ef0144a52df7edfb754efce597e078bc185c57dZhijun He                        captureBurstTimes[i] - captureBurstTimes[i-1];
433a1bef2b9a66c92d6a1aae32c0b2d7c66fb5305abGaurav Batra                EXPECT_GE(timeDelta * ( 1 + TOLERANCE_MARGIN_CAPTURE), exposures[i]);
4348ef0144a52df7edfb754efce597e078bc185c57dZhijun He            }
4358ef0144a52df7edfb754efce597e078bc185c57dZhijun He        }
4368ef0144a52df7edfb754efce597e078bc185c57dZhijun He    }
4378ef0144a52df7edfb754efce597e078bc185c57dZhijun He
4388ef0144a52df7edfb754efce597e078bc185c57dZhijun He    /**
4398ef0144a52df7edfb754efce597e078bc185c57dZhijun He     * Intentionally shadow default CreateStream function from base class,
4408ef0144a52df7edfb754efce597e078bc185c57dZhijun He     * because we don't want any test in this class to use the default
4418ef0144a52df7edfb754efce597e078bc185c57dZhijun He     * stream creation function.
4428ef0144a52df7edfb754efce597e078bc185c57dZhijun He     */
4438ef0144a52df7edfb754efce597e078bc185c57dZhijun He    void CreateStream() {
4448ef0144a52df7edfb754efce597e078bc185c57dZhijun He    }
4458ef0144a52df7edfb754efce597e078bc185c57dZhijun He};
4468ef0144a52df7edfb754efce597e078bc185c57dZhijun He
4478ef0144a52df7edfb754efce597e078bc185c57dZhijun He/**
4488ef0144a52df7edfb754efce597e078bc185c57dZhijun He * This test adds multiple stream use case test, basically, test 3
4498ef0144a52df7edfb754efce597e078bc185c57dZhijun He * streams:
4508ef0144a52df7edfb754efce597e078bc185c57dZhijun He *
4518ef0144a52df7edfb754efce597e078bc185c57dZhijun He * 1. Preview stream, with large size that is no bigger than 1080p
4528ef0144a52df7edfb754efce597e078bc185c57dZhijun He * we render this stream to display and vary the exposure time for
4538ef0144a52df7edfb754efce597e078bc185c57dZhijun He * for certain amount of time for visualization purpose.
4548ef0144a52df7edfb754efce597e078bc185c57dZhijun He *
4558ef0144a52df7edfb754efce597e078bc185c57dZhijun He * 2. Metering stream, with small size that is no bigger than VGA size.
4568ef0144a52df7edfb754efce597e078bc185c57dZhijun He * a burst is issued for different exposure times and analog gains
4578ef0144a52df7edfb754efce597e078bc185c57dZhijun He * (or analog gain implemented sensitivities) then check if the capture
4588ef0144a52df7edfb754efce597e078bc185c57dZhijun He * result metadata matches the request.
4598ef0144a52df7edfb754efce597e078bc185c57dZhijun He *
4608ef0144a52df7edfb754efce597e078bc185c57dZhijun He * 3. Capture stream, this is basically similar as meterting stream, but
4618ef0144a52df7edfb754efce597e078bc185c57dZhijun He * has large size, which is the largest supported JPEG capture size.
4628ef0144a52df7edfb754efce597e078bc185c57dZhijun He *
4638ef0144a52df7edfb754efce597e078bc185c57dZhijun He * This multiple stream test is to test if HAL supports:
4648ef0144a52df7edfb754efce597e078bc185c57dZhijun He *
4658ef0144a52df7edfb754efce597e078bc185c57dZhijun He * 1. Multiple streams like above, HAL should support at least 3 streams
4668ef0144a52df7edfb754efce597e078bc185c57dZhijun He * concurrently: one preview stream, 2 other YUV stream.
4678ef0144a52df7edfb754efce597e078bc185c57dZhijun He *
4688ef0144a52df7edfb754efce597e078bc185c57dZhijun He * 2. Manual control(gain/exposure) of mutiple burst capture.
4698ef0144a52df7edfb754efce597e078bc185c57dZhijun He */
470b5ac45ff29d10bc31b2edd893125f1594b3f6065Zhijun He// Disable this test for now, as we need cleanup the usage of the deprecated tag quite a bit.
471b5ac45ff29d10bc31b2edd893125f1594b3f6065Zhijun HeTEST_F(CameraMultiStreamTest, DISABLED_MultiBurst) {
4728ef0144a52df7edfb754efce597e078bc185c57dZhijun He
4738ef0144a52df7edfb754efce597e078bc185c57dZhijun He    TEST_EXTENSION_FORKING_INIT;
4748ef0144a52df7edfb754efce597e078bc185c57dZhijun He
4758df990b3a2087e99d8a7c93e5f5084715263c4a6Yin-Chia Yeh    const int32_t* implDefData;
4768df990b3a2087e99d8a7c93e5f5084715263c4a6Yin-Chia Yeh    size_t implDefCount;
4778df990b3a2087e99d8a7c93e5f5084715263c4a6Yin-Chia Yeh    const int32_t* jpegData;
4788df990b3a2087e99d8a7c93e5f5084715263c4a6Yin-Chia Yeh    size_t jpegCount;
4798df990b3a2087e99d8a7c93e5f5084715263c4a6Yin-Chia Yeh    if (getDeviceVersion() < CAMERA_DEVICE_API_VERSION_3_2) {
4808df990b3a2087e99d8a7c93e5f5084715263c4a6Yin-Chia Yeh        camera_metadata_ro_entry availableProcessedSizes =
4818df990b3a2087e99d8a7c93e5f5084715263c4a6Yin-Chia Yeh            GetStaticEntry(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES);
4828df990b3a2087e99d8a7c93e5f5084715263c4a6Yin-Chia Yeh        ASSERT_EQ(0u, availableProcessedSizes.count % 2);
4838df990b3a2087e99d8a7c93e5f5084715263c4a6Yin-Chia Yeh        ASSERT_GE(availableProcessedSizes.count, 2u);
4848df990b3a2087e99d8a7c93e5f5084715263c4a6Yin-Chia Yeh        camera_metadata_ro_entry availableProcessedMinFrameDurations =
4858df990b3a2087e99d8a7c93e5f5084715263c4a6Yin-Chia Yeh            GetStaticEntry(ANDROID_SCALER_AVAILABLE_PROCESSED_MIN_DURATIONS);
4868df990b3a2087e99d8a7c93e5f5084715263c4a6Yin-Chia Yeh        EXPECT_EQ(availableProcessedSizes.count,
4878df990b3a2087e99d8a7c93e5f5084715263c4a6Yin-Chia Yeh            availableProcessedMinFrameDurations.count * 2);
4888df990b3a2087e99d8a7c93e5f5084715263c4a6Yin-Chia Yeh
4898df990b3a2087e99d8a7c93e5f5084715263c4a6Yin-Chia Yeh        camera_metadata_ro_entry availableJpegSizes =
4908df990b3a2087e99d8a7c93e5f5084715263c4a6Yin-Chia Yeh            GetStaticEntry(ANDROID_SCALER_AVAILABLE_JPEG_SIZES);
4918df990b3a2087e99d8a7c93e5f5084715263c4a6Yin-Chia Yeh        ASSERT_EQ(0u, availableJpegSizes.count % 2);
4928df990b3a2087e99d8a7c93e5f5084715263c4a6Yin-Chia Yeh        ASSERT_GE(availableJpegSizes.count, 2u);
4938df990b3a2087e99d8a7c93e5f5084715263c4a6Yin-Chia Yeh        implDefData = availableProcessedSizes.data.i32;
4948df990b3a2087e99d8a7c93e5f5084715263c4a6Yin-Chia Yeh        implDefCount = availableProcessedSizes.count;
4958df990b3a2087e99d8a7c93e5f5084715263c4a6Yin-Chia Yeh        jpegData = availableJpegSizes.data.i32;
4968df990b3a2087e99d8a7c93e5f5084715263c4a6Yin-Chia Yeh        jpegCount = availableJpegSizes.count;
4978df990b3a2087e99d8a7c93e5f5084715263c4a6Yin-Chia Yeh    } else {
4988df990b3a2087e99d8a7c93e5f5084715263c4a6Yin-Chia Yeh        const int32_t *implDefResolutions;
4998df990b3a2087e99d8a7c93e5f5084715263c4a6Yin-Chia Yeh        size_t   implDefResolutionsCount;
5008df990b3a2087e99d8a7c93e5f5084715263c4a6Yin-Chia Yeh
5018df990b3a2087e99d8a7c93e5f5084715263c4a6Yin-Chia Yeh        getResolutionList(HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, &implDefData, &implDefCount);
5028df990b3a2087e99d8a7c93e5f5084715263c4a6Yin-Chia Yeh        ASSERT_NE(0u, implDefCount)
5038df990b3a2087e99d8a7c93e5f5084715263c4a6Yin-Chia Yeh            << "Missing implementation defined sizes";
5048df990b3a2087e99d8a7c93e5f5084715263c4a6Yin-Chia Yeh        ASSERT_EQ(0u, implDefCount % 2);
5058df990b3a2087e99d8a7c93e5f5084715263c4a6Yin-Chia Yeh        ASSERT_GE(implDefCount, 2u);
5068df990b3a2087e99d8a7c93e5f5084715263c4a6Yin-Chia Yeh
5078df990b3a2087e99d8a7c93e5f5084715263c4a6Yin-Chia Yeh        getResolutionList(HAL_PIXEL_FORMAT_BLOB, &jpegData, &jpegCount);
5088df990b3a2087e99d8a7c93e5f5084715263c4a6Yin-Chia Yeh        ASSERT_EQ(0u, jpegCount % 2);
5098df990b3a2087e99d8a7c93e5f5084715263c4a6Yin-Chia Yeh        ASSERT_GE(jpegCount, 2u);
5108df990b3a2087e99d8a7c93e5f5084715263c4a6Yin-Chia Yeh    }
5118ef0144a52df7edfb754efce597e078bc185c57dZhijun He
5123bf3b45f2d5eb43b74e1a46ff03ed3e2142b1b38Zhijun He    camera_metadata_ro_entry hardwareLevel =
5133bf3b45f2d5eb43b74e1a46ff03ed3e2142b1b38Zhijun He        GetStaticEntry(ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL);
5143bf3b45f2d5eb43b74e1a46ff03ed3e2142b1b38Zhijun He    ASSERT_EQ(1u, hardwareLevel.count);
5153bf3b45f2d5eb43b74e1a46ff03ed3e2142b1b38Zhijun He    uint8_t level = hardwareLevel.data.u8[0];
5163bf3b45f2d5eb43b74e1a46ff03ed3e2142b1b38Zhijun He    ASSERT_GE(level, ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED);
5173bf3b45f2d5eb43b74e1a46ff03ed3e2142b1b38Zhijun He    ASSERT_LE(level, ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_FULL);
5183bf3b45f2d5eb43b74e1a46ff03ed3e2142b1b38Zhijun He    if (level == ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED) {
5193bf3b45f2d5eb43b74e1a46ff03ed3e2142b1b38Zhijun He        const ::testing::TestInfo* const test_info =
5203bf3b45f2d5eb43b74e1a46ff03ed3e2142b1b38Zhijun He            ::testing::UnitTest::GetInstance()->current_test_info();
5213bf3b45f2d5eb43b74e1a46ff03ed3e2142b1b38Zhijun He        std::cerr << "Skipping test "
5223bf3b45f2d5eb43b74e1a46ff03ed3e2142b1b38Zhijun He                  << test_info->test_case_name() << "."
5233bf3b45f2d5eb43b74e1a46ff03ed3e2142b1b38Zhijun He                  << test_info->name()
5243bf3b45f2d5eb43b74e1a46ff03ed3e2142b1b38Zhijun He                  << " because HAL hardware supported level is limited "
5253bf3b45f2d5eb43b74e1a46ff03ed3e2142b1b38Zhijun He                  << std::endl;
5263bf3b45f2d5eb43b74e1a46ff03ed3e2142b1b38Zhijun He        return;
5273bf3b45f2d5eb43b74e1a46ff03ed3e2142b1b38Zhijun He    }
5283bf3b45f2d5eb43b74e1a46ff03ed3e2142b1b38Zhijun He
5298ef0144a52df7edfb754efce597e078bc185c57dZhijun He    // Find the right sizes for preview, metering, and capture streams
5308ef0144a52df7edfb754efce597e078bc185c57dZhijun He    int64_t minFrameDuration = DEFAULT_FRAME_DURATION;
5318ef0144a52df7edfb754efce597e078bc185c57dZhijun He    Size processedMinSize, processedMaxSize, jpegMaxSize;
5328ef0144a52df7edfb754efce597e078bc185c57dZhijun He
5338ef0144a52df7edfb754efce597e078bc185c57dZhijun He    int32_t minIdx, maxIdx;
5348df990b3a2087e99d8a7c93e5f5084715263c4a6Yin-Chia Yeh    GetMinSize(implDefData, implDefCount, &processedMinSize, &minIdx);
5358df990b3a2087e99d8a7c93e5f5084715263c4a6Yin-Chia Yeh    GetMaxSize(implDefData, implDefCount, &processedMaxSize, &maxIdx);
5368ef0144a52df7edfb754efce597e078bc185c57dZhijun He    ALOGV("Found processed max size: %dx%d, min size = %dx%d",
5378ef0144a52df7edfb754efce597e078bc185c57dZhijun He            processedMaxSize.width, processedMaxSize.height,
5388ef0144a52df7edfb754efce597e078bc185c57dZhijun He            processedMinSize.width, processedMinSize.height);
5398ef0144a52df7edfb754efce597e078bc185c57dZhijun He
5408df990b3a2087e99d8a7c93e5f5084715263c4a6Yin-Chia Yeh    if (getDeviceVersion() < CAMERA_DEVICE_API_VERSION_3_2) {
5418df990b3a2087e99d8a7c93e5f5084715263c4a6Yin-Chia Yeh        camera_metadata_ro_entry availableProcessedMinFrameDurations =
5428df990b3a2087e99d8a7c93e5f5084715263c4a6Yin-Chia Yeh            GetStaticEntry(ANDROID_SCALER_AVAILABLE_PROCESSED_MIN_DURATIONS);
5438ef0144a52df7edfb754efce597e078bc185c57dZhijun He        minFrameDuration =
5448ef0144a52df7edfb754efce597e078bc185c57dZhijun He            availableProcessedMinFrameDurations.data.i64[maxIdx / 2];
5458df990b3a2087e99d8a7c93e5f5084715263c4a6Yin-Chia Yeh    } else {
5468df990b3a2087e99d8a7c93e5f5084715263c4a6Yin-Chia Yeh        minFrameDuration = getMinFrameDurationFor(
5478df990b3a2087e99d8a7c93e5f5084715263c4a6Yin-Chia Yeh                HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED,
5488df990b3a2087e99d8a7c93e5f5084715263c4a6Yin-Chia Yeh                processedMaxSize.width, processedMaxSize.height);
5498ef0144a52df7edfb754efce597e078bc185c57dZhijun He    }
5508ef0144a52df7edfb754efce597e078bc185c57dZhijun He
5518ef0144a52df7edfb754efce597e078bc185c57dZhijun He    EXPECT_GT(minFrameDuration, 0);
5528ef0144a52df7edfb754efce597e078bc185c57dZhijun He
5538ef0144a52df7edfb754efce597e078bc185c57dZhijun He    if (minFrameDuration <= 0) {
5548ef0144a52df7edfb754efce597e078bc185c57dZhijun He        minFrameDuration = DEFAULT_FRAME_DURATION;
5558ef0144a52df7edfb754efce597e078bc185c57dZhijun He    }
5568ef0144a52df7edfb754efce597e078bc185c57dZhijun He
5570ab4c96ab8889127955971bbf5c157b7191cd1eaSasha Levitskiy    ALOGV("targeted minimal frame duration is: %"PRId64"ns", minFrameDuration);
5588ef0144a52df7edfb754efce597e078bc185c57dZhijun He
5598df990b3a2087e99d8a7c93e5f5084715263c4a6Yin-Chia Yeh    GetMaxSize(jpegData, jpegCount, &jpegMaxSize, &maxIdx);
5608ef0144a52df7edfb754efce597e078bc185c57dZhijun He    ALOGV("Found Jpeg size max idx = %d", maxIdx);
5618ef0144a52df7edfb754efce597e078bc185c57dZhijun He
5628ef0144a52df7edfb754efce597e078bc185c57dZhijun He    // Max Jpeg size should be available in processed sizes. Use it for
5638ef0144a52df7edfb754efce597e078bc185c57dZhijun He    // YUV capture anyway.
5648ef0144a52df7edfb754efce597e078bc185c57dZhijun He    EXPECT_EQ(processedMaxSize.width, jpegMaxSize.width);
5658ef0144a52df7edfb754efce597e078bc185c57dZhijun He    EXPECT_EQ(processedMaxSize.height, jpegMaxSize.height);
5668ef0144a52df7edfb754efce597e078bc185c57dZhijun He
5678ef0144a52df7edfb754efce597e078bc185c57dZhijun He    // Cap preview size.
5688ef0144a52df7edfb754efce597e078bc185c57dZhijun He    Size previewLimit = { PREVIEW_WIDTH_CAP, PREVIEW_HEIGHT_CAP };
5698ef0144a52df7edfb754efce597e078bc185c57dZhijun He    // FIXME: need make sure the previewLimit is supported by HAL.
5708ef0144a52df7edfb754efce597e078bc185c57dZhijun He    Size previewSize = CapSize(previewLimit, processedMaxSize);
5718ef0144a52df7edfb754efce597e078bc185c57dZhijun He    // Cap Metering size.
5728ef0144a52df7edfb754efce597e078bc185c57dZhijun He    Size meteringLimit = { METERING_WIDTH_CAP, METERING_HEIGHT_CAP };
5738ef0144a52df7edfb754efce597e078bc185c57dZhijun He    // Cap metering size to VGA (VGA is mandatory by CDD)
5748ef0144a52df7edfb754efce597e078bc185c57dZhijun He    Size meteringSize = CapSize(meteringLimit, processedMinSize);
5758ef0144a52df7edfb754efce597e078bc185c57dZhijun He    // Capture stream should be the max size of jpeg sizes.
5768ef0144a52df7edfb754efce597e078bc185c57dZhijun He    ALOGV("preview size: %dx%d, metering size: %dx%d, capture size: %dx%d",
5778ef0144a52df7edfb754efce597e078bc185c57dZhijun He            previewSize.width, previewSize.height,
5788ef0144a52df7edfb754efce597e078bc185c57dZhijun He            meteringSize.width, meteringSize.height,
5798ef0144a52df7edfb754efce597e078bc185c57dZhijun He            jpegMaxSize.width, jpegMaxSize.height);
5808ef0144a52df7edfb754efce597e078bc185c57dZhijun He
5818ef0144a52df7edfb754efce597e078bc185c57dZhijun He    // Create streams
5828ef0144a52df7edfb754efce597e078bc185c57dZhijun He    // Preview stream: small resolution, render on the screen.
5838ef0144a52df7edfb754efce597e078bc185c57dZhijun He    sp<CameraStream> previewStream;
5848ef0144a52df7edfb754efce597e078bc185c57dZhijun He    {
5858ef0144a52df7edfb754efce597e078bc185c57dZhijun He        sp<ANativeWindow> surface;
5868ef0144a52df7edfb754efce597e078bc185c57dZhijun He        ASSERT_NO_FATAL_FAILURE(CreateOnScreenSurface(/*out*/surface));
5878ef0144a52df7edfb754efce597e078bc185c57dZhijun He        previewStream = CreateStream(
5888ef0144a52df7edfb754efce597e078bc185c57dZhijun He                previewSize.width,
5898ef0144a52df7edfb754efce597e078bc185c57dZhijun He                previewSize.height,
5908ef0144a52df7edfb754efce597e078bc185c57dZhijun He                mDevice,
5918ef0144a52df7edfb754efce597e078bc185c57dZhijun He                DISPLAY_STREAM_PARAMETERS,
5928ef0144a52df7edfb754efce597e078bc185c57dZhijun He                surface,
5938ef0144a52df7edfb754efce597e078bc185c57dZhijun He                false);
5948ef0144a52df7edfb754efce597e078bc185c57dZhijun He        ASSERT_NE((void*)NULL, previewStream.get());
5958ef0144a52df7edfb754efce597e078bc185c57dZhijun He        ASSERT_NO_FATAL_FAILURE(previewStream->SetUp());
5968ef0144a52df7edfb754efce597e078bc185c57dZhijun He    }
5978ef0144a52df7edfb754efce597e078bc185c57dZhijun He    // Metering burst stream: small resolution yuv stream
5988ef0144a52df7edfb754efce597e078bc185c57dZhijun He    sp<CameraStream> meteringStream =
5998ef0144a52df7edfb754efce597e078bc185c57dZhijun He            CreateStream(
6008ef0144a52df7edfb754efce597e078bc185c57dZhijun He                    meteringSize.width,
6018ef0144a52df7edfb754efce597e078bc185c57dZhijun He                    meteringSize.height,
6028ef0144a52df7edfb754efce597e078bc185c57dZhijun He                    mDevice);
6038ef0144a52df7edfb754efce597e078bc185c57dZhijun He    ASSERT_NE((void*)NULL, meteringStream.get());
6048ef0144a52df7edfb754efce597e078bc185c57dZhijun He    ASSERT_NO_FATAL_FAILURE(meteringStream->SetUp());
6058ef0144a52df7edfb754efce597e078bc185c57dZhijun He    // Capture burst stream: full resolution yuv stream
6068ef0144a52df7edfb754efce597e078bc185c57dZhijun He    sp<CameraStream> captureStream =
6078ef0144a52df7edfb754efce597e078bc185c57dZhijun He            CreateStream(
6088ef0144a52df7edfb754efce597e078bc185c57dZhijun He                    jpegMaxSize.width,
6098ef0144a52df7edfb754efce597e078bc185c57dZhijun He                    jpegMaxSize.height,
6108ef0144a52df7edfb754efce597e078bc185c57dZhijun He                    mDevice);
6118ef0144a52df7edfb754efce597e078bc185c57dZhijun He    ASSERT_NE((void*)NULL, captureStream.get());
6128ef0144a52df7edfb754efce597e078bc185c57dZhijun He    ASSERT_NO_FATAL_FAILURE(captureStream->SetUp());
6138ef0144a52df7edfb754efce597e078bc185c57dZhijun He
6148ef0144a52df7edfb754efce597e078bc185c57dZhijun He    // Create Preview request.
6158ef0144a52df7edfb754efce597e078bc185c57dZhijun He    CameraMetadata previewRequest, meteringRequest, captureRequest;
6168ef0144a52df7edfb754efce597e078bc185c57dZhijun He    ASSERT_NO_FATAL_FAILURE(CreateRequests(previewRequest, meteringRequest,
6178ef0144a52df7edfb754efce597e078bc185c57dZhijun He            captureRequest, previewStream->GetStreamId(),
6188ef0144a52df7edfb754efce597e078bc185c57dZhijun He            meteringStream->GetStreamId(), captureStream->GetStreamId()));
6198ef0144a52df7edfb754efce597e078bc185c57dZhijun He
6208ef0144a52df7edfb754efce597e078bc185c57dZhijun He    // Start preview
6218ef0144a52df7edfb754efce597e078bc185c57dZhijun He    if (CAMERA_MULTI_STREAM_DEBUGGING) {
6228ef0144a52df7edfb754efce597e078bc185c57dZhijun He        previewRequest.dump(STDOUT_FILENO);
6238ef0144a52df7edfb754efce597e078bc185c57dZhijun He    }
6248ef0144a52df7edfb754efce597e078bc185c57dZhijun He
6258ef0144a52df7edfb754efce597e078bc185c57dZhijun He    // Generate exposure and sensitivity lists
6268ef0144a52df7edfb754efce597e078bc185c57dZhijun He    camera_metadata_ro_entry exposureTimeRange =
6278ef0144a52df7edfb754efce597e078bc185c57dZhijun He        GetStaticEntry(ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE);
6288ef0144a52df7edfb754efce597e078bc185c57dZhijun He    ASSERT_EQ(exposureTimeRange.count, 2u);
6298ef0144a52df7edfb754efce597e078bc185c57dZhijun He    int64_t minExp = exposureTimeRange.data.i64[0];
6308ef0144a52df7edfb754efce597e078bc185c57dZhijun He    int64_t maxExp = exposureTimeRange.data.i64[1];
6318ef0144a52df7edfb754efce597e078bc185c57dZhijun He    ASSERT_GT(maxExp, minExp);
6328ef0144a52df7edfb754efce597e078bc185c57dZhijun He
6338ef0144a52df7edfb754efce597e078bc185c57dZhijun He    camera_metadata_ro_entry sensivityRange =
6348ef0144a52df7edfb754efce597e078bc185c57dZhijun He        GetStaticEntry(ANDROID_SENSOR_INFO_SENSITIVITY_RANGE);
6358ef0144a52df7edfb754efce597e078bc185c57dZhijun He    ASSERT_EQ(2u, sensivityRange.count);
6368ef0144a52df7edfb754efce597e078bc185c57dZhijun He    int32_t minSensitivity = sensivityRange.data.i32[0];
6378ef0144a52df7edfb754efce597e078bc185c57dZhijun He    int32_t maxSensitivity = sensivityRange.data.i32[1];
6388ef0144a52df7edfb754efce597e078bc185c57dZhijun He    camera_metadata_ro_entry maxAnalogSenEntry =
6398ef0144a52df7edfb754efce597e078bc185c57dZhijun He            GetStaticEntry(ANDROID_SENSOR_MAX_ANALOG_SENSITIVITY);
6408ef0144a52df7edfb754efce597e078bc185c57dZhijun He    EXPECT_EQ(1u, maxAnalogSenEntry.count);
6418ef0144a52df7edfb754efce597e078bc185c57dZhijun He    int32_t maxAnalogSensitivity = maxAnalogSenEntry.data.i32[0];
6428ef0144a52df7edfb754efce597e078bc185c57dZhijun He    EXPECT_LE(maxAnalogSensitivity, maxSensitivity);
6438ef0144a52df7edfb754efce597e078bc185c57dZhijun He    // Only test the sensitivity implemented by analog gain.
6448ef0144a52df7edfb754efce597e078bc185c57dZhijun He    if (maxAnalogSensitivity > maxSensitivity) {
6458ef0144a52df7edfb754efce597e078bc185c57dZhijun He        // Fallback to maxSensitity
6468ef0144a52df7edfb754efce597e078bc185c57dZhijun He        maxAnalogSensitivity = maxSensitivity;
6478ef0144a52df7edfb754efce597e078bc185c57dZhijun He    }
6488ef0144a52df7edfb754efce597e078bc185c57dZhijun He
6498ef0144a52df7edfb754efce597e078bc185c57dZhijun He    // sensitivity list, only include the sensitivities that are implemented
6508ef0144a52df7edfb754efce597e078bc185c57dZhijun He    // purely by analog gain if possible.
6518ef0144a52df7edfb754efce597e078bc185c57dZhijun He    Vector<int32_t> sensitivities;
6528ef0144a52df7edfb754efce597e078bc185c57dZhijun He    Vector<int64_t> exposures;
6538df990b3a2087e99d8a7c93e5f5084715263c4a6Yin-Chia Yeh    size_t count = (maxAnalogSensitivity - minSensitivity + 99) / 100;
6548ef0144a52df7edfb754efce597e078bc185c57dZhijun He    sensitivities.push_back(minSensitivity);
6558ef0144a52df7edfb754efce597e078bc185c57dZhijun He    for (size_t i = 1; i < count; i++) {
6568ef0144a52df7edfb754efce597e078bc185c57dZhijun He        sensitivities.push_back(minSensitivity + i * 100);
6578ef0144a52df7edfb754efce597e078bc185c57dZhijun He    }
6588ef0144a52df7edfb754efce597e078bc185c57dZhijun He    sensitivities.push_back(maxAnalogSensitivity);
6598ef0144a52df7edfb754efce597e078bc185c57dZhijun He    ALOGV("Sensitivity Range: min=%d, max=%d", minSensitivity,
6608ef0144a52df7edfb754efce597e078bc185c57dZhijun He            maxAnalogSensitivity);
6618ef0144a52df7edfb754efce597e078bc185c57dZhijun He    int64_t exp = minExp;
6628ef0144a52df7edfb754efce597e078bc185c57dZhijun He    while (exp < maxExp) {
6638ef0144a52df7edfb754efce597e078bc185c57dZhijun He        exposures.push_back(exp);
6648ef0144a52df7edfb754efce597e078bc185c57dZhijun He        exp *= 2;
6658ef0144a52df7edfb754efce597e078bc185c57dZhijun He    }
6668ef0144a52df7edfb754efce597e078bc185c57dZhijun He    // Sweep the exposure value for preview, just for visual inspection purpose.
6678ef0144a52df7edfb754efce597e078bc185c57dZhijun He    uint8_t cmOff = static_cast<uint8_t>(ANDROID_CONTROL_MODE_OFF);
6688ef0144a52df7edfb754efce597e078bc185c57dZhijun He    for (size_t i = 0; i < exposures.size(); i++) {
6698ef0144a52df7edfb754efce597e078bc185c57dZhijun He        ASSERT_EQ(OK, previewRequest.update(
6708ef0144a52df7edfb754efce597e078bc185c57dZhijun He                ANDROID_CONTROL_MODE,
6718ef0144a52df7edfb754efce597e078bc185c57dZhijun He                &cmOff, 1));
6728ef0144a52df7edfb754efce597e078bc185c57dZhijun He        ASSERT_EQ(OK, previewRequest.update(
6738ef0144a52df7edfb754efce597e078bc185c57dZhijun He                ANDROID_SENSOR_EXPOSURE_TIME,
6748ef0144a52df7edfb754efce597e078bc185c57dZhijun He                &exposures[i], 1));
6750ab4c96ab8889127955971bbf5c157b7191cd1eaSasha Levitskiy        ALOGV("Submitting preview request %zu with exposure %"PRId64,
6768ef0144a52df7edfb754efce597e078bc185c57dZhijun He                i, exposures[i]);
6778ef0144a52df7edfb754efce597e078bc185c57dZhijun He
6788ef0144a52df7edfb754efce597e078bc185c57dZhijun He        ASSERT_EQ(OK, mDevice->setStreamingRequest(previewRequest));
6798ef0144a52df7edfb754efce597e078bc185c57dZhijun He
6808ef0144a52df7edfb754efce597e078bc185c57dZhijun He        // Let preview run 200ms on screen for each exposure time.
6818ef0144a52df7edfb754efce597e078bc185c57dZhijun He        usleep(PREVIEW_RENDERING_TIME_INTERVAL);
6828ef0144a52df7edfb754efce597e078bc185c57dZhijun He    }
6838ef0144a52df7edfb754efce597e078bc185c57dZhijun He
6848ef0144a52df7edfb754efce597e078bc185c57dZhijun He    size_t requestCount = sensitivities.size();
6858ef0144a52df7edfb754efce597e078bc185c57dZhijun He    if (requestCount > exposures.size()) {
6868ef0144a52df7edfb754efce597e078bc185c57dZhijun He        requestCount = exposures.size();
6878ef0144a52df7edfb754efce597e078bc185c57dZhijun He    }
6888ef0144a52df7edfb754efce597e078bc185c57dZhijun He
689914226ce7607ed991d7e0e0477d0575e6fc02d37Zhijun He    // To maintain the request id uniqueness (preview request id is 0), make burst capture start
690914226ce7607ed991d7e0e0477d0575e6fc02d37Zhijun He    // request id 1 here.
691914226ce7607ed991d7e0e0477d0575e6fc02d37Zhijun He    int32_t requestIdStart = 1;
6928ef0144a52df7edfb754efce597e078bc185c57dZhijun He    /**
6938ef0144a52df7edfb754efce597e078bc185c57dZhijun He     * Submit metering request, set default frame duration to minimal possible
6948ef0144a52df7edfb754efce597e078bc185c57dZhijun He     * value, we want the capture to run as fast as possible. HAL should adjust
6958ef0144a52df7edfb754efce597e078bc185c57dZhijun He     * the frame duration to minimal necessary value to support the requested
6968ef0144a52df7edfb754efce597e078bc185c57dZhijun He     * exposure value if exposure is larger than frame duration.
6978ef0144a52df7edfb754efce597e078bc185c57dZhijun He     */
6988ef0144a52df7edfb754efce597e078bc185c57dZhijun He    CaptureBurst(meteringRequest, requestCount, exposures, sensitivities,
699914226ce7607ed991d7e0e0477d0575e6fc02d37Zhijun He            meteringStream, minFrameDuration, &requestIdStart);
7008ef0144a52df7edfb754efce597e078bc185c57dZhijun He
7018ef0144a52df7edfb754efce597e078bc185c57dZhijun He    /**
7028ef0144a52df7edfb754efce597e078bc185c57dZhijun He     * Submit capture request, set default frame duration to minimal possible
7038ef0144a52df7edfb754efce597e078bc185c57dZhijun He     * value, we want the capture to run as fast as possible. HAL should adjust
7048ef0144a52df7edfb754efce597e078bc185c57dZhijun He     * the frame duration to minimal necessary value to support the requested
7058ef0144a52df7edfb754efce597e078bc185c57dZhijun He     * exposure value if exposure is larger than frame duration.
7068ef0144a52df7edfb754efce597e078bc185c57dZhijun He     */
7078ef0144a52df7edfb754efce597e078bc185c57dZhijun He    CaptureBurst(captureRequest, requestCount, exposures, sensitivities,
708914226ce7607ed991d7e0e0477d0575e6fc02d37Zhijun He            captureStream, minFrameDuration, &requestIdStart);
7098ef0144a52df7edfb754efce597e078bc185c57dZhijun He
7108ef0144a52df7edfb754efce597e078bc185c57dZhijun He    ASSERT_EQ(OK, mDevice->clearStreamingRequest());
7118ef0144a52df7edfb754efce597e078bc185c57dZhijun He}
7128ef0144a52df7edfb754efce597e078bc185c57dZhijun He
7138ef0144a52df7edfb754efce597e078bc185c57dZhijun He}
7148ef0144a52df7edfb754efce597e078bc185c57dZhijun He}
7158ef0144a52df7edfb754efce597e078bc185c57dZhijun He}
716