/*
 * 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_EQ(version2_0, module->module_api_version)
                << "Camera module version is 0x"
                << std::hex << module->module_api_version
                << ", not 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) {
                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;
        ALOGV("Closing camera %p", cam_dev);

        hw_device_t *dev = reinterpret_cast<hw_device_t *>(cam_dev);
        res = dev->close(dev);
        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);
        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);
        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 %d", 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
