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