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