VtsHalCameraProviderV2_4TargetTest.cpp revision e18057b42f1698f33f34d14e86a53934bd337bb8
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                ASSERT_TRUE(ret.isOk());
1920            }
1921            break;
1922            case CAMERA_DEVICE_API_VERSION_1_0: {
1923                //Not applicable
1924            }
1925            break;
1926            default: {
1927                ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
1928                ADD_FAILURE();
1929            }
1930            break;
1931        }
1932    }
1933}
1934
1935//In case it is supported verify that torch can be enabled.
1936//Check for corresponding toch callbacks as well.
1937TEST_F(CameraHidlTest, setTorchMode) {
1938    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
1939    bool torchControlSupported = false;
1940    Return<void> ret;
1941
1942    ret = mProvider->isSetTorchModeSupported([&](auto status, bool support) {
1943        ALOGI("isSetTorchModeSupported returns status:%d supported:%d", (int)status, support);
1944        ASSERT_EQ(Status::OK, status);
1945        torchControlSupported = support;
1946    });
1947
1948    sp<TorchProviderCb> cb = new TorchProviderCb(this);
1949    Return<Status> returnStatus = mProvider->setCallback(cb);
1950    ASSERT_TRUE(returnStatus.isOk());
1951    ASSERT_EQ(Status::OK, returnStatus);
1952
1953    for (const auto& name : cameraDeviceNames) {
1954        int deviceVersion = getCameraDeviceVersion(name, mProviderType);
1955        switch (deviceVersion) {
1956            case CAMERA_DEVICE_API_VERSION_3_4:
1957            case CAMERA_DEVICE_API_VERSION_3_3:
1958            case CAMERA_DEVICE_API_VERSION_3_2: {
1959                ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_x;
1960                ALOGI("setTorchMode: Testing camera device %s", name.c_str());
1961                ret = mProvider->getCameraDeviceInterface_V3_x(
1962                    name, [&](auto status, const auto& device) {
1963                        ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
1964                        ASSERT_EQ(Status::OK, status);
1965                        ASSERT_NE(device, nullptr);
1966                        device3_x = device;
1967                    });
1968                ASSERT_TRUE(ret.isOk());
1969
1970                mTorchStatus = TorchModeStatus::NOT_AVAILABLE;
1971                returnStatus = device3_x->setTorchMode(TorchMode::ON);
1972                ASSERT_TRUE(returnStatus.isOk());
1973                if (!torchControlSupported) {
1974                    ASSERT_EQ(Status::METHOD_NOT_SUPPORTED, returnStatus);
1975                } else {
1976                    ASSERT_TRUE(returnStatus == Status::OK ||
1977                                returnStatus == Status::OPERATION_NOT_SUPPORTED);
1978                    if (returnStatus == Status::OK) {
1979                        {
1980                            std::unique_lock<std::mutex> l(mTorchLock);
1981                            while (TorchModeStatus::NOT_AVAILABLE == mTorchStatus) {
1982                                auto timeout = std::chrono::system_clock::now() +
1983                                               std::chrono::seconds(kTorchTimeoutSec);
1984                                ASSERT_NE(std::cv_status::timeout, mTorchCond.wait_until(l, timeout));
1985                            }
1986                            ASSERT_EQ(TorchModeStatus::AVAILABLE_ON, mTorchStatus);
1987                            mTorchStatus = TorchModeStatus::NOT_AVAILABLE;
1988                        }
1989
1990                        returnStatus = device3_x->setTorchMode(TorchMode::OFF);
1991                        ASSERT_TRUE(returnStatus.isOk());
1992                        ASSERT_EQ(Status::OK, returnStatus);
1993
1994                        {
1995                            std::unique_lock<std::mutex> l(mTorchLock);
1996                            while (TorchModeStatus::NOT_AVAILABLE == mTorchStatus) {
1997                                auto timeout = std::chrono::system_clock::now() +
1998                                               std::chrono::seconds(kTorchTimeoutSec);
1999                                ASSERT_NE(std::cv_status::timeout, mTorchCond.wait_until(l, timeout));
2000                            }
2001                            ASSERT_EQ(TorchModeStatus::AVAILABLE_OFF, mTorchStatus);
2002                        }
2003                    }
2004                }
2005            }
2006            break;
2007            case CAMERA_DEVICE_API_VERSION_1_0: {
2008                ::android::sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
2009                ALOGI("dumpState: Testing camera device %s", name.c_str());
2010                ret = mProvider->getCameraDeviceInterface_V1_x(
2011                    name, [&](auto status, const auto& device) {
2012                        ALOGI("getCameraDeviceInterface_V1_x returns status:%d", (int)status);
2013                        ASSERT_EQ(Status::OK, status);
2014                        ASSERT_NE(device, nullptr);
2015                        device1 = device;
2016                    });
2017                ASSERT_TRUE(ret.isOk());
2018
2019                mTorchStatus = TorchModeStatus::NOT_AVAILABLE;
2020                returnStatus = device1->setTorchMode(TorchMode::ON);
2021                ASSERT_TRUE(returnStatus.isOk());
2022                if (!torchControlSupported) {
2023                    ASSERT_EQ(Status::METHOD_NOT_SUPPORTED, returnStatus);
2024                } else {
2025                    ASSERT_TRUE(returnStatus == Status::OK ||
2026                                returnStatus == Status::OPERATION_NOT_SUPPORTED);
2027                    if (returnStatus == Status::OK) {
2028                        {
2029                            std::unique_lock<std::mutex> l(mTorchLock);
2030                            while (TorchModeStatus::NOT_AVAILABLE == mTorchStatus) {
2031                                auto timeout = std::chrono::system_clock::now() +
2032                                               std::chrono::seconds(kTorchTimeoutSec);
2033                                ASSERT_NE(std::cv_status::timeout, mTorchCond.wait_until(l,
2034                                        timeout));
2035                            }
2036                            ASSERT_EQ(TorchModeStatus::AVAILABLE_ON, mTorchStatus);
2037                            mTorchStatus = TorchModeStatus::NOT_AVAILABLE;
2038                        }
2039
2040                        returnStatus = device1->setTorchMode(TorchMode::OFF);
2041                        ASSERT_TRUE(returnStatus.isOk());
2042                        ASSERT_EQ(Status::OK, returnStatus);
2043
2044                        {
2045                            std::unique_lock<std::mutex> l(mTorchLock);
2046                            while (TorchModeStatus::NOT_AVAILABLE == mTorchStatus) {
2047                                auto timeout = std::chrono::system_clock::now() +
2048                                               std::chrono::seconds(kTorchTimeoutSec);
2049                                ASSERT_NE(std::cv_status::timeout, mTorchCond.wait_until(l,
2050                                        timeout));
2051                            }
2052                            ASSERT_EQ(TorchModeStatus::AVAILABLE_OFF, mTorchStatus);
2053                        }
2054                    }
2055                }
2056                ret = device1->close();
2057                ASSERT_TRUE(ret.isOk());
2058            }
2059            break;
2060            default: {
2061                ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
2062                ADD_FAILURE();
2063            }
2064            break;
2065        }
2066    }
2067
2068    returnStatus = mProvider->setCallback(nullptr);
2069    ASSERT_TRUE(returnStatus.isOk());
2070    ASSERT_EQ(Status::OK, returnStatus);
2071}
2072
2073// Check dump functionality.
2074TEST_F(CameraHidlTest, dumpState) {
2075    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
2076    Return<void> ret;
2077
2078    for (const auto& name : cameraDeviceNames) {
2079        int deviceVersion = getCameraDeviceVersion(name, mProviderType);
2080        switch (deviceVersion) {
2081            case CAMERA_DEVICE_API_VERSION_3_4:
2082            case CAMERA_DEVICE_API_VERSION_3_3:
2083            case CAMERA_DEVICE_API_VERSION_3_2: {
2084                ::android::sp<ICameraDevice> device3_x;
2085                ALOGI("dumpState: Testing camera device %s", name.c_str());
2086                ret = mProvider->getCameraDeviceInterface_V3_x(
2087                    name, [&](auto status, const auto& device) {
2088                        ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
2089                        ASSERT_EQ(Status::OK, status);
2090                        ASSERT_NE(device, nullptr);
2091                        device3_x = device;
2092                    });
2093                ASSERT_TRUE(ret.isOk());
2094
2095                native_handle_t* raw_handle = native_handle_create(1, 0);
2096                raw_handle->data[0] = open(kDumpOutput, O_RDWR);
2097                ASSERT_GE(raw_handle->data[0], 0);
2098                hidl_handle handle = raw_handle;
2099                ret = device3_x->dumpState(handle);
2100                ASSERT_TRUE(ret.isOk());
2101                close(raw_handle->data[0]);
2102                native_handle_delete(raw_handle);
2103            }
2104            break;
2105            case CAMERA_DEVICE_API_VERSION_1_0: {
2106                ::android::sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
2107                ALOGI("dumpState: Testing camera device %s", name.c_str());
2108                ret = mProvider->getCameraDeviceInterface_V1_x(
2109                    name, [&](auto status, const auto& device) {
2110                        ALOGI("getCameraDeviceInterface_V1_x returns status:%d", (int)status);
2111                        ASSERT_EQ(Status::OK, status);
2112                        ASSERT_NE(device, nullptr);
2113                        device1 = device;
2114                    });
2115                ASSERT_TRUE(ret.isOk());
2116
2117                native_handle_t* raw_handle = native_handle_create(1, 0);
2118                raw_handle->data[0] = open(kDumpOutput, O_RDWR);
2119                ASSERT_GE(raw_handle->data[0], 0);
2120                hidl_handle handle = raw_handle;
2121                Return<Status> returnStatus = device1->dumpState(handle);
2122                ASSERT_TRUE(returnStatus.isOk());
2123                ASSERT_EQ(Status::OK, returnStatus);
2124                close(raw_handle->data[0]);
2125                native_handle_delete(raw_handle);
2126            }
2127            break;
2128            default: {
2129                ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
2130                ADD_FAILURE();
2131            }
2132            break;
2133        }
2134    }
2135}
2136
2137// Open, dumpStates, then close
2138TEST_F(CameraHidlTest, openClose) {
2139    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
2140    Return<void> ret;
2141
2142    for (const auto& name : cameraDeviceNames) {
2143        int deviceVersion = getCameraDeviceVersion(name, mProviderType);
2144        switch (deviceVersion) {
2145            case CAMERA_DEVICE_API_VERSION_3_4:
2146            case CAMERA_DEVICE_API_VERSION_3_3:
2147            case CAMERA_DEVICE_API_VERSION_3_2: {
2148                ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_x;
2149                ALOGI("openClose: Testing camera device %s", name.c_str());
2150                ret = mProvider->getCameraDeviceInterface_V3_x(
2151                    name, [&](auto status, const auto& device) {
2152                        ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
2153                        ASSERT_EQ(Status::OK, status);
2154                        ASSERT_NE(device, nullptr);
2155                        device3_x = device;
2156                    });
2157                ASSERT_TRUE(ret.isOk());
2158
2159                sp<EmptyDeviceCb> cb = new EmptyDeviceCb;
2160                sp<ICameraDeviceSession> session;
2161                ret = device3_x->open(cb, [&](auto status, const auto& newSession) {
2162                    ALOGI("device::open returns status:%d", (int)status);
2163                    ASSERT_EQ(Status::OK, status);
2164                    ASSERT_NE(newSession, nullptr);
2165                    session = newSession;
2166                });
2167                ASSERT_TRUE(ret.isOk());
2168                // Ensure that a device labeling itself as 3.3/3.4 can have its session interface
2169                // cast the 3.3/3.4 interface, and that lower versions can't be cast to it.
2170                sp<device::V3_3::ICameraDeviceSession> sessionV3_3;
2171                sp<device::V3_4::ICameraDeviceSession> sessionV3_4;
2172                castSession(session, deviceVersion, &sessionV3_3, &sessionV3_4);
2173                if (deviceVersion == CAMERA_DEVICE_API_VERSION_3_4) {
2174                    ASSERT_TRUE(sessionV3_4.get() != nullptr);
2175                } else if (deviceVersion == CAMERA_DEVICE_API_VERSION_3_3) {
2176                    ASSERT_TRUE(sessionV3_3.get() != nullptr);
2177                } else {
2178                    ASSERT_TRUE(sessionV3_3.get() == nullptr);
2179                }
2180                native_handle_t* raw_handle = native_handle_create(1, 0);
2181                raw_handle->data[0] = open(kDumpOutput, O_RDWR);
2182                ASSERT_GE(raw_handle->data[0], 0);
2183                hidl_handle handle = raw_handle;
2184                ret = device3_x->dumpState(handle);
2185                ASSERT_TRUE(ret.isOk());
2186                close(raw_handle->data[0]);
2187                native_handle_delete(raw_handle);
2188
2189                ret = session->close();
2190                ASSERT_TRUE(ret.isOk());
2191                // TODO: test all session API calls return INTERNAL_ERROR after close
2192                // TODO: keep a wp copy here and verify session cannot be promoted out of this scope
2193            }
2194            break;
2195            case CAMERA_DEVICE_API_VERSION_1_0: {
2196                sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
2197                openCameraDevice(name, mProvider, &device1 /*out*/);
2198                ASSERT_NE(nullptr, device1.get());
2199
2200                native_handle_t* raw_handle = native_handle_create(1, 0);
2201                raw_handle->data[0] = open(kDumpOutput, O_RDWR);
2202                ASSERT_GE(raw_handle->data[0], 0);
2203                hidl_handle handle = raw_handle;
2204                Return<Status> returnStatus = device1->dumpState(handle);
2205                ASSERT_TRUE(returnStatus.isOk());
2206                ASSERT_EQ(Status::OK, returnStatus);
2207                close(raw_handle->data[0]);
2208                native_handle_delete(raw_handle);
2209
2210                ret = device1->close();
2211                ASSERT_TRUE(ret.isOk());
2212            }
2213            break;
2214            default: {
2215                ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
2216                ADD_FAILURE();
2217            }
2218            break;
2219        }
2220    }
2221}
2222
2223// Check whether all common default request settings can be sucessfully
2224// constructed.
2225TEST_F(CameraHidlTest, constructDefaultRequestSettings) {
2226    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
2227
2228    for (const auto& name : cameraDeviceNames) {
2229        int deviceVersion = getCameraDeviceVersion(name, mProviderType);
2230        switch (deviceVersion) {
2231            case CAMERA_DEVICE_API_VERSION_3_4:
2232            case CAMERA_DEVICE_API_VERSION_3_3:
2233            case CAMERA_DEVICE_API_VERSION_3_2: {
2234                ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_x;
2235                Return<void> ret;
2236                ALOGI("constructDefaultRequestSettings: Testing camera device %s", name.c_str());
2237                ret = mProvider->getCameraDeviceInterface_V3_x(
2238                    name, [&](auto status, const auto& device) {
2239                        ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
2240                        ASSERT_EQ(Status::OK, status);
2241                        ASSERT_NE(device, nullptr);
2242                        device3_x = device;
2243                    });
2244                ASSERT_TRUE(ret.isOk());
2245
2246                sp<EmptyDeviceCb> cb = new EmptyDeviceCb;
2247                sp<ICameraDeviceSession> session;
2248                ret = device3_x->open(cb, [&](auto status, const auto& newSession) {
2249                    ALOGI("device::open returns status:%d", (int)status);
2250                    ASSERT_EQ(Status::OK, status);
2251                    ASSERT_NE(newSession, nullptr);
2252                    session = newSession;
2253                });
2254                ASSERT_TRUE(ret.isOk());
2255
2256                for (uint32_t t = (uint32_t)RequestTemplate::PREVIEW;
2257                     t <= (uint32_t)RequestTemplate::MANUAL; t++) {
2258                    RequestTemplate reqTemplate = (RequestTemplate)t;
2259                    ret =
2260                        session->constructDefaultRequestSettings(
2261                            reqTemplate, [&](auto status, const auto& req) {
2262                                ALOGI("constructDefaultRequestSettings returns status:%d",
2263                                      (int)status);
2264                                if (reqTemplate == RequestTemplate::ZERO_SHUTTER_LAG ||
2265                                        reqTemplate == RequestTemplate::MANUAL) {
2266                                    // optional templates
2267                                    ASSERT_TRUE((status == Status::OK) ||
2268                                            (status == Status::ILLEGAL_ARGUMENT));
2269                                } else {
2270                                    ASSERT_EQ(Status::OK, status);
2271                                }
2272
2273                                if (status == Status::OK) {
2274                                    const camera_metadata_t* metadata =
2275                                        (camera_metadata_t*) req.data();
2276                                    size_t expectedSize = req.size();
2277                                    int result = validate_camera_metadata_structure(
2278                                            metadata, &expectedSize);
2279                                    ASSERT_TRUE((result == 0) ||
2280                                            (result == CAMERA_METADATA_VALIDATION_SHIFTED));
2281                                    size_t entryCount =
2282                                            get_camera_metadata_entry_count(metadata);
2283                                    // TODO: we can do better than 0 here. Need to check how many required
2284                                    // request keys we've defined for each template
2285                                    ASSERT_GT(entryCount, 0u);
2286                                    ALOGI("template %u metadata entry count is %zu",
2287                                          t, entryCount);
2288                                } else {
2289                                    ASSERT_EQ(0u, req.size());
2290                                }
2291                            });
2292                    ASSERT_TRUE(ret.isOk());
2293                }
2294                ret = session->close();
2295                ASSERT_TRUE(ret.isOk());
2296            }
2297            break;
2298            case CAMERA_DEVICE_API_VERSION_1_0: {
2299                //Not applicable
2300            }
2301            break;
2302            default: {
2303                ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
2304                ADD_FAILURE();
2305            }
2306            break;
2307        }
2308    }
2309}
2310
2311
2312// Verify that all supported stream formats and sizes can be configured
2313// successfully.
2314TEST_F(CameraHidlTest, configureStreamsAvailableOutputs) {
2315    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
2316    std::vector<AvailableStream> outputStreams;
2317
2318    for (const auto& name : cameraDeviceNames) {
2319        int deviceVersion = getCameraDeviceVersion(name, mProviderType);
2320        if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) {
2321            continue;
2322        } else if (deviceVersion <= 0) {
2323            ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
2324            ADD_FAILURE();
2325            return;
2326        }
2327
2328        camera_metadata_t* staticMeta;
2329        Return<void> ret;
2330        sp<ICameraDeviceSession> session;
2331        sp<device::V3_3::ICameraDeviceSession> session3_3;
2332        sp<device::V3_4::ICameraDeviceSession> session3_4;
2333        openEmptyDeviceSession(name, mProvider,
2334                &session /*out*/, &staticMeta /*out*/);
2335        castSession(session, deviceVersion, &session3_3, &session3_4);
2336
2337        outputStreams.clear();
2338        ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta, outputStreams));
2339        ASSERT_NE(0u, outputStreams.size());
2340
2341        int32_t streamId = 0;
2342        for (auto& it : outputStreams) {
2343            Stream stream = {streamId,
2344                             StreamType::OUTPUT,
2345                             static_cast<uint32_t>(it.width),
2346                             static_cast<uint32_t>(it.height),
2347                             static_cast<PixelFormat>(it.format),
2348                             GRALLOC1_CONSUMER_USAGE_HWCOMPOSER,
2349                             0,
2350                             StreamRotation::ROTATION_0};
2351            ::android::hardware::hidl_vec<Stream> streams = {stream};
2352            ::android::hardware::camera::device::V3_4::StreamConfiguration config;
2353            config.v3_2 = {streams, StreamConfigurationMode::NORMAL_MODE};
2354            if (session3_4 != nullptr) {
2355                ret = session3_4->configureStreams_3_4(config,
2356                        [streamId](Status s, device::V3_3::HalStreamConfiguration halConfig) {
2357                            ASSERT_EQ(Status::OK, s);
2358                            ASSERT_EQ(1u, halConfig.streams.size());
2359                            ASSERT_EQ(halConfig.streams[0].v3_2.id, streamId);
2360                        });
2361            } else if (session3_3 != nullptr) {
2362                ret = session3_3->configureStreams_3_3(config.v3_2,
2363                        [streamId](Status s, device::V3_3::HalStreamConfiguration halConfig) {
2364                            ASSERT_EQ(Status::OK, s);
2365                            ASSERT_EQ(1u, halConfig.streams.size());
2366                            ASSERT_EQ(halConfig.streams[0].v3_2.id, streamId);
2367                        });
2368            } else {
2369                ret = session->configureStreams(config.v3_2,
2370                        [streamId](Status s, HalStreamConfiguration halConfig) {
2371                            ASSERT_EQ(Status::OK, s);
2372                            ASSERT_EQ(1u, halConfig.streams.size());
2373                            ASSERT_EQ(halConfig.streams[0].id, streamId);
2374                        });
2375            }
2376            ASSERT_TRUE(ret.isOk());
2377            streamId++;
2378        }
2379
2380        free_camera_metadata(staticMeta);
2381        ret = session->close();
2382        ASSERT_TRUE(ret.isOk());
2383    }
2384}
2385
2386// Check for correct handling of invalid/incorrect configuration parameters.
2387TEST_F(CameraHidlTest, configureStreamsInvalidOutputs) {
2388    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
2389    std::vector<AvailableStream> outputStreams;
2390
2391    for (const auto& name : cameraDeviceNames) {
2392        int deviceVersion = getCameraDeviceVersion(name, mProviderType);
2393        if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) {
2394            continue;
2395        } else if (deviceVersion <= 0) {
2396            ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
2397            ADD_FAILURE();
2398            return;
2399        }
2400
2401        camera_metadata_t* staticMeta;
2402        Return<void> ret;
2403        sp<ICameraDeviceSession> session;
2404        sp<device::V3_3::ICameraDeviceSession> session3_3;
2405        sp<device::V3_4::ICameraDeviceSession> session3_4;
2406        openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/);
2407        castSession(session, deviceVersion, &session3_3, &session3_4);
2408
2409        outputStreams.clear();
2410        ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta, outputStreams));
2411        ASSERT_NE(0u, outputStreams.size());
2412
2413        int32_t streamId = 0;
2414        Stream stream = {streamId++,
2415                         StreamType::OUTPUT,
2416                         static_cast<uint32_t>(0),
2417                         static_cast<uint32_t>(0),
2418                         static_cast<PixelFormat>(outputStreams[0].format),
2419                         GRALLOC1_CONSUMER_USAGE_HWCOMPOSER,
2420                         0,
2421                         StreamRotation::ROTATION_0};
2422        ::android::hardware::hidl_vec<Stream> streams = {stream};
2423        ::android::hardware::camera::device::V3_4::StreamConfiguration config;
2424        config.v3_2 = {streams, StreamConfigurationMode::NORMAL_MODE};
2425        if(session3_4 != nullptr) {
2426            ret = session3_4->configureStreams_3_4(config,
2427                [](Status s, device::V3_3::HalStreamConfiguration) {
2428                    ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) ||
2429                            (Status::INTERNAL_ERROR == s));
2430                });
2431        } else if(session3_3 != nullptr) {
2432            ret = session3_3->configureStreams_3_3(config.v3_2,
2433                [](Status s, device::V3_3::HalStreamConfiguration) {
2434                    ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) ||
2435                            (Status::INTERNAL_ERROR == s));
2436                });
2437        } else {
2438            ret = session->configureStreams(config.v3_2,
2439                [](Status s, HalStreamConfiguration) {
2440                    ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) ||
2441                            (Status::INTERNAL_ERROR == s));
2442                });
2443        }
2444        ASSERT_TRUE(ret.isOk());
2445
2446        stream = {streamId++,
2447                  StreamType::OUTPUT,
2448                  static_cast<uint32_t>(UINT32_MAX),
2449                  static_cast<uint32_t>(UINT32_MAX),
2450                  static_cast<PixelFormat>(outputStreams[0].format),
2451                  GRALLOC1_CONSUMER_USAGE_HWCOMPOSER,
2452                  0,
2453                  StreamRotation::ROTATION_0};
2454        streams[0] = stream;
2455        config.v3_2 = {streams, StreamConfigurationMode::NORMAL_MODE};
2456        if(session3_4 != nullptr) {
2457            ret = session3_4->configureStreams_3_4(config, [](Status s,
2458                        device::V3_3::HalStreamConfiguration) {
2459                    ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
2460                });
2461        } else if(session3_3 != nullptr) {
2462            ret = session3_3->configureStreams_3_3(config.v3_2, [](Status s,
2463                        device::V3_3::HalStreamConfiguration) {
2464                    ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
2465                });
2466        } else {
2467            ret = session->configureStreams(config.v3_2, [](Status s,
2468                        HalStreamConfiguration) {
2469                    ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
2470                });
2471        }
2472        ASSERT_TRUE(ret.isOk());
2473
2474        for (auto& it : outputStreams) {
2475            stream = {streamId++,
2476                      StreamType::OUTPUT,
2477                      static_cast<uint32_t>(it.width),
2478                      static_cast<uint32_t>(it.height),
2479                      static_cast<PixelFormat>(UINT32_MAX),
2480                      GRALLOC1_CONSUMER_USAGE_HWCOMPOSER,
2481                      0,
2482                      StreamRotation::ROTATION_0};
2483            streams[0] = stream;
2484            config.v3_2 = {streams, StreamConfigurationMode::NORMAL_MODE};
2485            if(session3_4 != nullptr) {
2486                ret = session3_4->configureStreams_3_4(config,
2487                        [](Status s, device::V3_3::HalStreamConfiguration) {
2488                            ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
2489                        });
2490            } else if(session3_3 != nullptr) {
2491                ret = session3_3->configureStreams_3_3(config.v3_2,
2492                        [](Status s, device::V3_3::HalStreamConfiguration) {
2493                            ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
2494                        });
2495            } else {
2496                ret = session->configureStreams(config.v3_2,
2497                        [](Status s, HalStreamConfiguration) {
2498                            ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
2499                        });
2500            }
2501            ASSERT_TRUE(ret.isOk());
2502
2503            stream = {streamId++,
2504                      StreamType::OUTPUT,
2505                      static_cast<uint32_t>(it.width),
2506                      static_cast<uint32_t>(it.height),
2507                      static_cast<PixelFormat>(it.format),
2508                      GRALLOC1_CONSUMER_USAGE_HWCOMPOSER,
2509                      0,
2510                      static_cast<StreamRotation>(UINT32_MAX)};
2511            streams[0] = stream;
2512            config.v3_2 = {streams, StreamConfigurationMode::NORMAL_MODE};
2513            if(session3_4 != nullptr) {
2514                ret = session3_4->configureStreams_3_4(config,
2515                        [](Status s, device::V3_3::HalStreamConfiguration) {
2516                            ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
2517                        });
2518            } else if(session3_3 != nullptr) {
2519                ret = session3_3->configureStreams_3_3(config.v3_2,
2520                        [](Status s, device::V3_3::HalStreamConfiguration) {
2521                            ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
2522                        });
2523            } else {
2524                ret = session->configureStreams(config.v3_2,
2525                        [](Status s, HalStreamConfiguration) {
2526                            ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
2527                        });
2528            }
2529            ASSERT_TRUE(ret.isOk());
2530        }
2531
2532        free_camera_metadata(staticMeta);
2533        ret = session->close();
2534        ASSERT_TRUE(ret.isOk());
2535    }
2536}
2537
2538// Check whether all supported ZSL output stream combinations can be
2539// configured successfully.
2540TEST_F(CameraHidlTest, configureStreamsZSLInputOutputs) {
2541    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
2542    std::vector<AvailableStream> inputStreams;
2543    std::vector<AvailableZSLInputOutput> inputOutputMap;
2544
2545    for (const auto& name : cameraDeviceNames) {
2546        int deviceVersion = getCameraDeviceVersion(name, mProviderType);
2547        if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) {
2548            continue;
2549        } else if (deviceVersion <= 0) {
2550            ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
2551            ADD_FAILURE();
2552            return;
2553        }
2554
2555        camera_metadata_t* staticMeta;
2556        Return<void> ret;
2557        sp<ICameraDeviceSession> session;
2558        sp<device::V3_3::ICameraDeviceSession> session3_3;
2559        sp<device::V3_4::ICameraDeviceSession> session3_4;
2560        openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/);
2561        castSession(session, deviceVersion, &session3_3, &session3_4);
2562
2563        Status rc = isZSLModeAvailable(staticMeta);
2564        if (Status::METHOD_NOT_SUPPORTED == rc) {
2565            ret = session->close();
2566            ASSERT_TRUE(ret.isOk());
2567            continue;
2568        }
2569        ASSERT_EQ(Status::OK, rc);
2570
2571        inputStreams.clear();
2572        ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta, inputStreams));
2573        ASSERT_NE(0u, inputStreams.size());
2574
2575        inputOutputMap.clear();
2576        ASSERT_EQ(Status::OK, getZSLInputOutputMap(staticMeta, inputOutputMap));
2577        ASSERT_NE(0u, inputOutputMap.size());
2578
2579        int32_t streamId = 0;
2580        for (auto& inputIter : inputOutputMap) {
2581            AvailableStream input;
2582            ASSERT_EQ(Status::OK, findLargestSize(inputStreams, inputIter.inputFormat,
2583                    input));
2584            ASSERT_NE(0u, inputStreams.size());
2585
2586            AvailableStream outputThreshold = {INT32_MAX, INT32_MAX,
2587                                               inputIter.outputFormat};
2588            std::vector<AvailableStream> outputStreams;
2589            ASSERT_EQ(Status::OK,
2590                      getAvailableOutputStreams(staticMeta, outputStreams,
2591                              &outputThreshold));
2592            for (auto& outputIter : outputStreams) {
2593                Stream zslStream = {streamId++,
2594                                    StreamType::OUTPUT,
2595                                    static_cast<uint32_t>(input.width),
2596                                    static_cast<uint32_t>(input.height),
2597                                    static_cast<PixelFormat>(input.format),
2598                                    GRALLOC_USAGE_HW_CAMERA_ZSL,
2599                                    0,
2600                                    StreamRotation::ROTATION_0};
2601                Stream inputStream = {streamId++,
2602                                      StreamType::INPUT,
2603                                      static_cast<uint32_t>(input.width),
2604                                      static_cast<uint32_t>(input.height),
2605                                      static_cast<PixelFormat>(input.format),
2606                                      0,
2607                                      0,
2608                                      StreamRotation::ROTATION_0};
2609                Stream outputStream = {streamId++,
2610                                       StreamType::OUTPUT,
2611                                       static_cast<uint32_t>(outputIter.width),
2612                                       static_cast<uint32_t>(outputIter.height),
2613                                       static_cast<PixelFormat>(outputIter.format),
2614                                       GRALLOC1_CONSUMER_USAGE_HWCOMPOSER,
2615                                       0,
2616                                       StreamRotation::ROTATION_0};
2617
2618                ::android::hardware::hidl_vec<Stream> streams = {inputStream, zslStream,
2619                                                                 outputStream};
2620                ::android::hardware::camera::device::V3_4::StreamConfiguration config;
2621                config.v3_2 = {streams, StreamConfigurationMode::NORMAL_MODE};
2622                if (session3_4 != nullptr) {
2623                    ret = session3_4->configureStreams_3_4(config,
2624                            [](Status s, device::V3_3::HalStreamConfiguration halConfig) {
2625                                ASSERT_EQ(Status::OK, s);
2626                                ASSERT_EQ(3u, halConfig.streams.size());
2627                            });
2628                } else if (session3_3 != nullptr) {
2629                    ret = session3_3->configureStreams_3_3(config.v3_2,
2630                            [](Status s, device::V3_3::HalStreamConfiguration halConfig) {
2631                                ASSERT_EQ(Status::OK, s);
2632                                ASSERT_EQ(3u, halConfig.streams.size());
2633                            });
2634                } else {
2635                    ret = session->configureStreams(config.v3_2,
2636                            [](Status s, HalStreamConfiguration halConfig) {
2637                                ASSERT_EQ(Status::OK, s);
2638                                ASSERT_EQ(3u, halConfig.streams.size());
2639                            });
2640                }
2641                ASSERT_TRUE(ret.isOk());
2642            }
2643        }
2644
2645        free_camera_metadata(staticMeta);
2646        ret = session->close();
2647        ASSERT_TRUE(ret.isOk());
2648    }
2649}
2650
2651// Check wehether session parameters are supported. If Hal support for them
2652// exist, then try to configure a preview stream using them.
2653TEST_F(CameraHidlTest, configureStreamsWithSessionParameters) {
2654    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
2655    std::vector<AvailableStream> outputPreviewStreams;
2656    AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
2657                                        static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
2658
2659    for (const auto& name : cameraDeviceNames) {
2660        int deviceVersion = getCameraDeviceVersion(name, mProviderType);
2661        if (deviceVersion <= 0) {
2662            ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
2663            ADD_FAILURE();
2664            return;
2665        } else if (deviceVersion < CAMERA_DEVICE_API_VERSION_3_4) {
2666            continue;
2667        }
2668
2669        camera_metadata_t* staticMetaBuffer;
2670        Return<void> ret;
2671        sp<ICameraDeviceSession> session;
2672        sp<device::V3_3::ICameraDeviceSession> session3_3;
2673        sp<device::V3_4::ICameraDeviceSession> session3_4;
2674        openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMetaBuffer /*out*/);
2675        castSession(session, deviceVersion, &session3_3, &session3_4);
2676        ASSERT_NE(session3_4, nullptr);
2677
2678        const android::hardware::camera::common::V1_0::helper::CameraMetadata staticMeta(
2679                staticMetaBuffer);
2680        camera_metadata_ro_entry availableSessionKeys = staticMeta.find(
2681                ANDROID_REQUEST_AVAILABLE_SESSION_KEYS);
2682        if (availableSessionKeys.count == 0) {
2683            ret = session->close();
2684            ASSERT_TRUE(ret.isOk());
2685            continue;
2686        }
2687
2688        android::hardware::camera::common::V1_0::helper::CameraMetadata previewRequestSettings;
2689        ret = session->constructDefaultRequestSettings(RequestTemplate::PREVIEW,
2690                [&previewRequestSettings] (auto status, const auto& req) mutable {
2691                    ASSERT_EQ(Status::OK, status);
2692
2693                    const camera_metadata_t *metadata = reinterpret_cast<const camera_metadata_t*> (
2694                            req.data());
2695                    size_t expectedSize = req.size();
2696                    int result = validate_camera_metadata_structure(metadata, &expectedSize);
2697                    ASSERT_TRUE((result == 0) || (result == CAMERA_METADATA_VALIDATION_SHIFTED));
2698
2699                    size_t entryCount = get_camera_metadata_entry_count(metadata);
2700                    ASSERT_GT(entryCount, 0u);
2701                    previewRequestSettings = metadata;
2702                    });
2703        ASSERT_TRUE(ret.isOk());
2704        const android::hardware::camera::common::V1_0::helper::CameraMetadata &constSettings =
2705            previewRequestSettings;
2706        android::hardware::camera::common::V1_0::helper::CameraMetadata sessionParams;
2707        for (size_t i = 0; i < availableSessionKeys.count; i++) {
2708            camera_metadata_ro_entry entry = constSettings.find(availableSessionKeys.data.i32[i]);
2709            if (entry.count > 0) {
2710                sessionParams.update(entry);
2711            }
2712        }
2713        if (sessionParams.isEmpty()) {
2714            ret = session->close();
2715            ASSERT_TRUE(ret.isOk());
2716            continue;
2717        }
2718
2719        ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMetaBuffer, outputPreviewStreams,
2720                &previewThreshold));
2721        ASSERT_NE(0u, outputPreviewStreams.size());
2722
2723        Stream previewStream = {0,
2724                                StreamType::OUTPUT,
2725                                static_cast<uint32_t>(outputPreviewStreams[0].width),
2726                                static_cast<uint32_t>(outputPreviewStreams[0].height),
2727                                static_cast<PixelFormat>(outputPreviewStreams[0].format),
2728                                GRALLOC1_CONSUMER_USAGE_HWCOMPOSER,
2729                                0,
2730                                StreamRotation::ROTATION_0};
2731        ::android::hardware::hidl_vec<Stream> streams = {previewStream};
2732        ::android::hardware::camera::device::V3_4::StreamConfiguration config;
2733        config.v3_2 = {streams, StreamConfigurationMode::NORMAL_MODE};
2734        const camera_metadata_t *sessionParamsBuffer = sessionParams.getAndLock();
2735        config.sessionParams.setToExternal(
2736                reinterpret_cast<uint8_t *> (const_cast<camera_metadata_t *> (sessionParamsBuffer)),
2737                get_camera_metadata_size(sessionParamsBuffer));
2738        ret = session3_4->configureStreams_3_4(config,
2739                [](Status s, device::V3_3::HalStreamConfiguration halConfig) {
2740                    ASSERT_EQ(Status::OK, s);
2741                    ASSERT_EQ(1u, halConfig.streams.size());
2742                });
2743        ASSERT_TRUE(ret.isOk());
2744
2745        sessionParams.unlock(sessionParamsBuffer);
2746        ret = session->close();
2747        ASSERT_TRUE(ret.isOk());
2748    }
2749}
2750
2751// Verify that all supported preview + still capture stream combinations
2752// can be configured successfully.
2753TEST_F(CameraHidlTest, configureStreamsPreviewStillOutputs) {
2754    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
2755    std::vector<AvailableStream> outputBlobStreams;
2756    std::vector<AvailableStream> outputPreviewStreams;
2757    AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
2758                                        static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
2759    AvailableStream blobThreshold = {INT32_MAX, INT32_MAX,
2760                                     static_cast<int32_t>(PixelFormat::BLOB)};
2761
2762    for (const auto& name : cameraDeviceNames) {
2763        int deviceVersion = getCameraDeviceVersion(name, mProviderType);
2764        if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) {
2765            continue;
2766        } else if (deviceVersion <= 0) {
2767            ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
2768            ADD_FAILURE();
2769            return;
2770        }
2771
2772        camera_metadata_t* staticMeta;
2773        Return<void> ret;
2774        sp<ICameraDeviceSession> session;
2775        sp<device::V3_3::ICameraDeviceSession> session3_3;
2776        sp<device::V3_4::ICameraDeviceSession> session3_4;
2777        openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/);
2778        castSession(session, deviceVersion, &session3_3, &session3_4);
2779
2780        outputBlobStreams.clear();
2781        ASSERT_EQ(Status::OK,
2782                  getAvailableOutputStreams(staticMeta, outputBlobStreams,
2783                          &blobThreshold));
2784        ASSERT_NE(0u, outputBlobStreams.size());
2785
2786        outputPreviewStreams.clear();
2787        ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta, outputPreviewStreams,
2788                &previewThreshold));
2789        ASSERT_NE(0u, outputPreviewStreams.size());
2790
2791        int32_t streamId = 0;
2792        for (auto& blobIter : outputBlobStreams) {
2793            for (auto& previewIter : outputPreviewStreams) {
2794                Stream previewStream = {streamId++,
2795                                        StreamType::OUTPUT,
2796                                        static_cast<uint32_t>(previewIter.width),
2797                                        static_cast<uint32_t>(previewIter.height),
2798                                        static_cast<PixelFormat>(previewIter.format),
2799                                        GRALLOC1_CONSUMER_USAGE_HWCOMPOSER,
2800                                        0,
2801                                        StreamRotation::ROTATION_0};
2802                Stream blobStream = {streamId++,
2803                                     StreamType::OUTPUT,
2804                                     static_cast<uint32_t>(blobIter.width),
2805                                     static_cast<uint32_t>(blobIter.height),
2806                                     static_cast<PixelFormat>(blobIter.format),
2807                                     GRALLOC1_CONSUMER_USAGE_CPU_READ,
2808                                     0,
2809                                     StreamRotation::ROTATION_0};
2810                ::android::hardware::hidl_vec<Stream> streams = {previewStream,
2811                                                                 blobStream};
2812                ::android::hardware::camera::device::V3_4::StreamConfiguration config;
2813                config.v3_2 = {streams, StreamConfigurationMode::NORMAL_MODE};
2814                if (session3_4 != nullptr) {
2815                    ret = session3_4->configureStreams_3_4(config,
2816                            [](Status s, device::V3_3::HalStreamConfiguration halConfig) {
2817                                ASSERT_EQ(Status::OK, s);
2818                                ASSERT_EQ(2u, halConfig.streams.size());
2819                            });
2820                } else if (session3_3 != nullptr) {
2821                    ret = session3_3->configureStreams_3_3(config.v3_2,
2822                            [](Status s, device::V3_3::HalStreamConfiguration halConfig) {
2823                                ASSERT_EQ(Status::OK, s);
2824                                ASSERT_EQ(2u, halConfig.streams.size());
2825                            });
2826                } else {
2827                    ret = session->configureStreams(config.v3_2,
2828                            [](Status s, HalStreamConfiguration halConfig) {
2829                                ASSERT_EQ(Status::OK, s);
2830                                ASSERT_EQ(2u, halConfig.streams.size());
2831                            });
2832                }
2833                ASSERT_TRUE(ret.isOk());
2834            }
2835        }
2836
2837        free_camera_metadata(staticMeta);
2838        ret = session->close();
2839        ASSERT_TRUE(ret.isOk());
2840    }
2841}
2842
2843// In case constrained mode is supported, test whether it can be
2844// configured. Additionally check for common invalid inputs when
2845// using this mode.
2846TEST_F(CameraHidlTest, configureStreamsConstrainedOutputs) {
2847    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
2848
2849    for (const auto& name : cameraDeviceNames) {
2850        int deviceVersion = getCameraDeviceVersion(name, mProviderType);
2851        if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) {
2852            continue;
2853        } else if (deviceVersion <= 0) {
2854            ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
2855            ADD_FAILURE();
2856            return;
2857        }
2858
2859        camera_metadata_t* staticMeta;
2860        Return<void> ret;
2861        sp<ICameraDeviceSession> session;
2862        sp<device::V3_3::ICameraDeviceSession> session3_3;
2863        sp<device::V3_4::ICameraDeviceSession> session3_4;
2864        openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/);
2865        castSession(session, deviceVersion, &session3_3, &session3_4);
2866
2867        Status rc = isConstrainedModeAvailable(staticMeta);
2868        if (Status::METHOD_NOT_SUPPORTED == rc) {
2869            ret = session->close();
2870            ASSERT_TRUE(ret.isOk());
2871            continue;
2872        }
2873        ASSERT_EQ(Status::OK, rc);
2874
2875        AvailableStream hfrStream;
2876        rc = pickConstrainedModeSize(staticMeta, hfrStream);
2877        ASSERT_EQ(Status::OK, rc);
2878
2879        int32_t streamId = 0;
2880        Stream stream = {streamId,
2881                         StreamType::OUTPUT,
2882                         static_cast<uint32_t>(hfrStream.width),
2883                         static_cast<uint32_t>(hfrStream.height),
2884                         static_cast<PixelFormat>(hfrStream.format),
2885                         GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER,
2886                         0,
2887                         StreamRotation::ROTATION_0};
2888        ::android::hardware::hidl_vec<Stream> streams = {stream};
2889        ::android::hardware::camera::device::V3_4::StreamConfiguration config;
2890        config.v3_2 = {streams, StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE};
2891        if (session3_4 != nullptr) {
2892            ret = session3_4->configureStreams_3_4(config,
2893                    [streamId](Status s, device::V3_3::HalStreamConfiguration halConfig) {
2894                        ASSERT_EQ(Status::OK, s);
2895                        ASSERT_EQ(1u, halConfig.streams.size());
2896                        ASSERT_EQ(halConfig.streams[0].v3_2.id, streamId);
2897                    });
2898        } else if (session3_3 != nullptr) {
2899            ret = session3_3->configureStreams_3_3(config.v3_2,
2900                    [streamId](Status s, device::V3_3::HalStreamConfiguration halConfig) {
2901                        ASSERT_EQ(Status::OK, s);
2902                        ASSERT_EQ(1u, halConfig.streams.size());
2903                        ASSERT_EQ(halConfig.streams[0].v3_2.id, streamId);
2904                    });
2905        } else {
2906            ret = session->configureStreams(config.v3_2,
2907                    [streamId](Status s, HalStreamConfiguration halConfig) {
2908                        ASSERT_EQ(Status::OK, s);
2909                        ASSERT_EQ(1u, halConfig.streams.size());
2910                        ASSERT_EQ(halConfig.streams[0].id, streamId);
2911                    });
2912        }
2913        ASSERT_TRUE(ret.isOk());
2914
2915        stream = {streamId++,
2916                  StreamType::OUTPUT,
2917                  static_cast<uint32_t>(0),
2918                  static_cast<uint32_t>(0),
2919                  static_cast<PixelFormat>(hfrStream.format),
2920                  GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER,
2921                  0,
2922                  StreamRotation::ROTATION_0};
2923        streams[0] = stream;
2924        config.v3_2 = {streams, StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE};
2925        if (session3_4 != nullptr) {
2926            ret = session3_4->configureStreams_3_4(config,
2927                    [](Status s, device::V3_3::HalStreamConfiguration) {
2928                        ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) ||
2929                                (Status::INTERNAL_ERROR == s));
2930                    });
2931        } else if (session3_3 != nullptr) {
2932            ret = session3_3->configureStreams_3_3(config.v3_2,
2933                    [](Status s, device::V3_3::HalStreamConfiguration) {
2934                        ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) ||
2935                                (Status::INTERNAL_ERROR == s));
2936                    });
2937        } else {
2938            ret = session->configureStreams(config.v3_2,
2939                    [](Status s, HalStreamConfiguration) {
2940                        ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) ||
2941                                (Status::INTERNAL_ERROR == s));
2942                    });
2943        }
2944        ASSERT_TRUE(ret.isOk());
2945
2946        stream = {streamId++,
2947                  StreamType::OUTPUT,
2948                  static_cast<uint32_t>(UINT32_MAX),
2949                  static_cast<uint32_t>(UINT32_MAX),
2950                  static_cast<PixelFormat>(hfrStream.format),
2951                  GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER,
2952                  0,
2953                  StreamRotation::ROTATION_0};
2954        streams[0] = stream;
2955        config.v3_2 = {streams, StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE};
2956        if (session3_4 != nullptr) {
2957            ret = session3_4->configureStreams_3_4(config,
2958                    [](Status s, device::V3_3::HalStreamConfiguration) {
2959                        ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
2960                    });
2961        } else if (session3_3 != nullptr) {
2962            ret = session3_3->configureStreams_3_3(config.v3_2,
2963                    [](Status s, device::V3_3::HalStreamConfiguration) {
2964                        ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
2965                    });
2966        } else {
2967            ret = session->configureStreams(config.v3_2,
2968                    [](Status s, HalStreamConfiguration) {
2969                        ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
2970                    });
2971        }
2972        ASSERT_TRUE(ret.isOk());
2973
2974        stream = {streamId++,
2975                  StreamType::OUTPUT,
2976                  static_cast<uint32_t>(hfrStream.width),
2977                  static_cast<uint32_t>(hfrStream.height),
2978                  static_cast<PixelFormat>(UINT32_MAX),
2979                  GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER,
2980                  0,
2981                  StreamRotation::ROTATION_0};
2982        streams[0] = stream;
2983        config.v3_2 = {streams, StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE};
2984        if (session3_4 != nullptr) {
2985            ret = session3_4->configureStreams_3_4(config,
2986                    [](Status s, device::V3_3::HalStreamConfiguration) {
2987                        ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
2988                    });
2989        } else if (session3_3 != nullptr) {
2990            ret = session3_3->configureStreams_3_3(config.v3_2,
2991                    [](Status s, device::V3_3::HalStreamConfiguration) {
2992                        ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
2993                    });
2994        } else {
2995            ret = session->configureStreams(config.v3_2,
2996                    [](Status s, HalStreamConfiguration) {
2997                        ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
2998                    });
2999        }
3000        ASSERT_TRUE(ret.isOk());
3001
3002        free_camera_metadata(staticMeta);
3003        ret = session->close();
3004        ASSERT_TRUE(ret.isOk());
3005    }
3006}
3007
3008// Verify that all supported video + snapshot stream combinations can
3009// be configured successfully.
3010TEST_F(CameraHidlTest, configureStreamsVideoStillOutputs) {
3011    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
3012    std::vector<AvailableStream> outputBlobStreams;
3013    std::vector<AvailableStream> outputVideoStreams;
3014    AvailableStream videoThreshold = {kMaxVideoWidth, kMaxVideoHeight,
3015                                      static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
3016    AvailableStream blobThreshold = {kMaxVideoWidth, kMaxVideoHeight,
3017                                     static_cast<int32_t>(PixelFormat::BLOB)};
3018
3019    for (const auto& name : cameraDeviceNames) {
3020        int deviceVersion = getCameraDeviceVersion(name, mProviderType);
3021        if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) {
3022            continue;
3023        } else if (deviceVersion <= 0) {
3024            ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
3025            ADD_FAILURE();
3026            return;
3027        }
3028
3029        camera_metadata_t* staticMeta;
3030        Return<void> ret;
3031        sp<ICameraDeviceSession> session;
3032        sp<device::V3_3::ICameraDeviceSession> session3_3;
3033        sp<device::V3_4::ICameraDeviceSession> session3_4;
3034        openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/);
3035        castSession(session, deviceVersion, &session3_3, &session3_4);
3036
3037        outputBlobStreams.clear();
3038        ASSERT_EQ(Status::OK,
3039                  getAvailableOutputStreams(staticMeta, outputBlobStreams,
3040                          &blobThreshold));
3041        ASSERT_NE(0u, outputBlobStreams.size());
3042
3043        outputVideoStreams.clear();
3044        ASSERT_EQ(Status::OK,
3045                  getAvailableOutputStreams(staticMeta, outputVideoStreams,
3046                          &videoThreshold));
3047        ASSERT_NE(0u, outputVideoStreams.size());
3048
3049        int32_t streamId = 0;
3050        for (auto& blobIter : outputBlobStreams) {
3051            for (auto& videoIter : outputVideoStreams) {
3052                Stream videoStream = {streamId++,
3053                                      StreamType::OUTPUT,
3054                                      static_cast<uint32_t>(videoIter.width),
3055                                      static_cast<uint32_t>(videoIter.height),
3056                                      static_cast<PixelFormat>(videoIter.format),
3057                                      GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER,
3058                                      0,
3059                                      StreamRotation::ROTATION_0};
3060                Stream blobStream = {streamId++,
3061                                     StreamType::OUTPUT,
3062                                     static_cast<uint32_t>(blobIter.width),
3063                                     static_cast<uint32_t>(blobIter.height),
3064                                     static_cast<PixelFormat>(blobIter.format),
3065                                     GRALLOC1_CONSUMER_USAGE_CPU_READ,
3066                                     0,
3067                                     StreamRotation::ROTATION_0};
3068                ::android::hardware::hidl_vec<Stream> streams = {videoStream, blobStream};
3069                ::android::hardware::camera::device::V3_4::StreamConfiguration config;
3070                config.v3_2 = {streams, StreamConfigurationMode::NORMAL_MODE};
3071                if (session3_4 != nullptr) {
3072                    ret = session3_4->configureStreams_3_4(config,
3073                            [](Status s, device::V3_3::HalStreamConfiguration halConfig) {
3074                                ASSERT_EQ(Status::OK, s);
3075                                ASSERT_EQ(2u, halConfig.streams.size());
3076                            });
3077                } else if (session3_3 != nullptr) {
3078                    ret = session3_3->configureStreams_3_3(config.v3_2,
3079                            [](Status s, device::V3_3::HalStreamConfiguration halConfig) {
3080                                ASSERT_EQ(Status::OK, s);
3081                                ASSERT_EQ(2u, halConfig.streams.size());
3082                            });
3083                } else {
3084                    ret = session->configureStreams(config.v3_2,
3085                            [](Status s, HalStreamConfiguration halConfig) {
3086                                ASSERT_EQ(Status::OK, s);
3087                                ASSERT_EQ(2u, halConfig.streams.size());
3088                            });
3089                }
3090                ASSERT_TRUE(ret.isOk());
3091            }
3092        }
3093
3094        free_camera_metadata(staticMeta);
3095        ret = session->close();
3096        ASSERT_TRUE(ret.isOk());
3097    }
3098}
3099
3100// Generate and verify a camera capture request
3101TEST_F(CameraHidlTest, processCaptureRequestPreview) {
3102    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
3103    AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
3104                                        static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
3105    uint64_t bufferId = 1;
3106    uint32_t frameNumber = 1;
3107    ::android::hardware::hidl_vec<uint8_t> settings;
3108
3109    for (const auto& name : cameraDeviceNames) {
3110        int deviceVersion = getCameraDeviceVersion(name, mProviderType);
3111        if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) {
3112            continue;
3113        } else if (deviceVersion <= 0) {
3114            ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
3115            ADD_FAILURE();
3116            return;
3117        }
3118
3119        Stream previewStream;
3120        HalStreamConfiguration halStreamConfig;
3121        sp<ICameraDeviceSession> session;
3122        bool supportsPartialResults = false;
3123        uint32_t partialResultCount = 0;
3124        configurePreviewStream(name, deviceVersion, mProvider, &previewThreshold, &session /*out*/,
3125                &previewStream /*out*/, &halStreamConfig /*out*/,
3126                &supportsPartialResults /*out*/,
3127                &partialResultCount /*out*/);
3128
3129        std::shared_ptr<ResultMetadataQueue> resultQueue;
3130        auto resultQueueRet =
3131            session->getCaptureResultMetadataQueue(
3132                [&resultQueue](const auto& descriptor) {
3133                    resultQueue = std::make_shared<ResultMetadataQueue>(
3134                            descriptor);
3135                    if (!resultQueue->isValid() ||
3136                            resultQueue->availableToWrite() <= 0) {
3137                        ALOGE("%s: HAL returns empty result metadata fmq,"
3138                                " not use it", __func__);
3139                        resultQueue = nullptr;
3140                        // Don't use the queue onwards.
3141                    }
3142                });
3143        ASSERT_TRUE(resultQueueRet.isOk());
3144
3145        InFlightRequest inflightReq = {1, false, supportsPartialResults,
3146                                       partialResultCount, resultQueue};
3147
3148        RequestTemplate reqTemplate = RequestTemplate::PREVIEW;
3149        Return<void> ret;
3150        ret = session->constructDefaultRequestSettings(reqTemplate,
3151                                                       [&](auto status, const auto& req) {
3152                                                           ASSERT_EQ(Status::OK, status);
3153                                                           settings = req;
3154                                                       });
3155        ASSERT_TRUE(ret.isOk());
3156
3157        sp<GraphicBuffer> gb = new GraphicBuffer(
3158            previewStream.width, previewStream.height,
3159            static_cast<int32_t>(halStreamConfig.streams[0].overrideFormat), 1,
3160            android_convertGralloc1To0Usage(halStreamConfig.streams[0].producerUsage,
3161                                            halStreamConfig.streams[0].consumerUsage));
3162        ASSERT_NE(nullptr, gb.get());
3163        StreamBuffer outputBuffer = {halStreamConfig.streams[0].id,
3164                                     bufferId,
3165                                     hidl_handle(gb->getNativeBuffer()->handle),
3166                                     BufferStatus::OK,
3167                                     nullptr,
3168                                     nullptr};
3169        ::android::hardware::hidl_vec<StreamBuffer> outputBuffers = {outputBuffer};
3170        StreamBuffer emptyInputBuffer = {-1, 0, nullptr, BufferStatus::ERROR, nullptr,
3171                                         nullptr};
3172        CaptureRequest request = {frameNumber, 0 /* fmqSettingsSize */, settings,
3173                                  emptyInputBuffer, outputBuffers};
3174
3175        {
3176            std::unique_lock<std::mutex> l(mLock);
3177            mInflightMap.clear();
3178            mInflightMap.add(frameNumber, &inflightReq);
3179        }
3180
3181        Status status = Status::INTERNAL_ERROR;
3182        uint32_t numRequestProcessed = 0;
3183        hidl_vec<BufferCache> cachesToRemove;
3184        Return<void> returnStatus = session->processCaptureRequest(
3185            {request}, cachesToRemove, [&status, &numRequestProcessed](auto s,
3186                    uint32_t n) {
3187                status = s;
3188                numRequestProcessed = n;
3189            });
3190        ASSERT_TRUE(returnStatus.isOk());
3191        ASSERT_EQ(Status::OK, status);
3192        ASSERT_EQ(numRequestProcessed, 1u);
3193
3194        {
3195            std::unique_lock<std::mutex> l(mLock);
3196            while (!inflightReq.errorCodeValid &&
3197                   ((0 < inflightReq.numBuffersLeft) ||
3198                           (!inflightReq.haveResultMetadata))) {
3199                auto timeout = std::chrono::system_clock::now() +
3200                               std::chrono::seconds(kStreamBufferTimeoutSec);
3201                ASSERT_NE(std::cv_status::timeout,
3202                        mResultCondition.wait_until(l, timeout));
3203            }
3204
3205            ASSERT_FALSE(inflightReq.errorCodeValid);
3206            ASSERT_NE(inflightReq.resultOutputBuffers.size(), 0u);
3207            ASSERT_EQ(previewStream.id, inflightReq.resultOutputBuffers[0].streamId);
3208
3209            request.frameNumber++;
3210            // Empty settings should be supported after the first call
3211            // for repeating requests.
3212            request.settings.setToExternal(nullptr, 0, true);
3213            // The buffer has been registered to HAL by bufferId, so per
3214            // API contract we should send a null handle for this buffer
3215            request.outputBuffers[0].buffer = nullptr;
3216            mInflightMap.clear();
3217            inflightReq = {1, false, supportsPartialResults, partialResultCount,
3218                           resultQueue};
3219            mInflightMap.add(request.frameNumber, &inflightReq);
3220        }
3221
3222        returnStatus = session->processCaptureRequest(
3223            {request}, cachesToRemove, [&status, &numRequestProcessed](auto s,
3224                    uint32_t n) {
3225                status = s;
3226                numRequestProcessed = n;
3227            });
3228        ASSERT_TRUE(returnStatus.isOk());
3229        ASSERT_EQ(Status::OK, status);
3230        ASSERT_EQ(numRequestProcessed, 1u);
3231
3232        {
3233            std::unique_lock<std::mutex> l(mLock);
3234            while (!inflightReq.errorCodeValid &&
3235                   ((0 < inflightReq.numBuffersLeft) ||
3236                           (!inflightReq.haveResultMetadata))) {
3237                auto timeout = std::chrono::system_clock::now() +
3238                               std::chrono::seconds(kStreamBufferTimeoutSec);
3239                ASSERT_NE(std::cv_status::timeout,
3240                        mResultCondition.wait_until(l, timeout));
3241            }
3242
3243            ASSERT_FALSE(inflightReq.errorCodeValid);
3244            ASSERT_NE(inflightReq.resultOutputBuffers.size(), 0u);
3245            ASSERT_EQ(previewStream.id, inflightReq.resultOutputBuffers[0].streamId);
3246        }
3247
3248        ret = session->close();
3249        ASSERT_TRUE(ret.isOk());
3250    }
3251}
3252
3253// Test whether an incorrect capture request with missing settings will
3254// be reported correctly.
3255TEST_F(CameraHidlTest, processCaptureRequestInvalidSinglePreview) {
3256    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
3257    std::vector<AvailableStream> outputPreviewStreams;
3258    AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
3259                                        static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
3260    uint64_t bufferId = 1;
3261    uint32_t frameNumber = 1;
3262    ::android::hardware::hidl_vec<uint8_t> settings;
3263
3264    for (const auto& name : cameraDeviceNames) {
3265        int deviceVersion = getCameraDeviceVersion(name, mProviderType);
3266        if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) {
3267            continue;
3268        } else if (deviceVersion <= 0) {
3269            ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
3270            ADD_FAILURE();
3271            return;
3272        }
3273
3274        Stream previewStream;
3275        HalStreamConfiguration halStreamConfig;
3276        sp<ICameraDeviceSession> session;
3277        bool supportsPartialResults = false;
3278        uint32_t partialResultCount = 0;
3279        configurePreviewStream(name, deviceVersion, mProvider, &previewThreshold, &session /*out*/,
3280                &previewStream /*out*/, &halStreamConfig /*out*/,
3281                &supportsPartialResults /*out*/,
3282                &partialResultCount /*out*/);
3283
3284        sp<GraphicBuffer> gb = new GraphicBuffer(
3285            previewStream.width, previewStream.height,
3286            static_cast<int32_t>(halStreamConfig.streams[0].overrideFormat), 1,
3287            android_convertGralloc1To0Usage(halStreamConfig.streams[0].producerUsage,
3288                                            halStreamConfig.streams[0].consumerUsage));
3289
3290        StreamBuffer outputBuffer = {halStreamConfig.streams[0].id,
3291                                     bufferId,
3292                                     hidl_handle(gb->getNativeBuffer()->handle),
3293                                     BufferStatus::OK,
3294                                     nullptr,
3295                                     nullptr};
3296        ::android::hardware::hidl_vec<StreamBuffer> outputBuffers = {outputBuffer};
3297        StreamBuffer emptyInputBuffer = {-1, 0, nullptr, BufferStatus::ERROR, nullptr,
3298                                         nullptr};
3299        CaptureRequest request = {frameNumber, 0 /* fmqSettingsSize */, settings,
3300                                  emptyInputBuffer, outputBuffers};
3301
3302        // Settings were not correctly initialized, we should fail here
3303        Status status = Status::OK;
3304        uint32_t numRequestProcessed = 0;
3305        hidl_vec<BufferCache> cachesToRemove;
3306        Return<void> ret = session->processCaptureRequest(
3307            {request}, cachesToRemove, [&status, &numRequestProcessed](auto s,
3308                    uint32_t n) {
3309                status = s;
3310                numRequestProcessed = n;
3311            });
3312        ASSERT_TRUE(ret.isOk());
3313        ASSERT_EQ(Status::ILLEGAL_ARGUMENT, status);
3314        ASSERT_EQ(numRequestProcessed, 0u);
3315
3316        ret = session->close();
3317        ASSERT_TRUE(ret.isOk());
3318    }
3319}
3320
3321// Check whether an invalid capture request with missing output buffers
3322// will be reported correctly.
3323TEST_F(CameraHidlTest, processCaptureRequestInvalidBuffer) {
3324    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
3325    std::vector<AvailableStream> outputBlobStreams;
3326    AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
3327                                        static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
3328    uint32_t frameNumber = 1;
3329    ::android::hardware::hidl_vec<uint8_t> settings;
3330
3331    for (const auto& name : cameraDeviceNames) {
3332        int deviceVersion = getCameraDeviceVersion(name, mProviderType);
3333        if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) {
3334            continue;
3335        } else if (deviceVersion <= 0) {
3336            ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
3337            ADD_FAILURE();
3338            return;
3339        }
3340
3341        Stream previewStream;
3342        HalStreamConfiguration halStreamConfig;
3343        sp<ICameraDeviceSession> session;
3344        bool supportsPartialResults = false;
3345        uint32_t partialResultCount = 0;
3346        configurePreviewStream(name, deviceVersion, mProvider, &previewThreshold, &session /*out*/,
3347                &previewStream /*out*/, &halStreamConfig /*out*/,
3348                &supportsPartialResults /*out*/,
3349                &partialResultCount /*out*/);
3350
3351        RequestTemplate reqTemplate = RequestTemplate::PREVIEW;
3352        Return<void> ret;
3353        ret = session->constructDefaultRequestSettings(reqTemplate,
3354                                                       [&](auto status, const auto& req) {
3355                                                           ASSERT_EQ(Status::OK, status);
3356                                                           settings = req;
3357                                                       });
3358        ASSERT_TRUE(ret.isOk());
3359
3360        ::android::hardware::hidl_vec<StreamBuffer> emptyOutputBuffers;
3361        StreamBuffer emptyInputBuffer = {-1, 0, nullptr, BufferStatus::ERROR, nullptr,
3362                                         nullptr};
3363        CaptureRequest request = {frameNumber, 0 /* fmqSettingsSize */, settings,
3364                                  emptyInputBuffer, emptyOutputBuffers};
3365
3366        // Output buffers are missing, we should fail here
3367        Status status = Status::OK;
3368        uint32_t numRequestProcessed = 0;
3369        hidl_vec<BufferCache> cachesToRemove;
3370        ret = session->processCaptureRequest(
3371            {request}, cachesToRemove, [&status, &numRequestProcessed](auto s,
3372                    uint32_t n) {
3373                status = s;
3374                numRequestProcessed = n;
3375            });
3376        ASSERT_TRUE(ret.isOk());
3377        ASSERT_EQ(Status::ILLEGAL_ARGUMENT, status);
3378        ASSERT_EQ(numRequestProcessed, 0u);
3379
3380        ret = session->close();
3381        ASSERT_TRUE(ret.isOk());
3382    }
3383}
3384
3385// Generate, trigger and flush a preview request
3386TEST_F(CameraHidlTest, flushPreviewRequest) {
3387    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
3388    std::vector<AvailableStream> outputPreviewStreams;
3389    AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
3390                                        static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
3391    uint64_t bufferId = 1;
3392    uint32_t frameNumber = 1;
3393    ::android::hardware::hidl_vec<uint8_t> settings;
3394
3395    for (const auto& name : cameraDeviceNames) {
3396        int deviceVersion = getCameraDeviceVersion(name, mProviderType);
3397        if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) {
3398            continue;
3399        } else if (deviceVersion <= 0) {
3400            ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
3401            ADD_FAILURE();
3402            return;
3403        }
3404
3405        Stream previewStream;
3406        HalStreamConfiguration halStreamConfig;
3407        sp<ICameraDeviceSession> session;
3408        bool supportsPartialResults = false;
3409        uint32_t partialResultCount = 0;
3410        configurePreviewStream(name, deviceVersion, mProvider, &previewThreshold, &session /*out*/,
3411                &previewStream /*out*/, &halStreamConfig /*out*/,
3412                &supportsPartialResults /*out*/,
3413                &partialResultCount /*out*/);
3414
3415        std::shared_ptr<ResultMetadataQueue> resultQueue;
3416        auto resultQueueRet =
3417            session->getCaptureResultMetadataQueue(
3418                [&resultQueue](const auto& descriptor) {
3419                    resultQueue = std::make_shared<ResultMetadataQueue>(
3420                            descriptor);
3421                    if (!resultQueue->isValid() ||
3422                            resultQueue->availableToWrite() <= 0) {
3423                        ALOGE("%s: HAL returns empty result metadata fmq,"
3424                                " not use it", __func__);
3425                        resultQueue = nullptr;
3426                        // Don't use the queue onwards.
3427                    }
3428                });
3429        ASSERT_TRUE(resultQueueRet.isOk());
3430
3431        InFlightRequest inflightReq = {1, false, supportsPartialResults,
3432                                       partialResultCount, resultQueue};
3433        RequestTemplate reqTemplate = RequestTemplate::PREVIEW;
3434        Return<void> ret;
3435        ret = session->constructDefaultRequestSettings(reqTemplate,
3436                                                       [&](auto status, const auto& req) {
3437                                                           ASSERT_EQ(Status::OK, status);
3438                                                           settings = req;
3439                                                       });
3440        ASSERT_TRUE(ret.isOk());
3441
3442        sp<GraphicBuffer> gb = new GraphicBuffer(
3443            previewStream.width, previewStream.height,
3444            static_cast<int32_t>(halStreamConfig.streams[0].overrideFormat), 1,
3445            android_convertGralloc1To0Usage(halStreamConfig.streams[0].producerUsage,
3446                                            halStreamConfig.streams[0].consumerUsage));
3447        ASSERT_NE(nullptr, gb.get());
3448        StreamBuffer outputBuffer = {halStreamConfig.streams[0].id,
3449                                     bufferId,
3450                                     hidl_handle(gb->getNativeBuffer()->handle),
3451                                     BufferStatus::OK,
3452                                     nullptr,
3453                                     nullptr};
3454        ::android::hardware::hidl_vec<StreamBuffer> outputBuffers = {outputBuffer};
3455        const StreamBuffer emptyInputBuffer = {-1, 0, nullptr,
3456                                               BufferStatus::ERROR, nullptr, nullptr};
3457        CaptureRequest request = {frameNumber, 0 /* fmqSettingsSize */, settings,
3458                                  emptyInputBuffer, outputBuffers};
3459
3460        {
3461            std::unique_lock<std::mutex> l(mLock);
3462            mInflightMap.clear();
3463            mInflightMap.add(frameNumber, &inflightReq);
3464        }
3465
3466        Status status = Status::INTERNAL_ERROR;
3467        uint32_t numRequestProcessed = 0;
3468        hidl_vec<BufferCache> cachesToRemove;
3469        ret = session->processCaptureRequest(
3470            {request}, cachesToRemove, [&status, &numRequestProcessed](auto s,
3471                    uint32_t n) {
3472                status = s;
3473                numRequestProcessed = n;
3474            });
3475
3476        ASSERT_TRUE(ret.isOk());
3477        ASSERT_EQ(Status::OK, status);
3478        ASSERT_EQ(numRequestProcessed, 1u);
3479        // Flush before waiting for request to complete.
3480        Return<Status> returnStatus = session->flush();
3481        ASSERT_TRUE(returnStatus.isOk());
3482        ASSERT_EQ(Status::OK, returnStatus);
3483
3484        {
3485            std::unique_lock<std::mutex> l(mLock);
3486            while (!inflightReq.errorCodeValid &&
3487                   ((0 < inflightReq.numBuffersLeft) ||
3488                           (!inflightReq.haveResultMetadata))) {
3489                auto timeout = std::chrono::system_clock::now() +
3490                               std::chrono::seconds(kStreamBufferTimeoutSec);
3491                ASSERT_NE(std::cv_status::timeout, mResultCondition.wait_until(l,
3492                        timeout));
3493            }
3494
3495            if (!inflightReq.errorCodeValid) {
3496                ASSERT_NE(inflightReq.resultOutputBuffers.size(), 0u);
3497                ASSERT_EQ(previewStream.id, inflightReq.resultOutputBuffers[0].streamId);
3498            } else {
3499                switch (inflightReq.errorCode) {
3500                    case ErrorCode::ERROR_REQUEST:
3501                    case ErrorCode::ERROR_RESULT:
3502                    case ErrorCode::ERROR_BUFFER:
3503                        // Expected
3504                        break;
3505                    case ErrorCode::ERROR_DEVICE:
3506                    default:
3507                        FAIL() << "Unexpected error:"
3508                               << static_cast<uint32_t>(inflightReq.errorCode);
3509                }
3510            }
3511
3512            ret = session->close();
3513            ASSERT_TRUE(ret.isOk());
3514        }
3515    }
3516}
3517
3518// Verify that camera flushes correctly without any pending requests.
3519TEST_F(CameraHidlTest, flushEmpty) {
3520    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
3521    std::vector<AvailableStream> outputPreviewStreams;
3522    AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
3523                                        static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
3524
3525    for (const auto& name : cameraDeviceNames) {
3526        int deviceVersion = getCameraDeviceVersion(name, mProviderType);
3527        if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) {
3528            continue;
3529        } else if (deviceVersion <= 0) {
3530            ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
3531            ADD_FAILURE();
3532            return;
3533        }
3534
3535        Stream previewStream;
3536        HalStreamConfiguration halStreamConfig;
3537        sp<ICameraDeviceSession> session;
3538        bool supportsPartialResults = false;
3539        uint32_t partialResultCount = 0;
3540        configurePreviewStream(name, deviceVersion, mProvider, &previewThreshold, &session /*out*/,
3541                &previewStream /*out*/, &halStreamConfig /*out*/,
3542                &supportsPartialResults /*out*/,
3543                &partialResultCount /*out*/);
3544
3545        Return<Status> returnStatus = session->flush();
3546        ASSERT_TRUE(returnStatus.isOk());
3547        ASSERT_EQ(Status::OK, returnStatus);
3548
3549        {
3550            std::unique_lock<std::mutex> l(mLock);
3551            auto timeout = std::chrono::system_clock::now() +
3552                           std::chrono::milliseconds(kEmptyFlushTimeoutMSec);
3553            ASSERT_EQ(std::cv_status::timeout, mResultCondition.wait_until(l, timeout));
3554        }
3555
3556        Return<void> ret = session->close();
3557        ASSERT_TRUE(ret.isOk());
3558    }
3559}
3560
3561// Retrieve all valid output stream resolutions from the camera
3562// static characteristics.
3563Status CameraHidlTest::getAvailableOutputStreams(camera_metadata_t *staticMeta,
3564        std::vector<AvailableStream> &outputStreams,
3565        const AvailableStream *threshold) {
3566    if (nullptr == staticMeta) {
3567        return Status::ILLEGAL_ARGUMENT;
3568    }
3569
3570    camera_metadata_ro_entry entry;
3571    int rc = find_camera_metadata_ro_entry(staticMeta,
3572            ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS, &entry);
3573    if ((0 != rc) || (0 != (entry.count % 4))) {
3574        return Status::ILLEGAL_ARGUMENT;
3575    }
3576
3577    for (size_t i = 0; i < entry.count; i+=4) {
3578        if (ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT ==
3579                entry.data.i32[i + 3]) {
3580            if(nullptr == threshold) {
3581                AvailableStream s = {entry.data.i32[i+1],
3582                        entry.data.i32[i+2], entry.data.i32[i]};
3583                outputStreams.push_back(s);
3584            } else {
3585                if ((threshold->format == entry.data.i32[i]) &&
3586                        (threshold->width >= entry.data.i32[i+1]) &&
3587                        (threshold->height >= entry.data.i32[i+2])) {
3588                    AvailableStream s = {entry.data.i32[i+1],
3589                            entry.data.i32[i+2], threshold->format};
3590                    outputStreams.push_back(s);
3591                }
3592            }
3593        }
3594
3595    }
3596
3597    return Status::OK;
3598}
3599
3600// Check if constrained mode is supported by using the static
3601// camera characteristics.
3602Status CameraHidlTest::isConstrainedModeAvailable(camera_metadata_t *staticMeta) {
3603    Status ret = Status::METHOD_NOT_SUPPORTED;
3604    if (nullptr == staticMeta) {
3605        return Status::ILLEGAL_ARGUMENT;
3606    }
3607
3608    camera_metadata_ro_entry entry;
3609    int rc = find_camera_metadata_ro_entry(staticMeta,
3610            ANDROID_REQUEST_AVAILABLE_CAPABILITIES, &entry);
3611    if (0 != rc) {
3612        return Status::ILLEGAL_ARGUMENT;
3613    }
3614
3615    for (size_t i = 0; i < entry.count; i++) {
3616        if (ANDROID_REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO ==
3617                entry.data.u8[i]) {
3618            ret = Status::OK;
3619            break;
3620        }
3621    }
3622
3623    return ret;
3624}
3625
3626// Pick the largest supported HFR mode from the static camera
3627// characteristics.
3628Status CameraHidlTest::pickConstrainedModeSize(camera_metadata_t *staticMeta,
3629        AvailableStream &hfrStream) {
3630    if (nullptr == staticMeta) {
3631        return Status::ILLEGAL_ARGUMENT;
3632    }
3633
3634    camera_metadata_ro_entry entry;
3635    int rc = find_camera_metadata_ro_entry(staticMeta,
3636            ANDROID_CONTROL_AVAILABLE_HIGH_SPEED_VIDEO_CONFIGURATIONS, &entry);
3637    if (0 != rc) {
3638        return Status::METHOD_NOT_SUPPORTED;
3639    } else if (0 != (entry.count % 5)) {
3640        return Status::ILLEGAL_ARGUMENT;
3641    }
3642
3643    hfrStream = {0, 0,
3644            static_cast<uint32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
3645    for (size_t i = 0; i < entry.count; i+=5) {
3646        int32_t w = entry.data.i32[i];
3647        int32_t h = entry.data.i32[i+1];
3648        if ((hfrStream.width * hfrStream.height) < (w *h)) {
3649            hfrStream.width = w;
3650            hfrStream.height = h;
3651        }
3652    }
3653
3654    return Status::OK;
3655}
3656
3657// Check whether ZSL is available using the static camera
3658// characteristics.
3659Status CameraHidlTest::isZSLModeAvailable(camera_metadata_t *staticMeta) {
3660    Status ret = Status::METHOD_NOT_SUPPORTED;
3661    if (nullptr == staticMeta) {
3662        return Status::ILLEGAL_ARGUMENT;
3663    }
3664
3665    camera_metadata_ro_entry entry;
3666    int rc = find_camera_metadata_ro_entry(staticMeta,
3667            ANDROID_REQUEST_AVAILABLE_CAPABILITIES, &entry);
3668    if (0 != rc) {
3669        return Status::ILLEGAL_ARGUMENT;
3670    }
3671
3672    for (size_t i = 0; i < entry.count; i++) {
3673        if ((ANDROID_REQUEST_AVAILABLE_CAPABILITIES_PRIVATE_REPROCESSING ==
3674                entry.data.u8[i]) ||
3675                (ANDROID_REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING ==
3676                        entry.data.u8[i]) ){
3677            ret = Status::OK;
3678            break;
3679        }
3680    }
3681
3682    return ret;
3683}
3684
3685// Retrieve the reprocess input-output format map from the static
3686// camera characteristics.
3687Status CameraHidlTest::getZSLInputOutputMap(camera_metadata_t *staticMeta,
3688        std::vector<AvailableZSLInputOutput> &inputOutputMap) {
3689    if (nullptr == staticMeta) {
3690        return Status::ILLEGAL_ARGUMENT;
3691    }
3692
3693    camera_metadata_ro_entry entry;
3694    int rc = find_camera_metadata_ro_entry(staticMeta,
3695            ANDROID_SCALER_AVAILABLE_INPUT_OUTPUT_FORMATS_MAP, &entry);
3696    if ((0 != rc) || (0 >= entry.count)) {
3697        return Status::ILLEGAL_ARGUMENT;
3698    }
3699
3700    const int32_t* contents = &entry.data.i32[0];
3701    for (size_t i = 0; i < entry.count; ) {
3702        int32_t inputFormat = contents[i++];
3703        int32_t length = contents[i++];
3704        for (int32_t j = 0; j < length; j++) {
3705            int32_t outputFormat = contents[i+j];
3706            AvailableZSLInputOutput zslEntry = {inputFormat, outputFormat};
3707            inputOutputMap.push_back(zslEntry);
3708        }
3709        i += length;
3710    }
3711
3712    return Status::OK;
3713}
3714
3715// Search for the largest stream size for a given format.
3716Status CameraHidlTest::findLargestSize(
3717        const std::vector<AvailableStream> &streamSizes, int32_t format,
3718        AvailableStream &result) {
3719    result = {0, 0, 0};
3720    for (auto &iter : streamSizes) {
3721        if (format == iter.format) {
3722            if ((result.width * result.height) < (iter.width * iter.height)) {
3723                result = iter;
3724            }
3725        }
3726    }
3727
3728    return (result.format == format) ? Status::OK : Status::ILLEGAL_ARGUMENT;
3729}
3730
3731// Check whether the camera device supports specific focus mode.
3732Status CameraHidlTest::isAutoFocusModeAvailable(
3733        CameraParameters &cameraParams,
3734        const char *mode) {
3735    ::android::String8 focusModes(cameraParams.get(
3736            CameraParameters::KEY_SUPPORTED_FOCUS_MODES));
3737    if (focusModes.contains(mode)) {
3738        return Status::OK;
3739    }
3740
3741    return Status::METHOD_NOT_SUPPORTED;
3742}
3743
3744// Open a device session and configure a preview stream.
3745void CameraHidlTest::configurePreviewStream(const std::string &name, int32_t deviceVersion,
3746        sp<ICameraProvider> provider,
3747        const AvailableStream *previewThreshold,
3748        sp<ICameraDeviceSession> *session /*out*/,
3749        Stream *previewStream /*out*/,
3750        HalStreamConfiguration *halStreamConfig /*out*/,
3751        bool *supportsPartialResults /*out*/,
3752        uint32_t *partialResultCount /*out*/) {
3753    ASSERT_NE(nullptr, session);
3754    ASSERT_NE(nullptr, previewStream);
3755    ASSERT_NE(nullptr, halStreamConfig);
3756    ASSERT_NE(nullptr, supportsPartialResults);
3757    ASSERT_NE(nullptr, partialResultCount);
3758
3759    std::vector<AvailableStream> outputPreviewStreams;
3760    ::android::sp<ICameraDevice> device3_x;
3761    ALOGI("configureStreams: Testing camera device %s", name.c_str());
3762    Return<void> ret;
3763    ret = provider->getCameraDeviceInterface_V3_x(
3764        name,
3765        [&](auto status, const auto& device) {
3766            ALOGI("getCameraDeviceInterface_V3_x returns status:%d",
3767                  (int)status);
3768            ASSERT_EQ(Status::OK, status);
3769            ASSERT_NE(device, nullptr);
3770            device3_x = device;
3771        });
3772    ASSERT_TRUE(ret.isOk());
3773
3774    sp<DeviceCb> cb = new DeviceCb(this);
3775    ret = device3_x->open(
3776        cb,
3777        [&](auto status, const auto& newSession) {
3778            ALOGI("device::open returns status:%d", (int)status);
3779            ASSERT_EQ(Status::OK, status);
3780            ASSERT_NE(newSession, nullptr);
3781            *session = newSession;
3782        });
3783    ASSERT_TRUE(ret.isOk());
3784
3785    sp<device::V3_3::ICameraDeviceSession> session3_3;
3786    sp<device::V3_4::ICameraDeviceSession> session3_4;
3787    castSession(*session, deviceVersion, &session3_3, &session3_4);
3788
3789    camera_metadata_t *staticMeta;
3790    ret = device3_x->getCameraCharacteristics([&] (Status s,
3791            CameraMetadata metadata) {
3792        ASSERT_EQ(Status::OK, s);
3793        staticMeta = clone_camera_metadata(
3794                reinterpret_cast<const camera_metadata_t*>(metadata.data()));
3795         ASSERT_NE(nullptr, staticMeta);
3796    });
3797    ASSERT_TRUE(ret.isOk());
3798
3799    camera_metadata_ro_entry entry;
3800    auto status = find_camera_metadata_ro_entry(staticMeta,
3801            ANDROID_REQUEST_PARTIAL_RESULT_COUNT, &entry);
3802    if ((0 == status) && (entry.count > 0)) {
3803        *partialResultCount = entry.data.i32[0];
3804        *supportsPartialResults = (*partialResultCount > 1);
3805    }
3806
3807    outputPreviewStreams.clear();
3808    auto rc = getAvailableOutputStreams(staticMeta,
3809            outputPreviewStreams, previewThreshold);
3810    free_camera_metadata(staticMeta);
3811    ASSERT_EQ(Status::OK, rc);
3812    ASSERT_FALSE(outputPreviewStreams.empty());
3813
3814    *previewStream = {0, StreamType::OUTPUT,
3815            static_cast<uint32_t> (outputPreviewStreams[0].width),
3816            static_cast<uint32_t> (outputPreviewStreams[0].height),
3817            static_cast<PixelFormat> (outputPreviewStreams[0].format),
3818            GRALLOC1_CONSUMER_USAGE_HWCOMPOSER, 0, StreamRotation::ROTATION_0};
3819    ::android::hardware::hidl_vec<Stream> streams = {*previewStream};
3820    ::android::hardware::camera::device::V3_4::StreamConfiguration config;
3821    config.v3_2 = {streams, StreamConfigurationMode::NORMAL_MODE};
3822    if (session3_4 != nullptr) {
3823        ret = session3_4->configureStreams_3_4(config,
3824                [&] (Status s, device::V3_3::HalStreamConfiguration halConfig) {
3825                    ASSERT_EQ(Status::OK, s);
3826                    ASSERT_EQ(1u, halConfig.streams.size());
3827                    halStreamConfig->streams.resize(halConfig.streams.size());
3828                    for (size_t i = 0; i < halConfig.streams.size(); i++) {
3829                        halStreamConfig->streams[i] = halConfig.streams[i].v3_2;
3830                    }
3831                });
3832    } else if (session3_3 != nullptr) {
3833        ret = session3_3->configureStreams_3_3(config.v3_2,
3834                [&] (Status s, device::V3_3::HalStreamConfiguration halConfig) {
3835                    ASSERT_EQ(Status::OK, s);
3836                    ASSERT_EQ(1u, halConfig.streams.size());
3837                    halStreamConfig->streams.resize(halConfig.streams.size());
3838                    for (size_t i = 0; i < halConfig.streams.size(); i++) {
3839                        halStreamConfig->streams[i] = halConfig.streams[i].v3_2;
3840                    }
3841                });
3842    } else {
3843        ret = (*session)->configureStreams(config.v3_2,
3844                [&] (Status s, HalStreamConfiguration halConfig) {
3845                    ASSERT_EQ(Status::OK, s);
3846                    ASSERT_EQ(1u, halConfig.streams.size());
3847                    *halStreamConfig = halConfig;
3848                });
3849    }
3850    ASSERT_TRUE(ret.isOk());
3851}
3852
3853//Cast camera device session to corresponding version
3854void CameraHidlTest::castSession(const sp<ICameraDeviceSession> &session, int32_t deviceVersion,
3855        sp<device::V3_3::ICameraDeviceSession> *session3_3 /*out*/,
3856        sp<device::V3_4::ICameraDeviceSession> *session3_4 /*out*/) {
3857    ASSERT_NE(nullptr, session3_3);
3858    ASSERT_NE(nullptr, session3_4);
3859
3860    switch (deviceVersion) {
3861        case CAMERA_DEVICE_API_VERSION_3_4: {
3862            auto castResult = device::V3_4::ICameraDeviceSession::castFrom(session);
3863            ASSERT_TRUE(castResult.isOk());
3864            *session3_4 = castResult;
3865            break;
3866        }
3867        case CAMERA_DEVICE_API_VERSION_3_3: {
3868            auto castResult = device::V3_3::ICameraDeviceSession::castFrom(session);
3869            ASSERT_TRUE(castResult.isOk());
3870            *session3_3 = castResult;
3871            break;
3872        }
3873        default:
3874            //no-op
3875            return;
3876    }
3877}
3878
3879// Open a device session with empty callbacks and return static metadata.
3880void CameraHidlTest::openEmptyDeviceSession(const std::string &name,
3881        sp<ICameraProvider> provider,
3882        sp<ICameraDeviceSession> *session /*out*/,
3883        camera_metadata_t **staticMeta /*out*/) {
3884    ASSERT_NE(nullptr, session);
3885    ASSERT_NE(nullptr, staticMeta);
3886
3887    ::android::sp<ICameraDevice> device3_x;
3888    ALOGI("configureStreams: Testing camera device %s", name.c_str());
3889    Return<void> ret;
3890    ret = provider->getCameraDeviceInterface_V3_x(
3891        name,
3892        [&](auto status, const auto& device) {
3893            ALOGI("getCameraDeviceInterface_V3_x returns status:%d",
3894                  (int)status);
3895            ASSERT_EQ(Status::OK, status);
3896            ASSERT_NE(device, nullptr);
3897            device3_x = device;
3898        });
3899    ASSERT_TRUE(ret.isOk());
3900
3901    sp<EmptyDeviceCb> cb = new EmptyDeviceCb();
3902    ret = device3_x->open(cb, [&](auto status, const auto& newSession) {
3903            ALOGI("device::open returns status:%d", (int)status);
3904            ASSERT_EQ(Status::OK, status);
3905            ASSERT_NE(newSession, nullptr);
3906            *session = newSession;
3907        });
3908    ASSERT_TRUE(ret.isOk());
3909
3910    ret = device3_x->getCameraCharacteristics([&] (Status s,
3911            CameraMetadata metadata) {
3912        ASSERT_EQ(Status::OK, s);
3913        *staticMeta = clone_camera_metadata(
3914                reinterpret_cast<const camera_metadata_t*>(metadata.data()));
3915        ASSERT_NE(nullptr, *staticMeta);
3916    });
3917    ASSERT_TRUE(ret.isOk());
3918}
3919
3920// Open a particular camera device.
3921void CameraHidlTest::openCameraDevice(const std::string &name,
3922        sp<ICameraProvider> provider,
3923        sp<::android::hardware::camera::device::V1_0::ICameraDevice> *device1 /*out*/) {
3924    ASSERT_TRUE(nullptr != device1);
3925
3926    Return<void> ret;
3927    ret = provider->getCameraDeviceInterface_V1_x(
3928            name,
3929            [&](auto status, const auto& device) {
3930            ALOGI("getCameraDeviceInterface_V1_x returns status:%d",
3931                  (int)status);
3932            ASSERT_EQ(Status::OK, status);
3933            ASSERT_NE(device, nullptr);
3934            *device1 = device;
3935        });
3936    ASSERT_TRUE(ret.isOk());
3937
3938    sp<Camera1DeviceCb> deviceCb = new Camera1DeviceCb(this);
3939    Return<Status> returnStatus = (*device1)->open(deviceCb);
3940    ASSERT_TRUE(returnStatus.isOk());
3941    ASSERT_EQ(Status::OK, returnStatus);
3942}
3943
3944// Initialize and configure a preview window.
3945void CameraHidlTest::setupPreviewWindow(
3946        const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device,
3947        sp<BufferItemConsumer> *bufferItemConsumer /*out*/,
3948        sp<BufferItemHander> *bufferHandler /*out*/) {
3949    ASSERT_NE(nullptr, device.get());
3950    ASSERT_NE(nullptr, bufferItemConsumer);
3951    ASSERT_NE(nullptr, bufferHandler);
3952
3953    sp<IGraphicBufferProducer> producer;
3954    sp<IGraphicBufferConsumer> consumer;
3955    BufferQueue::createBufferQueue(&producer, &consumer);
3956    *bufferItemConsumer = new BufferItemConsumer(consumer,
3957            GraphicBuffer::USAGE_HW_TEXTURE); //Use GLConsumer default usage flags
3958    ASSERT_NE(nullptr, (*bufferItemConsumer).get());
3959    *bufferHandler = new BufferItemHander(*bufferItemConsumer);
3960    ASSERT_NE(nullptr, (*bufferHandler).get());
3961    (*bufferItemConsumer)->setFrameAvailableListener(*bufferHandler);
3962    sp<Surface> surface = new Surface(producer);
3963    sp<PreviewWindowCb> previewCb = new PreviewWindowCb(surface);
3964
3965    auto rc = device->setPreviewWindow(previewCb);
3966    ASSERT_TRUE(rc.isOk());
3967    ASSERT_EQ(Status::OK, rc);
3968}
3969
3970// Stop camera preview and close camera.
3971void CameraHidlTest::stopPreviewAndClose(
3972        const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device) {
3973    Return<void> ret = device->stopPreview();
3974    ASSERT_TRUE(ret.isOk());
3975
3976    ret = device->close();
3977    ASSERT_TRUE(ret.isOk());
3978}
3979
3980// Enable a specific camera message type.
3981void CameraHidlTest::enableMsgType(unsigned int msgType,
3982        const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device) {
3983    Return<void> ret = device->enableMsgType(msgType);
3984    ASSERT_TRUE(ret.isOk());
3985
3986    Return<bool> returnBoolStatus = device->msgTypeEnabled(msgType);
3987    ASSERT_TRUE(returnBoolStatus.isOk());
3988    ASSERT_TRUE(returnBoolStatus);
3989}
3990
3991// Disable a specific camera message type.
3992void CameraHidlTest::disableMsgType(unsigned int msgType,
3993        const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device) {
3994    Return<void> ret = device->disableMsgType(msgType);
3995    ASSERT_TRUE(ret.isOk());
3996
3997    Return<bool> returnBoolStatus = device->msgTypeEnabled(msgType);
3998    ASSERT_TRUE(returnBoolStatus.isOk());
3999    ASSERT_FALSE(returnBoolStatus);
4000}
4001
4002// Wait until a specific frame notification arrives.
4003void CameraHidlTest::waitForFrameLocked(DataCallbackMsg msgFrame,
4004        std::unique_lock<std::mutex> &l) {
4005    while (msgFrame != mDataMessageTypeReceived) {
4006        auto timeout = std::chrono::system_clock::now() +
4007                std::chrono::seconds(kStreamBufferTimeoutSec);
4008        ASSERT_NE(std::cv_status::timeout,
4009                mResultCondition.wait_until(l, timeout));
4010    }
4011}
4012
4013// Start preview on a particular camera device
4014void CameraHidlTest::startPreview(
4015        const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device) {
4016    Return<Status> returnStatus = device->startPreview();
4017    ASSERT_TRUE(returnStatus.isOk());
4018    ASSERT_EQ(Status::OK, returnStatus);
4019}
4020
4021// Retrieve camera parameters.
4022void CameraHidlTest::getParameters(
4023        const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device,
4024        CameraParameters *cameraParams /*out*/) {
4025    ASSERT_NE(nullptr, cameraParams);
4026
4027    Return<void> ret;
4028    ret = device->getParameters([&] (const ::android::hardware::hidl_string& params) {
4029        ASSERT_FALSE(params.empty());
4030        ::android::String8 paramString(params.c_str());
4031        (*cameraParams).unflatten(paramString);
4032    });
4033    ASSERT_TRUE(ret.isOk());
4034}
4035
4036// Set camera parameters.
4037void CameraHidlTest::setParameters(
4038        const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device,
4039        const CameraParameters &cameraParams) {
4040    Return<Status> returnStatus = device->setParameters(
4041            cameraParams.flatten().string());
4042    ASSERT_TRUE(returnStatus.isOk());
4043    ASSERT_EQ(Status::OK, returnStatus);
4044}
4045
4046int main(int argc, char **argv) {
4047  ::testing::AddGlobalTestEnvironment(CameraHidlEnvironment::Instance());
4048  ::testing::InitGoogleTest(&argc, argv);
4049  CameraHidlEnvironment::Instance()->init(&argc, argv);
4050  int status = RUN_ALL_TESTS();
4051  ALOGI("Test result = %d", status);
4052  return status;
4053}
4054