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