OSDN Git Service

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