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