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