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