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