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