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