1 /*
2  * Copyright (C) 2016-2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define LOG_TAG "camera_hidl_hal_test"
18 
19 #include <algorithm>
20 #include <chrono>
21 #include <mutex>
22 #include <regex>
23 #include <unordered_map>
24 #include <unordered_set>
25 #include <condition_variable>
26 
27 #include <inttypes.h>
28 
29 #include <android/hardware/camera/device/1.0/ICameraDevice.h>
30 #include <android/hardware/camera/device/3.2/ICameraDevice.h>
31 #include <android/hardware/camera/device/3.5/ICameraDevice.h>
32 #include <android/hardware/camera/device/3.3/ICameraDeviceSession.h>
33 #include <android/hardware/camera/device/3.4/ICameraDeviceSession.h>
34 #include <android/hardware/camera/device/3.5/ICameraDeviceSession.h>
35 #include <android/hardware/camera/device/3.4/ICameraDeviceCallback.h>
36 #include <android/hardware/camera/device/3.5/ICameraDeviceCallback.h>
37 #include <android/hardware/camera/provider/2.4/ICameraProvider.h>
38 #include <android/hardware/camera/provider/2.5/ICameraProvider.h>
39 #include <android/hardware/camera/metadata/3.4/types.h>
40 #include <android/hidl/manager/1.0/IServiceManager.h>
41 #include <binder/MemoryHeapBase.h>
42 #include <CameraMetadata.h>
43 #include <CameraParameters.h>
44 #include <cutils/properties.h>
45 #include <fmq/MessageQueue.h>
46 #include <grallocusage/GrallocUsageConversion.h>
47 #include <gui/BufferItemConsumer.h>
48 #include <gui/BufferQueue.h>
49 #include <gui/Surface.h>
50 #include <hardware/gralloc.h>
51 #include <hardware/gralloc1.h>
52 #include <system/camera.h>
53 #include <system/camera_metadata.h>
54 #include <ui/GraphicBuffer.h>
55 
56 #include <android/hardware/graphics/allocator/2.0/IAllocator.h>
57 #include <android/hardware/graphics/allocator/3.0/IAllocator.h>
58 #include <android/hardware/graphics/mapper/2.0/IMapper.h>
59 #include <android/hardware/graphics/mapper/2.0/types.h>
60 #include <android/hardware/graphics/mapper/3.0/IMapper.h>
61 #include <android/hidl/allocator/1.0/IAllocator.h>
62 #include <android/hidl/memory/1.0/IMapper.h>
63 #include <android/hidl/memory/1.0/IMemory.h>
64 
65 #include <VtsHalHidlTargetTestBase.h>
66 #include <VtsHalHidlTargetTestEnvBase.h>
67 
68 using namespace ::android::hardware::camera::device;
69 using ::android::hardware::Return;
70 using ::android::hardware::Void;
71 using ::android::hardware::hidl_bitfield;
72 using ::android::hardware::hidl_handle;
73 using ::android::hardware::hidl_string;
74 using ::android::hardware::hidl_vec;
75 using ::android::sp;
76 using ::android::wp;
77 using ::android::GraphicBuffer;
78 using ::android::IGraphicBufferProducer;
79 using ::android::IGraphicBufferConsumer;
80 using ::android::BufferQueue;
81 using ::android::BufferItemConsumer;
82 using ::android::Surface;
83 using ::android::hardware::graphics::common::V1_0::BufferUsage;
84 using ::android::hardware::graphics::common::V1_0::Dataspace;
85 using ::android::hardware::graphics::common::V1_0::PixelFormat;
86 using ::android::hardware::camera::common::V1_0::Status;
87 using ::android::hardware::camera::common::V1_0::CameraDeviceStatus;
88 using ::android::hardware::camera::common::V1_0::TorchMode;
89 using ::android::hardware::camera::common::V1_0::TorchModeStatus;
90 using ::android::hardware::camera::common::V1_0::helper::CameraParameters;
91 using ::android::hardware::camera::common::V1_0::helper::Size;
92 using ::android::hardware::camera::provider::V2_4::ICameraProvider;
93 using ::android::hardware::camera::provider::V2_4::ICameraProviderCallback;
94 using ::android::hardware::camera::device::V3_2::ICameraDevice;
95 using ::android::hardware::camera::device::V3_2::BufferCache;
96 using ::android::hardware::camera::device::V3_2::CaptureRequest;
97 using ::android::hardware::camera::device::V3_2::CaptureResult;
98 using ::android::hardware::camera::device::V3_2::ICameraDeviceSession;
99 using ::android::hardware::camera::device::V3_2::NotifyMsg;
100 using ::android::hardware::camera::device::V3_2::RequestTemplate;
101 using ::android::hardware::camera::device::V3_2::StreamType;
102 using ::android::hardware::camera::device::V3_2::StreamRotation;
103 using ::android::hardware::camera::device::V3_2::StreamConfiguration;
104 using ::android::hardware::camera::device::V3_2::StreamConfigurationMode;
105 using ::android::hardware::camera::device::V3_2::CameraMetadata;
106 using ::android::hardware::camera::device::V3_2::HalStreamConfiguration;
107 using ::android::hardware::camera::device::V3_2::BufferStatus;
108 using ::android::hardware::camera::device::V3_2::StreamBuffer;
109 using ::android::hardware::camera::device::V3_2::MsgType;
110 using ::android::hardware::camera::device::V3_2::ErrorMsg;
111 using ::android::hardware::camera::device::V3_2::ErrorCode;
112 using ::android::hardware::camera::device::V1_0::CameraFacing;
113 using ::android::hardware::camera::device::V1_0::NotifyCallbackMsg;
114 using ::android::hardware::camera::device::V1_0::CommandType;
115 using ::android::hardware::camera::device::V1_0::DataCallbackMsg;
116 using ::android::hardware::camera::device::V1_0::CameraFrameMetadata;
117 using ::android::hardware::camera::device::V1_0::ICameraDevicePreviewCallback;
118 using ::android::hardware::camera::device::V1_0::FrameCallbackFlag;
119 using ::android::hardware::camera::device::V1_0::HandleTimestampMessage;
120 using ::android::hardware::camera::metadata::V3_4::CameraMetadataEnumAndroidSensorInfoColorFilterArrangement;
121 using ::android::hardware::camera::metadata::V3_4::CameraMetadataTag;
122 using ::android::hardware::camera::device::V3_4::PhysicalCameraMetadata;
123 using ::android::hardware::MessageQueue;
124 using ::android::hardware::kSynchronizedReadWrite;
125 using ::android::hidl::allocator::V1_0::IAllocator;
126 using ::android::hidl::memory::V1_0::IMemory;
127 using ::android::hidl::memory::V1_0::IMapper;
128 using ResultMetadataQueue = MessageQueue<uint8_t, kSynchronizedReadWrite>;
129 using ::android::hidl::manager::V1_0::IServiceManager;
130 
131 using namespace ::android::hardware::camera;
132 
133 const uint32_t kMaxPreviewWidth = 1920;
134 const uint32_t kMaxPreviewHeight = 1080;
135 const uint32_t kMaxVideoWidth = 4096;
136 const uint32_t kMaxVideoHeight = 2160;
137 const int64_t kStreamBufferTimeoutSec = 3;
138 const int64_t kAutoFocusTimeoutSec = 5;
139 const int64_t kTorchTimeoutSec = 1;
140 const int64_t kEmptyFlushTimeoutMSec = 200;
141 const char kDumpOutput[] = "/dev/null";
142 const uint32_t kBurstFrameCount = 10;
143 const int64_t kBufferReturnTimeoutSec = 1;
144 
145 struct AvailableStream {
146     int32_t width;
147     int32_t height;
148     int32_t format;
149 };
150 
151 struct AvailableZSLInputOutput {
152     int32_t inputFormat;
153     int32_t outputFormat;
154 };
155 
156 enum ReprocessType {
157     PRIV_REPROCESS,
158     YUV_REPROCESS,
159 };
160 
161 namespace {
162     // "device@<version>/legacy/<id>"
163     const char *kDeviceNameRE = "device@([0-9]+\\.[0-9]+)/%s/(.+)";
164     const int CAMERA_DEVICE_API_VERSION_3_5 = 0x305;
165     const int CAMERA_DEVICE_API_VERSION_3_4 = 0x304;
166     const int CAMERA_DEVICE_API_VERSION_3_3 = 0x303;
167     const int CAMERA_DEVICE_API_VERSION_3_2 = 0x302;
168     const int CAMERA_DEVICE_API_VERSION_1_0 = 0x100;
169     const char *kHAL3_5 = "3.5";
170     const char *kHAL3_4 = "3.4";
171     const char *kHAL3_3 = "3.3";
172     const char *kHAL3_2 = "3.2";
173     const char *kHAL1_0 = "1.0";
174 
matchDeviceName(const hidl_string & deviceName,const hidl_string & providerType,std::string * deviceVersion,std::string * cameraId)175     bool matchDeviceName(const hidl_string& deviceName,
176             const hidl_string &providerType,
177             std::string* deviceVersion,
178             std::string* cameraId) {
179         ::android::String8 pattern;
180         pattern.appendFormat(kDeviceNameRE, providerType.c_str());
181         std::regex e(pattern.string());
182         std::string deviceNameStd(deviceName.c_str());
183         std::smatch sm;
184         if (std::regex_match(deviceNameStd, sm, e)) {
185             if (deviceVersion != nullptr) {
186                 *deviceVersion = sm[1];
187             }
188             if (cameraId != nullptr) {
189                 *cameraId = sm[2];
190             }
191             return true;
192         }
193         return false;
194     }
195 
getCameraDeviceVersion(const hidl_string & deviceName,const hidl_string & providerType)196     int getCameraDeviceVersion(const hidl_string& deviceName,
197             const hidl_string &providerType) {
198         std::string version;
199         bool match = matchDeviceName(deviceName, providerType, &version, nullptr);
200         if (!match) {
201             return -1;
202         }
203 
204         if (version.compare(kHAL3_5) == 0) {
205             return CAMERA_DEVICE_API_VERSION_3_5;
206         } else if (version.compare(kHAL3_4) == 0) {
207             return CAMERA_DEVICE_API_VERSION_3_4;
208         } else if (version.compare(kHAL3_3) == 0) {
209             return CAMERA_DEVICE_API_VERSION_3_3;
210         } else if (version.compare(kHAL3_2) == 0) {
211             return CAMERA_DEVICE_API_VERSION_3_2;
212         } else if (version.compare(kHAL1_0) == 0) {
213             return CAMERA_DEVICE_API_VERSION_1_0;
214         }
215         return 0;
216     }
217 
parseProviderName(const std::string & name,std::string * type,uint32_t * id)218     bool parseProviderName(const std::string& name, std::string *type /*out*/,
219             uint32_t *id /*out*/) {
220         if (!type || !id) {
221             ADD_FAILURE();
222             return false;
223         }
224 
225         std::string::size_type slashIdx = name.find('/');
226         if (slashIdx == std::string::npos || slashIdx == name.size() - 1) {
227             ADD_FAILURE() << "Provider name does not have / separator between type"
228                     "and id";
229             return false;
230         }
231 
232         std::string typeVal = name.substr(0, slashIdx);
233 
234         char *endPtr;
235         errno = 0;
236         long idVal = strtol(name.c_str() + slashIdx + 1, &endPtr, 10);
237         if (errno != 0) {
238             ADD_FAILURE() << "cannot parse provider id as an integer:" <<
239                     name.c_str() << strerror(errno) << errno;
240             return false;
241         }
242         if (endPtr != name.c_str() + name.size()) {
243             ADD_FAILURE() << "provider id has unexpected length " << name.c_str();
244             return false;
245         }
246         if (idVal < 0) {
247             ADD_FAILURE() << "id is negative: " << name.c_str() << idVal;
248             return false;
249         }
250 
251         *type = typeVal;
252         *id = static_cast<uint32_t>(idVal);
253 
254         return true;
255     }
256 
mapToStatus(::android::status_t s)257     Status mapToStatus(::android::status_t s)  {
258         switch(s) {
259             case ::android::OK:
260                 return Status::OK ;
261             case ::android::BAD_VALUE:
262                 return Status::ILLEGAL_ARGUMENT ;
263             case -EBUSY:
264                 return Status::CAMERA_IN_USE;
265             case -EUSERS:
266                 return Status::MAX_CAMERAS_IN_USE;
267             case ::android::UNKNOWN_TRANSACTION:
268                 return Status::METHOD_NOT_SUPPORTED;
269             case ::android::INVALID_OPERATION:
270                 return Status::OPERATION_NOT_SUPPORTED;
271             case ::android::DEAD_OBJECT:
272                 return Status::CAMERA_DISCONNECTED;
273         }
274         ALOGW("Unexpected HAL status code %d", s);
275         return Status::OPERATION_NOT_SUPPORTED;
276     }
277 
getFirstApiLevel(int32_t * outApiLevel)278     void getFirstApiLevel(/*out*/int32_t* outApiLevel) {
279         int32_t firstApiLevel = property_get_int32("ro.product.first_api_level", /*default*/-1);
280         if (firstApiLevel < 0) {
281             firstApiLevel = property_get_int32("ro.build.version.sdk", /*default*/-1);
282         }
283         ASSERT_GT(firstApiLevel, 0); // first_api_level must exist
284         *outApiLevel = firstApiLevel;
285         return;
286     }
287 }
288 
289 // Test environment for camera
290 class CameraHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
291    public:
292     // get the test environment singleton
Instance()293     static CameraHidlEnvironment* Instance() {
294         static CameraHidlEnvironment* instance = new CameraHidlEnvironment;
295         return instance;
296     }
297 
HidlSetUp()298     virtual void HidlSetUp() override { ALOGI("SetUp CameraHidlEnvironment"); }
299 
HidlTearDown()300     virtual void HidlTearDown() override { ALOGI("TearDown CameraHidlEnvironment"); }
301 
registerTestServices()302     virtual void registerTestServices() override { registerTestService<ICameraProvider>(); }
303 
304    private:
CameraHidlEnvironment()305     CameraHidlEnvironment() {}
306 
307     GTEST_DISALLOW_COPY_AND_ASSIGN_(CameraHidlEnvironment);
308 };
309 
310 struct BufferItemHander: public BufferItemConsumer::FrameAvailableListener {
BufferItemHanderBufferItemHander311     BufferItemHander(wp<BufferItemConsumer> consumer) : mConsumer(consumer) {}
312 
onFrameAvailableBufferItemHander313     void onFrameAvailable(const android::BufferItem&) override {
314         sp<BufferItemConsumer> consumer = mConsumer.promote();
315         ASSERT_NE(nullptr, consumer.get());
316 
317         android::BufferItem buffer;
318         ASSERT_EQ(android::OK, consumer->acquireBuffer(&buffer, 0));
319         ASSERT_EQ(android::OK, consumer->releaseBuffer(buffer));
320     }
321 
322  private:
323     wp<BufferItemConsumer> mConsumer;
324 };
325 
326 struct PreviewWindowCb : public ICameraDevicePreviewCallback {
PreviewWindowCbPreviewWindowCb327     PreviewWindowCb(sp<ANativeWindow> anw) : mPreviewWidth(0),
328             mPreviewHeight(0), mFormat(0), mPreviewUsage(0),
329             mPreviewSwapInterval(-1), mCrop{-1, -1, -1, -1}, mAnw(anw) {}
330 
331     using dequeueBuffer_cb =
332             std::function<void(Status status, uint64_t bufferId,
333                     const hidl_handle& buffer, uint32_t stride)>;
334     Return<void> dequeueBuffer(dequeueBuffer_cb _hidl_cb) override;
335 
336     Return<Status> enqueueBuffer(uint64_t bufferId) override;
337 
338     Return<Status> cancelBuffer(uint64_t bufferId) override;
339 
340     Return<Status> setBufferCount(uint32_t count) override;
341 
342     Return<Status> setBuffersGeometry(uint32_t w,
343             uint32_t h, PixelFormat format) override;
344 
345     Return<Status> setCrop(int32_t left, int32_t top,
346             int32_t right, int32_t bottom) override;
347 
348     Return<Status> setUsage(BufferUsage usage) override;
349 
350     Return<Status> setSwapInterval(int32_t interval) override;
351 
352     using getMinUndequeuedBufferCount_cb =
353             std::function<void(Status status, uint32_t count)>;
354     Return<void> getMinUndequeuedBufferCount(
355             getMinUndequeuedBufferCount_cb _hidl_cb) override;
356 
357     Return<Status> setTimestamp(int64_t timestamp) override;
358 
359  private:
360     struct BufferHasher {
operator ()PreviewWindowCb::BufferHasher361         size_t operator()(const buffer_handle_t& buf) const {
362             if (buf == nullptr)
363                 return 0;
364 
365             size_t result = 1;
366             result = 31 * result + buf->numFds;
367             for (int i = 0; i < buf->numFds; i++) {
368                 result = 31 * result + buf->data[i];
369             }
370             return result;
371         }
372     };
373 
374     struct BufferComparator {
operator ()PreviewWindowCb::BufferComparator375         bool operator()(const buffer_handle_t& buf1,
376                 const buffer_handle_t& buf2) const {
377             if (buf1->numFds == buf2->numFds) {
378                 for (int i = 0; i < buf1->numFds; i++) {
379                     if (buf1->data[i] != buf2->data[i]) {
380                         return false;
381                     }
382                 }
383                 return true;
384             }
385             return false;
386         }
387     };
388 
389     std::pair<bool, uint64_t> getBufferId(ANativeWindowBuffer* anb);
390     void cleanupCirculatingBuffers();
391 
392     std::mutex mBufferIdMapLock; // protecting mBufferIdMap and mNextBufferId
393     typedef std::unordered_map<const buffer_handle_t, uint64_t,
394             BufferHasher, BufferComparator> BufferIdMap;
395 
396     BufferIdMap mBufferIdMap; // stream ID -> per stream buffer ID map
397     std::unordered_map<uint64_t, ANativeWindowBuffer*> mReversedBufMap;
398     uint64_t mNextBufferId = 1;
399 
400     uint32_t mPreviewWidth, mPreviewHeight;
401     int mFormat, mPreviewUsage;
402     int32_t mPreviewSwapInterval;
403     android_native_rect_t mCrop;
404     sp<ANativeWindow> mAnw;     //Native window reference
405 };
406 
getBufferId(ANativeWindowBuffer * anb)407 std::pair<bool, uint64_t> PreviewWindowCb::getBufferId(
408         ANativeWindowBuffer* anb) {
409     std::lock_guard<std::mutex> lock(mBufferIdMapLock);
410 
411     buffer_handle_t& buf = anb->handle;
412     auto it = mBufferIdMap.find(buf);
413     if (it == mBufferIdMap.end()) {
414         uint64_t bufId = mNextBufferId++;
415         mBufferIdMap[buf] = bufId;
416         mReversedBufMap[bufId] = anb;
417         return std::make_pair(true, bufId);
418     } else {
419         return std::make_pair(false, it->second);
420     }
421 }
422 
cleanupCirculatingBuffers()423 void PreviewWindowCb::cleanupCirculatingBuffers() {
424     std::lock_guard<std::mutex> lock(mBufferIdMapLock);
425     mBufferIdMap.clear();
426     mReversedBufMap.clear();
427 }
428 
dequeueBuffer(dequeueBuffer_cb _hidl_cb)429 Return<void> PreviewWindowCb::dequeueBuffer(dequeueBuffer_cb _hidl_cb) {
430     ANativeWindowBuffer* anb;
431     auto rc = native_window_dequeue_buffer_and_wait(mAnw.get(), &anb);
432     uint64_t bufferId = 0;
433     uint32_t stride = 0;
434     hidl_handle buf = nullptr;
435     if (rc == ::android::OK) {
436         auto pair = getBufferId(anb);
437         buf = (pair.first) ? anb->handle : nullptr;
438         bufferId = pair.second;
439         stride = anb->stride;
440     }
441 
442     _hidl_cb(mapToStatus(rc), bufferId, buf, stride);
443     return Void();
444 }
445 
enqueueBuffer(uint64_t bufferId)446 Return<Status> PreviewWindowCb::enqueueBuffer(uint64_t bufferId) {
447     if (mReversedBufMap.count(bufferId) == 0) {
448         ALOGE("%s: bufferId %" PRIu64 " not found", __FUNCTION__, bufferId);
449         return Status::ILLEGAL_ARGUMENT;
450     }
451     return mapToStatus(mAnw->queueBuffer(mAnw.get(),
452             mReversedBufMap.at(bufferId), -1));
453 }
454 
cancelBuffer(uint64_t bufferId)455 Return<Status> PreviewWindowCb::cancelBuffer(uint64_t bufferId) {
456     if (mReversedBufMap.count(bufferId) == 0) {
457         ALOGE("%s: bufferId %" PRIu64 " not found", __FUNCTION__, bufferId);
458         return Status::ILLEGAL_ARGUMENT;
459     }
460     return mapToStatus(mAnw->cancelBuffer(mAnw.get(),
461             mReversedBufMap.at(bufferId), -1));
462 }
463 
setBufferCount(uint32_t count)464 Return<Status> PreviewWindowCb::setBufferCount(uint32_t count) {
465     if (mAnw.get() != nullptr) {
466         // WAR for b/27039775
467         native_window_api_disconnect(mAnw.get(), NATIVE_WINDOW_API_CAMERA);
468         native_window_api_connect(mAnw.get(), NATIVE_WINDOW_API_CAMERA);
469         if (mPreviewWidth != 0) {
470             native_window_set_buffers_dimensions(mAnw.get(),
471                     mPreviewWidth, mPreviewHeight);
472             native_window_set_buffers_format(mAnw.get(), mFormat);
473         }
474         if (mPreviewUsage != 0) {
475             native_window_set_usage(mAnw.get(), mPreviewUsage);
476         }
477         if (mPreviewSwapInterval >= 0) {
478             mAnw->setSwapInterval(mAnw.get(), mPreviewSwapInterval);
479         }
480         if (mCrop.left >= 0) {
481             native_window_set_crop(mAnw.get(), &(mCrop));
482         }
483     }
484 
485     auto rc = native_window_set_buffer_count(mAnw.get(), count);
486     if (rc == ::android::OK) {
487         cleanupCirculatingBuffers();
488     }
489 
490     return mapToStatus(rc);
491 }
492 
setBuffersGeometry(uint32_t w,uint32_t h,PixelFormat format)493 Return<Status> PreviewWindowCb::setBuffersGeometry(uint32_t w, uint32_t h,
494         PixelFormat format) {
495     auto rc = native_window_set_buffers_dimensions(mAnw.get(), w, h);
496     if (rc == ::android::OK) {
497         mPreviewWidth = w;
498         mPreviewHeight = h;
499         rc = native_window_set_buffers_format(mAnw.get(),
500                 static_cast<int>(format));
501         if (rc == ::android::OK) {
502             mFormat = static_cast<int>(format);
503         }
504     }
505 
506     return mapToStatus(rc);
507 }
508 
setCrop(int32_t left,int32_t top,int32_t right,int32_t bottom)509 Return<Status> PreviewWindowCb::setCrop(int32_t left, int32_t top,
510         int32_t right, int32_t bottom) {
511     android_native_rect_t crop = { left, top, right, bottom };
512     auto rc = native_window_set_crop(mAnw.get(), &crop);
513     if (rc == ::android::OK) {
514         mCrop = crop;
515     }
516     return mapToStatus(rc);
517 }
518 
setUsage(BufferUsage usage)519 Return<Status> PreviewWindowCb::setUsage(BufferUsage usage) {
520     auto rc = native_window_set_usage(mAnw.get(), static_cast<int>(usage));
521     if (rc == ::android::OK) {
522         mPreviewUsage =  static_cast<int>(usage);
523     }
524     return mapToStatus(rc);
525 }
526 
setSwapInterval(int32_t interval)527 Return<Status> PreviewWindowCb::setSwapInterval(int32_t interval) {
528     auto rc = mAnw->setSwapInterval(mAnw.get(), interval);
529     if (rc == ::android::OK) {
530         mPreviewSwapInterval = interval;
531     }
532     return mapToStatus(rc);
533 }
534 
getMinUndequeuedBufferCount(getMinUndequeuedBufferCount_cb _hidl_cb)535 Return<void> PreviewWindowCb::getMinUndequeuedBufferCount(
536         getMinUndequeuedBufferCount_cb _hidl_cb) {
537     int count = 0;
538     auto rc = mAnw->query(mAnw.get(),
539             NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &count);
540     _hidl_cb(mapToStatus(rc), count);
541     return Void();
542 }
543 
setTimestamp(int64_t timestamp)544 Return<Status> PreviewWindowCb::setTimestamp(int64_t timestamp) {
545     return mapToStatus(native_window_set_buffers_timestamp(mAnw.get(),
546             timestamp));
547 }
548 
549 // The main test class for camera HIDL HAL.
550 class CameraHidlTest : public ::testing::VtsHalHidlTargetTestBase {
551 public:
SetUp()552  virtual void SetUp() override {
553      string service_name = CameraHidlEnvironment::Instance()->getServiceName<ICameraProvider>();
554      ALOGI("get service with name: %s", service_name.c_str());
555      mProvider = ::testing::VtsHalHidlTargetTestBase::getService<ICameraProvider>(service_name);
556      ASSERT_NE(mProvider, nullptr);
557 
558      uint32_t id;
559      ASSERT_TRUE(parseProviderName(service_name, &mProviderType, &id));
560 
561      castProvider(mProvider, &mProvider2_5);
562      notifyDeviceState(provider::V2_5::DeviceState::NORMAL);
563  }
TearDown()564  virtual void TearDown() override {}
565 
566  hidl_vec<hidl_string> getCameraDeviceNames(sp<ICameraProvider> provider);
567 
568     struct EmptyDeviceCb : public V3_5::ICameraDeviceCallback {
processCaptureResultCameraHidlTest::EmptyDeviceCb569      virtual Return<void> processCaptureResult(
570          const hidl_vec<CaptureResult>& /*results*/) override {
571          ALOGI("processCaptureResult callback");
572          ADD_FAILURE();  // Empty callback should not reach here
573          return Void();
574      }
575 
processCaptureResult_3_4CameraHidlTest::EmptyDeviceCb576      virtual Return<void> processCaptureResult_3_4(
577          const hidl_vec<V3_4::CaptureResult>& /*results*/) override {
578          ALOGI("processCaptureResult_3_4 callback");
579          ADD_FAILURE();  // Empty callback should not reach here
580          return Void();
581      }
582 
notifyCameraHidlTest::EmptyDeviceCb583      virtual Return<void> notify(const hidl_vec<NotifyMsg>& /*msgs*/) override {
584          ALOGI("notify callback");
585          ADD_FAILURE();  // Empty callback should not reach here
586          return Void();
587      }
588 
requestStreamBuffersCameraHidlTest::EmptyDeviceCb589      virtual Return<void> requestStreamBuffers(
590              const hidl_vec<V3_5::BufferRequest>&,
591              requestStreamBuffers_cb _hidl_cb) override {
592          ALOGI("requestStreamBuffers callback");
593          // HAL might want to request buffer after configureStreams, but tests with EmptyDeviceCb
594          // doesn't actually need to send capture requests, so just return an error.
595          hidl_vec<V3_5::StreamBufferRet> emptyBufRets;
596          _hidl_cb(V3_5::BufferRequestStatus::FAILED_UNKNOWN, emptyBufRets);
597          return Void();
598      }
599 
returnStreamBuffersCameraHidlTest::EmptyDeviceCb600      virtual Return<void> returnStreamBuffers(const hidl_vec<StreamBuffer>&) override {
601          ALOGI("returnStreamBuffers");
602          ADD_FAILURE();  // Empty callback should not reach here
603          return Void();
604      }
605 
606     };
607 
608     struct DeviceCb : public V3_5::ICameraDeviceCallback {
DeviceCbCameraHidlTest::DeviceCb609         DeviceCb(CameraHidlTest *parent, int deviceVersion, const camera_metadata_t *staticMeta) :
610                 mParent(parent), mDeviceVersion(deviceVersion) {
611             mStaticMetadata = staticMeta;
612         }
613 
614         Return<void> processCaptureResult_3_4(
615                 const hidl_vec<V3_4::CaptureResult>& results) override;
616         Return<void> processCaptureResult(const hidl_vec<CaptureResult>& results) override;
617         Return<void> notify(const hidl_vec<NotifyMsg>& msgs) override;
618 
619         Return<void> requestStreamBuffers(
620                 const hidl_vec<V3_5::BufferRequest>& bufReqs,
621                 requestStreamBuffers_cb _hidl_cb) override;
622 
623         Return<void> returnStreamBuffers(const hidl_vec<StreamBuffer>& buffers) override;
624 
625         void setCurrentStreamConfig(const hidl_vec<V3_2::Stream>& streams,
626                 const hidl_vec<V3_2::HalStream>& halStreams);
627 
628         void waitForBuffersReturned();
629 
630      private:
631         bool processCaptureResultLocked(const CaptureResult& results,
632                 hidl_vec<PhysicalCameraMetadata> physicalCameraMetadata);
633 
634         CameraHidlTest *mParent; // Parent object
635         int mDeviceVersion;
636         android::hardware::camera::common::V1_0::helper::CameraMetadata mStaticMetadata;
637         bool hasOutstandingBuffersLocked();
638 
639         /* members for requestStreamBuffers() and returnStreamBuffers()*/
640         std::mutex mLock; // protecting members below
641         bool                      mUseHalBufManager = false;
642         hidl_vec<V3_2::Stream>    mStreams;
643         hidl_vec<V3_2::HalStream> mHalStreams;
644         uint64_t mNextBufferId = 1;
645         using OutstandingBuffers = std::unordered_map<uint64_t, hidl_handle>;
646         // size == mStreams.size(). Tracking each streams outstanding buffers
647         std::vector<OutstandingBuffers> mOutstandingBufferIds;
648         std::condition_variable mFlushedCondition;
649     };
650 
651     struct TorchProviderCb : public ICameraProviderCallback {
TorchProviderCbCameraHidlTest::TorchProviderCb652         TorchProviderCb(CameraHidlTest *parent) : mParent(parent) {}
cameraDeviceStatusChangeCameraHidlTest::TorchProviderCb653         virtual Return<void> cameraDeviceStatusChange(
654                 const hidl_string&, CameraDeviceStatus) override {
655             return Void();
656         }
657 
torchModeStatusChangeCameraHidlTest::TorchProviderCb658         virtual Return<void> torchModeStatusChange(
659                 const hidl_string&, TorchModeStatus newStatus) override {
660             std::lock_guard<std::mutex> l(mParent->mTorchLock);
661             mParent->mTorchStatus = newStatus;
662             mParent->mTorchCond.notify_one();
663             return Void();
664         }
665 
666      private:
667         CameraHidlTest *mParent;               // Parent object
668     };
669 
670     struct Camera1DeviceCb :
671             public ::android::hardware::camera::device::V1_0::ICameraDeviceCallback {
Camera1DeviceCbCameraHidlTest::Camera1DeviceCb672         Camera1DeviceCb(CameraHidlTest *parent) : mParent(parent) {}
673 
674         Return<void> notifyCallback(NotifyCallbackMsg msgType,
675                 int32_t ext1, int32_t ext2) override;
676 
677         Return<uint32_t> registerMemory(const hidl_handle& descriptor,
678                 uint32_t bufferSize, uint32_t bufferCount) override;
679 
680         Return<void> unregisterMemory(uint32_t memId) override;
681 
682         Return<void> dataCallback(DataCallbackMsg msgType,
683                 uint32_t data, uint32_t bufferIndex,
684                 const CameraFrameMetadata& metadata) override;
685 
686         Return<void> dataCallbackTimestamp(DataCallbackMsg msgType,
687                 uint32_t data, uint32_t bufferIndex,
688                 int64_t timestamp) override;
689 
690         Return<void> handleCallbackTimestamp(DataCallbackMsg msgType,
691                 const hidl_handle& frameData,uint32_t data,
692                 uint32_t bufferIndex, int64_t timestamp) override;
693 
694         Return<void> handleCallbackTimestampBatch(DataCallbackMsg msgType,
695                 const ::android::hardware::hidl_vec<HandleTimestampMessage>& batch) override;
696 
697 
698      private:
699         CameraHidlTest *mParent;               // Parent object
700     };
701 
702     void notifyDeviceState(::android::hardware::camera::provider::V2_5::DeviceState newState);
703 
704     void openCameraDevice(const std::string &name, sp<ICameraProvider> provider,
705             sp<::android::hardware::camera::device::V1_0::ICameraDevice> *device /*out*/);
706     void setupPreviewWindow(
707             const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device,
708             sp<BufferItemConsumer> *bufferItemConsumer /*out*/,
709             sp<BufferItemHander> *bufferHandler /*out*/);
710     void stopPreviewAndClose(
711             const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device);
712     void startPreview(
713             const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device);
714     void enableMsgType(unsigned int msgType,
715             const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device);
716     void disableMsgType(unsigned int msgType,
717             const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device);
718     void getParameters(
719             const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device,
720             CameraParameters *cameraParams /*out*/);
721     void setParameters(
722             const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device,
723             const CameraParameters &cameraParams);
724     void allocateGraphicBuffer(uint32_t width, uint32_t height, uint64_t usage,
725             PixelFormat format, hidl_handle *buffer_handle /*out*/);
726     void waitForFrameLocked(DataCallbackMsg msgFrame,
727             std::unique_lock<std::mutex> &l);
728     void openEmptyDeviceSession(const std::string &name,
729             sp<ICameraProvider> provider,
730             sp<ICameraDeviceSession> *session /*out*/,
731             camera_metadata_t **staticMeta /*out*/,
732             ::android::sp<ICameraDevice> *device = nullptr/*out*/);
733     void castProvider(const sp<provider::V2_4::ICameraProvider> &provider,
734             sp<provider::V2_5::ICameraProvider> *provider2_5 /*out*/);
735     void castSession(const sp<ICameraDeviceSession> &session, int32_t deviceVersion,
736             sp<device::V3_3::ICameraDeviceSession> *session3_3 /*out*/,
737             sp<device::V3_4::ICameraDeviceSession> *session3_4 /*out*/,
738             sp<device::V3_5::ICameraDeviceSession> *session3_5 /*out*/);
739     void castDevice(const sp<device::V3_2::ICameraDevice> &device, int32_t deviceVersion,
740             sp<device::V3_5::ICameraDevice> *device3_5/*out*/);
741     void createStreamConfiguration(const ::android::hardware::hidl_vec<V3_2::Stream>& streams3_2,
742             StreamConfigurationMode configMode,
743             ::android::hardware::camera::device::V3_2::StreamConfiguration *config3_2,
744             ::android::hardware::camera::device::V3_4::StreamConfiguration *config3_4,
745             ::android::hardware::camera::device::V3_5::StreamConfiguration *config3_5,
746             uint32_t jpegBufferSize = 0);
747 
748     void configurePreviewStreams3_4(const std::string &name, int32_t deviceVersion,
749             sp<ICameraProvider> provider,
750             const AvailableStream *previewThreshold,
751             const std::unordered_set<std::string>& physicalIds,
752             sp<device::V3_4::ICameraDeviceSession> *session3_4 /*out*/,
753             sp<device::V3_5::ICameraDeviceSession> *session3_5 /*out*/,
754             V3_2::Stream* previewStream /*out*/,
755             device::V3_4::HalStreamConfiguration *halStreamConfig /*out*/,
756             bool *supportsPartialResults /*out*/,
757             uint32_t *partialResultCount /*out*/,
758             bool *useHalBufManager /*out*/,
759             sp<DeviceCb> *cb /*out*/,
760             uint32_t streamConfigCounter = 0,
761             bool allowUnsupport = false);
762     void configurePreviewStream(const std::string &name, int32_t deviceVersion,
763             sp<ICameraProvider> provider,
764             const AvailableStream *previewThreshold,
765             sp<ICameraDeviceSession> *session /*out*/,
766             V3_2::Stream *previewStream /*out*/,
767             HalStreamConfiguration *halStreamConfig /*out*/,
768             bool *supportsPartialResults /*out*/,
769             uint32_t *partialResultCount /*out*/,
770             bool *useHalBufManager /*out*/,
771             sp<DeviceCb> *cb /*out*/,
772             uint32_t streamConfigCounter = 0);
773 
774     void verifyLogicalCameraMetadata(const std::string& cameraName,
775             const ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice>& device,
776             const CameraMetadata& chars, int deviceVersion,
777             const hidl_vec<hidl_string>& deviceNames);
778     void verifyCameraCharacteristics(Status status, const CameraMetadata& chars);
779     void verifyRecommendedConfigs(const CameraMetadata& metadata);
780     void verifyMonochromeCharacteristics(const CameraMetadata& chars, int deviceVersion);
781     void verifyMonochromeCameraResult(
782             const ::android::hardware::camera::common::V1_0::helper::CameraMetadata& metadata);
783     void verifyStreamCombination(sp<device::V3_5::ICameraDevice> cameraDevice3_5,
784             const ::android::hardware::camera::device::V3_4::StreamConfiguration &config3_4,
785             bool expectedStatus, bool expectStreamCombQuery);
786     void verifyLogicalCameraResult(const camera_metadata_t* staticMetadata,
787             const ::android::hardware::camera::common::V1_0::helper::CameraMetadata& resultMetadata);
788 
789     void verifyBuffersReturned(sp<device::V3_2::ICameraDeviceSession> session,
790             int deviceVerison, int32_t streamId, sp<DeviceCb> cb,
791             uint32_t streamConfigCounter = 0);
792 
793     void verifyBuffersReturned(sp<device::V3_4::ICameraDeviceSession> session,
794             hidl_vec<int32_t> streamIds, sp<DeviceCb> cb,
795             uint32_t streamConfigCounter = 0);
796 
797     void verifySessionReconfigurationQuery(sp<device::V3_5::ICameraDeviceSession> session3_5,
798             camera_metadata* oldSessionParams, camera_metadata* newSessionParams);
799 
800     bool isDepthOnly(camera_metadata_t* staticMeta);
801 
802     static Status getAvailableOutputStreams(camera_metadata_t *staticMeta,
803             std::vector<AvailableStream> &outputStreams,
804             const AvailableStream *threshold = nullptr);
805     static Status getJpegBufferSize(camera_metadata_t *staticMeta,
806             uint32_t* outBufSize);
807     static Status isConstrainedModeAvailable(camera_metadata_t *staticMeta);
808     static Status isLogicalMultiCamera(const camera_metadata_t *staticMeta);
809     static Status getPhysicalCameraIds(const camera_metadata_t *staticMeta,
810             std::unordered_set<std::string> *physicalIds/*out*/);
811     static Status getSupportedKeys(camera_metadata_t *staticMeta,
812             uint32_t tagId, std::unordered_set<int32_t> *requestIDs/*out*/);
813     static void fillOutputStreams(camera_metadata_ro_entry_t* entry,
814             std::vector<AvailableStream>& outputStreams,
815             const AvailableStream *threshold = nullptr,
816             const int32_t availableConfigOutputTag = 0u);
817     static void constructFilteredSettings(const sp<ICameraDeviceSession>& session,
818             const std::unordered_set<int32_t>& availableKeys, RequestTemplate reqTemplate,
819             android::hardware::camera::common::V1_0::helper::CameraMetadata* defaultSettings/*out*/,
820             android::hardware::camera::common::V1_0::helper::CameraMetadata* filteredSettings
821             /*out*/);
822     static Status pickConstrainedModeSize(camera_metadata_t *staticMeta,
823             AvailableStream &hfrStream);
824     static Status isZSLModeAvailable(const camera_metadata_t *staticMeta);
825     static Status isZSLModeAvailable(const camera_metadata_t *staticMeta, ReprocessType reprocType);
826     static Status getZSLInputOutputMap(camera_metadata_t *staticMeta,
827             std::vector<AvailableZSLInputOutput> &inputOutputMap);
828     static Status findLargestSize(
829             const std::vector<AvailableStream> &streamSizes,
830             int32_t format, AvailableStream &result);
831     static Status isAutoFocusModeAvailable(
832             CameraParameters &cameraParams, const char *mode) ;
833     static Status isMonochromeCamera(const camera_metadata_t *staticMeta);
834 
835 protected:
836 
837     // In-flight queue for tracking completion of capture requests.
838     struct InFlightRequest {
839         // Set by notify() SHUTTER call.
840         nsecs_t shutterTimestamp;
841 
842         bool errorCodeValid;
843         ErrorCode errorCode;
844 
845         //Is partial result supported
846         bool usePartialResult;
847 
848         //Partial result count expected
849         uint32_t numPartialResults;
850 
851         // Message queue
852         std::shared_ptr<ResultMetadataQueue> resultQueue;
853 
854         // Set by process_capture_result call with valid metadata
855         bool haveResultMetadata;
856 
857         // Decremented by calls to process_capture_result with valid output
858         // and input buffers
859         ssize_t numBuffersLeft;
860 
861          // A 64bit integer to index the frame number associated with this result.
862         int64_t frameNumber;
863 
864          // The partial result count (index) for this capture result.
865         int32_t partialResultCount;
866 
867         // For buffer drop errors, the stream ID for the stream that lost a buffer.
868         // Otherwise -1.
869         int32_t errorStreamId;
870 
871         // If this request has any input buffer
872         bool hasInputBuffer;
873 
874         // Result metadata
875         ::android::hardware::camera::common::V1_0::helper::CameraMetadata collectedResult;
876 
877         // Buffers are added by process_capture_result when output buffers
878         // return from HAL but framework.
879         ::android::Vector<StreamBuffer> resultOutputBuffers;
880 
InFlightRequestCameraHidlTest::InFlightRequest881         InFlightRequest() :
882                 shutterTimestamp(0),
883                 errorCodeValid(false),
884                 errorCode(ErrorCode::ERROR_BUFFER),
885                 usePartialResult(false),
886                 numPartialResults(0),
887                 resultQueue(nullptr),
888                 haveResultMetadata(false),
889                 numBuffersLeft(0),
890                 frameNumber(0),
891                 partialResultCount(0),
892                 errorStreamId(-1),
893                 hasInputBuffer(false) {}
894 
InFlightRequestCameraHidlTest::InFlightRequest895         InFlightRequest(ssize_t numBuffers, bool hasInput,
896                 bool partialResults, uint32_t partialCount,
897                 std::shared_ptr<ResultMetadataQueue> queue = nullptr) :
898                 shutterTimestamp(0),
899                 errorCodeValid(false),
900                 errorCode(ErrorCode::ERROR_BUFFER),
901                 usePartialResult(partialResults),
902                 numPartialResults(partialCount),
903                 resultQueue(queue),
904                 haveResultMetadata(false),
905                 numBuffersLeft(numBuffers),
906                 frameNumber(0),
907                 partialResultCount(0),
908                 errorStreamId(-1),
909                 hasInputBuffer(hasInput) {}
910     };
911 
912     // Map from frame number to the in-flight request state
913     typedef ::android::KeyedVector<uint32_t, InFlightRequest*> InFlightMap;
914 
915     std::mutex mLock;                          // Synchronize access to member variables
916     std::condition_variable mResultCondition;  // Condition variable for incoming results
917     InFlightMap mInflightMap;                  // Map of all inflight requests
918 
919     DataCallbackMsg mDataMessageTypeReceived;  // Most recent message type received through data callbacks
920     uint32_t mVideoBufferIndex;                // Buffer index of the most recent video buffer
921     uint32_t mVideoData;                       // Buffer data of the most recent video buffer
922     hidl_handle mVideoNativeHandle;            // Most recent video buffer native handle
923     NotifyCallbackMsg mNotifyMessage;          // Current notification message
924 
925     std::mutex mTorchLock;                     // Synchronize access to torch status
926     std::condition_variable mTorchCond;        // Condition variable for torch status
927     TorchModeStatus mTorchStatus;              // Current torch status
928 
929     // Holds camera registered buffers
930     std::unordered_map<uint32_t, sp<::android::MemoryHeapBase> > mMemoryPool;
931 
932     // Camera provider service
933     sp<ICameraProvider> mProvider;
934     sp<::android::hardware::camera::provider::V2_5::ICameraProvider> mProvider2_5;
935 
936     // Camera provider type.
937     std::string mProviderType;
938 };
939 
notifyCallback(NotifyCallbackMsg msgType,int32_t ext1 __unused,int32_t ext2 __unused)940 Return<void> CameraHidlTest::Camera1DeviceCb::notifyCallback(
941         NotifyCallbackMsg msgType, int32_t ext1 __unused,
942         int32_t ext2 __unused) {
943     std::unique_lock<std::mutex> l(mParent->mLock);
944     mParent->mNotifyMessage = msgType;
945     mParent->mResultCondition.notify_one();
946 
947     return Void();
948 }
949 
registerMemory(const hidl_handle & descriptor,uint32_t bufferSize,uint32_t bufferCount)950 Return<uint32_t> CameraHidlTest::Camera1DeviceCb::registerMemory(
951         const hidl_handle& descriptor, uint32_t bufferSize,
952         uint32_t bufferCount) {
953     if (descriptor->numFds != 1) {
954         ADD_FAILURE() << "camera memory descriptor has"
955                 " numFds " <<  descriptor->numFds << " (expect 1)" ;
956         return 0;
957     }
958     if (descriptor->data[0] < 0) {
959         ADD_FAILURE() << "camera memory descriptor has"
960                 " FD " << descriptor->data[0] << " (expect >= 0)";
961         return 0;
962     }
963 
964     sp<::android::MemoryHeapBase> pool = new ::android::MemoryHeapBase(
965             descriptor->data[0], bufferSize*bufferCount, 0, 0);
966     mParent->mMemoryPool.emplace(pool->getHeapID(), pool);
967 
968     return pool->getHeapID();
969 }
970 
unregisterMemory(uint32_t memId)971 Return<void> CameraHidlTest::Camera1DeviceCb::unregisterMemory(uint32_t memId) {
972     if (mParent->mMemoryPool.count(memId) == 0) {
973         ALOGE("%s: memory pool ID %d not found", __FUNCTION__, memId);
974         ADD_FAILURE();
975         return Void();
976     }
977 
978     mParent->mMemoryPool.erase(memId);
979     return Void();
980 }
981 
dataCallback(DataCallbackMsg msgType __unused,uint32_t data __unused,uint32_t bufferIndex __unused,const CameraFrameMetadata & metadata __unused)982 Return<void> CameraHidlTest::Camera1DeviceCb::dataCallback(
983         DataCallbackMsg msgType __unused, uint32_t data __unused,
984         uint32_t bufferIndex __unused,
985         const CameraFrameMetadata& metadata __unused) {
986     std::unique_lock<std::mutex> l(mParent->mLock);
987     mParent->mDataMessageTypeReceived = msgType;
988     mParent->mResultCondition.notify_one();
989 
990     return Void();
991 }
992 
dataCallbackTimestamp(DataCallbackMsg msgType,uint32_t data,uint32_t bufferIndex,int64_t timestamp __unused)993 Return<void> CameraHidlTest::Camera1DeviceCb::dataCallbackTimestamp(
994         DataCallbackMsg msgType, uint32_t data,
995         uint32_t bufferIndex, int64_t timestamp __unused) {
996     std::unique_lock<std::mutex> l(mParent->mLock);
997     mParent->mDataMessageTypeReceived = msgType;
998     mParent->mVideoBufferIndex = bufferIndex;
999     if (mParent->mMemoryPool.count(data) == 0) {
1000         ADD_FAILURE() << "memory pool ID " << data << "not found";
1001     }
1002     mParent->mVideoData = data;
1003     mParent->mResultCondition.notify_one();
1004 
1005     return Void();
1006 }
1007 
handleCallbackTimestamp(DataCallbackMsg msgType,const hidl_handle & frameData,uint32_t data __unused,uint32_t bufferIndex,int64_t timestamp __unused)1008 Return<void> CameraHidlTest::Camera1DeviceCb::handleCallbackTimestamp(
1009         DataCallbackMsg msgType, const hidl_handle& frameData,
1010         uint32_t data __unused, uint32_t bufferIndex,
1011         int64_t timestamp __unused) {
1012     std::unique_lock<std::mutex> l(mParent->mLock);
1013     mParent->mDataMessageTypeReceived = msgType;
1014     mParent->mVideoBufferIndex = bufferIndex;
1015     if (mParent->mMemoryPool.count(data) == 0) {
1016         ADD_FAILURE() << "memory pool ID " << data << " not found";
1017     }
1018     mParent->mVideoData = data;
1019     mParent->mVideoNativeHandle = frameData;
1020     mParent->mResultCondition.notify_one();
1021 
1022     return Void();
1023 }
1024 
handleCallbackTimestampBatch(DataCallbackMsg msgType,const hidl_vec<HandleTimestampMessage> & batch)1025 Return<void> CameraHidlTest::Camera1DeviceCb::handleCallbackTimestampBatch(
1026         DataCallbackMsg msgType,
1027         const hidl_vec<HandleTimestampMessage>& batch) {
1028     std::unique_lock<std::mutex> l(mParent->mLock);
1029     for (auto& msg : batch) {
1030         mParent->mDataMessageTypeReceived = msgType;
1031         mParent->mVideoBufferIndex = msg.bufferIndex;
1032         if (mParent->mMemoryPool.count(msg.data) == 0) {
1033             ADD_FAILURE() << "memory pool ID " << msg.data << " not found";
1034         }
1035         mParent->mVideoData = msg.data;
1036         mParent->mVideoNativeHandle = msg.frameData;
1037         mParent->mResultCondition.notify_one();
1038     }
1039     return Void();
1040 }
1041 
processCaptureResult_3_4(const hidl_vec<V3_4::CaptureResult> & results)1042 Return<void> CameraHidlTest::DeviceCb::processCaptureResult_3_4(
1043         const hidl_vec<V3_4::CaptureResult>& results) {
1044 
1045     if (nullptr == mParent) {
1046         return Void();
1047     }
1048 
1049     bool notify = false;
1050     std::unique_lock<std::mutex> l(mParent->mLock);
1051     for (size_t i = 0 ; i < results.size(); i++) {
1052         notify = processCaptureResultLocked(results[i].v3_2, results[i].physicalCameraMetadata);
1053     }
1054 
1055     l.unlock();
1056     if (notify) {
1057         mParent->mResultCondition.notify_one();
1058     }
1059 
1060     return Void();
1061 }
1062 
processCaptureResult(const hidl_vec<CaptureResult> & results)1063 Return<void> CameraHidlTest::DeviceCb::processCaptureResult(
1064         const hidl_vec<CaptureResult>& results) {
1065     if (nullptr == mParent) {
1066         return Void();
1067     }
1068 
1069     bool notify = false;
1070     std::unique_lock<std::mutex> l(mParent->mLock);
1071     ::android::hardware::hidl_vec<PhysicalCameraMetadata> noPhysMetadata;
1072     for (size_t i = 0 ; i < results.size(); i++) {
1073         notify = processCaptureResultLocked(results[i], noPhysMetadata);
1074     }
1075 
1076     l.unlock();
1077     if (notify) {
1078         mParent->mResultCondition.notify_one();
1079     }
1080 
1081     return Void();
1082 }
1083 
processCaptureResultLocked(const CaptureResult & results,hidl_vec<PhysicalCameraMetadata> physicalCameraMetadata)1084 bool CameraHidlTest::DeviceCb::processCaptureResultLocked(const CaptureResult& results,
1085         hidl_vec<PhysicalCameraMetadata> physicalCameraMetadata) {
1086     bool notify = false;
1087     uint32_t frameNumber = results.frameNumber;
1088 
1089     if ((results.result.size() == 0) &&
1090             (results.outputBuffers.size() == 0) &&
1091             (results.inputBuffer.buffer == nullptr) &&
1092             (results.fmqResultSize == 0)) {
1093         ALOGE("%s: No result data provided by HAL for frame %d result count: %d",
1094                 __func__, frameNumber, (int) results.fmqResultSize);
1095         ADD_FAILURE();
1096         return notify;
1097     }
1098 
1099     ssize_t idx = mParent->mInflightMap.indexOfKey(frameNumber);
1100     if (::android::NAME_NOT_FOUND == idx) {
1101         ALOGE("%s: Unexpected frame number! received: %u",
1102                 __func__, frameNumber);
1103         ADD_FAILURE();
1104         return notify;
1105     }
1106 
1107     bool isPartialResult = false;
1108     bool hasInputBufferInRequest = false;
1109     InFlightRequest *request = mParent->mInflightMap.editValueAt(idx);
1110     ::android::hardware::camera::device::V3_2::CameraMetadata resultMetadata;
1111     size_t resultSize = 0;
1112     if (results.fmqResultSize > 0) {
1113         resultMetadata.resize(results.fmqResultSize);
1114         if (request->resultQueue == nullptr) {
1115             ADD_FAILURE();
1116             return notify;
1117         }
1118         if (!request->resultQueue->read(resultMetadata.data(),
1119                     results.fmqResultSize)) {
1120             ALOGE("%s: Frame %d: Cannot read camera metadata from fmq,"
1121                     "size = %" PRIu64, __func__, frameNumber,
1122                     results.fmqResultSize);
1123             ADD_FAILURE();
1124             return notify;
1125         }
1126 
1127         std::vector<::android::hardware::camera::device::V3_2::CameraMetadata> physResultMetadata;
1128         physResultMetadata.resize(physicalCameraMetadata.size());
1129         for (size_t i = 0; i < physicalCameraMetadata.size(); i++) {
1130             physResultMetadata[i].resize(physicalCameraMetadata[i].fmqMetadataSize);
1131             if (!request->resultQueue->read(physResultMetadata[i].data(),
1132                     physicalCameraMetadata[i].fmqMetadataSize)) {
1133                 ALOGE("%s: Frame %d: Cannot read physical camera metadata from fmq,"
1134                         "size = %" PRIu64, __func__, frameNumber,
1135                         physicalCameraMetadata[i].fmqMetadataSize);
1136                 ADD_FAILURE();
1137                 return notify;
1138             }
1139         }
1140         resultSize = resultMetadata.size();
1141     } else if (results.result.size() > 0) {
1142         resultMetadata.setToExternal(const_cast<uint8_t *>(
1143                     results.result.data()), results.result.size());
1144         resultSize = resultMetadata.size();
1145     }
1146 
1147     if (!request->usePartialResult && (resultSize > 0) &&
1148             (results.partialResult != 1)) {
1149         ALOGE("%s: Result is malformed for frame %d: partial_result %u "
1150                 "must be 1  if partial result is not supported", __func__,
1151                 frameNumber, results.partialResult);
1152         ADD_FAILURE();
1153         return notify;
1154     }
1155 
1156     if (results.partialResult != 0) {
1157         request->partialResultCount = results.partialResult;
1158     }
1159 
1160     // Check if this result carries only partial metadata
1161     if (request->usePartialResult && (resultSize > 0)) {
1162         if ((results.partialResult > request->numPartialResults) ||
1163                 (results.partialResult < 1)) {
1164             ALOGE("%s: Result is malformed for frame %d: partial_result %u"
1165                     " must be  in the range of [1, %d] when metadata is "
1166                     "included in the result", __func__, frameNumber,
1167                     results.partialResult, request->numPartialResults);
1168             ADD_FAILURE();
1169             return notify;
1170         }
1171         request->collectedResult.append(
1172                 reinterpret_cast<const camera_metadata_t*>(
1173                     resultMetadata.data()));
1174 
1175         isPartialResult =
1176             (results.partialResult < request->numPartialResults);
1177     } else if (resultSize > 0) {
1178         request->collectedResult.append(reinterpret_cast<const camera_metadata_t*>(
1179                     resultMetadata.data()));
1180         isPartialResult = false;
1181     }
1182 
1183     hasInputBufferInRequest = request->hasInputBuffer;
1184 
1185     // Did we get the (final) result metadata for this capture?
1186     if ((resultSize > 0) && !isPartialResult) {
1187         if (request->haveResultMetadata) {
1188             ALOGE("%s: Called multiple times with metadata for frame %d",
1189                     __func__, frameNumber);
1190             ADD_FAILURE();
1191             return notify;
1192         }
1193         request->haveResultMetadata = true;
1194         request->collectedResult.sort();
1195 
1196         // Verify final result metadata
1197         bool isAtLeast_3_5 = mDeviceVersion >= CAMERA_DEVICE_API_VERSION_3_5;
1198         if (isAtLeast_3_5) {
1199             auto staticMetadataBuffer = mStaticMetadata.getAndLock();
1200             bool isMonochrome = Status::OK ==
1201                     CameraHidlTest::isMonochromeCamera(staticMetadataBuffer);
1202             if (isMonochrome) {
1203                 mParent->verifyMonochromeCameraResult(request->collectedResult);
1204             }
1205 
1206             // Verify logical camera result metadata
1207             bool isLogicalCamera =
1208                     Status::OK == CameraHidlTest::isLogicalMultiCamera(staticMetadataBuffer);
1209             if (isLogicalCamera) {
1210                 mParent->verifyLogicalCameraResult(staticMetadataBuffer, request->collectedResult);
1211             }
1212             mStaticMetadata.unlock(staticMetadataBuffer);
1213         }
1214     }
1215 
1216     uint32_t numBuffersReturned = results.outputBuffers.size();
1217     if (results.inputBuffer.buffer != nullptr) {
1218         if (hasInputBufferInRequest) {
1219             numBuffersReturned += 1;
1220         } else {
1221             ALOGW("%s: Input buffer should be NULL if there is no input"
1222                     " buffer sent in the request", __func__);
1223         }
1224     }
1225     request->numBuffersLeft -= numBuffersReturned;
1226     if (request->numBuffersLeft < 0) {
1227         ALOGE("%s: Too many buffers returned for frame %d", __func__,
1228                 frameNumber);
1229         ADD_FAILURE();
1230         return notify;
1231     }
1232 
1233     request->resultOutputBuffers.appendArray(results.outputBuffers.data(),
1234             results.outputBuffers.size());
1235     // If shutter event is received notify the pending threads.
1236     if (request->shutterTimestamp != 0) {
1237         notify = true;
1238     }
1239 
1240     if (mUseHalBufManager) {
1241         // Don't return buffers of bufId 0 (empty buffer)
1242         std::vector<StreamBuffer> buffers;
1243         for (const auto& sb : results.outputBuffers) {
1244             if (sb.bufferId != 0) {
1245                 buffers.push_back(sb);
1246             }
1247         }
1248         returnStreamBuffers(buffers);
1249     }
1250     return notify;
1251 }
1252 
setCurrentStreamConfig(const hidl_vec<V3_2::Stream> & streams,const hidl_vec<V3_2::HalStream> & halStreams)1253 void CameraHidlTest::DeviceCb::setCurrentStreamConfig(
1254         const hidl_vec<V3_2::Stream>& streams, const hidl_vec<V3_2::HalStream>& halStreams) {
1255     ASSERT_EQ(streams.size(), halStreams.size());
1256     ASSERT_NE(streams.size(), 0);
1257     for (size_t i = 0; i < streams.size(); i++) {
1258         ASSERT_EQ(streams[i].id, halStreams[i].id);
1259     }
1260     std::lock_guard<std::mutex> l(mLock);
1261     mUseHalBufManager = true;
1262     mStreams = streams;
1263     mHalStreams = halStreams;
1264     mOutstandingBufferIds.clear();
1265     for (size_t i = 0; i < streams.size(); i++) {
1266         mOutstandingBufferIds.emplace_back();
1267     }
1268 }
1269 
hasOutstandingBuffersLocked()1270 bool CameraHidlTest::DeviceCb::hasOutstandingBuffersLocked() {
1271     if (!mUseHalBufManager) {
1272         return false;
1273     }
1274     for (const auto& outstandingBuffers : mOutstandingBufferIds) {
1275         if (!outstandingBuffers.empty()) {
1276             return true;
1277         }
1278     }
1279     return false;
1280 }
1281 
waitForBuffersReturned()1282 void CameraHidlTest::DeviceCb::waitForBuffersReturned() {
1283     std::unique_lock<std::mutex> lk(mLock);
1284     if (hasOutstandingBuffersLocked()) {
1285         auto timeout = std::chrono::seconds(kBufferReturnTimeoutSec);
1286         auto st = mFlushedCondition.wait_for(lk, timeout);
1287         ASSERT_NE(std::cv_status::timeout, st);
1288     }
1289 }
1290 
notify(const hidl_vec<NotifyMsg> & messages)1291 Return<void> CameraHidlTest::DeviceCb::notify(
1292         const hidl_vec<NotifyMsg>& messages) {
1293     std::lock_guard<std::mutex> l(mParent->mLock);
1294 
1295     for (size_t i = 0; i < messages.size(); i++) {
1296         ssize_t idx = mParent->mInflightMap.indexOfKey(
1297                 messages[i].msg.shutter.frameNumber);
1298         if (::android::NAME_NOT_FOUND == idx) {
1299             ALOGE("%s: Unexpected frame number! received: %u",
1300                   __func__, messages[i].msg.shutter.frameNumber);
1301             ADD_FAILURE();
1302             break;
1303         }
1304         InFlightRequest *r = mParent->mInflightMap.editValueAt(idx);
1305 
1306         switch(messages[i].type) {
1307             case MsgType::ERROR:
1308                 if (ErrorCode::ERROR_DEVICE == messages[i].msg.error.errorCode) {
1309                     ALOGE("%s: Camera reported serious device error",
1310                           __func__);
1311                     ADD_FAILURE();
1312                 } else {
1313                     r->errorCodeValid = true;
1314                     r->errorCode = messages[i].msg.error.errorCode;
1315                     r->errorStreamId = messages[i].msg.error.errorStreamId;
1316                 }
1317                 break;
1318             case MsgType::SHUTTER:
1319                 r->shutterTimestamp = messages[i].msg.shutter.timestamp;
1320                 break;
1321             default:
1322                 ALOGE("%s: Unsupported notify message %d", __func__,
1323                       messages[i].type);
1324                 ADD_FAILURE();
1325                 break;
1326         }
1327     }
1328 
1329     mParent->mResultCondition.notify_one();
1330     return Void();
1331 }
1332 
requestStreamBuffers(const hidl_vec<V3_5::BufferRequest> & bufReqs,requestStreamBuffers_cb _hidl_cb)1333 Return<void> CameraHidlTest::DeviceCb::requestStreamBuffers(
1334         const hidl_vec<V3_5::BufferRequest>& bufReqs,
1335         requestStreamBuffers_cb _hidl_cb) {
1336     using V3_5::BufferRequestStatus;
1337     using V3_5::StreamBufferRet;
1338     using V3_5::StreamBufferRequestError;
1339     hidl_vec<StreamBufferRet> bufRets;
1340     std::unique_lock<std::mutex> l(mLock);
1341 
1342     if (!mUseHalBufManager) {
1343         ALOGE("%s: Camera does not support HAL buffer management", __FUNCTION__);
1344         ADD_FAILURE();
1345         _hidl_cb(BufferRequestStatus::FAILED_ILLEGAL_ARGUMENTS, bufRets);
1346         return Void();
1347     }
1348 
1349     if (bufReqs.size() > mStreams.size()) {
1350         ALOGE("%s: illegal buffer request: too many requests!", __FUNCTION__);
1351         ADD_FAILURE();
1352         _hidl_cb(BufferRequestStatus::FAILED_ILLEGAL_ARGUMENTS, bufRets);
1353         return Void();
1354     }
1355 
1356     std::vector<int32_t> indexes(bufReqs.size());
1357     for (size_t i = 0; i < bufReqs.size(); i++) {
1358         bool found = false;
1359         for (size_t idx = 0; idx < mStreams.size(); idx++) {
1360             if (bufReqs[i].streamId == mStreams[idx].id) {
1361                 found = true;
1362                 indexes[i] = idx;
1363                 break;
1364             }
1365         }
1366         if (!found) {
1367             ALOGE("%s: illegal buffer request: unknown streamId %d!",
1368                     __FUNCTION__, bufReqs[i].streamId);
1369             ADD_FAILURE();
1370             _hidl_cb(BufferRequestStatus::FAILED_ILLEGAL_ARGUMENTS, bufRets);
1371             return Void();
1372         }
1373     }
1374 
1375     bool allStreamOk = true;
1376     bool atLeastOneStreamOk = false;
1377     bufRets.resize(bufReqs.size());
1378     for (size_t i = 0; i < bufReqs.size(); i++) {
1379         int32_t idx = indexes[i];
1380         const auto& stream = mStreams[idx];
1381         const auto& halStream = mHalStreams[idx];
1382         const V3_5::BufferRequest& bufReq = bufReqs[i];
1383         if (mOutstandingBufferIds[idx].size() + bufReq.numBuffersRequested > halStream.maxBuffers) {
1384             bufRets[i].streamId = stream.id;
1385             bufRets[i].val.error(StreamBufferRequestError::MAX_BUFFER_EXCEEDED);
1386             allStreamOk = false;
1387             continue;
1388         }
1389 
1390         hidl_vec<StreamBuffer> tmpRetBuffers(bufReq.numBuffersRequested);
1391         for (size_t j = 0; j < bufReq.numBuffersRequested; j++) {
1392             hidl_handle buffer_handle;
1393             mParent->allocateGraphicBuffer(stream.width, stream.height,
1394                     android_convertGralloc1To0Usage(
1395                             halStream.producerUsage, halStream.consumerUsage),
1396                     halStream.overrideFormat, &buffer_handle);
1397 
1398             tmpRetBuffers[j] = {stream.id, mNextBufferId, buffer_handle, BufferStatus::OK,
1399                                 nullptr, nullptr};
1400             mOutstandingBufferIds[idx].insert(std::make_pair(mNextBufferId++, buffer_handle));
1401         }
1402         atLeastOneStreamOk = true;
1403         bufRets[i].streamId = stream.id;
1404         bufRets[i].val.buffers(std::move(tmpRetBuffers));
1405     }
1406 
1407     if (allStreamOk) {
1408         _hidl_cb(BufferRequestStatus::OK, bufRets);
1409     } else if (atLeastOneStreamOk) {
1410         _hidl_cb(BufferRequestStatus::FAILED_PARTIAL, bufRets);
1411     } else {
1412         _hidl_cb(BufferRequestStatus::FAILED_UNKNOWN, bufRets);
1413     }
1414 
1415     if (!hasOutstandingBuffersLocked()) {
1416         l.unlock();
1417         mFlushedCondition.notify_one();
1418     }
1419     return Void();
1420 }
1421 
returnStreamBuffers(const hidl_vec<StreamBuffer> & buffers)1422 Return<void> CameraHidlTest::DeviceCb::returnStreamBuffers(
1423         const hidl_vec<StreamBuffer>& buffers) {
1424     if (!mUseHalBufManager) {
1425         ALOGE("%s: Camera does not support HAL buffer management", __FUNCTION__);
1426         ADD_FAILURE();
1427     }
1428 
1429     std::lock_guard<std::mutex> l(mLock);
1430     for (const auto& buf : buffers) {
1431         bool found = false;
1432         for (size_t idx = 0; idx < mOutstandingBufferIds.size(); idx++) {
1433             if (mStreams[idx].id == buf.streamId &&
1434                     mOutstandingBufferIds[idx].count(buf.bufferId) == 1) {
1435                 mOutstandingBufferIds[idx].erase(buf.bufferId);
1436                 // TODO: check do we need to close/delete native handle or assume we have enough
1437                 // memory to run till the test finish? since we do not capture much requests (and
1438                 // most of time one buffer is sufficient)
1439                 found = true;
1440                 break;
1441             }
1442         }
1443         if (found) {
1444             continue;
1445         }
1446         ALOGE("%s: unknown buffer ID %" PRIu64, __FUNCTION__, buf.bufferId);
1447         ADD_FAILURE();
1448     }
1449     return Void();
1450 }
1451 
getCameraDeviceNames(sp<ICameraProvider> provider)1452 hidl_vec<hidl_string> CameraHidlTest::getCameraDeviceNames(sp<ICameraProvider> provider) {
1453     std::vector<std::string> cameraDeviceNames;
1454     Return<void> ret;
1455     ret = provider->getCameraIdList(
1456         [&](auto status, const auto& idList) {
1457             ALOGI("getCameraIdList returns status:%d", (int)status);
1458             for (size_t i = 0; i < idList.size(); i++) {
1459                 ALOGI("Camera Id[%zu] is %s", i, idList[i].c_str());
1460             }
1461             ASSERT_EQ(Status::OK, status);
1462             for (const auto& id : idList) {
1463                 cameraDeviceNames.push_back(id);
1464             }
1465         });
1466     if (!ret.isOk()) {
1467         ADD_FAILURE();
1468     }
1469 
1470     // External camera devices are reported through cameraDeviceStatusChange
1471     struct ProviderCb : public ICameraProviderCallback {
1472         virtual Return<void> cameraDeviceStatusChange(
1473                 const hidl_string& devName,
1474                 CameraDeviceStatus newStatus) override {
1475             ALOGI("camera device status callback name %s, status %d",
1476                     devName.c_str(), (int) newStatus);
1477             if (newStatus == CameraDeviceStatus::PRESENT) {
1478                 externalCameraDeviceNames.push_back(devName);
1479 
1480             }
1481             return Void();
1482         }
1483 
1484         virtual Return<void> torchModeStatusChange(
1485                 const hidl_string&, TorchModeStatus) override {
1486             return Void();
1487         }
1488 
1489         std::vector<std::string> externalCameraDeviceNames;
1490     };
1491     sp<ProviderCb> cb = new ProviderCb;
1492     auto status = mProvider->setCallback(cb);
1493 
1494     for (const auto& devName : cb->externalCameraDeviceNames) {
1495         if (cameraDeviceNames.end() == std::find(
1496                 cameraDeviceNames.begin(), cameraDeviceNames.end(), devName)) {
1497             cameraDeviceNames.push_back(devName);
1498         }
1499     }
1500 
1501     hidl_vec<hidl_string> retList(cameraDeviceNames.size());
1502     for (size_t i = 0; i < cameraDeviceNames.size(); i++) {
1503         retList[i] = cameraDeviceNames[i];
1504     }
1505     return retList;
1506 }
1507 
1508 // Test devices with first_api_level >= P does not advertise device@1.0
TEST_F(CameraHidlTest,noHal1AfterP)1509 TEST_F(CameraHidlTest, noHal1AfterP) {
1510     constexpr int32_t HAL1_PHASE_OUT_API_LEVEL = 28;
1511     int32_t firstApiLevel = 0;
1512     getFirstApiLevel(&firstApiLevel);
1513 
1514     // all devices with first API level == 28 and <= 1GB of RAM must set low_ram
1515     // and thus be allowed to continue using HAL1
1516     if ((firstApiLevel == HAL1_PHASE_OUT_API_LEVEL) &&
1517         (property_get_bool("ro.config.low_ram", /*default*/ false))) {
1518         ALOGI("Hal1 allowed for low ram device");
1519         return;
1520     }
1521 
1522     if (firstApiLevel >= HAL1_PHASE_OUT_API_LEVEL) {
1523         hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
1524         for (const auto& name : cameraDeviceNames) {
1525             int deviceVersion = getCameraDeviceVersion(name, mProviderType);
1526             ASSERT_NE(deviceVersion, 0); // Must be a valid device version
1527             ASSERT_NE(deviceVersion, CAMERA_DEVICE_API_VERSION_1_0); // Must not be device@1.0
1528         }
1529     }
1530 }
1531 
1532 // Test if ICameraProvider::isTorchModeSupported returns Status::OK
1533 // Also if first_api_level >= Q torch API must be supported.
TEST_F(CameraHidlTest,isTorchModeSupported)1534 TEST_F(CameraHidlTest, isTorchModeSupported) {
1535     constexpr int32_t API_LEVEL_Q = 29;
1536     int32_t firstApiLevel = 0;
1537     getFirstApiLevel(&firstApiLevel);
1538 
1539     Return<void> ret;
1540     ret = mProvider->isSetTorchModeSupported([&](auto status, bool support) {
1541         ALOGI("isSetTorchModeSupported returns status:%d supported:%d", (int)status, support);
1542         ASSERT_EQ(Status::OK, status);
1543         if (firstApiLevel >= API_LEVEL_Q) {
1544             ASSERT_EQ(true, support);
1545         }
1546     });
1547     ASSERT_TRUE(ret.isOk());
1548 }
1549 
1550 // TODO: consider removing this test if getCameraDeviceNames() has the same coverage
TEST_F(CameraHidlTest,getCameraIdList)1551 TEST_F(CameraHidlTest, getCameraIdList) {
1552     Return<void> ret;
1553     ret = mProvider->getCameraIdList([&](auto status, const auto& idList) {
1554         ALOGI("getCameraIdList returns status:%d", (int)status);
1555         for (size_t i = 0; i < idList.size(); i++) {
1556             ALOGI("Camera Id[%zu] is %s", i, idList[i].c_str());
1557         }
1558         ASSERT_EQ(Status::OK, status);
1559     });
1560     ASSERT_TRUE(ret.isOk());
1561 }
1562 
1563 // Test if ICameraProvider::getVendorTags returns Status::OK
TEST_F(CameraHidlTest,getVendorTags)1564 TEST_F(CameraHidlTest, getVendorTags) {
1565     Return<void> ret;
1566     ret = mProvider->getVendorTags([&](auto status, const auto& vendorTagSecs) {
1567         ALOGI("getVendorTags returns status:%d numSections %zu", (int)status, vendorTagSecs.size());
1568         for (size_t i = 0; i < vendorTagSecs.size(); i++) {
1569             ALOGI("Vendor tag section %zu name %s", i, vendorTagSecs[i].sectionName.c_str());
1570             for (size_t j = 0; j < vendorTagSecs[i].tags.size(); j++) {
1571                 const auto& tag = vendorTagSecs[i].tags[j];
1572                 ALOGI("Vendor tag id %u name %s type %d", tag.tagId, tag.tagName.c_str(),
1573                       (int)tag.tagType);
1574             }
1575         }
1576         ASSERT_EQ(Status::OK, status);
1577     });
1578     ASSERT_TRUE(ret.isOk());
1579 }
1580 
1581 // Test if ICameraProvider::setCallback returns Status::OK
TEST_F(CameraHidlTest,setCallback)1582 TEST_F(CameraHidlTest, setCallback) {
1583     struct ProviderCb : public ICameraProviderCallback {
1584         virtual Return<void> cameraDeviceStatusChange(
1585                 const hidl_string& cameraDeviceName,
1586                 CameraDeviceStatus newStatus) override {
1587             ALOGI("camera device status callback name %s, status %d",
1588                     cameraDeviceName.c_str(), (int) newStatus);
1589             return Void();
1590         }
1591 
1592         virtual Return<void> torchModeStatusChange(
1593                 const hidl_string& cameraDeviceName,
1594                 TorchModeStatus newStatus) override {
1595             ALOGI("Torch mode status callback name %s, status %d",
1596                     cameraDeviceName.c_str(), (int) newStatus);
1597             return Void();
1598         }
1599     };
1600     sp<ProviderCb> cb = new ProviderCb;
1601     auto status = mProvider->setCallback(cb);
1602     ASSERT_TRUE(status.isOk());
1603     ASSERT_EQ(Status::OK, status);
1604     status = mProvider->setCallback(nullptr);
1605     ASSERT_TRUE(status.isOk());
1606     ASSERT_EQ(Status::OK, status);
1607 }
1608 
1609 // Test if ICameraProvider::getCameraDeviceInterface returns Status::OK and non-null device
TEST_F(CameraHidlTest,getCameraDeviceInterface)1610 TEST_F(CameraHidlTest, getCameraDeviceInterface) {
1611     hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
1612 
1613     for (const auto& name : cameraDeviceNames) {
1614         int deviceVersion = getCameraDeviceVersion(name, mProviderType);
1615         switch (deviceVersion) {
1616             case CAMERA_DEVICE_API_VERSION_3_5:
1617             case CAMERA_DEVICE_API_VERSION_3_4:
1618             case CAMERA_DEVICE_API_VERSION_3_3:
1619             case CAMERA_DEVICE_API_VERSION_3_2: {
1620                 Return<void> ret;
1621                 ret = mProvider->getCameraDeviceInterface_V3_x(
1622                     name, [&](auto status, const auto& device3_x) {
1623                         ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
1624                         ASSERT_EQ(Status::OK, status);
1625                         ASSERT_NE(device3_x, nullptr);
1626                     });
1627                 ASSERT_TRUE(ret.isOk());
1628             }
1629             break;
1630             case CAMERA_DEVICE_API_VERSION_1_0: {
1631                 Return<void> ret;
1632                 ret = mProvider->getCameraDeviceInterface_V1_x(
1633                     name, [&](auto status, const auto& device1) {
1634                         ALOGI("getCameraDeviceInterface_V1_x returns status:%d", (int)status);
1635                         ASSERT_EQ(Status::OK, status);
1636                         ASSERT_NE(device1, nullptr);
1637                     });
1638                 ASSERT_TRUE(ret.isOk());
1639             }
1640             break;
1641             default: {
1642                 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
1643                 ADD_FAILURE();
1644             }
1645             break;
1646         }
1647     }
1648 }
1649 
1650 // Verify that the device resource cost can be retrieved and the values are
1651 // sane.
TEST_F(CameraHidlTest,getResourceCost)1652 TEST_F(CameraHidlTest, getResourceCost) {
1653     hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
1654 
1655     for (const auto& name : cameraDeviceNames) {
1656         int deviceVersion = getCameraDeviceVersion(name, mProviderType);
1657         switch (deviceVersion) {
1658             case CAMERA_DEVICE_API_VERSION_3_5:
1659             case CAMERA_DEVICE_API_VERSION_3_4:
1660             case CAMERA_DEVICE_API_VERSION_3_3:
1661             case CAMERA_DEVICE_API_VERSION_3_2: {
1662                 ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_x;
1663                 ALOGI("getResourceCost: Testing camera device %s", name.c_str());
1664                 Return<void> ret;
1665                 ret = mProvider->getCameraDeviceInterface_V3_x(
1666                     name, [&](auto status, const auto& device) {
1667                         ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
1668                         ASSERT_EQ(Status::OK, status);
1669                         ASSERT_NE(device, nullptr);
1670                         device3_x = device;
1671                     });
1672                 ASSERT_TRUE(ret.isOk());
1673 
1674                 ret = device3_x->getResourceCost([&](auto status, const auto& resourceCost) {
1675                     ALOGI("getResourceCost returns status:%d", (int)status);
1676                     ASSERT_EQ(Status::OK, status);
1677                     ALOGI("    Resource cost is %d", resourceCost.resourceCost);
1678                     ASSERT_LE(resourceCost.resourceCost, 100u);
1679                     for (const auto& name : resourceCost.conflictingDevices) {
1680                         ALOGI("    Conflicting device: %s", name.c_str());
1681                     }
1682                 });
1683                 ASSERT_TRUE(ret.isOk());
1684             }
1685             break;
1686             case CAMERA_DEVICE_API_VERSION_1_0: {
1687                 ::android::sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
1688                 ALOGI("getResourceCost: Testing camera device %s", name.c_str());
1689                 Return<void> ret;
1690                 ret = mProvider->getCameraDeviceInterface_V1_x(
1691                     name, [&](auto status, const auto& device) {
1692                         ALOGI("getCameraDeviceInterface_V1_x returns status:%d", (int)status);
1693                         ASSERT_EQ(Status::OK, status);
1694                         ASSERT_NE(device, nullptr);
1695                         device1 = device;
1696                     });
1697                 ASSERT_TRUE(ret.isOk());
1698 
1699                 ret = device1->getResourceCost([&](auto status, const auto& resourceCost) {
1700                     ALOGI("getResourceCost returns status:%d", (int)status);
1701                     ASSERT_EQ(Status::OK, status);
1702                     ALOGI("    Resource cost is %d", resourceCost.resourceCost);
1703                     ASSERT_LE(resourceCost.resourceCost, 100u);
1704                     for (const auto& name : resourceCost.conflictingDevices) {
1705                         ALOGI("    Conflicting device: %s", name.c_str());
1706                     }
1707                 });
1708                 ASSERT_TRUE(ret.isOk());
1709             }
1710             break;
1711             default: {
1712                 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
1713                 ADD_FAILURE();
1714             }
1715             break;
1716         }
1717     }
1718 }
1719 
1720 // Verify that the static camera info can be retrieved
1721 // successfully.
TEST_F(CameraHidlTest,getCameraInfo)1722 TEST_F(CameraHidlTest, getCameraInfo) {
1723     hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
1724 
1725     for (const auto& name : cameraDeviceNames) {
1726         if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_1_0) {
1727             ::android::sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
1728             ALOGI("getCameraCharacteristics: Testing camera device %s", name.c_str());
1729             Return<void> ret;
1730             ret = mProvider->getCameraDeviceInterface_V1_x(
1731                 name, [&](auto status, const auto& device) {
1732                     ALOGI("getCameraDeviceInterface_V1_x returns status:%d", (int)status);
1733                     ASSERT_EQ(Status::OK, status);
1734                     ASSERT_NE(device, nullptr);
1735                     device1 = device;
1736                 });
1737             ASSERT_TRUE(ret.isOk());
1738 
1739             ret = device1->getCameraInfo([&](auto status, const auto& info) {
1740                 ALOGI("getCameraInfo returns status:%d", (int)status);
1741                 ASSERT_EQ(Status::OK, status);
1742                 switch (info.orientation) {
1743                     case 0:
1744                     case 90:
1745                     case 180:
1746                     case 270:
1747                         // Expected cases
1748                         ALOGI("camera orientation: %d", info.orientation);
1749                         break;
1750                     default:
1751                         FAIL() << "Unexpected camera orientation:" << info.orientation;
1752                 }
1753                 switch (info.facing) {
1754                     case CameraFacing::BACK:
1755                     case CameraFacing::FRONT:
1756                     case CameraFacing::EXTERNAL:
1757                         // Expected cases
1758                         ALOGI("camera facing: %d", info.facing);
1759                         break;
1760                     default:
1761                         FAIL() << "Unexpected camera facing:" << static_cast<uint32_t>(info.facing);
1762                 }
1763             });
1764             ASSERT_TRUE(ret.isOk());
1765         }
1766     }
1767 }
1768 
1769 // Check whether preview window can be configured
TEST_F(CameraHidlTest,setPreviewWindow)1770 TEST_F(CameraHidlTest, setPreviewWindow) {
1771     hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
1772 
1773     for (const auto& name : cameraDeviceNames) {
1774         if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_1_0) {
1775             sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
1776             openCameraDevice(name, mProvider, &device1 /*out*/);
1777             ASSERT_NE(nullptr, device1.get());
1778             sp<BufferItemConsumer> bufferItemConsumer;
1779             sp<BufferItemHander> bufferHandler;
1780             setupPreviewWindow(device1, &bufferItemConsumer /*out*/, &bufferHandler /*out*/);
1781 
1782             Return<void> ret;
1783             ret = device1->close();
1784             ASSERT_TRUE(ret.isOk());
1785         }
1786     }
1787 }
1788 
1789 // Verify that setting preview window fails in case device is not open
TEST_F(CameraHidlTest,setPreviewWindowInvalid)1790 TEST_F(CameraHidlTest, setPreviewWindowInvalid) {
1791     hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
1792 
1793     for (const auto& name : cameraDeviceNames) {
1794         if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_1_0) {
1795             ::android::sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
1796             ALOGI("getCameraCharacteristics: Testing camera device %s", name.c_str());
1797             Return<void> ret;
1798             ret = mProvider->getCameraDeviceInterface_V1_x(
1799                 name, [&](auto status, const auto& device) {
1800                     ALOGI("getCameraDeviceInterface_V1_x returns status:%d", (int)status);
1801                     ASSERT_EQ(Status::OK, status);
1802                     ASSERT_NE(device, nullptr);
1803                     device1 = device;
1804                 });
1805             ASSERT_TRUE(ret.isOk());
1806 
1807             Return<Status> returnStatus = device1->setPreviewWindow(nullptr);
1808             ASSERT_TRUE(returnStatus.isOk());
1809             ASSERT_EQ(Status::OPERATION_NOT_SUPPORTED, returnStatus);
1810         }
1811     }
1812 }
1813 
1814 // Start and stop preview checking whether it gets enabled in between.
TEST_F(CameraHidlTest,startStopPreview)1815 TEST_F(CameraHidlTest, startStopPreview) {
1816     hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
1817 
1818     for (const auto& name : cameraDeviceNames) {
1819         if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_1_0) {
1820             sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
1821             openCameraDevice(name, mProvider, &device1 /*out*/);
1822             ASSERT_NE(nullptr, device1.get());
1823             sp<BufferItemConsumer> bufferItemConsumer;
1824             sp<BufferItemHander> bufferHandler;
1825             setupPreviewWindow(device1, &bufferItemConsumer /*out*/, &bufferHandler /*out*/);
1826 
1827             startPreview(device1);
1828 
1829             Return<bool> returnBoolStatus = device1->previewEnabled();
1830             ASSERT_TRUE(returnBoolStatus.isOk());
1831             ASSERT_TRUE(returnBoolStatus);
1832 
1833             stopPreviewAndClose(device1);
1834         }
1835     }
1836 }
1837 
1838 // Start preview without active preview window. Preview should start as soon
1839 // as a valid active window gets configured.
TEST_F(CameraHidlTest,startStopPreviewDelayed)1840 TEST_F(CameraHidlTest, startStopPreviewDelayed) {
1841     hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
1842 
1843     for (const auto& name : cameraDeviceNames) {
1844         if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_1_0) {
1845             sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
1846             openCameraDevice(name, mProvider, &device1 /*out*/);
1847             ASSERT_NE(nullptr, device1.get());
1848 
1849             Return<Status> returnStatus = device1->setPreviewWindow(nullptr);
1850             ASSERT_TRUE(returnStatus.isOk());
1851             ASSERT_EQ(Status::OK, returnStatus);
1852 
1853             startPreview(device1);
1854 
1855             sp<BufferItemConsumer> bufferItemConsumer;
1856             sp<BufferItemHander> bufferHandler;
1857             setupPreviewWindow(device1, &bufferItemConsumer /*out*/, &bufferHandler /*out*/);
1858 
1859             // Preview should get enabled now
1860             Return<bool> returnBoolStatus = device1->previewEnabled();
1861             ASSERT_TRUE(returnBoolStatus.isOk());
1862             ASSERT_TRUE(returnBoolStatus);
1863 
1864             stopPreviewAndClose(device1);
1865         }
1866     }
1867 }
1868 
1869 // Verify that image capture behaves as expected along with preview callbacks.
TEST_F(CameraHidlTest,takePicture)1870 TEST_F(CameraHidlTest, takePicture) {
1871     hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
1872 
1873     for (const auto& name : cameraDeviceNames) {
1874         if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_1_0) {
1875             sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
1876             openCameraDevice(name, mProvider, &device1 /*out*/);
1877             ASSERT_NE(nullptr, device1.get());
1878             sp<BufferItemConsumer> bufferItemConsumer;
1879             sp<BufferItemHander> bufferHandler;
1880             setupPreviewWindow(device1, &bufferItemConsumer /*out*/, &bufferHandler /*out*/);
1881 
1882             {
1883                 std::unique_lock<std::mutex> l(mLock);
1884                 mDataMessageTypeReceived = DataCallbackMsg::RAW_IMAGE_NOTIFY;
1885             }
1886 
1887             enableMsgType((unsigned int)DataCallbackMsg::PREVIEW_FRAME, device1);
1888             startPreview(device1);
1889 
1890             {
1891                 std::unique_lock<std::mutex> l(mLock);
1892                 waitForFrameLocked(DataCallbackMsg::PREVIEW_FRAME, l);
1893             }
1894 
1895             disableMsgType((unsigned int)DataCallbackMsg::PREVIEW_FRAME, device1);
1896             enableMsgType((unsigned int)DataCallbackMsg::COMPRESSED_IMAGE, device1);
1897 
1898             {
1899                 std::unique_lock<std::mutex> l(mLock);
1900                 mDataMessageTypeReceived = DataCallbackMsg::RAW_IMAGE_NOTIFY;
1901             }
1902 
1903             Return<Status> returnStatus = device1->takePicture();
1904             ASSERT_TRUE(returnStatus.isOk());
1905             ASSERT_EQ(Status::OK, returnStatus);
1906 
1907             {
1908                 std::unique_lock<std::mutex> l(mLock);
1909                 waitForFrameLocked(DataCallbackMsg::COMPRESSED_IMAGE, l);
1910             }
1911 
1912             disableMsgType((unsigned int)DataCallbackMsg::COMPRESSED_IMAGE, device1);
1913             stopPreviewAndClose(device1);
1914         }
1915     }
1916 }
1917 
1918 // Image capture should fail in case preview didn't get enabled first.
TEST_F(CameraHidlTest,takePictureFail)1919 TEST_F(CameraHidlTest, takePictureFail) {
1920     hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
1921 
1922     for (const auto& name : cameraDeviceNames) {
1923         if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_1_0) {
1924             sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
1925             openCameraDevice(name, mProvider, &device1 /*out*/);
1926             ASSERT_NE(nullptr, device1.get());
1927 
1928             Return<Status> returnStatus = device1->takePicture();
1929             ASSERT_TRUE(returnStatus.isOk());
1930             ASSERT_NE(Status::OK, returnStatus);
1931 
1932             Return<void> ret = device1->close();
1933             ASSERT_TRUE(ret.isOk());
1934         }
1935     }
1936 }
1937 
1938 // Verify that image capture can be cancelled.
TEST_F(CameraHidlTest,cancelPicture)1939 TEST_F(CameraHidlTest, cancelPicture) {
1940     hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
1941 
1942     for (const auto& name : cameraDeviceNames) {
1943         if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_1_0) {
1944             sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
1945             openCameraDevice(name, mProvider, &device1 /*out*/);
1946             ASSERT_NE(nullptr, device1.get());
1947             sp<BufferItemConsumer> bufferItemConsumer;
1948             sp<BufferItemHander> bufferHandler;
1949             setupPreviewWindow(device1, &bufferItemConsumer /*out*/, &bufferHandler /*out*/);
1950             startPreview(device1);
1951 
1952             Return<Status> returnStatus = device1->takePicture();
1953             ASSERT_TRUE(returnStatus.isOk());
1954             ASSERT_EQ(Status::OK, returnStatus);
1955 
1956             returnStatus = device1->cancelPicture();
1957             ASSERT_TRUE(returnStatus.isOk());
1958             ASSERT_EQ(Status::OK, returnStatus);
1959 
1960             stopPreviewAndClose(device1);
1961         }
1962     }
1963 }
1964 
1965 // Image capture cancel is a no-op when image capture is not running.
TEST_F(CameraHidlTest,cancelPictureNOP)1966 TEST_F(CameraHidlTest, cancelPictureNOP) {
1967     hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
1968 
1969     for (const auto& name : cameraDeviceNames) {
1970         if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_1_0) {
1971             sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
1972             openCameraDevice(name, mProvider, &device1 /*out*/);
1973             ASSERT_NE(nullptr, device1.get());
1974             sp<BufferItemConsumer> bufferItemConsumer;
1975             sp<BufferItemHander> bufferHandler;
1976             setupPreviewWindow(device1, &bufferItemConsumer /*out*/, &bufferHandler /*out*/);
1977             startPreview(device1);
1978 
1979             Return<Status> returnStatus = device1->cancelPicture();
1980             ASSERT_TRUE(returnStatus.isOk());
1981             ASSERT_EQ(Status::OK, returnStatus);
1982 
1983             stopPreviewAndClose(device1);
1984         }
1985     }
1986 }
1987 
1988 // Test basic video recording.
TEST_F(CameraHidlTest,startStopRecording)1989 TEST_F(CameraHidlTest, startStopRecording) {
1990     hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
1991 
1992     for (const auto& name : cameraDeviceNames) {
1993         if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_1_0) {
1994             sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
1995             openCameraDevice(name, mProvider, &device1 /*out*/);
1996             ASSERT_NE(nullptr, device1.get());
1997             sp<BufferItemConsumer> bufferItemConsumer;
1998             sp<BufferItemHander> bufferHandler;
1999             setupPreviewWindow(device1, &bufferItemConsumer /*out*/, &bufferHandler /*out*/);
2000 
2001             {
2002                 std::unique_lock<std::mutex> l(mLock);
2003                 mDataMessageTypeReceived = DataCallbackMsg::RAW_IMAGE_NOTIFY;
2004             }
2005 
2006             enableMsgType((unsigned int)DataCallbackMsg::PREVIEW_FRAME, device1);
2007             startPreview(device1);
2008 
2009             {
2010                 std::unique_lock<std::mutex> l(mLock);
2011                 waitForFrameLocked(DataCallbackMsg::PREVIEW_FRAME, l);
2012                 mDataMessageTypeReceived = DataCallbackMsg::RAW_IMAGE_NOTIFY;
2013                 mVideoBufferIndex = UINT32_MAX;
2014             }
2015 
2016             disableMsgType((unsigned int)DataCallbackMsg::PREVIEW_FRAME, device1);
2017 
2018             bool videoMetaEnabled = false;
2019             Return<Status> returnStatus = device1->storeMetaDataInBuffers(true);
2020             ASSERT_TRUE(returnStatus.isOk());
2021             // It is allowed for devices to not support this feature
2022             ASSERT_TRUE((Status::OK == returnStatus) ||
2023                         (Status::OPERATION_NOT_SUPPORTED == returnStatus));
2024             if (Status::OK == returnStatus) {
2025                 videoMetaEnabled = true;
2026             }
2027 
2028             enableMsgType((unsigned int)DataCallbackMsg::VIDEO_FRAME, device1);
2029             Return<bool> returnBoolStatus = device1->recordingEnabled();
2030             ASSERT_TRUE(returnBoolStatus.isOk());
2031             ASSERT_FALSE(returnBoolStatus);
2032 
2033             returnStatus = device1->startRecording();
2034             ASSERT_TRUE(returnStatus.isOk());
2035             ASSERT_EQ(Status::OK, returnStatus);
2036 
2037             {
2038                 std::unique_lock<std::mutex> l(mLock);
2039                 waitForFrameLocked(DataCallbackMsg::VIDEO_FRAME, l);
2040                 ASSERT_NE(UINT32_MAX, mVideoBufferIndex);
2041                 disableMsgType((unsigned int)DataCallbackMsg::VIDEO_FRAME, device1);
2042             }
2043 
2044             returnBoolStatus = device1->recordingEnabled();
2045             ASSERT_TRUE(returnBoolStatus.isOk());
2046             ASSERT_TRUE(returnBoolStatus);
2047 
2048             Return<void> ret;
2049             if (videoMetaEnabled) {
2050                 ret = device1->releaseRecordingFrameHandle(mVideoData, mVideoBufferIndex,
2051                                                            mVideoNativeHandle);
2052                 ASSERT_TRUE(ret.isOk());
2053             } else {
2054                 ret = device1->releaseRecordingFrame(mVideoData, mVideoBufferIndex);
2055                 ASSERT_TRUE(ret.isOk());
2056             }
2057 
2058             ret = device1->stopRecording();
2059             ASSERT_TRUE(ret.isOk());
2060 
2061             stopPreviewAndClose(device1);
2062         }
2063     }
2064 }
2065 
2066 // It shouldn't be possible to start recording without enabling preview first.
TEST_F(CameraHidlTest,startRecordingFail)2067 TEST_F(CameraHidlTest, startRecordingFail) {
2068     hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
2069 
2070     for (const auto& name : cameraDeviceNames) {
2071         if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_1_0) {
2072             sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
2073             openCameraDevice(name, mProvider, &device1 /*out*/);
2074             ASSERT_NE(nullptr, device1.get());
2075 
2076             Return<bool> returnBoolStatus = device1->recordingEnabled();
2077             ASSERT_TRUE(returnBoolStatus.isOk());
2078             ASSERT_FALSE(returnBoolStatus);
2079 
2080             Return<Status> returnStatus = device1->startRecording();
2081             ASSERT_TRUE(returnStatus.isOk());
2082             ASSERT_NE(Status::OK, returnStatus);
2083 
2084             Return<void> ret = device1->close();
2085             ASSERT_TRUE(ret.isOk());
2086         }
2087     }
2088 }
2089 
2090 // Check autofocus support if available.
TEST_F(CameraHidlTest,autoFocus)2091 TEST_F(CameraHidlTest, autoFocus) {
2092     hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
2093     std::vector<const char*> focusModes = {CameraParameters::FOCUS_MODE_AUTO,
2094                                            CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE,
2095                                            CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO};
2096 
2097     for (const auto& name : cameraDeviceNames) {
2098         if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_1_0) {
2099             sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
2100             openCameraDevice(name, mProvider, &device1 /*out*/);
2101             ASSERT_NE(nullptr, device1.get());
2102 
2103             CameraParameters cameraParams;
2104             getParameters(device1, &cameraParams /*out*/);
2105 
2106             if (Status::OK !=
2107                 isAutoFocusModeAvailable(cameraParams, CameraParameters::FOCUS_MODE_AUTO)) {
2108                 Return<void> ret = device1->close();
2109                 ASSERT_TRUE(ret.isOk());
2110                 continue;
2111             }
2112 
2113             sp<BufferItemConsumer> bufferItemConsumer;
2114             sp<BufferItemHander> bufferHandler;
2115             setupPreviewWindow(device1, &bufferItemConsumer /*out*/, &bufferHandler /*out*/);
2116             startPreview(device1);
2117             enableMsgType((unsigned int)NotifyCallbackMsg::FOCUS, device1);
2118 
2119             for (auto& iter : focusModes) {
2120                 if (Status::OK != isAutoFocusModeAvailable(cameraParams, iter)) {
2121                     continue;
2122                 }
2123 
2124                 cameraParams.set(CameraParameters::KEY_FOCUS_MODE, iter);
2125                 setParameters(device1, cameraParams);
2126                 {
2127                     std::unique_lock<std::mutex> l(mLock);
2128                     mNotifyMessage = NotifyCallbackMsg::ERROR;
2129                 }
2130 
2131                 Return<Status> returnStatus = device1->autoFocus();
2132                 ASSERT_TRUE(returnStatus.isOk());
2133                 ASSERT_EQ(Status::OK, returnStatus);
2134 
2135                 {
2136                     std::unique_lock<std::mutex> l(mLock);
2137                     while (NotifyCallbackMsg::FOCUS != mNotifyMessage) {
2138                         auto timeout = std::chrono::system_clock::now() +
2139                                        std::chrono::seconds(kAutoFocusTimeoutSec);
2140                         ASSERT_NE(std::cv_status::timeout, mResultCondition.wait_until(l, timeout));
2141                     }
2142                 }
2143             }
2144 
2145             disableMsgType((unsigned int)NotifyCallbackMsg::FOCUS, device1);
2146             stopPreviewAndClose(device1);
2147         }
2148     }
2149 }
2150 
2151 // In case autofocus is supported verify that it can be cancelled.
TEST_F(CameraHidlTest,cancelAutoFocus)2152 TEST_F(CameraHidlTest, cancelAutoFocus) {
2153     hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
2154 
2155     for (const auto& name : cameraDeviceNames) {
2156         if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_1_0) {
2157             sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
2158             openCameraDevice(name, mProvider, &device1 /*out*/);
2159             ASSERT_NE(nullptr, device1.get());
2160 
2161             CameraParameters cameraParams;
2162             getParameters(device1, &cameraParams /*out*/);
2163 
2164             if (Status::OK !=
2165                 isAutoFocusModeAvailable(cameraParams, CameraParameters::FOCUS_MODE_AUTO)) {
2166                 Return<void> ret = device1->close();
2167                 ASSERT_TRUE(ret.isOk());
2168                 continue;
2169             }
2170 
2171             // It should be fine to call before preview starts.
2172             ASSERT_EQ(Status::OK, device1->cancelAutoFocus());
2173 
2174             sp<BufferItemConsumer> bufferItemConsumer;
2175             sp<BufferItemHander> bufferHandler;
2176             setupPreviewWindow(device1, &bufferItemConsumer /*out*/, &bufferHandler /*out*/);
2177             startPreview(device1);
2178 
2179             // It should be fine to call after preview starts too.
2180             Return<Status> returnStatus = device1->cancelAutoFocus();
2181             ASSERT_TRUE(returnStatus.isOk());
2182             ASSERT_EQ(Status::OK, returnStatus);
2183 
2184             returnStatus = device1->autoFocus();
2185             ASSERT_TRUE(returnStatus.isOk());
2186             ASSERT_EQ(Status::OK, returnStatus);
2187 
2188             returnStatus = device1->cancelAutoFocus();
2189             ASSERT_TRUE(returnStatus.isOk());
2190             ASSERT_EQ(Status::OK, returnStatus);
2191 
2192             stopPreviewAndClose(device1);
2193         }
2194     }
2195 }
2196 
2197 // Check whether face detection is available and try to enable&disable.
TEST_F(CameraHidlTest,sendCommandFaceDetection)2198 TEST_F(CameraHidlTest, sendCommandFaceDetection) {
2199     hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
2200 
2201     for (const auto& name : cameraDeviceNames) {
2202         if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_1_0) {
2203             sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
2204             openCameraDevice(name, mProvider, &device1 /*out*/);
2205             ASSERT_NE(nullptr, device1.get());
2206 
2207             CameraParameters cameraParams;
2208             getParameters(device1, &cameraParams /*out*/);
2209 
2210             int32_t hwFaces = cameraParams.getInt(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_HW);
2211             int32_t swFaces = cameraParams.getInt(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_SW);
2212             if ((0 >= hwFaces) && (0 >= swFaces)) {
2213                 Return<void> ret = device1->close();
2214                 ASSERT_TRUE(ret.isOk());
2215                 continue;
2216             }
2217 
2218             sp<BufferItemConsumer> bufferItemConsumer;
2219             sp<BufferItemHander> bufferHandler;
2220             setupPreviewWindow(device1, &bufferItemConsumer /*out*/, &bufferHandler /*out*/);
2221             startPreview(device1);
2222 
2223             if (0 < hwFaces) {
2224                 Return<Status> returnStatus = device1->sendCommand(
2225                     CommandType::START_FACE_DETECTION, CAMERA_FACE_DETECTION_HW, 0);
2226                 ASSERT_TRUE(returnStatus.isOk());
2227                 ASSERT_EQ(Status::OK, returnStatus);
2228                 // TODO(epeev) : Enable and check for face notifications
2229                 returnStatus = device1->sendCommand(CommandType::STOP_FACE_DETECTION,
2230                                                     CAMERA_FACE_DETECTION_HW, 0);
2231                 ASSERT_TRUE(returnStatus.isOk());
2232                 ASSERT_EQ(Status::OK, returnStatus);
2233             }
2234 
2235             if (0 < swFaces) {
2236                 Return<Status> returnStatus = device1->sendCommand(
2237                     CommandType::START_FACE_DETECTION, CAMERA_FACE_DETECTION_SW, 0);
2238                 ASSERT_TRUE(returnStatus.isOk());
2239                 ASSERT_EQ(Status::OK, returnStatus);
2240                 // TODO(epeev) : Enable and check for face notifications
2241                 returnStatus = device1->sendCommand(CommandType::STOP_FACE_DETECTION,
2242                                                     CAMERA_FACE_DETECTION_SW, 0);
2243                 ASSERT_TRUE(returnStatus.isOk());
2244                 ASSERT_EQ(Status::OK, returnStatus);
2245             }
2246 
2247             stopPreviewAndClose(device1);
2248         }
2249     }
2250 }
2251 
2252 // Check whether smooth zoom is available and try to enable&disable.
TEST_F(CameraHidlTest,sendCommandSmoothZoom)2253 TEST_F(CameraHidlTest, sendCommandSmoothZoom) {
2254     hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
2255 
2256     for (const auto& name : cameraDeviceNames) {
2257         if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_1_0) {
2258             sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
2259             openCameraDevice(name, mProvider, &device1 /*out*/);
2260             ASSERT_NE(nullptr, device1.get());
2261 
2262             CameraParameters cameraParams;
2263             getParameters(device1, &cameraParams /*out*/);
2264 
2265             const char* smoothZoomStr =
2266                 cameraParams.get(CameraParameters::KEY_SMOOTH_ZOOM_SUPPORTED);
2267             bool smoothZoomSupported =
2268                 ((nullptr != smoothZoomStr) && (strcmp(smoothZoomStr, CameraParameters::TRUE) == 0))
2269                     ? true
2270                     : false;
2271             if (!smoothZoomSupported) {
2272                 Return<void> ret = device1->close();
2273                 ASSERT_TRUE(ret.isOk());
2274                 continue;
2275             }
2276 
2277             int32_t maxZoom = cameraParams.getInt(CameraParameters::KEY_MAX_ZOOM);
2278             ASSERT_TRUE(0 < maxZoom);
2279 
2280             sp<BufferItemConsumer> bufferItemConsumer;
2281             sp<BufferItemHander> bufferHandler;
2282             setupPreviewWindow(device1, &bufferItemConsumer /*out*/, &bufferHandler /*out*/);
2283             startPreview(device1);
2284             setParameters(device1, cameraParams);
2285 
2286             Return<Status> returnStatus =
2287                 device1->sendCommand(CommandType::START_SMOOTH_ZOOM, maxZoom, 0);
2288             ASSERT_TRUE(returnStatus.isOk());
2289             ASSERT_EQ(Status::OK, returnStatus);
2290             // TODO(epeev) : Enable and check for face notifications
2291             returnStatus = device1->sendCommand(CommandType::STOP_SMOOTH_ZOOM, 0, 0);
2292             ASSERT_TRUE(returnStatus.isOk());
2293             ASSERT_EQ(Status::OK, returnStatus);
2294 
2295             stopPreviewAndClose(device1);
2296         }
2297     }
2298 }
2299 
2300 // Basic sanity tests related to camera parameters.
TEST_F(CameraHidlTest,getSetParameters)2301 TEST_F(CameraHidlTest, getSetParameters) {
2302     hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
2303 
2304     for (const auto& name : cameraDeviceNames) {
2305         if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_1_0) {
2306             sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
2307             openCameraDevice(name, mProvider, &device1 /*out*/);
2308             ASSERT_NE(nullptr, device1.get());
2309 
2310             CameraParameters cameraParams;
2311             getParameters(device1, &cameraParams /*out*/);
2312 
2313             int32_t width, height;
2314             cameraParams.getPictureSize(&width, &height);
2315             ASSERT_TRUE((0 < width) && (0 < height));
2316             cameraParams.getPreviewSize(&width, &height);
2317             ASSERT_TRUE((0 < width) && (0 < height));
2318             int32_t minFps, maxFps;
2319             cameraParams.getPreviewFpsRange(&minFps, &maxFps);
2320             ASSERT_TRUE((0 < minFps) && (0 < maxFps));
2321             ASSERT_NE(nullptr, cameraParams.getPreviewFormat());
2322             ASSERT_NE(nullptr, cameraParams.getPictureFormat());
2323             ASSERT_TRUE(
2324                 strcmp(CameraParameters::PIXEL_FORMAT_JPEG, cameraParams.getPictureFormat()) == 0);
2325 
2326             const char* flashMode = cameraParams.get(CameraParameters::KEY_FLASH_MODE);
2327             ASSERT_TRUE((nullptr == flashMode) ||
2328                         (strcmp(CameraParameters::FLASH_MODE_OFF, flashMode) == 0));
2329 
2330             const char* wbMode = cameraParams.get(CameraParameters::KEY_WHITE_BALANCE);
2331             ASSERT_TRUE((nullptr == wbMode) ||
2332                         (strcmp(CameraParameters::WHITE_BALANCE_AUTO, wbMode) == 0));
2333 
2334             const char* effect = cameraParams.get(CameraParameters::KEY_EFFECT);
2335             ASSERT_TRUE((nullptr == effect) ||
2336                         (strcmp(CameraParameters::EFFECT_NONE, effect) == 0));
2337 
2338             ::android::Vector<Size> previewSizes;
2339             cameraParams.getSupportedPreviewSizes(previewSizes);
2340             ASSERT_FALSE(previewSizes.empty());
2341             ::android::Vector<Size> pictureSizes;
2342             cameraParams.getSupportedPictureSizes(pictureSizes);
2343             ASSERT_FALSE(pictureSizes.empty());
2344             const char* previewFormats =
2345                 cameraParams.get(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS);
2346             ASSERT_NE(nullptr, previewFormats);
2347             ::android::String8 previewFormatsString(previewFormats);
2348             ASSERT_TRUE(previewFormatsString.contains(CameraParameters::PIXEL_FORMAT_YUV420SP));
2349             ASSERT_NE(nullptr, cameraParams.get(CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS));
2350             ASSERT_NE(nullptr,
2351                       cameraParams.get(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES));
2352             const char* focusModes = cameraParams.get(CameraParameters::KEY_SUPPORTED_FOCUS_MODES);
2353             ASSERT_NE(nullptr, focusModes);
2354             ::android::String8 focusModesString(focusModes);
2355             const char* focusMode = cameraParams.get(CameraParameters::KEY_FOCUS_MODE);
2356             ASSERT_NE(nullptr, focusMode);
2357             // Auto focus mode should be default
2358             if (focusModesString.contains(CameraParameters::FOCUS_MODE_AUTO)) {
2359                 ASSERT_TRUE(strcmp(CameraParameters::FOCUS_MODE_AUTO, focusMode) == 0);
2360             }
2361             ASSERT_TRUE(0 < cameraParams.getInt(CameraParameters::KEY_FOCAL_LENGTH));
2362             int32_t horizontalViewAngle =
2363                 cameraParams.getInt(CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE);
2364             ASSERT_TRUE((0 < horizontalViewAngle) && (360 >= horizontalViewAngle));
2365             int32_t verticalViewAngle =
2366                 cameraParams.getInt(CameraParameters::KEY_VERTICAL_VIEW_ANGLE);
2367             ASSERT_TRUE((0 < verticalViewAngle) && (360 >= verticalViewAngle));
2368             int32_t jpegQuality = cameraParams.getInt(CameraParameters::KEY_JPEG_QUALITY);
2369             ASSERT_TRUE((1 <= jpegQuality) && (100 >= jpegQuality));
2370             int32_t jpegThumbQuality =
2371                 cameraParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY);
2372             ASSERT_TRUE((1 <= jpegThumbQuality) && (100 >= jpegThumbQuality));
2373 
2374             cameraParams.setPictureSize(pictureSizes[0].width, pictureSizes[0].height);
2375             cameraParams.setPreviewSize(previewSizes[0].width, previewSizes[0].height);
2376 
2377             setParameters(device1, cameraParams);
2378             getParameters(device1, &cameraParams /*out*/);
2379 
2380             cameraParams.getPictureSize(&width, &height);
2381             ASSERT_TRUE((pictureSizes[0].width == width) && (pictureSizes[0].height == height));
2382             cameraParams.getPreviewSize(&width, &height);
2383             ASSERT_TRUE((previewSizes[0].width == width) && (previewSizes[0].height == height));
2384 
2385             Return<void> ret = device1->close();
2386             ASSERT_TRUE(ret.isOk());
2387         }
2388     }
2389 }
2390 
2391 // Verify that the static camera characteristics can be retrieved
2392 // successfully.
TEST_F(CameraHidlTest,getCameraCharacteristics)2393 TEST_F(CameraHidlTest, getCameraCharacteristics) {
2394     hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
2395 
2396     for (const auto& name : cameraDeviceNames) {
2397         int deviceVersion = getCameraDeviceVersion(name, mProviderType);
2398         switch (deviceVersion) {
2399             case CAMERA_DEVICE_API_VERSION_3_5:
2400             case CAMERA_DEVICE_API_VERSION_3_4:
2401             case CAMERA_DEVICE_API_VERSION_3_3:
2402             case CAMERA_DEVICE_API_VERSION_3_2: {
2403                 ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_x;
2404                 ALOGI("getCameraCharacteristics: Testing camera device %s", name.c_str());
2405                 Return<void> ret;
2406                 ret = mProvider->getCameraDeviceInterface_V3_x(
2407                     name, [&](auto status, const auto& device) {
2408                         ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
2409                         ASSERT_EQ(Status::OK, status);
2410                         ASSERT_NE(device, nullptr);
2411                         device3_x = device;
2412                     });
2413                 ASSERT_TRUE(ret.isOk());
2414 
2415                 ret = device3_x->getCameraCharacteristics([&](auto status, const auto& chars) {
2416                     verifyCameraCharacteristics(status, chars);
2417                     verifyMonochromeCharacteristics(chars, deviceVersion);
2418                     verifyRecommendedConfigs(chars);
2419                     verifyLogicalCameraMetadata(name, device3_x, chars, deviceVersion,
2420                             cameraDeviceNames);
2421                 });
2422                 ASSERT_TRUE(ret.isOk());
2423 
2424                 //getPhysicalCameraCharacteristics will fail for publicly
2425                 //advertised camera IDs.
2426                 if (deviceVersion >= CAMERA_DEVICE_API_VERSION_3_5) {
2427                     auto castResult = device::V3_5::ICameraDevice::castFrom(device3_x);
2428                     ASSERT_TRUE(castResult.isOk());
2429                     ::android::sp<::android::hardware::camera::device::V3_5::ICameraDevice>
2430                             device3_5 = castResult;
2431                     ASSERT_NE(device3_5, nullptr);
2432 
2433                     std::string version, cameraId;
2434                     ASSERT_TRUE(::matchDeviceName(name, mProviderType, &version, &cameraId));
2435                     Return<void> ret = device3_5->getPhysicalCameraCharacteristics(cameraId,
2436                             [&](auto status, const auto& chars) {
2437                         ASSERT_TRUE(Status::ILLEGAL_ARGUMENT == status);
2438                         ASSERT_EQ(0, chars.size());
2439                     });
2440                     ASSERT_TRUE(ret.isOk());
2441                 }
2442             }
2443             break;
2444             case CAMERA_DEVICE_API_VERSION_1_0: {
2445                 //Not applicable
2446             }
2447             break;
2448             default: {
2449                 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
2450                 ADD_FAILURE();
2451             }
2452             break;
2453         }
2454     }
2455 }
2456 
2457 //In case it is supported verify that torch can be enabled.
2458 //Check for corresponding toch callbacks as well.
TEST_F(CameraHidlTest,setTorchMode)2459 TEST_F(CameraHidlTest, setTorchMode) {
2460     hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
2461     bool torchControlSupported = false;
2462     Return<void> ret;
2463 
2464     ret = mProvider->isSetTorchModeSupported([&](auto status, bool support) {
2465         ALOGI("isSetTorchModeSupported returns status:%d supported:%d", (int)status, support);
2466         ASSERT_EQ(Status::OK, status);
2467         torchControlSupported = support;
2468     });
2469 
2470     sp<TorchProviderCb> cb = new TorchProviderCb(this);
2471     Return<Status> returnStatus = mProvider->setCallback(cb);
2472     ASSERT_TRUE(returnStatus.isOk());
2473     ASSERT_EQ(Status::OK, returnStatus);
2474 
2475     for (const auto& name : cameraDeviceNames) {
2476         int deviceVersion = getCameraDeviceVersion(name, mProviderType);
2477         switch (deviceVersion) {
2478             case CAMERA_DEVICE_API_VERSION_3_5:
2479             case CAMERA_DEVICE_API_VERSION_3_4:
2480             case CAMERA_DEVICE_API_VERSION_3_3:
2481             case CAMERA_DEVICE_API_VERSION_3_2: {
2482                 ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_x;
2483                 ALOGI("setTorchMode: Testing camera device %s", name.c_str());
2484                 ret = mProvider->getCameraDeviceInterface_V3_x(
2485                     name, [&](auto status, const auto& device) {
2486                         ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
2487                         ASSERT_EQ(Status::OK, status);
2488                         ASSERT_NE(device, nullptr);
2489                         device3_x = device;
2490                     });
2491                 ASSERT_TRUE(ret.isOk());
2492 
2493                 mTorchStatus = TorchModeStatus::NOT_AVAILABLE;
2494                 returnStatus = device3_x->setTorchMode(TorchMode::ON);
2495                 ASSERT_TRUE(returnStatus.isOk());
2496                 if (!torchControlSupported) {
2497                     ASSERT_EQ(Status::METHOD_NOT_SUPPORTED, returnStatus);
2498                 } else {
2499                     ASSERT_TRUE(returnStatus == Status::OK ||
2500                                 returnStatus == Status::OPERATION_NOT_SUPPORTED);
2501                     if (returnStatus == Status::OK) {
2502                         {
2503                             std::unique_lock<std::mutex> l(mTorchLock);
2504                             while (TorchModeStatus::NOT_AVAILABLE == mTorchStatus) {
2505                                 auto timeout = std::chrono::system_clock::now() +
2506                                                std::chrono::seconds(kTorchTimeoutSec);
2507                                 ASSERT_NE(std::cv_status::timeout, mTorchCond.wait_until(l, timeout));
2508                             }
2509                             ASSERT_EQ(TorchModeStatus::AVAILABLE_ON, mTorchStatus);
2510                             mTorchStatus = TorchModeStatus::NOT_AVAILABLE;
2511                         }
2512 
2513                         returnStatus = device3_x->setTorchMode(TorchMode::OFF);
2514                         ASSERT_TRUE(returnStatus.isOk());
2515                         ASSERT_EQ(Status::OK, returnStatus);
2516 
2517                         {
2518                             std::unique_lock<std::mutex> l(mTorchLock);
2519                             while (TorchModeStatus::NOT_AVAILABLE == mTorchStatus) {
2520                                 auto timeout = std::chrono::system_clock::now() +
2521                                                std::chrono::seconds(kTorchTimeoutSec);
2522                                 ASSERT_NE(std::cv_status::timeout, mTorchCond.wait_until(l, timeout));
2523                             }
2524                             ASSERT_EQ(TorchModeStatus::AVAILABLE_OFF, mTorchStatus);
2525                         }
2526                     }
2527                 }
2528             }
2529             break;
2530             case CAMERA_DEVICE_API_VERSION_1_0: {
2531                 ::android::sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
2532                 ALOGI("dumpState: Testing camera device %s", name.c_str());
2533                 ret = mProvider->getCameraDeviceInterface_V1_x(
2534                     name, [&](auto status, const auto& device) {
2535                         ALOGI("getCameraDeviceInterface_V1_x returns status:%d", (int)status);
2536                         ASSERT_EQ(Status::OK, status);
2537                         ASSERT_NE(device, nullptr);
2538                         device1 = device;
2539                     });
2540                 ASSERT_TRUE(ret.isOk());
2541 
2542                 mTorchStatus = TorchModeStatus::NOT_AVAILABLE;
2543                 returnStatus = device1->setTorchMode(TorchMode::ON);
2544                 ASSERT_TRUE(returnStatus.isOk());
2545                 if (!torchControlSupported) {
2546                     ASSERT_EQ(Status::METHOD_NOT_SUPPORTED, returnStatus);
2547                 } else {
2548                     ASSERT_TRUE(returnStatus == Status::OK ||
2549                                 returnStatus == Status::OPERATION_NOT_SUPPORTED);
2550                     if (returnStatus == Status::OK) {
2551                         {
2552                             std::unique_lock<std::mutex> l(mTorchLock);
2553                             while (TorchModeStatus::NOT_AVAILABLE == mTorchStatus) {
2554                                 auto timeout = std::chrono::system_clock::now() +
2555                                                std::chrono::seconds(kTorchTimeoutSec);
2556                                 ASSERT_NE(std::cv_status::timeout, mTorchCond.wait_until(l,
2557                                         timeout));
2558                             }
2559                             ASSERT_EQ(TorchModeStatus::AVAILABLE_ON, mTorchStatus);
2560                             mTorchStatus = TorchModeStatus::NOT_AVAILABLE;
2561                         }
2562 
2563                         returnStatus = device1->setTorchMode(TorchMode::OFF);
2564                         ASSERT_TRUE(returnStatus.isOk());
2565                         ASSERT_EQ(Status::OK, returnStatus);
2566 
2567                         {
2568                             std::unique_lock<std::mutex> l(mTorchLock);
2569                             while (TorchModeStatus::NOT_AVAILABLE == mTorchStatus) {
2570                                 auto timeout = std::chrono::system_clock::now() +
2571                                                std::chrono::seconds(kTorchTimeoutSec);
2572                                 ASSERT_NE(std::cv_status::timeout, mTorchCond.wait_until(l,
2573                                         timeout));
2574                             }
2575                             ASSERT_EQ(TorchModeStatus::AVAILABLE_OFF, mTorchStatus);
2576                         }
2577                     }
2578                 }
2579                 ret = device1->close();
2580                 ASSERT_TRUE(ret.isOk());
2581             }
2582             break;
2583             default: {
2584                 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
2585                 ADD_FAILURE();
2586             }
2587             break;
2588         }
2589     }
2590 
2591     returnStatus = mProvider->setCallback(nullptr);
2592     ASSERT_TRUE(returnStatus.isOk());
2593     ASSERT_EQ(Status::OK, returnStatus);
2594 }
2595 
2596 // Check dump functionality.
TEST_F(CameraHidlTest,dumpState)2597 TEST_F(CameraHidlTest, dumpState) {
2598     hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
2599     Return<void> ret;
2600 
2601     for (const auto& name : cameraDeviceNames) {
2602         int deviceVersion = getCameraDeviceVersion(name, mProviderType);
2603         switch (deviceVersion) {
2604             case CAMERA_DEVICE_API_VERSION_3_5:
2605             case CAMERA_DEVICE_API_VERSION_3_4:
2606             case CAMERA_DEVICE_API_VERSION_3_3:
2607             case CAMERA_DEVICE_API_VERSION_3_2: {
2608                 ::android::sp<ICameraDevice> device3_x;
2609                 ALOGI("dumpState: Testing camera device %s", name.c_str());
2610                 ret = mProvider->getCameraDeviceInterface_V3_x(
2611                     name, [&](auto status, const auto& device) {
2612                         ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
2613                         ASSERT_EQ(Status::OK, status);
2614                         ASSERT_NE(device, nullptr);
2615                         device3_x = device;
2616                     });
2617                 ASSERT_TRUE(ret.isOk());
2618 
2619                 native_handle_t* raw_handle = native_handle_create(1, 0);
2620                 raw_handle->data[0] = open(kDumpOutput, O_RDWR);
2621                 ASSERT_GE(raw_handle->data[0], 0);
2622                 hidl_handle handle = raw_handle;
2623                 ret = device3_x->dumpState(handle);
2624                 ASSERT_TRUE(ret.isOk());
2625                 close(raw_handle->data[0]);
2626                 native_handle_delete(raw_handle);
2627             }
2628             break;
2629             case CAMERA_DEVICE_API_VERSION_1_0: {
2630                 ::android::sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
2631                 ALOGI("dumpState: Testing camera device %s", name.c_str());
2632                 ret = mProvider->getCameraDeviceInterface_V1_x(
2633                     name, [&](auto status, const auto& device) {
2634                         ALOGI("getCameraDeviceInterface_V1_x returns status:%d", (int)status);
2635                         ASSERT_EQ(Status::OK, status);
2636                         ASSERT_NE(device, nullptr);
2637                         device1 = device;
2638                     });
2639                 ASSERT_TRUE(ret.isOk());
2640 
2641                 native_handle_t* raw_handle = native_handle_create(1, 0);
2642                 raw_handle->data[0] = open(kDumpOutput, O_RDWR);
2643                 ASSERT_GE(raw_handle->data[0], 0);
2644                 hidl_handle handle = raw_handle;
2645                 Return<Status> returnStatus = device1->dumpState(handle);
2646                 ASSERT_TRUE(returnStatus.isOk());
2647                 ASSERT_EQ(Status::OK, returnStatus);
2648                 close(raw_handle->data[0]);
2649                 native_handle_delete(raw_handle);
2650             }
2651             break;
2652             default: {
2653                 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
2654                 ADD_FAILURE();
2655             }
2656             break;
2657         }
2658     }
2659 }
2660 
2661 // Open, dumpStates, then close
TEST_F(CameraHidlTest,openClose)2662 TEST_F(CameraHidlTest, openClose) {
2663     hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
2664     Return<void> ret;
2665 
2666     for (const auto& name : cameraDeviceNames) {
2667         int deviceVersion = getCameraDeviceVersion(name, mProviderType);
2668         switch (deviceVersion) {
2669             case CAMERA_DEVICE_API_VERSION_3_5:
2670             case CAMERA_DEVICE_API_VERSION_3_4:
2671             case CAMERA_DEVICE_API_VERSION_3_3:
2672             case CAMERA_DEVICE_API_VERSION_3_2: {
2673                 ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_x;
2674                 ALOGI("openClose: Testing camera device %s", name.c_str());
2675                 ret = mProvider->getCameraDeviceInterface_V3_x(
2676                     name, [&](auto status, const auto& device) {
2677                         ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
2678                         ASSERT_EQ(Status::OK, status);
2679                         ASSERT_NE(device, nullptr);
2680                         device3_x = device;
2681                     });
2682                 ASSERT_TRUE(ret.isOk());
2683 
2684                 sp<EmptyDeviceCb> cb = new EmptyDeviceCb;
2685                 sp<ICameraDeviceSession> session;
2686                 ret = device3_x->open(cb, [&](auto status, const auto& newSession) {
2687                     ALOGI("device::open returns status:%d", (int)status);
2688                     ASSERT_EQ(Status::OK, status);
2689                     ASSERT_NE(newSession, nullptr);
2690                     session = newSession;
2691                 });
2692                 ASSERT_TRUE(ret.isOk());
2693                 // Ensure that a device labeling itself as 3.3/3.4 can have its session interface
2694                 // cast the 3.3/3.4 interface, and that lower versions can't be cast to it.
2695                 sp<device::V3_3::ICameraDeviceSession> sessionV3_3;
2696                 sp<device::V3_4::ICameraDeviceSession> sessionV3_4;
2697                 sp<device::V3_5::ICameraDeviceSession> sessionV3_5;
2698                 castSession(session, deviceVersion, &sessionV3_3, &sessionV3_4, &sessionV3_5);
2699                 if (deviceVersion == CAMERA_DEVICE_API_VERSION_3_5) {
2700                     ASSERT_TRUE(sessionV3_5.get() != nullptr);
2701                 } else if (deviceVersion == CAMERA_DEVICE_API_VERSION_3_4) {
2702                     ASSERT_TRUE(sessionV3_4.get() != nullptr);
2703                 } else if (deviceVersion == CAMERA_DEVICE_API_VERSION_3_3) {
2704                     ASSERT_TRUE(sessionV3_3.get() != nullptr);
2705                 } else { //V3_2
2706                     ASSERT_TRUE(sessionV3_3.get() == nullptr);
2707                     ASSERT_TRUE(sessionV3_4.get() == nullptr);
2708                     ASSERT_TRUE(sessionV3_5.get() == nullptr);
2709                 }
2710                 native_handle_t* raw_handle = native_handle_create(1, 0);
2711                 raw_handle->data[0] = open(kDumpOutput, O_RDWR);
2712                 ASSERT_GE(raw_handle->data[0], 0);
2713                 hidl_handle handle = raw_handle;
2714                 ret = device3_x->dumpState(handle);
2715                 ASSERT_TRUE(ret.isOk());
2716                 close(raw_handle->data[0]);
2717                 native_handle_delete(raw_handle);
2718 
2719                 ret = session->close();
2720                 ASSERT_TRUE(ret.isOk());
2721                 // TODO: test all session API calls return INTERNAL_ERROR after close
2722                 // TODO: keep a wp copy here and verify session cannot be promoted out of this scope
2723             }
2724             break;
2725             case CAMERA_DEVICE_API_VERSION_1_0: {
2726                 sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
2727                 openCameraDevice(name, mProvider, &device1 /*out*/);
2728                 ASSERT_NE(nullptr, device1.get());
2729 
2730                 native_handle_t* raw_handle = native_handle_create(1, 0);
2731                 raw_handle->data[0] = open(kDumpOutput, O_RDWR);
2732                 ASSERT_GE(raw_handle->data[0], 0);
2733                 hidl_handle handle = raw_handle;
2734                 Return<Status> returnStatus = device1->dumpState(handle);
2735                 ASSERT_TRUE(returnStatus.isOk());
2736                 ASSERT_EQ(Status::OK, returnStatus);
2737                 close(raw_handle->data[0]);
2738                 native_handle_delete(raw_handle);
2739 
2740                 ret = device1->close();
2741                 ASSERT_TRUE(ret.isOk());
2742             }
2743             break;
2744             default: {
2745                 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
2746                 ADD_FAILURE();
2747             }
2748             break;
2749         }
2750     }
2751 }
2752 
2753 // Check whether all common default request settings can be sucessfully
2754 // constructed.
TEST_F(CameraHidlTest,constructDefaultRequestSettings)2755 TEST_F(CameraHidlTest, constructDefaultRequestSettings) {
2756     hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
2757 
2758     for (const auto& name : cameraDeviceNames) {
2759         int deviceVersion = getCameraDeviceVersion(name, mProviderType);
2760         switch (deviceVersion) {
2761             case CAMERA_DEVICE_API_VERSION_3_5:
2762             case CAMERA_DEVICE_API_VERSION_3_4:
2763             case CAMERA_DEVICE_API_VERSION_3_3:
2764             case CAMERA_DEVICE_API_VERSION_3_2: {
2765                 ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_x;
2766                 Return<void> ret;
2767                 ALOGI("constructDefaultRequestSettings: Testing camera device %s", name.c_str());
2768                 ret = mProvider->getCameraDeviceInterface_V3_x(
2769                     name, [&](auto status, const auto& device) {
2770                         ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
2771                         ASSERT_EQ(Status::OK, status);
2772                         ASSERT_NE(device, nullptr);
2773                         device3_x = device;
2774                     });
2775                 ASSERT_TRUE(ret.isOk());
2776 
2777                 sp<EmptyDeviceCb> cb = new EmptyDeviceCb;
2778                 sp<ICameraDeviceSession> session;
2779                 ret = device3_x->open(cb, [&](auto status, const auto& newSession) {
2780                     ALOGI("device::open returns status:%d", (int)status);
2781                     ASSERT_EQ(Status::OK, status);
2782                     ASSERT_NE(newSession, nullptr);
2783                     session = newSession;
2784                 });
2785                 ASSERT_TRUE(ret.isOk());
2786 
2787                 for (uint32_t t = (uint32_t)RequestTemplate::PREVIEW;
2788                      t <= (uint32_t)RequestTemplate::MANUAL; t++) {
2789                     RequestTemplate reqTemplate = (RequestTemplate)t;
2790                     ret =
2791                         session->constructDefaultRequestSettings(
2792                             reqTemplate, [&](auto status, const auto& req) {
2793                                 ALOGI("constructDefaultRequestSettings returns status:%d",
2794                                       (int)status);
2795                                 if (reqTemplate == RequestTemplate::ZERO_SHUTTER_LAG ||
2796                                         reqTemplate == RequestTemplate::MANUAL) {
2797                                     // optional templates
2798                                     ASSERT_TRUE((status == Status::OK) ||
2799                                             (status == Status::ILLEGAL_ARGUMENT));
2800                                 } else {
2801                                     ASSERT_EQ(Status::OK, status);
2802                                 }
2803 
2804                                 if (status == Status::OK) {
2805                                     const camera_metadata_t* metadata =
2806                                         (camera_metadata_t*) req.data();
2807                                     size_t expectedSize = req.size();
2808                                     int result = validate_camera_metadata_structure(
2809                                             metadata, &expectedSize);
2810                                     ASSERT_TRUE((result == 0) ||
2811                                             (result == CAMERA_METADATA_VALIDATION_SHIFTED));
2812                                     size_t entryCount =
2813                                             get_camera_metadata_entry_count(metadata);
2814                                     // TODO: we can do better than 0 here. Need to check how many required
2815                                     // request keys we've defined for each template
2816                                     ASSERT_GT(entryCount, 0u);
2817                                     ALOGI("template %u metadata entry count is %zu",
2818                                           t, entryCount);
2819                                 } else {
2820                                     ASSERT_EQ(0u, req.size());
2821                                 }
2822                             });
2823                     ASSERT_TRUE(ret.isOk());
2824                 }
2825                 ret = session->close();
2826                 ASSERT_TRUE(ret.isOk());
2827             }
2828             break;
2829             case CAMERA_DEVICE_API_VERSION_1_0: {
2830                 //Not applicable
2831             }
2832             break;
2833             default: {
2834                 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
2835                 ADD_FAILURE();
2836             }
2837             break;
2838         }
2839     }
2840 }
2841 
2842 
2843 // Verify that all supported stream formats and sizes can be configured
2844 // successfully.
TEST_F(CameraHidlTest,configureStreamsAvailableOutputs)2845 TEST_F(CameraHidlTest, configureStreamsAvailableOutputs) {
2846     hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
2847     std::vector<AvailableStream> outputStreams;
2848 
2849     for (const auto& name : cameraDeviceNames) {
2850         int deviceVersion = getCameraDeviceVersion(name, mProviderType);
2851         if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) {
2852             continue;
2853         } else if (deviceVersion <= 0) {
2854             ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
2855             ADD_FAILURE();
2856             return;
2857         }
2858 
2859         camera_metadata_t* staticMeta;
2860         Return<void> ret;
2861         sp<ICameraDeviceSession> session;
2862         sp<device::V3_3::ICameraDeviceSession> session3_3;
2863         sp<device::V3_4::ICameraDeviceSession> session3_4;
2864         sp<device::V3_5::ICameraDeviceSession> session3_5;
2865         sp<device::V3_2::ICameraDevice> cameraDevice;
2866         sp<device::V3_5::ICameraDevice> cameraDevice3_5;
2867         openEmptyDeviceSession(name, mProvider,
2868                 &session /*out*/, &staticMeta /*out*/, &cameraDevice /*out*/);
2869         castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5);
2870         castDevice(cameraDevice, deviceVersion, &cameraDevice3_5);
2871 
2872         outputStreams.clear();
2873         ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta, outputStreams));
2874         ASSERT_NE(0u, outputStreams.size());
2875 
2876         uint32_t jpegBufferSize = 0;
2877         ASSERT_EQ(Status::OK, getJpegBufferSize(staticMeta, &jpegBufferSize));
2878         ASSERT_NE(0u, jpegBufferSize);
2879 
2880         int32_t streamId = 0;
2881         uint32_t streamConfigCounter = 0;
2882         for (auto& it : outputStreams) {
2883             V3_2::Stream stream3_2;
2884             V3_2::DataspaceFlags dataspaceFlag = 0;
2885             switch (static_cast<PixelFormat>(it.format)) {
2886                 case PixelFormat::BLOB:
2887                     dataspaceFlag = static_cast<V3_2::DataspaceFlags>(Dataspace::V0_JFIF);
2888                     break;
2889                 case PixelFormat::Y16:
2890                     dataspaceFlag = static_cast<V3_2::DataspaceFlags>(Dataspace::DEPTH);
2891                     break;
2892                 default:
2893                     dataspaceFlag = static_cast<V3_2::DataspaceFlags>(Dataspace::UNKNOWN);
2894             }
2895             stream3_2 = {streamId,
2896                              StreamType::OUTPUT,
2897                              static_cast<uint32_t>(it.width),
2898                              static_cast<uint32_t>(it.height),
2899                              static_cast<PixelFormat>(it.format),
2900                              GRALLOC1_CONSUMER_USAGE_HWCOMPOSER,
2901                              dataspaceFlag,
2902                              StreamRotation::ROTATION_0};
2903             ::android::hardware::hidl_vec<V3_2::Stream> streams3_2 = {stream3_2};
2904             ::android::hardware::camera::device::V3_5::StreamConfiguration config3_5;
2905             ::android::hardware::camera::device::V3_4::StreamConfiguration config3_4;
2906             ::android::hardware::camera::device::V3_2::StreamConfiguration config3_2;
2907             createStreamConfiguration(streams3_2, StreamConfigurationMode::NORMAL_MODE,
2908                                       &config3_2, &config3_4, &config3_5, jpegBufferSize);
2909             if (session3_5 != nullptr) {
2910                 bool expectStreamCombQuery = (isLogicalMultiCamera(staticMeta) == Status::OK);
2911                 verifyStreamCombination(cameraDevice3_5, config3_4,
2912                         /*expectedStatus*/ true, expectStreamCombQuery);
2913                 config3_5.streamConfigCounter = streamConfigCounter++;
2914                 ret = session3_5->configureStreams_3_5(config3_5,
2915                         [streamId](Status s, device::V3_4::HalStreamConfiguration halConfig) {
2916                             ASSERT_EQ(Status::OK, s);
2917                             ASSERT_EQ(1u, halConfig.streams.size());
2918                             ASSERT_EQ(halConfig.streams[0].v3_3.v3_2.id, streamId);
2919                         });
2920             } else if (session3_4 != nullptr) {
2921                 ret = session3_4->configureStreams_3_4(config3_4,
2922                         [streamId](Status s, device::V3_4::HalStreamConfiguration halConfig) {
2923                             ASSERT_EQ(Status::OK, s);
2924                             ASSERT_EQ(1u, halConfig.streams.size());
2925                             ASSERT_EQ(halConfig.streams[0].v3_3.v3_2.id, streamId);
2926                         });
2927             } else if (session3_3 != nullptr) {
2928                 ret = session3_3->configureStreams_3_3(config3_2,
2929                         [streamId](Status s, device::V3_3::HalStreamConfiguration halConfig) {
2930                             ASSERT_EQ(Status::OK, s);
2931                             ASSERT_EQ(1u, halConfig.streams.size());
2932                             ASSERT_EQ(halConfig.streams[0].v3_2.id, streamId);
2933                         });
2934             } else {
2935                 ret = session->configureStreams(config3_2,
2936                         [streamId](Status s, HalStreamConfiguration halConfig) {
2937                             ASSERT_EQ(Status::OK, s);
2938                             ASSERT_EQ(1u, halConfig.streams.size());
2939                             ASSERT_EQ(halConfig.streams[0].id, streamId);
2940                         });
2941             }
2942             ASSERT_TRUE(ret.isOk());
2943             streamId++;
2944         }
2945 
2946         free_camera_metadata(staticMeta);
2947         ret = session->close();
2948         ASSERT_TRUE(ret.isOk());
2949     }
2950 }
2951 
2952 // Check for correct handling of invalid/incorrect configuration parameters.
TEST_F(CameraHidlTest,configureStreamsInvalidOutputs)2953 TEST_F(CameraHidlTest, configureStreamsInvalidOutputs) {
2954     hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
2955     std::vector<AvailableStream> outputStreams;
2956 
2957     for (const auto& name : cameraDeviceNames) {
2958         int deviceVersion = getCameraDeviceVersion(name, mProviderType);
2959         if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) {
2960             continue;
2961         } else if (deviceVersion <= 0) {
2962             ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
2963             ADD_FAILURE();
2964             return;
2965         }
2966 
2967         camera_metadata_t* staticMeta;
2968         Return<void> ret;
2969         sp<ICameraDeviceSession> session;
2970         sp<device::V3_3::ICameraDeviceSession> session3_3;
2971         sp<device::V3_4::ICameraDeviceSession> session3_4;
2972         sp<device::V3_5::ICameraDeviceSession> session3_5;
2973         sp<device::V3_2::ICameraDevice> cameraDevice;
2974         sp<device::V3_5::ICameraDevice> cameraDevice3_5;
2975         openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/,
2976                 &cameraDevice /*out*/);
2977         castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5);
2978         castDevice(cameraDevice, deviceVersion, &cameraDevice3_5);
2979 
2980         outputStreams.clear();
2981         ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta, outputStreams));
2982         ASSERT_NE(0u, outputStreams.size());
2983 
2984         uint32_t jpegBufferSize = 0;
2985         ASSERT_EQ(Status::OK, getJpegBufferSize(staticMeta, &jpegBufferSize));
2986         ASSERT_NE(0u, jpegBufferSize);
2987 
2988         int32_t streamId = 0;
2989         V3_2::Stream stream3_2 = {streamId++,
2990                          StreamType::OUTPUT,
2991                          static_cast<uint32_t>(0),
2992                          static_cast<uint32_t>(0),
2993                          static_cast<PixelFormat>(outputStreams[0].format),
2994                          GRALLOC1_CONSUMER_USAGE_HWCOMPOSER,
2995                          0,
2996                          StreamRotation::ROTATION_0};
2997         uint32_t streamConfigCounter = 0;
2998         ::android::hardware::hidl_vec<V3_2::Stream> streams = {stream3_2};
2999         ::android::hardware::camera::device::V3_5::StreamConfiguration config3_5;
3000         ::android::hardware::camera::device::V3_4::StreamConfiguration config3_4;
3001         ::android::hardware::camera::device::V3_2::StreamConfiguration config3_2;
3002         createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE,
3003                                   &config3_2, &config3_4, &config3_5, jpegBufferSize);
3004         if (session3_5 != nullptr) {
3005             verifyStreamCombination(cameraDevice3_5, config3_4, /*expectedStatus*/ false,
3006                     /*expectStreamCombQuery*/false);
3007             config3_5.streamConfigCounter = streamConfigCounter++;
3008             ret = session3_5->configureStreams_3_5(config3_5,
3009                     [](Status s, device::V3_4::HalStreamConfiguration) {
3010                         ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) ||
3011                             (Status::INTERNAL_ERROR == s));
3012                     });
3013         } else if (session3_4 != nullptr) {
3014             ret = session3_4->configureStreams_3_4(config3_4,
3015                     [](Status s, device::V3_4::HalStreamConfiguration) {
3016                         ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) ||
3017                                 (Status::INTERNAL_ERROR == s));
3018                     });
3019         } else if(session3_3 != nullptr) {
3020             ret = session3_3->configureStreams_3_3(config3_2,
3021                     [](Status s, device::V3_3::HalStreamConfiguration) {
3022                         ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) ||
3023                                 (Status::INTERNAL_ERROR == s));
3024                     });
3025         } else {
3026             ret = session->configureStreams(config3_2,
3027                     [](Status s, HalStreamConfiguration) {
3028                         ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) ||
3029                                 (Status::INTERNAL_ERROR == s));
3030                     });
3031         }
3032         ASSERT_TRUE(ret.isOk());
3033 
3034         stream3_2 = {streamId++,
3035                   StreamType::OUTPUT,
3036                   static_cast<uint32_t>(UINT32_MAX),
3037                   static_cast<uint32_t>(UINT32_MAX),
3038                   static_cast<PixelFormat>(outputStreams[0].format),
3039                   GRALLOC1_CONSUMER_USAGE_HWCOMPOSER,
3040                   0,
3041                   StreamRotation::ROTATION_0};
3042         streams[0] = stream3_2;
3043         createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE,
3044                 &config3_2, &config3_4, &config3_5, jpegBufferSize);
3045         if (session3_5 != nullptr) {
3046             config3_5.streamConfigCounter = streamConfigCounter++;
3047             ret = session3_5->configureStreams_3_5(config3_5, [](Status s,
3048                         device::V3_4::HalStreamConfiguration) {
3049                     ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
3050                 });
3051         } else if(session3_4 != nullptr) {
3052             ret = session3_4->configureStreams_3_4(config3_4, [](Status s,
3053                         device::V3_4::HalStreamConfiguration) {
3054                     ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
3055                 });
3056         } else if(session3_3 != nullptr) {
3057             ret = session3_3->configureStreams_3_3(config3_2, [](Status s,
3058                         device::V3_3::HalStreamConfiguration) {
3059                     ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
3060                 });
3061         } else {
3062             ret = session->configureStreams(config3_2, [](Status s,
3063                         HalStreamConfiguration) {
3064                     ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
3065                 });
3066         }
3067         ASSERT_TRUE(ret.isOk());
3068 
3069         for (auto& it : outputStreams) {
3070             stream3_2 = {streamId++,
3071                       StreamType::OUTPUT,
3072                       static_cast<uint32_t>(it.width),
3073                       static_cast<uint32_t>(it.height),
3074                       static_cast<PixelFormat>(UINT32_MAX),
3075                       GRALLOC1_CONSUMER_USAGE_HWCOMPOSER,
3076                       0,
3077                       StreamRotation::ROTATION_0};
3078             streams[0] = stream3_2;
3079             createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE,
3080                     &config3_2, &config3_4, &config3_5, jpegBufferSize);
3081             if (session3_5 != nullptr) {
3082                 config3_5.streamConfigCounter = streamConfigCounter++;
3083                 ret = session3_5->configureStreams_3_5(config3_5,
3084                         [](Status s, device::V3_4::HalStreamConfiguration) {
3085                             ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
3086                         });
3087             } else if(session3_4 != nullptr) {
3088                 ret = session3_4->configureStreams_3_4(config3_4,
3089                         [](Status s, device::V3_4::HalStreamConfiguration) {
3090                             ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
3091                         });
3092             } else if(session3_3 != nullptr) {
3093                 ret = session3_3->configureStreams_3_3(config3_2,
3094                         [](Status s, device::V3_3::HalStreamConfiguration) {
3095                             ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
3096                         });
3097             } else {
3098                 ret = session->configureStreams(config3_2,
3099                         [](Status s, HalStreamConfiguration) {
3100                             ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
3101                         });
3102             }
3103             ASSERT_TRUE(ret.isOk());
3104 
3105             stream3_2 = {streamId++,
3106                       StreamType::OUTPUT,
3107                       static_cast<uint32_t>(it.width),
3108                       static_cast<uint32_t>(it.height),
3109                       static_cast<PixelFormat>(it.format),
3110                       GRALLOC1_CONSUMER_USAGE_HWCOMPOSER,
3111                       0,
3112                       static_cast<StreamRotation>(UINT32_MAX)};
3113             streams[0] = stream3_2;
3114             createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE,
3115                     &config3_2, &config3_4, &config3_5, jpegBufferSize);
3116             if (session3_5 != nullptr) {
3117                 config3_5.streamConfigCounter = streamConfigCounter++;
3118                 ret = session3_5->configureStreams_3_5(config3_5,
3119                         [](Status s, device::V3_4::HalStreamConfiguration) {
3120                             ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
3121                         });
3122             } else if(session3_4 != nullptr) {
3123                 ret = session3_4->configureStreams_3_4(config3_4,
3124                         [](Status s, device::V3_4::HalStreamConfiguration) {
3125                             ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
3126                         });
3127             } else if(session3_3 != nullptr) {
3128                 ret = session3_3->configureStreams_3_3(config3_2,
3129                         [](Status s, device::V3_3::HalStreamConfiguration) {
3130                             ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
3131                         });
3132             } else {
3133                 ret = session->configureStreams(config3_2,
3134                         [](Status s, HalStreamConfiguration) {
3135                             ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
3136                         });
3137             }
3138             ASSERT_TRUE(ret.isOk());
3139         }
3140 
3141         free_camera_metadata(staticMeta);
3142         ret = session->close();
3143         ASSERT_TRUE(ret.isOk());
3144     }
3145 }
3146 
3147 // Check whether all supported ZSL output stream combinations can be
3148 // configured successfully.
TEST_F(CameraHidlTest,configureStreamsZSLInputOutputs)3149 TEST_F(CameraHidlTest, configureStreamsZSLInputOutputs) {
3150     hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
3151     std::vector<AvailableStream> inputStreams;
3152     std::vector<AvailableZSLInputOutput> inputOutputMap;
3153 
3154     for (const auto& name : cameraDeviceNames) {
3155         int deviceVersion = getCameraDeviceVersion(name, mProviderType);
3156         if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) {
3157             continue;
3158         } else if (deviceVersion <= 0) {
3159             ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
3160             ADD_FAILURE();
3161             return;
3162         }
3163 
3164         camera_metadata_t* staticMeta;
3165         Return<void> ret;
3166         sp<ICameraDeviceSession> session;
3167         sp<device::V3_3::ICameraDeviceSession> session3_3;
3168         sp<device::V3_4::ICameraDeviceSession> session3_4;
3169         sp<device::V3_5::ICameraDeviceSession> session3_5;
3170         sp<device::V3_2::ICameraDevice> cameraDevice;
3171         sp<device::V3_5::ICameraDevice> cameraDevice3_5;
3172         openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/,
3173                 &cameraDevice /*out*/);
3174         castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5);
3175         castDevice(cameraDevice, deviceVersion, &cameraDevice3_5);
3176 
3177         Status rc = isZSLModeAvailable(staticMeta);
3178         if (Status::METHOD_NOT_SUPPORTED == rc) {
3179             ret = session->close();
3180             ASSERT_TRUE(ret.isOk());
3181             continue;
3182         }
3183         ASSERT_EQ(Status::OK, rc);
3184 
3185         inputStreams.clear();
3186         ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta, inputStreams));
3187         ASSERT_NE(0u, inputStreams.size());
3188 
3189         inputOutputMap.clear();
3190         ASSERT_EQ(Status::OK, getZSLInputOutputMap(staticMeta, inputOutputMap));
3191         ASSERT_NE(0u, inputOutputMap.size());
3192 
3193         bool supportMonoY8 = false;
3194         if (Status::OK == isMonochromeCamera(staticMeta)) {
3195             for (auto& it : inputStreams) {
3196                 if (it.format == static_cast<uint32_t>(PixelFormat::Y8)) {
3197                     supportMonoY8 = true;
3198                     break;
3199                 }
3200             }
3201         }
3202 
3203         uint32_t jpegBufferSize = 0;
3204         ASSERT_EQ(Status::OK, getJpegBufferSize(staticMeta, &jpegBufferSize));
3205         ASSERT_NE(0u, jpegBufferSize);
3206 
3207         int32_t streamId = 0;
3208         bool hasPrivToY8 = false, hasY8ToY8 = false, hasY8ToBlob = false;
3209         uint32_t streamConfigCounter = 0;
3210         for (auto& inputIter : inputOutputMap) {
3211             AvailableStream input;
3212             ASSERT_EQ(Status::OK, findLargestSize(inputStreams, inputIter.inputFormat,
3213                     input));
3214             ASSERT_NE(0u, inputStreams.size());
3215 
3216             if (inputIter.inputFormat == static_cast<uint32_t>(PixelFormat::IMPLEMENTATION_DEFINED)
3217                     && inputIter.outputFormat == static_cast<uint32_t>(PixelFormat::Y8)) {
3218                 hasPrivToY8 = true;
3219             } else if (inputIter.inputFormat == static_cast<uint32_t>(PixelFormat::Y8)) {
3220                 if (inputIter.outputFormat == static_cast<uint32_t>(PixelFormat::BLOB)) {
3221                     hasY8ToBlob = true;
3222                 } else if (inputIter.outputFormat == static_cast<uint32_t>(PixelFormat::Y8)) {
3223                     hasY8ToY8 = true;
3224                 }
3225             }
3226             AvailableStream outputThreshold = {INT32_MAX, INT32_MAX,
3227                                                inputIter.outputFormat};
3228             std::vector<AvailableStream> outputStreams;
3229             ASSERT_EQ(Status::OK,
3230                       getAvailableOutputStreams(staticMeta, outputStreams,
3231                               &outputThreshold));
3232             for (auto& outputIter : outputStreams) {
3233                 V3_2::Stream zslStream = {streamId++,
3234                                     StreamType::OUTPUT,
3235                                     static_cast<uint32_t>(input.width),
3236                                     static_cast<uint32_t>(input.height),
3237                                     static_cast<PixelFormat>(input.format),
3238                                     GRALLOC_USAGE_HW_CAMERA_ZSL,
3239                                     0,
3240                                     StreamRotation::ROTATION_0};
3241                 V3_2::Stream inputStream = {streamId++,
3242                                       StreamType::INPUT,
3243                                       static_cast<uint32_t>(input.width),
3244                                       static_cast<uint32_t>(input.height),
3245                                       static_cast<PixelFormat>(input.format),
3246                                       0,
3247                                       0,
3248                                       StreamRotation::ROTATION_0};
3249                 V3_2::Stream outputStream = {streamId++,
3250                                        StreamType::OUTPUT,
3251                                        static_cast<uint32_t>(outputIter.width),
3252                                        static_cast<uint32_t>(outputIter.height),
3253                                        static_cast<PixelFormat>(outputIter.format),
3254                                        GRALLOC1_CONSUMER_USAGE_HWCOMPOSER,
3255                                        0,
3256                                        StreamRotation::ROTATION_0};
3257 
3258                 ::android::hardware::hidl_vec<V3_2::Stream> streams = {inputStream, zslStream,
3259                                                                  outputStream};
3260                 ::android::hardware::camera::device::V3_5::StreamConfiguration config3_5;
3261                 ::android::hardware::camera::device::V3_4::StreamConfiguration config3_4;
3262                 ::android::hardware::camera::device::V3_2::StreamConfiguration config3_2;
3263                 createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE,
3264                                           &config3_2, &config3_4, &config3_5, jpegBufferSize);
3265                 if (session3_5 != nullptr) {
3266                     verifyStreamCombination(cameraDevice3_5, config3_4,
3267                             /*expectedStatus*/ true, /*expectStreamCombQuery*/ false);
3268                     config3_5.streamConfigCounter = streamConfigCounter++;
3269                     ret = session3_5->configureStreams_3_5(config3_5,
3270                             [](Status s, device::V3_4::HalStreamConfiguration halConfig) {
3271                                 ASSERT_EQ(Status::OK, s);
3272                                 ASSERT_EQ(3u, halConfig.streams.size());
3273                             });
3274                 } else if (session3_4 != nullptr) {
3275                     ret = session3_4->configureStreams_3_4(config3_4,
3276                             [](Status s, device::V3_4::HalStreamConfiguration halConfig) {
3277                                 ASSERT_EQ(Status::OK, s);
3278                                 ASSERT_EQ(3u, halConfig.streams.size());
3279                             });
3280                 } else if (session3_3 != nullptr) {
3281                     ret = session3_3->configureStreams_3_3(config3_2,
3282                             [](Status s, device::V3_3::HalStreamConfiguration halConfig) {
3283                                 ASSERT_EQ(Status::OK, s);
3284                                 ASSERT_EQ(3u, halConfig.streams.size());
3285                             });
3286                 } else {
3287                     ret = session->configureStreams(config3_2,
3288                             [](Status s, HalStreamConfiguration halConfig) {
3289                                 ASSERT_EQ(Status::OK, s);
3290                                 ASSERT_EQ(3u, halConfig.streams.size());
3291                             });
3292                 }
3293                 ASSERT_TRUE(ret.isOk());
3294             }
3295         }
3296 
3297         if (supportMonoY8) {
3298             if (Status::OK == isZSLModeAvailable(staticMeta, PRIV_REPROCESS)) {
3299                 ASSERT_TRUE(hasPrivToY8);
3300             }
3301             if (Status::OK == isZSLModeAvailable(staticMeta, YUV_REPROCESS)) {
3302                 ASSERT_TRUE(hasY8ToY8);
3303                 ASSERT_TRUE(hasY8ToBlob);
3304             }
3305         }
3306 
3307         free_camera_metadata(staticMeta);
3308         ret = session->close();
3309         ASSERT_TRUE(ret.isOk());
3310     }
3311 }
3312 
3313 // Check whether session parameters are supported. If Hal support for them
3314 // exist, then try to configure a preview stream using them.
TEST_F(CameraHidlTest,configureStreamsWithSessionParameters)3315 TEST_F(CameraHidlTest, configureStreamsWithSessionParameters) {
3316     hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
3317     std::vector<AvailableStream> outputPreviewStreams;
3318     AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
3319                                         static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
3320 
3321     for (const auto& name : cameraDeviceNames) {
3322         int deviceVersion = getCameraDeviceVersion(name, mProviderType);
3323         if (deviceVersion <= 0) {
3324             ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
3325             ADD_FAILURE();
3326             return;
3327         } else if (deviceVersion < CAMERA_DEVICE_API_VERSION_3_4) {
3328             continue;
3329         }
3330 
3331         camera_metadata_t* staticMetaBuffer;
3332         Return<void> ret;
3333         sp<ICameraDeviceSession> session;
3334         sp<device::V3_3::ICameraDeviceSession> session3_3;
3335         sp<device::V3_4::ICameraDeviceSession> session3_4;
3336         sp<device::V3_5::ICameraDeviceSession> session3_5;
3337         openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMetaBuffer /*out*/);
3338         castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5);
3339         if (deviceVersion == CAMERA_DEVICE_API_VERSION_3_4) {
3340             ASSERT_NE(session3_4, nullptr);
3341         } else {
3342             ASSERT_NE(session3_5, nullptr);
3343         }
3344 
3345         std::unordered_set<int32_t> availableSessionKeys;
3346         auto rc = getSupportedKeys(staticMetaBuffer, ANDROID_REQUEST_AVAILABLE_SESSION_KEYS,
3347                 &availableSessionKeys);
3348         ASSERT_TRUE(Status::OK == rc);
3349         if (availableSessionKeys.empty()) {
3350             free_camera_metadata(staticMetaBuffer);
3351             ret = session->close();
3352             ASSERT_TRUE(ret.isOk());
3353             continue;
3354         }
3355 
3356         android::hardware::camera::common::V1_0::helper::CameraMetadata previewRequestSettings;
3357         android::hardware::camera::common::V1_0::helper::CameraMetadata sessionParams,
3358                 modifiedSessionParams;
3359         constructFilteredSettings(session, availableSessionKeys, RequestTemplate::PREVIEW,
3360                 &previewRequestSettings, &sessionParams);
3361         if (sessionParams.isEmpty()) {
3362             free_camera_metadata(staticMetaBuffer);
3363             ret = session->close();
3364             ASSERT_TRUE(ret.isOk());
3365             continue;
3366         }
3367 
3368         outputPreviewStreams.clear();
3369 
3370         ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMetaBuffer, outputPreviewStreams,
3371                 &previewThreshold));
3372         ASSERT_NE(0u, outputPreviewStreams.size());
3373 
3374         V3_4::Stream previewStream;
3375         previewStream.v3_2 = {0,
3376                                 StreamType::OUTPUT,
3377                                 static_cast<uint32_t>(outputPreviewStreams[0].width),
3378                                 static_cast<uint32_t>(outputPreviewStreams[0].height),
3379                                 static_cast<PixelFormat>(outputPreviewStreams[0].format),
3380                                 GRALLOC1_CONSUMER_USAGE_HWCOMPOSER,
3381                                 0,
3382                                 StreamRotation::ROTATION_0};
3383         previewStream.bufferSize = 0;
3384         ::android::hardware::hidl_vec<V3_4::Stream> streams = {previewStream};
3385         ::android::hardware::camera::device::V3_4::StreamConfiguration config;
3386         ::android::hardware::camera::device::V3_5::StreamConfiguration config3_5;
3387         config.streams = streams;
3388         config.operationMode = StreamConfigurationMode::NORMAL_MODE;
3389         modifiedSessionParams = sessionParams;
3390         auto sessionParamsBuffer = sessionParams.release();
3391         config.sessionParams.setToExternal(reinterpret_cast<uint8_t *> (sessionParamsBuffer),
3392                 get_camera_metadata_size(sessionParamsBuffer));
3393         config3_5.v3_4 = config;
3394         config3_5.streamConfigCounter = 0;
3395         if (session3_5 != nullptr) {
3396             bool newSessionParamsAvailable = false;
3397             for (const auto& it : availableSessionKeys) {
3398                 if (modifiedSessionParams.exists(it)) {
3399                     modifiedSessionParams.erase(it);
3400                     newSessionParamsAvailable = true;
3401                     break;
3402                 }
3403             }
3404             if (newSessionParamsAvailable) {
3405                 auto modifiedSessionParamsBuffer = modifiedSessionParams.release();
3406                 verifySessionReconfigurationQuery(session3_5, sessionParamsBuffer,
3407                         modifiedSessionParamsBuffer);
3408                 modifiedSessionParams.acquire(modifiedSessionParamsBuffer);
3409             }
3410 
3411             ret = session3_5->configureStreams_3_5(config3_5,
3412                     [](Status s, device::V3_4::HalStreamConfiguration halConfig) {
3413                         ASSERT_EQ(Status::OK, s);
3414                         ASSERT_EQ(1u, halConfig.streams.size());
3415                     });
3416         } else {
3417             ret = session3_4->configureStreams_3_4(config,
3418                     [](Status s, device::V3_4::HalStreamConfiguration halConfig) {
3419                         ASSERT_EQ(Status::OK, s);
3420                         ASSERT_EQ(1u, halConfig.streams.size());
3421                     });
3422         }
3423         sessionParams.acquire(sessionParamsBuffer);
3424         ASSERT_TRUE(ret.isOk());
3425 
3426         free_camera_metadata(staticMetaBuffer);
3427         ret = session->close();
3428         ASSERT_TRUE(ret.isOk());
3429     }
3430 }
3431 
3432 // Verify that all supported preview + still capture stream combinations
3433 // can be configured successfully.
TEST_F(CameraHidlTest,configureStreamsPreviewStillOutputs)3434 TEST_F(CameraHidlTest, configureStreamsPreviewStillOutputs) {
3435     hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
3436     std::vector<AvailableStream> outputBlobStreams;
3437     std::vector<AvailableStream> outputPreviewStreams;
3438     AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
3439                                         static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
3440     AvailableStream blobThreshold = {INT32_MAX, INT32_MAX,
3441                                      static_cast<int32_t>(PixelFormat::BLOB)};
3442 
3443     for (const auto& name : cameraDeviceNames) {
3444         int deviceVersion = getCameraDeviceVersion(name, mProviderType);
3445         if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) {
3446             continue;
3447         } else if (deviceVersion <= 0) {
3448             ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
3449             ADD_FAILURE();
3450             return;
3451         }
3452 
3453         camera_metadata_t* staticMeta;
3454         Return<void> ret;
3455         sp<ICameraDeviceSession> session;
3456         sp<device::V3_3::ICameraDeviceSession> session3_3;
3457         sp<device::V3_4::ICameraDeviceSession> session3_4;
3458         sp<device::V3_5::ICameraDeviceSession> session3_5;
3459         sp<device::V3_2::ICameraDevice> cameraDevice;
3460         sp<device::V3_5::ICameraDevice> cameraDevice3_5;
3461         openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/,
3462                 &cameraDevice /*out*/);
3463         castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5);
3464         castDevice(cameraDevice, deviceVersion, &cameraDevice3_5);
3465 
3466         // Check if camera support depth only
3467         if (isDepthOnly(staticMeta)) {
3468             free_camera_metadata(staticMeta);
3469             ret = session->close();
3470             ASSERT_TRUE(ret.isOk());
3471             continue;
3472         }
3473 
3474         outputBlobStreams.clear();
3475         ASSERT_EQ(Status::OK,
3476                   getAvailableOutputStreams(staticMeta, outputBlobStreams,
3477                           &blobThreshold));
3478         ASSERT_NE(0u, outputBlobStreams.size());
3479 
3480         outputPreviewStreams.clear();
3481         ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta, outputPreviewStreams,
3482                 &previewThreshold));
3483         ASSERT_NE(0u, outputPreviewStreams.size());
3484 
3485         uint32_t jpegBufferSize = 0;
3486         ASSERT_EQ(Status::OK, getJpegBufferSize(staticMeta, &jpegBufferSize));
3487         ASSERT_NE(0u, jpegBufferSize);
3488 
3489         int32_t streamId = 0;
3490         uint32_t streamConfigCounter = 0;
3491         for (auto& blobIter : outputBlobStreams) {
3492             for (auto& previewIter : outputPreviewStreams) {
3493                 V3_2::Stream previewStream = {streamId++,
3494                                         StreamType::OUTPUT,
3495                                         static_cast<uint32_t>(previewIter.width),
3496                                         static_cast<uint32_t>(previewIter.height),
3497                                         static_cast<PixelFormat>(previewIter.format),
3498                                         GRALLOC1_CONSUMER_USAGE_HWCOMPOSER,
3499                                         0,
3500                                         StreamRotation::ROTATION_0};
3501                 V3_2::Stream blobStream = {streamId++,
3502                                      StreamType::OUTPUT,
3503                                      static_cast<uint32_t>(blobIter.width),
3504                                      static_cast<uint32_t>(blobIter.height),
3505                                      static_cast<PixelFormat>(blobIter.format),
3506                                      GRALLOC1_CONSUMER_USAGE_CPU_READ,
3507                                      static_cast<V3_2::DataspaceFlags>(Dataspace::V0_JFIF),
3508                                      StreamRotation::ROTATION_0};
3509                 ::android::hardware::hidl_vec<V3_2::Stream> streams = {previewStream,
3510                                                                  blobStream};
3511                 ::android::hardware::camera::device::V3_5::StreamConfiguration config3_5;
3512                 ::android::hardware::camera::device::V3_4::StreamConfiguration config3_4;
3513                 ::android::hardware::camera::device::V3_2::StreamConfiguration config3_2;
3514                 createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE,
3515                                           &config3_2, &config3_4, &config3_5, jpegBufferSize);
3516                 if (session3_5 != nullptr) {
3517                     verifyStreamCombination(cameraDevice3_5, config3_4,
3518                             /*expectedStatus*/ true, /*expectStreamCombQuery*/ false);
3519                     config3_5.streamConfigCounter = streamConfigCounter++;
3520                     ret = session3_5->configureStreams_3_5(config3_5,
3521                             [](Status s, device::V3_4::HalStreamConfiguration halConfig) {
3522                                 ASSERT_EQ(Status::OK, s);
3523                                 ASSERT_EQ(2u, halConfig.streams.size());
3524                             });
3525                 } else if (session3_4 != nullptr) {
3526                     ret = session3_4->configureStreams_3_4(config3_4,
3527                             [](Status s, device::V3_4::HalStreamConfiguration halConfig) {
3528                                 ASSERT_EQ(Status::OK, s);
3529                                 ASSERT_EQ(2u, halConfig.streams.size());
3530                             });
3531                 } else if (session3_3 != nullptr) {
3532                     ret = session3_3->configureStreams_3_3(config3_2,
3533                             [](Status s, device::V3_3::HalStreamConfiguration halConfig) {
3534                                 ASSERT_EQ(Status::OK, s);
3535                                 ASSERT_EQ(2u, halConfig.streams.size());
3536                             });
3537                 } else {
3538                     ret = session->configureStreams(config3_2,
3539                             [](Status s, HalStreamConfiguration halConfig) {
3540                                 ASSERT_EQ(Status::OK, s);
3541                                 ASSERT_EQ(2u, halConfig.streams.size());
3542                             });
3543                 }
3544                 ASSERT_TRUE(ret.isOk());
3545             }
3546         }
3547 
3548         free_camera_metadata(staticMeta);
3549         ret = session->close();
3550         ASSERT_TRUE(ret.isOk());
3551     }
3552 }
3553 
3554 // In case constrained mode is supported, test whether it can be
3555 // configured. Additionally check for common invalid inputs when
3556 // using this mode.
TEST_F(CameraHidlTest,configureStreamsConstrainedOutputs)3557 TEST_F(CameraHidlTest, configureStreamsConstrainedOutputs) {
3558     hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
3559 
3560     for (const auto& name : cameraDeviceNames) {
3561         int deviceVersion = getCameraDeviceVersion(name, mProviderType);
3562         if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) {
3563             continue;
3564         } else if (deviceVersion <= 0) {
3565             ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
3566             ADD_FAILURE();
3567             return;
3568         }
3569 
3570         camera_metadata_t* staticMeta;
3571         Return<void> ret;
3572         sp<ICameraDeviceSession> session;
3573         sp<device::V3_3::ICameraDeviceSession> session3_3;
3574         sp<device::V3_4::ICameraDeviceSession> session3_4;
3575         sp<device::V3_5::ICameraDeviceSession> session3_5;
3576         sp<device::V3_2::ICameraDevice> cameraDevice;
3577         sp<device::V3_5::ICameraDevice> cameraDevice3_5;
3578         openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/,
3579                 &cameraDevice /*out*/);
3580         castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5);
3581         castDevice(cameraDevice, deviceVersion, &cameraDevice3_5);
3582 
3583         Status rc = isConstrainedModeAvailable(staticMeta);
3584         if (Status::METHOD_NOT_SUPPORTED == rc) {
3585             ret = session->close();
3586             ASSERT_TRUE(ret.isOk());
3587             continue;
3588         }
3589         ASSERT_EQ(Status::OK, rc);
3590 
3591         AvailableStream hfrStream;
3592         rc = pickConstrainedModeSize(staticMeta, hfrStream);
3593         ASSERT_EQ(Status::OK, rc);
3594 
3595         int32_t streamId = 0;
3596         uint32_t streamConfigCounter = 0;
3597         V3_2::Stream stream = {streamId,
3598                          StreamType::OUTPUT,
3599                          static_cast<uint32_t>(hfrStream.width),
3600                          static_cast<uint32_t>(hfrStream.height),
3601                          static_cast<PixelFormat>(hfrStream.format),
3602                          GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER,
3603                          0,
3604                          StreamRotation::ROTATION_0};
3605         ::android::hardware::hidl_vec<V3_2::Stream> streams = {stream};
3606         ::android::hardware::camera::device::V3_5::StreamConfiguration config3_5;
3607         ::android::hardware::camera::device::V3_4::StreamConfiguration config3_4;
3608         ::android::hardware::camera::device::V3_2::StreamConfiguration config3_2;
3609         createStreamConfiguration(streams, StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE,
3610                                   &config3_2, &config3_4, &config3_5);
3611         if (session3_5 != nullptr) {
3612             verifyStreamCombination(cameraDevice3_5, config3_4,
3613                     /*expectedStatus*/ true, /*expectStreamCombQuery*/ false);
3614             config3_5.streamConfigCounter = streamConfigCounter++;
3615             ret = session3_5->configureStreams_3_5(config3_5,
3616                     [streamId](Status s, device::V3_4::HalStreamConfiguration halConfig) {
3617                         ASSERT_EQ(Status::OK, s);
3618                         ASSERT_EQ(1u, halConfig.streams.size());
3619                         ASSERT_EQ(halConfig.streams[0].v3_3.v3_2.id, streamId);
3620                     });
3621         } else if (session3_4 != nullptr) {
3622             ret = session3_4->configureStreams_3_4(config3_4,
3623                     [streamId](Status s, device::V3_4::HalStreamConfiguration halConfig) {
3624                         ASSERT_EQ(Status::OK, s);
3625                         ASSERT_EQ(1u, halConfig.streams.size());
3626                         ASSERT_EQ(halConfig.streams[0].v3_3.v3_2.id, streamId);
3627                     });
3628         } else if (session3_3 != nullptr) {
3629             ret = session3_3->configureStreams_3_3(config3_2,
3630                     [streamId](Status s, device::V3_3::HalStreamConfiguration halConfig) {
3631                         ASSERT_EQ(Status::OK, s);
3632                         ASSERT_EQ(1u, halConfig.streams.size());
3633                         ASSERT_EQ(halConfig.streams[0].v3_2.id, streamId);
3634                     });
3635         } else {
3636             ret = session->configureStreams(config3_2,
3637                     [streamId](Status s, HalStreamConfiguration halConfig) {
3638                         ASSERT_EQ(Status::OK, s);
3639                         ASSERT_EQ(1u, halConfig.streams.size());
3640                         ASSERT_EQ(halConfig.streams[0].id, streamId);
3641                     });
3642         }
3643         ASSERT_TRUE(ret.isOk());
3644 
3645         stream = {streamId++,
3646                   StreamType::OUTPUT,
3647                   static_cast<uint32_t>(0),
3648                   static_cast<uint32_t>(0),
3649                   static_cast<PixelFormat>(hfrStream.format),
3650                   GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER,
3651                   0,
3652                   StreamRotation::ROTATION_0};
3653         streams[0] = stream;
3654         createStreamConfiguration(streams, StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE,
3655                                   &config3_2, &config3_4, &config3_5);
3656         if (session3_5 != nullptr) {
3657             config3_5.streamConfigCounter = streamConfigCounter++;
3658             ret = session3_5->configureStreams_3_5(config3_5,
3659                     [](Status s, device::V3_4::HalStreamConfiguration) {
3660                         ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) ||
3661                                 (Status::INTERNAL_ERROR == s));
3662                     });
3663         } else if (session3_4 != nullptr) {
3664             ret = session3_4->configureStreams_3_4(config3_4,
3665                     [](Status s, device::V3_4::HalStreamConfiguration) {
3666                         ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) ||
3667                                 (Status::INTERNAL_ERROR == s));
3668                     });
3669         } else if (session3_3 != nullptr) {
3670             ret = session3_3->configureStreams_3_3(config3_2,
3671                     [](Status s, device::V3_3::HalStreamConfiguration) {
3672                         ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) ||
3673                                 (Status::INTERNAL_ERROR == s));
3674                     });
3675         } else {
3676             ret = session->configureStreams(config3_2,
3677                     [](Status s, HalStreamConfiguration) {
3678                         ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) ||
3679                                 (Status::INTERNAL_ERROR == s));
3680                     });
3681         }
3682         ASSERT_TRUE(ret.isOk());
3683 
3684         stream = {streamId++,
3685                   StreamType::OUTPUT,
3686                   static_cast<uint32_t>(UINT32_MAX),
3687                   static_cast<uint32_t>(UINT32_MAX),
3688                   static_cast<PixelFormat>(hfrStream.format),
3689                   GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER,
3690                   0,
3691                   StreamRotation::ROTATION_0};
3692         streams[0] = stream;
3693         createStreamConfiguration(streams, StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE,
3694                                   &config3_2, &config3_4, &config3_5);
3695         if (session3_5 != nullptr) {
3696             config3_5.streamConfigCounter = streamConfigCounter++;
3697             ret = session3_5->configureStreams_3_5(config3_5,
3698                     [](Status s, device::V3_4::HalStreamConfiguration) {
3699                         ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
3700                     });
3701         } else if (session3_4 != nullptr) {
3702             ret = session3_4->configureStreams_3_4(config3_4,
3703                     [](Status s, device::V3_4::HalStreamConfiguration) {
3704                         ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
3705                     });
3706         } else if (session3_3 != nullptr) {
3707             ret = session3_3->configureStreams_3_3(config3_2,
3708                     [](Status s, device::V3_3::HalStreamConfiguration) {
3709                         ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
3710                     });
3711         } else {
3712             ret = session->configureStreams(config3_2,
3713                     [](Status s, HalStreamConfiguration) {
3714                         ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
3715                     });
3716         }
3717         ASSERT_TRUE(ret.isOk());
3718 
3719         stream = {streamId++,
3720                   StreamType::OUTPUT,
3721                   static_cast<uint32_t>(hfrStream.width),
3722                   static_cast<uint32_t>(hfrStream.height),
3723                   static_cast<PixelFormat>(UINT32_MAX),
3724                   GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER,
3725                   0,
3726                   StreamRotation::ROTATION_0};
3727         streams[0] = stream;
3728         createStreamConfiguration(streams, StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE,
3729                                   &config3_2, &config3_4, &config3_5);
3730         if (session3_5 != nullptr) {
3731             config3_5.streamConfigCounter = streamConfigCounter++;
3732             ret = session3_5->configureStreams_3_5(config3_5,
3733                     [](Status s, device::V3_4::HalStreamConfiguration) {
3734                         ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
3735                     });
3736         } else if (session3_4 != nullptr) {
3737             ret = session3_4->configureStreams_3_4(config3_4,
3738                     [](Status s, device::V3_4::HalStreamConfiguration) {
3739                         ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
3740                     });
3741         } else if (session3_3 != nullptr) {
3742             ret = session3_3->configureStreams_3_3(config3_2,
3743                     [](Status s, device::V3_3::HalStreamConfiguration) {
3744                         ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
3745                     });
3746         } else {
3747             ret = session->configureStreams(config3_2,
3748                     [](Status s, HalStreamConfiguration) {
3749                         ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
3750                     });
3751         }
3752         ASSERT_TRUE(ret.isOk());
3753 
3754         free_camera_metadata(staticMeta);
3755         ret = session->close();
3756         ASSERT_TRUE(ret.isOk());
3757     }
3758 }
3759 
3760 // Verify that all supported video + snapshot stream combinations can
3761 // be configured successfully.
TEST_F(CameraHidlTest,configureStreamsVideoStillOutputs)3762 TEST_F(CameraHidlTest, configureStreamsVideoStillOutputs) {
3763     hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
3764     std::vector<AvailableStream> outputBlobStreams;
3765     std::vector<AvailableStream> outputVideoStreams;
3766     AvailableStream videoThreshold = {kMaxVideoWidth, kMaxVideoHeight,
3767                                       static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
3768     AvailableStream blobThreshold = {kMaxVideoWidth, kMaxVideoHeight,
3769                                      static_cast<int32_t>(PixelFormat::BLOB)};
3770 
3771     for (const auto& name : cameraDeviceNames) {
3772         int deviceVersion = getCameraDeviceVersion(name, mProviderType);
3773         if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) {
3774             continue;
3775         } else if (deviceVersion <= 0) {
3776             ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
3777             ADD_FAILURE();
3778             return;
3779         }
3780 
3781         camera_metadata_t* staticMeta;
3782         Return<void> ret;
3783         sp<ICameraDeviceSession> session;
3784         sp<device::V3_3::ICameraDeviceSession> session3_3;
3785         sp<device::V3_4::ICameraDeviceSession> session3_4;
3786         sp<device::V3_5::ICameraDeviceSession> session3_5;
3787         sp<device::V3_2::ICameraDevice> cameraDevice;
3788         sp<device::V3_5::ICameraDevice> cameraDevice3_5;
3789         openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/,
3790                 &cameraDevice /*out*/);
3791         castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5);
3792         castDevice(cameraDevice, deviceVersion, &cameraDevice3_5);
3793 
3794         // Check if camera support depth only
3795         if (isDepthOnly(staticMeta)) {
3796             free_camera_metadata(staticMeta);
3797             ret = session->close();
3798             ASSERT_TRUE(ret.isOk());
3799             continue;
3800         }
3801 
3802         outputBlobStreams.clear();
3803         ASSERT_EQ(Status::OK,
3804                   getAvailableOutputStreams(staticMeta, outputBlobStreams,
3805                           &blobThreshold));
3806         ASSERT_NE(0u, outputBlobStreams.size());
3807 
3808         outputVideoStreams.clear();
3809         ASSERT_EQ(Status::OK,
3810                   getAvailableOutputStreams(staticMeta, outputVideoStreams,
3811                           &videoThreshold));
3812         ASSERT_NE(0u, outputVideoStreams.size());
3813 
3814         uint32_t jpegBufferSize = 0;
3815         ASSERT_EQ(Status::OK, getJpegBufferSize(staticMeta, &jpegBufferSize));
3816         ASSERT_NE(0u, jpegBufferSize);
3817 
3818         int32_t streamId = 0;
3819         uint32_t streamConfigCounter = 0;
3820         for (auto& blobIter : outputBlobStreams) {
3821             for (auto& videoIter : outputVideoStreams) {
3822                 V3_2::Stream videoStream = {streamId++,
3823                                       StreamType::OUTPUT,
3824                                       static_cast<uint32_t>(videoIter.width),
3825                                       static_cast<uint32_t>(videoIter.height),
3826                                       static_cast<PixelFormat>(videoIter.format),
3827                                       GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER,
3828                                       0,
3829                                       StreamRotation::ROTATION_0};
3830                 V3_2::Stream blobStream = {streamId++,
3831                                      StreamType::OUTPUT,
3832                                      static_cast<uint32_t>(blobIter.width),
3833                                      static_cast<uint32_t>(blobIter.height),
3834                                      static_cast<PixelFormat>(blobIter.format),
3835                                      GRALLOC1_CONSUMER_USAGE_CPU_READ,
3836                                      static_cast<V3_2::DataspaceFlags>(Dataspace::V0_JFIF),
3837                                      StreamRotation::ROTATION_0};
3838                 ::android::hardware::hidl_vec<V3_2::Stream> streams = {videoStream, blobStream};
3839                 ::android::hardware::camera::device::V3_5::StreamConfiguration config3_5;
3840                 ::android::hardware::camera::device::V3_4::StreamConfiguration config3_4;
3841                 ::android::hardware::camera::device::V3_2::StreamConfiguration config3_2;
3842                 createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE,
3843                                           &config3_2, &config3_4, &config3_5, jpegBufferSize);
3844                 if (session3_5 != nullptr) {
3845                     verifyStreamCombination(cameraDevice3_5, config3_4,
3846                             /*expectedStatus*/ true, /*expectStreamCombQuery*/ false);
3847                     config3_5.streamConfigCounter = streamConfigCounter++;
3848                     ret = session3_5->configureStreams_3_5(config3_5,
3849                             [](Status s, device::V3_4::HalStreamConfiguration halConfig) {
3850                                 ASSERT_EQ(Status::OK, s);
3851                                 ASSERT_EQ(2u, halConfig.streams.size());
3852                             });
3853                 } else if (session3_4 != nullptr) {
3854                     ret = session3_4->configureStreams_3_4(config3_4,
3855                             [](Status s, device::V3_4::HalStreamConfiguration halConfig) {
3856                                 ASSERT_EQ(Status::OK, s);
3857                                 ASSERT_EQ(2u, halConfig.streams.size());
3858                             });
3859                 } else if (session3_3 != nullptr) {
3860                     ret = session3_3->configureStreams_3_3(config3_2,
3861                             [](Status s, device::V3_3::HalStreamConfiguration halConfig) {
3862                                 ASSERT_EQ(Status::OK, s);
3863                                 ASSERT_EQ(2u, halConfig.streams.size());
3864                             });
3865                 } else {
3866                     ret = session->configureStreams(config3_2,
3867                             [](Status s, HalStreamConfiguration halConfig) {
3868                                 ASSERT_EQ(Status::OK, s);
3869                                 ASSERT_EQ(2u, halConfig.streams.size());
3870                             });
3871                 }
3872                 ASSERT_TRUE(ret.isOk());
3873             }
3874         }
3875 
3876         free_camera_metadata(staticMeta);
3877         ret = session->close();
3878         ASSERT_TRUE(ret.isOk());
3879     }
3880 }
3881 
3882 // Generate and verify a camera capture request
TEST_F(CameraHidlTest,processCaptureRequestPreview)3883 TEST_F(CameraHidlTest, processCaptureRequestPreview) {
3884     hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
3885     AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
3886                                         static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
3887     uint64_t bufferId = 1;
3888     uint32_t frameNumber = 1;
3889     ::android::hardware::hidl_vec<uint8_t> settings;
3890 
3891     for (const auto& name : cameraDeviceNames) {
3892         int deviceVersion = getCameraDeviceVersion(name, mProviderType);
3893         if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) {
3894             continue;
3895         } else if (deviceVersion <= 0) {
3896             ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
3897             ADD_FAILURE();
3898             return;
3899         }
3900 
3901         V3_2::Stream previewStream;
3902         HalStreamConfiguration halStreamConfig;
3903         sp<ICameraDeviceSession> session;
3904         sp<DeviceCb> cb;
3905         bool supportsPartialResults = false;
3906         bool useHalBufManager = false;
3907         uint32_t partialResultCount = 0;
3908         configurePreviewStream(name, deviceVersion, mProvider, &previewThreshold, &session /*out*/,
3909                 &previewStream /*out*/, &halStreamConfig /*out*/,
3910                 &supportsPartialResults /*out*/,
3911                 &partialResultCount /*out*/, &useHalBufManager /*out*/, &cb /*out*/);
3912 
3913         std::shared_ptr<ResultMetadataQueue> resultQueue;
3914         auto resultQueueRet =
3915             session->getCaptureResultMetadataQueue(
3916                 [&resultQueue](const auto& descriptor) {
3917                     resultQueue = std::make_shared<ResultMetadataQueue>(
3918                             descriptor);
3919                     if (!resultQueue->isValid() ||
3920                             resultQueue->availableToWrite() <= 0) {
3921                         ALOGE("%s: HAL returns empty result metadata fmq,"
3922                                 " not use it", __func__);
3923                         resultQueue = nullptr;
3924                         // Don't use the queue onwards.
3925                     }
3926                 });
3927         ASSERT_TRUE(resultQueueRet.isOk());
3928 
3929         InFlightRequest inflightReq = {1, false, supportsPartialResults,
3930                                        partialResultCount, resultQueue};
3931 
3932         RequestTemplate reqTemplate = RequestTemplate::PREVIEW;
3933         Return<void> ret;
3934         ret = session->constructDefaultRequestSettings(reqTemplate,
3935                                                        [&](auto status, const auto& req) {
3936                                                            ASSERT_EQ(Status::OK, status);
3937                                                            settings = req;
3938                                                        });
3939         ASSERT_TRUE(ret.isOk());
3940 
3941         hidl_handle buffer_handle;
3942         StreamBuffer outputBuffer;
3943         if (useHalBufManager) {
3944             outputBuffer = {halStreamConfig.streams[0].id,
3945                             /*bufferId*/ 0,
3946                             buffer_handle,
3947                             BufferStatus::OK,
3948                             nullptr,
3949                             nullptr};
3950         } else {
3951             allocateGraphicBuffer(previewStream.width, previewStream.height,
3952                     android_convertGralloc1To0Usage(halStreamConfig.streams[0].producerUsage,
3953                         halStreamConfig.streams[0].consumerUsage),
3954                     halStreamConfig.streams[0].overrideFormat, &buffer_handle);
3955             outputBuffer = {halStreamConfig.streams[0].id,
3956                             bufferId,
3957                             buffer_handle,
3958                             BufferStatus::OK,
3959                             nullptr,
3960                             nullptr};
3961         }
3962         ::android::hardware::hidl_vec<StreamBuffer> outputBuffers = {outputBuffer};
3963         StreamBuffer emptyInputBuffer = {-1, 0, nullptr, BufferStatus::ERROR, nullptr,
3964                                          nullptr};
3965         CaptureRequest request = {frameNumber, 0 /* fmqSettingsSize */, settings,
3966                                   emptyInputBuffer, outputBuffers};
3967 
3968         {
3969             std::unique_lock<std::mutex> l(mLock);
3970             mInflightMap.clear();
3971             mInflightMap.add(frameNumber, &inflightReq);
3972         }
3973 
3974         Status status = Status::INTERNAL_ERROR;
3975         uint32_t numRequestProcessed = 0;
3976         hidl_vec<BufferCache> cachesToRemove;
3977         Return<void> returnStatus = session->processCaptureRequest(
3978             {request}, cachesToRemove, [&status, &numRequestProcessed](auto s,
3979                     uint32_t n) {
3980                 status = s;
3981                 numRequestProcessed = n;
3982             });
3983         ASSERT_TRUE(returnStatus.isOk());
3984         ASSERT_EQ(Status::OK, status);
3985         ASSERT_EQ(numRequestProcessed, 1u);
3986 
3987         {
3988             std::unique_lock<std::mutex> l(mLock);
3989             while (!inflightReq.errorCodeValid &&
3990                    ((0 < inflightReq.numBuffersLeft) ||
3991                            (!inflightReq.haveResultMetadata))) {
3992                 auto timeout = std::chrono::system_clock::now() +
3993                                std::chrono::seconds(kStreamBufferTimeoutSec);
3994                 ASSERT_NE(std::cv_status::timeout,
3995                         mResultCondition.wait_until(l, timeout));
3996             }
3997 
3998             ASSERT_FALSE(inflightReq.errorCodeValid);
3999             ASSERT_NE(inflightReq.resultOutputBuffers.size(), 0u);
4000             ASSERT_EQ(previewStream.id, inflightReq.resultOutputBuffers[0].streamId);
4001 
4002             request.frameNumber++;
4003             // Empty settings should be supported after the first call
4004             // for repeating requests.
4005             request.settings.setToExternal(nullptr, 0, true);
4006             // The buffer has been registered to HAL by bufferId, so per
4007             // API contract we should send a null handle for this buffer
4008             request.outputBuffers[0].buffer = nullptr;
4009             mInflightMap.clear();
4010             inflightReq = {1, false, supportsPartialResults, partialResultCount,
4011                            resultQueue};
4012             mInflightMap.add(request.frameNumber, &inflightReq);
4013         }
4014 
4015         returnStatus = session->processCaptureRequest(
4016             {request}, cachesToRemove, [&status, &numRequestProcessed](auto s,
4017                     uint32_t n) {
4018                 status = s;
4019                 numRequestProcessed = n;
4020             });
4021         ASSERT_TRUE(returnStatus.isOk());
4022         ASSERT_EQ(Status::OK, status);
4023         ASSERT_EQ(numRequestProcessed, 1u);
4024 
4025         {
4026             std::unique_lock<std::mutex> l(mLock);
4027             while (!inflightReq.errorCodeValid &&
4028                    ((0 < inflightReq.numBuffersLeft) ||
4029                            (!inflightReq.haveResultMetadata))) {
4030                 auto timeout = std::chrono::system_clock::now() +
4031                                std::chrono::seconds(kStreamBufferTimeoutSec);
4032                 ASSERT_NE(std::cv_status::timeout,
4033                         mResultCondition.wait_until(l, timeout));
4034             }
4035 
4036             ASSERT_FALSE(inflightReq.errorCodeValid);
4037             ASSERT_NE(inflightReq.resultOutputBuffers.size(), 0u);
4038             ASSERT_EQ(previewStream.id, inflightReq.resultOutputBuffers[0].streamId);
4039         }
4040 
4041         if (useHalBufManager) {
4042             verifyBuffersReturned(session, deviceVersion, previewStream.id, cb);
4043         }
4044 
4045         ret = session->close();
4046         ASSERT_TRUE(ret.isOk());
4047     }
4048 }
4049 
4050 // Generate and verify a multi-camera capture request
TEST_F(CameraHidlTest,processMultiCaptureRequestPreview)4051 TEST_F(CameraHidlTest, processMultiCaptureRequestPreview) {
4052     hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
4053     AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
4054                                         static_cast<int32_t>(PixelFormat::YCBCR_420_888)};
4055     uint64_t bufferId = 1;
4056     uint32_t frameNumber = 1;
4057     ::android::hardware::hidl_vec<uint8_t> settings;
4058     ::android::hardware::hidl_vec<uint8_t> emptySettings;
4059     hidl_string invalidPhysicalId = "-1";
4060 
4061     for (const auto& name : cameraDeviceNames) {
4062         int deviceVersion = getCameraDeviceVersion(name, mProviderType);
4063         if (deviceVersion < CAMERA_DEVICE_API_VERSION_3_5) {
4064             continue;
4065         }
4066         std::string version, deviceId;
4067         ASSERT_TRUE(::matchDeviceName(name, mProviderType, &version, &deviceId));
4068         camera_metadata_t* staticMeta;
4069         Return<void> ret;
4070         sp<ICameraDeviceSession> session;
4071         openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/);
4072 
4073         Status rc = isLogicalMultiCamera(staticMeta);
4074         if (Status::METHOD_NOT_SUPPORTED == rc) {
4075             free_camera_metadata(staticMeta);
4076             ret = session->close();
4077             ASSERT_TRUE(ret.isOk());
4078             continue;
4079         }
4080         std::unordered_set<std::string> physicalIds;
4081         rc = getPhysicalCameraIds(staticMeta, &physicalIds);
4082         ASSERT_TRUE(Status::OK == rc);
4083         ASSERT_TRUE(physicalIds.size() > 1);
4084 
4085         std::unordered_set<int32_t> physicalRequestKeyIDs;
4086         rc = getSupportedKeys(staticMeta,
4087                 ANDROID_REQUEST_AVAILABLE_PHYSICAL_CAMERA_REQUEST_KEYS, &physicalRequestKeyIDs);
4088         ASSERT_TRUE(Status::OK == rc);
4089         if (physicalRequestKeyIDs.empty()) {
4090             free_camera_metadata(staticMeta);
4091             ret = session->close();
4092             ASSERT_TRUE(ret.isOk());
4093             // The logical camera doesn't support any individual physical requests.
4094             continue;
4095         }
4096 
4097         android::hardware::camera::common::V1_0::helper::CameraMetadata defaultPreviewSettings;
4098         android::hardware::camera::common::V1_0::helper::CameraMetadata filteredSettings;
4099         constructFilteredSettings(session, physicalRequestKeyIDs, RequestTemplate::PREVIEW,
4100                 &defaultPreviewSettings, &filteredSettings);
4101         if (filteredSettings.isEmpty()) {
4102             // No physical device settings in default request.
4103             free_camera_metadata(staticMeta);
4104             ret = session->close();
4105             ASSERT_TRUE(ret.isOk());
4106             continue;
4107         }
4108 
4109         const camera_metadata_t *settingsBuffer = defaultPreviewSettings.getAndLock();
4110         settings.setToExternal(
4111                 reinterpret_cast<uint8_t *> (const_cast<camera_metadata_t *> (settingsBuffer)),
4112                 get_camera_metadata_size(settingsBuffer));
4113 
4114         free_camera_metadata(staticMeta);
4115         ret = session->close();
4116         ASSERT_TRUE(ret.isOk());
4117 
4118         // Leave only 2 physical devices in the id set.
4119         auto it = physicalIds.begin();
4120         string physicalDeviceId = *it; it++;
4121         physicalIds.erase(++it, physicalIds.end());
4122         ASSERT_EQ(physicalIds.size(), 2u);
4123 
4124         V3_4::HalStreamConfiguration halStreamConfig;
4125         bool supportsPartialResults = false;
4126         bool useHalBufManager = false;
4127         uint32_t partialResultCount = 0;
4128         V3_2::Stream previewStream;
4129         sp<device::V3_4::ICameraDeviceSession> session3_4;
4130         sp<device::V3_5::ICameraDeviceSession> session3_5;
4131         sp<DeviceCb> cb;
4132         configurePreviewStreams3_4(name, deviceVersion, mProvider, &previewThreshold, physicalIds,
4133                 &session3_4, &session3_5, &previewStream, &halStreamConfig /*out*/,
4134                 &supportsPartialResults /*out*/, &partialResultCount /*out*/,
4135                 &useHalBufManager /*out*/, &cb /*out*/, 0 /*streamConfigCounter*/,
4136                 true /*allowUnsupport*/);
4137         if (session3_5 == nullptr) {
4138             ret = session3_4->close();
4139             ASSERT_TRUE(ret.isOk());
4140             continue;
4141         }
4142 
4143         std::shared_ptr<ResultMetadataQueue> resultQueue;
4144         auto resultQueueRet =
4145             session3_4->getCaptureResultMetadataQueue(
4146                 [&resultQueue](const auto& descriptor) {
4147                     resultQueue = std::make_shared<ResultMetadataQueue>(
4148                             descriptor);
4149                     if (!resultQueue->isValid() ||
4150                             resultQueue->availableToWrite() <= 0) {
4151                         ALOGE("%s: HAL returns empty result metadata fmq,"
4152                                 " not use it", __func__);
4153                         resultQueue = nullptr;
4154                         // Don't use the queue onwards.
4155                     }
4156                 });
4157         ASSERT_TRUE(resultQueueRet.isOk());
4158 
4159         InFlightRequest inflightReq = {static_cast<ssize_t> (halStreamConfig.streams.size()), false,
4160             supportsPartialResults, partialResultCount, resultQueue};
4161 
4162         std::vector<hidl_handle> graphicBuffers;
4163         graphicBuffers.reserve(halStreamConfig.streams.size());
4164         ::android::hardware::hidl_vec<StreamBuffer> outputBuffers;
4165         outputBuffers.resize(halStreamConfig.streams.size());
4166         size_t k = 0;
4167         for (const auto& halStream : halStreamConfig.streams) {
4168             hidl_handle buffer_handle;
4169             if (useHalBufManager) {
4170                 outputBuffers[k] = {halStream.v3_3.v3_2.id, /*bufferId*/0, buffer_handle,
4171                     BufferStatus::OK, nullptr, nullptr};
4172             } else {
4173                 allocateGraphicBuffer(previewStream.width, previewStream.height,
4174                         android_convertGralloc1To0Usage(halStream.v3_3.v3_2.producerUsage,
4175                             halStream.v3_3.v3_2.consumerUsage),
4176                         halStream.v3_3.v3_2.overrideFormat, &buffer_handle);
4177                 graphicBuffers.push_back(buffer_handle);
4178                 outputBuffers[k] = {halStream.v3_3.v3_2.id, bufferId, buffer_handle,
4179                     BufferStatus::OK, nullptr, nullptr};
4180                 bufferId++;
4181             }
4182             k++;
4183         }
4184         hidl_vec<V3_4::PhysicalCameraSetting> camSettings(1);
4185         const camera_metadata_t *filteredSettingsBuffer = filteredSettings.getAndLock();
4186         camSettings[0].settings.setToExternal(
4187                 reinterpret_cast<uint8_t *> (const_cast<camera_metadata_t *> (
4188                         filteredSettingsBuffer)),
4189                 get_camera_metadata_size(filteredSettingsBuffer));
4190         camSettings[0].fmqSettingsSize = 0;
4191         camSettings[0].physicalCameraId = physicalDeviceId;
4192 
4193         StreamBuffer emptyInputBuffer = {-1, 0, nullptr, BufferStatus::ERROR, nullptr, nullptr};
4194         V3_4::CaptureRequest request = {{frameNumber, 0 /* fmqSettingsSize */, settings,
4195                                   emptyInputBuffer, outputBuffers}, camSettings};
4196 
4197         {
4198             std::unique_lock<std::mutex> l(mLock);
4199             mInflightMap.clear();
4200             mInflightMap.add(frameNumber, &inflightReq);
4201         }
4202 
4203         Status stat = Status::INTERNAL_ERROR;
4204         uint32_t numRequestProcessed = 0;
4205         hidl_vec<BufferCache> cachesToRemove;
4206         Return<void> returnStatus = session3_4->processCaptureRequest_3_4(
4207             {request}, cachesToRemove, [&stat, &numRequestProcessed](auto s, uint32_t n) {
4208                 stat = s;
4209                 numRequestProcessed = n;
4210             });
4211         ASSERT_TRUE(returnStatus.isOk());
4212         ASSERT_EQ(Status::OK, stat);
4213         ASSERT_EQ(numRequestProcessed, 1u);
4214 
4215         {
4216             std::unique_lock<std::mutex> l(mLock);
4217             while (!inflightReq.errorCodeValid &&
4218                     ((0 < inflightReq.numBuffersLeft) ||
4219                      (!inflightReq.haveResultMetadata))) {
4220                 auto timeout = std::chrono::system_clock::now() +
4221                     std::chrono::seconds(kStreamBufferTimeoutSec);
4222                 ASSERT_NE(std::cv_status::timeout,
4223                         mResultCondition.wait_until(l, timeout));
4224             }
4225 
4226             ASSERT_FALSE(inflightReq.errorCodeValid);
4227             ASSERT_NE(inflightReq.resultOutputBuffers.size(), 0u);
4228 
4229             request.v3_2.frameNumber++;
4230             // Empty settings should be supported after the first call
4231             // for repeating requests.
4232             request.v3_2.settings.setToExternal(nullptr, 0, true);
4233             request.physicalCameraSettings[0].settings.setToExternal(nullptr, 0, true);
4234             // The buffer has been registered to HAL by bufferId, so per
4235             // API contract we should send a null handle for this buffer
4236             request.v3_2.outputBuffers[0].buffer = nullptr;
4237             mInflightMap.clear();
4238             inflightReq = {static_cast<ssize_t> (physicalIds.size()), false,
4239                 supportsPartialResults, partialResultCount, resultQueue};
4240             mInflightMap.add(request.v3_2.frameNumber, &inflightReq);
4241         }
4242 
4243         returnStatus = session3_4->processCaptureRequest_3_4(
4244             {request}, cachesToRemove, [&stat, &numRequestProcessed](auto s, uint32_t n) {
4245                 stat = s;
4246                 numRequestProcessed = n;
4247             });
4248         ASSERT_TRUE(returnStatus.isOk());
4249         ASSERT_EQ(Status::OK, stat);
4250         ASSERT_EQ(numRequestProcessed, 1u);
4251 
4252         {
4253             std::unique_lock<std::mutex> l(mLock);
4254             while (!inflightReq.errorCodeValid &&
4255                     ((0 < inflightReq.numBuffersLeft) ||
4256                      (!inflightReq.haveResultMetadata))) {
4257                 auto timeout = std::chrono::system_clock::now() +
4258                     std::chrono::seconds(kStreamBufferTimeoutSec);
4259                 ASSERT_NE(std::cv_status::timeout,
4260                         mResultCondition.wait_until(l, timeout));
4261             }
4262 
4263             ASSERT_FALSE(inflightReq.errorCodeValid);
4264             ASSERT_NE(inflightReq.resultOutputBuffers.size(), 0u);
4265         }
4266 
4267         // Invalid physical camera id should fail process requests
4268         frameNumber++;
4269         camSettings[0].physicalCameraId = invalidPhysicalId;
4270         camSettings[0].settings = settings;
4271         request = {{frameNumber, 0 /* fmqSettingsSize */, settings,
4272             emptyInputBuffer, outputBuffers}, camSettings};
4273         returnStatus = session3_4->processCaptureRequest_3_4(
4274             {request}, cachesToRemove, [&stat, &numRequestProcessed](auto s, uint32_t n) {
4275                 stat = s;
4276                 numRequestProcessed = n;
4277             });
4278         ASSERT_TRUE(returnStatus.isOk());
4279         ASSERT_EQ(Status::ILLEGAL_ARGUMENT, stat);
4280 
4281         defaultPreviewSettings.unlock(settingsBuffer);
4282         filteredSettings.unlock(filteredSettingsBuffer);
4283 
4284         if (useHalBufManager) {
4285             hidl_vec<int32_t> streamIds(halStreamConfig.streams.size());
4286             for (size_t i = 0; i < streamIds.size(); i++) {
4287                 streamIds[i] = halStreamConfig.streams[i].v3_3.v3_2.id;
4288             }
4289             verifyBuffersReturned(session3_4, streamIds, cb);
4290         }
4291 
4292         ret = session3_4->close();
4293         ASSERT_TRUE(ret.isOk());
4294     }
4295 }
4296 
4297 // Generate and verify a burst containing alternating sensor sensitivity values
TEST_F(CameraHidlTest,processCaptureRequestBurstISO)4298 TEST_F(CameraHidlTest, processCaptureRequestBurstISO) {
4299     hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
4300     AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
4301                                         static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
4302     uint64_t bufferId = 1;
4303     uint32_t frameNumber = 1;
4304     float isoTol = .03f;
4305     ::android::hardware::hidl_vec<uint8_t> settings;
4306 
4307     for (const auto& name : cameraDeviceNames) {
4308         int deviceVersion = getCameraDeviceVersion(name, mProviderType);
4309         if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) {
4310             continue;
4311         } else if (deviceVersion <= 0) {
4312             ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
4313             ADD_FAILURE();
4314             return;
4315         }
4316         camera_metadata_t* staticMetaBuffer;
4317         Return<void> ret;
4318         sp<ICameraDeviceSession> session;
4319         openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMetaBuffer /*out*/);
4320         ::android::hardware::camera::common::V1_0::helper::CameraMetadata staticMeta(
4321                 staticMetaBuffer);
4322 
4323         camera_metadata_entry_t hwLevel = staticMeta.find(ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL);
4324         ASSERT_TRUE(0 < hwLevel.count);
4325         if (ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED == hwLevel.data.u8[0] ||
4326                 ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_EXTERNAL == hwLevel.data.u8[0]) {
4327             //Limited/External devices can skip this test
4328             ret = session->close();
4329             ASSERT_TRUE(ret.isOk());
4330             continue;
4331         }
4332 
4333         camera_metadata_entry_t isoRange = staticMeta.find(ANDROID_SENSOR_INFO_SENSITIVITY_RANGE);
4334         ASSERT_EQ(isoRange.count, 2u);
4335 
4336         ret = session->close();
4337         ASSERT_TRUE(ret.isOk());
4338 
4339         bool supportsPartialResults = false;
4340         bool useHalBufManager = false;
4341         uint32_t partialResultCount = 0;
4342         V3_2::Stream previewStream;
4343         HalStreamConfiguration halStreamConfig;
4344         sp<DeviceCb> cb;
4345         configurePreviewStream(name, deviceVersion, mProvider, &previewThreshold,
4346                 &session /*out*/, &previewStream /*out*/, &halStreamConfig /*out*/,
4347                 &supportsPartialResults /*out*/, &partialResultCount /*out*/,
4348                 &useHalBufManager /*out*/, &cb /*out*/);
4349         std::shared_ptr<ResultMetadataQueue> resultQueue;
4350 
4351         auto resultQueueRet = session->getCaptureResultMetadataQueue(
4352             [&resultQueue](const auto& descriptor) {
4353                 resultQueue = std::make_shared<ResultMetadataQueue>(descriptor);
4354                 if (!resultQueue->isValid() || resultQueue->availableToWrite() <= 0) {
4355                     ALOGE("%s: HAL returns empty result metadata fmq,"
4356                             " not use it", __func__);
4357                     resultQueue = nullptr;
4358                     // Don't use the queue onwards.
4359                 }
4360             });
4361         ASSERT_TRUE(resultQueueRet.isOk());
4362         ASSERT_NE(nullptr, resultQueue);
4363 
4364         ret = session->constructDefaultRequestSettings(RequestTemplate::PREVIEW,
4365             [&](auto status, const auto& req) {
4366                 ASSERT_EQ(Status::OK, status);
4367                 settings = req; });
4368         ASSERT_TRUE(ret.isOk());
4369 
4370         ::android::hardware::camera::common::V1_0::helper::CameraMetadata requestMeta;
4371         StreamBuffer emptyInputBuffer = {-1, 0, nullptr, BufferStatus::ERROR, nullptr, nullptr};
4372         hidl_handle buffers[kBurstFrameCount];
4373         StreamBuffer outputBuffers[kBurstFrameCount];
4374         CaptureRequest requests[kBurstFrameCount];
4375         InFlightRequest inflightReqs[kBurstFrameCount];
4376         int32_t isoValues[kBurstFrameCount];
4377         hidl_vec<uint8_t> requestSettings[kBurstFrameCount];
4378         for (uint32_t i = 0; i < kBurstFrameCount; i++) {
4379             std::unique_lock<std::mutex> l(mLock);
4380 
4381             isoValues[i] = ((i % 2) == 0) ? isoRange.data.i32[0] : isoRange.data.i32[1];
4382             if (useHalBufManager) {
4383                 outputBuffers[i] = {halStreamConfig.streams[0].id, /*bufferId*/0,
4384                     nullptr, BufferStatus::OK, nullptr, nullptr};
4385             } else {
4386                 allocateGraphicBuffer(previewStream.width, previewStream.height,
4387                         android_convertGralloc1To0Usage(halStreamConfig.streams[0].producerUsage,
4388                             halStreamConfig.streams[0].consumerUsage),
4389                         halStreamConfig.streams[0].overrideFormat, &buffers[i]);
4390                 outputBuffers[i] = {halStreamConfig.streams[0].id, bufferId + i,
4391                     buffers[i], BufferStatus::OK, nullptr, nullptr};
4392             }
4393 
4394             requestMeta.append(reinterpret_cast<camera_metadata_t *> (settings.data()));
4395 
4396             // Disable all 3A routines
4397             uint8_t mode = static_cast<uint8_t>(ANDROID_CONTROL_MODE_OFF);
4398             ASSERT_EQ(::android::OK, requestMeta.update(ANDROID_CONTROL_MODE, &mode, 1));
4399             ASSERT_EQ(::android::OK, requestMeta.update(ANDROID_SENSOR_SENSITIVITY, &isoValues[i],
4400                         1));
4401             camera_metadata_t *metaBuffer = requestMeta.release();
4402             requestSettings[i].setToExternal(reinterpret_cast<uint8_t *> (metaBuffer),
4403                     get_camera_metadata_size(metaBuffer), true);
4404 
4405             requests[i] = {frameNumber + i, 0 /* fmqSettingsSize */, requestSettings[i],
4406                 emptyInputBuffer, {outputBuffers[i]}};
4407 
4408             inflightReqs[i] = {1, false, supportsPartialResults, partialResultCount, resultQueue};
4409             mInflightMap.add(frameNumber + i, &inflightReqs[i]);
4410         }
4411 
4412         Status status = Status::INTERNAL_ERROR;
4413         uint32_t numRequestProcessed = 0;
4414         hidl_vec<BufferCache> cachesToRemove;
4415         hidl_vec<CaptureRequest> burstRequest;
4416         burstRequest.setToExternal(requests, kBurstFrameCount);
4417         Return<void> returnStatus = session->processCaptureRequest(burstRequest, cachesToRemove,
4418                 [&status, &numRequestProcessed] (auto s, uint32_t n) {
4419                     status = s;
4420                     numRequestProcessed = n;
4421                 });
4422         ASSERT_TRUE(returnStatus.isOk());
4423         ASSERT_EQ(Status::OK, status);
4424         ASSERT_EQ(numRequestProcessed, kBurstFrameCount);
4425 
4426         for (size_t i = 0; i < kBurstFrameCount; i++) {
4427             std::unique_lock<std::mutex> l(mLock);
4428             while (!inflightReqs[i].errorCodeValid && ((0 < inflightReqs[i].numBuffersLeft) ||
4429                             (!inflightReqs[i].haveResultMetadata))) {
4430                 auto timeout = std::chrono::system_clock::now() +
4431                         std::chrono::seconds(kStreamBufferTimeoutSec);
4432                 ASSERT_NE(std::cv_status::timeout, mResultCondition.wait_until(l, timeout));
4433             }
4434 
4435             ASSERT_FALSE(inflightReqs[i].errorCodeValid);
4436             ASSERT_NE(inflightReqs[i].resultOutputBuffers.size(), 0u);
4437             ASSERT_EQ(previewStream.id, inflightReqs[i].resultOutputBuffers[0].streamId);
4438             ASSERT_FALSE(inflightReqs[i].collectedResult.isEmpty());
4439             ASSERT_TRUE(inflightReqs[i].collectedResult.exists(ANDROID_SENSOR_SENSITIVITY));
4440             camera_metadata_entry_t isoResult = inflightReqs[i].collectedResult.find(
4441                     ANDROID_SENSOR_SENSITIVITY);
4442             ASSERT_TRUE(std::abs(isoResult.data.i32[0] - isoValues[i]) <=
4443                         std::round(isoValues[i]*isoTol));
4444         }
4445 
4446         if (useHalBufManager) {
4447             verifyBuffersReturned(session, deviceVersion, previewStream.id, cb);
4448         }
4449         ret = session->close();
4450         ASSERT_TRUE(ret.isOk());
4451     }
4452 }
4453 
4454 // Test whether an incorrect capture request with missing settings will
4455 // be reported correctly.
TEST_F(CameraHidlTest,processCaptureRequestInvalidSinglePreview)4456 TEST_F(CameraHidlTest, processCaptureRequestInvalidSinglePreview) {
4457     hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
4458     std::vector<AvailableStream> outputPreviewStreams;
4459     AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
4460                                         static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
4461     uint64_t bufferId = 1;
4462     uint32_t frameNumber = 1;
4463     ::android::hardware::hidl_vec<uint8_t> settings;
4464 
4465     for (const auto& name : cameraDeviceNames) {
4466         int deviceVersion = getCameraDeviceVersion(name, mProviderType);
4467         if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) {
4468             continue;
4469         } else if (deviceVersion <= 0) {
4470             ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
4471             ADD_FAILURE();
4472             return;
4473         }
4474 
4475         V3_2::Stream previewStream;
4476         HalStreamConfiguration halStreamConfig;
4477         sp<ICameraDeviceSession> session;
4478         sp<DeviceCb> cb;
4479         bool supportsPartialResults = false;
4480         bool useHalBufManager = false;
4481         uint32_t partialResultCount = 0;
4482         configurePreviewStream(name, deviceVersion, mProvider, &previewThreshold, &session /*out*/,
4483                 &previewStream /*out*/, &halStreamConfig /*out*/,
4484                 &supportsPartialResults /*out*/,
4485                 &partialResultCount /*out*/, &useHalBufManager /*out*/, &cb /*out*/);
4486 
4487         hidl_handle buffer_handle;
4488 
4489         if (useHalBufManager) {
4490             bufferId = 0;
4491         } else {
4492             allocateGraphicBuffer(previewStream.width, previewStream.height,
4493                     android_convertGralloc1To0Usage(halStreamConfig.streams[0].producerUsage,
4494                         halStreamConfig.streams[0].consumerUsage),
4495                     halStreamConfig.streams[0].overrideFormat, &buffer_handle);
4496         }
4497 
4498         StreamBuffer outputBuffer = {halStreamConfig.streams[0].id,
4499                                      bufferId,
4500                                      buffer_handle,
4501                                      BufferStatus::OK,
4502                                      nullptr,
4503                                      nullptr};
4504         ::android::hardware::hidl_vec<StreamBuffer> outputBuffers = {outputBuffer};
4505         StreamBuffer emptyInputBuffer = {-1, 0, nullptr, BufferStatus::ERROR, nullptr,
4506                                          nullptr};
4507         CaptureRequest request = {frameNumber, 0 /* fmqSettingsSize */, settings,
4508                                   emptyInputBuffer, outputBuffers};
4509 
4510         // Settings were not correctly initialized, we should fail here
4511         Status status = Status::OK;
4512         uint32_t numRequestProcessed = 0;
4513         hidl_vec<BufferCache> cachesToRemove;
4514         Return<void> ret = session->processCaptureRequest(
4515             {request}, cachesToRemove, [&status, &numRequestProcessed](auto s,
4516                     uint32_t n) {
4517                 status = s;
4518                 numRequestProcessed = n;
4519             });
4520         ASSERT_TRUE(ret.isOk());
4521         ASSERT_EQ(Status::ILLEGAL_ARGUMENT, status);
4522         ASSERT_EQ(numRequestProcessed, 0u);
4523 
4524         ret = session->close();
4525         ASSERT_TRUE(ret.isOk());
4526     }
4527 }
4528 
4529 // Check whether an invalid capture request with missing output buffers
4530 // will be reported correctly.
TEST_F(CameraHidlTest,processCaptureRequestInvalidBuffer)4531 TEST_F(CameraHidlTest, processCaptureRequestInvalidBuffer) {
4532     hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
4533     std::vector<AvailableStream> outputBlobStreams;
4534     AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
4535                                         static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
4536     uint32_t frameNumber = 1;
4537     ::android::hardware::hidl_vec<uint8_t> settings;
4538 
4539     for (const auto& name : cameraDeviceNames) {
4540         int deviceVersion = getCameraDeviceVersion(name, mProviderType);
4541         if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) {
4542             continue;
4543         } else if (deviceVersion <= 0) {
4544             ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
4545             ADD_FAILURE();
4546             return;
4547         }
4548 
4549         V3_2::Stream previewStream;
4550         HalStreamConfiguration halStreamConfig;
4551         sp<ICameraDeviceSession> session;
4552         sp<DeviceCb> cb;
4553         bool supportsPartialResults = false;
4554         bool useHalBufManager = false;
4555         uint32_t partialResultCount = 0;
4556         configurePreviewStream(name, deviceVersion, mProvider, &previewThreshold, &session /*out*/,
4557                 &previewStream /*out*/, &halStreamConfig /*out*/,
4558                 &supportsPartialResults /*out*/,
4559                 &partialResultCount /*out*/, &useHalBufManager /*out*/, &cb /*out*/);
4560 
4561         RequestTemplate reqTemplate = RequestTemplate::PREVIEW;
4562         Return<void> ret;
4563         ret = session->constructDefaultRequestSettings(reqTemplate,
4564                                                        [&](auto status, const auto& req) {
4565                                                            ASSERT_EQ(Status::OK, status);
4566                                                            settings = req;
4567                                                        });
4568         ASSERT_TRUE(ret.isOk());
4569 
4570         ::android::hardware::hidl_vec<StreamBuffer> emptyOutputBuffers;
4571         StreamBuffer emptyInputBuffer = {-1, 0, nullptr, BufferStatus::ERROR, nullptr,
4572                                          nullptr};
4573         CaptureRequest request = {frameNumber, 0 /* fmqSettingsSize */, settings,
4574                                   emptyInputBuffer, emptyOutputBuffers};
4575 
4576         // Output buffers are missing, we should fail here
4577         Status status = Status::OK;
4578         uint32_t numRequestProcessed = 0;
4579         hidl_vec<BufferCache> cachesToRemove;
4580         ret = session->processCaptureRequest(
4581             {request}, cachesToRemove, [&status, &numRequestProcessed](auto s,
4582                     uint32_t n) {
4583                 status = s;
4584                 numRequestProcessed = n;
4585             });
4586         ASSERT_TRUE(ret.isOk());
4587         ASSERT_EQ(Status::ILLEGAL_ARGUMENT, status);
4588         ASSERT_EQ(numRequestProcessed, 0u);
4589 
4590         ret = session->close();
4591         ASSERT_TRUE(ret.isOk());
4592     }
4593 }
4594 
4595 // Generate, trigger and flush a preview request
TEST_F(CameraHidlTest,flushPreviewRequest)4596 TEST_F(CameraHidlTest, flushPreviewRequest) {
4597     hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
4598     std::vector<AvailableStream> outputPreviewStreams;
4599     AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
4600                                         static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
4601     uint64_t bufferId = 1;
4602     uint32_t frameNumber = 1;
4603     ::android::hardware::hidl_vec<uint8_t> settings;
4604 
4605     for (const auto& name : cameraDeviceNames) {
4606         int deviceVersion = getCameraDeviceVersion(name, mProviderType);
4607         if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) {
4608             continue;
4609         } else if (deviceVersion <= 0) {
4610             ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
4611             ADD_FAILURE();
4612             return;
4613         }
4614 
4615         V3_2::Stream previewStream;
4616         HalStreamConfiguration halStreamConfig;
4617         sp<ICameraDeviceSession> session;
4618         sp<DeviceCb> cb;
4619         bool supportsPartialResults = false;
4620         bool useHalBufManager = false;
4621         uint32_t partialResultCount = 0;
4622         configurePreviewStream(name, deviceVersion, mProvider, &previewThreshold, &session /*out*/,
4623                 &previewStream /*out*/, &halStreamConfig /*out*/,
4624                 &supportsPartialResults /*out*/,
4625                 &partialResultCount /*out*/, &useHalBufManager /*out*/, &cb /*out*/);
4626 
4627         std::shared_ptr<ResultMetadataQueue> resultQueue;
4628         auto resultQueueRet =
4629             session->getCaptureResultMetadataQueue(
4630                 [&resultQueue](const auto& descriptor) {
4631                     resultQueue = std::make_shared<ResultMetadataQueue>(
4632                             descriptor);
4633                     if (!resultQueue->isValid() ||
4634                             resultQueue->availableToWrite() <= 0) {
4635                         ALOGE("%s: HAL returns empty result metadata fmq,"
4636                                 " not use it", __func__);
4637                         resultQueue = nullptr;
4638                         // Don't use the queue onwards.
4639                     }
4640                 });
4641         ASSERT_TRUE(resultQueueRet.isOk());
4642 
4643         InFlightRequest inflightReq = {1, false, supportsPartialResults,
4644                                        partialResultCount, resultQueue};
4645         RequestTemplate reqTemplate = RequestTemplate::PREVIEW;
4646         Return<void> ret;
4647         ret = session->constructDefaultRequestSettings(reqTemplate,
4648                                                        [&](auto status, const auto& req) {
4649                                                            ASSERT_EQ(Status::OK, status);
4650                                                            settings = req;
4651                                                        });
4652         ASSERT_TRUE(ret.isOk());
4653 
4654         hidl_handle buffer_handle;
4655         if (useHalBufManager) {
4656             bufferId = 0;
4657         } else {
4658             allocateGraphicBuffer(previewStream.width, previewStream.height,
4659                     android_convertGralloc1To0Usage(halStreamConfig.streams[0].producerUsage,
4660                         halStreamConfig.streams[0].consumerUsage),
4661                     halStreamConfig.streams[0].overrideFormat, &buffer_handle);
4662         }
4663 
4664         StreamBuffer outputBuffer = {halStreamConfig.streams[0].id,
4665                                      bufferId,
4666                                      buffer_handle,
4667                                      BufferStatus::OK,
4668                                      nullptr,
4669                                      nullptr};
4670         ::android::hardware::hidl_vec<StreamBuffer> outputBuffers = {outputBuffer};
4671         const StreamBuffer emptyInputBuffer = {-1, 0, nullptr,
4672                                                BufferStatus::ERROR, nullptr, nullptr};
4673         CaptureRequest request = {frameNumber, 0 /* fmqSettingsSize */, settings,
4674                                   emptyInputBuffer, outputBuffers};
4675 
4676         {
4677             std::unique_lock<std::mutex> l(mLock);
4678             mInflightMap.clear();
4679             mInflightMap.add(frameNumber, &inflightReq);
4680         }
4681 
4682         Status status = Status::INTERNAL_ERROR;
4683         uint32_t numRequestProcessed = 0;
4684         hidl_vec<BufferCache> cachesToRemove;
4685         ret = session->processCaptureRequest(
4686             {request}, cachesToRemove, [&status, &numRequestProcessed](auto s,
4687                     uint32_t n) {
4688                 status = s;
4689                 numRequestProcessed = n;
4690             });
4691 
4692         ASSERT_TRUE(ret.isOk());
4693         ASSERT_EQ(Status::OK, status);
4694         ASSERT_EQ(numRequestProcessed, 1u);
4695         // Flush before waiting for request to complete.
4696         Return<Status> returnStatus = session->flush();
4697         ASSERT_TRUE(returnStatus.isOk());
4698         ASSERT_EQ(Status::OK, returnStatus);
4699 
4700         {
4701             std::unique_lock<std::mutex> l(mLock);
4702             while (!inflightReq.errorCodeValid &&
4703                    ((0 < inflightReq.numBuffersLeft) ||
4704                            (!inflightReq.haveResultMetadata))) {
4705                 auto timeout = std::chrono::system_clock::now() +
4706                                std::chrono::seconds(kStreamBufferTimeoutSec);
4707                 ASSERT_NE(std::cv_status::timeout, mResultCondition.wait_until(l,
4708                         timeout));
4709             }
4710 
4711             if (!inflightReq.errorCodeValid) {
4712                 ASSERT_NE(inflightReq.resultOutputBuffers.size(), 0u);
4713                 ASSERT_EQ(previewStream.id, inflightReq.resultOutputBuffers[0].streamId);
4714             } else {
4715                 switch (inflightReq.errorCode) {
4716                     case ErrorCode::ERROR_REQUEST:
4717                     case ErrorCode::ERROR_RESULT:
4718                     case ErrorCode::ERROR_BUFFER:
4719                         // Expected
4720                         break;
4721                     case ErrorCode::ERROR_DEVICE:
4722                     default:
4723                         FAIL() << "Unexpected error:"
4724                                << static_cast<uint32_t>(inflightReq.errorCode);
4725                 }
4726             }
4727         }
4728 
4729         if (useHalBufManager) {
4730             verifyBuffersReturned(session, deviceVersion, previewStream.id, cb);
4731         }
4732 
4733         ret = session->close();
4734         ASSERT_TRUE(ret.isOk());
4735     }
4736 }
4737 
4738 // Verify that camera flushes correctly without any pending requests.
TEST_F(CameraHidlTest,flushEmpty)4739 TEST_F(CameraHidlTest, flushEmpty) {
4740     hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
4741     std::vector<AvailableStream> outputPreviewStreams;
4742     AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
4743                                         static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
4744 
4745     for (const auto& name : cameraDeviceNames) {
4746         int deviceVersion = getCameraDeviceVersion(name, mProviderType);
4747         if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) {
4748             continue;
4749         } else if (deviceVersion <= 0) {
4750             ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
4751             ADD_FAILURE();
4752             return;
4753         }
4754 
4755         V3_2::Stream previewStream;
4756         HalStreamConfiguration halStreamConfig;
4757         sp<ICameraDeviceSession> session;
4758         sp<DeviceCb> cb;
4759         bool supportsPartialResults = false;
4760         bool useHalBufManager = false;
4761         uint32_t partialResultCount = 0;
4762         configurePreviewStream(name, deviceVersion, mProvider, &previewThreshold, &session /*out*/,
4763                 &previewStream /*out*/, &halStreamConfig /*out*/,
4764                 &supportsPartialResults /*out*/,
4765                 &partialResultCount /*out*/, &useHalBufManager /*out*/, &cb /*out*/);
4766 
4767         Return<Status> returnStatus = session->flush();
4768         ASSERT_TRUE(returnStatus.isOk());
4769         ASSERT_EQ(Status::OK, returnStatus);
4770 
4771         {
4772             std::unique_lock<std::mutex> l(mLock);
4773             auto timeout = std::chrono::system_clock::now() +
4774                            std::chrono::milliseconds(kEmptyFlushTimeoutMSec);
4775             ASSERT_EQ(std::cv_status::timeout, mResultCondition.wait_until(l, timeout));
4776         }
4777 
4778         Return<void> ret = session->close();
4779         ASSERT_TRUE(ret.isOk());
4780     }
4781 }
4782 
4783 // Test camera provider@2.5 notify method
TEST_F(CameraHidlTest,providerDeviceStateNotification)4784 TEST_F(CameraHidlTest, providerDeviceStateNotification) {
4785 
4786     notifyDeviceState(provider::V2_5::DeviceState::BACK_COVERED);
4787     notifyDeviceState(provider::V2_5::DeviceState::NORMAL);
4788 }
4789 
4790 // Retrieve all valid output stream resolutions from the camera
4791 // static characteristics.
getAvailableOutputStreams(camera_metadata_t * staticMeta,std::vector<AvailableStream> & outputStreams,const AvailableStream * threshold)4792 Status CameraHidlTest::getAvailableOutputStreams(camera_metadata_t *staticMeta,
4793         std::vector<AvailableStream> &outputStreams,
4794         const AvailableStream *threshold) {
4795     AvailableStream depthPreviewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
4796                                              static_cast<int32_t>(PixelFormat::Y16)};
4797     if (nullptr == staticMeta) {
4798         return Status::ILLEGAL_ARGUMENT;
4799     }
4800 
4801     camera_metadata_ro_entry scalarEntry;
4802     camera_metadata_ro_entry depthEntry;
4803     int foundScalar = find_camera_metadata_ro_entry(staticMeta,
4804             ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS, &scalarEntry);
4805     int foundDepth = find_camera_metadata_ro_entry(staticMeta,
4806             ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS, &depthEntry);
4807     if ((0 != foundScalar || (0 != (scalarEntry.count % 4))) &&
4808         (0 != foundDepth || (0 != (depthEntry.count % 4)))) {
4809         return Status::ILLEGAL_ARGUMENT;
4810     }
4811 
4812     if(foundScalar == 0 && (0 == (scalarEntry.count % 4))) {
4813         fillOutputStreams(&scalarEntry, outputStreams, threshold,
4814                 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT);
4815     }
4816 
4817     if(foundDepth == 0 && (0 == (depthEntry.count % 4))) {
4818         fillOutputStreams(&depthEntry, outputStreams, &depthPreviewThreshold,
4819                 ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS_OUTPUT);
4820     }
4821 
4822     return Status::OK;
4823 }
4824 
fillOutputStreams(camera_metadata_ro_entry_t * entry,std::vector<AvailableStream> & outputStreams,const AvailableStream * threshold,const int32_t availableConfigOutputTag)4825 void CameraHidlTest::fillOutputStreams(camera_metadata_ro_entry_t* entry,
4826         std::vector<AvailableStream>& outputStreams, const AvailableStream* threshold,
4827         const int32_t availableConfigOutputTag) {
4828     for (size_t i = 0; i < entry->count; i+=4) {
4829         if (availableConfigOutputTag == entry->data.i32[i + 3]) {
4830             if(nullptr == threshold) {
4831                 AvailableStream s = {entry->data.i32[i+1],
4832                         entry->data.i32[i+2], entry->data.i32[i]};
4833                 outputStreams.push_back(s);
4834             } else {
4835                 if ((threshold->format == entry->data.i32[i]) &&
4836                         (threshold->width >= entry->data.i32[i+1]) &&
4837                         (threshold->height >= entry->data.i32[i+2])) {
4838                     AvailableStream s = {entry->data.i32[i+1],
4839                             entry->data.i32[i+2], threshold->format};
4840                     outputStreams.push_back(s);
4841                 }
4842             }
4843         }
4844     }
4845 }
4846 
4847 // Get max jpeg buffer size in android.jpeg.maxSize
getJpegBufferSize(camera_metadata_t * staticMeta,uint32_t * outBufSize)4848 Status CameraHidlTest::getJpegBufferSize(camera_metadata_t *staticMeta, uint32_t* outBufSize) {
4849     if (nullptr == staticMeta || nullptr == outBufSize) {
4850         return Status::ILLEGAL_ARGUMENT;
4851     }
4852 
4853     camera_metadata_ro_entry entry;
4854     int rc = find_camera_metadata_ro_entry(staticMeta,
4855             ANDROID_JPEG_MAX_SIZE, &entry);
4856     if ((0 != rc) || (1 != entry.count)) {
4857         return Status::ILLEGAL_ARGUMENT;
4858     }
4859 
4860     *outBufSize = static_cast<uint32_t>(entry.data.i32[0]);
4861     return Status::OK;
4862 }
4863 
4864 // Check if the camera device has logical multi-camera capability.
isLogicalMultiCamera(const camera_metadata_t * staticMeta)4865 Status CameraHidlTest::isLogicalMultiCamera(const camera_metadata_t *staticMeta) {
4866     Status ret = Status::METHOD_NOT_SUPPORTED;
4867     if (nullptr == staticMeta) {
4868         return Status::ILLEGAL_ARGUMENT;
4869     }
4870 
4871     camera_metadata_ro_entry entry;
4872     int rc = find_camera_metadata_ro_entry(staticMeta,
4873             ANDROID_REQUEST_AVAILABLE_CAPABILITIES, &entry);
4874     if (0 != rc) {
4875         return Status::ILLEGAL_ARGUMENT;
4876     }
4877 
4878     for (size_t i = 0; i < entry.count; i++) {
4879         if (ANDROID_REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA == entry.data.u8[i]) {
4880             ret = Status::OK;
4881             break;
4882         }
4883     }
4884 
4885     return ret;
4886 }
4887 
4888 // Generate a list of physical camera ids backing a logical multi-camera.
getPhysicalCameraIds(const camera_metadata_t * staticMeta,std::unordered_set<std::string> * physicalIds)4889 Status CameraHidlTest::getPhysicalCameraIds(const camera_metadata_t *staticMeta,
4890         std::unordered_set<std::string> *physicalIds) {
4891     if ((nullptr == staticMeta) || (nullptr == physicalIds)) {
4892         return Status::ILLEGAL_ARGUMENT;
4893     }
4894 
4895     camera_metadata_ro_entry entry;
4896     int rc = find_camera_metadata_ro_entry(staticMeta, ANDROID_LOGICAL_MULTI_CAMERA_PHYSICAL_IDS,
4897             &entry);
4898     if (0 != rc) {
4899         return Status::ILLEGAL_ARGUMENT;
4900     }
4901 
4902     const uint8_t* ids = entry.data.u8;
4903     size_t start = 0;
4904     for (size_t i = 0; i < entry.count; i++) {
4905         if (ids[i] == '\0') {
4906             if (start != i) {
4907                 std::string currentId(reinterpret_cast<const char *> (ids + start));
4908                 physicalIds->emplace(currentId);
4909             }
4910             start = i + 1;
4911         }
4912     }
4913 
4914     return Status::OK;
4915 }
4916 
4917 // Generate a set of suported camera key ids.
getSupportedKeys(camera_metadata_t * staticMeta,uint32_t tagId,std::unordered_set<int32_t> * requestIDs)4918 Status CameraHidlTest::getSupportedKeys(camera_metadata_t *staticMeta,
4919         uint32_t tagId, std::unordered_set<int32_t> *requestIDs) {
4920     if ((nullptr == staticMeta) || (nullptr == requestIDs)) {
4921         return Status::ILLEGAL_ARGUMENT;
4922     }
4923 
4924     camera_metadata_ro_entry entry;
4925     int rc = find_camera_metadata_ro_entry(staticMeta, tagId, &entry);
4926     if ((0 != rc) || (entry.count == 0)) {
4927         return Status::OK;
4928     }
4929 
4930     requestIDs->insert(entry.data.i32, entry.data.i32 + entry.count);
4931 
4932     return Status::OK;
4933 }
4934 
constructFilteredSettings(const sp<ICameraDeviceSession> & session,const std::unordered_set<int32_t> & availableKeys,RequestTemplate reqTemplate,android::hardware::camera::common::V1_0::helper::CameraMetadata * defaultSettings,android::hardware::camera::common::V1_0::helper::CameraMetadata * filteredSettings)4935 void CameraHidlTest::constructFilteredSettings(const sp<ICameraDeviceSession>& session,
4936         const std::unordered_set<int32_t>& availableKeys, RequestTemplate reqTemplate,
4937         android::hardware::camera::common::V1_0::helper::CameraMetadata* defaultSettings,
4938         android::hardware::camera::common::V1_0::helper::CameraMetadata* filteredSettings) {
4939     ASSERT_NE(defaultSettings, nullptr);
4940     ASSERT_NE(filteredSettings, nullptr);
4941 
4942     auto ret = session->constructDefaultRequestSettings(reqTemplate,
4943             [&defaultSettings] (auto status, const auto& req) mutable {
4944                 ASSERT_EQ(Status::OK, status);
4945 
4946                 const camera_metadata_t *metadata = reinterpret_cast<const camera_metadata_t*> (
4947                         req.data());
4948                 size_t expectedSize = req.size();
4949                 int result = validate_camera_metadata_structure(metadata, &expectedSize);
4950                 ASSERT_TRUE((result == 0) || (result == CAMERA_METADATA_VALIDATION_SHIFTED));
4951 
4952                 size_t entryCount = get_camera_metadata_entry_count(metadata);
4953                 ASSERT_GT(entryCount, 0u);
4954                 *defaultSettings = metadata;
4955                 });
4956     ASSERT_TRUE(ret.isOk());
4957     const android::hardware::camera::common::V1_0::helper::CameraMetadata &constSettings =
4958         *defaultSettings;
4959     for (const auto& keyIt : availableKeys) {
4960         camera_metadata_ro_entry entry = constSettings.find(keyIt);
4961         if (entry.count > 0) {
4962             filteredSettings->update(entry);
4963         }
4964     }
4965 }
4966 
4967 // Check if constrained mode is supported by using the static
4968 // camera characteristics.
isConstrainedModeAvailable(camera_metadata_t * staticMeta)4969 Status CameraHidlTest::isConstrainedModeAvailable(camera_metadata_t *staticMeta) {
4970     Status ret = Status::METHOD_NOT_SUPPORTED;
4971     if (nullptr == staticMeta) {
4972         return Status::ILLEGAL_ARGUMENT;
4973     }
4974 
4975     camera_metadata_ro_entry entry;
4976     int rc = find_camera_metadata_ro_entry(staticMeta,
4977             ANDROID_REQUEST_AVAILABLE_CAPABILITIES, &entry);
4978     if (0 != rc) {
4979         return Status::ILLEGAL_ARGUMENT;
4980     }
4981 
4982     for (size_t i = 0; i < entry.count; i++) {
4983         if (ANDROID_REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO ==
4984                 entry.data.u8[i]) {
4985             ret = Status::OK;
4986             break;
4987         }
4988     }
4989 
4990     return ret;
4991 }
4992 
4993 // Pick the largest supported HFR mode from the static camera
4994 // characteristics.
pickConstrainedModeSize(camera_metadata_t * staticMeta,AvailableStream & hfrStream)4995 Status CameraHidlTest::pickConstrainedModeSize(camera_metadata_t *staticMeta,
4996         AvailableStream &hfrStream) {
4997     if (nullptr == staticMeta) {
4998         return Status::ILLEGAL_ARGUMENT;
4999     }
5000 
5001     camera_metadata_ro_entry entry;
5002     int rc = find_camera_metadata_ro_entry(staticMeta,
5003             ANDROID_CONTROL_AVAILABLE_HIGH_SPEED_VIDEO_CONFIGURATIONS, &entry);
5004     if (0 != rc) {
5005         return Status::METHOD_NOT_SUPPORTED;
5006     } else if (0 != (entry.count % 5)) {
5007         return Status::ILLEGAL_ARGUMENT;
5008     }
5009 
5010     hfrStream = {0, 0,
5011             static_cast<uint32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
5012     for (size_t i = 0; i < entry.count; i+=5) {
5013         int32_t w = entry.data.i32[i];
5014         int32_t h = entry.data.i32[i+1];
5015         if ((hfrStream.width * hfrStream.height) < (w *h)) {
5016             hfrStream.width = w;
5017             hfrStream.height = h;
5018         }
5019     }
5020 
5021     return Status::OK;
5022 }
5023 
5024 // Check whether ZSL is available using the static camera
5025 // characteristics.
isZSLModeAvailable(const camera_metadata_t * staticMeta)5026 Status CameraHidlTest::isZSLModeAvailable(const camera_metadata_t *staticMeta) {
5027     if (Status::OK == isZSLModeAvailable(staticMeta, PRIV_REPROCESS)) {
5028         return Status::OK;
5029     } else {
5030         return isZSLModeAvailable(staticMeta, YUV_REPROCESS);
5031     }
5032 }
5033 
isZSLModeAvailable(const camera_metadata_t * staticMeta,ReprocessType reprocType)5034 Status CameraHidlTest::isZSLModeAvailable(const camera_metadata_t *staticMeta,
5035         ReprocessType reprocType) {
5036 
5037     Status ret = Status::METHOD_NOT_SUPPORTED;
5038     if (nullptr == staticMeta) {
5039         return Status::ILLEGAL_ARGUMENT;
5040     }
5041 
5042     camera_metadata_ro_entry entry;
5043     int rc = find_camera_metadata_ro_entry(staticMeta,
5044             ANDROID_REQUEST_AVAILABLE_CAPABILITIES, &entry);
5045     if (0 != rc) {
5046         return Status::ILLEGAL_ARGUMENT;
5047     }
5048 
5049     for (size_t i = 0; i < entry.count; i++) {
5050         if ((reprocType == PRIV_REPROCESS &&
5051                 ANDROID_REQUEST_AVAILABLE_CAPABILITIES_PRIVATE_REPROCESSING == entry.data.u8[i]) ||
5052                 (reprocType == YUV_REPROCESS &&
5053                 ANDROID_REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING == entry.data.u8[i])) {
5054             ret = Status::OK;
5055             break;
5056         }
5057     }
5058 
5059     return ret;
5060 }
5061 
5062 // Check whether this is a monochrome camera using the static camera characteristics.
isMonochromeCamera(const camera_metadata_t * staticMeta)5063 Status CameraHidlTest::isMonochromeCamera(const camera_metadata_t *staticMeta) {
5064     Status ret = Status::METHOD_NOT_SUPPORTED;
5065     if (nullptr == staticMeta) {
5066         return Status::ILLEGAL_ARGUMENT;
5067     }
5068 
5069     camera_metadata_ro_entry entry;
5070     int rc = find_camera_metadata_ro_entry(staticMeta,
5071             ANDROID_REQUEST_AVAILABLE_CAPABILITIES, &entry);
5072     if (0 != rc) {
5073         return Status::ILLEGAL_ARGUMENT;
5074     }
5075 
5076     for (size_t i = 0; i < entry.count; i++) {
5077         if (ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MONOCHROME == entry.data.u8[i]) {
5078             ret = Status::OK;
5079             break;
5080         }
5081     }
5082 
5083     return ret;
5084 }
5085 
5086 // Retrieve the reprocess input-output format map from the static
5087 // camera characteristics.
getZSLInputOutputMap(camera_metadata_t * staticMeta,std::vector<AvailableZSLInputOutput> & inputOutputMap)5088 Status CameraHidlTest::getZSLInputOutputMap(camera_metadata_t *staticMeta,
5089         std::vector<AvailableZSLInputOutput> &inputOutputMap) {
5090     if (nullptr == staticMeta) {
5091         return Status::ILLEGAL_ARGUMENT;
5092     }
5093 
5094     camera_metadata_ro_entry entry;
5095     int rc = find_camera_metadata_ro_entry(staticMeta,
5096             ANDROID_SCALER_AVAILABLE_INPUT_OUTPUT_FORMATS_MAP, &entry);
5097     if ((0 != rc) || (0 >= entry.count)) {
5098         return Status::ILLEGAL_ARGUMENT;
5099     }
5100 
5101     const int32_t* contents = &entry.data.i32[0];
5102     for (size_t i = 0; i < entry.count; ) {
5103         int32_t inputFormat = contents[i++];
5104         int32_t length = contents[i++];
5105         for (int32_t j = 0; j < length; j++) {
5106             int32_t outputFormat = contents[i+j];
5107             AvailableZSLInputOutput zslEntry = {inputFormat, outputFormat};
5108             inputOutputMap.push_back(zslEntry);
5109         }
5110         i += length;
5111     }
5112 
5113     return Status::OK;
5114 }
5115 
5116 // Search for the largest stream size for a given format.
findLargestSize(const std::vector<AvailableStream> & streamSizes,int32_t format,AvailableStream & result)5117 Status CameraHidlTest::findLargestSize(
5118         const std::vector<AvailableStream> &streamSizes, int32_t format,
5119         AvailableStream &result) {
5120     result = {0, 0, 0};
5121     for (auto &iter : streamSizes) {
5122         if (format == iter.format) {
5123             if ((result.width * result.height) < (iter.width * iter.height)) {
5124                 result = iter;
5125             }
5126         }
5127     }
5128 
5129     return (result.format == format) ? Status::OK : Status::ILLEGAL_ARGUMENT;
5130 }
5131 
5132 // Check whether the camera device supports specific focus mode.
isAutoFocusModeAvailable(CameraParameters & cameraParams,const char * mode)5133 Status CameraHidlTest::isAutoFocusModeAvailable(
5134         CameraParameters &cameraParams,
5135         const char *mode) {
5136     ::android::String8 focusModes(cameraParams.get(
5137             CameraParameters::KEY_SUPPORTED_FOCUS_MODES));
5138     if (focusModes.contains(mode)) {
5139         return Status::OK;
5140     }
5141 
5142     return Status::METHOD_NOT_SUPPORTED;
5143 }
5144 
createStreamConfiguration(const::android::hardware::hidl_vec<V3_2::Stream> & streams3_2,StreamConfigurationMode configMode,::android::hardware::camera::device::V3_2::StreamConfiguration * config3_2,::android::hardware::camera::device::V3_4::StreamConfiguration * config3_4,::android::hardware::camera::device::V3_5::StreamConfiguration * config3_5,uint32_t jpegBufferSize)5145 void CameraHidlTest::createStreamConfiguration(
5146         const ::android::hardware::hidl_vec<V3_2::Stream>& streams3_2,
5147         StreamConfigurationMode configMode,
5148         ::android::hardware::camera::device::V3_2::StreamConfiguration *config3_2 /*out*/,
5149         ::android::hardware::camera::device::V3_4::StreamConfiguration *config3_4 /*out*/,
5150         ::android::hardware::camera::device::V3_5::StreamConfiguration *config3_5 /*out*/,
5151         uint32_t jpegBufferSize) {
5152     ASSERT_NE(nullptr, config3_2);
5153     ASSERT_NE(nullptr, config3_4);
5154     ASSERT_NE(nullptr, config3_5);
5155 
5156     ::android::hardware::hidl_vec<V3_4::Stream> streams3_4(streams3_2.size());
5157     size_t idx = 0;
5158     for (auto& stream3_2 : streams3_2) {
5159         V3_4::Stream stream;
5160         stream.v3_2 = stream3_2;
5161         stream.bufferSize = 0;
5162         if (stream3_2.format == PixelFormat::BLOB &&
5163                 stream3_2.dataSpace == static_cast<V3_2::DataspaceFlags>(Dataspace::V0_JFIF)) {
5164             stream.bufferSize = jpegBufferSize;
5165         }
5166         streams3_4[idx++] = stream;
5167     }
5168     // Caller is responsible to fill in non-zero config3_5->streamConfigCounter after this returns
5169     *config3_5 = {{streams3_4, configMode, {}}, 0};
5170     *config3_4 = config3_5->v3_4;
5171     *config3_2 = {streams3_2, configMode};
5172 }
5173 
5174 // Configure multiple preview streams using different physical ids.
configurePreviewStreams3_4(const std::string & name,int32_t deviceVersion,sp<ICameraProvider> provider,const AvailableStream * previewThreshold,const std::unordered_set<std::string> & physicalIds,sp<device::V3_4::ICameraDeviceSession> * session3_4,sp<device::V3_5::ICameraDeviceSession> * session3_5,V3_2::Stream * previewStream,device::V3_4::HalStreamConfiguration * halStreamConfig,bool * supportsPartialResults,uint32_t * partialResultCount,bool * useHalBufManager,sp<DeviceCb> * outCb,uint32_t streamConfigCounter,bool allowUnsupport)5175 void CameraHidlTest::configurePreviewStreams3_4(const std::string &name, int32_t deviceVersion,
5176         sp<ICameraProvider> provider,
5177         const AvailableStream *previewThreshold,
5178         const std::unordered_set<std::string>& physicalIds,
5179         sp<device::V3_4::ICameraDeviceSession> *session3_4 /*out*/,
5180         sp<device::V3_5::ICameraDeviceSession> *session3_5 /*out*/,
5181         V3_2::Stream *previewStream /*out*/,
5182         device::V3_4::HalStreamConfiguration *halStreamConfig /*out*/,
5183         bool *supportsPartialResults /*out*/,
5184         uint32_t *partialResultCount /*out*/,
5185         bool *useHalBufManager /*out*/,
5186         sp<DeviceCb> *outCb /*out*/,
5187         uint32_t streamConfigCounter,
5188         bool allowUnsupport) {
5189     ASSERT_NE(nullptr, session3_4);
5190     ASSERT_NE(nullptr, session3_5);
5191     ASSERT_NE(nullptr, halStreamConfig);
5192     ASSERT_NE(nullptr, previewStream);
5193     ASSERT_NE(nullptr, supportsPartialResults);
5194     ASSERT_NE(nullptr, partialResultCount);
5195     ASSERT_NE(nullptr, useHalBufManager);
5196     ASSERT_NE(nullptr, outCb);
5197     ASSERT_FALSE(physicalIds.empty());
5198 
5199     std::vector<AvailableStream> outputPreviewStreams;
5200     ::android::sp<ICameraDevice> device3_x;
5201     ALOGI("configureStreams: Testing camera device %s", name.c_str());
5202     Return<void> ret;
5203     ret = provider->getCameraDeviceInterface_V3_x(
5204         name,
5205         [&](auto status, const auto& device) {
5206             ALOGI("getCameraDeviceInterface_V3_x returns status:%d",
5207                   (int)status);
5208             ASSERT_EQ(Status::OK, status);
5209             ASSERT_NE(device, nullptr);
5210             device3_x = device;
5211         });
5212     ASSERT_TRUE(ret.isOk());
5213 
5214     camera_metadata_t *staticMeta;
5215     ret = device3_x->getCameraCharacteristics([&] (Status s,
5216             CameraMetadata metadata) {
5217         ASSERT_EQ(Status::OK, s);
5218         staticMeta = clone_camera_metadata(
5219                 reinterpret_cast<const camera_metadata_t*>(metadata.data()));
5220         ASSERT_NE(nullptr, staticMeta);
5221     });
5222     ASSERT_TRUE(ret.isOk());
5223 
5224     camera_metadata_ro_entry entry;
5225     auto status = find_camera_metadata_ro_entry(staticMeta,
5226             ANDROID_REQUEST_PARTIAL_RESULT_COUNT, &entry);
5227     if ((0 == status) && (entry.count > 0)) {
5228         *partialResultCount = entry.data.i32[0];
5229         *supportsPartialResults = (*partialResultCount > 1);
5230     }
5231 
5232     sp<DeviceCb> cb = new DeviceCb(this, deviceVersion, staticMeta);
5233     sp<ICameraDeviceSession> session;
5234     ret = device3_x->open(
5235         cb,
5236         [&session](auto status, const auto& newSession) {
5237             ALOGI("device::open returns status:%d", (int)status);
5238             ASSERT_EQ(Status::OK, status);
5239             ASSERT_NE(newSession, nullptr);
5240             session = newSession;
5241         });
5242     ASSERT_TRUE(ret.isOk());
5243     *outCb = cb;
5244 
5245     sp<device::V3_3::ICameraDeviceSession> session3_3;
5246     castSession(session, deviceVersion, &session3_3, session3_4, session3_5);
5247     ASSERT_NE(nullptr, (*session3_4).get());
5248 
5249     *useHalBufManager = false;
5250     status = find_camera_metadata_ro_entry(staticMeta,
5251             ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION, &entry);
5252     if ((0 == status) && (entry.count == 1)) {
5253         *useHalBufManager = (entry.data.u8[0] ==
5254             ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_HIDL_DEVICE_3_5);
5255     }
5256 
5257     outputPreviewStreams.clear();
5258     auto rc = getAvailableOutputStreams(staticMeta,
5259             outputPreviewStreams, previewThreshold);
5260     free_camera_metadata(staticMeta);
5261     ASSERT_EQ(Status::OK, rc);
5262     ASSERT_FALSE(outputPreviewStreams.empty());
5263 
5264     ::android::hardware::hidl_vec<V3_4::Stream> streams3_4(physicalIds.size());
5265     int32_t streamId = 0;
5266     for (auto const& physicalId : physicalIds) {
5267         V3_4::Stream stream3_4 = {{streamId, StreamType::OUTPUT,
5268             static_cast<uint32_t> (outputPreviewStreams[0].width),
5269             static_cast<uint32_t> (outputPreviewStreams[0].height),
5270             static_cast<PixelFormat> (outputPreviewStreams[0].format),
5271             GRALLOC1_CONSUMER_USAGE_HWCOMPOSER, 0, StreamRotation::ROTATION_0},
5272             physicalId.c_str(), /*bufferSize*/ 0};
5273         streams3_4[streamId++] = stream3_4;
5274     }
5275 
5276     ::android::hardware::camera::device::V3_4::StreamConfiguration config3_4;
5277     ::android::hardware::camera::device::V3_5::StreamConfiguration config3_5;
5278     config3_4 = {streams3_4, StreamConfigurationMode::NORMAL_MODE, {}};
5279     RequestTemplate reqTemplate = RequestTemplate::PREVIEW;
5280     ret = (*session3_4)->constructDefaultRequestSettings(reqTemplate,
5281             [&config3_4](auto status, const auto& req) {
5282             ASSERT_EQ(Status::OK, status);
5283             config3_4.sessionParams = req;
5284             });
5285     ASSERT_TRUE(ret.isOk());
5286 
5287     ASSERT_TRUE(!allowUnsupport || deviceVersion == CAMERA_DEVICE_API_VERSION_3_5);
5288     if (allowUnsupport) {
5289         sp<device::V3_5::ICameraDevice> cameraDevice3_5;
5290         castDevice(device3_x, deviceVersion, &cameraDevice3_5);
5291 
5292         bool supported = false;
5293         ret = cameraDevice3_5->isStreamCombinationSupported(config3_4,
5294                 [&supported](Status s, bool combStatus) {
5295                     ASSERT_TRUE((Status::OK == s) ||
5296                             (Status::METHOD_NOT_SUPPORTED == s));
5297                     if (Status::OK == s) {
5298                         supported = combStatus;
5299                     }
5300                 });
5301         ASSERT_TRUE(ret.isOk());
5302         // If stream combination is not supported, return null session.
5303         if (!supported) {
5304             *session3_5 = nullptr;
5305             return;
5306         }
5307     }
5308 
5309     if (*session3_5 != nullptr) {
5310         config3_5.v3_4 = config3_4;
5311         config3_5.streamConfigCounter = streamConfigCounter;
5312         ret = (*session3_5)->configureStreams_3_5(config3_5,
5313                 [&] (Status s, device::V3_4::HalStreamConfiguration halConfig) {
5314                     ASSERT_EQ(Status::OK, s);
5315                     ASSERT_EQ(physicalIds.size(), halConfig.streams.size());
5316                     *halStreamConfig = halConfig;
5317                     if (*useHalBufManager) {
5318                         hidl_vec<V3_2::Stream> streams(physicalIds.size());
5319                         hidl_vec<V3_2::HalStream> halStreams(physicalIds.size());
5320                         for (size_t i = 0; i < physicalIds.size(); i++) {
5321                             streams[i] = streams3_4[i].v3_2;
5322                             halStreams[i] = halConfig.streams[i].v3_3.v3_2;
5323                         }
5324                         cb->setCurrentStreamConfig(streams, halStreams);
5325                     }
5326                 });
5327     } else {
5328         ret = (*session3_4)->configureStreams_3_4(config3_4,
5329                 [&] (Status s, device::V3_4::HalStreamConfiguration halConfig) {
5330                 ASSERT_EQ(Status::OK, s);
5331                 ASSERT_EQ(physicalIds.size(), halConfig.streams.size());
5332                 *halStreamConfig = halConfig;
5333                 });
5334     }
5335     *previewStream = streams3_4[0].v3_2;
5336     ASSERT_TRUE(ret.isOk());
5337 }
5338 
isDepthOnly(camera_metadata_t * staticMeta)5339 bool CameraHidlTest::isDepthOnly(camera_metadata_t* staticMeta) {
5340     camera_metadata_ro_entry scalarEntry;
5341     camera_metadata_ro_entry depthEntry;
5342 
5343     int rc = find_camera_metadata_ro_entry(
5344         staticMeta, ANDROID_REQUEST_AVAILABLE_CAPABILITIES, &scalarEntry);
5345     if (rc == 0) {
5346         for (uint32_t i = 0; i < scalarEntry.count; i++) {
5347             if (scalarEntry.data.u8[i] == ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE) {
5348                 return false;
5349             }
5350         }
5351     }
5352 
5353     for (uint32_t i = 0; i < scalarEntry.count; i++) {
5354         if (scalarEntry.data.u8[i] == ANDROID_REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT) {
5355 
5356             rc = find_camera_metadata_ro_entry(
5357                 staticMeta, ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS, &depthEntry);
5358             size_t i = 0;
5359             if (rc == 0 && depthEntry.data.i32[i] == static_cast<int32_t>(PixelFormat::Y16)) {
5360                 // only Depth16 format is supported now
5361                 return true;
5362             }
5363             break;
5364         }
5365     }
5366 
5367     return false;
5368 }
5369 
5370 // Open a device session and configure a preview stream.
configurePreviewStream(const std::string & name,int32_t deviceVersion,sp<ICameraProvider> provider,const AvailableStream * previewThreshold,sp<ICameraDeviceSession> * session,V3_2::Stream * previewStream,HalStreamConfiguration * halStreamConfig,bool * supportsPartialResults,uint32_t * partialResultCount,bool * useHalBufManager,sp<DeviceCb> * outCb,uint32_t streamConfigCounter)5371 void CameraHidlTest::configurePreviewStream(const std::string &name, int32_t deviceVersion,
5372         sp<ICameraProvider> provider,
5373         const AvailableStream *previewThreshold,
5374         sp<ICameraDeviceSession> *session /*out*/,
5375         V3_2::Stream *previewStream /*out*/,
5376         HalStreamConfiguration *halStreamConfig /*out*/,
5377         bool *supportsPartialResults /*out*/,
5378         uint32_t *partialResultCount /*out*/,
5379         bool *useHalBufManager /*out*/,
5380         sp<DeviceCb> *outCb /*out*/,
5381         uint32_t streamConfigCounter) {
5382     ASSERT_NE(nullptr, session);
5383     ASSERT_NE(nullptr, previewStream);
5384     ASSERT_NE(nullptr, halStreamConfig);
5385     ASSERT_NE(nullptr, supportsPartialResults);
5386     ASSERT_NE(nullptr, partialResultCount);
5387     ASSERT_NE(nullptr, useHalBufManager);
5388     ASSERT_NE(nullptr, outCb);
5389 
5390     std::vector<AvailableStream> outputPreviewStreams;
5391     ::android::sp<ICameraDevice> device3_x;
5392     ALOGI("configureStreams: Testing camera device %s", name.c_str());
5393     Return<void> ret;
5394     ret = provider->getCameraDeviceInterface_V3_x(
5395         name,
5396         [&](auto status, const auto& device) {
5397             ALOGI("getCameraDeviceInterface_V3_x returns status:%d",
5398                   (int)status);
5399             ASSERT_EQ(Status::OK, status);
5400             ASSERT_NE(device, nullptr);
5401             device3_x = device;
5402         });
5403     ASSERT_TRUE(ret.isOk());
5404 
5405     camera_metadata_t *staticMeta;
5406     ret = device3_x->getCameraCharacteristics([&] (Status s,
5407             CameraMetadata metadata) {
5408         ASSERT_EQ(Status::OK, s);
5409         staticMeta = clone_camera_metadata(
5410                 reinterpret_cast<const camera_metadata_t*>(metadata.data()));
5411         ASSERT_NE(nullptr, staticMeta);
5412     });
5413     ASSERT_TRUE(ret.isOk());
5414 
5415     camera_metadata_ro_entry entry;
5416     auto status = find_camera_metadata_ro_entry(staticMeta,
5417             ANDROID_REQUEST_PARTIAL_RESULT_COUNT, &entry);
5418     if ((0 == status) && (entry.count > 0)) {
5419         *partialResultCount = entry.data.i32[0];
5420         *supportsPartialResults = (*partialResultCount > 1);
5421     }
5422 
5423     sp<DeviceCb> cb = new DeviceCb(this, deviceVersion, staticMeta);
5424     ret = device3_x->open(
5425         cb,
5426         [&](auto status, const auto& newSession) {
5427             ALOGI("device::open returns status:%d", (int)status);
5428             ASSERT_EQ(Status::OK, status);
5429             ASSERT_NE(newSession, nullptr);
5430             *session = newSession;
5431         });
5432     ASSERT_TRUE(ret.isOk());
5433     *outCb = cb;
5434 
5435     sp<device::V3_3::ICameraDeviceSession> session3_3;
5436     sp<device::V3_4::ICameraDeviceSession> session3_4;
5437     sp<device::V3_5::ICameraDeviceSession> session3_5;
5438     castSession(*session, deviceVersion, &session3_3, &session3_4, &session3_5);
5439 
5440     *useHalBufManager = false;
5441     status = find_camera_metadata_ro_entry(staticMeta,
5442             ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION, &entry);
5443     if ((0 == status) && (entry.count == 1)) {
5444         *useHalBufManager = (entry.data.u8[0] ==
5445             ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_HIDL_DEVICE_3_5);
5446     }
5447 
5448     outputPreviewStreams.clear();
5449     auto rc = getAvailableOutputStreams(staticMeta,
5450             outputPreviewStreams, previewThreshold);
5451 
5452     uint32_t jpegBufferSize = 0;
5453     ASSERT_EQ(Status::OK, getJpegBufferSize(staticMeta, &jpegBufferSize));
5454     ASSERT_NE(0u, jpegBufferSize);
5455 
5456     free_camera_metadata(staticMeta);
5457     ASSERT_EQ(Status::OK, rc);
5458     ASSERT_FALSE(outputPreviewStreams.empty());
5459 
5460     V3_2::DataspaceFlags dataspaceFlag = 0;
5461     switch (static_cast<PixelFormat>(outputPreviewStreams[0].format)) {
5462         case PixelFormat::Y16:
5463             dataspaceFlag = static_cast<V3_2::DataspaceFlags>(Dataspace::DEPTH);
5464             break;
5465         default:
5466             dataspaceFlag = static_cast<V3_2::DataspaceFlags>(Dataspace::UNKNOWN);
5467     }
5468 
5469     V3_2::Stream stream3_2 = {0, StreamType::OUTPUT,
5470             static_cast<uint32_t> (outputPreviewStreams[0].width),
5471             static_cast<uint32_t> (outputPreviewStreams[0].height),
5472             static_cast<PixelFormat> (outputPreviewStreams[0].format),
5473             GRALLOC1_CONSUMER_USAGE_HWCOMPOSER, dataspaceFlag, StreamRotation::ROTATION_0};
5474     ::android::hardware::hidl_vec<V3_2::Stream> streams3_2 = {stream3_2};
5475     ::android::hardware::camera::device::V3_2::StreamConfiguration config3_2;
5476     ::android::hardware::camera::device::V3_4::StreamConfiguration config3_4;
5477     ::android::hardware::camera::device::V3_5::StreamConfiguration config3_5;
5478     createStreamConfiguration(streams3_2, StreamConfigurationMode::NORMAL_MODE,
5479                               &config3_2, &config3_4, &config3_5, jpegBufferSize);
5480     if (session3_5 != nullptr) {
5481         RequestTemplate reqTemplate = RequestTemplate::PREVIEW;
5482         ret = session3_5->constructDefaultRequestSettings(reqTemplate,
5483                                                        [&config3_5](auto status, const auto& req) {
5484                                                            ASSERT_EQ(Status::OK, status);
5485                                                            config3_5.v3_4.sessionParams = req;
5486                                                        });
5487         ASSERT_TRUE(ret.isOk());
5488         config3_5.streamConfigCounter = streamConfigCounter;
5489         ret = session3_5->configureStreams_3_5(config3_5,
5490                 [&] (Status s, device::V3_4::HalStreamConfiguration halConfig) {
5491                     ASSERT_EQ(Status::OK, s);
5492                     ASSERT_EQ(1u, halConfig.streams.size());
5493                     halStreamConfig->streams.resize(1);
5494                     halStreamConfig->streams[0] = halConfig.streams[0].v3_3.v3_2;
5495                     if (*useHalBufManager) {
5496                         hidl_vec<V3_2::Stream> streams(1);
5497                         hidl_vec<V3_2::HalStream> halStreams(1);
5498                         streams[0] = stream3_2;
5499                         halStreams[0] = halConfig.streams[0].v3_3.v3_2;
5500                         cb->setCurrentStreamConfig(streams, halStreams);
5501                     }
5502                 });
5503     } else if (session3_4 != nullptr) {
5504         RequestTemplate reqTemplate = RequestTemplate::PREVIEW;
5505         ret = session3_4->constructDefaultRequestSettings(reqTemplate,
5506                                                        [&config3_4](auto status, const auto& req) {
5507                                                            ASSERT_EQ(Status::OK, status);
5508                                                            config3_4.sessionParams = req;
5509                                                        });
5510         ASSERT_TRUE(ret.isOk());
5511         ret = session3_4->configureStreams_3_4(config3_4,
5512                 [&] (Status s, device::V3_4::HalStreamConfiguration halConfig) {
5513                     ASSERT_EQ(Status::OK, s);
5514                     ASSERT_EQ(1u, halConfig.streams.size());
5515                     halStreamConfig->streams.resize(halConfig.streams.size());
5516                     for (size_t i = 0; i < halConfig.streams.size(); i++) {
5517                         halStreamConfig->streams[i] = halConfig.streams[i].v3_3.v3_2;
5518                     }
5519                 });
5520     } else if (session3_3 != nullptr) {
5521         ret = session3_3->configureStreams_3_3(config3_2,
5522                 [&] (Status s, device::V3_3::HalStreamConfiguration halConfig) {
5523                     ASSERT_EQ(Status::OK, s);
5524                     ASSERT_EQ(1u, halConfig.streams.size());
5525                     halStreamConfig->streams.resize(halConfig.streams.size());
5526                     for (size_t i = 0; i < halConfig.streams.size(); i++) {
5527                         halStreamConfig->streams[i] = halConfig.streams[i].v3_2;
5528                     }
5529                 });
5530     } else {
5531         ret = (*session)->configureStreams(config3_2,
5532                 [&] (Status s, HalStreamConfiguration halConfig) {
5533                     ASSERT_EQ(Status::OK, s);
5534                     ASSERT_EQ(1u, halConfig.streams.size());
5535                     *halStreamConfig = halConfig;
5536                 });
5537     }
5538     *previewStream = stream3_2;
5539     ASSERT_TRUE(ret.isOk());
5540 }
5541 
castDevice(const sp<device::V3_2::ICameraDevice> & device,int32_t deviceVersion,sp<device::V3_5::ICameraDevice> * device3_5)5542 void CameraHidlTest::castDevice(const sp<device::V3_2::ICameraDevice> &device,
5543         int32_t deviceVersion, sp<device::V3_5::ICameraDevice> *device3_5/*out*/) {
5544     ASSERT_NE(nullptr, device3_5);
5545     if (deviceVersion == CAMERA_DEVICE_API_VERSION_3_5) {
5546         auto castResult = device::V3_5::ICameraDevice::castFrom(device);
5547         ASSERT_TRUE(castResult.isOk());
5548         *device3_5 = castResult;
5549     }
5550 }
5551 
5552 //Cast camera provider to corresponding version if available
castProvider(const sp<ICameraProvider> & provider,sp<provider::V2_5::ICameraProvider> * provider2_5)5553 void CameraHidlTest::castProvider(const sp<ICameraProvider> &provider,
5554         sp<provider::V2_5::ICameraProvider> *provider2_5 /*out*/) {
5555     ASSERT_NE(nullptr, provider2_5);
5556     auto castResult = provider::V2_5::ICameraProvider::castFrom(provider);
5557     if (castResult.isOk()) {
5558         *provider2_5 = castResult;
5559     }
5560 }
5561 
5562 //Cast camera device session to corresponding version
castSession(const sp<ICameraDeviceSession> & session,int32_t deviceVersion,sp<device::V3_3::ICameraDeviceSession> * session3_3,sp<device::V3_4::ICameraDeviceSession> * session3_4,sp<device::V3_5::ICameraDeviceSession> * session3_5)5563 void CameraHidlTest::castSession(const sp<ICameraDeviceSession> &session, int32_t deviceVersion,
5564         sp<device::V3_3::ICameraDeviceSession> *session3_3 /*out*/,
5565         sp<device::V3_4::ICameraDeviceSession> *session3_4 /*out*/,
5566         sp<device::V3_5::ICameraDeviceSession> *session3_5 /*out*/) {
5567     ASSERT_NE(nullptr, session3_3);
5568     ASSERT_NE(nullptr, session3_4);
5569     ASSERT_NE(nullptr, session3_5);
5570 
5571     switch (deviceVersion) {
5572         case CAMERA_DEVICE_API_VERSION_3_5: {
5573             auto castResult = device::V3_5::ICameraDeviceSession::castFrom(session);
5574             ASSERT_TRUE(castResult.isOk());
5575             *session3_5 = castResult;
5576         }
5577         [[fallthrough]];
5578         case CAMERA_DEVICE_API_VERSION_3_4: {
5579             auto castResult = device::V3_4::ICameraDeviceSession::castFrom(session);
5580             ASSERT_TRUE(castResult.isOk());
5581             *session3_4 = castResult;
5582         }
5583         [[fallthrough]];
5584         case CAMERA_DEVICE_API_VERSION_3_3: {
5585             auto castResult = device::V3_3::ICameraDeviceSession::castFrom(session);
5586             ASSERT_TRUE(castResult.isOk());
5587             *session3_3 = castResult;
5588             break;
5589         }
5590         default:
5591             //no-op
5592             return;
5593     }
5594 }
5595 
verifyStreamCombination(sp<device::V3_5::ICameraDevice> cameraDevice3_5,const::android::hardware::camera::device::V3_4::StreamConfiguration & config3_4,bool expectedStatus,bool expectMethodSupported)5596 void CameraHidlTest::verifyStreamCombination(sp<device::V3_5::ICameraDevice> cameraDevice3_5,
5597         const ::android::hardware::camera::device::V3_4::StreamConfiguration &config3_4,
5598         bool expectedStatus, bool expectMethodSupported) {
5599     if (cameraDevice3_5.get() != nullptr) {
5600         auto ret = cameraDevice3_5->isStreamCombinationSupported(config3_4,
5601                 [expectedStatus, expectMethodSupported] (Status s, bool combStatus) {
5602                     ASSERT_TRUE((Status::OK == s) ||
5603                             (!expectMethodSupported && Status::METHOD_NOT_SUPPORTED == s));
5604                     if (Status::OK == s) {
5605                         ASSERT_TRUE(combStatus == expectedStatus);
5606                     }
5607                 });
5608         ASSERT_TRUE(ret.isOk());
5609     }
5610 }
5611 
5612 // Verify logical camera static metadata
verifyLogicalCameraMetadata(const std::string & cameraName,const::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> & device,const CameraMetadata & chars,int deviceVersion,const hidl_vec<hidl_string> & deviceNames)5613 void CameraHidlTest::verifyLogicalCameraMetadata(const std::string& cameraName,
5614         const ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice>& device,
5615         const CameraMetadata &chars, int deviceVersion,
5616         const hidl_vec<hidl_string>& deviceNames) {
5617     const camera_metadata_t* metadata = (camera_metadata_t*)chars.data();
5618     ASSERT_NE(nullptr, metadata);
5619 
5620     Status rc = isLogicalMultiCamera(metadata);
5621     ASSERT_TRUE(Status::OK == rc || Status::METHOD_NOT_SUPPORTED == rc);
5622     if (Status::METHOD_NOT_SUPPORTED == rc) {
5623         return;
5624     }
5625 
5626     std::string version, cameraId;
5627     ASSERT_TRUE(::matchDeviceName(cameraName, mProviderType, &version, &cameraId));
5628     std::unordered_set<std::string> physicalIds;
5629     ASSERT_TRUE(Status::OK == getPhysicalCameraIds(metadata, &physicalIds));
5630     for (auto physicalId : physicalIds) {
5631         ASSERT_NE(physicalId, cameraId);
5632         bool isPublicId = false;
5633         for (auto& deviceName : deviceNames) {
5634             std::string publicVersion, publicId;
5635             ASSERT_TRUE(::matchDeviceName(deviceName, mProviderType, &publicVersion, &publicId));
5636             if (physicalId == publicId) {
5637                 isPublicId = true;
5638                 break;
5639             }
5640         }
5641         if (isPublicId) {
5642             continue;
5643         }
5644 
5645         ASSERT_TRUE(deviceVersion >= CAMERA_DEVICE_API_VERSION_3_5);
5646         auto castResult = device::V3_5::ICameraDevice::castFrom(device);
5647         ASSERT_TRUE(castResult.isOk());
5648         ::android::sp<::android::hardware::camera::device::V3_5::ICameraDevice> device3_5 =
5649                 castResult;
5650         ASSERT_NE(device3_5, nullptr);
5651 
5652         // Check camera characteristics for hidden camera id
5653         Return<void> ret = device3_5->getPhysicalCameraCharacteristics(physicalId,
5654                 [&](auto status, const auto& chars) {
5655             verifyCameraCharacteristics(status, chars);
5656             verifyMonochromeCharacteristics(chars, deviceVersion);
5657         });
5658         ASSERT_TRUE(ret.isOk());
5659 
5660         // Check calling getCameraDeviceInterface_V3_x() on hidden camera id returns
5661         // ILLEGAL_ARGUMENT.
5662         std::stringstream s;
5663         s << "device@" << version << "/" << mProviderType << "/" << physicalId;
5664         hidl_string fullPhysicalId(s.str());
5665         ret = mProvider->getCameraDeviceInterface_V3_x(fullPhysicalId,
5666                 [&](auto status, const auto& device3_x) {
5667             ASSERT_EQ(Status::ILLEGAL_ARGUMENT, status);
5668             ASSERT_EQ(device3_x, nullptr);
5669         });
5670         ASSERT_TRUE(ret.isOk());
5671     }
5672 
5673     // Make sure ANDROID_LOGICAL_MULTI_CAMERA_ACTIVE_PHYSICAL_ID is available in
5674     // result keys.
5675     if (deviceVersion >= CAMERA_DEVICE_API_VERSION_3_5) {
5676         camera_metadata_ro_entry entry;
5677         int retcode = find_camera_metadata_ro_entry(metadata,
5678                 ANDROID_REQUEST_AVAILABLE_RESULT_KEYS, &entry);
5679         if ((0 == retcode) && (entry.count > 0)) {
5680                 ASSERT_NE(std::find(entry.data.i32, entry.data.i32 + entry.count,
5681                     static_cast<int32_t>(
5682                             CameraMetadataTag::ANDROID_LOGICAL_MULTI_CAMERA_ACTIVE_PHYSICAL_ID)),
5683                     entry.data.i32 + entry.count);
5684         } else {
5685             ADD_FAILURE() << "Get camera availableResultKeys failed!";
5686         }
5687     }
5688 }
5689 
verifyCameraCharacteristics(Status status,const CameraMetadata & chars)5690 void CameraHidlTest::verifyCameraCharacteristics(Status status, const CameraMetadata& chars) {
5691     ASSERT_EQ(Status::OK, status);
5692     const camera_metadata_t* metadata = (camera_metadata_t*)chars.data();
5693     size_t expectedSize = chars.size();
5694     int result = validate_camera_metadata_structure(metadata, &expectedSize);
5695     ASSERT_TRUE((result == 0) || (result == CAMERA_METADATA_VALIDATION_SHIFTED));
5696     size_t entryCount = get_camera_metadata_entry_count(metadata);
5697     // TODO: we can do better than 0 here. Need to check how many required
5698     // characteristics keys we've defined.
5699     ASSERT_GT(entryCount, 0u);
5700 
5701     camera_metadata_ro_entry entry;
5702     int retcode = find_camera_metadata_ro_entry(metadata,
5703             ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL, &entry);
5704     if ((0 == retcode) && (entry.count > 0)) {
5705         uint8_t hardwareLevel = entry.data.u8[0];
5706         ASSERT_TRUE(
5707                 hardwareLevel == ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED ||
5708                 hardwareLevel == ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_FULL ||
5709                 hardwareLevel == ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_3 ||
5710                 hardwareLevel == ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_EXTERNAL);
5711     } else {
5712         ADD_FAILURE() << "Get camera hardware level failed!";
5713     }
5714 
5715     entry.count = 0;
5716     retcode = find_camera_metadata_ro_entry(metadata,
5717             ANDROID_REQUEST_CHARACTERISTIC_KEYS_NEEDING_PERMISSION, &entry);
5718     if ((0 == retcode) || (entry.count > 0)) {
5719         ADD_FAILURE() << "ANDROID_REQUEST_CHARACTERISTIC_KEYS_NEEDING_PERMISSION "
5720             << " per API contract should never be set by Hal!";
5721     }
5722     retcode = find_camera_metadata_ro_entry(metadata,
5723             ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS, &entry);
5724     if ((0 == retcode) || (entry.count > 0)) {
5725         ADD_FAILURE() << "ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS"
5726             << " per API contract should never be set by Hal!";
5727     }
5728     retcode = find_camera_metadata_ro_entry(metadata,
5729             ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_MIN_FRAME_DURATIONS, &entry);
5730     if ((0 == retcode) || (entry.count > 0)) {
5731         ADD_FAILURE() << "ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_MIN_FRAME_DURATIONS"
5732             << " per API contract should never be set by Hal!";
5733     }
5734     retcode = find_camera_metadata_ro_entry(metadata,
5735             ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STALL_DURATIONS, &entry);
5736     if ((0 == retcode) || (entry.count > 0)) {
5737         ADD_FAILURE() << "ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STALL_DURATIONS"
5738             << " per API contract should never be set by Hal!";
5739     }
5740 
5741     retcode = find_camera_metadata_ro_entry(metadata,
5742             ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS, &entry);
5743     if (0 == retcode || entry.count > 0) {
5744         ADD_FAILURE() << "ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS "
5745             << " per API contract should never be set by Hal!";
5746     }
5747 
5748     retcode = find_camera_metadata_ro_entry(metadata,
5749             ANDROID_HEIC_AVAILABLE_HEIC_MIN_FRAME_DURATIONS, &entry);
5750     if (0 == retcode || entry.count > 0) {
5751         ADD_FAILURE() << "ANDROID_HEIC_AVAILABLE_HEIC_MIN_FRAME_DURATIONS "
5752             << " per API contract should never be set by Hal!";
5753     }
5754 
5755     retcode = find_camera_metadata_ro_entry(metadata,
5756             ANDROID_HEIC_AVAILABLE_HEIC_STALL_DURATIONS, &entry);
5757     if (0 == retcode || entry.count > 0) {
5758         ADD_FAILURE() << "ANDROID_HEIC_AVAILABLE_HEIC_STALL_DURATIONS "
5759             << " per API contract should never be set by Hal!";
5760     }
5761 
5762     retcode = find_camera_metadata_ro_entry(metadata,
5763             ANDROID_HEIC_INFO_SUPPORTED, &entry);
5764     if (0 == retcode && entry.count > 0) {
5765         retcode = find_camera_metadata_ro_entry(metadata,
5766             ANDROID_HEIC_INFO_MAX_JPEG_APP_SEGMENTS_COUNT, &entry);
5767         if (0 == retcode && entry.count > 0) {
5768             uint8_t maxJpegAppSegmentsCount = entry.data.u8[0];
5769             ASSERT_TRUE(maxJpegAppSegmentsCount >= 1 &&
5770                     maxJpegAppSegmentsCount <= 16);
5771         } else {
5772             ADD_FAILURE() << "Get Heic maxJpegAppSegmentsCount failed!";
5773         }
5774     }
5775 }
5776 
verifyMonochromeCharacteristics(const CameraMetadata & chars,int deviceVersion)5777 void CameraHidlTest::verifyMonochromeCharacteristics(const CameraMetadata& chars,
5778         int deviceVersion) {
5779     const camera_metadata_t* metadata = (camera_metadata_t*)chars.data();
5780     Status rc = isMonochromeCamera(metadata);
5781     if (Status::METHOD_NOT_SUPPORTED == rc) {
5782         return;
5783     }
5784     ASSERT_EQ(Status::OK, rc);
5785 
5786     camera_metadata_ro_entry entry;
5787     // Check capabilities
5788     int retcode = find_camera_metadata_ro_entry(metadata,
5789                 ANDROID_REQUEST_AVAILABLE_CAPABILITIES, &entry);
5790     if ((0 == retcode) && (entry.count > 0)) {
5791         ASSERT_EQ(std::find(entry.data.u8, entry.data.u8 + entry.count,
5792                 ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING),
5793                 entry.data.u8 + entry.count);
5794         if (deviceVersion < CAMERA_DEVICE_API_VERSION_3_5) {
5795             ASSERT_EQ(std::find(entry.data.u8, entry.data.u8 + entry.count,
5796                     ANDROID_REQUEST_AVAILABLE_CAPABILITIES_RAW),
5797                     entry.data.u8 + entry.count);
5798         }
5799     }
5800 
5801     if (deviceVersion >= CAMERA_DEVICE_API_VERSION_3_5) {
5802         // Check Cfa
5803         retcode = find_camera_metadata_ro_entry(metadata,
5804                 ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT, &entry);
5805         if ((0 == retcode) && (entry.count == 1)) {
5806             ASSERT_TRUE(entry.data.i32[0] == static_cast<int32_t>(
5807                     CameraMetadataEnumAndroidSensorInfoColorFilterArrangement::ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_MONO)
5808                     || entry.data.i32[0] == static_cast<int32_t>(
5809                     CameraMetadataEnumAndroidSensorInfoColorFilterArrangement::ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_NIR));
5810         }
5811 
5812         // Check availableRequestKeys
5813         retcode = find_camera_metadata_ro_entry(metadata,
5814                 ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS, &entry);
5815         if ((0 == retcode) && (entry.count > 0)) {
5816             for (size_t i = 0; i < entry.count; i++) {
5817                 ASSERT_NE(entry.data.i32[i], ANDROID_COLOR_CORRECTION_MODE);
5818                 ASSERT_NE(entry.data.i32[i], ANDROID_COLOR_CORRECTION_TRANSFORM);
5819                 ASSERT_NE(entry.data.i32[i], ANDROID_COLOR_CORRECTION_GAINS);
5820             }
5821         } else {
5822             ADD_FAILURE() << "Get camera availableRequestKeys failed!";
5823         }
5824 
5825         // Check availableResultKeys
5826         retcode = find_camera_metadata_ro_entry(metadata,
5827                 ANDROID_REQUEST_AVAILABLE_RESULT_KEYS, &entry);
5828         if ((0 == retcode) && (entry.count > 0)) {
5829             for (size_t i = 0; i < entry.count; i++) {
5830                 ASSERT_NE(entry.data.i32[i], ANDROID_SENSOR_GREEN_SPLIT);
5831                 ASSERT_NE(entry.data.i32[i], ANDROID_SENSOR_NEUTRAL_COLOR_POINT);
5832                 ASSERT_NE(entry.data.i32[i], ANDROID_COLOR_CORRECTION_MODE);
5833                 ASSERT_NE(entry.data.i32[i], ANDROID_COLOR_CORRECTION_TRANSFORM);
5834                 ASSERT_NE(entry.data.i32[i], ANDROID_COLOR_CORRECTION_GAINS);
5835             }
5836         } else {
5837             ADD_FAILURE() << "Get camera availableResultKeys failed!";
5838         }
5839 
5840         // Check availableCharacteristicKeys
5841         retcode = find_camera_metadata_ro_entry(metadata,
5842                 ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS, &entry);
5843         if ((0 == retcode) && (entry.count > 0)) {
5844             for (size_t i = 0; i < entry.count; i++) {
5845                 ASSERT_NE(entry.data.i32[i], ANDROID_SENSOR_REFERENCE_ILLUMINANT1);
5846                 ASSERT_NE(entry.data.i32[i], ANDROID_SENSOR_REFERENCE_ILLUMINANT2);
5847                 ASSERT_NE(entry.data.i32[i], ANDROID_SENSOR_CALIBRATION_TRANSFORM1);
5848                 ASSERT_NE(entry.data.i32[i], ANDROID_SENSOR_CALIBRATION_TRANSFORM2);
5849                 ASSERT_NE(entry.data.i32[i], ANDROID_SENSOR_COLOR_TRANSFORM1);
5850                 ASSERT_NE(entry.data.i32[i], ANDROID_SENSOR_COLOR_TRANSFORM2);
5851                 ASSERT_NE(entry.data.i32[i], ANDROID_SENSOR_FORWARD_MATRIX1);
5852                 ASSERT_NE(entry.data.i32[i], ANDROID_SENSOR_FORWARD_MATRIX2);
5853             }
5854         } else {
5855             ADD_FAILURE() << "Get camera availableResultKeys failed!";
5856         }
5857 
5858         // Check blackLevelPattern
5859         retcode = find_camera_metadata_ro_entry(metadata,
5860                 ANDROID_SENSOR_BLACK_LEVEL_PATTERN, &entry);
5861         if ((0 == retcode) && (entry.count > 0)) {
5862             ASSERT_EQ(entry.count, 4);
5863             for (size_t i = 1; i < entry.count; i++) {
5864                 ASSERT_EQ(entry.data.i32[i], entry.data.i32[0]);
5865             }
5866         }
5867     }
5868 }
5869 
verifyMonochromeCameraResult(const::android::hardware::camera::common::V1_0::helper::CameraMetadata & metadata)5870 void CameraHidlTest::verifyMonochromeCameraResult(
5871         const ::android::hardware::camera::common::V1_0::helper::CameraMetadata& metadata) {
5872     camera_metadata_ro_entry entry;
5873 
5874     // Check tags that are not applicable for monochrome camera
5875     ASSERT_FALSE(metadata.exists(ANDROID_SENSOR_GREEN_SPLIT));
5876     ASSERT_FALSE(metadata.exists(ANDROID_SENSOR_NEUTRAL_COLOR_POINT));
5877     ASSERT_FALSE(metadata.exists(ANDROID_COLOR_CORRECTION_MODE));
5878     ASSERT_FALSE(metadata.exists(ANDROID_COLOR_CORRECTION_TRANSFORM));
5879     ASSERT_FALSE(metadata.exists(ANDROID_COLOR_CORRECTION_GAINS));
5880 
5881     // Check dynamicBlackLevel
5882     entry = metadata.find(ANDROID_SENSOR_DYNAMIC_BLACK_LEVEL);
5883     if (entry.count > 0) {
5884         ASSERT_EQ(entry.count, 4);
5885         for (size_t i = 1; i < entry.count; i++) {
5886             ASSERT_FLOAT_EQ(entry.data.f[i], entry.data.f[0]);
5887         }
5888     }
5889 
5890     // Check noiseProfile
5891     entry = metadata.find(ANDROID_SENSOR_NOISE_PROFILE);
5892     if (entry.count > 0) {
5893         ASSERT_EQ(entry.count, 2);
5894     }
5895 
5896     // Check lensShadingMap
5897     entry = metadata.find(ANDROID_STATISTICS_LENS_SHADING_MAP);
5898     if (entry.count > 0) {
5899         ASSERT_EQ(entry.count % 4, 0);
5900         for (size_t i = 0; i < entry.count/4; i++) {
5901             ASSERT_FLOAT_EQ(entry.data.f[i*4+1], entry.data.f[i*4]);
5902             ASSERT_FLOAT_EQ(entry.data.f[i*4+2], entry.data.f[i*4]);
5903             ASSERT_FLOAT_EQ(entry.data.f[i*4+3], entry.data.f[i*4]);
5904         }
5905     }
5906 
5907     // Check tonemapCurve
5908     camera_metadata_ro_entry curveRed = metadata.find(ANDROID_TONEMAP_CURVE_RED);
5909     camera_metadata_ro_entry curveGreen = metadata.find(ANDROID_TONEMAP_CURVE_GREEN);
5910     camera_metadata_ro_entry curveBlue = metadata.find(ANDROID_TONEMAP_CURVE_BLUE);
5911     if (curveRed.count > 0 && curveGreen.count > 0 && curveBlue.count > 0) {
5912         ASSERT_EQ(curveRed.count, curveGreen.count);
5913         ASSERT_EQ(curveRed.count, curveBlue.count);
5914         for (size_t i = 0; i < curveRed.count; i++) {
5915             ASSERT_FLOAT_EQ(curveGreen.data.f[i], curveRed.data.f[i]);
5916             ASSERT_FLOAT_EQ(curveBlue.data.f[i], curveRed.data.f[i]);
5917         }
5918     }
5919 }
5920 
verifyBuffersReturned(sp<device::V3_2::ICameraDeviceSession> session,int deviceVersion,int32_t streamId,sp<DeviceCb> cb,uint32_t streamConfigCounter)5921 void CameraHidlTest::verifyBuffersReturned(
5922         sp<device::V3_2::ICameraDeviceSession> session,
5923         int deviceVersion, int32_t streamId,
5924         sp<DeviceCb> cb, uint32_t streamConfigCounter) {
5925     sp<device::V3_3::ICameraDeviceSession> session3_3;
5926     sp<device::V3_4::ICameraDeviceSession> session3_4;
5927     sp<device::V3_5::ICameraDeviceSession> session3_5;
5928     castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5);
5929     ASSERT_NE(nullptr, session3_5.get());
5930 
5931     hidl_vec<int32_t> streamIds(1);
5932     streamIds[0] = streamId;
5933     session3_5->signalStreamFlush(streamIds, /*streamConfigCounter*/streamConfigCounter);
5934     cb->waitForBuffersReturned();
5935 }
5936 
verifyBuffersReturned(sp<device::V3_4::ICameraDeviceSession> session3_4,hidl_vec<int32_t> streamIds,sp<DeviceCb> cb,uint32_t streamConfigCounter)5937 void CameraHidlTest::verifyBuffersReturned(
5938         sp<device::V3_4::ICameraDeviceSession> session3_4,
5939         hidl_vec<int32_t> streamIds, sp<DeviceCb> cb, uint32_t streamConfigCounter) {
5940     auto castResult = device::V3_5::ICameraDeviceSession::castFrom(session3_4);
5941     ASSERT_TRUE(castResult.isOk());
5942     sp<device::V3_5::ICameraDeviceSession> session3_5 = castResult;
5943     ASSERT_NE(nullptr, session3_5.get());
5944 
5945     session3_5->signalStreamFlush(streamIds, /*streamConfigCounter*/streamConfigCounter);
5946     cb->waitForBuffersReturned();
5947 }
5948 
verifyLogicalCameraResult(const camera_metadata_t * staticMetadata,const::android::hardware::camera::common::V1_0::helper::CameraMetadata & resultMetadata)5949 void CameraHidlTest::verifyLogicalCameraResult(const camera_metadata_t* staticMetadata,
5950         const ::android::hardware::camera::common::V1_0::helper::CameraMetadata& resultMetadata) {
5951     std::unordered_set<std::string> physicalIds;
5952     Status rc = getPhysicalCameraIds(staticMetadata, &physicalIds);
5953     ASSERT_TRUE(Status::OK == rc);
5954     ASSERT_TRUE(physicalIds.size() > 1);
5955 
5956     camera_metadata_ro_entry entry;
5957     // Check mainPhysicalId
5958     entry = resultMetadata.find(ANDROID_LOGICAL_MULTI_CAMERA_ACTIVE_PHYSICAL_ID);
5959     if (entry.count > 0) {
5960         std::string mainPhysicalId(reinterpret_cast<const char *>(entry.data.u8));
5961         ASSERT_NE(physicalIds.find(mainPhysicalId), physicalIds.end());
5962     } else {
5963         ADD_FAILURE() << "Get LOGICAL_MULTI_CAMERA_ACTIVE_PHYSICAL_ID failed!";
5964     }
5965 }
5966 
5967 // Open a device session with empty callbacks and return static metadata.
openEmptyDeviceSession(const std::string & name,sp<ICameraProvider> provider,sp<ICameraDeviceSession> * session,camera_metadata_t ** staticMeta,::android::sp<ICameraDevice> * cameraDevice)5968 void CameraHidlTest::openEmptyDeviceSession(const std::string &name, sp<ICameraProvider> provider,
5969         sp<ICameraDeviceSession> *session /*out*/, camera_metadata_t **staticMeta /*out*/,
5970         ::android::sp<ICameraDevice> *cameraDevice /*out*/) {
5971     ASSERT_NE(nullptr, session);
5972     ASSERT_NE(nullptr, staticMeta);
5973 
5974     ::android::sp<ICameraDevice> device3_x;
5975     ALOGI("configureStreams: Testing camera device %s", name.c_str());
5976     Return<void> ret;
5977     ret = provider->getCameraDeviceInterface_V3_x(
5978         name,
5979         [&](auto status, const auto& device) {
5980             ALOGI("getCameraDeviceInterface_V3_x returns status:%d",
5981                   (int)status);
5982             ASSERT_EQ(Status::OK, status);
5983             ASSERT_NE(device, nullptr);
5984             device3_x = device;
5985         });
5986     ASSERT_TRUE(ret.isOk());
5987     if (cameraDevice != nullptr) {
5988         *cameraDevice = device3_x;
5989     }
5990 
5991     sp<EmptyDeviceCb> cb = new EmptyDeviceCb();
5992     ret = device3_x->open(cb, [&](auto status, const auto& newSession) {
5993             ALOGI("device::open returns status:%d", (int)status);
5994             ASSERT_EQ(Status::OK, status);
5995             ASSERT_NE(newSession, nullptr);
5996             *session = newSession;
5997         });
5998     ASSERT_TRUE(ret.isOk());
5999 
6000     ret = device3_x->getCameraCharacteristics([&] (Status s,
6001             CameraMetadata metadata) {
6002         ASSERT_EQ(Status::OK, s);
6003         *staticMeta = clone_camera_metadata(
6004                 reinterpret_cast<const camera_metadata_t*>(metadata.data()));
6005         ASSERT_NE(nullptr, *staticMeta);
6006     });
6007     ASSERT_TRUE(ret.isOk());
6008 }
6009 
notifyDeviceState(provider::V2_5::DeviceState newState)6010 void CameraHidlTest::notifyDeviceState(provider::V2_5::DeviceState newState) {
6011     if (mProvider2_5.get() == nullptr) return;
6012 
6013     mProvider2_5->notifyDeviceStateChange(
6014             static_cast<hidl_bitfield<provider::V2_5::DeviceState>>(newState));
6015 }
6016 
6017 // Open a particular camera device.
openCameraDevice(const std::string & name,sp<ICameraProvider> provider,sp<::android::hardware::camera::device::V1_0::ICameraDevice> * device1)6018 void CameraHidlTest::openCameraDevice(const std::string &name,
6019         sp<ICameraProvider> provider,
6020         sp<::android::hardware::camera::device::V1_0::ICameraDevice> *device1 /*out*/) {
6021     ASSERT_TRUE(nullptr != device1);
6022 
6023     Return<void> ret;
6024     ret = provider->getCameraDeviceInterface_V1_x(
6025             name,
6026             [&](auto status, const auto& device) {
6027             ALOGI("getCameraDeviceInterface_V1_x returns status:%d",
6028                   (int)status);
6029             ASSERT_EQ(Status::OK, status);
6030             ASSERT_NE(device, nullptr);
6031             *device1 = device;
6032         });
6033     ASSERT_TRUE(ret.isOk());
6034 
6035     sp<Camera1DeviceCb> deviceCb = new Camera1DeviceCb(this);
6036     Return<Status> returnStatus = (*device1)->open(deviceCb);
6037     ASSERT_TRUE(returnStatus.isOk());
6038     ASSERT_EQ(Status::OK, returnStatus);
6039 }
6040 
6041 // Initialize and configure a preview window.
setupPreviewWindow(const sp<::android::hardware::camera::device::V1_0::ICameraDevice> & device,sp<BufferItemConsumer> * bufferItemConsumer,sp<BufferItemHander> * bufferHandler)6042 void CameraHidlTest::setupPreviewWindow(
6043         const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device,
6044         sp<BufferItemConsumer> *bufferItemConsumer /*out*/,
6045         sp<BufferItemHander> *bufferHandler /*out*/) {
6046     ASSERT_NE(nullptr, device.get());
6047     ASSERT_NE(nullptr, bufferItemConsumer);
6048     ASSERT_NE(nullptr, bufferHandler);
6049 
6050     sp<IGraphicBufferProducer> producer;
6051     sp<IGraphicBufferConsumer> consumer;
6052     BufferQueue::createBufferQueue(&producer, &consumer);
6053     *bufferItemConsumer = new BufferItemConsumer(consumer,
6054             GraphicBuffer::USAGE_HW_TEXTURE); //Use GLConsumer default usage flags
6055     ASSERT_NE(nullptr, (*bufferItemConsumer).get());
6056     *bufferHandler = new BufferItemHander(*bufferItemConsumer);
6057     ASSERT_NE(nullptr, (*bufferHandler).get());
6058     (*bufferItemConsumer)->setFrameAvailableListener(*bufferHandler);
6059     sp<Surface> surface = new Surface(producer);
6060     sp<PreviewWindowCb> previewCb = new PreviewWindowCb(surface);
6061 
6062     auto rc = device->setPreviewWindow(previewCb);
6063     ASSERT_TRUE(rc.isOk());
6064     ASSERT_EQ(Status::OK, rc);
6065 }
6066 
6067 // Stop camera preview and close camera.
stopPreviewAndClose(const sp<::android::hardware::camera::device::V1_0::ICameraDevice> & device)6068 void CameraHidlTest::stopPreviewAndClose(
6069         const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device) {
6070     Return<void> ret = device->stopPreview();
6071     ASSERT_TRUE(ret.isOk());
6072 
6073     ret = device->close();
6074     ASSERT_TRUE(ret.isOk());
6075 }
6076 
6077 // Enable a specific camera message type.
enableMsgType(unsigned int msgType,const sp<::android::hardware::camera::device::V1_0::ICameraDevice> & device)6078 void CameraHidlTest::enableMsgType(unsigned int msgType,
6079         const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device) {
6080     Return<void> ret = device->enableMsgType(msgType);
6081     ASSERT_TRUE(ret.isOk());
6082 
6083     Return<bool> returnBoolStatus = device->msgTypeEnabled(msgType);
6084     ASSERT_TRUE(returnBoolStatus.isOk());
6085     ASSERT_TRUE(returnBoolStatus);
6086 }
6087 
6088 // Disable a specific camera message type.
disableMsgType(unsigned int msgType,const sp<::android::hardware::camera::device::V1_0::ICameraDevice> & device)6089 void CameraHidlTest::disableMsgType(unsigned int msgType,
6090         const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device) {
6091     Return<void> ret = device->disableMsgType(msgType);
6092     ASSERT_TRUE(ret.isOk());
6093 
6094     Return<bool> returnBoolStatus = device->msgTypeEnabled(msgType);
6095     ASSERT_TRUE(returnBoolStatus.isOk());
6096     ASSERT_FALSE(returnBoolStatus);
6097 }
6098 
6099 // Wait until a specific frame notification arrives.
waitForFrameLocked(DataCallbackMsg msgFrame,std::unique_lock<std::mutex> & l)6100 void CameraHidlTest::waitForFrameLocked(DataCallbackMsg msgFrame,
6101         std::unique_lock<std::mutex> &l) {
6102     while (msgFrame != mDataMessageTypeReceived) {
6103         auto timeout = std::chrono::system_clock::now() +
6104                 std::chrono::seconds(kStreamBufferTimeoutSec);
6105         ASSERT_NE(std::cv_status::timeout,
6106                 mResultCondition.wait_until(l, timeout));
6107     }
6108 }
6109 
6110 // Start preview on a particular camera device
startPreview(const sp<::android::hardware::camera::device::V1_0::ICameraDevice> & device)6111 void CameraHidlTest::startPreview(
6112         const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device) {
6113     Return<Status> returnStatus = device->startPreview();
6114     ASSERT_TRUE(returnStatus.isOk());
6115     ASSERT_EQ(Status::OK, returnStatus);
6116 }
6117 
6118 // Retrieve camera parameters.
getParameters(const sp<::android::hardware::camera::device::V1_0::ICameraDevice> & device,CameraParameters * cameraParams)6119 void CameraHidlTest::getParameters(
6120         const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device,
6121         CameraParameters *cameraParams /*out*/) {
6122     ASSERT_NE(nullptr, cameraParams);
6123 
6124     Return<void> ret;
6125     ret = device->getParameters([&] (const ::android::hardware::hidl_string& params) {
6126         ASSERT_FALSE(params.empty());
6127         ::android::String8 paramString(params.c_str());
6128         (*cameraParams).unflatten(paramString);
6129     });
6130     ASSERT_TRUE(ret.isOk());
6131 }
6132 
6133 // Set camera parameters.
setParameters(const sp<::android::hardware::camera::device::V1_0::ICameraDevice> & device,const CameraParameters & cameraParams)6134 void CameraHidlTest::setParameters(
6135         const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device,
6136         const CameraParameters &cameraParams) {
6137     Return<Status> returnStatus = device->setParameters(
6138             cameraParams.flatten().string());
6139     ASSERT_TRUE(returnStatus.isOk());
6140     ASSERT_EQ(Status::OK, returnStatus);
6141 }
6142 
allocateGraphicBuffer(uint32_t width,uint32_t height,uint64_t usage,PixelFormat format,hidl_handle * buffer_handle)6143 void CameraHidlTest::allocateGraphicBuffer(uint32_t width, uint32_t height, uint64_t usage,
6144         PixelFormat format, hidl_handle *buffer_handle /*out*/) {
6145     ASSERT_NE(buffer_handle, nullptr);
6146 
6147     sp<android::hardware::graphics::allocator::V2_0::IAllocator> allocator =
6148         android::hardware::graphics::allocator::V2_0::IAllocator::getService();
6149     sp<android::hardware::graphics::allocator::V3_0::IAllocator> allocatorV3 =
6150         android::hardware::graphics::allocator::V3_0::IAllocator::getService();
6151 
6152     sp<android::hardware::graphics::mapper::V3_0::IMapper> mapperV3 =
6153         android::hardware::graphics::mapper::V3_0::IMapper::getService();
6154     sp<android::hardware::graphics::mapper::V2_0::IMapper> mapper =
6155         android::hardware::graphics::mapper::V2_0::IMapper::getService();
6156     ::android::hardware::hidl_vec<uint32_t> descriptor;
6157     if (mapperV3 != nullptr && allocatorV3 != nullptr) {
6158         android::hardware::graphics::mapper::V3_0::IMapper::BufferDescriptorInfo descriptorInfo {};
6159         descriptorInfo.width = width;
6160         descriptorInfo.height = height;
6161         descriptorInfo.layerCount = 1;
6162         descriptorInfo.format =
6163                 static_cast<android::hardware::graphics::common::V1_2::PixelFormat>(format);
6164         descriptorInfo.usage = usage;
6165 
6166         auto ret = mapperV3->createDescriptor(
6167             descriptorInfo, [&descriptor](android::hardware::graphics::mapper::V3_0::Error err,
6168                                 ::android::hardware::hidl_vec<uint32_t> desc) {
6169                 ASSERT_EQ(err, android::hardware::graphics::mapper::V3_0::Error::NONE);
6170                 descriptor = desc;
6171             });
6172         ASSERT_TRUE(ret.isOk());
6173 
6174         ret = allocatorV3->allocate(descriptor, 1u,
6175             [&](android::hardware::graphics::mapper::V3_0::Error err, uint32_t /*stride*/,
6176                 const ::android::hardware::hidl_vec<::android::hardware::hidl_handle>& buffers) {
6177                 ASSERT_EQ(android::hardware::graphics::mapper::V3_0::Error::NONE, err);
6178                 ASSERT_EQ(buffers.size(), 1u);
6179                 *buffer_handle = buffers[0];
6180             });
6181         ASSERT_TRUE(ret.isOk());
6182     } else {
6183         ASSERT_NE(mapper.get(), nullptr);
6184         ASSERT_NE(allocator.get(), nullptr);
6185         android::hardware::graphics::mapper::V2_0::IMapper::BufferDescriptorInfo descriptorInfo {};
6186         descriptorInfo.width = width;
6187         descriptorInfo.height = height;
6188         descriptorInfo.layerCount = 1;
6189         descriptorInfo.format = format;
6190         descriptorInfo.usage = usage;
6191 
6192         auto ret = mapper->createDescriptor(
6193             descriptorInfo, [&descriptor](android::hardware::graphics::mapper::V2_0::Error err,
6194                                 ::android::hardware::hidl_vec<uint32_t> desc) {
6195                 ASSERT_EQ(err, android::hardware::graphics::mapper::V2_0::Error::NONE);
6196                 descriptor = desc;
6197             });
6198         ASSERT_TRUE(ret.isOk());
6199 
6200         ret = allocator->allocate(descriptor, 1u,
6201             [&](android::hardware::graphics::mapper::V2_0::Error err, uint32_t /*stride*/,
6202                 const ::android::hardware::hidl_vec<::android::hardware::hidl_handle>& buffers) {
6203                 ASSERT_EQ(android::hardware::graphics::mapper::V2_0::Error::NONE, err);
6204                 ASSERT_EQ(buffers.size(), 1u);
6205                 *buffer_handle = buffers[0];
6206             });
6207         ASSERT_TRUE(ret.isOk());
6208     }
6209 }
6210 
verifyRecommendedConfigs(const CameraMetadata & chars)6211 void CameraHidlTest::verifyRecommendedConfigs(const CameraMetadata& chars) {
6212     size_t CONFIG_ENTRY_SIZE = 5;
6213     size_t CONFIG_ENTRY_TYPE_OFFSET = 3;
6214     size_t CONFIG_ENTRY_BITFIELD_OFFSET = 4;
6215     uint32_t maxPublicUsecase =
6216             ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_PUBLIC_END;
6217     uint32_t vendorUsecaseStart =
6218             ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_VENDOR_START;
6219     uint32_t usecaseMask = (1 << vendorUsecaseStart) - 1;
6220     usecaseMask &= ~((1 << maxPublicUsecase) - 1);
6221 
6222     const camera_metadata_t* metadata = reinterpret_cast<const camera_metadata_t*> (chars.data());
6223 
6224     camera_metadata_ro_entry recommendedConfigsEntry, recommendedDepthConfigsEntry, ioMapEntry;
6225     recommendedConfigsEntry.count = recommendedDepthConfigsEntry.count = ioMapEntry.count = 0;
6226     int retCode = find_camera_metadata_ro_entry(metadata,
6227             ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS, &recommendedConfigsEntry);
6228     int depthRetCode = find_camera_metadata_ro_entry(metadata,
6229             ANDROID_DEPTH_AVAILABLE_RECOMMENDED_DEPTH_STREAM_CONFIGURATIONS,
6230             &recommendedDepthConfigsEntry);
6231     int ioRetCode = find_camera_metadata_ro_entry(metadata,
6232             ANDROID_SCALER_AVAILABLE_RECOMMENDED_INPUT_OUTPUT_FORMATS_MAP, &ioMapEntry);
6233     if ((0 != retCode) && (0 != depthRetCode)) {
6234         //In case both regular and depth recommended configurations are absent,
6235         //I/O should be absent as well.
6236         ASSERT_NE(ioRetCode, 0);
6237         return;
6238     }
6239 
6240     camera_metadata_ro_entry availableKeysEntry;
6241     retCode = find_camera_metadata_ro_entry(metadata,
6242             ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS, &availableKeysEntry);
6243     ASSERT_TRUE((0 == retCode) && (availableKeysEntry.count > 0));
6244     std::vector<int32_t> availableKeys;
6245     availableKeys.reserve(availableKeysEntry.count);
6246     availableKeys.insert(availableKeys.end(), availableKeysEntry.data.i32,
6247             availableKeysEntry.data.i32 + availableKeysEntry.count);
6248 
6249     if (recommendedConfigsEntry.count > 0) {
6250         ASSERT_NE(std::find(availableKeys.begin(), availableKeys.end(),
6251                     ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS),
6252                 availableKeys.end());
6253         ASSERT_EQ((recommendedConfigsEntry.count % CONFIG_ENTRY_SIZE), 0);
6254         for (size_t i = 0; i < recommendedConfigsEntry.count; i += CONFIG_ENTRY_SIZE) {
6255             int32_t entryType =
6256                 recommendedConfigsEntry.data.i32[i + CONFIG_ENTRY_TYPE_OFFSET];
6257             uint32_t bitfield =
6258                 recommendedConfigsEntry.data.i32[i + CONFIG_ENTRY_BITFIELD_OFFSET];
6259             ASSERT_TRUE((entryType ==
6260                      ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT) ||
6261                     (entryType ==
6262                      ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_INPUT));
6263             ASSERT_TRUE((bitfield & usecaseMask) == 0);
6264         }
6265     }
6266 
6267     if (recommendedDepthConfigsEntry.count > 0) {
6268         ASSERT_NE(std::find(availableKeys.begin(), availableKeys.end(),
6269                     ANDROID_DEPTH_AVAILABLE_RECOMMENDED_DEPTH_STREAM_CONFIGURATIONS),
6270                 availableKeys.end());
6271         ASSERT_EQ((recommendedDepthConfigsEntry.count % CONFIG_ENTRY_SIZE), 0);
6272         for (size_t i = 0; i < recommendedDepthConfigsEntry.count; i += CONFIG_ENTRY_SIZE) {
6273             int32_t entryType =
6274                 recommendedDepthConfigsEntry.data.i32[i + CONFIG_ENTRY_TYPE_OFFSET];
6275             uint32_t bitfield =
6276                 recommendedDepthConfigsEntry.data.i32[i + CONFIG_ENTRY_BITFIELD_OFFSET];
6277             ASSERT_TRUE((entryType ==
6278                      ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT) ||
6279                     (entryType ==
6280                      ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_INPUT));
6281             ASSERT_TRUE((bitfield & usecaseMask) == 0);
6282         }
6283 
6284         if (recommendedConfigsEntry.count == 0) {
6285             //In case regular recommended configurations are absent but suggested depth
6286             //configurations are present, I/O should be absent.
6287             ASSERT_NE(ioRetCode, 0);
6288         }
6289     }
6290 
6291     if ((ioRetCode == 0) && (ioMapEntry.count > 0)) {
6292         ASSERT_NE(std::find(availableKeys.begin(), availableKeys.end(),
6293                     ANDROID_SCALER_AVAILABLE_RECOMMENDED_INPUT_OUTPUT_FORMATS_MAP),
6294                 availableKeys.end());
6295         ASSERT_EQ(isZSLModeAvailable(metadata), Status::OK);
6296     }
6297 }
6298 
verifySessionReconfigurationQuery(sp<device::V3_5::ICameraDeviceSession> session3_5,camera_metadata * oldSessionParams,camera_metadata * newSessionParams)6299 void CameraHidlTest::verifySessionReconfigurationQuery(
6300         sp<device::V3_5::ICameraDeviceSession> session3_5, camera_metadata* oldSessionParams,
6301         camera_metadata* newSessionParams) {
6302     ASSERT_NE(nullptr, session3_5.get());
6303     ASSERT_NE(nullptr, oldSessionParams);
6304     ASSERT_NE(nullptr, newSessionParams);
6305 
6306     android::hardware::hidl_vec<uint8_t> oldParams, newParams;
6307     oldParams.setToExternal(reinterpret_cast<uint8_t*>(oldSessionParams),
6308             get_camera_metadata_size(oldSessionParams));
6309     newParams.setToExternal(reinterpret_cast<uint8_t*>(newSessionParams),
6310             get_camera_metadata_size(newSessionParams));
6311     android::hardware::camera::common::V1_0::Status callStatus;
6312     auto hidlCb = [&callStatus] (android::hardware::camera::common::V1_0::Status s,
6313             bool /*requiredFlag*/) {
6314         callStatus = s;
6315     };
6316     auto ret = session3_5->isReconfigurationRequired(oldParams, newParams, hidlCb);
6317     ASSERT_TRUE(ret.isOk());
6318     switch (callStatus) {
6319         case android::hardware::camera::common::V1_0::Status::OK:
6320         case android::hardware::camera::common::V1_0::Status::METHOD_NOT_SUPPORTED:
6321             break;
6322         case android::hardware::camera::common::V1_0::Status::INTERNAL_ERROR:
6323         default:
6324             ADD_FAILURE() << "Query calllback failed";
6325     }
6326 }
6327 
main(int argc,char ** argv)6328 int main(int argc, char **argv) {
6329   ::testing::AddGlobalTestEnvironment(CameraHidlEnvironment::Instance());
6330   ::testing::InitGoogleTest(&argc, argv);
6331   CameraHidlEnvironment::Instance()->init(&argc, argv);
6332   int status = RUN_ALL_TESTS();
6333   ALOGI("Test result = %d", status);
6334   return status;
6335 }
6336