/*
 * Copyright (C) 2012 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 "Camera2_test"
//#define LOG_NDEBUG 0

#include <utils/Log.h>
#include <gtest/gtest.h>
#include <iostream>
#include <fstream>

#include <utils/Vector.h>
#include <gui/CpuConsumer.h>
#include <ui/PixelFormat.h>
#include <system/camera_metadata.h>

#include "camera2_utils.h"
#include "TestExtensions.h"

namespace android {
namespace camera2 {
namespace tests {

class Camera2Test: public testing::Test {
  public:
    void SetUpModule() {
        int res;

        hw_module_t *module = NULL;
        res = hw_get_module(CAMERA_HARDWARE_MODULE_ID,
                (const hw_module_t **)&module);

        ASSERT_EQ(0, res)
                << "Failure opening camera hardware module: " << res;
        ASSERT_TRUE(NULL != module)
                << "No camera module was set by hw_get_module";

        IF_ALOGV() {
            std::cout << "  Camera module name: "
                    << module->name << std::endl;
            std::cout << "  Camera module author: "
                    << module->author << std::endl;
            std::cout << "  Camera module API version: 0x" << std::hex
                    << module->module_api_version << std::endl;
            std::cout << "  Camera module HAL API version: 0x" << std::hex
                    << module->hal_api_version << std::endl;
        }

        int16_t version2_0 = CAMERA_MODULE_API_VERSION_2_0;
        ASSERT_LE(version2_0, module->module_api_version)
                << "Camera module version is 0x"
                << std::hex << module->module_api_version
                << ", should be at least 2.0. (0x"
                << std::hex << CAMERA_MODULE_API_VERSION_2_0 << ")";

        sCameraModule = reinterpret_cast<camera_module_t*>(module);

        sNumCameras = sCameraModule->get_number_of_cameras();
        ASSERT_LT(0, sNumCameras) << "No camera devices available!";

        IF_ALOGV() {
            std::cout << "  Camera device count: " << sNumCameras << std::endl;
        }

        sCameraSupportsHal2 = new bool[sNumCameras];

        for (int i = 0; i < sNumCameras; i++) {
            camera_info info;
            res = sCameraModule->get_camera_info(i, &info);
            ASSERT_EQ(0, res)
                    << "Failure getting camera info for camera " << i;
            IF_ALOGV() {
                std::cout << "  Camera device: " << std::dec
                          << i << std::endl;;
                std::cout << "    Facing: " << std::dec
                          << info.facing  << std::endl;
                std::cout << "    Orientation: " << std::dec
                          << info.orientation  << std::endl;
                std::cout << "    Version: 0x" << std::hex <<
                        info.device_version  << std::endl;
            }
            if (info.device_version >= CAMERA_DEVICE_API_VERSION_2_0 &&
                    info.device_version < CAMERA_DEVICE_API_VERSION_3_0) {
                sCameraSupportsHal2[i] = true;
                ASSERT_TRUE(NULL != info.static_camera_characteristics);
                IF_ALOGV() {
                    std::cout << "    Static camera metadata:"  << std::endl;
                    dump_indented_camera_metadata(info.static_camera_characteristics,
                            0, 1, 6);
                }
            } else {
                sCameraSupportsHal2[i] = false;
            }
        }
    }

    void TearDownModule() {
        hw_module_t *module = reinterpret_cast<hw_module_t*>(sCameraModule);
        ASSERT_EQ(0, HWModuleHelpers::closeModule(module));
    }

    static const camera_module_t *getCameraModule() {
        return sCameraModule;
    }

    static int getNumCameras() {
        return sNumCameras;
    }

    static bool isHal2Supported(int id) {
        return sCameraSupportsHal2[id];
    }

    static camera2_device_t *openCameraDevice(int id) {
        ALOGV("Opening camera %d", id);
        if (NULL == sCameraSupportsHal2) return NULL;
        if (id >= sNumCameras) return NULL;
        if (!sCameraSupportsHal2[id]) return NULL;

        hw_device_t *device = NULL;
        const camera_module_t *cam_module = getCameraModule();
        if (cam_module == NULL) {
            return NULL;
        }

        char camId[10];
        int res;

        snprintf(camId, 10, "%d", id);
        res = cam_module->common.methods->open(
            (const hw_module_t*)cam_module,
            camId,
            &device);
        if (res != NO_ERROR || device == NULL) {
            return NULL;
        }
        camera2_device_t *cam_device =
                reinterpret_cast<camera2_device_t*>(device);
        return cam_device;
    }

    static status_t configureCameraDevice(camera2_device_t *dev,
            MetadataQueue &requestQueue,
            MetadataQueue  &frameQueue,
            NotifierListener &listener) {

        status_t err;

        err = dev->ops->set_request_queue_src_ops(dev,
                requestQueue.getToConsumerInterface());
        if (err != OK) return err;

        requestQueue.setFromConsumerInterface(dev);

        err = dev->ops->set_frame_queue_dst_ops(dev,
                frameQueue.getToProducerInterface());
        if (err != OK) return err;

        err = listener.getNotificationsFrom(dev);
        if (err != OK) return err;

        vendor_tag_query_ops_t *vendor_metadata_tag_ops;
        err = dev->ops->get_metadata_vendor_tag_ops(dev, &vendor_metadata_tag_ops);
        if (err != OK) return err;

        err = set_camera_metadata_vendor_tag_ops(vendor_metadata_tag_ops);
        if (err != OK) return err;

        return OK;
    }

    static status_t closeCameraDevice(camera2_device_t **cam_dev) {
        int res;
        if (*cam_dev == NULL ) return OK;

        ALOGV("Closing camera %p", cam_dev);

        hw_device_t *dev = reinterpret_cast<hw_device_t *>(*cam_dev);
        res = dev->close(dev);
        *cam_dev = NULL;
        return res;
    }

    void setUpCamera(int id) {
        ASSERT_GT(sNumCameras, id);
        status_t res;

        if (mDevice != NULL) {
            closeCameraDevice(&mDevice);
        }
        mDevice = openCameraDevice(id);
        ASSERT_TRUE(NULL != mDevice) << "Failed to open camera device";

        camera_info info;
        res = sCameraModule->get_camera_info(id, &info);
        ASSERT_EQ(OK, res);

        mStaticInfo = info.static_camera_characteristics;

        res = configureCameraDevice(mDevice,
                mRequests,
                mFrames,
                mNotifications);
        ASSERT_EQ(OK, res) << "Failure to configure camera device";

    }

    void setUpStream(sp<IGraphicBufferProducer> consumer,
            int width, int height, int format, int *id) {
        status_t res;

        StreamAdapter* stream = new StreamAdapter(consumer);

        ALOGV("Creating stream, format 0x%x, %d x %d", format, width, height);
        res = stream->connectToDevice(mDevice, width, height, format);
        ASSERT_EQ(NO_ERROR, res) << "Failed to connect to stream: "
                                 << strerror(-res);
        mStreams.push_back(stream);

        *id = stream->getId();
    }

    void disconnectStream(int id) {
        status_t res;
        unsigned int i=0;
        for (; i < mStreams.size(); i++) {
            if (mStreams[i]->getId() == id) {
                res = mStreams[i]->disconnect();
                ASSERT_EQ(NO_ERROR, res) <<
                        "Failed to disconnect stream " << id;
                break;
            }
        }
        ASSERT_GT(mStreams.size(), i) << "Stream id not found:" << id;
    }

    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);
            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);

        *list = availableSizes.data.i32;
        *count = availableSizes.count;
    }

    status_t waitUntilDrained() {
        static const uint32_t kSleepTime = 50000; // 50 ms
        static const uint32_t kMaxSleepTime = 10000000; // 10 s
        ALOGV("%s: Camera %d: Starting wait", __FUNCTION__, mId);

        // TODO: Set up notifications from HAL, instead of sleeping here
        uint32_t totalTime = 0;
        while (mDevice->ops->get_in_progress_count(mDevice) > 0) {
            usleep(kSleepTime);
            totalTime += kSleepTime;
            if (totalTime > kMaxSleepTime) {
                ALOGE("%s: Waited %d us, %d requests still in flight", __FUNCTION__,
                        mDevice->ops->get_in_progress_count(mDevice), totalTime);
                return TIMED_OUT;
            }
        }
        ALOGV("%s: Camera %d: HAL is idle", __FUNCTION__, mId);
        return OK;
    }

    virtual void SetUp() {
        TEST_EXTENSION_FORKING_SET_UP;

        SetUpModule();

        const ::testing::TestInfo* const testInfo =
                ::testing::UnitTest::GetInstance()->current_test_info();
        (void)testInfo;

        ALOGV("*** Starting test %s in test case %s", testInfo->name(),
              testInfo->test_case_name());
        mDevice = NULL;
    }

    virtual void TearDown() {
        TEST_EXTENSION_FORKING_TEAR_DOWN;

        for (unsigned int i = 0; i < mStreams.size(); i++) {
            delete mStreams[i];
        }
        if (mDevice != NULL) {
            closeCameraDevice(&mDevice);
        }

        TearDownModule();
    }

    camera2_device    *mDevice;
    const camera_metadata_t *mStaticInfo;

    MetadataQueue    mRequests;
    MetadataQueue    mFrames;
    NotifierListener mNotifications;

    Vector<StreamAdapter*> mStreams;

  private:
    static camera_module_t *sCameraModule;
    static int              sNumCameras;
    static bool            *sCameraSupportsHal2;
};

camera_module_t *Camera2Test::sCameraModule = NULL;
bool *Camera2Test::sCameraSupportsHal2      = NULL;
int Camera2Test::sNumCameras                = 0;

static const nsecs_t USEC = 1000;
static const nsecs_t MSEC = 1000*USEC;
static const nsecs_t SEC = 1000*MSEC;


TEST_F(Camera2Test, OpenClose) {

    TEST_EXTENSION_FORKING_INIT;

    status_t res;

    for (int id = 0; id < getNumCameras(); id++) {
        if (!isHal2Supported(id)) continue;

        camera2_device_t *d = openCameraDevice(id);
        ASSERT_TRUE(NULL != d) << "Failed to open camera device";

        res = closeCameraDevice(&d);
        ASSERT_EQ(NO_ERROR, res) << "Failed to close camera device";
    }
}

TEST_F(Camera2Test, Capture1Raw) {

    TEST_EXTENSION_FORKING_INIT;

    status_t res;

    for (int id = 0; id < getNumCameras(); id++) {
        if (!isHal2Supported(id)) continue;

        ASSERT_NO_FATAL_FAILURE(setUpCamera(id));

        sp<CpuConsumer> rawConsumer = new CpuConsumer(1);
        sp<FrameWaiter> rawWaiter = new FrameWaiter();
        rawConsumer->setFrameAvailableListener(rawWaiter);

        const int32_t *rawResolutions;
        size_t   rawResolutionsCount;

        int format = HAL_PIXEL_FORMAT_RAW_SENSOR;

        getResolutionList(format,
                &rawResolutions, &rawResolutionsCount);

        if (rawResolutionsCount <= 0) {
            const ::testing::TestInfo* const test_info =
                ::testing::UnitTest::GetInstance()->current_test_info();
            std::cerr << "Skipping test "
                      << test_info->test_case_name() << "."
                      << test_info->name()
                      << " because the optional format was not available: "
                      << "RAW_SENSOR" << std::endl;
            return;
        }

        ASSERT_LT((size_t)0, rawResolutionsCount);

        // Pick first available raw resolution
        int width = rawResolutions[0];
        int height = rawResolutions[1];

        int streamId;
        ASSERT_NO_FATAL_FAILURE(
            setUpStream(rawConsumer->getProducerInterface(),
                    width, height, format, &streamId) );

        camera_metadata_t *request;
        request = allocate_camera_metadata(20, 2000);

        uint8_t metadataMode = ANDROID_REQUEST_METADATA_MODE_FULL;
        add_camera_metadata_entry(request,
                ANDROID_REQUEST_METADATA_MODE,
                (void**)&metadataMode, 1);
        uint32_t outputStreams = streamId;
        add_camera_metadata_entry(request,
                ANDROID_REQUEST_OUTPUT_STREAMS,
                (void**)&outputStreams, 1);

        uint64_t exposureTime = 10*MSEC;
        add_camera_metadata_entry(request,
                ANDROID_SENSOR_EXPOSURE_TIME,
                (void**)&exposureTime, 1);
        uint64_t frameDuration = 30*MSEC;
        add_camera_metadata_entry(request,
                ANDROID_SENSOR_FRAME_DURATION,
                (void**)&frameDuration, 1);
        uint32_t sensitivity = 100;
        add_camera_metadata_entry(request,
                ANDROID_SENSOR_SENSITIVITY,
                (void**)&sensitivity, 1);
        uint8_t requestType = ANDROID_REQUEST_TYPE_CAPTURE;
        add_camera_metadata_entry(request,
                ANDROID_REQUEST_TYPE,
                (void**)&requestType, 1);

        uint32_t hourOfDay = 12;
        add_camera_metadata_entry(request,
                0x80000000, // EMULATOR_HOUROFDAY
                &hourOfDay, 1);

        IF_ALOGV() {
            std::cout << "Input request: " << std::endl;
            dump_indented_camera_metadata(request, 0, 1, 2);
        }

        res = mRequests.enqueue(request);
        ASSERT_EQ(NO_ERROR, res) << "Can't enqueue request: " << strerror(-res);

        res = mFrames.waitForBuffer(exposureTime + SEC);
        ASSERT_EQ(NO_ERROR, res) << "No frame to get: " << strerror(-res);

        camera_metadata_t *frame;
        res = mFrames.dequeue(&frame);
        ASSERT_EQ(NO_ERROR, res);
        ASSERT_TRUE(frame != NULL);

        IF_ALOGV() {
            std::cout << "Output frame:" << std::endl;
            dump_indented_camera_metadata(frame, 0, 1, 2);
        }

        res = rawWaiter->waitForFrame(exposureTime + SEC);
        ASSERT_EQ(NO_ERROR, res);

        CpuConsumer::LockedBuffer buffer;
        res = rawConsumer->lockNextBuffer(&buffer);
        ASSERT_EQ(NO_ERROR, res);

        IF_ALOGV() {
            const char *dumpname =
                    "/data/local/tmp/camera2_test-capture1raw-dump.raw";
            ALOGV("Dumping raw buffer to %s", dumpname);
            // Write to file
            std::ofstream rawFile(dumpname);
            size_t bpp = 2;
            for (unsigned int y = 0; y < buffer.height; y++) {
                rawFile.write(
                        (const char *)(buffer.data + y * buffer.stride * bpp),
                        buffer.width * bpp);
            }
            rawFile.close();
        }

        res = rawConsumer->unlockBuffer(buffer);
        ASSERT_EQ(NO_ERROR, res);

        ASSERT_EQ(OK, waitUntilDrained());
        ASSERT_NO_FATAL_FAILURE(disconnectStream(streamId));

        res = closeCameraDevice(&mDevice);
        ASSERT_EQ(NO_ERROR, res) << "Failed to close camera device";

    }
}

TEST_F(Camera2Test, CaptureBurstRaw) {

    TEST_EXTENSION_FORKING_INIT;

    status_t res;

    for (int id = 0; id < getNumCameras(); id++) {
        if (!isHal2Supported(id)) continue;

        ASSERT_NO_FATAL_FAILURE(setUpCamera(id));

        sp<CpuConsumer> rawConsumer = new CpuConsumer(1);
        sp<FrameWaiter> rawWaiter = new FrameWaiter();
        rawConsumer->setFrameAvailableListener(rawWaiter);

        const int32_t *rawResolutions;
        size_t    rawResolutionsCount;

        int format = HAL_PIXEL_FORMAT_RAW_SENSOR;

        getResolutionList(format,
                &rawResolutions, &rawResolutionsCount);

        if (rawResolutionsCount <= 0) {
            const ::testing::TestInfo* const test_info =
                ::testing::UnitTest::GetInstance()->current_test_info();
            std::cerr << "Skipping test "
                      << test_info->test_case_name() << "."
                      << test_info->name()
                      << " because the optional format was not available: "
                      << "RAW_SENSOR" << std::endl;
            return;
        }

        ASSERT_LT((uint32_t)0, rawResolutionsCount);

        // Pick first available raw resolution
        int width = rawResolutions[0];
        int height = rawResolutions[1];

        int streamId;
        ASSERT_NO_FATAL_FAILURE(
            setUpStream(rawConsumer->getProducerInterface(),
                    width, height, format, &streamId) );

        camera_metadata_t *request;
        request = allocate_camera_metadata(20, 2000);

        uint8_t metadataMode = ANDROID_REQUEST_METADATA_MODE_FULL;
        add_camera_metadata_entry(request,
                ANDROID_REQUEST_METADATA_MODE,
                (void**)&metadataMode, 1);
        uint32_t outputStreams = streamId;
        add_camera_metadata_entry(request,
                ANDROID_REQUEST_OUTPUT_STREAMS,
                (void**)&outputStreams, 1);

        uint64_t frameDuration = 30*MSEC;
        add_camera_metadata_entry(request,
                ANDROID_SENSOR_FRAME_DURATION,
                (void**)&frameDuration, 1);
        uint32_t sensitivity = 100;
        add_camera_metadata_entry(request,
                ANDROID_SENSOR_SENSITIVITY,
                (void**)&sensitivity, 1);
        uint8_t requestType = ANDROID_REQUEST_TYPE_CAPTURE;
        add_camera_metadata_entry(request,
                ANDROID_REQUEST_TYPE,
                (void**)&requestType, 1);

        uint32_t hourOfDay = 12;
        add_camera_metadata_entry(request,
                0x80000000, // EMULATOR_HOUROFDAY
                &hourOfDay, 1);

        IF_ALOGV() {
            std::cout << "Input request template: " << std::endl;
            dump_indented_camera_metadata(request, 0, 1, 2);
        }

        int numCaptures = 10;

        // Enqueue numCaptures requests with increasing exposure time

        uint64_t exposureTime = 100 * USEC;
        for (int reqCount = 0; reqCount < numCaptures; reqCount++ ) {
            camera_metadata_t *req;
            req = allocate_camera_metadata(20, 2000);
            append_camera_metadata(req, request);

            add_camera_metadata_entry(req,
                    ANDROID_SENSOR_EXPOSURE_TIME,
                    (void**)&exposureTime, 1);
            exposureTime *= 2;

            res = mRequests.enqueue(req);
            ASSERT_EQ(NO_ERROR, res) << "Can't enqueue request: "
                    << strerror(-res);
        }

        // Get frames and image buffers one by one
        uint64_t expectedExposureTime = 100 * USEC;
        for (int frameCount = 0; frameCount < 10; frameCount++) {
            res = mFrames.waitForBuffer(SEC + expectedExposureTime);
            ASSERT_EQ(NO_ERROR, res) << "No frame to get: " << strerror(-res);

            camera_metadata_t *frame;
            res = mFrames.dequeue(&frame);
            ASSERT_EQ(NO_ERROR, res);
            ASSERT_TRUE(frame != NULL);

            camera_metadata_entry_t frameNumber;
            res = find_camera_metadata_entry(frame,
                    ANDROID_REQUEST_FRAME_COUNT,
                    &frameNumber);
            ASSERT_EQ(NO_ERROR, res);
            ASSERT_EQ(frameCount, *frameNumber.data.i32);

            res = rawWaiter->waitForFrame(SEC + expectedExposureTime);
            ASSERT_EQ(NO_ERROR, res) <<
                    "Never got raw data for capture " << frameCount;

            CpuConsumer::LockedBuffer buffer;
            res = rawConsumer->lockNextBuffer(&buffer);
            ASSERT_EQ(NO_ERROR, res);

            IF_ALOGV() {
                char dumpname[60];
                snprintf(dumpname, 60,
                        "/data/local/tmp/camera2_test-"
                        "captureBurstRaw-dump_%d.raw",
                        frameCount);
                ALOGV("Dumping raw buffer to %s", dumpname);
                // Write to file
                std::ofstream rawFile(dumpname);
                for (unsigned int y = 0; y < buffer.height; y++) {
                    rawFile.write(
                            (const char *)(buffer.data + y * buffer.stride * 2),
                            buffer.width * 2);
                }
                rawFile.close();
            }

            res = rawConsumer->unlockBuffer(buffer);
            ASSERT_EQ(NO_ERROR, res);

            expectedExposureTime *= 2;
        }
    }
}

TEST_F(Camera2Test, ConstructDefaultRequests) {

    TEST_EXTENSION_FORKING_INIT;

    status_t res;

    for (int id = 0; id < getNumCameras(); id++) {
        if (!isHal2Supported(id)) continue;

        ASSERT_NO_FATAL_FAILURE(setUpCamera(id));

        for (int i = CAMERA2_TEMPLATE_PREVIEW; i < CAMERA2_TEMPLATE_COUNT;
             i++) {
            camera_metadata_t *request = NULL;
            res = mDevice->ops->construct_default_request(mDevice,
                    i,
                    &request);
            EXPECT_EQ(NO_ERROR, res) <<
                    "Unable to construct request from template type " << i;
            EXPECT_TRUE(request != NULL);
            EXPECT_LT((size_t)0, get_camera_metadata_entry_count(request));
            EXPECT_LT((size_t)0, get_camera_metadata_data_count(request));

            IF_ALOGV() {
                std::cout << "  ** Template type " << i << ":"<<std::endl;
                dump_indented_camera_metadata(request, 0, 2, 4);
            }

            free_camera_metadata(request);
        }
    }
}

TEST_F(Camera2Test, Capture1Jpeg) {
    status_t res;

    for (int id = 0; id < getNumCameras(); id++) {
        if (!isHal2Supported(id)) continue;

        ASSERT_NO_FATAL_FAILURE(setUpCamera(id));

        sp<CpuConsumer> jpegConsumer = new CpuConsumer(1);
        sp<FrameWaiter> jpegWaiter = new FrameWaiter();
        jpegConsumer->setFrameAvailableListener(jpegWaiter);

        const int32_t *jpegResolutions;
        size_t   jpegResolutionsCount;

        int format = HAL_PIXEL_FORMAT_BLOB;

        getResolutionList(format,
                &jpegResolutions, &jpegResolutionsCount);
        ASSERT_LT((size_t)0, jpegResolutionsCount);

        // Pick first available JPEG resolution
        int width = jpegResolutions[0];
        int height = jpegResolutions[1];

        int streamId;
        ASSERT_NO_FATAL_FAILURE(
            setUpStream(jpegConsumer->getProducerInterface(),
                    width, height, format, &streamId) );

        camera_metadata_t *request;
        request = allocate_camera_metadata(20, 2000);

        uint8_t metadataMode = ANDROID_REQUEST_METADATA_MODE_FULL;
        add_camera_metadata_entry(request,
                ANDROID_REQUEST_METADATA_MODE,
                (void**)&metadataMode, 1);
        uint32_t outputStreams = streamId;
        add_camera_metadata_entry(request,
                ANDROID_REQUEST_OUTPUT_STREAMS,
                (void**)&outputStreams, 1);

        uint64_t exposureTime = 10*MSEC;
        add_camera_metadata_entry(request,
                ANDROID_SENSOR_EXPOSURE_TIME,
                (void**)&exposureTime, 1);
        uint64_t frameDuration = 30*MSEC;
        add_camera_metadata_entry(request,
                ANDROID_SENSOR_FRAME_DURATION,
                (void**)&frameDuration, 1);
        uint32_t sensitivity = 100;
        add_camera_metadata_entry(request,
                ANDROID_SENSOR_SENSITIVITY,
                (void**)&sensitivity, 1);
        uint8_t requestType = ANDROID_REQUEST_TYPE_CAPTURE;
        add_camera_metadata_entry(request,
                ANDROID_REQUEST_TYPE,
                (void**)&requestType, 1);

        uint32_t hourOfDay = 12;
        add_camera_metadata_entry(request,
                0x80000000, // EMULATOR_HOUROFDAY
                &hourOfDay, 1);

        IF_ALOGV() {
            std::cout << "Input request: " << std::endl;
            dump_indented_camera_metadata(request, 0, 1, 4);
        }

        res = mRequests.enqueue(request);
        ASSERT_EQ(NO_ERROR, res) << "Can't enqueue request: " << strerror(-res);

        res = mFrames.waitForBuffer(exposureTime + SEC);
        ASSERT_EQ(NO_ERROR, res) << "No frame to get: " << strerror(-res);

        camera_metadata_t *frame;
        res = mFrames.dequeue(&frame);
        ASSERT_EQ(NO_ERROR, res);
        ASSERT_TRUE(frame != NULL);

        IF_ALOGV() {
            std::cout << "Output frame:" << std::endl;
            dump_indented_camera_metadata(frame, 0, 1, 4);
        }

        res = jpegWaiter->waitForFrame(exposureTime + SEC);
        ASSERT_EQ(NO_ERROR, res);

        CpuConsumer::LockedBuffer buffer;
        res = jpegConsumer->lockNextBuffer(&buffer);
        ASSERT_EQ(NO_ERROR, res);

        IF_ALOGV() {
            const char *dumpname =
                    "/data/local/tmp/camera2_test-capture1jpeg-dump.jpeg";
            ALOGV("Dumping raw buffer to %s", dumpname);
            // Write to file
            std::ofstream jpegFile(dumpname);
            size_t bpp = 1;
            for (unsigned int y = 0; y < buffer.height; y++) {
                jpegFile.write(
                        (const char *)(buffer.data + y * buffer.stride * bpp),
                        buffer.width * bpp);
            }
            jpegFile.close();
        }

        res = jpegConsumer->unlockBuffer(buffer);
        ASSERT_EQ(NO_ERROR, res);

        ASSERT_EQ(OK, waitUntilDrained());
        ASSERT_NO_FATAL_FAILURE(disconnectStream(streamId));

        res = closeCameraDevice(&mDevice);
        ASSERT_EQ(NO_ERROR, res) << "Failed to close camera device";

    }
}

} // namespace tests
} // namespace camera2
} // namespace android
