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