VtsHalCameraProviderV2_4TargetTest.cpp revision afc6723e862a5b9565ce00c21f3254f339300ae2
1/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "camera_hidl_hal_test"
18#include <android/hardware/camera/provider/2.4/ICameraProvider.h>
19#include <android/hardware/camera/device/3.2/ICameraDevice.h>
20#include <android/hardware/camera/device/1.0/ICameraDevice.h>
21#include "CameraParameters.h"
22#include <system/camera.h>
23#include <android/log.h>
24#include <ui/GraphicBuffer.h>
25#include <VtsHalHidlTargetTestBase.h>
26#include <gui/BufferQueue.h>
27#include <gui/Surface.h>
28#include <gui/BufferItemConsumer.h>
29#include <binder/MemoryHeapBase.h>
30#include <regex>
31#include "system/camera_metadata.h"
32#include <hardware/gralloc.h>
33#include <hardware/gralloc1.h>
34#include <unordered_map>
35#include <mutex>
36#include <condition_variable>
37#include <chrono>
38#include <inttypes.h>
39#include <utils/Errors.h>
40
41using ::android::hardware::Return;
42using ::android::hardware::Void;
43using ::android::hardware::hidl_handle;
44using ::android::hardware::hidl_string;
45using ::android::hardware::hidl_vec;
46using ::android::sp;
47using ::android::wp;
48using ::android::GraphicBuffer;
49using ::android::IGraphicBufferProducer;
50using ::android::IGraphicBufferConsumer;
51using ::android::BufferQueue;
52using ::android::BufferItemConsumer;
53using ::android::Surface;
54using ::android::CameraParameters;
55using ::android::hardware::graphics::common::V1_0::PixelFormat;
56using ::android::hardware::graphics::allocator::V2_0::ProducerUsage;
57using ::android::hardware::camera::common::V1_0::Status;
58using ::android::hardware::camera::common::V1_0::CameraDeviceStatus;
59using ::android::hardware::camera::common::V1_0::TorchMode;
60using ::android::hardware::camera::common::V1_0::TorchModeStatus;
61using ::android::hardware::camera::provider::V2_4::ICameraProvider;
62using ::android::hardware::camera::provider::V2_4::ICameraProviderCallback;
63using ::android::hardware::camera::device::V3_2::ICameraDevice;
64using ::android::hardware::camera::device::V3_2::CaptureRequest;
65using ::android::hardware::camera::device::V3_2::CaptureResult;
66using ::android::hardware::camera::device::V3_2::ICameraDeviceCallback;
67using ::android::hardware::camera::device::V3_2::ICameraDeviceSession;
68using ::android::hardware::camera::device::V3_2::NotifyMsg;
69using ::android::hardware::camera::device::V3_2::RequestTemplate;
70using ::android::hardware::camera::device::V3_2::Stream;
71using ::android::hardware::camera::device::V3_2::StreamType;
72using ::android::hardware::camera::device::V3_2::StreamRotation;
73using ::android::hardware::camera::device::V3_2::StreamConfiguration;
74using ::android::hardware::camera::device::V3_2::StreamConfigurationMode;
75using ::android::hardware::camera::device::V3_2::CameraMetadata;
76using ::android::hardware::camera::device::V3_2::HalStreamConfiguration;
77using ::android::hardware::camera::device::V3_2::BufferStatus;
78using ::android::hardware::camera::device::V3_2::StreamBuffer;
79using ::android::hardware::camera::device::V3_2::MsgType;
80using ::android::hardware::camera::device::V3_2::ErrorMsg;
81using ::android::hardware::camera::device::V3_2::ErrorCode;
82using ::android::hardware::camera::device::V1_0::CameraFacing;
83using ::android::hardware::camera::device::V1_0::NotifyCallbackMsg;
84using ::android::hardware::camera::device::V1_0::CommandType;
85using ::android::hardware::camera::device::V1_0::DataCallbackMsg;
86using ::android::hardware::camera::device::V1_0::CameraFrameMetadata;
87using ::android::hardware::camera::device::V1_0::ICameraDevicePreviewCallback;
88using ::android::hardware::camera::device::V1_0::FrameCallbackFlag;
89
90const char kCameraPassthroughServiceName[] = "legacy/0";
91const uint32_t kMaxPreviewWidth = 1920;
92const uint32_t kMaxPreviewHeight = 1080;
93const uint32_t kMaxVideoWidth = 4096;
94const uint32_t kMaxVideoHeight = 2160;
95const int64_t kStreamBufferTimeoutSec = 3;
96const int64_t kAutoFocusTimeoutSec = 5;
97const int64_t kTorchTimeoutSec = 1;
98const int64_t kEmptyFlushTimeoutMSec = 200;
99const char kDumpOutput[] = "/dev/null";
100
101struct AvailableStream {
102    int32_t width;
103    int32_t height;
104    int32_t format;
105};
106
107struct AvailableZSLInputOutput {
108    int32_t inputFormat;
109    int32_t outputFormat;
110};
111
112namespace {
113    // "device@<version>/legacy/<id>"
114    const char *kDeviceNameRE = "device@([0-9]+\\.[0-9]+)/legacy/(.+)";
115    const int CAMERA_DEVICE_API_VERSION_3_2 = 0x302;
116    const int CAMERA_DEVICE_API_VERSION_1_0 = 0x100;
117    const char *kHAL3_2 = "3.2";
118    const char *kHAL1_0 = "1.0";
119
120    bool matchDeviceName(const hidl_string& deviceName, std::smatch& sm) {
121        std::regex e(kDeviceNameRE);
122        std::string deviceNameStd(deviceName.c_str());
123        return std::regex_match(deviceNameStd, sm, e);
124    }
125
126    int getCameraDeviceVersion(const hidl_string& deviceName) {
127        std::smatch sm;
128        bool match = matchDeviceName(deviceName, sm);
129        if (!match) {
130            return -1;
131        }
132        std::string version = sm[1].str();
133        if (version.compare(kHAL3_2) == 0) {
134            // maybe switched to 3.4 or define the hidl version enumlater
135            return CAMERA_DEVICE_API_VERSION_3_2;
136        } else if (version.compare(kHAL1_0) == 0) {
137            return CAMERA_DEVICE_API_VERSION_1_0;
138        }
139        return 0;
140    }
141
142    Status mapToStatus(::android::status_t s)  {
143        switch(s) {
144            case ::android::OK:
145                return Status::OK ;
146            case ::android::BAD_VALUE:
147                return Status::ILLEGAL_ARGUMENT ;
148            case -EBUSY:
149                return Status::CAMERA_IN_USE;
150            case -EUSERS:
151                return Status::MAX_CAMERAS_IN_USE;
152            case ::android::UNKNOWN_TRANSACTION:
153                return Status::METHOD_NOT_SUPPORTED;
154            case ::android::INVALID_OPERATION:
155                return Status::OPERATION_NOT_SUPPORTED;
156            case ::android::DEAD_OBJECT:
157                return Status::CAMERA_DISCONNECTED;
158        }
159        ALOGW("Unexpected HAL status code %d", s);
160        return Status::OPERATION_NOT_SUPPORTED;
161    }
162}
163
164// Test environment for camera
165class CameraHidlEnvironment : public ::testing::Environment {
166public:
167    // get the test environment singleton
168    static CameraHidlEnvironment* Instance() {
169        static CameraHidlEnvironment* instance = new CameraHidlEnvironment;
170        return instance;
171    }
172
173    virtual void SetUp() override;
174    virtual void TearDown() override;
175
176    sp<ICameraProvider> mProvider;
177
178private:
179    CameraHidlEnvironment() {}
180
181    GTEST_DISALLOW_COPY_AND_ASSIGN_(CameraHidlEnvironment);
182};
183
184void CameraHidlEnvironment::SetUp() {
185    // TODO: test the binderized mode
186    mProvider = ::testing::VtsHalHidlTargetTestBase::getService<ICameraProvider>(kCameraPassthroughServiceName);
187    // TODO: handle the device doesn't have any camera case
188    ALOGI_IF(mProvider, "provider is not nullptr, %p", mProvider.get());
189    ASSERT_NE(mProvider, nullptr);
190}
191
192void CameraHidlEnvironment::TearDown() {
193    ALOGI("TearDown CameraHidlEnvironment");
194}
195
196struct BufferItemHander: public BufferItemConsumer::FrameAvailableListener {
197    BufferItemHander(wp<BufferItemConsumer> consumer) : mConsumer(consumer) {}
198
199    void onFrameAvailable(const android::BufferItem&) override {
200        sp<BufferItemConsumer> consumer = mConsumer.promote();
201        ASSERT_NE(nullptr, consumer.get());
202
203        android::BufferItem buffer;
204        ASSERT_EQ(android::OK, consumer->acquireBuffer(&buffer, 0));
205        ASSERT_EQ(android::OK, consumer->releaseBuffer(buffer));
206    }
207
208 private:
209    wp<BufferItemConsumer> mConsumer;
210};
211
212struct PreviewWindowCb : public ICameraDevicePreviewCallback {
213    PreviewWindowCb(sp<ANativeWindow> anw) : mPreviewWidth(0),
214            mPreviewHeight(0), mFormat(0), mPreviewUsage(0),
215            mPreviewSwapInterval(-1), mCrop{-1, -1, -1, -1}, mAnw(anw) {}
216
217    using dequeueBuffer_cb =
218            std::function<void(Status status, uint64_t bufferId,
219                    const hidl_handle& buffer, uint32_t stride)>;
220    Return<void> dequeueBuffer(dequeueBuffer_cb _hidl_cb) override;
221
222    Return<Status> enqueueBuffer(uint64_t bufferId) override;
223
224    Return<Status> cancelBuffer(uint64_t bufferId) override;
225
226    Return<Status> setBufferCount(uint32_t count) override;
227
228    Return<Status> setBuffersGeometry(uint32_t w,
229            uint32_t h, PixelFormat format) override;
230
231    Return<Status> setCrop(int32_t left, int32_t top,
232            int32_t right, int32_t bottom) override;
233
234    Return<Status> setUsage(ProducerUsage usage) override;
235
236    Return<Status> setSwapInterval(int32_t interval) override;
237
238    using getMinUndequeuedBufferCount_cb =
239            std::function<void(Status status, uint32_t count)>;
240    Return<void> getMinUndequeuedBufferCount(
241            getMinUndequeuedBufferCount_cb _hidl_cb) override;
242
243    Return<Status> setTimestamp(int64_t timestamp) override;
244
245 private:
246    struct BufferHasher {
247        size_t operator()(const buffer_handle_t& buf) const {
248            if (buf == nullptr)
249                return 0;
250
251            size_t result = 1;
252            result = 31 * result + buf->numFds;
253            result = 31 * result + buf->numInts;
254            int length = buf->numFds + buf->numInts;
255            for (int i = 0; i < length; i++) {
256                result = 31 * result + buf->data[i];
257            }
258            return result;
259        }
260    };
261
262    struct BufferComparator {
263        bool operator()(const buffer_handle_t& buf1,
264                const buffer_handle_t& buf2) const {
265            if ((buf1->numFds == buf2->numFds) &&
266                    (buf1->numInts == buf2->numInts)) {
267                int length = buf1->numFds + buf1->numInts;
268                for (int i = 0; i < length; i++) {
269                    if (buf1->data[i] != buf2->data[i]) {
270                        return false;
271                    }
272                }
273                return true;
274            }
275            return false;
276        }
277    };
278
279    std::pair<bool, uint64_t> getBufferId(ANativeWindowBuffer* anb);
280    void cleanupCirculatingBuffers();
281
282    std::mutex mBufferIdMapLock; // protecting mBufferIdMap and mNextBufferId
283    typedef std::unordered_map<const buffer_handle_t, uint64_t,
284            BufferHasher, BufferComparator> BufferIdMap;
285
286    BufferIdMap mBufferIdMap; // stream ID -> per stream buffer ID map
287    std::unordered_map<uint64_t, ANativeWindowBuffer*> mReversedBufMap;
288    uint64_t mNextBufferId = 1;
289
290    uint32_t mPreviewWidth, mPreviewHeight;
291    int mFormat, mPreviewUsage;
292    int32_t mPreviewSwapInterval;
293    android_native_rect_t mCrop;
294    sp<ANativeWindow> mAnw;     //Native window reference
295};
296
297std::pair<bool, uint64_t> PreviewWindowCb::getBufferId(
298        ANativeWindowBuffer* anb) {
299    std::lock_guard<std::mutex> lock(mBufferIdMapLock);
300
301    buffer_handle_t& buf = anb->handle;
302    auto it = mBufferIdMap.find(buf);
303    if (it == mBufferIdMap.end()) {
304        uint64_t bufId = mNextBufferId++;
305        mBufferIdMap[buf] = bufId;
306        mReversedBufMap[bufId] = anb;
307        return std::make_pair(true, bufId);
308    } else {
309        return std::make_pair(false, it->second);
310    }
311}
312
313void PreviewWindowCb::cleanupCirculatingBuffers() {
314    std::lock_guard<std::mutex> lock(mBufferIdMapLock);
315    mBufferIdMap.clear();
316    mReversedBufMap.clear();
317}
318
319Return<void> PreviewWindowCb::dequeueBuffer(dequeueBuffer_cb _hidl_cb) {
320    ANativeWindowBuffer* anb;
321    auto rc = native_window_dequeue_buffer_and_wait(mAnw.get(), &anb);
322    uint64_t bufferId = 0;
323    uint32_t stride = 0;
324    hidl_handle buf = nullptr;
325    if (rc == ::android::OK) {
326        auto pair = getBufferId(anb);
327        buf = (pair.first) ? anb->handle : nullptr;
328        bufferId = pair.second;
329        stride = anb->stride;
330    }
331
332    _hidl_cb(mapToStatus(rc), bufferId, buf, stride);
333    return Void();
334}
335
336Return<Status> PreviewWindowCb::enqueueBuffer(uint64_t bufferId) {
337    if (mReversedBufMap.count(bufferId) == 0) {
338        ALOGE("%s: bufferId %" PRIu64 " not found", __FUNCTION__, bufferId);
339        return Status::ILLEGAL_ARGUMENT;
340    }
341    return mapToStatus(mAnw->queueBuffer(mAnw.get(),
342            mReversedBufMap.at(bufferId), -1));
343}
344
345Return<Status> PreviewWindowCb::cancelBuffer(uint64_t bufferId) {
346    if (mReversedBufMap.count(bufferId) == 0) {
347        ALOGE("%s: bufferId %" PRIu64 " not found", __FUNCTION__, bufferId);
348        return Status::ILLEGAL_ARGUMENT;
349    }
350    return mapToStatus(mAnw->cancelBuffer(mAnw.get(),
351            mReversedBufMap.at(bufferId), -1));
352}
353
354Return<Status> PreviewWindowCb::setBufferCount(uint32_t count) {
355    if (mAnw.get() != nullptr) {
356        // WAR for b/27039775
357        native_window_api_disconnect(mAnw.get(), NATIVE_WINDOW_API_CAMERA);
358        native_window_api_connect(mAnw.get(), NATIVE_WINDOW_API_CAMERA);
359        if (mPreviewWidth != 0) {
360            native_window_set_buffers_dimensions(mAnw.get(),
361                    mPreviewWidth, mPreviewHeight);
362            native_window_set_buffers_format(mAnw.get(), mFormat);
363        }
364        if (mPreviewUsage != 0) {
365            native_window_set_usage(mAnw.get(), mPreviewUsage);
366        }
367        if (mPreviewSwapInterval >= 0) {
368            mAnw->setSwapInterval(mAnw.get(), mPreviewSwapInterval);
369        }
370        if (mCrop.left >= 0) {
371            native_window_set_crop(mAnw.get(), &(mCrop));
372        }
373    }
374
375    auto rc = native_window_set_buffer_count(mAnw.get(), count);
376    if (rc == ::android::OK) {
377        cleanupCirculatingBuffers();
378    }
379
380    return mapToStatus(rc);
381}
382
383Return<Status> PreviewWindowCb::setBuffersGeometry(uint32_t w, uint32_t h,
384        PixelFormat format) {
385    auto rc = native_window_set_buffers_dimensions(mAnw.get(), w, h);
386    if (rc == ::android::OK) {
387        mPreviewWidth = w;
388        mPreviewHeight = h;
389        rc = native_window_set_buffers_format(mAnw.get(),
390                static_cast<int>(format));
391        if (rc == ::android::OK) {
392            mFormat = static_cast<int>(format);
393        }
394    }
395
396    return mapToStatus(rc);
397}
398
399Return<Status> PreviewWindowCb::setCrop(int32_t left, int32_t top,
400        int32_t right, int32_t bottom) {
401    android_native_rect_t crop = { left, top, right, bottom };
402    auto rc = native_window_set_crop(mAnw.get(), &crop);
403    if (rc == ::android::OK) {
404        mCrop = crop;
405    }
406    return mapToStatus(rc);
407}
408
409Return<Status> PreviewWindowCb::setUsage(ProducerUsage usage) {
410    auto rc = native_window_set_usage(mAnw.get(), static_cast<int>(usage));
411    if (rc == ::android::OK) {
412        mPreviewUsage =  static_cast<int>(usage);
413    }
414    return mapToStatus(rc);
415}
416
417Return<Status> PreviewWindowCb::setSwapInterval(int32_t interval) {
418    auto rc = mAnw->setSwapInterval(mAnw.get(), interval);
419    if (rc == ::android::OK) {
420        mPreviewSwapInterval = interval;
421    }
422    return mapToStatus(rc);
423}
424
425Return<void> PreviewWindowCb::getMinUndequeuedBufferCount(
426        getMinUndequeuedBufferCount_cb _hidl_cb) {
427    int count = 0;
428    auto rc = mAnw->query(mAnw.get(),
429            NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &count);
430    _hidl_cb(mapToStatus(rc), count);
431    return Void();
432}
433
434Return<Status> PreviewWindowCb::setTimestamp(int64_t timestamp) {
435    return mapToStatus(native_window_set_buffers_timestamp(mAnw.get(),
436            timestamp));
437}
438
439// The main test class for camera HIDL HAL.
440class CameraHidlTest : public ::testing::VtsHalHidlTargetTestBase {
441public:
442    virtual void SetUp() override {}
443    virtual void TearDown() override {}
444
445    hidl_vec<hidl_string> getCameraDeviceNames();
446
447    struct EmptyDeviceCb : public ICameraDeviceCallback {
448        virtual Return<void> processCaptureResult(const CaptureResult& /*result*/) override {
449            ALOGI("processCaptureResult callback");
450            ADD_FAILURE(); // Empty callback should not reach here
451            return Void();
452        }
453
454        virtual Return<void> notify(const NotifyMsg& /*msg*/) override {
455            ALOGI("notify callback");
456            ADD_FAILURE(); // Empty callback should not reach here
457            return Void();
458        }
459    };
460
461    struct DeviceCb : public ICameraDeviceCallback {
462        DeviceCb(CameraHidlTest *parent) : mParent(parent) {}
463        Return<void> processCaptureResult(const CaptureResult& result) override;
464        Return<void> notify(const NotifyMsg& msg) override;
465
466     private:
467        CameraHidlTest *mParent;               // Parent object
468    };
469
470    struct TorchProviderCb : public ICameraProviderCallback {
471        TorchProviderCb(CameraHidlTest *parent) : mParent(parent) {}
472        virtual Return<void> cameraDeviceStatusChange(
473                const hidl_string&, CameraDeviceStatus) override {
474            return Void();
475        }
476
477        virtual Return<void> torchModeStatusChange(
478                const hidl_string&, TorchModeStatus newStatus) override {
479            std::lock_guard<std::mutex> l(mParent->mTorchLock);
480            mParent->mTorchStatus = newStatus;
481            mParent->mTorchCond.notify_one();
482            return Void();
483        }
484
485     private:
486        CameraHidlTest *mParent;               // Parent object
487    };
488
489    struct Camera1DeviceCb :
490            public ::android::hardware::camera::device::V1_0::ICameraDeviceCallback {
491        Camera1DeviceCb(CameraHidlTest *parent) : mParent(parent) {}
492
493        Return<void> notifyCallback(NotifyCallbackMsg msgType,
494                int32_t ext1, int32_t ext2) override;
495
496        Return<uint32_t> registerMemory(const hidl_handle& descriptor,
497                uint32_t bufferSize, uint32_t bufferCount) override;
498
499        Return<void> unregisterMemory(uint32_t memId) override;
500
501        Return<void> dataCallback(DataCallbackMsg msgType,
502                uint32_t data, uint32_t bufferIndex,
503                const CameraFrameMetadata& metadata) override;
504
505        Return<void> dataCallbackTimestamp(DataCallbackMsg msgType,
506                uint32_t data, uint32_t bufferIndex,
507                int64_t timestamp) override;
508
509        Return<void> handleCallbackTimestamp(DataCallbackMsg msgType,
510                const hidl_handle& frameData,uint32_t data,
511                uint32_t bufferIndex, int64_t timestamp) override;
512
513     private:
514        CameraHidlTest *mParent;               // Parent object
515    };
516
517    void openCameraDevice(const std::string &name,const CameraHidlEnvironment* env,
518            sp<::android::hardware::camera::device::V1_0::ICameraDevice> *device /*out*/);
519    void setupPreviewWindow(
520            const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device,
521            sp<BufferItemConsumer> *bufferItemConsumer /*out*/,
522            sp<BufferItemHander> *bufferHandler /*out*/);
523    void stopPreviewAndClose(
524            const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device);
525    void startPreview(
526            const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device);
527    void enableMsgType(unsigned int msgType,
528            const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device);
529    void disableMsgType(unsigned int msgType,
530            const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device);
531    void getParameters(
532            const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device,
533            CameraParameters *cameraParams /*out*/);
534    void setParameters(
535            const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device,
536            const CameraParameters &cameraParams);
537    void waitForFrameLocked(DataCallbackMsg msgFrame,
538            std::unique_lock<std::mutex> &l);
539    void openEmptyDeviceSession(const std::string &name,
540            const CameraHidlEnvironment* env,
541            sp<ICameraDeviceSession> *session /*out*/,
542            camera_metadata_t **staticMeta /*out*/);
543    void configurePreviewStream(const std::string &name,
544            const CameraHidlEnvironment* env,
545            const AvailableStream *previewThreshold,
546            sp<ICameraDeviceSession> *session /*out*/,
547            Stream *previewStream /*out*/,
548            HalStreamConfiguration *halStreamConfig /*out*/);
549    static Status getAvailableOutputStreams(camera_metadata_t *staticMeta,
550            std::vector<AvailableStream> &outputStreams,
551            const AvailableStream *threshold = nullptr);
552    static Status isConstrainedModeAvailable(camera_metadata_t *staticMeta);
553    static Status pickConstrainedModeSize(camera_metadata_t *staticMeta,
554            AvailableStream &hfrStream);
555    static Status isZSLModeAvailable(camera_metadata_t *staticMeta);
556    static Status getZSLInputOutputMap(camera_metadata_t *staticMeta,
557            std::vector<AvailableZSLInputOutput> &inputOutputMap);
558    static Status findLargestSize(
559            const std::vector<AvailableStream> &streamSizes,
560            int32_t format, AvailableStream &result);
561    static Status isAutoFocusModeAvailable(
562            ::android::CameraParameters &cameraParams, const char *mode) ;
563
564protected:
565    std::mutex mLock;                          // Synchronize access to member variables
566    std::condition_variable mResultCondition;  // Condition variable for incoming results
567    uint32_t mResultFrameNumber;               // Expected result frame number
568    std::vector<StreamBuffer> mResultBuffers;  // Holds stream buffers from capture result
569    std::vector<ErrorMsg> mErrors;             // Holds incoming error notifications
570    DataCallbackMsg mDataMessageTypeReceived;  // Most recent message type received through data callbacks
571    uint32_t mVideoBufferIndex;                // Buffer index of the most recent video buffer
572    uint32_t mVideoData;                       // Buffer data of the most recent video buffer
573    hidl_handle mVideoNativeHandle;            // Most recent video buffer native handle
574    NotifyCallbackMsg mNotifyMessage;          // Current notification message
575
576    std::mutex mTorchLock;                     // Synchronize access to torch status
577    std::condition_variable mTorchCond;        // Condition variable for torch status
578    TorchModeStatus mTorchStatus;              // Current torch status
579
580    // Holds camera registered buffers
581    std::unordered_map<uint32_t, sp<::android::MemoryHeapBase> > mMemoryPool;
582};
583
584Return<void> CameraHidlTest::Camera1DeviceCb::notifyCallback(
585        NotifyCallbackMsg msgType, int32_t ext1 __unused,
586        int32_t ext2 __unused) {
587    std::unique_lock<std::mutex> l(mParent->mLock);
588    mParent->mNotifyMessage = msgType;
589    mParent->mResultCondition.notify_one();
590
591    return Void();
592}
593
594Return<uint32_t> CameraHidlTest::Camera1DeviceCb::registerMemory(
595        const hidl_handle& descriptor, uint32_t bufferSize,
596        uint32_t bufferCount) {
597    if (descriptor->numFds != 1) {
598        ADD_FAILURE() << "camera memory descriptor has"
599                " numFds " <<  descriptor->numFds << " (expect 1)" ;
600        return 0;
601    }
602    if (descriptor->data[0] < 0) {
603        ADD_FAILURE() << "camera memory descriptor has"
604                " FD " << descriptor->data[0] << " (expect >= 0)";
605        return 0;
606    }
607
608    sp<::android::MemoryHeapBase> pool = new ::android::MemoryHeapBase(
609            descriptor->data[0], bufferSize*bufferCount, 0, 0);
610    mParent->mMemoryPool.emplace(pool->getHeapID(), pool);
611
612    return pool->getHeapID();
613}
614
615Return<void> CameraHidlTest::Camera1DeviceCb::unregisterMemory(uint32_t memId) {
616    if (mParent->mMemoryPool.count(memId) == 0) {
617        ALOGE("%s: memory pool ID %d not found", __FUNCTION__, memId);
618        ADD_FAILURE();
619        return Void();
620    }
621
622    mParent->mMemoryPool.erase(memId);
623    return Void();
624}
625
626Return<void> CameraHidlTest::Camera1DeviceCb::dataCallback(
627        DataCallbackMsg msgType __unused, uint32_t data __unused,
628        uint32_t bufferIndex __unused,
629        const CameraFrameMetadata& metadata __unused) {
630    std::unique_lock<std::mutex> l(mParent->mLock);
631    mParent->mDataMessageTypeReceived = msgType;
632    mParent->mResultCondition.notify_one();
633
634    return Void();
635}
636
637Return<void> CameraHidlTest::Camera1DeviceCb::dataCallbackTimestamp(
638        DataCallbackMsg msgType, uint32_t data,
639        uint32_t bufferIndex, int64_t timestamp __unused) {
640    std::unique_lock<std::mutex> l(mParent->mLock);
641    mParent->mDataMessageTypeReceived = msgType;
642    mParent->mVideoBufferIndex = bufferIndex;
643    if (mParent->mMemoryPool.count(data) == 0) {
644        ADD_FAILURE() << "memory pool ID " << data << "not found";
645    }
646    mParent->mVideoData = data;
647    mParent->mResultCondition.notify_one();
648
649    return Void();
650}
651
652Return<void> CameraHidlTest::Camera1DeviceCb::handleCallbackTimestamp(
653        DataCallbackMsg msgType, const hidl_handle& frameData,
654        uint32_t data __unused, uint32_t bufferIndex,
655        int64_t timestamp __unused) {
656    std::unique_lock<std::mutex> l(mParent->mLock);
657    mParent->mDataMessageTypeReceived = msgType;
658    mParent->mVideoBufferIndex = bufferIndex;
659    if (mParent->mMemoryPool.count(data) == 0) {
660        ADD_FAILURE() << "memory pool ID " << data << " not found";
661    }
662    mParent->mVideoData = data;
663    mParent->mVideoNativeHandle = frameData;
664    mParent->mResultCondition.notify_one();
665
666    return Void();
667}
668
669Return<void> CameraHidlTest::DeviceCb::processCaptureResult(
670        const CaptureResult& result) {
671    if (nullptr == mParent) {
672        return Void();
673    }
674
675    std::unique_lock<std::mutex> l(mParent->mLock);
676
677    if(mParent->mResultFrameNumber != result.frameNumber) {
678        ALOGE("%s: Unexpected frame number! Expected: %u received: %u",
679              __func__, mParent->mResultFrameNumber, result.frameNumber);
680        ADD_FAILURE();
681    }
682
683    size_t resultLength = result.outputBuffers.size();
684    for (size_t i = 0; i < resultLength; i++) {
685        mParent->mResultBuffers.push_back(result.outputBuffers[i]);
686    }
687
688    // TODO(epeev): Handle partial results in case client supports them and
689    //              verify the result against request settings.
690
691    l.unlock();
692    mParent->mResultCondition.notify_one();
693
694    return Void();
695}
696
697Return<void> CameraHidlTest::DeviceCb::notify(
698        const NotifyMsg& message) {
699
700    if (MsgType::ERROR == message.type) {
701        {
702            std::lock_guard<std::mutex> l(mParent->mLock);
703            mParent->mErrors.push_back(message.msg.error);
704        }
705
706        if ((ErrorCode::ERROR_REQUEST == message.msg.error.errorCode)
707                || (ErrorCode::ERROR_BUFFER == message.msg.error.errorCode)) {
708            mParent->mResultCondition.notify_one();
709        }
710    }
711
712    return Void();
713}
714
715hidl_vec<hidl_string> CameraHidlTest::getCameraDeviceNames() {
716    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
717    hidl_vec<hidl_string> cameraDeviceNames;
718    Return<void> ret;
719    ret = env->mProvider->getCameraIdList(
720        [&](auto status, const auto& idList) {
721            ALOGI("getCameraIdList returns status:%d", (int)status);
722            for (size_t i = 0; i < idList.size(); i++) {
723                ALOGI("Camera Id[%zu] is %s", i, idList[i].c_str());
724            }
725            ASSERT_EQ(Status::OK, status);
726            cameraDeviceNames = idList;
727        });
728    if (!ret.isOk()) {
729        ADD_FAILURE();
730    }
731    return cameraDeviceNames;
732}
733
734// Test if ICameraProvider::isTorchModeSupported returns Status::OK
735TEST_F(CameraHidlTest, isTorchModeSupported) {
736    Return<void> ret;
737    ret = CameraHidlEnvironment::Instance()->mProvider->isSetTorchModeSupported(
738        [&](auto status, bool support) {
739            ALOGI("isSetTorchModeSupported returns status:%d supported:%d",
740                    (int)status, support);
741            ASSERT_EQ(Status::OK, status);
742        });
743    ASSERT_TRUE(ret.isOk());
744}
745
746// TODO: consider removing this test if getCameraDeviceNames() has the same coverage
747TEST_F(CameraHidlTest, getCameraIdList) {
748    Return<void> ret;
749    ret = CameraHidlEnvironment::Instance()->mProvider->getCameraIdList(
750        [&](auto status, const auto& idList) {
751            ALOGI("getCameraIdList returns status:%d", (int)status);
752            for (size_t i = 0; i < idList.size(); i++) {
753                ALOGI("Camera Id[%zu] is %s", i, idList[i].c_str());
754            }
755            ASSERT_EQ(Status::OK, status);
756            // This is true for internal camera provider.
757            // Not necessary hold for external cameras providers
758            ASSERT_GT(idList.size(), 0u);
759        });
760    ASSERT_TRUE(ret.isOk());
761}
762
763// Test if ICameraProvider::getVendorTags returns Status::OK
764TEST_F(CameraHidlTest, getVendorTags) {
765    Return<void> ret;
766    ret = CameraHidlEnvironment::Instance()->mProvider->getVendorTags(
767        [&](auto status, const auto& vendorTagSecs) {
768            ALOGI("getVendorTags returns status:%d numSections %zu",
769                    (int)status, vendorTagSecs.size());
770            for (size_t i = 0; i < vendorTagSecs.size(); i++) {
771                ALOGI("Vendor tag section %zu name %s",
772                        i, vendorTagSecs[i].sectionName.c_str());
773                for (size_t j = 0; j < vendorTagSecs[i].tags.size(); j++) {
774                    const auto& tag = vendorTagSecs[i].tags[j];
775                    ALOGI("Vendor tag id %u name %s type %d",
776                            tag.tagId,
777                            tag.tagName.c_str(),
778                            (int) tag.tagType);
779                }
780            }
781            ASSERT_EQ(Status::OK, status);
782        });
783    ASSERT_TRUE(ret.isOk());
784}
785
786// Test if ICameraProvider::setCallback returns Status::OK
787TEST_F(CameraHidlTest, setCallback) {
788    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
789    struct ProviderCb : public ICameraProviderCallback {
790        virtual Return<void> cameraDeviceStatusChange(
791                const hidl_string& cameraDeviceName,
792                CameraDeviceStatus newStatus) override {
793            ALOGI("camera device status callback name %s, status %d",
794                    cameraDeviceName.c_str(), (int) newStatus);
795            return Void();
796        }
797
798        virtual Return<void> torchModeStatusChange(
799                const hidl_string& cameraDeviceName,
800                TorchModeStatus newStatus) override {
801            ALOGI("Torch mode status callback name %s, status %d",
802                    cameraDeviceName.c_str(), (int) newStatus);
803            return Void();
804        }
805    };
806    sp<ProviderCb> cb = new ProviderCb;
807    auto status = env->mProvider->setCallback(cb);
808    ASSERT_TRUE(status.isOk());
809    ASSERT_EQ(Status::OK, status);
810}
811
812// Test if ICameraProvider::getCameraDeviceInterface returns Status::OK and non-null device
813TEST_F(CameraHidlTest, getCameraDeviceInterface) {
814    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
815    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
816
817    for (const auto& name : cameraDeviceNames) {
818        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
819            Return<void> ret;
820            ret = env->mProvider->getCameraDeviceInterface_V3_x(
821                name,
822                [&](auto status, const auto& device3_2) {
823                    ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
824                    ASSERT_EQ(Status::OK, status);
825                    ASSERT_NE(device3_2, nullptr);
826                });
827            ASSERT_TRUE(ret.isOk());
828        } else if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
829            Return<void> ret;
830            ret = env->mProvider->getCameraDeviceInterface_V1_x(
831                name,
832                [&](auto status, const auto& device1) {
833                    ALOGI("getCameraDeviceInterface_V1_x returns status:%d", (int)status);
834                    ASSERT_EQ(Status::OK, status);
835                    ASSERT_NE(device1, nullptr);
836                });
837            ASSERT_TRUE(ret.isOk());
838        }
839    }
840}
841
842// Verify that the device resource cost can be retrieved and the values are
843// sane.
844TEST_F(CameraHidlTest, getResourceCost) {
845    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
846    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
847
848    for (const auto& name : cameraDeviceNames) {
849        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
850            ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_2;
851            ALOGI("getResourceCost: Testing camera device %s", name.c_str());
852            Return<void> ret;
853            ret = env->mProvider->getCameraDeviceInterface_V3_x(
854                name,
855                [&](auto status, const auto& device) {
856                    ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
857                    ASSERT_EQ(Status::OK, status);
858                    ASSERT_NE(device, nullptr);
859                    device3_2 = device;
860                });
861            ASSERT_TRUE(ret.isOk());
862
863            ret = device3_2->getResourceCost(
864                [&](auto status, const auto& resourceCost) {
865                    ALOGI("getResourceCost returns status:%d", (int)status);
866                    ASSERT_EQ(Status::OK, status);
867                    ALOGI("    Resource cost is %d", resourceCost.resourceCost);
868                    ASSERT_LE(resourceCost.resourceCost, 100u);
869                    for (const auto& name : resourceCost.conflictingDevices) {
870                        ALOGI("    Conflicting device: %s", name.c_str());
871                    }
872                });
873            ASSERT_TRUE(ret.isOk());
874        } else {
875            ::android::sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
876            ALOGI("getResourceCost: Testing camera device %s", name.c_str());
877            Return<void> ret;
878            ret = env->mProvider->getCameraDeviceInterface_V1_x(
879                name,
880                [&](auto status, const auto& device) {
881                    ALOGI("getCameraDeviceInterface_V1_x returns status:%d", (int)status);
882                    ASSERT_EQ(Status::OK, status);
883                    ASSERT_NE(device, nullptr);
884                    device1 = device;
885                });
886            ASSERT_TRUE(ret.isOk());
887
888            ret = device1->getResourceCost(
889                [&](auto status, const auto& resourceCost) {
890                    ALOGI("getResourceCost returns status:%d", (int)status);
891                    ASSERT_EQ(Status::OK, status);
892                    ALOGI("    Resource cost is %d", resourceCost.resourceCost);
893                    ASSERT_LE(resourceCost.resourceCost, 100u);
894                    for (const auto& name : resourceCost.conflictingDevices) {
895                        ALOGI("    Conflicting device: %s", name.c_str());
896                    }
897                });
898            ASSERT_TRUE(ret.isOk());
899        }
900    }
901}
902
903// Verify that the static camera info can be retrieved
904// successfully.
905TEST_F(CameraHidlTest, getCameraInfo) {
906    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
907    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
908
909    for (const auto& name : cameraDeviceNames) {
910        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
911            ::android::sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
912            ALOGI("getCameraCharacteristics: Testing camera device %s", name.c_str());
913            Return<void> ret;
914            ret = env->mProvider->getCameraDeviceInterface_V1_x(
915                name,
916                [&](auto status, const auto& device) {
917                    ALOGI("getCameraDeviceInterface_V1_x returns status:%d", (int)status);
918                    ASSERT_EQ(Status::OK, status);
919                    ASSERT_NE(device, nullptr);
920                    device1 = device;
921                });
922            ASSERT_TRUE(ret.isOk());
923
924            ret = device1->getCameraInfo(
925                [&](auto status, const auto& info) {
926                    ALOGI("getCameraInfo returns status:%d", (int)status);
927                    ASSERT_EQ(Status::OK, status);
928                    switch(info.orientation) {
929                        case 0:
930                        case 90:
931                        case 180:
932                        case 270:
933                            //Expected cases
934                            ALOGI("camera orientation: %d", info.orientation);
935                            break;
936                        default:
937                            FAIL() << "Unexpected camera orientation:" << info.orientation;
938                    }
939                    switch(info.facing) {
940                        case CameraFacing::BACK:
941                        case CameraFacing::FRONT:
942                        case CameraFacing::EXTERNAL:
943                            //Expected cases
944                            ALOGI("camera facing: %d", info.facing);
945                            break;
946                        default:
947                            FAIL() << "Unexpected camera facing:" << static_cast<uint32_t> (info.facing);
948                    }
949                });
950            ASSERT_TRUE(ret.isOk());
951        }
952    }
953}
954
955// Check whether preview window can be configured
956TEST_F(CameraHidlTest, setPreviewWindow) {
957    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
958    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
959
960    for (const auto& name : cameraDeviceNames) {
961        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
962            sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
963                    openCameraDevice(name, env, &device1 /*out*/);
964            ASSERT_NE(nullptr, device1.get());
965            sp<BufferItemConsumer> bufferItemConsumer;
966            sp<BufferItemHander> bufferHandler;
967            setupPreviewWindow(device1,
968                    &bufferItemConsumer /*out*/, &bufferHandler /*out*/);
969
970            Return<void> ret;
971            ret = device1->close();
972            ASSERT_TRUE(ret.isOk());
973        }
974    }
975}
976
977// Verify that setting preview window fails in case device is not open
978TEST_F(CameraHidlTest, setPreviewWindowInvalid) {
979    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
980    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
981
982    for (const auto& name : cameraDeviceNames) {
983        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
984            ::android::sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
985            ALOGI("getCameraCharacteristics: Testing camera device %s", name.c_str());
986            Return<void> ret;
987            ret = env->mProvider->getCameraDeviceInterface_V1_x(
988                name,
989                [&](auto status, const auto& device) {
990                    ALOGI("getCameraDeviceInterface_V1_x returns status:%d", (int)status);
991                    ASSERT_EQ(Status::OK, status);
992                    ASSERT_NE(device, nullptr);
993                    device1 = device;
994                });
995            ASSERT_TRUE(ret.isOk());
996
997            Return<Status> returnStatus = device1->setPreviewWindow(nullptr);
998            ASSERT_TRUE(returnStatus.isOk());
999            ASSERT_EQ(Status::OPERATION_NOT_SUPPORTED, returnStatus);
1000        }
1001    }
1002}
1003
1004// Start and stop preview checking whether it gets enabled in between.
1005TEST_F(CameraHidlTest, startStopPreview) {
1006    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
1007    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
1008
1009    for (const auto& name : cameraDeviceNames) {
1010        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
1011            sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
1012                    openCameraDevice(name, env, &device1 /*out*/);
1013            ASSERT_NE(nullptr, device1.get());
1014            sp<BufferItemConsumer> bufferItemConsumer;
1015            sp<BufferItemHander> bufferHandler;
1016            setupPreviewWindow(device1,
1017                    &bufferItemConsumer /*out*/, &bufferHandler /*out*/);
1018
1019            startPreview(device1);
1020
1021            Return<bool> returnBoolStatus = device1->previewEnabled();
1022            ASSERT_TRUE(returnBoolStatus.isOk());
1023            ASSERT_TRUE(returnBoolStatus);
1024
1025            stopPreviewAndClose(device1);
1026        }
1027    }
1028}
1029
1030// Start preview without active preview window. Preview should start as soon
1031// as a valid active window gets configured.
1032TEST_F(CameraHidlTest, startStopPreviewDelayed) {
1033    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
1034    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
1035
1036    for (const auto& name : cameraDeviceNames) {
1037        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
1038            sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
1039            openCameraDevice(name, env, &device1 /*out*/);
1040            ASSERT_NE(nullptr, device1.get());
1041
1042            Return<Status> returnStatus = device1->setPreviewWindow(nullptr);
1043            ASSERT_TRUE(returnStatus.isOk());
1044            ASSERT_EQ(Status::OK, returnStatus);
1045
1046            startPreview(device1);
1047
1048            sp<BufferItemConsumer> bufferItemConsumer;
1049            sp<BufferItemHander> bufferHandler;
1050            setupPreviewWindow(device1, &bufferItemConsumer /*out*/,
1051                    &bufferHandler /*out*/);
1052
1053            //Preview should get enabled now
1054            Return<bool> returnBoolStatus = device1->previewEnabled();
1055            ASSERT_TRUE(returnBoolStatus.isOk());
1056            ASSERT_TRUE(returnBoolStatus);
1057
1058            stopPreviewAndClose(device1);
1059        }
1060    }
1061}
1062
1063// Verify that image capture behaves as expected along with preview callbacks.
1064TEST_F(CameraHidlTest, takePicture) {
1065    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
1066    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
1067
1068    for (const auto& name : cameraDeviceNames) {
1069        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
1070            sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
1071            openCameraDevice(name, env, &device1 /*out*/);
1072            ASSERT_NE(nullptr, device1.get());
1073            sp<BufferItemConsumer> bufferItemConsumer;
1074            sp<BufferItemHander> bufferHandler;
1075            setupPreviewWindow(device1, &bufferItemConsumer /*out*/,
1076                    &bufferHandler /*out*/);
1077
1078            {
1079                std::unique_lock<std::mutex> l(mLock);
1080                mDataMessageTypeReceived = DataCallbackMsg::RAW_IMAGE_NOTIFY;
1081            }
1082
1083            enableMsgType((unsigned int)DataCallbackMsg::PREVIEW_FRAME, device1);
1084            startPreview(device1);
1085
1086            {
1087                std::unique_lock<std::mutex> l(mLock);
1088                waitForFrameLocked(DataCallbackMsg::PREVIEW_FRAME, l);
1089            }
1090
1091            disableMsgType((unsigned int)DataCallbackMsg::PREVIEW_FRAME,
1092                            device1);
1093            enableMsgType((unsigned int)DataCallbackMsg::COMPRESSED_IMAGE,
1094                    device1);
1095
1096            {
1097                std::unique_lock<std::mutex> l(mLock);
1098                mDataMessageTypeReceived = DataCallbackMsg::RAW_IMAGE_NOTIFY;
1099            }
1100
1101            Return<Status> returnStatus = device1->takePicture();
1102            ASSERT_TRUE(returnStatus.isOk());
1103            ASSERT_EQ(Status::OK, returnStatus);
1104
1105            {
1106                std::unique_lock<std::mutex> l(mLock);
1107                waitForFrameLocked(DataCallbackMsg::COMPRESSED_IMAGE, l);
1108            }
1109
1110            disableMsgType((unsigned int)DataCallbackMsg::COMPRESSED_IMAGE,
1111                    device1);
1112            stopPreviewAndClose(device1);
1113        }
1114    }
1115}
1116
1117// Image capture should fail in case preview didn't get enabled first.
1118TEST_F(CameraHidlTest, takePictureFail) {
1119    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
1120    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
1121
1122    for (const auto& name : cameraDeviceNames) {
1123        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
1124            sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
1125            openCameraDevice(name, env, &device1 /*out*/);
1126            ASSERT_NE(nullptr, device1.get());
1127
1128            Return<Status> returnStatus = device1->takePicture();
1129            ASSERT_TRUE(returnStatus.isOk());
1130            ASSERT_NE(Status::OK, returnStatus);
1131
1132            Return<void> ret = device1->close();
1133            ASSERT_TRUE(ret.isOk());
1134        }
1135    }
1136}
1137
1138// Verify that image capture can be cancelled.
1139TEST_F(CameraHidlTest, cancelPicture) {
1140    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
1141    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
1142
1143    for (const auto& name : cameraDeviceNames) {
1144        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
1145            sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
1146            openCameraDevice(name, env, &device1 /*out*/);
1147            ASSERT_NE(nullptr, device1.get());
1148            sp<BufferItemConsumer> bufferItemConsumer;
1149            sp<BufferItemHander> bufferHandler;
1150            setupPreviewWindow(device1, &bufferItemConsumer /*out*/,
1151                    &bufferHandler /*out*/);
1152            startPreview(device1);
1153
1154            Return<Status> returnStatus = device1->takePicture();
1155            ASSERT_TRUE(returnStatus.isOk());
1156            ASSERT_EQ(Status::OK, returnStatus);
1157
1158            returnStatus = device1->cancelPicture();
1159            ASSERT_TRUE(returnStatus.isOk());
1160            ASSERT_EQ(Status::OK, returnStatus);
1161
1162            stopPreviewAndClose(device1);
1163        }
1164    }
1165}
1166
1167// Image capture cancel should fail when image capture is not running.
1168TEST_F(CameraHidlTest, cancelPictureFail) {
1169    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
1170    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
1171
1172    for (const auto& name : cameraDeviceNames) {
1173        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
1174            sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
1175            openCameraDevice(name, env, &device1 /*out*/);
1176            ASSERT_NE(nullptr, device1.get());
1177            sp<BufferItemConsumer> bufferItemConsumer;
1178            sp<BufferItemHander> bufferHandler;
1179            setupPreviewWindow(device1, &bufferItemConsumer /*out*/,
1180                    &bufferHandler /*out*/);
1181            startPreview(device1);
1182
1183            Return<Status> returnStatus = device1->cancelPicture();
1184            ASSERT_TRUE(returnStatus.isOk());
1185            ASSERT_NE(Status::OK, returnStatus);
1186
1187            stopPreviewAndClose(device1);
1188        }
1189    }
1190}
1191
1192// Test basic video recording.
1193TEST_F(CameraHidlTest, startStopRecording) {
1194    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
1195    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
1196
1197    for (const auto& name : cameraDeviceNames) {
1198        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
1199            sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
1200            openCameraDevice(name, env, &device1 /*out*/);
1201            ASSERT_NE(nullptr, device1.get());
1202            sp<BufferItemConsumer> bufferItemConsumer;
1203            sp<BufferItemHander> bufferHandler;
1204            setupPreviewWindow(device1, &bufferItemConsumer /*out*/,
1205                    &bufferHandler /*out*/);
1206
1207            {
1208                std::unique_lock<std::mutex> l(mLock);
1209                mDataMessageTypeReceived = DataCallbackMsg::RAW_IMAGE_NOTIFY;
1210            }
1211
1212            enableMsgType((unsigned int)DataCallbackMsg::PREVIEW_FRAME, device1);
1213            startPreview(device1);
1214
1215            {
1216                std::unique_lock<std::mutex> l(mLock);
1217                waitForFrameLocked(DataCallbackMsg::PREVIEW_FRAME, l);
1218                mDataMessageTypeReceived = DataCallbackMsg::RAW_IMAGE_NOTIFY;
1219                mVideoBufferIndex = UINT32_MAX;
1220            }
1221
1222            disableMsgType((unsigned int)DataCallbackMsg::PREVIEW_FRAME, device1);
1223
1224            bool videoMetaEnabled = false;
1225            Return<Status> returnStatus = device1->storeMetaDataInBuffers(true);
1226            ASSERT_TRUE(returnStatus.isOk());
1227            // It is allowed for devices to not support this feature
1228            ASSERT_TRUE((Status::OK == returnStatus) ||
1229                    (Status::OPERATION_NOT_SUPPORTED == returnStatus));
1230            if (Status::OK == returnStatus) {
1231                videoMetaEnabled = true;
1232            }
1233
1234            enableMsgType((unsigned int)DataCallbackMsg::VIDEO_FRAME, device1);
1235            Return<bool> returnBoolStatus = device1->recordingEnabled();
1236            ASSERT_TRUE(returnBoolStatus.isOk());
1237            ASSERT_FALSE(returnBoolStatus);
1238
1239            returnStatus = device1->startRecording();
1240            ASSERT_TRUE(returnStatus.isOk());
1241            ASSERT_EQ(Status::OK, returnStatus);
1242
1243            {
1244                std::unique_lock<std::mutex> l(mLock);
1245                waitForFrameLocked(DataCallbackMsg::VIDEO_FRAME, l);
1246                ASSERT_NE(UINT32_MAX, mVideoBufferIndex);
1247                disableMsgType((unsigned int)DataCallbackMsg::VIDEO_FRAME,
1248                        device1);
1249            }
1250
1251            returnBoolStatus = device1->recordingEnabled();
1252            ASSERT_TRUE(returnBoolStatus.isOk());
1253            ASSERT_TRUE(returnBoolStatus);
1254
1255            Return<void> ret;
1256            if (videoMetaEnabled) {
1257                ret = device1->releaseRecordingFrameHandle(mVideoData,
1258                        mVideoBufferIndex, mVideoNativeHandle);
1259                ASSERT_TRUE(ret.isOk());
1260            } else {
1261                ret = device1->releaseRecordingFrame(mVideoData, mVideoBufferIndex);
1262                ASSERT_TRUE(ret.isOk());
1263            }
1264
1265            ret = device1->stopRecording();
1266            ASSERT_TRUE(ret.isOk());
1267
1268            stopPreviewAndClose(device1);
1269        }
1270    }
1271}
1272
1273// It shouldn't be possible to start recording without enabling preview first.
1274TEST_F(CameraHidlTest, startRecordingFail) {
1275    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
1276    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
1277
1278    for (const auto& name : cameraDeviceNames) {
1279        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
1280            sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
1281            openCameraDevice(name, env, &device1 /*out*/);
1282            ASSERT_NE(nullptr, device1.get());
1283
1284            Return<bool> returnBoolStatus = device1->recordingEnabled();
1285            ASSERT_TRUE(returnBoolStatus.isOk());
1286            ASSERT_FALSE(returnBoolStatus);
1287
1288            Return<Status> returnStatus = device1->startRecording();
1289            ASSERT_TRUE(returnStatus.isOk());
1290            ASSERT_NE(Status::OK, returnStatus);
1291
1292            Return<void> ret = device1->close();
1293            ASSERT_TRUE(ret.isOk());
1294        }
1295    }
1296}
1297
1298// Check autofocus support if available.
1299TEST_F(CameraHidlTest, autoFocus) {
1300    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
1301    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
1302    std::vector<const char *> focusModes = {CameraParameters::FOCUS_MODE_AUTO,
1303            CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE,
1304            CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO};
1305
1306    for (const auto& name : cameraDeviceNames) {
1307        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
1308            sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
1309            openCameraDevice(name, env, &device1 /*out*/);
1310            ASSERT_NE(nullptr, device1.get());
1311
1312            ::android::CameraParameters cameraParams;
1313            getParameters(device1, &cameraParams /*out*/);
1314
1315            if (Status::OK != isAutoFocusModeAvailable(cameraParams,
1316                    CameraParameters::FOCUS_MODE_AUTO)) {
1317                Return<void> ret = device1->close();
1318                ASSERT_TRUE(ret.isOk());
1319                continue;
1320            }
1321
1322            sp<BufferItemConsumer> bufferItemConsumer;
1323            sp<BufferItemHander> bufferHandler;
1324            setupPreviewWindow(device1, &bufferItemConsumer /*out*/,
1325                    &bufferHandler /*out*/);
1326            startPreview(device1);
1327            enableMsgType((unsigned int)NotifyCallbackMsg::FOCUS, device1);
1328
1329            for (auto &iter : focusModes) {
1330                if (Status::OK != isAutoFocusModeAvailable(cameraParams,
1331                        iter)) {
1332                    continue;
1333                }
1334
1335                cameraParams.set(CameraParameters::KEY_FOCUS_MODE, iter);
1336                setParameters(device1, cameraParams);
1337                {
1338                    std::unique_lock<std::mutex> l(mLock);
1339                    mNotifyMessage = NotifyCallbackMsg::ERROR;
1340                }
1341
1342                Return<Status> returnStatus = device1->autoFocus();
1343                ASSERT_TRUE(returnStatus.isOk());
1344                ASSERT_EQ(Status::OK, returnStatus);
1345
1346                {
1347                    std::unique_lock<std::mutex> l(mLock);
1348                    while (NotifyCallbackMsg::FOCUS != mNotifyMessage) {
1349                        auto timeout = std::chrono::system_clock::now() +
1350                                std::chrono::seconds(kAutoFocusTimeoutSec);
1351                        ASSERT_NE(std::cv_status::timeout,
1352                                mResultCondition.wait_until(l, timeout));
1353                    }
1354                }
1355            }
1356
1357            disableMsgType((unsigned int)NotifyCallbackMsg::FOCUS, device1);
1358            stopPreviewAndClose(device1);
1359        }
1360    }
1361}
1362
1363// In case autofocus is supported verify that it can be cancelled.
1364TEST_F(CameraHidlTest, cancelAutoFocus) {
1365    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
1366    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
1367
1368    for (const auto& name : cameraDeviceNames) {
1369        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
1370            sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
1371            openCameraDevice(name, env, &device1 /*out*/);
1372            ASSERT_NE(nullptr, device1.get());
1373
1374            ::android::CameraParameters cameraParams;
1375            getParameters(device1, &cameraParams /*out*/);
1376
1377            if (Status::OK != isAutoFocusModeAvailable(cameraParams,
1378                    CameraParameters::FOCUS_MODE_AUTO)) {
1379                Return<void> ret = device1->close();
1380                ASSERT_TRUE(ret.isOk());
1381                continue;
1382            }
1383
1384            // It should be fine to call before preview starts.
1385            ASSERT_EQ(Status::OK, device1->cancelAutoFocus());
1386
1387            sp<BufferItemConsumer> bufferItemConsumer;
1388            sp<BufferItemHander> bufferHandler;
1389            setupPreviewWindow(device1, &bufferItemConsumer /*out*/,
1390                    &bufferHandler /*out*/);
1391            startPreview(device1);
1392
1393            // It should be fine to call after preview starts too.
1394            Return<Status> returnStatus = device1->cancelAutoFocus();
1395            ASSERT_TRUE(returnStatus.isOk());
1396            ASSERT_EQ(Status::OK, returnStatus);
1397
1398            returnStatus = device1->autoFocus();
1399            ASSERT_TRUE(returnStatus.isOk());
1400            ASSERT_EQ(Status::OK, returnStatus);
1401
1402            returnStatus = device1->cancelAutoFocus();
1403            ASSERT_TRUE(returnStatus.isOk());
1404            ASSERT_EQ(Status::OK, returnStatus);
1405
1406            stopPreviewAndClose(device1);
1407        }
1408    }
1409}
1410
1411// Check whether face detection is available and try to enable&disable.
1412TEST_F(CameraHidlTest, sendCommandFaceDetection) {
1413    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
1414    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
1415
1416    for (const auto& name : cameraDeviceNames) {
1417        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
1418            sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
1419            openCameraDevice(name, env, &device1 /*out*/);
1420            ASSERT_NE(nullptr, device1.get());
1421
1422            ::android::CameraParameters cameraParams;
1423            getParameters(device1, &cameraParams /*out*/);
1424
1425            int32_t hwFaces = cameraParams.getInt(
1426                    CameraParameters::KEY_MAX_NUM_DETECTED_FACES_HW);
1427            int32_t swFaces = cameraParams.getInt(
1428                    CameraParameters::KEY_MAX_NUM_DETECTED_FACES_SW);
1429            if ((0 >= hwFaces) && (0 >= swFaces)) {
1430                Return<void> ret = device1->close();
1431                ASSERT_TRUE(ret.isOk());
1432                continue;
1433            }
1434
1435            sp<BufferItemConsumer> bufferItemConsumer;
1436            sp<BufferItemHander> bufferHandler;
1437            setupPreviewWindow(device1, &bufferItemConsumer /*out*/,
1438                    &bufferHandler /*out*/);
1439            startPreview(device1);
1440
1441            if (0 < hwFaces) {
1442                Return<Status> returnStatus = device1->sendCommand(
1443                        CommandType::START_FACE_DETECTION,
1444                        CAMERA_FACE_DETECTION_HW, 0);
1445                ASSERT_TRUE(returnStatus.isOk());
1446                ASSERT_EQ(Status::OK, returnStatus);
1447                // TODO(epeev) : Enable and check for face notifications
1448                returnStatus = device1->sendCommand(
1449                        CommandType::STOP_FACE_DETECTION,
1450                        CAMERA_FACE_DETECTION_HW, 0);
1451                ASSERT_TRUE(returnStatus.isOk());
1452                ASSERT_EQ(Status::OK, returnStatus);
1453            }
1454
1455            if (0 < swFaces) {
1456                Return<Status> returnStatus = device1->sendCommand(
1457                        CommandType::START_FACE_DETECTION,
1458                        CAMERA_FACE_DETECTION_SW, 0);
1459                ASSERT_TRUE(returnStatus.isOk());
1460                ASSERT_EQ(Status::OK, returnStatus);
1461                // TODO(epeev) : Enable and check for face notifications
1462                returnStatus = device1->sendCommand(
1463                        CommandType::STOP_FACE_DETECTION,
1464                        CAMERA_FACE_DETECTION_SW, 0);
1465                ASSERT_TRUE(returnStatus.isOk());
1466                ASSERT_EQ(Status::OK, returnStatus);
1467            }
1468
1469            stopPreviewAndClose(device1);
1470        }
1471    }
1472}
1473
1474// Check whether smooth zoom is available and try to enable&disable.
1475TEST_F(CameraHidlTest, sendCommandSmoothZoom) {
1476    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
1477    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
1478
1479    for (const auto& name : cameraDeviceNames) {
1480        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
1481            sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
1482            openCameraDevice(name, env, &device1 /*out*/);
1483            ASSERT_NE(nullptr, device1.get());
1484
1485            ::android::CameraParameters cameraParams;
1486            getParameters(device1, &cameraParams /*out*/);
1487
1488            const char *smoothZoomStr = cameraParams.get(
1489                    CameraParameters::KEY_SMOOTH_ZOOM_SUPPORTED);
1490            bool smoothZoomSupported = ((nullptr != smoothZoomStr) &&
1491                    (strcmp(smoothZoomStr, CameraParameters::TRUE) == 0)) ?
1492                            true : false;
1493            if (!smoothZoomSupported) {
1494                Return<void> ret = device1->close();
1495                ASSERT_TRUE(ret.isOk());
1496                continue;
1497            }
1498
1499            int32_t maxZoom = cameraParams.getInt(
1500                    CameraParameters::KEY_MAX_ZOOM);
1501            ASSERT_TRUE(0 < maxZoom);
1502
1503            sp<BufferItemConsumer> bufferItemConsumer;
1504            sp<BufferItemHander> bufferHandler;
1505            setupPreviewWindow(device1, &bufferItemConsumer /*out*/,
1506                    &bufferHandler /*out*/);
1507            startPreview(device1);
1508            setParameters(device1, cameraParams);
1509
1510            Return<Status> returnStatus = device1->sendCommand(
1511                    CommandType::START_SMOOTH_ZOOM, maxZoom, 0);
1512            ASSERT_TRUE(returnStatus.isOk());
1513            ASSERT_EQ(Status::OK, returnStatus);
1514            // TODO(epeev) : Enable and check for face notifications
1515            returnStatus = device1->sendCommand(CommandType::STOP_SMOOTH_ZOOM,
1516                    0, 0);
1517            ASSERT_TRUE(returnStatus.isOk());
1518            ASSERT_EQ(Status::OK, returnStatus);
1519
1520            stopPreviewAndClose(device1);
1521        }
1522    }
1523}
1524
1525// Basic sanity tests related to camera parameters.
1526TEST_F(CameraHidlTest, getSetParameters) {
1527    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
1528    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
1529
1530    for (const auto& name : cameraDeviceNames) {
1531        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
1532            sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
1533            openCameraDevice(name, env, &device1 /*out*/);
1534            ASSERT_NE(nullptr, device1.get());
1535
1536            ::android::CameraParameters cameraParams;
1537            getParameters(device1, &cameraParams /*out*/);
1538
1539            int32_t width, height;
1540            cameraParams.getPictureSize(&width, &height);
1541            ASSERT_TRUE((0 < width) && (0 < height));
1542            cameraParams.getPreviewSize(&width, &height);
1543            ASSERT_TRUE((0 < width) && (0 < height));
1544            int32_t minFps, maxFps;
1545            cameraParams.getPreviewFpsRange(&minFps, &maxFps);
1546            ASSERT_TRUE((0 < minFps) && (0 < maxFps));
1547            ASSERT_NE(nullptr, cameraParams.getPreviewFormat());
1548            ASSERT_NE(nullptr, cameraParams.getPictureFormat());
1549            ASSERT_TRUE(strcmp(CameraParameters::PIXEL_FORMAT_JPEG,
1550                    cameraParams.getPictureFormat()) == 0);
1551
1552            const char *flashMode = cameraParams.get(
1553                    CameraParameters::KEY_FLASH_MODE);
1554            ASSERT_TRUE((nullptr == flashMode) || (strcmp(
1555                    CameraParameters::FLASH_MODE_OFF, flashMode) == 0));
1556
1557            const char *wbMode = cameraParams.get(
1558                    CameraParameters::KEY_WHITE_BALANCE);
1559            ASSERT_TRUE((nullptr == wbMode) || (strcmp(
1560                    CameraParameters::WHITE_BALANCE_AUTO, wbMode) == 0));
1561
1562            const char *effect = cameraParams.get(CameraParameters::KEY_EFFECT);
1563            ASSERT_TRUE((nullptr == effect) || (strcmp(
1564                    CameraParameters::EFFECT_NONE, effect) == 0));
1565
1566            ::android::Vector<::android::Size> previewSizes;
1567            cameraParams.getSupportedPreviewSizes(previewSizes);
1568            ASSERT_FALSE(previewSizes.empty());
1569            ::android::Vector<::android::Size> pictureSizes;
1570            cameraParams.getSupportedPictureSizes(pictureSizes);
1571            ASSERT_FALSE(pictureSizes.empty());
1572            const char *previewFormats = cameraParams.get(
1573                    CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS);
1574            ASSERT_NE(nullptr, previewFormats);
1575            ::android::String8 previewFormatsString(previewFormats);
1576            ASSERT_TRUE(previewFormatsString.contains(
1577                    CameraParameters::PIXEL_FORMAT_YUV420SP));
1578            ASSERT_NE(nullptr, cameraParams.get(
1579                    CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS));
1580            ASSERT_NE(nullptr, cameraParams.get(
1581                    CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES));
1582            const char *focusModes = cameraParams.get(
1583                    CameraParameters::KEY_SUPPORTED_FOCUS_MODES);
1584            ASSERT_NE(nullptr, focusModes);
1585            ::android::String8 focusModesString(focusModes);
1586            const char *focusMode = cameraParams.get(
1587                    CameraParameters::KEY_FOCUS_MODE);
1588            ASSERT_NE(nullptr, focusMode);
1589            // Auto focus mode should be default
1590            if (focusModesString.contains(CameraParameters::FOCUS_MODE_AUTO)) {
1591                ASSERT_TRUE(strcmp(
1592                        CameraParameters::FOCUS_MODE_AUTO, focusMode) == 0);
1593            }
1594            ASSERT_TRUE(0 < cameraParams.getInt(
1595                    CameraParameters::KEY_FOCAL_LENGTH));
1596            int32_t horizontalViewAngle = cameraParams.getInt(
1597                    CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE);
1598            ASSERT_TRUE((0 < horizontalViewAngle) && (360 >= horizontalViewAngle));
1599            int32_t verticalViewAngle = cameraParams.getInt(
1600                    CameraParameters::KEY_VERTICAL_VIEW_ANGLE);
1601            ASSERT_TRUE((0 < verticalViewAngle) && (360 >= verticalViewAngle));
1602            int32_t jpegQuality = cameraParams.getInt(
1603                    CameraParameters::KEY_JPEG_QUALITY);
1604            ASSERT_TRUE((1 <= jpegQuality) && (100 >= jpegQuality));
1605            int32_t jpegThumbQuality = cameraParams.getInt(
1606                    CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY);
1607            ASSERT_TRUE((1 <= jpegThumbQuality) && (100 >= jpegThumbQuality));
1608
1609            cameraParams.setPictureSize(pictureSizes[0].width,
1610                    pictureSizes[0].height);
1611            cameraParams.setPreviewSize(previewSizes[0].width,
1612                    previewSizes[0].height);
1613
1614            setParameters(device1, cameraParams);
1615            getParameters(device1, &cameraParams /*out*/);
1616
1617            cameraParams.getPictureSize(&width, &height);
1618            ASSERT_TRUE((pictureSizes[0].width == width) &&
1619                    (pictureSizes[0].height == height));
1620            cameraParams.getPreviewSize(&width, &height);
1621            ASSERT_TRUE((previewSizes[0].width == width) &&
1622                    (previewSizes[0].height == height));
1623
1624            Return<void> ret = device1->close();
1625            ASSERT_TRUE(ret.isOk());
1626        }
1627    }
1628}
1629
1630// Verify that the static camera characteristics can be retrieved
1631// successfully.
1632TEST_F(CameraHidlTest, getCameraCharacteristics) {
1633    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
1634    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
1635
1636    for (const auto& name : cameraDeviceNames) {
1637        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
1638            ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_2;
1639            ALOGI("getCameraCharacteristics: Testing camera device %s", name.c_str());
1640            Return<void> ret;
1641            ret = env->mProvider->getCameraDeviceInterface_V3_x(
1642                name,
1643                [&](auto status, const auto& device) {
1644                    ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
1645                    ASSERT_EQ(Status::OK, status);
1646                    ASSERT_NE(device, nullptr);
1647                    device3_2 = device;
1648                });
1649            ASSERT_TRUE(ret.isOk());
1650
1651            ret = device3_2->getCameraCharacteristics(
1652                [&](auto status, const auto& chars) {
1653                    ALOGI("getCameraCharacteristics returns status:%d", (int)status);
1654                    ASSERT_EQ(Status::OK, status);
1655                    const camera_metadata_t* metadata = (camera_metadata_t*) chars.data();
1656                    size_t expectedSize = chars.size();
1657                    ASSERT_EQ(0, validate_camera_metadata_structure(metadata, &expectedSize));
1658                    size_t entryCount = get_camera_metadata_entry_count(metadata);
1659                    // TODO: we can do better than 0 here. Need to check how many required
1660                    // characteristics keys we've defined.
1661                    ASSERT_GT(entryCount, 0u);
1662                    ALOGI("getCameraCharacteristics metadata entry count is %zu", entryCount);
1663                });
1664            ASSERT_TRUE(ret.isOk());
1665        }
1666    }
1667}
1668
1669//In case it is supported verify that torch can be enabled.
1670//Check for corresponding toch callbacks as well.
1671TEST_F(CameraHidlTest, setTorchMode) {
1672    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
1673    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
1674    bool torchControlSupported = false;
1675    Return<void> ret;
1676
1677    ret = CameraHidlEnvironment::Instance()->mProvider->isSetTorchModeSupported(
1678        [&](auto status, bool support) {
1679            ALOGI("isSetTorchModeSupported returns status:%d supported:%d",
1680                    (int)status, support);
1681            ASSERT_EQ(Status::OK, status);
1682            torchControlSupported = support;
1683        });
1684
1685
1686    sp<TorchProviderCb> cb = new TorchProviderCb(this);
1687    Return<Status> returnStatus = env->mProvider->setCallback(cb);
1688    ASSERT_TRUE(returnStatus.isOk());
1689    ASSERT_EQ(Status::OK, returnStatus);
1690
1691    for (const auto& name : cameraDeviceNames) {
1692        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
1693            ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_2;
1694            ALOGI("setTorchMode: Testing camera device %s", name.c_str());
1695            ret = env->mProvider->getCameraDeviceInterface_V3_x(
1696                name,
1697                [&](auto status, const auto& device) {
1698                    ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
1699                    ASSERT_EQ(Status::OK, status);
1700                    ASSERT_NE(device, nullptr);
1701                    device3_2 = device;
1702                });
1703            ASSERT_TRUE(ret.isOk());
1704
1705            mTorchStatus = TorchModeStatus::NOT_AVAILABLE;
1706            returnStatus = device3_2->setTorchMode(TorchMode::ON);
1707            ASSERT_TRUE(returnStatus.isOk());
1708            if (!torchControlSupported) {
1709                ASSERT_EQ(Status::METHOD_NOT_SUPPORTED, returnStatus);
1710            } else {
1711                ASSERT_TRUE(returnStatus == Status::OK ||
1712                            returnStatus == Status::OPERATION_NOT_SUPPORTED);
1713                if (returnStatus == Status::OK) {
1714                    {
1715                        std::unique_lock<std::mutex> l(mTorchLock);
1716                        while (TorchModeStatus::NOT_AVAILABLE == mTorchStatus) {
1717                            auto timeout = std::chrono::system_clock::now() +
1718                                    std::chrono::seconds(kTorchTimeoutSec);
1719                            ASSERT_NE(std::cv_status::timeout,
1720                                    mTorchCond.wait_until(l, timeout));
1721                        }
1722                        ASSERT_EQ(TorchModeStatus::AVAILABLE_ON, mTorchStatus);
1723                        mTorchStatus = TorchModeStatus::NOT_AVAILABLE;
1724                    }
1725
1726                    returnStatus = device3_2->setTorchMode(TorchMode::OFF);
1727                    ASSERT_TRUE(returnStatus.isOk());
1728                    ASSERT_EQ(Status::OK, returnStatus);
1729
1730                    {
1731                        std::unique_lock<std::mutex> l(mTorchLock);
1732                        while (TorchModeStatus::NOT_AVAILABLE == mTorchStatus) {
1733                            auto timeout = std::chrono::system_clock::now() +
1734                                    std::chrono::seconds(kTorchTimeoutSec);
1735                            ASSERT_NE(std::cv_status::timeout,
1736                                    mTorchCond.wait_until(l, timeout));
1737                        }
1738                        ASSERT_EQ(TorchModeStatus::AVAILABLE_OFF, mTorchStatus);
1739                    }
1740                }
1741            }
1742        } else if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
1743            ::android::sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
1744            ALOGI("dumpState: Testing camera device %s", name.c_str());
1745            ret = env->mProvider->getCameraDeviceInterface_V1_x(
1746                name,
1747                [&](auto status, const auto& device) {
1748                    ALOGI("getCameraDeviceInterface_V1_x returns status:%d", (int)status);
1749                    ASSERT_EQ(Status::OK, status);
1750                    ASSERT_NE(device, nullptr);
1751                    device1 = device;
1752                });
1753            ASSERT_TRUE(ret.isOk());
1754
1755            mTorchStatus = TorchModeStatus::NOT_AVAILABLE;
1756            returnStatus = device1->setTorchMode(TorchMode::ON);
1757            ASSERT_TRUE(returnStatus.isOk());
1758            if (!torchControlSupported) {
1759                ASSERT_EQ(Status::METHOD_NOT_SUPPORTED, returnStatus);
1760            } else {
1761                ASSERT_TRUE(returnStatus == Status::OK ||
1762                            returnStatus == Status::OPERATION_NOT_SUPPORTED);
1763                if (returnStatus == Status::OK) {
1764                    {
1765                        std::unique_lock<std::mutex> l(mTorchLock);
1766                        while (TorchModeStatus::NOT_AVAILABLE == mTorchStatus) {
1767                            auto timeout = std::chrono::system_clock::now() +
1768                                    std::chrono::seconds(kTorchTimeoutSec);
1769                            ASSERT_NE(std::cv_status::timeout,
1770                                    mTorchCond.wait_until(l, timeout));
1771                        }
1772                        ASSERT_EQ(TorchModeStatus::AVAILABLE_ON, mTorchStatus);
1773                        mTorchStatus = TorchModeStatus::NOT_AVAILABLE;
1774                    }
1775
1776                    returnStatus = device1->setTorchMode(TorchMode::OFF);
1777                    ASSERT_TRUE(returnStatus.isOk());
1778                    ASSERT_EQ(Status::OK, returnStatus);
1779
1780                    {
1781                        std::unique_lock<std::mutex> l(mTorchLock);
1782                        while (TorchModeStatus::NOT_AVAILABLE == mTorchStatus) {
1783                            auto timeout = std::chrono::system_clock::now() +
1784                                    std::chrono::seconds(kTorchTimeoutSec);
1785                            ASSERT_NE(std::cv_status::timeout,
1786                                    mTorchCond.wait_until(l, timeout));
1787                        }
1788                        ASSERT_EQ(TorchModeStatus::AVAILABLE_OFF, mTorchStatus);
1789                    }
1790                }
1791            }
1792            ret = device1->close();
1793            ASSERT_TRUE(ret.isOk());
1794        }
1795    }
1796
1797    returnStatus = env->mProvider->setCallback(nullptr);
1798    ASSERT_TRUE(returnStatus.isOk());
1799    ASSERT_EQ(Status::OK, returnStatus);
1800}
1801
1802// Check dump functionality.
1803TEST_F(CameraHidlTest, dumpState) {
1804    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
1805    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
1806    Return<void> ret;
1807
1808    for (const auto& name : cameraDeviceNames) {
1809        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
1810            ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_2;
1811            ALOGI("dumpState: Testing camera device %s", name.c_str());
1812            ret = env->mProvider->getCameraDeviceInterface_V3_x(
1813                name,
1814                [&](auto status, const auto& device) {
1815                    ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
1816                    ASSERT_EQ(Status::OK, status);
1817                    ASSERT_NE(device, nullptr);
1818                    device3_2 = device;
1819                });
1820            ASSERT_TRUE(ret.isOk());
1821
1822            native_handle_t* raw_handle = native_handle_create(1, 0);
1823            raw_handle->data[0] = open(kDumpOutput, O_RDWR);
1824            ASSERT_GE(raw_handle->data[0], 0);
1825            hidl_handle handle = raw_handle;
1826            ret= device3_2->dumpState(handle);
1827            ASSERT_TRUE(ret.isOk());
1828            close(raw_handle->data[0]);
1829            native_handle_delete(raw_handle);
1830        } else if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
1831            ::android::sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
1832            ALOGI("dumpState: Testing camera device %s", name.c_str());
1833            ret = env->mProvider->getCameraDeviceInterface_V1_x(
1834                name,
1835                [&](auto status, const auto& device) {
1836                    ALOGI("getCameraDeviceInterface_V1_x returns status:%d", (int)status);
1837                    ASSERT_EQ(Status::OK, status);
1838                    ASSERT_NE(device, nullptr);
1839                    device1 = device;
1840                });
1841            ASSERT_TRUE(ret.isOk());
1842
1843            native_handle_t* raw_handle = native_handle_create(1, 0);
1844            raw_handle->data[0] = open(kDumpOutput, O_RDWR);
1845            ASSERT_GE(raw_handle->data[0], 0);
1846            hidl_handle handle = raw_handle;
1847            Return<Status> returnStatus = device1->dumpState(handle);
1848            ASSERT_TRUE(returnStatus.isOk());
1849            ASSERT_EQ(Status::OK, returnStatus);
1850            close(raw_handle->data[0]);
1851            native_handle_delete(raw_handle);
1852        }
1853    }
1854}
1855
1856// Open, dumpStates, then close
1857TEST_F(CameraHidlTest, openClose) {
1858    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
1859    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
1860    Return<void> ret;
1861
1862    for (const auto& name : cameraDeviceNames) {
1863        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
1864            ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_2;
1865            ALOGI("openClose: Testing camera device %s", name.c_str());
1866            ret = env->mProvider->getCameraDeviceInterface_V3_x(
1867                name,
1868                [&](auto status, const auto& device) {
1869                    ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
1870                    ASSERT_EQ(Status::OK, status);
1871                    ASSERT_NE(device, nullptr);
1872                    device3_2 = device;
1873                });
1874            ASSERT_TRUE(ret.isOk());
1875
1876            sp<EmptyDeviceCb> cb = new EmptyDeviceCb;
1877            sp<ICameraDeviceSession> session;
1878            ret = device3_2->open(
1879                cb,
1880                [&](auto status, const auto& newSession) {
1881                    ALOGI("device::open returns status:%d", (int)status);
1882                    ASSERT_EQ(Status::OK, status);
1883                    ASSERT_NE(newSession, nullptr);
1884                    session = newSession;
1885                });
1886            ASSERT_TRUE(ret.isOk());
1887
1888            native_handle_t* raw_handle = native_handle_create(1, 0);
1889            raw_handle->data[0] = open(kDumpOutput, O_RDWR);
1890            ASSERT_GE(raw_handle->data[0], 0);
1891            hidl_handle handle = raw_handle;
1892            ret = device3_2->dumpState(handle);
1893            ASSERT_TRUE(ret.isOk());
1894            close(raw_handle->data[0]);
1895            native_handle_delete(raw_handle);
1896
1897            ret = session->close();
1898            ASSERT_TRUE(ret.isOk());
1899            // TODO: test all session API calls return INTERNAL_ERROR after close
1900            // TODO: keep a wp copy here and verify session cannot be promoted out of this scope
1901        } else if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
1902            sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
1903            openCameraDevice(name, env, &device1 /*out*/);
1904            ASSERT_NE(nullptr, device1.get());
1905
1906            native_handle_t* raw_handle = native_handle_create(1, 0);
1907            raw_handle->data[0] = open(kDumpOutput, O_RDWR);
1908            ASSERT_GE(raw_handle->data[0], 0);
1909            hidl_handle handle = raw_handle;
1910            Return<Status> returnStatus = device1->dumpState(handle);
1911            ASSERT_TRUE(returnStatus.isOk());
1912            ASSERT_EQ(Status::OK, returnStatus);
1913            close(raw_handle->data[0]);
1914            native_handle_delete(raw_handle);
1915
1916            ret = device1->close();
1917            ASSERT_TRUE(ret.isOk());
1918        }
1919    }
1920}
1921
1922// Check whether all common default request settings can be sucessfully
1923// constructed.
1924TEST_F(CameraHidlTest, constructDefaultRequestSettings) {
1925    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
1926    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
1927
1928    for (const auto& name : cameraDeviceNames) {
1929        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
1930            ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_2;
1931            Return<void> ret;
1932            ALOGI("constructDefaultRequestSettings: Testing camera device %s", name.c_str());
1933            ret = env->mProvider->getCameraDeviceInterface_V3_x(
1934                name,
1935                [&](auto status, const auto& device) {
1936                    ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
1937                    ASSERT_EQ(Status::OK, status);
1938                    ASSERT_NE(device, nullptr);
1939                    device3_2 = device;
1940                });
1941            ASSERT_TRUE(ret.isOk());
1942
1943            sp<EmptyDeviceCb> cb = new EmptyDeviceCb;
1944            sp<ICameraDeviceSession> session;
1945            ret = device3_2->open(
1946                cb,
1947                [&](auto status, const auto& newSession) {
1948                    ALOGI("device::open returns status:%d", (int)status);
1949                    ASSERT_EQ(Status::OK, status);
1950                    ASSERT_NE(newSession, nullptr);
1951                    session = newSession;
1952                });
1953            ASSERT_TRUE(ret.isOk());
1954
1955            for (uint32_t t = (uint32_t) RequestTemplate::PREVIEW;
1956                    t <= (uint32_t) RequestTemplate::MANUAL; t++) {
1957                RequestTemplate reqTemplate = (RequestTemplate) t;
1958                ret = session->constructDefaultRequestSettings(
1959                    reqTemplate,
1960                    [&](auto status, const auto& req) {
1961                        ALOGI("constructDefaultRequestSettings returns status:%d", (int)status);
1962                        if (reqTemplate == RequestTemplate::ZERO_SHUTTER_LAG ||
1963                                reqTemplate == RequestTemplate::MANUAL) {
1964                            // optional templates
1965                            ASSERT_TRUE(status == Status::OK || status == Status::ILLEGAL_ARGUMENT);
1966                        } else {
1967                            ASSERT_EQ(Status::OK, status);
1968                        }
1969
1970                        if (status == Status::OK) {
1971                            const camera_metadata_t* metadata =
1972                                (camera_metadata_t*) req.data();
1973                            size_t expectedSize = req.size();
1974                            ASSERT_EQ(0, validate_camera_metadata_structure(
1975                                    metadata, &expectedSize));
1976                            size_t entryCount = get_camera_metadata_entry_count(metadata);
1977                            // TODO: we can do better than 0 here. Need to check how many required
1978                            // request keys we've defined for each template
1979                            ASSERT_GT(entryCount, 0u);
1980                            ALOGI("template %u metadata entry count is %zu", t, entryCount);
1981                        } else {
1982                            ASSERT_EQ(0u, req.size());
1983                        }
1984                    });
1985                ASSERT_TRUE(ret.isOk());
1986            }
1987            ret = session->close();
1988            ASSERT_TRUE(ret.isOk());
1989        }
1990    }
1991}
1992
1993// Verify that all supported stream formats and sizes can be configured
1994// successfully.
1995TEST_F(CameraHidlTest, configureStreamsAvailableOutputs) {
1996    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
1997    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
1998    std::vector<AvailableStream> outputStreams;
1999
2000    for (const auto& name : cameraDeviceNames) {
2001        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
2002            camera_metadata_t *staticMeta;
2003            Return<void> ret;
2004            sp<ICameraDeviceSession> session;
2005            openEmptyDeviceSession(name, env, &session /*out*/,
2006                    &staticMeta /*out*/);
2007
2008            outputStreams.clear();
2009            ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta,
2010                    outputStreams));
2011            ASSERT_NE(0u, outputStreams.size());
2012
2013            int32_t streamId = 0;
2014            for (auto &it : outputStreams) {
2015                Stream stream = {streamId, StreamType::OUTPUT,
2016                        static_cast<uint32_t> (it.width),
2017                        static_cast<uint32_t> (it.height),
2018                        static_cast<PixelFormat> (it.format), 0, 0,
2019                        StreamRotation::ROTATION_0};
2020                ::android::hardware::hidl_vec<Stream> streams = {stream};
2021                StreamConfiguration config = {streams,
2022                        StreamConfigurationMode::NORMAL_MODE};
2023                ret = session->configureStreams(config, [streamId] (Status s,
2024                        HalStreamConfiguration halConfig) {
2025                    ASSERT_EQ(Status::OK, s);
2026                    ASSERT_EQ(1u, halConfig.streams.size());
2027                    ASSERT_EQ(halConfig.streams[0].id, streamId);
2028                });
2029                ASSERT_TRUE(ret.isOk());
2030                streamId++;
2031            }
2032
2033            free_camera_metadata(staticMeta);
2034            ret = session->close();
2035            ASSERT_TRUE(ret.isOk());
2036        }
2037    }
2038}
2039
2040// Check for correct handling of invalid/incorrect configuration parameters.
2041TEST_F(CameraHidlTest, configureStreamsInvalidOutputs) {
2042    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
2043    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
2044    std::vector<AvailableStream> outputStreams;
2045
2046    for (const auto& name : cameraDeviceNames) {
2047        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
2048            camera_metadata_t *staticMeta;
2049            Return<void> ret;
2050            sp<ICameraDeviceSession> session;
2051            openEmptyDeviceSession(name, env, &session /*out*/,
2052                    &staticMeta /*out*/);
2053
2054            outputStreams.clear();
2055            ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta,
2056                    outputStreams));
2057            ASSERT_NE(0u, outputStreams.size());
2058
2059            int32_t streamId = 0;
2060            Stream stream = {streamId++, StreamType::OUTPUT,
2061                    static_cast<uint32_t> (0),
2062                    static_cast<uint32_t> (0),
2063                    static_cast<PixelFormat> (outputStreams[0].format),
2064                    0, 0, StreamRotation::ROTATION_0};
2065            ::android::hardware::hidl_vec<Stream> streams = {stream};
2066            StreamConfiguration config = {streams,
2067                    StreamConfigurationMode::NORMAL_MODE};
2068            ret = session->configureStreams(config, [] (Status s,
2069                    HalStreamConfiguration) {
2070                ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) ||
2071                            (Status::INTERNAL_ERROR == s));
2072            });
2073            ASSERT_TRUE(ret.isOk());
2074
2075            stream = {streamId++, StreamType::OUTPUT,
2076                    static_cast<uint32_t> (UINT32_MAX),
2077                    static_cast<uint32_t> (UINT32_MAX),
2078                    static_cast<PixelFormat> (outputStreams[0].format),
2079                    0, 0, StreamRotation::ROTATION_0};
2080            streams[0] = stream;
2081            config = {streams,
2082                    StreamConfigurationMode::NORMAL_MODE};
2083            ret = session->configureStreams(config, [] (Status s,
2084                    HalStreamConfiguration) {
2085                ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
2086            });
2087            ASSERT_TRUE(ret.isOk());
2088
2089            for (auto &it : outputStreams) {
2090                stream = {streamId++, StreamType::OUTPUT,
2091                        static_cast<uint32_t> (it.width),
2092                        static_cast<uint32_t> (it.height),
2093                        static_cast<PixelFormat> (UINT32_MAX),
2094                        0, 0, StreamRotation::ROTATION_0};
2095                streams[0] = stream;
2096                config = {streams,
2097                        StreamConfigurationMode::NORMAL_MODE};
2098                ret = session->configureStreams(config, [] (Status s,
2099                        HalStreamConfiguration) {
2100                    ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
2101                });
2102                ASSERT_TRUE(ret.isOk());
2103
2104                stream = {streamId++, StreamType::OUTPUT,
2105                        static_cast<uint32_t> (it.width),
2106                        static_cast<uint32_t> (it.height),
2107                        static_cast<PixelFormat> (it.format),
2108                        0, 0, static_cast<StreamRotation> (UINT32_MAX)};
2109                streams[0] = stream;
2110                config = {streams,
2111                        StreamConfigurationMode::NORMAL_MODE};
2112                ret = session->configureStreams(config, [] (Status s,
2113                        HalStreamConfiguration) {
2114                    ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
2115                });
2116                ASSERT_TRUE(ret.isOk());
2117            }
2118
2119            free_camera_metadata(staticMeta);
2120            ret = session->close();
2121            ASSERT_TRUE(ret.isOk());
2122        }
2123    }
2124}
2125
2126// Check whether all supported ZSL output stream combinations can be
2127// configured successfully.
2128TEST_F(CameraHidlTest, configureStreamsZSLInputOutputs) {
2129    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
2130    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
2131    std::vector<AvailableStream> inputStreams;
2132    std::vector<AvailableZSLInputOutput> inputOutputMap;
2133
2134    for (const auto& name : cameraDeviceNames) {
2135        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
2136            camera_metadata_t *staticMeta;
2137            Return<void> ret;
2138            sp<ICameraDeviceSession> session;
2139            openEmptyDeviceSession(name, env, &session /*out*/,
2140                    &staticMeta /*out*/);
2141
2142            Status rc = isZSLModeAvailable(staticMeta);
2143            if (Status::METHOD_NOT_SUPPORTED == rc) {
2144                ret = session->close();
2145                ASSERT_TRUE(ret.isOk());
2146                continue;
2147            }
2148            ASSERT_EQ(Status::OK, rc);
2149
2150            inputStreams.clear();
2151            ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta,
2152                    inputStreams));
2153            ASSERT_NE(0u, inputStreams.size());
2154
2155            inputOutputMap.clear();
2156            ASSERT_EQ(Status::OK, getZSLInputOutputMap(staticMeta,
2157                    inputOutputMap));
2158            ASSERT_NE(0u, inputOutputMap.size());
2159
2160            int32_t streamId = 0;
2161            for (auto &inputIter : inputOutputMap) {
2162                AvailableStream input;
2163                ASSERT_EQ(Status::OK,
2164                        findLargestSize(inputStreams, inputIter.inputFormat, input));
2165                ASSERT_NE(0u, inputStreams.size());
2166
2167                AvailableStream outputThreshold = {INT32_MAX, INT32_MAX,
2168                        inputIter.outputFormat};
2169                std::vector<AvailableStream> outputStreams;
2170                ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta,
2171                        outputStreams, &outputThreshold));
2172                for (auto &outputIter : outputStreams) {
2173                    Stream zslStream = {streamId++, StreamType::OUTPUT,
2174                            static_cast<uint32_t> (input.width),
2175                            static_cast<uint32_t> (input.height),
2176                            static_cast<PixelFormat> (input.format),
2177                            GRALLOC_USAGE_HW_CAMERA_ZSL, 0,
2178                            StreamRotation::ROTATION_0};
2179                    Stream inputStream = {streamId++, StreamType::INPUT,
2180                            static_cast<uint32_t> (input.width),
2181                            static_cast<uint32_t> (input.height),
2182                            static_cast<PixelFormat> (input.format), 0, 0,
2183                            StreamRotation::ROTATION_0};
2184                    Stream outputStream = {streamId++, StreamType::OUTPUT,
2185                            static_cast<uint32_t> (outputIter.width),
2186                            static_cast<uint32_t> (outputIter.height),
2187                            static_cast<PixelFormat> (outputIter.format), 0, 0,
2188                            StreamRotation::ROTATION_0};
2189
2190                    ::android::hardware::hidl_vec<Stream> streams = {
2191                            inputStream, zslStream, outputStream};
2192                    StreamConfiguration config = {streams,
2193                            StreamConfigurationMode::NORMAL_MODE};
2194                    ret = session->configureStreams(config, [streamId] (Status s,
2195                            HalStreamConfiguration halConfig) {
2196                        ASSERT_EQ(Status::OK, s);
2197                        ASSERT_EQ(3u, halConfig.streams.size());
2198                    });
2199                    ASSERT_TRUE(ret.isOk());
2200                }
2201            }
2202
2203            free_camera_metadata(staticMeta);
2204            ret = session->close();
2205            ASSERT_TRUE(ret.isOk());
2206        }
2207    }
2208}
2209
2210// Verify that all supported preview + still capture stream combinations
2211// can be configured successfully.
2212TEST_F(CameraHidlTest, configureStreamsPreviewStillOutputs) {
2213    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
2214    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
2215    std::vector<AvailableStream> outputBlobStreams;
2216    std::vector<AvailableStream> outputPreviewStreams;
2217    AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
2218            static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
2219    AvailableStream blobThreshold = {INT32_MAX, INT32_MAX,
2220            static_cast<int32_t>(PixelFormat::BLOB)};
2221
2222    for (const auto& name : cameraDeviceNames) {
2223        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
2224            camera_metadata_t *staticMeta;
2225            Return<void> ret;
2226            sp<ICameraDeviceSession> session;
2227            openEmptyDeviceSession(name, env, &session /*out*/,
2228                    &staticMeta /*out*/);
2229
2230            outputBlobStreams.clear();
2231            ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta,
2232                    outputBlobStreams, &blobThreshold));
2233            ASSERT_NE(0u, outputBlobStreams.size());
2234
2235            outputPreviewStreams.clear();
2236            ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta,
2237                    outputPreviewStreams, &previewThreshold));
2238            ASSERT_NE(0u, outputPreviewStreams.size());
2239
2240            int32_t streamId = 0;
2241            for (auto &blobIter : outputBlobStreams) {
2242                for (auto &previewIter : outputPreviewStreams) {
2243                    Stream previewStream = {streamId++, StreamType::OUTPUT,
2244                            static_cast<uint32_t> (previewIter.width),
2245                            static_cast<uint32_t> (previewIter.height),
2246                            static_cast<PixelFormat> (previewIter.format), 0, 0,
2247                            StreamRotation::ROTATION_0};
2248                    Stream blobStream = {streamId++, StreamType::OUTPUT,
2249                            static_cast<uint32_t> (blobIter.width),
2250                            static_cast<uint32_t> (blobIter.height),
2251                            static_cast<PixelFormat> (blobIter.format), 0, 0,
2252                            StreamRotation::ROTATION_0};
2253                    ::android::hardware::hidl_vec<Stream> streams = {
2254                            previewStream, blobStream};
2255                    StreamConfiguration config = {streams,
2256                            StreamConfigurationMode::NORMAL_MODE};
2257                    ret = session->configureStreams(config, [streamId] (Status s,
2258                            HalStreamConfiguration halConfig) {
2259                        ASSERT_EQ(Status::OK, s);
2260                        ASSERT_EQ(2u, halConfig.streams.size());
2261                    });
2262                    ASSERT_TRUE(ret.isOk());
2263                }
2264            }
2265
2266            free_camera_metadata(staticMeta);
2267            ret = session->close();
2268            ASSERT_TRUE(ret.isOk());
2269        }
2270    }
2271}
2272
2273// In case constrained mode is supported, test whether it can be
2274// configured. Additionally check for common invalid inputs when
2275// using this mode.
2276TEST_F(CameraHidlTest, configureStreamsConstrainedOutputs) {
2277    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
2278    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
2279
2280    for (const auto& name : cameraDeviceNames) {
2281        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
2282            camera_metadata_t *staticMeta;
2283            Return<void> ret;
2284            sp<ICameraDeviceSession> session;
2285            openEmptyDeviceSession(name, env, &session /*out*/,
2286                    &staticMeta /*out*/);
2287
2288            Status rc = isConstrainedModeAvailable(staticMeta);
2289            if (Status::METHOD_NOT_SUPPORTED == rc) {
2290                ret = session->close();
2291                ASSERT_TRUE(ret.isOk());
2292                continue;
2293            }
2294            ASSERT_EQ(Status::OK, rc);
2295
2296            AvailableStream hfrStream;
2297            rc = pickConstrainedModeSize(staticMeta, hfrStream);
2298            ASSERT_EQ(Status::OK, rc);
2299
2300            int32_t streamId = 0;
2301            Stream stream = {streamId, StreamType::OUTPUT,
2302                    static_cast<uint32_t> (hfrStream.width),
2303                    static_cast<uint32_t> (hfrStream.height),
2304                    static_cast<PixelFormat> (hfrStream.format), 0, 0,
2305                    StreamRotation::ROTATION_0};
2306            ::android::hardware::hidl_vec<Stream> streams = {stream};
2307            StreamConfiguration config = {streams,
2308                    StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE};
2309            ret = session->configureStreams(config, [streamId] (Status s,
2310                    HalStreamConfiguration halConfig) {
2311                ASSERT_EQ(Status::OK, s);
2312                ASSERT_EQ(1u, halConfig.streams.size());
2313                ASSERT_EQ(halConfig.streams[0].id, streamId);
2314            });
2315            ASSERT_TRUE(ret.isOk());
2316
2317            stream = {streamId++, StreamType::OUTPUT,
2318                    static_cast<uint32_t> (0),
2319                    static_cast<uint32_t> (0),
2320                    static_cast<PixelFormat> (hfrStream.format), 0, 0,
2321                    StreamRotation::ROTATION_0};
2322            streams[0] = stream;
2323            config = {streams,
2324                    StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE};
2325            ret = session->configureStreams(config, [streamId] (Status s,
2326                    HalStreamConfiguration) {
2327                ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) ||
2328                            (Status::INTERNAL_ERROR == s));
2329            });
2330            ASSERT_TRUE(ret.isOk());
2331
2332            stream = {streamId++, StreamType::OUTPUT,
2333                    static_cast<uint32_t> (UINT32_MAX),
2334                    static_cast<uint32_t> (UINT32_MAX),
2335                    static_cast<PixelFormat> (hfrStream.format), 0, 0,
2336                    StreamRotation::ROTATION_0};
2337            streams[0] = stream;
2338            config = {streams,
2339                    StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE};
2340            ret = session->configureStreams(config, [streamId] (Status s,
2341                    HalStreamConfiguration) {
2342                ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
2343            });
2344            ASSERT_TRUE(ret.isOk());
2345
2346            stream = {streamId++, StreamType::OUTPUT,
2347                    static_cast<uint32_t> (hfrStream.width),
2348                    static_cast<uint32_t> (hfrStream.height),
2349                    static_cast<PixelFormat> (UINT32_MAX), 0, 0,
2350                    StreamRotation::ROTATION_0};
2351            streams[0] = stream;
2352            config = {streams,
2353                    StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE};
2354            ret = session->configureStreams(config, [streamId] (Status s,
2355                    HalStreamConfiguration) {
2356                ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
2357            });
2358            ASSERT_TRUE(ret.isOk());
2359
2360            free_camera_metadata(staticMeta);
2361            ret = session->close();
2362            ASSERT_TRUE(ret.isOk());
2363        }
2364    }
2365}
2366
2367// Verify that all supported video + snapshot stream combinations can
2368// be configured successfully.
2369TEST_F(CameraHidlTest, configureStreamsVideoStillOutputs) {
2370    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
2371    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
2372    std::vector<AvailableStream> outputBlobStreams;
2373    std::vector<AvailableStream> outputVideoStreams;
2374    AvailableStream videoThreshold = {kMaxVideoWidth, kMaxVideoHeight,
2375            static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
2376    AvailableStream blobThreshold = {kMaxVideoWidth, kMaxVideoHeight,
2377            static_cast<int32_t>(PixelFormat::BLOB)};
2378
2379    for (const auto& name : cameraDeviceNames) {
2380        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
2381            camera_metadata_t *staticMeta;
2382            Return<void> ret;
2383            sp<ICameraDeviceSession> session;
2384            openEmptyDeviceSession(name, env, &session /*out*/,
2385                    &staticMeta /*out*/);
2386
2387            outputBlobStreams.clear();
2388            ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta,
2389                    outputBlobStreams, &blobThreshold));
2390            ASSERT_NE(0u, outputBlobStreams.size());
2391
2392            outputVideoStreams.clear();
2393            ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta,
2394                    outputVideoStreams, &videoThreshold));
2395            ASSERT_NE(0u, outputVideoStreams.size());
2396
2397            int32_t streamId = 0;
2398            for (auto &blobIter : outputBlobStreams) {
2399                for (auto &videoIter : outputVideoStreams) {
2400                    Stream videoStream = {streamId++, StreamType::OUTPUT,
2401                            static_cast<uint32_t> (videoIter.width),
2402                            static_cast<uint32_t> (videoIter.height),
2403                            static_cast<PixelFormat> (videoIter.format), 0, 0,
2404                            StreamRotation::ROTATION_0};
2405                    Stream blobStream = {streamId++, StreamType::OUTPUT,
2406                            static_cast<uint32_t> (blobIter.width),
2407                            static_cast<uint32_t> (blobIter.height),
2408                            static_cast<PixelFormat> (blobIter.format),
2409                            GRALLOC_USAGE_HW_VIDEO_ENCODER, 0,
2410                            StreamRotation::ROTATION_0};
2411                    ::android::hardware::hidl_vec<Stream> streams = {
2412                            videoStream, blobStream};
2413                    StreamConfiguration config = {streams,
2414                            StreamConfigurationMode::NORMAL_MODE};
2415                    ret = session->configureStreams(config, [streamId] (Status s,
2416                            HalStreamConfiguration halConfig) {
2417                        ASSERT_EQ(Status::OK, s);
2418                        ASSERT_EQ(2u, halConfig.streams.size());
2419                    });
2420                    ASSERT_TRUE(ret.isOk());
2421                }
2422            }
2423
2424            free_camera_metadata(staticMeta);
2425            ret = session->close();
2426            ASSERT_TRUE(ret.isOk());
2427        }
2428    }
2429}
2430
2431// Generate and verify a camera capture request
2432TEST_F(CameraHidlTest, processCaptureRequestPreview) {
2433    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
2434    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
2435    AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
2436            static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
2437    uint64_t bufferId = 1;
2438    uint32_t frameNumber = 1;
2439    ::android::hardware::hidl_vec<uint8_t> settings;
2440
2441    for (const auto& name : cameraDeviceNames) {
2442        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
2443            Stream previewStream;
2444            HalStreamConfiguration halStreamConfig;
2445            sp<ICameraDeviceSession> session;
2446            configurePreviewStream(name, env, &previewThreshold,
2447                    &session /*out*/, &previewStream /*out*/,
2448                    &halStreamConfig /*out*/);
2449
2450            RequestTemplate reqTemplate = RequestTemplate::PREVIEW;
2451            Return<void> ret;
2452            ret = session->constructDefaultRequestSettings(reqTemplate,
2453                [&](auto status, const auto& req) {
2454                    ASSERT_EQ(Status::OK, status);
2455                    settings = req; });
2456            ASSERT_TRUE(ret.isOk());
2457
2458            sp<GraphicBuffer> gb = new GraphicBuffer(previewStream.width,
2459                    previewStream.height,
2460                    static_cast<int32_t> (halStreamConfig.streams[0].overrideFormat),
2461                    1, halStreamConfig.streams[0].producerUsage,
2462                    halStreamConfig.streams[0].consumerUsage);
2463            ASSERT_NE(nullptr, gb.get());
2464            StreamBuffer outputBuffer = {halStreamConfig.streams[0].id,
2465                    bufferId, hidl_handle(gb->getNativeBuffer()->handle),
2466                    BufferStatus::OK, nullptr, nullptr};
2467            ::android::hardware::hidl_vec<StreamBuffer> outputBuffers = {
2468                    outputBuffer};
2469            StreamBuffer emptyInputBuffer = {-1, 0, nullptr,
2470                    BufferStatus::ERROR, nullptr, nullptr};
2471            CaptureRequest request = {frameNumber, settings,
2472                    emptyInputBuffer, outputBuffers};
2473
2474            {
2475                std::unique_lock<std::mutex> l(mLock);
2476                mResultBuffers.clear();
2477                mResultFrameNumber = frameNumber;
2478            }
2479
2480            Return<Status> returnStatus = session->processCaptureRequest(
2481                    request);
2482            ASSERT_TRUE(returnStatus.isOk());
2483            ASSERT_EQ(Status::OK, returnStatus);
2484
2485            {
2486                std::unique_lock<std::mutex> l(mLock);
2487                while (0 == mResultBuffers.size()) {
2488                    auto timeout = std::chrono::system_clock::now() +
2489                            std::chrono::seconds(kStreamBufferTimeoutSec);
2490                    ASSERT_NE(std::cv_status::timeout,
2491                            mResultCondition.wait_until(l, timeout));
2492                }
2493
2494                ASSERT_EQ(BufferStatus::OK, mResultBuffers[0].status);
2495                ASSERT_EQ(previewStream.id, mResultBuffers[0].streamId);
2496
2497                request.frameNumber++;
2498                //Empty settings should be supported after the first call
2499                //for repeating requests.
2500                request.settings.setToExternal(nullptr, 0, true);
2501                mResultBuffers.clear();
2502                mResultFrameNumber++;
2503            }
2504
2505            returnStatus = session->processCaptureRequest(
2506                    request);
2507            ASSERT_TRUE(returnStatus.isOk());
2508            ASSERT_EQ(Status::OK, returnStatus);
2509
2510            {
2511                std::unique_lock<std::mutex> l(mLock);
2512                while (0 == mResultBuffers.size()) {
2513                    auto timeout = std::chrono::system_clock::now() +
2514                            std::chrono::seconds(kStreamBufferTimeoutSec);
2515                    ASSERT_NE(std::cv_status::timeout,
2516                            mResultCondition.wait_until(l, timeout));
2517                }
2518                ASSERT_EQ(BufferStatus::OK, mResultBuffers[0].status);
2519                ASSERT_EQ(previewStream.id, mResultBuffers[0].streamId);
2520            }
2521
2522            ret = session->close();
2523            ASSERT_TRUE(ret.isOk());
2524        }
2525    }
2526}
2527
2528// Test whether an incorrect capture request with missing settings will
2529// be reported correctly.
2530TEST_F(CameraHidlTest, processCaptureRequestInvalidSinglePreview) {
2531    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
2532    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
2533    std::vector<AvailableStream> outputPreviewStreams;
2534    AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
2535            static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
2536    uint64_t bufferId = 1;
2537    uint32_t frameNumber = 1;
2538    ::android::hardware::hidl_vec<uint8_t> settings;
2539
2540    for (const auto& name : cameraDeviceNames) {
2541        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
2542            Stream previewStream;
2543            HalStreamConfiguration halStreamConfig;
2544            sp<ICameraDeviceSession> session;
2545            configurePreviewStream(name, env, &previewThreshold,
2546                    &session /*out*/, &previewStream /*out*/,
2547                    &halStreamConfig /*out*/);
2548
2549            sp<GraphicBuffer> gb = new GraphicBuffer(previewStream.width,
2550                    previewStream.height,
2551                    static_cast<int32_t> (halStreamConfig.streams[0].overrideFormat),
2552                    1, halStreamConfig.streams[0].producerUsage,
2553                    halStreamConfig.streams[0].consumerUsage);
2554
2555            StreamBuffer outputBuffer = {halStreamConfig.streams[0].id,
2556                    bufferId, hidl_handle(gb->getNativeBuffer()->handle),
2557                    BufferStatus::OK, nullptr, nullptr};
2558            ::android::hardware::hidl_vec<StreamBuffer> outputBuffers = {
2559                    outputBuffer};
2560            StreamBuffer emptyInputBuffer = {-1, 0, nullptr,
2561                    BufferStatus::ERROR, nullptr, nullptr};
2562            CaptureRequest request = {frameNumber, settings,
2563                    emptyInputBuffer, outputBuffers};
2564
2565            //Settings were not correctly initialized, we should fail here
2566            Return<Status> returnStatus = session->processCaptureRequest(
2567                    request);
2568            ASSERT_TRUE(returnStatus.isOk());
2569            ASSERT_EQ(Status::INTERNAL_ERROR, returnStatus);
2570
2571            Return<void> ret = session->close();
2572            ASSERT_TRUE(ret.isOk());
2573        }
2574    }
2575}
2576
2577// Check whether an invalid capture request with missing output buffers
2578// will be reported correctly.
2579TEST_F(CameraHidlTest, processCaptureRequestInvalidBuffer) {
2580    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
2581    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
2582    std::vector<AvailableStream> outputBlobStreams;
2583    AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
2584            static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
2585    uint32_t frameNumber = 1;
2586    ::android::hardware::hidl_vec<uint8_t> settings;
2587
2588    for (const auto& name : cameraDeviceNames) {
2589        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
2590            Stream previewStream;
2591            HalStreamConfiguration halStreamConfig;
2592            sp<ICameraDeviceSession> session;
2593            configurePreviewStream(name, env, &previewThreshold,
2594                    &session /*out*/, &previewStream /*out*/,
2595                    &halStreamConfig /*out*/);
2596
2597            RequestTemplate reqTemplate = RequestTemplate::PREVIEW;
2598            Return<void> ret;
2599            ret = session->constructDefaultRequestSettings(reqTemplate,
2600                [&](auto status, const auto& req) {
2601                    ASSERT_EQ(Status::OK, status);
2602                    settings = req; });
2603            ASSERT_TRUE(ret.isOk());
2604
2605            ::android::hardware::hidl_vec<StreamBuffer> emptyOutputBuffers;
2606            StreamBuffer emptyInputBuffer = {-1, 0, nullptr,
2607                    BufferStatus::ERROR, nullptr, nullptr};
2608            CaptureRequest request = {frameNumber, settings,
2609                    emptyInputBuffer, emptyOutputBuffers};
2610
2611            //Output buffers are missing, we should fail here
2612            Return<Status> returnStatus = session->processCaptureRequest(
2613                    request);
2614            ASSERT_TRUE(returnStatus.isOk());
2615            ASSERT_EQ(Status::INTERNAL_ERROR,
2616                      returnStatus);
2617
2618            ret = session->close();
2619            ASSERT_TRUE(ret.isOk());
2620        }
2621    }
2622}
2623
2624// Generate, trigger and flush a preview request
2625TEST_F(CameraHidlTest, flushPreviewRequest) {
2626    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
2627    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
2628    std::vector<AvailableStream> outputPreviewStreams;
2629    AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
2630            static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
2631    uint64_t bufferId = 1;
2632    uint32_t frameNumber = 1;
2633    ::android::hardware::hidl_vec<uint8_t> settings;
2634
2635    for (const auto& name : cameraDeviceNames) {
2636        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
2637            Stream previewStream;
2638            HalStreamConfiguration halStreamConfig;
2639            sp<ICameraDeviceSession> session;
2640            configurePreviewStream(name, env, &previewThreshold,
2641                    &session /*out*/, &previewStream /*out*/,
2642                    &halStreamConfig /*out*/);
2643
2644            RequestTemplate reqTemplate = RequestTemplate::PREVIEW;
2645            Return<void> ret;
2646            ret = session->constructDefaultRequestSettings(reqTemplate,
2647                [&](auto status, const auto& req) {
2648                    ASSERT_EQ(Status::OK, status);
2649                    settings = req; });
2650            ASSERT_TRUE(ret.isOk());
2651
2652            sp<GraphicBuffer> gb = new GraphicBuffer(previewStream.width,
2653                    previewStream.height,
2654                    static_cast<int32_t> (halStreamConfig.streams[0].overrideFormat),
2655                    1, halStreamConfig.streams[0].producerUsage,
2656                    halStreamConfig.streams[0].consumerUsage);
2657            ASSERT_NE(nullptr, gb.get());
2658            StreamBuffer outputBuffer = {halStreamConfig.streams[0].id,
2659                    bufferId, hidl_handle(gb->getNativeBuffer()->handle),
2660                    BufferStatus::OK, nullptr, nullptr};
2661            ::android::hardware::hidl_vec<StreamBuffer> outputBuffers = {
2662                    outputBuffer};
2663            const StreamBuffer emptyInputBuffer = {-1, 0, nullptr,
2664                    BufferStatus::ERROR, nullptr, nullptr};
2665            CaptureRequest request = {frameNumber, settings,
2666                    emptyInputBuffer, outputBuffers};
2667
2668            {
2669                std::unique_lock<std::mutex> l(mLock);
2670                mResultBuffers.clear();
2671                mErrors.clear();
2672                mResultFrameNumber = frameNumber;
2673            }
2674
2675            Return<Status> returnStatus = session->processCaptureRequest(
2676                    request);
2677            ASSERT_TRUE(returnStatus.isOk());
2678            ASSERT_EQ(Status::OK, returnStatus);
2679            //Flush before waiting for request to complete.
2680            returnStatus = session->flush();
2681            ASSERT_TRUE(returnStatus.isOk());
2682            ASSERT_EQ(Status::OK, returnStatus);
2683
2684            {
2685                std::unique_lock<std::mutex> l(mLock);
2686                while ((0 == mResultBuffers.size()) && (0 == mErrors.size())) {
2687                    auto timeout = std::chrono::system_clock::now() +
2688                            std::chrono::seconds(kStreamBufferTimeoutSec);
2689                    ASSERT_NE(std::cv_status::timeout,
2690                            mResultCondition.wait_until(l, timeout));
2691                }
2692
2693                if (mErrors.empty()) {
2694                    ASSERT_EQ(BufferStatus::OK, mResultBuffers[0].status);
2695                    ASSERT_EQ(previewStream.id, mResultBuffers[0].streamId);
2696                } else {
2697                    for (auto &error : mErrors) {
2698                        switch (error.errorCode) {
2699                            case ErrorCode::ERROR_REQUEST:
2700                            case ErrorCode::ERROR_RESULT:
2701                                //Expected
2702                                break;
2703                            case ErrorCode::ERROR_BUFFER:
2704                                //Expected as well
2705                                ASSERT_EQ(frameNumber, error.frameNumber);
2706                                ASSERT_EQ(previewStream.id, error.errorStreamId);
2707                                break;
2708                            case ErrorCode::ERROR_DEVICE:
2709                            default:
2710                                FAIL() <<"Unexpected error:" << static_cast<uint32_t> (error.errorCode);
2711                        }
2712                    }
2713                }
2714            }
2715
2716            ret = session->close();
2717            ASSERT_TRUE(ret.isOk());
2718        }
2719    }
2720}
2721
2722// Verify that camera flushes correctly without any pending requests.
2723TEST_F(CameraHidlTest, flushEmpty) {
2724    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
2725    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
2726    std::vector<AvailableStream> outputPreviewStreams;
2727    AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
2728            static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
2729
2730    for (const auto& name : cameraDeviceNames) {
2731        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
2732            Stream previewStream;
2733            HalStreamConfiguration halStreamConfig;
2734            sp<ICameraDeviceSession> session;
2735            configurePreviewStream(name, env, &previewThreshold,
2736                    &session /*out*/, &previewStream /*out*/,
2737                    &halStreamConfig /*out*/);
2738
2739            {
2740                std::unique_lock<std::mutex> l(mLock);
2741                mResultBuffers.clear();
2742                mErrors.clear();
2743                mResultFrameNumber = 0;
2744            }
2745
2746            Return<Status> returnStatus = session->flush();
2747            ASSERT_TRUE(returnStatus.isOk());
2748            ASSERT_EQ(Status::OK, returnStatus);
2749
2750            {
2751                std::unique_lock<std::mutex> l(mLock);
2752                auto timeout = std::chrono::system_clock::now() +
2753                        std::chrono::milliseconds(kEmptyFlushTimeoutMSec);
2754                ASSERT_EQ(std::cv_status::timeout,
2755                        mResultCondition.wait_until(l, timeout));
2756                ASSERT_TRUE(mErrors.empty());
2757                ASSERT_TRUE(mResultBuffers.empty());
2758            }
2759
2760            Return<void> ret = session->close();
2761            ASSERT_TRUE(ret.isOk());
2762        }
2763    }
2764}
2765
2766// Retrieve all valid output stream resolutions from the camera
2767// static characteristics.
2768Status CameraHidlTest::getAvailableOutputStreams(camera_metadata_t *staticMeta,
2769        std::vector<AvailableStream> &outputStreams,
2770        const AvailableStream *threshold) {
2771    if (nullptr == staticMeta) {
2772        return Status::ILLEGAL_ARGUMENT;
2773    }
2774
2775    camera_metadata_ro_entry entry;
2776    int rc = find_camera_metadata_ro_entry(staticMeta,
2777            ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS, &entry);
2778    if ((0 != rc) || (0 != (entry.count % 4))) {
2779        return Status::ILLEGAL_ARGUMENT;
2780    }
2781
2782    for (size_t i = 0; i < entry.count; i+=4) {
2783        if (ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT ==
2784                entry.data.i32[i + 3]) {
2785            if(nullptr == threshold) {
2786                AvailableStream s = {entry.data.i32[i+1],
2787                        entry.data.i32[i+2], entry.data.i32[i]};
2788                outputStreams.push_back(s);
2789            } else {
2790                if ((threshold->format == entry.data.i32[i]) &&
2791                        (threshold->width >= entry.data.i32[i+1]) &&
2792                        (threshold->height >= entry.data.i32[i+2])) {
2793                    AvailableStream s = {entry.data.i32[i+1],
2794                            entry.data.i32[i+2], threshold->format};
2795                    outputStreams.push_back(s);
2796                }
2797            }
2798        }
2799
2800    }
2801
2802    return Status::OK;
2803}
2804
2805// Check if constrained mode is supported by using the static
2806// camera characteristics.
2807Status CameraHidlTest::isConstrainedModeAvailable(camera_metadata_t *staticMeta) {
2808    Status ret = Status::METHOD_NOT_SUPPORTED;
2809    if (nullptr == staticMeta) {
2810        return Status::ILLEGAL_ARGUMENT;
2811    }
2812
2813    camera_metadata_ro_entry entry;
2814    int rc = find_camera_metadata_ro_entry(staticMeta,
2815            ANDROID_REQUEST_AVAILABLE_CAPABILITIES, &entry);
2816    if (0 != rc) {
2817        return Status::ILLEGAL_ARGUMENT;
2818    }
2819
2820    for (size_t i = 0; i < entry.count; i++) {
2821        if (ANDROID_REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO ==
2822                entry.data.u8[i]) {
2823            ret = Status::OK;
2824            break;
2825        }
2826    }
2827
2828    return ret;
2829}
2830
2831// Pick the largest supported HFR mode from the static camera
2832// characteristics.
2833Status CameraHidlTest::pickConstrainedModeSize(camera_metadata_t *staticMeta,
2834        AvailableStream &hfrStream) {
2835    if (nullptr == staticMeta) {
2836        return Status::ILLEGAL_ARGUMENT;
2837    }
2838
2839    camera_metadata_ro_entry entry;
2840    int rc = find_camera_metadata_ro_entry(staticMeta,
2841            ANDROID_CONTROL_AVAILABLE_HIGH_SPEED_VIDEO_CONFIGURATIONS, &entry);
2842    if (0 != rc) {
2843        return Status::METHOD_NOT_SUPPORTED;
2844    } else if (0 != (entry.count % 5)) {
2845        return Status::ILLEGAL_ARGUMENT;
2846    }
2847
2848    hfrStream = {0, 0,
2849            static_cast<uint32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
2850    for (size_t i = 0; i < entry.count; i+=5) {
2851        int32_t w = entry.data.i32[i];
2852        int32_t h = entry.data.i32[i+1];
2853        if ((hfrStream.width * hfrStream.height) < (w *h)) {
2854            hfrStream.width = w;
2855            hfrStream.height = h;
2856        }
2857    }
2858
2859    return Status::OK;
2860}
2861
2862// Check whether ZSL is available using the static camera
2863// characteristics.
2864Status CameraHidlTest::isZSLModeAvailable(camera_metadata_t *staticMeta) {
2865    Status ret = Status::METHOD_NOT_SUPPORTED;
2866    if (nullptr == staticMeta) {
2867        return Status::ILLEGAL_ARGUMENT;
2868    }
2869
2870    camera_metadata_ro_entry entry;
2871    int rc = find_camera_metadata_ro_entry(staticMeta,
2872            ANDROID_REQUEST_AVAILABLE_CAPABILITIES, &entry);
2873    if (0 != rc) {
2874        return Status::ILLEGAL_ARGUMENT;
2875    }
2876
2877    for (size_t i = 0; i < entry.count; i++) {
2878        if ((ANDROID_REQUEST_AVAILABLE_CAPABILITIES_PRIVATE_REPROCESSING ==
2879                entry.data.u8[i]) ||
2880                (ANDROID_REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING ==
2881                        entry.data.u8[i]) ){
2882            ret = Status::OK;
2883            break;
2884        }
2885    }
2886
2887    return ret;
2888}
2889
2890// Retrieve the reprocess input-output format map from the static
2891// camera characteristics.
2892Status CameraHidlTest::getZSLInputOutputMap(camera_metadata_t *staticMeta,
2893        std::vector<AvailableZSLInputOutput> &inputOutputMap) {
2894    if (nullptr == staticMeta) {
2895        return Status::ILLEGAL_ARGUMENT;
2896    }
2897
2898    camera_metadata_ro_entry entry;
2899    int rc = find_camera_metadata_ro_entry(staticMeta,
2900            ANDROID_SCALER_AVAILABLE_INPUT_OUTPUT_FORMATS_MAP, &entry);
2901    if ((0 != rc) || (0 >= entry.count)) {
2902        return Status::ILLEGAL_ARGUMENT;
2903    }
2904
2905    const int32_t* contents = &entry.data.i32[0];
2906    for (size_t i = 0; i < entry.count; ) {
2907        int32_t inputFormat = contents[i++];
2908        int32_t length = contents[i++];
2909        for (int32_t j = 0; j < length; j++) {
2910            int32_t outputFormat = contents[i+j];
2911            AvailableZSLInputOutput zslEntry = {inputFormat, outputFormat};
2912            inputOutputMap.push_back(zslEntry);
2913        }
2914        i += length;
2915    }
2916
2917    return Status::OK;
2918}
2919
2920// Search for the largest stream size for a given format.
2921Status CameraHidlTest::findLargestSize(
2922        const std::vector<AvailableStream> &streamSizes, int32_t format,
2923        AvailableStream &result) {
2924    result = {0, 0, 0};
2925    for (auto &iter : streamSizes) {
2926        if (format == iter.format) {
2927            if ((result.width * result.height) < (iter.width * iter.height)) {
2928                result = iter;
2929            }
2930        }
2931    }
2932
2933    return (result.format == format) ? Status::OK : Status::ILLEGAL_ARGUMENT;
2934}
2935
2936// Check whether the camera device supports specific focus mode.
2937Status CameraHidlTest::isAutoFocusModeAvailable(
2938        ::android::CameraParameters &cameraParams,
2939        const char *mode) {
2940    ::android::String8 focusModes(cameraParams.get(
2941            CameraParameters::KEY_SUPPORTED_FOCUS_MODES));
2942    if (focusModes.contains(mode)) {
2943        return Status::OK;
2944    }
2945
2946    return Status::METHOD_NOT_SUPPORTED;
2947}
2948
2949// Open a device session and configure a preview stream.
2950void CameraHidlTest::configurePreviewStream(const std::string &name,
2951        const CameraHidlEnvironment* env,
2952        const AvailableStream *previewThreshold,
2953        sp<ICameraDeviceSession> *session /*out*/,
2954        Stream *previewStream /*out*/,
2955        HalStreamConfiguration *halStreamConfig /*out*/) {
2956    ASSERT_NE(nullptr, env);
2957    ASSERT_NE(nullptr, session);
2958    ASSERT_NE(nullptr, previewStream);
2959    ASSERT_NE(nullptr, halStreamConfig);
2960
2961    std::vector<AvailableStream> outputPreviewStreams;
2962    ::android::sp<ICameraDevice> device3_2;
2963    ALOGI("configureStreams: Testing camera device %s", name.c_str());
2964    Return<void> ret;
2965    ret = env->mProvider->getCameraDeviceInterface_V3_x(
2966        name,
2967        [&](auto status, const auto& device) {
2968            ALOGI("getCameraDeviceInterface_V3_x returns status:%d",
2969                  (int)status);
2970            ASSERT_EQ(Status::OK, status);
2971            ASSERT_NE(device, nullptr);
2972            device3_2 = device;
2973        });
2974    ASSERT_TRUE(ret.isOk());
2975
2976    sp<DeviceCb> cb = new DeviceCb(this);
2977    ret = device3_2->open(
2978        cb,
2979        [&](auto status, const auto& newSession) {
2980            ALOGI("device::open returns status:%d", (int)status);
2981            ASSERT_EQ(Status::OK, status);
2982            ASSERT_NE(newSession, nullptr);
2983            *session = newSession;
2984        });
2985    ASSERT_TRUE(ret.isOk());
2986
2987    camera_metadata_t *staticMeta;
2988    ret = device3_2->getCameraCharacteristics([&] (Status s,
2989            CameraMetadata metadata) {
2990        ASSERT_EQ(Status::OK, s);
2991        staticMeta = clone_camera_metadata(
2992                reinterpret_cast<const camera_metadata_t*>(metadata.data()));
2993         ASSERT_NE(nullptr, staticMeta);
2994    });
2995    ASSERT_TRUE(ret.isOk());
2996
2997    outputPreviewStreams.clear();
2998    auto rc = getAvailableOutputStreams(staticMeta,
2999            outputPreviewStreams, previewThreshold);
3000    free_camera_metadata(staticMeta);
3001    ASSERT_EQ(Status::OK, rc);
3002    ASSERT_FALSE(outputPreviewStreams.empty());
3003
3004    *previewStream = {0, StreamType::OUTPUT,
3005            static_cast<uint32_t> (outputPreviewStreams[0].width),
3006            static_cast<uint32_t> (outputPreviewStreams[0].height),
3007            static_cast<PixelFormat> (outputPreviewStreams[0].format),
3008            0, 0, StreamRotation::ROTATION_0};
3009    ::android::hardware::hidl_vec<Stream> streams = {*previewStream};
3010    StreamConfiguration config = {streams,
3011            StreamConfigurationMode::NORMAL_MODE};
3012    ret = (*session)->configureStreams(config, [&] (Status s,
3013            HalStreamConfiguration halConfig) {
3014        ASSERT_EQ(Status::OK, s);
3015        ASSERT_EQ(1u, halConfig.streams.size());
3016        *halStreamConfig = halConfig;
3017    });
3018    ASSERT_TRUE(ret.isOk());
3019}
3020
3021// Open a device session with empty callbacks and return static metadata.
3022void CameraHidlTest::openEmptyDeviceSession(const std::string &name,
3023        const CameraHidlEnvironment* env,
3024        sp<ICameraDeviceSession> *session /*out*/,
3025        camera_metadata_t **staticMeta /*out*/) {
3026    ASSERT_NE(nullptr, env);
3027    ASSERT_NE(nullptr, session);
3028    ASSERT_NE(nullptr, staticMeta);
3029
3030    ::android::sp<ICameraDevice> device3_2;
3031    ALOGI("configureStreams: Testing camera device %s", name.c_str());
3032    Return<void> ret;
3033    ret = env->mProvider->getCameraDeviceInterface_V3_x(
3034        name,
3035        [&](auto status, const auto& device) {
3036            ALOGI("getCameraDeviceInterface_V3_x returns status:%d",
3037                  (int)status);
3038            ASSERT_EQ(Status::OK, status);
3039            ASSERT_NE(device, nullptr);
3040            device3_2 = device;
3041        });
3042    ASSERT_TRUE(ret.isOk());
3043
3044    sp<EmptyDeviceCb> cb = new EmptyDeviceCb();
3045    ret = device3_2->open(cb, [&](auto status, const auto& newSession) {
3046            ALOGI("device::open returns status:%d", (int)status);
3047            ASSERT_EQ(Status::OK, status);
3048            ASSERT_NE(newSession, nullptr);
3049            *session = newSession;
3050        });
3051    ASSERT_TRUE(ret.isOk());
3052
3053    ret = device3_2->getCameraCharacteristics([&] (Status s,
3054            CameraMetadata metadata) {
3055        ASSERT_EQ(Status::OK, s);
3056        *staticMeta = clone_camera_metadata(
3057                reinterpret_cast<const camera_metadata_t*>(metadata.data()));
3058        ASSERT_NE(nullptr, *staticMeta);
3059    });
3060    ASSERT_TRUE(ret.isOk());
3061}
3062
3063// Open a particular camera device.
3064void CameraHidlTest::openCameraDevice(const std::string &name,
3065        const CameraHidlEnvironment* env,
3066        sp<::android::hardware::camera::device::V1_0::ICameraDevice> *device1 /*out*/) {
3067    ASSERT_TRUE(nullptr != env);
3068    ASSERT_TRUE(nullptr != device1);
3069
3070    Return<void> ret;
3071    ret = env->mProvider->getCameraDeviceInterface_V1_x(
3072            name,
3073            [&](auto status, const auto& device) {
3074            ALOGI("getCameraDeviceInterface_V1_x returns status:%d",
3075                  (int)status);
3076            ASSERT_EQ(Status::OK, status);
3077            ASSERT_NE(device, nullptr);
3078            *device1 = device;
3079        });
3080    ASSERT_TRUE(ret.isOk());
3081
3082    sp<Camera1DeviceCb> deviceCb = new Camera1DeviceCb(this);
3083    Return<Status> returnStatus = (*device1)->open(deviceCb);
3084    ASSERT_TRUE(returnStatus.isOk());
3085    ASSERT_EQ(Status::OK, returnStatus);
3086}
3087
3088// Initialize and configure a preview window.
3089void CameraHidlTest::setupPreviewWindow(
3090        const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device,
3091        sp<BufferItemConsumer> *bufferItemConsumer /*out*/,
3092        sp<BufferItemHander> *bufferHandler /*out*/) {
3093    ASSERT_NE(nullptr, device.get());
3094    ASSERT_NE(nullptr, bufferItemConsumer);
3095    ASSERT_NE(nullptr, bufferHandler);
3096
3097    sp<IGraphicBufferProducer> producer;
3098    sp<IGraphicBufferConsumer> consumer;
3099    BufferQueue::createBufferQueue(&producer, &consumer);
3100    *bufferItemConsumer = new BufferItemConsumer(consumer,
3101            GraphicBuffer::USAGE_HW_TEXTURE); //Use GLConsumer default usage flags
3102    ASSERT_NE(nullptr, (*bufferItemConsumer).get());
3103    *bufferHandler = new BufferItemHander(*bufferItemConsumer);
3104    ASSERT_NE(nullptr, (*bufferHandler).get());
3105    (*bufferItemConsumer)->setFrameAvailableListener(*bufferHandler);
3106    sp<Surface> surface = new Surface(producer);
3107    sp<PreviewWindowCb> previewCb = new PreviewWindowCb(surface);
3108
3109    auto rc = device->setPreviewWindow(previewCb);
3110    ASSERT_TRUE(rc.isOk());
3111    ASSERT_EQ(Status::OK, rc);
3112}
3113
3114// Stop camera preview and close camera.
3115void CameraHidlTest::stopPreviewAndClose(
3116        const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device) {
3117    Return<void> ret = device->stopPreview();
3118    ASSERT_TRUE(ret.isOk());
3119
3120    ret = device->close();
3121    ASSERT_TRUE(ret.isOk());
3122}
3123
3124// Enable a specific camera message type.
3125void CameraHidlTest::enableMsgType(unsigned int msgType,
3126        const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device) {
3127    Return<void> ret = device->enableMsgType(msgType);
3128    ASSERT_TRUE(ret.isOk());
3129
3130    Return<bool> returnBoolStatus = device->msgTypeEnabled(msgType);
3131    ASSERT_TRUE(returnBoolStatus.isOk());
3132    ASSERT_TRUE(returnBoolStatus);
3133}
3134
3135// Disable a specific camera message type.
3136void CameraHidlTest::disableMsgType(unsigned int msgType,
3137        const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device) {
3138    Return<void> ret = device->disableMsgType(msgType);
3139    ASSERT_TRUE(ret.isOk());
3140
3141    Return<bool> returnBoolStatus = device->msgTypeEnabled(msgType);
3142    ASSERT_TRUE(returnBoolStatus.isOk());
3143    ASSERT_FALSE(returnBoolStatus);
3144}
3145
3146// Wait until a specific frame notification arrives.
3147void CameraHidlTest::waitForFrameLocked(DataCallbackMsg msgFrame,
3148        std::unique_lock<std::mutex> &l) {
3149    while (msgFrame != mDataMessageTypeReceived) {
3150        auto timeout = std::chrono::system_clock::now() +
3151                std::chrono::seconds(kStreamBufferTimeoutSec);
3152        ASSERT_NE(std::cv_status::timeout,
3153                mResultCondition.wait_until(l, timeout));
3154    }
3155}
3156
3157// Start preview on a particular camera device
3158void CameraHidlTest::startPreview(
3159        const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device) {
3160    Return<Status> returnStatus = device->startPreview();
3161    ASSERT_TRUE(returnStatus.isOk());
3162    ASSERT_EQ(Status::OK, returnStatus);
3163}
3164
3165// Retrieve camera parameters.
3166void CameraHidlTest::getParameters(
3167        const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device,
3168        CameraParameters *cameraParams /*out*/) {
3169    ASSERT_NE(nullptr, cameraParams);
3170
3171    Return<void> ret;
3172    ret = device->getParameters([&] (const ::android::hardware::hidl_string& params) {
3173        ASSERT_FALSE(params.empty());
3174        ::android::String8 paramString(params.c_str());
3175        (*cameraParams).unflatten(paramString);
3176    });
3177    ASSERT_TRUE(ret.isOk());
3178}
3179
3180// Set camera parameters.
3181void CameraHidlTest::setParameters(
3182        const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device,
3183        const CameraParameters &cameraParams) {
3184    Return<Status> returnStatus = device->setParameters(
3185            cameraParams.flatten().string());
3186    ASSERT_TRUE(returnStatus.isOk());
3187    ASSERT_EQ(Status::OK, returnStatus);
3188}
3189
3190int main(int argc, char **argv) {
3191  ::testing::AddGlobalTestEnvironment(CameraHidlEnvironment::Instance());
3192  ::testing::InitGoogleTest(&argc, argv);
3193  int status = RUN_ALL_TESTS();
3194  ALOGI("Test result = %d", status);
3195  return status;
3196}
3197