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