blob: 720a9d4ff5bc67f394b39ae9c860a6cc80c82862 [file] [log] [blame]
Avichal Rakesh362242f2022-02-08 12:40:53 -08001/*
2 * Copyright (C) 2022 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 */
Rucha Katakward08a0152023-10-13 15:47:58 -070016#include <gtest/gtest.h>
Avichal Rakesh362242f2022-02-08 12:40:53 -080017
18#include <aidl/Vintf.h>
19#include <aidl/android/hardware/camera/common/VendorTagSection.h>
20#include <aidl/android/hardware/camera/device/ICameraDevice.h>
21#include <aidlcommonsupport/NativeHandle.h>
22#include <camera_aidl_test.h>
23#include <cutils/properties.h>
24#include <device_cb.h>
25#include <empty_device_cb.h>
26#include <grallocusage/GrallocUsageConversion.h>
27#include <gtest/gtest.h>
28#include <hardware/gralloc.h>
29#include <hardware/gralloc1.h>
30#include <hidl/GtestPrinter.h>
31#include <hidl/HidlSupport.h>
32#include <torch_provider_cb.h>
Rucha Katakward08a0152023-10-13 15:47:58 -070033#include <com_android_internal_camera_flags.h>
Avichal Rakesh362242f2022-02-08 12:40:53 -080034#include <list>
35
36using ::aidl::android::hardware::camera::common::CameraDeviceStatus;
37using ::aidl::android::hardware::camera::common::CameraResourceCost;
38using ::aidl::android::hardware::camera::common::TorchModeStatus;
39using ::aidl::android::hardware::camera::common::VendorTagSection;
40using ::aidl::android::hardware::camera::device::ICameraDevice;
Austin Borger4728fc42022-07-15 11:27:53 -070041using ::aidl::android::hardware::camera::metadata::RequestAvailableColorSpaceProfilesMap;
Avichal Rakeshd3503a32022-02-25 06:23:14 +000042using ::aidl::android::hardware::camera::metadata::RequestAvailableDynamicRangeProfilesMap;
Avichal Rakesh362242f2022-02-08 12:40:53 -080043using ::aidl::android::hardware::camera::metadata::SensorPixelMode;
44using ::aidl::android::hardware::camera::provider::CameraIdAndStreamCombination;
Avichal Rakesh4bf91c72022-05-23 20:44:02 +000045using ::aidl::android::hardware::camera::provider::BnCameraProviderCallback;
Avichal Rakesh362242f2022-02-08 12:40:53 -080046
47using ::ndk::ScopedAStatus;
48
49namespace {
50const int32_t kBurstFrameCount = 10;
51const uint32_t kMaxStillWidth = 2048;
52const uint32_t kMaxStillHeight = 1536;
53
54const int64_t kEmptyFlushTimeoutMSec = 200;
Rucha Katakward08a0152023-10-13 15:47:58 -070055namespace flags = com::android::internal::camera::flags;
Avichal Rakesh362242f2022-02-08 12:40:53 -080056
Shuzhen Wang36efa712022-03-08 10:10:44 -080057const static std::vector<int64_t> kMandatoryUseCases = {
Avichal Rakesh362242f2022-02-08 12:40:53 -080058 ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT,
59 ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_PREVIEW,
60 ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_STILL_CAPTURE,
61 ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VIDEO_RECORD,
62 ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_PREVIEW_VIDEO_STILL,
63 ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VIDEO_CALL};
64} // namespace
65
66TEST_P(CameraAidlTest, getCameraIdList) {
67 std::vector<std::string> idList;
68 ScopedAStatus ret = mProvider->getCameraIdList(&idList);
69 ASSERT_TRUE(ret.isOk());
70
71 for (size_t i = 0; i < idList.size(); i++) {
72 ALOGI("Camera Id[%zu] is %s", i, idList[i].c_str());
73 }
74}
75
76// Test if ICameraProvider::getVendorTags returns Status::OK
77TEST_P(CameraAidlTest, getVendorTags) {
78 std::vector<VendorTagSection> vendorTags;
79 ScopedAStatus ret = mProvider->getVendorTags(&vendorTags);
80
81 ASSERT_TRUE(ret.isOk());
82 for (size_t i = 0; i < vendorTags.size(); i++) {
83 ALOGI("Vendor tag section %zu name %s", i, vendorTags[i].sectionName.c_str());
84 for (auto& tag : vendorTags[i].tags) {
85 ALOGI("Vendor tag id %u name %s type %d", tag.tagId, tag.tagName.c_str(),
86 (int)tag.tagType);
87 }
88 }
89}
90
91// Test if ICameraProvider::setCallback returns Status::OK
92TEST_P(CameraAidlTest, setCallback) {
Avichal Rakesh4bf91c72022-05-23 20:44:02 +000093 struct ProviderCb : public BnCameraProviderCallback {
Avichal Rakesh362242f2022-02-08 12:40:53 -080094 ScopedAStatus cameraDeviceStatusChange(const std::string& cameraDeviceName,
95 CameraDeviceStatus newStatus) override {
96 ALOGI("camera device status callback name %s, status %d", cameraDeviceName.c_str(),
97 (int)newStatus);
98 return ScopedAStatus::ok();
99 }
100 ScopedAStatus torchModeStatusChange(const std::string& cameraDeviceName,
101 TorchModeStatus newStatus) override {
102 ALOGI("Torch mode status callback name %s, status %d", cameraDeviceName.c_str(),
103 (int)newStatus);
104 return ScopedAStatus::ok();
105 }
106 ScopedAStatus physicalCameraDeviceStatusChange(const std::string& cameraDeviceName,
107 const std::string& physicalCameraDeviceName,
108 CameraDeviceStatus newStatus) override {
109 ALOGI("physical camera device status callback name %s, physical camera name %s,"
110 " status %d",
111 cameraDeviceName.c_str(), physicalCameraDeviceName.c_str(), (int)newStatus);
112 return ScopedAStatus::ok();
113 }
114 };
115
Avichal Rakesh4bf91c72022-05-23 20:44:02 +0000116 std::shared_ptr<ProviderCb> cb = ndk::SharedRefBase::make<ProviderCb>();
Avichal Rakesh362242f2022-02-08 12:40:53 -0800117 ScopedAStatus ret = mProvider->setCallback(cb);
118 ASSERT_TRUE(ret.isOk());
119 ret = mProvider->setCallback(nullptr);
Avichal Rakesh4bf91c72022-05-23 20:44:02 +0000120 ASSERT_EQ(static_cast<int32_t>(Status::ILLEGAL_ARGUMENT), ret.getServiceSpecificError());
Avichal Rakesh362242f2022-02-08 12:40:53 -0800121}
122
123// Test if ICameraProvider::getCameraDeviceInterface returns Status::OK and non-null device
124TEST_P(CameraAidlTest, getCameraDeviceInterface) {
125 std::vector<std::string> cameraDeviceNames = getCameraDeviceNames(mProvider);
126
127 for (const auto& name : cameraDeviceNames) {
128 std::shared_ptr<ICameraDevice> cameraDevice;
129 ScopedAStatus ret = mProvider->getCameraDeviceInterface(name, &cameraDevice);
130 ALOGI("getCameraDeviceInterface returns: %d:%d", ret.getExceptionCode(),
131 ret.getServiceSpecificError());
132 ASSERT_TRUE(ret.isOk());
133 ASSERT_NE(cameraDevice, nullptr);
134 }
135}
136
137// Verify that the device resource cost can be retrieved and the values are
138// correct.
139TEST_P(CameraAidlTest, getResourceCost) {
140 std::vector<std::string> cameraDeviceNames = getCameraDeviceNames(mProvider);
141
142 for (const auto& deviceName : cameraDeviceNames) {
143 std::shared_ptr<ICameraDevice> cameraDevice;
144 ScopedAStatus ret = mProvider->getCameraDeviceInterface(deviceName, &cameraDevice);
145 ALOGI("getCameraDeviceInterface returns: %d:%d", ret.getExceptionCode(),
146 ret.getServiceSpecificError());
147 ASSERT_TRUE(ret.isOk());
148 ASSERT_NE(cameraDevice, nullptr);
149
150 CameraResourceCost resourceCost;
151 ret = cameraDevice->getResourceCost(&resourceCost);
152 ALOGI("getResourceCost returns: %d:%d", ret.getExceptionCode(),
153 ret.getServiceSpecificError());
154 ASSERT_TRUE(ret.isOk());
155
156 ALOGI(" Resource cost is %d", resourceCost.resourceCost);
157 ASSERT_LE(resourceCost.resourceCost, 100u);
158
159 for (const auto& name : resourceCost.conflictingDevices) {
160 ALOGI(" Conflicting device: %s", name.c_str());
161 }
162 }
163}
164
Rucha Katakward08a0152023-10-13 15:47:58 -0700165// Validate the integrity of manual flash strength control metadata
166TEST_P(CameraAidlTest, validateManualFlashStrengthControlKeys) {
167 if (flags::camera_manual_flash_strength_control()) {
168 std::vector<std::string> cameraDeviceNames = getCameraDeviceNames(mProvider);
169 for (const auto& name : cameraDeviceNames) {
170 ALOGI("validateManualFlashStrengthControlKeys: Testing camera device %s", name.c_str());
171 CameraMetadata meta;
172 std::shared_ptr<ICameraDevice> cameraDevice;
173 openEmptyDeviceSession(name, mProvider, &mSession /*out*/, &meta /*out*/,
174 &cameraDevice /*out*/);
175 ndk::ScopedAStatus ret = cameraDevice->getCameraCharacteristics(&meta);
176 ASSERT_TRUE(ret.isOk());
177 const camera_metadata_t* staticMeta =
178 reinterpret_cast<const camera_metadata_t*>(meta.metadata.data());
179 verifyManualFlashStrengthControlCharacteristics(staticMeta);
180 }
181 } else {
182 ALOGI("validateManualFlashStrengthControlKeys: Test skipped.\n");
183 GTEST_SKIP();
184 }
185}
186
Avichal Rakesh362242f2022-02-08 12:40:53 -0800187TEST_P(CameraAidlTest, systemCameraTest) {
188 std::vector<std::string> cameraDeviceNames = getCameraDeviceNames(mProvider);
189 std::map<std::string, std::vector<SystemCameraKind>> hiddenPhysicalIdToLogicalMap;
190 for (const auto& name : cameraDeviceNames) {
191 std::shared_ptr<ICameraDevice> device;
Avichal Rakeshfbcf7ea2022-03-09 01:00:34 +0000192 ALOGI("systemCameraTest: Testing camera device %s", name.c_str());
Avichal Rakesh362242f2022-02-08 12:40:53 -0800193 ndk::ScopedAStatus ret = mProvider->getCameraDeviceInterface(name, &device);
194 ASSERT_TRUE(ret.isOk());
195 ASSERT_NE(device, nullptr);
196
197 CameraMetadata cameraCharacteristics;
198 ret = device->getCameraCharacteristics(&cameraCharacteristics);
199 ASSERT_TRUE(ret.isOk());
200
201 const camera_metadata_t* staticMeta =
202 reinterpret_cast<const camera_metadata_t*>(cameraCharacteristics.metadata.data());
203 Status rc = isLogicalMultiCamera(staticMeta);
204 if (rc == Status::OPERATION_NOT_SUPPORTED) {
205 return;
206 }
207
208 ASSERT_EQ(rc, Status::OK);
209 std::unordered_set<std::string> physicalIds;
210 ASSERT_EQ(getPhysicalCameraIds(staticMeta, &physicalIds), Status::OK);
211 SystemCameraKind systemCameraKind = SystemCameraKind::PUBLIC;
212 Status retStatus = getSystemCameraKind(staticMeta, &systemCameraKind);
213 ASSERT_EQ(retStatus, Status::OK);
214
215 for (auto physicalId : physicalIds) {
216 bool isPublicId = false;
217 for (auto& deviceName : cameraDeviceNames) {
218 std::string publicVersion, publicId;
219 ASSERT_TRUE(matchDeviceName(deviceName, mProviderType, &publicVersion, &publicId));
220 if (physicalId == publicId) {
221 isPublicId = true;
222 break;
223 }
224 }
Avichal Rakeshfbcf7ea2022-03-09 01:00:34 +0000225
Avichal Rakesh362242f2022-02-08 12:40:53 -0800226 // For hidden physical cameras, collect their associated logical cameras
227 // and store the system camera kind.
228 if (!isPublicId) {
229 auto it = hiddenPhysicalIdToLogicalMap.find(physicalId);
230 if (it == hiddenPhysicalIdToLogicalMap.end()) {
231 hiddenPhysicalIdToLogicalMap.insert(std::make_pair(
Avichal Rakeshfbcf7ea2022-03-09 01:00:34 +0000232 physicalId, std::vector<SystemCameraKind>({systemCameraKind})));
Avichal Rakesh362242f2022-02-08 12:40:53 -0800233 } else {
234 it->second.push_back(systemCameraKind);
235 }
236 }
237 }
238 }
239
240 // Check that the system camera kind of the logical cameras associated with
241 // each hidden physical camera is the same.
242 for (const auto& it : hiddenPhysicalIdToLogicalMap) {
243 SystemCameraKind neededSystemCameraKind = it.second.front();
244 for (auto foundSystemCamera : it.second) {
245 ASSERT_EQ(neededSystemCameraKind, foundSystemCamera);
246 }
247 }
248}
249
250// Verify that the static camera characteristics can be retrieved
251// successfully.
252TEST_P(CameraAidlTest, getCameraCharacteristics) {
253 std::vector<std::string> cameraDeviceNames = getCameraDeviceNames(mProvider);
254
255 for (const auto& name : cameraDeviceNames) {
256 std::shared_ptr<ICameraDevice> device;
257 ALOGI("getCameraCharacteristics: Testing camera device %s", name.c_str());
258 ndk::ScopedAStatus ret = mProvider->getCameraDeviceInterface(name, &device);
259 ALOGI("getCameraDeviceInterface returns: %d:%d", ret.getExceptionCode(),
260 ret.getServiceSpecificError());
261 ASSERT_TRUE(ret.isOk());
262 ASSERT_NE(device, nullptr);
263
264 CameraMetadata chars;
265 ret = device->getCameraCharacteristics(&chars);
266 ASSERT_TRUE(ret.isOk());
267 verifyCameraCharacteristics(chars);
268 verifyMonochromeCharacteristics(chars);
269 verifyRecommendedConfigs(chars);
Kwangkyu Park4b7fd452023-05-12 00:22:22 +0900270 verifyHighSpeedRecordingCharacteristics(name, chars);
Avichal Rakesh362242f2022-02-08 12:40:53 -0800271 verifyLogicalOrUltraHighResCameraMetadata(name, device, chars, cameraDeviceNames);
272
273 ASSERT_TRUE(ret.isOk());
274
275 // getPhysicalCameraCharacteristics will fail for publicly
276 // advertised camera IDs.
277 std::string version, cameraId;
278 ASSERT_TRUE(matchDeviceName(name, mProviderType, &version, &cameraId));
279 CameraMetadata devChars;
280 ret = device->getPhysicalCameraCharacteristics(cameraId, &devChars);
281 ASSERT_EQ(static_cast<int32_t>(Status::ILLEGAL_ARGUMENT), ret.getServiceSpecificError());
282 ASSERT_EQ(0, devChars.metadata.size());
283 }
284}
285
286// Verify that the torch strength level can be set and retrieved successfully.
287TEST_P(CameraAidlTest, turnOnTorchWithStrengthLevel) {
288 std::vector<std::string> cameraDeviceNames = getCameraDeviceNames(mProvider);
289
290 std::shared_ptr<TorchProviderCb> cb = ndk::SharedRefBase::make<TorchProviderCb>(this);
291 ndk::ScopedAStatus ret = mProvider->setCallback(cb);
292 ASSERT_TRUE(ret.isOk());
293
294 for (const auto& name : cameraDeviceNames) {
295 int32_t defaultLevel;
296 std::shared_ptr<ICameraDevice> device;
297 ALOGI("%s: Testing camera device %s", __FUNCTION__, name.c_str());
298
299 ret = mProvider->getCameraDeviceInterface(name, &device);
300 ASSERT_TRUE(ret.isOk());
301 ASSERT_NE(device, nullptr);
302
303 CameraMetadata chars;
304 ret = device->getCameraCharacteristics(&chars);
305 ASSERT_TRUE(ret.isOk());
306
307 const camera_metadata_t* staticMeta =
308 reinterpret_cast<const camera_metadata_t*>(chars.metadata.data());
309 bool torchStrengthControlSupported = isTorchStrengthControlSupported(staticMeta);
310 camera_metadata_ro_entry entry;
311 int rc = find_camera_metadata_ro_entry(staticMeta,
312 ANDROID_FLASH_INFO_STRENGTH_DEFAULT_LEVEL, &entry);
313 if (torchStrengthControlSupported) {
314 ASSERT_EQ(rc, 0);
315 ASSERT_GT(entry.count, 0);
316 defaultLevel = *entry.data.i32;
317 ALOGI("Default level is:%d", defaultLevel);
318 }
319
320 mTorchStatus = TorchModeStatus::NOT_AVAILABLE;
321 ret = device->turnOnTorchWithStrengthLevel(2);
322 ALOGI("turnOnTorchWithStrengthLevel returns status: %d", ret.getServiceSpecificError());
323 // OPERATION_NOT_SUPPORTED check
324 if (!torchStrengthControlSupported) {
325 ALOGI("Torch strength control not supported.");
326 ASSERT_EQ(static_cast<int32_t>(Status::OPERATION_NOT_SUPPORTED),
327 ret.getServiceSpecificError());
328 } else {
329 {
330 ASSERT_TRUE(ret.isOk());
331 std::unique_lock<std::mutex> l(mTorchLock);
332 while (TorchModeStatus::NOT_AVAILABLE == mTorchStatus) {
333 auto timeout = std::chrono::system_clock::now() +
334 std::chrono::seconds(kTorchTimeoutSec);
335 ASSERT_NE(std::cv_status::timeout, mTorchCond.wait_until(l, timeout));
336 }
337 ASSERT_EQ(TorchModeStatus::AVAILABLE_ON, mTorchStatus);
338 mTorchStatus = TorchModeStatus::NOT_AVAILABLE;
339 }
340 ALOGI("getTorchStrengthLevel: Testing");
341 int32_t strengthLevel;
342 ret = device->getTorchStrengthLevel(&strengthLevel);
343 ASSERT_TRUE(ret.isOk());
344 ALOGI("Torch strength level is : %d", strengthLevel);
345 ASSERT_EQ(strengthLevel, 2);
346
347 // Turn OFF the torch and verify torch strength level is reset to default level.
348 ALOGI("Testing torch strength level reset after turning the torch OFF.");
349 ret = device->setTorchMode(false);
350 ASSERT_TRUE(ret.isOk());
351 {
352 std::unique_lock<std::mutex> l(mTorchLock);
353 while (TorchModeStatus::NOT_AVAILABLE == mTorchStatus) {
354 auto timeout = std::chrono::system_clock::now() +
355 std::chrono::seconds(kTorchTimeoutSec);
356 ASSERT_NE(std::cv_status::timeout, mTorchCond.wait_until(l, timeout));
357 }
358 ASSERT_EQ(TorchModeStatus::AVAILABLE_OFF, mTorchStatus);
359 }
360
361 ret = device->getTorchStrengthLevel(&strengthLevel);
362 ASSERT_TRUE(ret.isOk());
363 ALOGI("Torch strength level after turning OFF torch is : %d", strengthLevel);
364 ASSERT_EQ(strengthLevel, defaultLevel);
365 }
366 }
367}
368
369// In case it is supported verify that torch can be enabled.
370// Check for corresponding torch callbacks as well.
371TEST_P(CameraAidlTest, setTorchMode) {
372 std::vector<std::string> cameraDeviceNames = getCameraDeviceNames(mProvider);
373
374 std::shared_ptr<TorchProviderCb> cb = ndk::SharedRefBase::make<TorchProviderCb>(this);
375 ndk::ScopedAStatus ret = mProvider->setCallback(cb);
376 ALOGI("setCallback returns status: %d", ret.getServiceSpecificError());
377 ASSERT_TRUE(ret.isOk());
378 ASSERT_NE(cb, nullptr);
379
380 for (const auto& name : cameraDeviceNames) {
381 std::shared_ptr<ICameraDevice> device;
382 ALOGI("setTorchMode: Testing camera device %s", name.c_str());
383 ret = mProvider->getCameraDeviceInterface(name, &device);
384 ALOGI("getCameraDeviceInterface returns status:%d:%d", ret.getExceptionCode(),
385 ret.getServiceSpecificError());
386 ASSERT_TRUE(ret.isOk());
387 ASSERT_NE(device, nullptr);
388
389 CameraMetadata metadata;
390 ret = device->getCameraCharacteristics(&metadata);
391 ALOGI("getCameraCharacteristics returns status:%d", ret.getServiceSpecificError());
392 ASSERT_TRUE(ret.isOk());
393 camera_metadata_t* staticMeta =
394 reinterpret_cast<camera_metadata_t*>(metadata.metadata.data());
395 bool torchSupported = isTorchSupported(staticMeta);
396
397 mTorchStatus = TorchModeStatus::NOT_AVAILABLE;
398 ret = device->setTorchMode(true);
399 ALOGI("setTorchMode returns status: %d", ret.getServiceSpecificError());
400 if (!torchSupported) {
401 ASSERT_EQ(static_cast<int32_t>(Status::OPERATION_NOT_SUPPORTED),
402 ret.getServiceSpecificError());
403 } else {
404 ASSERT_TRUE(ret.isOk());
405 {
406 std::unique_lock<std::mutex> l(mTorchLock);
407 while (TorchModeStatus::NOT_AVAILABLE == mTorchStatus) {
408 auto timeout = std::chrono::system_clock::now() +
409 std::chrono::seconds(kTorchTimeoutSec);
410 ASSERT_NE(std::cv_status::timeout, mTorchCond.wait_until(l, timeout));
411 }
412 ASSERT_EQ(TorchModeStatus::AVAILABLE_ON, mTorchStatus);
413 mTorchStatus = TorchModeStatus::NOT_AVAILABLE;
414 }
415
416 ret = device->setTorchMode(false);
417 ASSERT_TRUE(ret.isOk());
418 {
419 std::unique_lock<std::mutex> l(mTorchLock);
420 while (TorchModeStatus::NOT_AVAILABLE == mTorchStatus) {
421 auto timeout = std::chrono::system_clock::now() +
422 std::chrono::seconds(kTorchTimeoutSec);
423 ASSERT_NE(std::cv_status::timeout, mTorchCond.wait_until(l, timeout));
424 }
425 ASSERT_EQ(TorchModeStatus::AVAILABLE_OFF, mTorchStatus);
426 }
427 }
428 }
Avichal Rakesh362242f2022-02-08 12:40:53 -0800429}
430
431// Check dump functionality.
432TEST_P(CameraAidlTest, dump) {
433 std::vector<std::string> cameraDeviceNames = getCameraDeviceNames(mProvider);
434
435 for (const auto& name : cameraDeviceNames) {
436 std::shared_ptr<ICameraDevice> device;
437 ALOGI("dump: Testing camera device %s", name.c_str());
438
439 ndk::ScopedAStatus ret = mProvider->getCameraDeviceInterface(name, &device);
440 ALOGI("getCameraDeviceInterface returns status:%d:%d", ret.getExceptionCode(),
441 ret.getServiceSpecificError());
442 ASSERT_TRUE(ret.isOk());
443 ASSERT_NE(device, nullptr);
444
445 int raw_handle = open(kDumpOutput, O_RDWR);
446 ASSERT_GE(raw_handle, 0);
447
448 auto retStatus = device->dump(raw_handle, nullptr, 0);
449 ASSERT_EQ(retStatus, ::android::OK);
450 close(raw_handle);
451 }
452}
453
454// Open, dump, then close
455TEST_P(CameraAidlTest, openClose) {
456 std::vector<std::string> cameraDeviceNames = getCameraDeviceNames(mProvider);
457
458 for (const auto& name : cameraDeviceNames) {
459 std::shared_ptr<ICameraDevice> device;
460 ALOGI("openClose: Testing camera device %s", name.c_str());
461 ndk::ScopedAStatus ret = mProvider->getCameraDeviceInterface(name, &device);
462 ALOGI("getCameraDeviceInterface returns status:%d:%d", ret.getExceptionCode(),
463 ret.getServiceSpecificError());
464 ASSERT_TRUE(ret.isOk());
465 ASSERT_NE(device, nullptr);
466
467 std::shared_ptr<EmptyDeviceCb> cb = ndk::SharedRefBase::make<EmptyDeviceCb>();
468
469 ret = device->open(cb, &mSession);
470 ASSERT_TRUE(ret.isOk());
471 ALOGI("device::open returns status:%d:%d", ret.getExceptionCode(),
472 ret.getServiceSpecificError());
473 ASSERT_NE(mSession, nullptr);
474 int raw_handle = open(kDumpOutput, O_RDWR);
475 ASSERT_GE(raw_handle, 0);
476
477 auto retStatus = device->dump(raw_handle, nullptr, 0);
478 ASSERT_EQ(retStatus, ::android::OK);
479 close(raw_handle);
480
481 ret = mSession->close();
482 mSession = nullptr;
483 ASSERT_TRUE(ret.isOk());
484 // TODO: test all session API calls return INTERNAL_ERROR after close
485 // TODO: keep a wp copy here and verify session cannot be promoted out of this scope
486 }
487}
488
489// Check whether all common default request settings can be successfully
490// constructed.
491TEST_P(CameraAidlTest, constructDefaultRequestSettings) {
492 std::vector<std::string> cameraDeviceNames = getCameraDeviceNames(mProvider);
493
494 for (const auto& name : cameraDeviceNames) {
495 std::shared_ptr<ICameraDevice> device;
496 ALOGI("constructDefaultRequestSettings: Testing camera device %s", name.c_str());
497 ndk::ScopedAStatus ret = mProvider->getCameraDeviceInterface(name, &device);
498 ALOGI("getCameraDeviceInterface returns status:%d:%d", ret.getExceptionCode(),
499 ret.getServiceSpecificError());
500 ASSERT_TRUE(ret.isOk());
501 ASSERT_NE(device, nullptr);
502
Shuzhen Wangdf89cb92023-11-09 18:24:42 -0800503 int32_t interfaceVersion;
504 ret = device->getInterfaceVersion(&interfaceVersion);
505 ASSERT_TRUE(ret.isOk());
506 bool supportFeatureCombinationQuery =
507 (interfaceVersion >= CAMERA_DEVICE_API_MINOR_VERSION_3);
508
Avichal Rakesh362242f2022-02-08 12:40:53 -0800509 std::shared_ptr<EmptyDeviceCb> cb = ndk::SharedRefBase::make<EmptyDeviceCb>();
510 ret = device->open(cb, &mSession);
511 ALOGI("device::open returns status:%d:%d", ret.getExceptionCode(),
512 ret.getServiceSpecificError());
513 ASSERT_TRUE(ret.isOk());
514 ASSERT_NE(mSession, nullptr);
515
516 for (int32_t t = (int32_t)RequestTemplate::PREVIEW; t <= (int32_t)RequestTemplate::MANUAL;
517 t++) {
518 RequestTemplate reqTemplate = (RequestTemplate)t;
519 CameraMetadata rawMetadata;
520 ret = mSession->constructDefaultRequestSettings(reqTemplate, &rawMetadata);
521 ALOGI("constructDefaultRequestSettings returns status:%d:%d", ret.getExceptionCode(),
522 ret.getServiceSpecificError());
Avichal Rakeshd3503a32022-02-25 06:23:14 +0000523
Avichal Rakesh362242f2022-02-08 12:40:53 -0800524 if (reqTemplate == RequestTemplate::ZERO_SHUTTER_LAG ||
525 reqTemplate == RequestTemplate::MANUAL) {
526 // optional templates
527 ASSERT_TRUE(ret.isOk() || static_cast<int32_t>(Status::ILLEGAL_ARGUMENT) ==
528 ret.getServiceSpecificError());
529 } else {
530 ASSERT_TRUE(ret.isOk());
531 }
532
533 if (ret.isOk()) {
534 const camera_metadata_t* metadata = (camera_metadata_t*)rawMetadata.metadata.data();
535 size_t expectedSize = rawMetadata.metadata.size();
536 int result = validate_camera_metadata_structure(metadata, &expectedSize);
537 ASSERT_TRUE((result == 0) || (result == CAMERA_METADATA_VALIDATION_SHIFTED));
538 verifyRequestTemplate(metadata, reqTemplate);
539 } else {
540 ASSERT_EQ(0u, rawMetadata.metadata.size());
541 }
Shuzhen Wangdf89cb92023-11-09 18:24:42 -0800542
543 if (flags::feature_combination_query()) {
544 if (supportFeatureCombinationQuery) {
545 CameraMetadata rawMetadata2;
546 ndk::ScopedAStatus ret2 =
547 device->constructDefaultRequestSettings(reqTemplate, &rawMetadata2);
548
549 // TODO: Do not allow OPERATION_NOT_SUPPORTED once HAL
550 // implementation is in place.
551 if (static_cast<Status>(ret2.getServiceSpecificError()) !=
552 Status::OPERATION_NOT_SUPPORTED) {
553 ASSERT_EQ(ret.isOk(), ret2.isOk());
554 ASSERT_EQ(ret.getStatus(), ret2.getStatus());
555
556 ASSERT_EQ(rawMetadata.metadata.size(), rawMetadata2.metadata.size());
557 if (ret2.isOk()) {
558 const camera_metadata_t* metadata =
559 (camera_metadata_t*)rawMetadata2.metadata.data();
560 size_t expectedSize = rawMetadata2.metadata.size();
561 int result =
562 validate_camera_metadata_structure(metadata, &expectedSize);
563 ASSERT_TRUE((result == 0) ||
564 (result == CAMERA_METADATA_VALIDATION_SHIFTED));
565 verifyRequestTemplate(metadata, reqTemplate);
566 }
567 }
568 }
569 }
Avichal Rakesh362242f2022-02-08 12:40:53 -0800570 }
571 ret = mSession->close();
572 mSession = nullptr;
573 ASSERT_TRUE(ret.isOk());
574 }
575}
576
577// Verify that all supported stream formats and sizes can be configured
578// successfully.
579TEST_P(CameraAidlTest, configureStreamsAvailableOutputs) {
580 std::vector<std::string> cameraDeviceNames = getCameraDeviceNames(mProvider);
581 std::vector<AvailableStream> outputStreams;
582
583 for (const auto& name : cameraDeviceNames) {
584 CameraMetadata meta;
585 std::shared_ptr<ICameraDevice> device;
586
587 openEmptyDeviceSession(name, mProvider, &mSession /*out*/, &meta /*out*/, &device /*out*/);
588
589 camera_metadata_t* staticMeta = reinterpret_cast<camera_metadata_t*>(meta.metadata.data());
590 outputStreams.clear();
591 ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta, outputStreams));
592 ASSERT_NE(0u, outputStreams.size());
593
594 int32_t jpegBufferSize = 0;
595 ASSERT_EQ(Status::OK, getJpegBufferSize(staticMeta, &jpegBufferSize));
596 ASSERT_NE(0u, jpegBufferSize);
597
598 int32_t streamId = 0;
599 int32_t streamConfigCounter = 0;
600 for (auto& it : outputStreams) {
601 Stream stream;
602 Dataspace dataspace = getDataspace(static_cast<PixelFormat>(it.format));
603 stream.id = streamId;
604 stream.streamType = StreamType::OUTPUT;
605 stream.width = it.width;
606 stream.height = it.height;
607 stream.format = static_cast<PixelFormat>(it.format);
608 stream.dataSpace = dataspace;
609 stream.usage = static_cast<aidl::android::hardware::graphics::common::BufferUsage>(
610 GRALLOC1_CONSUMER_USAGE_HWCOMPOSER);
611 stream.rotation = StreamRotation::ROTATION_0;
Avichal Rakeshd3503a32022-02-25 06:23:14 +0000612 stream.dynamicRangeProfile = RequestAvailableDynamicRangeProfilesMap::
613 ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD;
Austin Borger263e3622023-06-15 11:32:04 -0700614 stream.useCase = ScalerAvailableStreamUseCases::
615 ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT;
616 stream.colorSpace = static_cast<int>(
617 RequestAvailableColorSpaceProfilesMap::
618 ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_UNSPECIFIED);
Avichal Rakesh362242f2022-02-08 12:40:53 -0800619
620 std::vector<Stream> streams = {stream};
621 StreamConfiguration config;
622 createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE, &config,
623 jpegBufferSize);
624
Shuzhen Wangdf89cb92023-11-09 18:24:42 -0800625 verifyStreamCombination(device, config, /*expectedStatus*/ true);
Avichal Rakesh362242f2022-02-08 12:40:53 -0800626
627 config.streamConfigCounter = streamConfigCounter++;
628 std::vector<HalStream> halConfigs;
629 ndk::ScopedAStatus ret = mSession->configureStreams(config, &halConfigs);
630 ASSERT_TRUE(ret.isOk());
631 ASSERT_EQ(halConfigs.size(), 1);
632 ASSERT_EQ(halConfigs[0].id, streamId);
633
634 streamId++;
635 }
636
637 ndk::ScopedAStatus ret = mSession->close();
638 mSession = nullptr;
639 ASSERT_TRUE(ret.isOk());
640 }
641}
642
643// Verify that mandatory concurrent streams and outputs are supported.
644TEST_P(CameraAidlTest, configureConcurrentStreamsAvailableOutputs) {
645 struct CameraTestInfo {
646 CameraMetadata staticMeta;
647 std::shared_ptr<ICameraDeviceSession> session;
648 std::shared_ptr<ICameraDevice> cameraDevice;
649 StreamConfiguration config;
650 };
651
652 std::map<std::string, std::string> idToNameMap = getCameraDeviceIdToNameMap(mProvider);
653 std::vector<ConcurrentCameraIdCombination> concurrentDeviceCombinations =
654 getConcurrentDeviceCombinations(mProvider);
655 std::vector<AvailableStream> outputStreams;
656 for (const auto& cameraDeviceIds : concurrentDeviceCombinations) {
657 std::vector<CameraIdAndStreamCombination> cameraIdsAndStreamCombinations;
658 std::vector<CameraTestInfo> cameraTestInfos;
Avichal Rakesh362242f2022-02-08 12:40:53 -0800659 for (const auto& id : cameraDeviceIds.combination) {
660 CameraTestInfo cti;
661 auto it = idToNameMap.find(id);
662 ASSERT_TRUE(idToNameMap.end() != it);
663 std::string name = it->second;
664
665 openEmptyDeviceSession(name, mProvider, &cti.session /*out*/, &cti.staticMeta /*out*/,
666 &cti.cameraDevice /*out*/);
667
668 outputStreams.clear();
669 camera_metadata_t* staticMeta =
670 reinterpret_cast<camera_metadata_t*>(cti.staticMeta.metadata.data());
671 ASSERT_EQ(Status::OK, getMandatoryConcurrentStreams(staticMeta, &outputStreams));
672 ASSERT_NE(0u, outputStreams.size());
673
674 int32_t jpegBufferSize = 0;
675 ASSERT_EQ(Status::OK, getJpegBufferSize(staticMeta, &jpegBufferSize));
676 ASSERT_NE(0u, jpegBufferSize);
677
678 int32_t streamId = 0;
679 std::vector<Stream> streams(outputStreams.size());
680 size_t j = 0;
681 for (const auto& s : outputStreams) {
682 Stream stream;
683 Dataspace dataspace = getDataspace(static_cast<PixelFormat>(s.format));
684 stream.id = streamId++;
685 stream.streamType = StreamType::OUTPUT;
686 stream.width = s.width;
687 stream.height = s.height;
688 stream.format = static_cast<PixelFormat>(s.format);
689 stream.usage = static_cast<aidl::android::hardware::graphics::common::BufferUsage>(
690 GRALLOC1_CONSUMER_USAGE_HWCOMPOSER);
691 stream.dataSpace = dataspace;
692 stream.rotation = StreamRotation::ROTATION_0;
693 stream.sensorPixelModesUsed = {SensorPixelMode::ANDROID_SENSOR_PIXEL_MODE_DEFAULT};
Avichal Rakeshd3503a32022-02-25 06:23:14 +0000694 stream.dynamicRangeProfile = RequestAvailableDynamicRangeProfilesMap::
695 ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD;
Avichal Rakesh362242f2022-02-08 12:40:53 -0800696 streams[j] = stream;
697 j++;
698 }
699
700 // Add the created stream configs to cameraIdsAndStreamCombinations
701 createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE, &cti.config,
702 jpegBufferSize);
703
704 cti.config.streamConfigCounter = outputStreams.size();
705 CameraIdAndStreamCombination cameraIdAndStreamCombination;
706 cameraIdAndStreamCombination.cameraId = id;
707 cameraIdAndStreamCombination.streamConfiguration = cti.config;
708 cameraIdsAndStreamCombinations.push_back(cameraIdAndStreamCombination);
Avichal Rakesh362242f2022-02-08 12:40:53 -0800709 cameraTestInfos.push_back(cti);
710 }
711 // Now verify that concurrent streams are supported
712 bool combinationSupported;
713 ndk::ScopedAStatus ret = mProvider->isConcurrentStreamCombinationSupported(
714 cameraIdsAndStreamCombinations, &combinationSupported);
715 ASSERT_TRUE(ret.isOk());
716 ASSERT_EQ(combinationSupported, true);
717
718 // Test the stream can actually be configured
719 for (auto& cti : cameraTestInfos) {
720 if (cti.session != nullptr) {
Shuzhen Wangdf89cb92023-11-09 18:24:42 -0800721 verifyStreamCombination(cti.cameraDevice, cti.config, /*expectedStatus*/ true);
Avichal Rakesh362242f2022-02-08 12:40:53 -0800722 }
723
724 if (cti.session != nullptr) {
725 std::vector<HalStream> streamConfigs;
726 ret = cti.session->configureStreams(cti.config, &streamConfigs);
727 ASSERT_TRUE(ret.isOk());
728 ASSERT_EQ(cti.config.streams.size(), streamConfigs.size());
729 }
730 }
731
732 for (auto& cti : cameraTestInfos) {
733 ret = cti.session->close();
734 ASSERT_TRUE(ret.isOk());
735 }
736 }
737}
738
739// Check for correct handling of invalid/incorrect configuration parameters.
740TEST_P(CameraAidlTest, configureStreamsInvalidOutputs) {
741 std::vector<std::string> cameraDeviceNames = getCameraDeviceNames(mProvider);
742 std::vector<AvailableStream> outputStreams;
743
744 for (const auto& name : cameraDeviceNames) {
745 CameraMetadata meta;
746 std::shared_ptr<ICameraDevice> cameraDevice;
747
748 openEmptyDeviceSession(name, mProvider, &mSession /*out*/, &meta /*out*/,
749 &cameraDevice /*out*/);
750 camera_metadata_t* staticMeta = reinterpret_cast<camera_metadata_t*>(meta.metadata.data());
751 outputStreams.clear();
752
753 ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta, outputStreams));
754 ASSERT_NE(0u, outputStreams.size());
755
756 int32_t jpegBufferSize = 0;
757 ASSERT_EQ(Status::OK, getJpegBufferSize(staticMeta, &jpegBufferSize));
758 ASSERT_NE(0u, jpegBufferSize);
759
760 int32_t streamId = 0;
761 Stream stream = {streamId++,
762 StreamType::OUTPUT,
763 static_cast<uint32_t>(0),
764 static_cast<uint32_t>(0),
765 static_cast<PixelFormat>(outputStreams[0].format),
766 static_cast<aidl::android::hardware::graphics::common::BufferUsage>(
767 GRALLOC1_CONSUMER_USAGE_HWCOMPOSER),
768 Dataspace::UNKNOWN,
769 StreamRotation::ROTATION_0,
770 std::string(),
771 jpegBufferSize,
772 -1,
Avichal Rakeshd3503a32022-02-25 06:23:14 +0000773 {SensorPixelMode::ANDROID_SENSOR_PIXEL_MODE_DEFAULT},
774 RequestAvailableDynamicRangeProfilesMap::
775 ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD};
Avichal Rakesh362242f2022-02-08 12:40:53 -0800776 int32_t streamConfigCounter = 0;
777 std::vector<Stream> streams = {stream};
778 StreamConfiguration config;
779 createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE, &config,
780 jpegBufferSize);
781
Shuzhen Wangdf89cb92023-11-09 18:24:42 -0800782 verifyStreamCombination(cameraDevice, config, /*expectedStatus*/ false);
Avichal Rakesh362242f2022-02-08 12:40:53 -0800783
784 config.streamConfigCounter = streamConfigCounter++;
785 std::vector<HalStream> halConfigs;
786 ndk::ScopedAStatus ret = mSession->configureStreams(config, &halConfigs);
787 ASSERT_TRUE(static_cast<int32_t>(Status::ILLEGAL_ARGUMENT) ==
788 ret.getServiceSpecificError() ||
789 static_cast<int32_t>(Status::INTERNAL_ERROR) == ret.getServiceSpecificError());
790
791 stream = {streamId++,
792 StreamType::OUTPUT,
793 /*width*/ INT32_MAX,
794 /*height*/ INT32_MAX,
795 static_cast<PixelFormat>(outputStreams[0].format),
796 static_cast<aidl::android::hardware::graphics::common::BufferUsage>(
797 GRALLOC1_CONSUMER_USAGE_HWCOMPOSER),
798 Dataspace::UNKNOWN,
799 StreamRotation::ROTATION_0,
800 std::string(),
801 jpegBufferSize,
802 -1,
Avichal Rakeshd3503a32022-02-25 06:23:14 +0000803 {SensorPixelMode::ANDROID_SENSOR_PIXEL_MODE_DEFAULT},
804 RequestAvailableDynamicRangeProfilesMap::
805 ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD};
Avichal Rakesh362242f2022-02-08 12:40:53 -0800806
807 streams[0] = stream;
808 createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE, &config,
809 jpegBufferSize);
810
811 config.streamConfigCounter = streamConfigCounter++;
812 halConfigs.clear();
813 ret = mSession->configureStreams(config, &halConfigs);
814 ASSERT_EQ(static_cast<int32_t>(Status::ILLEGAL_ARGUMENT), ret.getServiceSpecificError());
815
816 for (auto& it : outputStreams) {
817 stream = {streamId++,
818 StreamType::OUTPUT,
819 it.width,
820 it.height,
821 static_cast<PixelFormat>(UINT32_MAX),
822 static_cast<aidl::android::hardware::graphics::common::BufferUsage>(
823 GRALLOC1_CONSUMER_USAGE_HWCOMPOSER),
824 Dataspace::UNKNOWN,
825 StreamRotation::ROTATION_0,
826 std::string(),
827 jpegBufferSize,
828 -1,
Avichal Rakeshd3503a32022-02-25 06:23:14 +0000829 {SensorPixelMode::ANDROID_SENSOR_PIXEL_MODE_DEFAULT},
830 RequestAvailableDynamicRangeProfilesMap::
831 ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD};
Avichal Rakesh362242f2022-02-08 12:40:53 -0800832
833 streams[0] = stream;
834 createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE, &config,
835 jpegBufferSize);
836 config.streamConfigCounter = streamConfigCounter++;
837 halConfigs.clear();
838 ret = mSession->configureStreams(config, &halConfigs);
839 ASSERT_EQ(static_cast<int32_t>(Status::ILLEGAL_ARGUMENT),
840 ret.getServiceSpecificError());
841
842 stream = {streamId++,
843 StreamType::OUTPUT,
844 it.width,
845 it.height,
846 static_cast<PixelFormat>(it.format),
847 static_cast<aidl::android::hardware::graphics::common::BufferUsage>(
848 GRALLOC1_CONSUMER_USAGE_HWCOMPOSER),
849 Dataspace::UNKNOWN,
850 static_cast<StreamRotation>(UINT32_MAX),
851 std::string(),
852 jpegBufferSize,
853 -1,
Avichal Rakeshd3503a32022-02-25 06:23:14 +0000854 {SensorPixelMode::ANDROID_SENSOR_PIXEL_MODE_DEFAULT},
855 RequestAvailableDynamicRangeProfilesMap::
856 ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD};
Avichal Rakesh362242f2022-02-08 12:40:53 -0800857
858 streams[0] = stream;
859 createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE, &config,
860 jpegBufferSize);
861
862 config.streamConfigCounter = streamConfigCounter++;
863 halConfigs.clear();
864 ret = mSession->configureStreams(config, &halConfigs);
865 ASSERT_EQ(static_cast<int32_t>(Status::ILLEGAL_ARGUMENT),
866 ret.getServiceSpecificError());
867 }
868
869 ret = mSession->close();
870 mSession = nullptr;
871 ASSERT_TRUE(ret.isOk());
872 }
873}
874
875// Check whether all supported ZSL output stream combinations can be
876// configured successfully.
877TEST_P(CameraAidlTest, configureStreamsZSLInputOutputs) {
878 std::vector<std::string> cameraDeviceNames = getCameraDeviceNames(mProvider);
879 std::vector<AvailableStream> inputStreams;
880 std::vector<AvailableZSLInputOutput> inputOutputMap;
881
882 for (const auto& name : cameraDeviceNames) {
883 CameraMetadata meta;
884 std::shared_ptr<ICameraDevice> cameraDevice;
885
886 openEmptyDeviceSession(name, mProvider, &mSession /*out*/, &meta /*out*/,
887 &cameraDevice /*out*/);
888 camera_metadata_t* staticMeta = reinterpret_cast<camera_metadata_t*>(meta.metadata.data());
889
890 Status rc = isZSLModeAvailable(staticMeta);
891 if (Status::OPERATION_NOT_SUPPORTED == rc) {
892 ndk::ScopedAStatus ret = mSession->close();
893 mSession = nullptr;
894 ASSERT_TRUE(ret.isOk());
895 continue;
896 }
897 ASSERT_EQ(Status::OK, rc);
898
899 inputStreams.clear();
900 ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta, inputStreams));
901 ASSERT_NE(0u, inputStreams.size());
902
903 inputOutputMap.clear();
904 ASSERT_EQ(Status::OK, getZSLInputOutputMap(staticMeta, inputOutputMap));
905 ASSERT_NE(0u, inputOutputMap.size());
906
907 bool supportMonoY8 = false;
908 if (Status::OK == isMonochromeCamera(staticMeta)) {
909 for (auto& it : inputStreams) {
910 if (it.format == static_cast<uint32_t>(PixelFormat::Y8)) {
911 supportMonoY8 = true;
912 break;
913 }
914 }
915 }
916
917 int32_t jpegBufferSize = 0;
918 ASSERT_EQ(Status::OK, getJpegBufferSize(staticMeta, &jpegBufferSize));
919 ASSERT_NE(0u, jpegBufferSize);
920
921 int32_t streamId = 0;
922 bool hasPrivToY8 = false, hasY8ToY8 = false, hasY8ToBlob = false;
923 uint32_t streamConfigCounter = 0;
924 for (auto& inputIter : inputOutputMap) {
925 AvailableStream input;
926 ASSERT_EQ(Status::OK, findLargestSize(inputStreams, inputIter.inputFormat, input));
927 ASSERT_NE(0u, inputStreams.size());
928
929 if (inputIter.inputFormat ==
930 static_cast<uint32_t>(PixelFormat::IMPLEMENTATION_DEFINED) &&
931 inputIter.outputFormat == static_cast<uint32_t>(PixelFormat::Y8)) {
932 hasPrivToY8 = true;
933 } else if (inputIter.inputFormat == static_cast<uint32_t>(PixelFormat::Y8)) {
934 if (inputIter.outputFormat == static_cast<uint32_t>(PixelFormat::BLOB)) {
935 hasY8ToBlob = true;
936 } else if (inputIter.outputFormat == static_cast<uint32_t>(PixelFormat::Y8)) {
937 hasY8ToY8 = true;
938 }
939 }
940 AvailableStream outputThreshold = {INT32_MAX, INT32_MAX, inputIter.outputFormat};
941 std::vector<AvailableStream> outputStreams;
942 ASSERT_EQ(Status::OK,
943 getAvailableOutputStreams(staticMeta, outputStreams, &outputThreshold));
944 for (auto& outputIter : outputStreams) {
945 Dataspace outputDataSpace =
946 getDataspace(static_cast<PixelFormat>(outputIter.format));
947 Stream zslStream = {
948 streamId++,
949 StreamType::OUTPUT,
950 input.width,
951 input.height,
952 static_cast<PixelFormat>(input.format),
953 static_cast<aidl::android::hardware::graphics::common::BufferUsage>(
954 GRALLOC_USAGE_HW_CAMERA_ZSL),
955 Dataspace::UNKNOWN,
956 StreamRotation::ROTATION_0,
957 std::string(),
958 jpegBufferSize,
959 -1,
Avichal Rakeshd3503a32022-02-25 06:23:14 +0000960 {SensorPixelMode::ANDROID_SENSOR_PIXEL_MODE_DEFAULT},
961 RequestAvailableDynamicRangeProfilesMap::
962 ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD};
Avichal Rakesh362242f2022-02-08 12:40:53 -0800963 Stream inputStream = {
964 streamId++,
965 StreamType::INPUT,
966 input.width,
967 input.height,
968 static_cast<PixelFormat>(input.format),
969 static_cast<aidl::android::hardware::graphics::common::BufferUsage>(0),
970 Dataspace::UNKNOWN,
971 StreamRotation::ROTATION_0,
972 std::string(),
973 jpegBufferSize,
974 -1,
Avichal Rakeshd3503a32022-02-25 06:23:14 +0000975 {SensorPixelMode::ANDROID_SENSOR_PIXEL_MODE_DEFAULT},
976 RequestAvailableDynamicRangeProfilesMap::
977 ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD};
Avichal Rakesh362242f2022-02-08 12:40:53 -0800978 Stream outputStream = {
979 streamId++,
980 StreamType::OUTPUT,
981 outputIter.width,
982 outputIter.height,
983 static_cast<PixelFormat>(outputIter.format),
984 static_cast<aidl::android::hardware::graphics::common::BufferUsage>(
985 GRALLOC1_CONSUMER_USAGE_HWCOMPOSER),
986 outputDataSpace,
987 StreamRotation::ROTATION_0,
988 std::string(),
989 jpegBufferSize,
990 -1,
Avichal Rakeshd3503a32022-02-25 06:23:14 +0000991 {SensorPixelMode::ANDROID_SENSOR_PIXEL_MODE_DEFAULT},
992 RequestAvailableDynamicRangeProfilesMap::
993 ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD};
Avichal Rakesh362242f2022-02-08 12:40:53 -0800994
995 std::vector<Stream> streams = {inputStream, zslStream, outputStream};
996
997 StreamConfiguration config;
998 createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE, &config,
999 jpegBufferSize);
1000
Shuzhen Wangdf89cb92023-11-09 18:24:42 -08001001 verifyStreamCombination(cameraDevice, config, /*expectedStatus*/ true);
Avichal Rakesh362242f2022-02-08 12:40:53 -08001002
1003 config.streamConfigCounter = streamConfigCounter++;
1004 std::vector<HalStream> halConfigs;
1005 ndk::ScopedAStatus ret = mSession->configureStreams(config, &halConfigs);
1006 ASSERT_TRUE(ret.isOk());
1007 ASSERT_EQ(3u, halConfigs.size());
1008 }
1009 }
1010
1011 if (supportMonoY8) {
1012 if (Status::OK == isZSLModeAvailable(staticMeta, PRIV_REPROCESS)) {
1013 ASSERT_TRUE(hasPrivToY8);
1014 }
1015 if (Status::OK == isZSLModeAvailable(staticMeta, YUV_REPROCESS)) {
1016 ASSERT_TRUE(hasY8ToY8);
1017 ASSERT_TRUE(hasY8ToBlob);
1018 }
1019 }
1020
1021 ndk::ScopedAStatus ret = mSession->close();
1022 mSession = nullptr;
1023 ASSERT_TRUE(ret.isOk());
1024 }
1025}
1026
1027// Check whether session parameters are supported. If Hal support for them
1028// exist, then try to configure a preview stream using them.
1029TEST_P(CameraAidlTest, configureStreamsWithSessionParameters) {
1030 std::vector<std::string> cameraDeviceNames = getCameraDeviceNames(mProvider);
1031 std::vector<AvailableStream> outputPreviewStreams;
1032 AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
1033 static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
1034
1035 for (const auto& name : cameraDeviceNames) {
1036 CameraMetadata meta;
1037
1038 std::shared_ptr<ICameraDevice> unusedCameraDevice;
1039 openEmptyDeviceSession(name, mProvider, &mSession /*out*/, &meta /*out*/,
1040 &unusedCameraDevice /*out*/);
1041 camera_metadata_t* staticMetaBuffer =
1042 reinterpret_cast<camera_metadata_t*>(meta.metadata.data());
1043
1044 std::unordered_set<int32_t> availableSessionKeys;
1045 auto rc = getSupportedKeys(staticMetaBuffer, ANDROID_REQUEST_AVAILABLE_SESSION_KEYS,
1046 &availableSessionKeys);
1047 ASSERT_TRUE(Status::OK == rc);
1048 if (availableSessionKeys.empty()) {
1049 ndk::ScopedAStatus ret = mSession->close();
1050 mSession = nullptr;
1051 ASSERT_TRUE(ret.isOk());
1052 continue;
1053 }
1054
1055 android::hardware::camera::common::V1_0::helper::CameraMetadata previewRequestSettings;
1056 android::hardware::camera::common::V1_0::helper::CameraMetadata sessionParams,
1057 modifiedSessionParams;
1058 constructFilteredSettings(mSession, availableSessionKeys, RequestTemplate::PREVIEW,
1059 &previewRequestSettings, &sessionParams);
1060 if (sessionParams.isEmpty()) {
1061 ndk::ScopedAStatus ret = mSession->close();
1062 mSession = nullptr;
1063 ASSERT_TRUE(ret.isOk());
1064 continue;
1065 }
1066
1067 outputPreviewStreams.clear();
1068
1069 ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMetaBuffer, outputPreviewStreams,
1070 &previewThreshold));
1071 ASSERT_NE(0u, outputPreviewStreams.size());
1072
Avichal Rakeshd3503a32022-02-25 06:23:14 +00001073 Stream previewStream = {
1074 0,
1075 StreamType::OUTPUT,
1076 outputPreviewStreams[0].width,
1077 outputPreviewStreams[0].height,
1078 static_cast<PixelFormat>(outputPreviewStreams[0].format),
1079 static_cast<aidl::android::hardware::graphics::common::BufferUsage>(
1080 GRALLOC1_CONSUMER_USAGE_HWCOMPOSER),
1081 Dataspace::UNKNOWN,
1082 StreamRotation::ROTATION_0,
1083 std::string(),
1084 /*bufferSize*/ 0,
1085 /*groupId*/ -1,
1086 {SensorPixelMode::ANDROID_SENSOR_PIXEL_MODE_DEFAULT},
1087 RequestAvailableDynamicRangeProfilesMap::
1088 ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD};
Avichal Rakesh362242f2022-02-08 12:40:53 -08001089
1090 std::vector<Stream> streams = {previewStream};
1091 StreamConfiguration config;
1092
1093 config.streams = streams;
1094 config.operationMode = StreamConfigurationMode::NORMAL_MODE;
1095 modifiedSessionParams = sessionParams;
1096 auto sessionParamsBuffer = sessionParams.release();
1097 std::vector<uint8_t> rawSessionParam =
1098 std::vector(reinterpret_cast<uint8_t*>(sessionParamsBuffer),
1099 reinterpret_cast<uint8_t*>(sessionParamsBuffer) +
1100 get_camera_metadata_size(sessionParamsBuffer));
1101
1102 config.sessionParams.metadata = rawSessionParam;
1103 config.streamConfigCounter = 0;
1104 config.streams = {previewStream};
1105 config.streamConfigCounter = 0;
1106 config.multiResolutionInputImage = false;
1107
1108 bool newSessionParamsAvailable = false;
1109 for (const auto& it : availableSessionKeys) {
1110 if (modifiedSessionParams.exists(it)) {
1111 modifiedSessionParams.erase(it);
1112 newSessionParamsAvailable = true;
1113 break;
1114 }
1115 }
1116 if (newSessionParamsAvailable) {
1117 auto modifiedSessionParamsBuffer = modifiedSessionParams.release();
1118 verifySessionReconfigurationQuery(mSession, sessionParamsBuffer,
1119 modifiedSessionParamsBuffer);
1120 modifiedSessionParams.acquire(modifiedSessionParamsBuffer);
1121 }
1122
1123 std::vector<HalStream> halConfigs;
1124 ndk::ScopedAStatus ret = mSession->configureStreams(config, &halConfigs);
1125 ASSERT_TRUE(ret.isOk());
1126 ASSERT_EQ(1u, halConfigs.size());
1127
1128 sessionParams.acquire(sessionParamsBuffer);
1129 ret = mSession->close();
1130 mSession = nullptr;
1131 ASSERT_TRUE(ret.isOk());
1132 }
1133}
1134
1135// Verify that all supported preview + still capture stream combinations
1136// can be configured successfully.
1137TEST_P(CameraAidlTest, configureStreamsPreviewStillOutputs) {
1138 std::vector<std::string> cameraDeviceNames = getCameraDeviceNames(mProvider);
1139 std::vector<AvailableStream> outputBlobStreams;
1140 std::vector<AvailableStream> outputPreviewStreams;
1141 AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
1142 static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
1143 AvailableStream blobThreshold = {INT32_MAX, INT32_MAX, static_cast<int32_t>(PixelFormat::BLOB)};
1144
1145 for (const auto& name : cameraDeviceNames) {
1146 CameraMetadata meta;
1147
1148 std::shared_ptr<ICameraDevice> cameraDevice;
1149 openEmptyDeviceSession(name, mProvider, &mSession /*out*/, &meta /*out*/,
1150 &cameraDevice /*out*/);
1151
1152 camera_metadata_t* staticMeta = reinterpret_cast<camera_metadata_t*>(meta.metadata.data());
1153
1154 // Check if camera support depth only
1155 if (isDepthOnly(staticMeta)) {
1156 ndk::ScopedAStatus ret = mSession->close();
1157 mSession = nullptr;
1158 ASSERT_TRUE(ret.isOk());
1159 continue;
1160 }
1161
1162 outputBlobStreams.clear();
1163 ASSERT_EQ(Status::OK,
1164 getAvailableOutputStreams(staticMeta, outputBlobStreams, &blobThreshold));
1165 ASSERT_NE(0u, outputBlobStreams.size());
1166
1167 outputPreviewStreams.clear();
1168 ASSERT_EQ(Status::OK,
1169 getAvailableOutputStreams(staticMeta, outputPreviewStreams, &previewThreshold));
1170 ASSERT_NE(0u, outputPreviewStreams.size());
1171
1172 int32_t jpegBufferSize = 0;
1173 ASSERT_EQ(Status::OK, getJpegBufferSize(staticMeta, &jpegBufferSize));
1174 ASSERT_NE(0u, jpegBufferSize);
1175
1176 int32_t streamId = 0;
1177 uint32_t streamConfigCounter = 0;
1178
1179 for (auto& blobIter : outputBlobStreams) {
1180 for (auto& previewIter : outputPreviewStreams) {
1181 Stream previewStream = {
1182 streamId++,
1183 StreamType::OUTPUT,
1184 previewIter.width,
1185 previewIter.height,
1186 static_cast<PixelFormat>(previewIter.format),
1187 static_cast<aidl::android::hardware::graphics::common::BufferUsage>(
1188 GRALLOC1_CONSUMER_USAGE_HWCOMPOSER),
1189 Dataspace::UNKNOWN,
1190 StreamRotation::ROTATION_0,
1191 std::string(),
1192 /*bufferSize*/ 0,
1193 /*groupId*/ -1,
Avichal Rakeshd3503a32022-02-25 06:23:14 +00001194 {SensorPixelMode::ANDROID_SENSOR_PIXEL_MODE_DEFAULT},
1195 RequestAvailableDynamicRangeProfilesMap::
1196 ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD};
Avichal Rakesh362242f2022-02-08 12:40:53 -08001197 Stream blobStream = {
1198 streamId++,
1199 StreamType::OUTPUT,
1200 blobIter.width,
1201 blobIter.height,
1202 static_cast<PixelFormat>(blobIter.format),
1203 static_cast<aidl::android::hardware::graphics::common::BufferUsage>(
1204 GRALLOC1_CONSUMER_USAGE_CPU_READ),
1205 Dataspace::JFIF,
1206 StreamRotation::ROTATION_0,
1207 std::string(),
1208 /*bufferSize*/ 0,
1209 /*groupId*/ -1,
Avichal Rakeshd3503a32022-02-25 06:23:14 +00001210 {SensorPixelMode::ANDROID_SENSOR_PIXEL_MODE_DEFAULT},
1211 RequestAvailableDynamicRangeProfilesMap::
1212 ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD};
Avichal Rakesh362242f2022-02-08 12:40:53 -08001213 std::vector<Stream> streams = {previewStream, blobStream};
1214 StreamConfiguration config;
1215
1216 createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE, &config,
1217 jpegBufferSize);
1218 config.streamConfigCounter = streamConfigCounter++;
Shuzhen Wangdf89cb92023-11-09 18:24:42 -08001219 verifyStreamCombination(cameraDevice, config, /*expectedStatus*/ true);
Avichal Rakesh362242f2022-02-08 12:40:53 -08001220
1221 std::vector<HalStream> halConfigs;
1222 ndk::ScopedAStatus ret = mSession->configureStreams(config, &halConfigs);
1223 ASSERT_TRUE(ret.isOk());
1224 ASSERT_EQ(2u, halConfigs.size());
1225 }
1226 }
1227
1228 ndk::ScopedAStatus ret = mSession->close();
1229 mSession = nullptr;
1230 ASSERT_TRUE(ret.isOk());
1231 }
1232}
1233
1234// In case constrained mode is supported, test whether it can be
1235// configured. Additionally check for common invalid inputs when
1236// using this mode.
1237TEST_P(CameraAidlTest, configureStreamsConstrainedOutputs) {
1238 std::vector<std::string> cameraDeviceNames = getCameraDeviceNames(mProvider);
1239
1240 for (const auto& name : cameraDeviceNames) {
1241 CameraMetadata meta;
1242 std::shared_ptr<ICameraDevice> cameraDevice;
1243
1244 openEmptyDeviceSession(name, mProvider, &mSession /*out*/, &meta /*out*/,
1245 &cameraDevice /*out*/);
1246 camera_metadata_t* staticMeta = reinterpret_cast<camera_metadata_t*>(meta.metadata.data());
1247
1248 Status rc = isConstrainedModeAvailable(staticMeta);
1249 if (Status::OPERATION_NOT_SUPPORTED == rc) {
1250 ndk::ScopedAStatus ret = mSession->close();
1251 mSession = nullptr;
1252 ASSERT_TRUE(ret.isOk());
1253 continue;
1254 }
1255 ASSERT_EQ(Status::OK, rc);
1256
1257 AvailableStream hfrStream;
1258 rc = pickConstrainedModeSize(staticMeta, hfrStream);
1259 ASSERT_EQ(Status::OK, rc);
1260
1261 int32_t streamId = 0;
1262 uint32_t streamConfigCounter = 0;
1263 Stream stream = {streamId,
1264 StreamType::OUTPUT,
1265 hfrStream.width,
1266 hfrStream.height,
1267 static_cast<PixelFormat>(hfrStream.format),
1268 static_cast<aidl::android::hardware::graphics::common::BufferUsage>(
1269 GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER),
1270 Dataspace::UNKNOWN,
1271 StreamRotation::ROTATION_0,
1272 std::string(),
1273 /*bufferSize*/ 0,
1274 /*groupId*/ -1,
Avichal Rakeshd3503a32022-02-25 06:23:14 +00001275 {SensorPixelMode::ANDROID_SENSOR_PIXEL_MODE_DEFAULT},
1276 RequestAvailableDynamicRangeProfilesMap::
1277 ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD};
Avichal Rakesh362242f2022-02-08 12:40:53 -08001278 std::vector<Stream> streams = {stream};
1279 StreamConfiguration config;
1280 createStreamConfiguration(streams, StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE,
1281 &config);
1282
Shuzhen Wangdf89cb92023-11-09 18:24:42 -08001283 verifyStreamCombination(cameraDevice, config, /*expectedStatus*/ true);
Avichal Rakesh362242f2022-02-08 12:40:53 -08001284
1285 config.streamConfigCounter = streamConfigCounter++;
1286 std::vector<HalStream> halConfigs;
1287 ndk::ScopedAStatus ret = mSession->configureStreams(config, &halConfigs);
1288 ASSERT_TRUE(ret.isOk());
1289 ASSERT_EQ(1u, halConfigs.size());
1290 ASSERT_EQ(halConfigs[0].id, streamId);
1291
1292 stream = {streamId++,
1293 StreamType::OUTPUT,
1294 static_cast<uint32_t>(0),
1295 static_cast<uint32_t>(0),
1296 static_cast<PixelFormat>(hfrStream.format),
1297 static_cast<aidl::android::hardware::graphics::common::BufferUsage>(
1298 GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER),
1299 Dataspace::UNKNOWN,
1300 StreamRotation::ROTATION_0,
1301 std::string(),
1302 /*bufferSize*/ 0,
1303 /*groupId*/ -1,
Avichal Rakeshd3503a32022-02-25 06:23:14 +00001304 {SensorPixelMode::ANDROID_SENSOR_PIXEL_MODE_DEFAULT},
1305 RequestAvailableDynamicRangeProfilesMap::
1306 ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD};
Avichal Rakesh362242f2022-02-08 12:40:53 -08001307 streams[0] = stream;
1308 createStreamConfiguration(streams, StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE,
1309 &config);
1310
1311 config.streamConfigCounter = streamConfigCounter++;
1312 std::vector<HalStream> halConfig;
1313 ret = mSession->configureStreams(config, &halConfig);
1314 ASSERT_TRUE(static_cast<int32_t>(Status::ILLEGAL_ARGUMENT) ==
1315 ret.getServiceSpecificError() ||
1316 static_cast<int32_t>(Status::INTERNAL_ERROR) == ret.getServiceSpecificError());
1317
1318 stream = {streamId++,
1319 StreamType::OUTPUT,
1320 INT32_MAX,
1321 INT32_MAX,
1322 static_cast<PixelFormat>(hfrStream.format),
1323 static_cast<aidl::android::hardware::graphics::common::BufferUsage>(
1324 GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER),
1325 Dataspace::UNKNOWN,
1326 StreamRotation::ROTATION_0,
1327 std::string(),
1328 /*bufferSize*/ 0,
1329 /*groupId*/ -1,
Avichal Rakeshd3503a32022-02-25 06:23:14 +00001330 {SensorPixelMode::ANDROID_SENSOR_PIXEL_MODE_DEFAULT},
1331 RequestAvailableDynamicRangeProfilesMap::
1332 ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD};
Avichal Rakesh362242f2022-02-08 12:40:53 -08001333 streams[0] = stream;
1334 createStreamConfiguration(streams, StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE,
1335 &config);
1336
1337 config.streamConfigCounter = streamConfigCounter++;
1338 halConfigs.clear();
1339 ret = mSession->configureStreams(config, &halConfigs);
1340 ASSERT_EQ(static_cast<int32_t>(Status::ILLEGAL_ARGUMENT), ret.getServiceSpecificError());
1341
1342 stream = {streamId++,
1343 StreamType::OUTPUT,
1344 hfrStream.width,
1345 hfrStream.height,
1346 static_cast<PixelFormat>(UINT32_MAX),
1347 static_cast<aidl::android::hardware::graphics::common::BufferUsage>(
1348 GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER),
1349 Dataspace::UNKNOWN,
1350 StreamRotation::ROTATION_0,
1351 std::string(),
1352 /*bufferSize*/ 0,
1353 /*groupId*/ -1,
Avichal Rakeshd3503a32022-02-25 06:23:14 +00001354 {SensorPixelMode::ANDROID_SENSOR_PIXEL_MODE_DEFAULT},
1355 RequestAvailableDynamicRangeProfilesMap::
1356 ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD};
Avichal Rakesh362242f2022-02-08 12:40:53 -08001357 streams[0] = stream;
1358 createStreamConfiguration(streams, StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE,
1359 &config);
1360
1361 config.streamConfigCounter = streamConfigCounter++;
1362 halConfigs.clear();
1363 ret = mSession->configureStreams(config, &halConfigs);
1364 ASSERT_EQ(static_cast<int32_t>(Status::ILLEGAL_ARGUMENT), ret.getServiceSpecificError());
1365
1366 ret = mSession->close();
1367 mSession = nullptr;
1368 ASSERT_TRUE(ret.isOk());
1369 }
1370}
1371
1372// Verify that all supported video + snapshot stream combinations can
1373// be configured successfully.
1374TEST_P(CameraAidlTest, configureStreamsVideoStillOutputs) {
1375 std::vector<std::string> cameraDeviceNames = getCameraDeviceNames(mProvider);
1376 std::vector<AvailableStream> outputBlobStreams;
1377 std::vector<AvailableStream> outputVideoStreams;
1378 AvailableStream videoThreshold = {kMaxVideoWidth, kMaxVideoHeight,
1379 static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
1380 AvailableStream blobThreshold = {kMaxVideoWidth, kMaxVideoHeight,
1381 static_cast<int32_t>(PixelFormat::BLOB)};
1382
1383 for (const auto& name : cameraDeviceNames) {
1384 CameraMetadata meta;
1385 std::shared_ptr<ICameraDevice> cameraDevice;
1386
1387 openEmptyDeviceSession(name, mProvider, &mSession /*out*/, &meta /*out*/,
1388 &cameraDevice /*out*/);
1389
1390 camera_metadata_t* staticMeta = reinterpret_cast<camera_metadata_t*>(meta.metadata.data());
1391
1392 // Check if camera support depth only
1393 if (isDepthOnly(staticMeta)) {
1394 ndk::ScopedAStatus ret = mSession->close();
1395 mSession = nullptr;
1396 ASSERT_TRUE(ret.isOk());
1397 continue;
1398 }
1399
1400 outputBlobStreams.clear();
1401 ASSERT_EQ(Status::OK,
1402 getAvailableOutputStreams(staticMeta, outputBlobStreams, &blobThreshold));
1403 ASSERT_NE(0u, outputBlobStreams.size());
1404
1405 outputVideoStreams.clear();
1406 ASSERT_EQ(Status::OK,
1407 getAvailableOutputStreams(staticMeta, outputVideoStreams, &videoThreshold));
1408 ASSERT_NE(0u, outputVideoStreams.size());
1409
1410 int32_t jpegBufferSize = 0;
1411 ASSERT_EQ(Status::OK, getJpegBufferSize(staticMeta, &jpegBufferSize));
1412 ASSERT_NE(0u, jpegBufferSize);
1413
1414 int32_t streamId = 0;
1415 uint32_t streamConfigCounter = 0;
1416 for (auto& blobIter : outputBlobStreams) {
1417 for (auto& videoIter : outputVideoStreams) {
1418 Stream videoStream = {
1419 streamId++,
1420 StreamType::OUTPUT,
1421 videoIter.width,
1422 videoIter.height,
1423 static_cast<PixelFormat>(videoIter.format),
1424 static_cast<aidl::android::hardware::graphics::common::BufferUsage>(
1425 GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER),
1426 Dataspace::UNKNOWN,
1427 StreamRotation::ROTATION_0,
1428 std::string(),
1429 jpegBufferSize,
1430 /*groupId*/ -1,
Avichal Rakeshd3503a32022-02-25 06:23:14 +00001431 {SensorPixelMode::ANDROID_SENSOR_PIXEL_MODE_DEFAULT},
1432 RequestAvailableDynamicRangeProfilesMap::
1433 ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD};
Avichal Rakesh362242f2022-02-08 12:40:53 -08001434 Stream blobStream = {
1435 streamId++,
1436 StreamType::OUTPUT,
1437 blobIter.width,
1438 blobIter.height,
1439 static_cast<PixelFormat>(blobIter.format),
1440 static_cast<aidl::android::hardware::graphics::common::BufferUsage>(
1441 GRALLOC1_CONSUMER_USAGE_CPU_READ),
1442 Dataspace::JFIF,
1443 StreamRotation::ROTATION_0,
1444 std::string(),
1445 jpegBufferSize,
1446 /*groupId*/ -1,
Avichal Rakeshd3503a32022-02-25 06:23:14 +00001447 {SensorPixelMode::ANDROID_SENSOR_PIXEL_MODE_DEFAULT},
1448 RequestAvailableDynamicRangeProfilesMap::
1449 ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD};
Avichal Rakesh362242f2022-02-08 12:40:53 -08001450 std::vector<Stream> streams = {videoStream, blobStream};
1451 StreamConfiguration config;
1452
1453 createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE, &config,
1454 jpegBufferSize);
Shuzhen Wangdf89cb92023-11-09 18:24:42 -08001455 verifyStreamCombination(cameraDevice, config, /*expectedStatus*/ true);
Avichal Rakesh362242f2022-02-08 12:40:53 -08001456
1457 config.streamConfigCounter = streamConfigCounter++;
1458 std::vector<HalStream> halConfigs;
1459 ndk::ScopedAStatus ret = mSession->configureStreams(config, &halConfigs);
1460 ASSERT_TRUE(ret.isOk());
1461 ASSERT_EQ(2u, halConfigs.size());
1462 }
1463 }
1464
1465 ndk::ScopedAStatus ret = mSession->close();
1466 mSession = nullptr;
1467 ASSERT_TRUE(ret.isOk());
1468 }
1469}
1470
1471// Generate and verify a camera capture request
1472TEST_P(CameraAidlTest, processCaptureRequestPreview) {
1473 // TODO(b/220897574): Failing with BUFFER_ERROR
1474 processCaptureRequestInternal(GRALLOC1_CONSUMER_USAGE_HWCOMPOSER, RequestTemplate::PREVIEW,
1475 false /*secureOnlyCameras*/);
1476}
1477
1478// Generate and verify a secure camera capture request
1479TEST_P(CameraAidlTest, processSecureCaptureRequest) {
1480 processCaptureRequestInternal(GRALLOC1_PRODUCER_USAGE_PROTECTED, RequestTemplate::STILL_CAPTURE,
1481 true /*secureOnlyCameras*/);
1482}
1483
1484TEST_P(CameraAidlTest, processCaptureRequestPreviewStabilization) {
1485 std::unordered_map<std::string, nsecs_t> cameraDeviceToTimeLag;
1486 processPreviewStabilizationCaptureRequestInternal(/*previewStabilizationOn*/ false,
1487 cameraDeviceToTimeLag);
1488 processPreviewStabilizationCaptureRequestInternal(/*previewStabilizationOn*/ true,
1489 cameraDeviceToTimeLag);
1490}
1491
1492// Generate and verify a multi-camera capture request
1493TEST_P(CameraAidlTest, processMultiCaptureRequestPreview) {
1494 std::vector<std::string> cameraDeviceNames = getCameraDeviceNames(mProvider);
1495 AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
1496 static_cast<int32_t>(PixelFormat::YCBCR_420_888)};
1497 int64_t bufferId = 1;
1498 uint32_t frameNumber = 1;
1499 std::vector<uint8_t> settings;
1500 std::vector<uint8_t> emptySettings;
1501 std::string invalidPhysicalId = "-1";
1502
1503 for (const auto& name : cameraDeviceNames) {
1504 std::string version, deviceId;
Avichal Rakeshfbcf7ea2022-03-09 01:00:34 +00001505 ALOGI("processMultiCaptureRequestPreview: Test device %s", name.c_str());
Avichal Rakesh362242f2022-02-08 12:40:53 -08001506 ASSERT_TRUE(matchDeviceName(name, mProviderType, &version, &deviceId));
1507 CameraMetadata metadata;
1508
1509 std::shared_ptr<ICameraDevice> unusedDevice;
1510 openEmptyDeviceSession(name, mProvider, &mSession /*out*/, &metadata /*out*/,
1511 &unusedDevice /*out*/);
1512
1513 camera_metadata_t* staticMeta =
1514 reinterpret_cast<camera_metadata_t*>(metadata.metadata.data());
1515 Status rc = isLogicalMultiCamera(staticMeta);
1516 if (Status::OPERATION_NOT_SUPPORTED == rc) {
1517 ndk::ScopedAStatus ret = mSession->close();
1518 mSession = nullptr;
1519 ASSERT_TRUE(ret.isOk());
1520 continue;
1521 }
Avichal Rakeshfbcf7ea2022-03-09 01:00:34 +00001522 ASSERT_EQ(Status::OK, rc);
Avichal Rakesh362242f2022-02-08 12:40:53 -08001523
1524 std::unordered_set<std::string> physicalIds;
1525 rc = getPhysicalCameraIds(staticMeta, &physicalIds);
1526 ASSERT_TRUE(Status::OK == rc);
1527 ASSERT_TRUE(physicalIds.size() > 1);
1528
1529 std::unordered_set<int32_t> physicalRequestKeyIDs;
1530 rc = getSupportedKeys(staticMeta, ANDROID_REQUEST_AVAILABLE_PHYSICAL_CAMERA_REQUEST_KEYS,
1531 &physicalRequestKeyIDs);
1532 ASSERT_TRUE(Status::OK == rc);
1533 if (physicalRequestKeyIDs.empty()) {
1534 ndk::ScopedAStatus ret = mSession->close();
1535 mSession = nullptr;
1536 ASSERT_TRUE(ret.isOk());
1537 // The logical camera doesn't support any individual physical requests.
1538 continue;
1539 }
1540
1541 android::hardware::camera::common::V1_0::helper::CameraMetadata defaultPreviewSettings;
1542 android::hardware::camera::common::V1_0::helper::CameraMetadata filteredSettings;
1543 constructFilteredSettings(mSession, physicalRequestKeyIDs, RequestTemplate::PREVIEW,
1544 &defaultPreviewSettings, &filteredSettings);
1545 if (filteredSettings.isEmpty()) {
1546 // No physical device settings in default request.
1547 ndk::ScopedAStatus ret = mSession->close();
1548 mSession = nullptr;
1549 ASSERT_TRUE(ret.isOk());
1550 continue;
1551 }
1552
1553 const camera_metadata_t* settingsBuffer = defaultPreviewSettings.getAndLock();
1554 uint8_t* rawSettingsBuffer = (uint8_t*)settingsBuffer;
1555 settings.assign(rawSettingsBuffer,
1556 rawSettingsBuffer + get_camera_metadata_size(settingsBuffer));
1557 CameraMetadata settingsMetadata = {settings};
1558 overrideRotateAndCrop(&settingsMetadata);
1559
1560 ndk::ScopedAStatus ret = mSession->close();
1561 mSession = nullptr;
1562 ASSERT_TRUE(ret.isOk());
1563
1564 // Leave only 2 physical devices in the id set.
1565 auto it = physicalIds.begin();
1566 std::string physicalDeviceId = *it;
1567 it++;
1568 physicalIds.erase(++it, physicalIds.end());
1569 ASSERT_EQ(physicalIds.size(), 2u);
1570
1571 std::vector<HalStream> halStreams;
1572 bool supportsPartialResults = false;
Jayant Chowdhary4869ae72023-12-18 05:36:14 +00001573 std::set<int32_t> halBufManagedStreamIds;
Avichal Rakesh362242f2022-02-08 12:40:53 -08001574 int32_t partialResultCount = 0;
1575 Stream previewStream;
1576 std::shared_ptr<DeviceCb> cb;
1577
Avichal Rakeshfbcf7ea2022-03-09 01:00:34 +00001578 configurePreviewStreams(
1579 name, mProvider, &previewThreshold, physicalIds, &mSession, &previewStream,
1580 &halStreams /*out*/, &supportsPartialResults /*out*/, &partialResultCount /*out*/,
Jayant Chowdhary4869ae72023-12-18 05:36:14 +00001581 &halBufManagedStreamIds /*out*/, &cb /*out*/, 0 /*streamConfigCounter*/, true);
Avichal Rakeshfbcf7ea2022-03-09 01:00:34 +00001582 if (mSession == nullptr) {
1583 // stream combination not supported by HAL, skip test for device
1584 continue;
1585 }
Avichal Rakesh362242f2022-02-08 12:40:53 -08001586
1587 ::aidl::android::hardware::common::fmq::MQDescriptor<
1588 int8_t, aidl::android::hardware::common::fmq::SynchronizedReadWrite>
1589 descriptor;
1590 auto resultQueueRet = mSession->getCaptureResultMetadataQueue(&descriptor);
1591 ASSERT_TRUE(resultQueueRet.isOk());
1592 std::shared_ptr<ResultMetadataQueue> resultQueue =
1593 std::make_shared<ResultMetadataQueue>(descriptor);
1594 if (!resultQueue->isValid() || resultQueue->availableToWrite() <= 0) {
1595 ALOGE("%s: HAL returns empty result metadata fmq, not use it", __func__);
1596 resultQueue = nullptr;
1597 // Don't use the queue onwards.
1598 }
1599
1600 std::shared_ptr<InFlightRequest> inflightReq = std::make_shared<InFlightRequest>(
1601 static_cast<ssize_t>(halStreams.size()), false, supportsPartialResults,
1602 partialResultCount, physicalIds, resultQueue);
1603
1604 std::vector<CaptureRequest> requests(1);
1605 CaptureRequest& request = requests[0];
1606 request.frameNumber = frameNumber;
1607 request.fmqSettingsSize = 0;
Emilian Peev3d919f92022-04-20 13:50:59 -07001608 request.settings = settingsMetadata;
Avichal Rakesh362242f2022-02-08 12:40:53 -08001609
1610 std::vector<StreamBuffer>& outputBuffers = request.outputBuffers;
1611
1612 std::vector<buffer_handle_t> graphicBuffers;
1613 graphicBuffers.reserve(halStreams.size());
1614 outputBuffers.resize(halStreams.size());
1615 size_t k = 0;
1616 for (const auto& halStream : halStreams) {
1617 buffer_handle_t buffer_handle;
Jayant Chowdhary4869ae72023-12-18 05:36:14 +00001618 bool useHalBufManagerForStream =
1619 halBufManagedStreamIds.find(halStream.id) != halBufManagedStreamIds.end();
1620 if (useHalBufManagerForStream) {
Avichal Rakesh362242f2022-02-08 12:40:53 -08001621 outputBuffers[k] = {halStream.id, /*bufferId*/ 0, NativeHandle(),
1622 BufferStatus::OK, NativeHandle(), NativeHandle()};
1623 } else {
1624 allocateGraphicBuffer(previewStream.width, previewStream.height,
1625 android_convertGralloc1To0Usage(
1626 static_cast<uint64_t>(halStream.producerUsage),
1627 static_cast<uint64_t>(halStream.consumerUsage)),
1628 halStream.overrideFormat, &buffer_handle);
1629 graphicBuffers.push_back(buffer_handle);
1630 outputBuffers[k] = {
1631 halStream.id, bufferId, ::android::makeToAidl(buffer_handle),
1632 BufferStatus::OK, NativeHandle(), NativeHandle()};
1633 bufferId++;
1634 }
1635 k++;
1636 }
1637
1638 std::vector<PhysicalCameraSetting> camSettings(1);
1639 const camera_metadata_t* filteredSettingsBuffer = filteredSettings.getAndLock();
1640 uint8_t* rawFilteredSettingsBuffer = (uint8_t*)filteredSettingsBuffer;
1641 camSettings[0].settings = {std::vector(
1642 rawFilteredSettingsBuffer,
1643 rawFilteredSettingsBuffer + get_camera_metadata_size(filteredSettingsBuffer))};
1644 overrideRotateAndCrop(&camSettings[0].settings);
1645 camSettings[0].fmqSettingsSize = 0;
1646 camSettings[0].physicalCameraId = physicalDeviceId;
1647
1648 request.inputBuffer = {
1649 -1, 0, NativeHandle(), BufferStatus::ERROR, NativeHandle(), NativeHandle()};
1650 request.physicalCameraSettings = camSettings;
1651
1652 {
1653 std::unique_lock<std::mutex> l(mLock);
1654 mInflightMap.clear();
1655 mInflightMap[frameNumber] = inflightReq;
1656 }
1657
1658 int32_t numRequestProcessed = 0;
1659 std::vector<BufferCache> cachesToRemove;
1660 ndk::ScopedAStatus returnStatus =
1661 mSession->processCaptureRequest(requests, cachesToRemove, &numRequestProcessed);
1662 ASSERT_TRUE(returnStatus.isOk());
1663 ASSERT_EQ(numRequestProcessed, 1u);
1664
1665 {
1666 std::unique_lock<std::mutex> l(mLock);
1667 while (!inflightReq->errorCodeValid &&
1668 ((0 < inflightReq->numBuffersLeft) || (!inflightReq->haveResultMetadata))) {
1669 auto timeout = std::chrono::system_clock::now() +
1670 std::chrono::seconds(kStreamBufferTimeoutSec);
1671 ASSERT_NE(std::cv_status::timeout, mResultCondition.wait_until(l, timeout));
1672 }
1673
1674 ASSERT_FALSE(inflightReq->errorCodeValid);
1675 ASSERT_NE(inflightReq->resultOutputBuffers.size(), 0u);
1676
1677 request.frameNumber++;
1678 // Empty settings should be supported after the first call
1679 // for repeating requests.
1680 request.settings.metadata.clear();
1681 request.physicalCameraSettings[0].settings.metadata.clear();
1682 // The buffer has been registered to HAL by bufferId, so per
1683 // API contract we should send a null handle for this buffer
1684 request.outputBuffers[0].buffer = NativeHandle();
1685 mInflightMap.clear();
1686 inflightReq = std::make_shared<InFlightRequest>(
1687 static_cast<ssize_t>(physicalIds.size()), false, supportsPartialResults,
1688 partialResultCount, physicalIds, resultQueue);
1689 mInflightMap[request.frameNumber] = inflightReq;
1690 }
1691
1692 returnStatus =
1693 mSession->processCaptureRequest(requests, cachesToRemove, &numRequestProcessed);
1694 ASSERT_TRUE(returnStatus.isOk());
1695 ASSERT_EQ(numRequestProcessed, 1u);
1696
1697 {
1698 std::unique_lock<std::mutex> l(mLock);
1699 while (!inflightReq->errorCodeValid &&
1700 ((0 < inflightReq->numBuffersLeft) || (!inflightReq->haveResultMetadata))) {
1701 auto timeout = std::chrono::system_clock::now() +
1702 std::chrono::seconds(kStreamBufferTimeoutSec);
1703 ASSERT_NE(std::cv_status::timeout, mResultCondition.wait_until(l, timeout));
1704 }
1705
1706 ASSERT_FALSE(inflightReq->errorCodeValid);
1707 ASSERT_NE(inflightReq->resultOutputBuffers.size(), 0u);
1708 }
1709
1710 // Invalid physical camera id should fail process requests
1711 frameNumber++;
1712 camSettings[0].physicalCameraId = invalidPhysicalId;
1713 camSettings[0].settings.metadata = settings;
1714
1715 request.physicalCameraSettings = camSettings; // Invalid camera settings
1716 returnStatus =
1717 mSession->processCaptureRequest(requests, cachesToRemove, &numRequestProcessed);
1718 ASSERT_EQ(static_cast<int32_t>(Status::ILLEGAL_ARGUMENT),
1719 returnStatus.getServiceSpecificError());
1720
1721 defaultPreviewSettings.unlock(settingsBuffer);
1722 filteredSettings.unlock(filteredSettingsBuffer);
1723
Jayant Chowdhary4869ae72023-12-18 05:36:14 +00001724 if (halBufManagedStreamIds.size() != 0) {
1725 std::vector<int32_t> streamIds;
1726 for (size_t i = 0; i < halStreams.size(); i++) {
1727 int32_t streamId = halStreams[i].id;
1728 if (halBufManagedStreamIds.find(streamId) != halBufManagedStreamIds.end()) {
1729 streamIds.emplace_back(streamId);
1730 }
Avichal Rakesh362242f2022-02-08 12:40:53 -08001731 }
1732 verifyBuffersReturned(mSession, streamIds, cb);
1733 }
1734
1735 ret = mSession->close();
1736 mSession = nullptr;
1737 ASSERT_TRUE(ret.isOk());
1738 }
1739}
1740
1741// Generate and verify an ultra high resolution capture request
1742TEST_P(CameraAidlTest, processUltraHighResolutionRequest) {
1743 std::vector<std::string> cameraDeviceNames = getCameraDeviceNames(mProvider);
1744 int64_t bufferId = 1;
1745 int32_t frameNumber = 1;
1746 CameraMetadata settings;
1747
1748 for (const auto& name : cameraDeviceNames) {
1749 std::string version, deviceId;
1750 ASSERT_TRUE(matchDeviceName(name, mProviderType, &version, &deviceId));
1751 CameraMetadata meta;
1752
1753 std::shared_ptr<ICameraDevice> unusedDevice;
1754 openEmptyDeviceSession(name, mProvider, &mSession, &meta, &unusedDevice);
1755 camera_metadata_t* staticMeta = reinterpret_cast<camera_metadata_t*>(meta.metadata.data());
1756 if (!isUltraHighResolution(staticMeta)) {
1757 ndk::ScopedAStatus ret = mSession->close();
1758 mSession = nullptr;
1759 ASSERT_TRUE(ret.isOk());
1760 continue;
1761 }
1762 CameraMetadata req;
1763 android::hardware::camera::common::V1_0::helper::CameraMetadata defaultSettings;
1764 ndk::ScopedAStatus ret =
1765 mSession->constructDefaultRequestSettings(RequestTemplate::STILL_CAPTURE, &req);
1766 ASSERT_TRUE(ret.isOk());
1767
1768 const camera_metadata_t* metadata =
1769 reinterpret_cast<const camera_metadata_t*>(req.metadata.data());
1770 size_t expectedSize = req.metadata.size();
1771 int result = validate_camera_metadata_structure(metadata, &expectedSize);
1772 ASSERT_TRUE((result == 0) || (result == CAMERA_METADATA_VALIDATION_SHIFTED));
1773
1774 size_t entryCount = get_camera_metadata_entry_count(metadata);
1775 ASSERT_GT(entryCount, 0u);
1776 defaultSettings = metadata;
1777 uint8_t sensorPixelMode =
1778 static_cast<uint8_t>(ANDROID_SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION);
1779 ASSERT_EQ(::android::OK,
1780 defaultSettings.update(ANDROID_SENSOR_PIXEL_MODE, &sensorPixelMode, 1));
1781
1782 const camera_metadata_t* settingsBuffer = defaultSettings.getAndLock();
1783 uint8_t* rawSettingsBuffer = (uint8_t*)settingsBuffer;
1784 settings.metadata = std::vector(
1785 rawSettingsBuffer, rawSettingsBuffer + get_camera_metadata_size(settingsBuffer));
1786 overrideRotateAndCrop(&settings);
1787
1788 ret = mSession->close();
1789 mSession = nullptr;
1790 ASSERT_TRUE(ret.isOk());
1791
1792 std::vector<HalStream> halStreams;
1793 bool supportsPartialResults = false;
Jayant Chowdhary4869ae72023-12-18 05:36:14 +00001794 std::set<int32_t> halBufManagedStreamIds;
Avichal Rakesh362242f2022-02-08 12:40:53 -08001795 int32_t partialResultCount = 0;
1796 Stream previewStream;
1797 std::shared_ptr<DeviceCb> cb;
1798
1799 std::list<PixelFormat> pixelFormats = {PixelFormat::YCBCR_420_888, PixelFormat::RAW16};
1800 for (PixelFormat format : pixelFormats) {
Emilian Peevdda1eb72022-07-28 16:37:40 -07001801 previewStream.usage =
1802 static_cast<aidl::android::hardware::graphics::common::BufferUsage>(
1803 GRALLOC1_CONSUMER_USAGE_CPU_READ);
1804 previewStream.dataSpace = Dataspace::UNKNOWN;
Avichal Rakesh362242f2022-02-08 12:40:53 -08001805 configureStreams(name, mProvider, format, &mSession, &previewStream, &halStreams,
Jayant Chowdhary4869ae72023-12-18 05:36:14 +00001806 &supportsPartialResults, &partialResultCount, &halBufManagedStreamIds,
1807 &cb, 0, /*maxResolution*/ true);
Avichal Rakesh362242f2022-02-08 12:40:53 -08001808 ASSERT_NE(mSession, nullptr);
1809
1810 ::aidl::android::hardware::common::fmq::MQDescriptor<
1811 int8_t, aidl::android::hardware::common::fmq::SynchronizedReadWrite>
1812 descriptor;
1813 auto resultQueueRet = mSession->getCaptureResultMetadataQueue(&descriptor);
1814 ASSERT_TRUE(resultQueueRet.isOk());
1815
1816 std::shared_ptr<ResultMetadataQueue> resultQueue =
1817 std::make_shared<ResultMetadataQueue>(descriptor);
1818 if (!resultQueue->isValid() || resultQueue->availableToWrite() <= 0) {
1819 ALOGE("%s: HAL returns empty result metadata fmq, not use it", __func__);
1820 resultQueue = nullptr;
1821 // Don't use the queue onwards.
1822 }
1823
1824 std::vector<buffer_handle_t> graphicBuffers;
1825 graphicBuffers.reserve(halStreams.size());
1826 std::shared_ptr<InFlightRequest> inflightReq = std::make_shared<InFlightRequest>(
1827 static_cast<ssize_t>(halStreams.size()), false, supportsPartialResults,
1828 partialResultCount, std::unordered_set<std::string>(), resultQueue);
1829
1830 std::vector<CaptureRequest> requests(1);
1831 CaptureRequest& request = requests[0];
1832 std::vector<StreamBuffer>& outputBuffers = request.outputBuffers;
1833 outputBuffers.resize(halStreams.size());
1834
1835 size_t k = 0;
1836 for (const auto& halStream : halStreams) {
1837 buffer_handle_t buffer_handle;
Jayant Chowdhary4869ae72023-12-18 05:36:14 +00001838 bool halBufManagerUsed =
1839 halBufManagedStreamIds.find(halStream.id) != halBufManagedStreamIds.end();
1840 if (halBufManagerUsed) {
Avichal Rakesh362242f2022-02-08 12:40:53 -08001841 outputBuffers[k] = {halStream.id, 0,
1842 NativeHandle(), BufferStatus::OK,
1843 NativeHandle(), NativeHandle()};
1844 } else {
1845 allocateGraphicBuffer(previewStream.width, previewStream.height,
1846 android_convertGralloc1To0Usage(
1847 static_cast<uint64_t>(halStream.producerUsage),
1848 static_cast<uint64_t>(halStream.consumerUsage)),
1849 halStream.overrideFormat, &buffer_handle);
1850 graphicBuffers.push_back(buffer_handle);
1851 outputBuffers[k] = {
1852 halStream.id, bufferId, ::android::makeToAidl(buffer_handle),
1853 BufferStatus::OK, NativeHandle(), NativeHandle()};
1854 bufferId++;
1855 }
1856 k++;
1857 }
1858
1859 request.inputBuffer = {
1860 -1, 0, NativeHandle(), BufferStatus::ERROR, NativeHandle(), NativeHandle()};
1861 request.frameNumber = frameNumber;
1862 request.fmqSettingsSize = 0;
1863 request.settings = settings;
1864 request.inputWidth = 0;
1865 request.inputHeight = 0;
1866
1867 {
1868 std::unique_lock<std::mutex> l(mLock);
1869 mInflightMap.clear();
1870 mInflightMap[frameNumber] = inflightReq;
1871 }
1872
1873 int32_t numRequestProcessed = 0;
1874 std::vector<BufferCache> cachesToRemove;
1875 ndk::ScopedAStatus returnStatus =
1876 mSession->processCaptureRequest(requests, cachesToRemove, &numRequestProcessed);
1877 ASSERT_TRUE(returnStatus.isOk());
1878 ASSERT_EQ(numRequestProcessed, 1u);
1879
1880 {
1881 std::unique_lock<std::mutex> l(mLock);
1882 while (!inflightReq->errorCodeValid &&
1883 ((0 < inflightReq->numBuffersLeft) || (!inflightReq->haveResultMetadata))) {
1884 auto timeout = std::chrono::system_clock::now() +
1885 std::chrono::seconds(kStreamBufferTimeoutSec);
1886 ASSERT_NE(std::cv_status::timeout, mResultCondition.wait_until(l, timeout));
1887 }
1888
1889 ASSERT_FALSE(inflightReq->errorCodeValid);
1890 ASSERT_NE(inflightReq->resultOutputBuffers.size(), 0u);
1891 }
Jayant Chowdhary4869ae72023-12-18 05:36:14 +00001892 if (halBufManagedStreamIds.size()) {
1893 std::vector<int32_t> streamIds;
1894 for (size_t i = 0; i < halStreams.size(); i++) {
1895 if (contains(halBufManagedStreamIds, halStreams[i].id)) {
1896 streamIds.emplace_back(halStreams[i].id);
1897 }
Avichal Rakesh362242f2022-02-08 12:40:53 -08001898 }
1899 verifyBuffersReturned(mSession, streamIds, cb);
1900 }
1901
1902 ret = mSession->close();
1903 mSession = nullptr;
1904 ASSERT_TRUE(ret.isOk());
1905 }
1906 }
1907}
1908
1909// Generate and verify 10-bit dynamic range request
1910TEST_P(CameraAidlTest, process10BitDynamicRangeRequest) {
1911 std::vector<std::string> cameraDeviceNames = getCameraDeviceNames(mProvider);
Avichal Rakesh362242f2022-02-08 12:40:53 -08001912 CameraMetadata settings;
1913
1914 for (const auto& name : cameraDeviceNames) {
1915 std::string version, deviceId;
1916 ASSERT_TRUE(matchDeviceName(name, mProviderType, &version, &deviceId));
1917 CameraMetadata meta;
1918 std::shared_ptr<ICameraDevice> device;
1919 openEmptyDeviceSession(name, mProvider, &mSession, &meta, &device);
1920 camera_metadata_t* staticMeta = reinterpret_cast<camera_metadata_t*>(meta.metadata.data());
1921 if (!is10BitDynamicRangeCapable(staticMeta)) {
1922 ndk::ScopedAStatus ret = mSession->close();
1923 mSession = nullptr;
1924 ASSERT_TRUE(ret.isOk());
1925 continue;
1926 }
Avichal Rakeshd3503a32022-02-25 06:23:14 +00001927 std::vector<RequestAvailableDynamicRangeProfilesMap> profileList;
Avichal Rakesh362242f2022-02-08 12:40:53 -08001928 get10BitDynamicRangeProfiles(staticMeta, &profileList);
1929 ASSERT_FALSE(profileList.empty());
1930
1931 CameraMetadata req;
1932 android::hardware::camera::common::V1_0::helper::CameraMetadata defaultSettings;
1933 ndk::ScopedAStatus ret =
Emilian Peevdda1eb72022-07-28 16:37:40 -07001934 mSession->constructDefaultRequestSettings(RequestTemplate::PREVIEW, &req);
Avichal Rakesh362242f2022-02-08 12:40:53 -08001935 ASSERT_TRUE(ret.isOk());
1936
1937 const camera_metadata_t* metadata =
1938 reinterpret_cast<const camera_metadata_t*>(req.metadata.data());
1939 size_t expectedSize = req.metadata.size();
1940 int result = validate_camera_metadata_structure(metadata, &expectedSize);
1941 ASSERT_TRUE((result == 0) || (result == CAMERA_METADATA_VALIDATION_SHIFTED));
1942
1943 size_t entryCount = get_camera_metadata_entry_count(metadata);
1944 ASSERT_GT(entryCount, 0u);
1945 defaultSettings = metadata;
1946
1947 const camera_metadata_t* settingsBuffer = defaultSettings.getAndLock();
1948 uint8_t* rawSettingsBuffer = (uint8_t*)settingsBuffer;
1949 settings.metadata = std::vector(
1950 rawSettingsBuffer, rawSettingsBuffer + get_camera_metadata_size(settingsBuffer));
1951 overrideRotateAndCrop(&settings);
1952
1953 ret = mSession->close();
1954 mSession = nullptr;
1955 ASSERT_TRUE(ret.isOk());
1956
1957 std::vector<HalStream> halStreams;
1958 bool supportsPartialResults = false;
Jayant Chowdhary4869ae72023-12-18 05:36:14 +00001959 std::set<int32_t> halBufManagedStreamIds;
Avichal Rakesh362242f2022-02-08 12:40:53 -08001960 int32_t partialResultCount = 0;
1961 Stream previewStream;
1962 std::shared_ptr<DeviceCb> cb;
1963 for (const auto& profile : profileList) {
Emilian Peevdda1eb72022-07-28 16:37:40 -07001964 previewStream.usage =
1965 static_cast<aidl::android::hardware::graphics::common::BufferUsage>(
1966 GRALLOC1_CONSUMER_USAGE_HWCOMPOSER);
1967 previewStream.dataSpace = getDataspace(PixelFormat::IMPLEMENTATION_DEFINED);
Avichal Rakesh362242f2022-02-08 12:40:53 -08001968 configureStreams(name, mProvider, PixelFormat::IMPLEMENTATION_DEFINED, &mSession,
1969 &previewStream, &halStreams, &supportsPartialResults,
Jayant Chowdhary4869ae72023-12-18 05:36:14 +00001970 &partialResultCount, &halBufManagedStreamIds, &cb, 0,
Avichal Rakesh362242f2022-02-08 12:40:53 -08001971 /*maxResolution*/ false, profile);
1972 ASSERT_NE(mSession, nullptr);
1973
1974 ::aidl::android::hardware::common::fmq::MQDescriptor<
1975 int8_t, aidl::android::hardware::common::fmq::SynchronizedReadWrite>
1976 descriptor;
1977 auto resultQueueRet = mSession->getCaptureResultMetadataQueue(&descriptor);
1978 ASSERT_TRUE(resultQueueRet.isOk());
1979
1980 std::shared_ptr<ResultMetadataQueue> resultQueue =
1981 std::make_shared<ResultMetadataQueue>(descriptor);
1982 if (!resultQueue->isValid() || resultQueue->availableToWrite() <= 0) {
1983 ALOGE("%s: HAL returns empty result metadata fmq, not use it", __func__);
1984 resultQueue = nullptr;
1985 // Don't use the queue onwards.
1986 }
1987
Emilian Peevdda1eb72022-07-28 16:37:40 -07001988 mInflightMap.clear();
1989 // Stream as long as needed to fill the Hal inflight queue
1990 std::vector<CaptureRequest> requests(halStreams[0].maxBuffers);
Avichal Rakesh362242f2022-02-08 12:40:53 -08001991
Emilian Peev470d1382023-01-18 11:09:09 -08001992 for (int32_t requestId = 0; requestId < requests.size(); requestId++) {
Emilian Peevdda1eb72022-07-28 16:37:40 -07001993 std::shared_ptr<InFlightRequest> inflightReq = std::make_shared<InFlightRequest>(
1994 static_cast<ssize_t>(halStreams.size()), false, supportsPartialResults,
1995 partialResultCount, std::unordered_set<std::string>(), resultQueue);
Avichal Rakesh362242f2022-02-08 12:40:53 -08001996
Emilian Peev470d1382023-01-18 11:09:09 -08001997 CaptureRequest& request = requests[requestId];
Emilian Peevdda1eb72022-07-28 16:37:40 -07001998 std::vector<StreamBuffer>& outputBuffers = request.outputBuffers;
1999 outputBuffers.resize(halStreams.size());
Avichal Rakesh362242f2022-02-08 12:40:53 -08002000
Emilian Peevdda1eb72022-07-28 16:37:40 -07002001 size_t k = 0;
2002 inflightReq->mOutstandingBufferIds.resize(halStreams.size());
2003 std::vector<buffer_handle_t> graphicBuffers;
2004 graphicBuffers.reserve(halStreams.size());
Avichal Rakesh362242f2022-02-08 12:40:53 -08002005
Emilian Peev470d1382023-01-18 11:09:09 -08002006 auto bufferId = requestId + 1; // Buffer id value 0 is not valid
Emilian Peevdda1eb72022-07-28 16:37:40 -07002007 for (const auto& halStream : halStreams) {
2008 buffer_handle_t buffer_handle;
Jayant Chowdhary4869ae72023-12-18 05:36:14 +00002009 if (contains(halBufManagedStreamIds, halStream.id)) {
Emilian Peevdda1eb72022-07-28 16:37:40 -07002010 outputBuffers[k] = {halStream.id, 0,
2011 NativeHandle(), BufferStatus::OK,
2012 NativeHandle(), NativeHandle()};
2013 } else {
2014 auto usage = android_convertGralloc1To0Usage(
2015 static_cast<uint64_t>(halStream.producerUsage),
2016 static_cast<uint64_t>(halStream.consumerUsage));
2017 allocateGraphicBuffer(previewStream.width, previewStream.height, usage,
2018 halStream.overrideFormat, &buffer_handle);
2019
2020 inflightReq->mOutstandingBufferIds[halStream.id][bufferId] = buffer_handle;
2021 graphicBuffers.push_back(buffer_handle);
2022 outputBuffers[k] = {halStream.id, bufferId,
2023 android::makeToAidl(buffer_handle), BufferStatus::OK, NativeHandle(),
2024 NativeHandle()};
Emilian Peevdda1eb72022-07-28 16:37:40 -07002025 }
2026 k++;
Avichal Rakesh362242f2022-02-08 12:40:53 -08002027 }
Avichal Rakesh362242f2022-02-08 12:40:53 -08002028
Emilian Peevdda1eb72022-07-28 16:37:40 -07002029 request.inputBuffer = {
2030 -1, 0, NativeHandle(), BufferStatus::ERROR, NativeHandle(), NativeHandle()};
Emilian Peev470d1382023-01-18 11:09:09 -08002031 request.frameNumber = bufferId;
Emilian Peevdda1eb72022-07-28 16:37:40 -07002032 request.fmqSettingsSize = 0;
2033 request.settings = settings;
2034 request.inputWidth = 0;
2035 request.inputHeight = 0;
Avichal Rakesh362242f2022-02-08 12:40:53 -08002036
Emilian Peevdda1eb72022-07-28 16:37:40 -07002037 {
2038 std::unique_lock<std::mutex> l(mLock);
Emilian Peev470d1382023-01-18 11:09:09 -08002039 mInflightMap[bufferId] = inflightReq;
Emilian Peevdda1eb72022-07-28 16:37:40 -07002040 }
2041
Avichal Rakesh362242f2022-02-08 12:40:53 -08002042 }
2043
2044 int32_t numRequestProcessed = 0;
2045 std::vector<BufferCache> cachesToRemove;
2046 ndk::ScopedAStatus returnStatus =
Emilian Peevdda1eb72022-07-28 16:37:40 -07002047 mSession->processCaptureRequest(requests, cachesToRemove, &numRequestProcessed);
Avichal Rakesh362242f2022-02-08 12:40:53 -08002048 ASSERT_TRUE(returnStatus.isOk());
Emilian Peevdda1eb72022-07-28 16:37:40 -07002049 ASSERT_EQ(numRequestProcessed, requests.size());
Avichal Rakesh362242f2022-02-08 12:40:53 -08002050
Emilian Peevdda1eb72022-07-28 16:37:40 -07002051 returnStatus = mSession->repeatingRequestEnd(requests.size() - 1,
2052 std::vector<int32_t> {halStreams[0].id});
2053 ASSERT_TRUE(returnStatus.isOk());
2054
Emilian Peev470d1382023-01-18 11:09:09 -08002055 // We are keeping frame numbers and buffer ids consistent. Buffer id value of 0
2056 // is used to indicate a buffer that is not present/available so buffer ids as well
2057 // as frame numbers begin with 1.
2058 for (int32_t frameNumber = 1; frameNumber <= requests.size(); frameNumber++) {
Emilian Peevdda1eb72022-07-28 16:37:40 -07002059 const auto& inflightReq = mInflightMap[frameNumber];
Avichal Rakesh362242f2022-02-08 12:40:53 -08002060 std::unique_lock<std::mutex> l(mLock);
2061 while (!inflightReq->errorCodeValid &&
2062 ((0 < inflightReq->numBuffersLeft) || (!inflightReq->haveResultMetadata))) {
2063 auto timeout = std::chrono::system_clock::now() +
2064 std::chrono::seconds(kStreamBufferTimeoutSec);
2065 ASSERT_NE(std::cv_status::timeout, mResultCondition.wait_until(l, timeout));
2066 }
2067
Shuzhen Wang0f56c562023-04-03 16:58:59 -07002068 waitForReleaseFence(inflightReq->resultOutputBuffers);
2069
Avichal Rakesh362242f2022-02-08 12:40:53 -08002070 ASSERT_FALSE(inflightReq->errorCodeValid);
2071 ASSERT_NE(inflightReq->resultOutputBuffers.size(), 0u);
2072 verify10BitMetadata(mHandleImporter, *inflightReq, profile);
2073 }
Emilian Peevdda1eb72022-07-28 16:37:40 -07002074
Jayant Chowdhary4869ae72023-12-18 05:36:14 +00002075 if (halBufManagedStreamIds.size() != 0) {
2076 std::vector<int32_t> streamIds;
2077 for (size_t i = 0; i < halStreams.size(); i++) {
2078 if (contains(halBufManagedStreamIds, halStreams[i].id)) {
2079 streamIds.emplace_back(halStreams[i].id);
2080 }
Avichal Rakesh362242f2022-02-08 12:40:53 -08002081 }
2082 mSession->signalStreamFlush(streamIds, /*streamConfigCounter*/ 0);
2083 cb->waitForBuffersReturned();
2084 }
2085
2086 ret = mSession->close();
2087 mSession = nullptr;
2088 ASSERT_TRUE(ret.isOk());
2089 }
2090 }
2091}
2092
Austin Borger4728fc42022-07-15 11:27:53 -07002093TEST_P(CameraAidlTest, process8BitColorSpaceRequests) {
Austin Borger54b22362023-03-22 11:25:06 -07002094 static int profiles[] = {ColorSpaceNamed::DISPLAY_P3, ColorSpaceNamed::SRGB};
Austin Borger4728fc42022-07-15 11:27:53 -07002095
2096 for (int32_t i = 0; i < sizeof(profiles) / sizeof(profiles[0]); i++) {
2097 processColorSpaceRequest(static_cast<RequestAvailableColorSpaceProfilesMap>(profiles[i]),
2098 static_cast<RequestAvailableDynamicRangeProfilesMap>(
2099 ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD));
2100 }
2101}
2102
2103TEST_P(CameraAidlTest, process10BitColorSpaceRequests) {
2104 static const camera_metadata_enum_android_request_available_dynamic_range_profiles_map
2105 dynamicRangeProfiles[] = {
2106 ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HLG10,
2107 ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10,
2108 ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10_PLUS,
2109 ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_REF,
2110 ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_REF_PO,
2111 ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_OEM,
2112 ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_OEM_PO,
2113 ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_REF,
2114 ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_REF_PO,
2115 ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_OEM,
2116 ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_OEM_PO
2117 };
2118
Austin Borger54b22362023-03-22 11:25:06 -07002119 // Process all dynamic range profiles with BT2020_HLG
Austin Borger4728fc42022-07-15 11:27:53 -07002120 for (int32_t i = 0; i < sizeof(dynamicRangeProfiles) / sizeof(dynamicRangeProfiles[0]); i++) {
2121 processColorSpaceRequest(
Austin Borger54b22362023-03-22 11:25:06 -07002122 static_cast<RequestAvailableColorSpaceProfilesMap>(ColorSpaceNamed::BT2020_HLG),
Austin Borger4728fc42022-07-15 11:27:53 -07002123 static_cast<RequestAvailableDynamicRangeProfilesMap>(dynamicRangeProfiles[i]));
2124 }
2125}
2126
Shuzhen Wang4dd6a512022-11-08 20:47:20 +00002127TEST_P(CameraAidlTest, processZoomSettingsOverrideRequests) {
2128 const int32_t kFrameCount = 5;
2129 const int32_t kTestCases = 2;
Shuzhen Wang38ddb272023-05-22 09:40:28 -07002130 const bool kOverrideSequence[kTestCases][kFrameCount] = {// ZOOM, ZOOM, ZOOM, ZOOM, ZOOM;
2131 {true, true, true, true, true},
2132 // OFF, ZOOM, ZOOM, ZOOM, OFF;
2133 {false, true, true, true, false}};
Shuzhen Wang4dd6a512022-11-08 20:47:20 +00002134 const bool kExpectedOverrideResults[kTestCases][kFrameCount] = {
Shuzhen Wang38ddb272023-05-22 09:40:28 -07002135 // All resuls should be overridden except the last one. The last result's
2136 // zoom doesn't have speed-up.
2137 {true, true, true, true, false},
2138 // Because we require at least 1 frame speed-up, request #1, #2 and #3
2139 // will be overridden.
2140 {true, true, true, false, false}};
Shuzhen Wang4dd6a512022-11-08 20:47:20 +00002141
2142 for (int i = 0; i < kTestCases; i++) {
2143 processZoomSettingsOverrideRequests(kFrameCount, kOverrideSequence[i],
2144 kExpectedOverrideResults[i]);
2145 }
2146}
2147
Avichal Rakesh362242f2022-02-08 12:40:53 -08002148// Generate and verify a burst containing alternating sensor sensitivity values
2149TEST_P(CameraAidlTest, processCaptureRequestBurstISO) {
2150 std::vector<std::string> cameraDeviceNames = getCameraDeviceNames(mProvider);
2151 AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
2152 static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
2153 int64_t bufferId = 1;
2154 int32_t frameNumber = 1;
2155 float isoTol = .03f;
2156 CameraMetadata settings;
2157
2158 for (const auto& name : cameraDeviceNames) {
2159 CameraMetadata meta;
2160 settings.metadata.clear();
2161 std::shared_ptr<ICameraDevice> unusedDevice;
2162 openEmptyDeviceSession(name, mProvider, &mSession /*out*/, &meta /*out*/,
2163 &unusedDevice /*out*/);
2164 camera_metadata_t* staticMetaBuffer =
2165 clone_camera_metadata(reinterpret_cast<camera_metadata_t*>(meta.metadata.data()));
2166 ::android::hardware::camera::common::V1_0::helper::CameraMetadata staticMeta(
2167 staticMetaBuffer);
2168
2169 camera_metadata_entry_t hwLevel = staticMeta.find(ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL);
2170 ASSERT_TRUE(0 < hwLevel.count);
2171 if (ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED == hwLevel.data.u8[0] ||
2172 ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_EXTERNAL == hwLevel.data.u8[0]) {
2173 // Limited/External devices can skip this test
2174 ndk::ScopedAStatus ret = mSession->close();
2175 mSession = nullptr;
2176 ASSERT_TRUE(ret.isOk());
2177 continue;
2178 }
2179
2180 camera_metadata_entry_t isoRange = staticMeta.find(ANDROID_SENSOR_INFO_SENSITIVITY_RANGE);
2181 ASSERT_EQ(isoRange.count, 2u);
2182
2183 ndk::ScopedAStatus ret = mSession->close();
2184 mSession = nullptr;
2185 ASSERT_TRUE(ret.isOk());
2186
2187 bool supportsPartialResults = false;
2188 bool useHalBufManager = false;
2189 int32_t partialResultCount = 0;
2190 Stream previewStream;
2191 std::vector<HalStream> halStreams;
2192 std::shared_ptr<DeviceCb> cb;
2193 configurePreviewStream(name, mProvider, &previewThreshold, &mSession /*out*/,
2194 &previewStream /*out*/, &halStreams /*out*/,
2195 &supportsPartialResults /*out*/, &partialResultCount /*out*/,
2196 &useHalBufManager /*out*/, &cb /*out*/);
2197
2198 ::aidl::android::hardware::common::fmq::MQDescriptor<
2199 int8_t, aidl::android::hardware::common::fmq::SynchronizedReadWrite>
2200 descriptor;
2201 auto resultQueueRet = mSession->getCaptureResultMetadataQueue(&descriptor);
2202 std::shared_ptr<ResultMetadataQueue> resultQueue =
2203 std::make_shared<ResultMetadataQueue>(descriptor);
2204 ASSERT_TRUE(resultQueueRet.isOk());
2205 if (!resultQueue->isValid() || resultQueue->availableToWrite() <= 0) {
2206 ALOGE("%s: HAL returns empty result metadata fmq, not use it", __func__);
2207 resultQueue = nullptr;
2208 // Don't use the queue onwards.
2209 }
2210
2211 ret = mSession->constructDefaultRequestSettings(RequestTemplate::PREVIEW, &settings);
2212 ASSERT_TRUE(ret.isOk());
2213
2214 ::android::hardware::camera::common::V1_0::helper::CameraMetadata requestMeta;
2215 std::vector<CaptureRequest> requests(kBurstFrameCount);
2216 std::vector<buffer_handle_t> buffers(kBurstFrameCount);
2217 std::vector<std::shared_ptr<InFlightRequest>> inflightReqs(kBurstFrameCount);
2218 std::vector<int32_t> isoValues(kBurstFrameCount);
2219 std::vector<CameraMetadata> requestSettings(kBurstFrameCount);
2220
2221 for (int32_t i = 0; i < kBurstFrameCount; i++) {
2222 std::unique_lock<std::mutex> l(mLock);
2223 CaptureRequest& request = requests[i];
2224 std::vector<StreamBuffer>& outputBuffers = request.outputBuffers;
2225 outputBuffers.resize(1);
2226 StreamBuffer& outputBuffer = outputBuffers[0];
2227
2228 isoValues[i] = ((i % 2) == 0) ? isoRange.data.i32[0] : isoRange.data.i32[1];
2229 if (useHalBufManager) {
2230 outputBuffer = {halStreams[0].id, 0,
2231 NativeHandle(), BufferStatus::OK,
2232 NativeHandle(), NativeHandle()};
2233 } else {
2234 allocateGraphicBuffer(previewStream.width, previewStream.height,
2235 android_convertGralloc1To0Usage(
2236 static_cast<uint64_t>(halStreams[0].producerUsage),
2237 static_cast<uint64_t>(halStreams[0].consumerUsage)),
2238 halStreams[0].overrideFormat, &buffers[i]);
2239 outputBuffer = {halStreams[0].id, bufferId + i, ::android::makeToAidl(buffers[i]),
2240 BufferStatus::OK, NativeHandle(), NativeHandle()};
2241 }
2242
2243 requestMeta.append(reinterpret_cast<camera_metadata_t*>(settings.metadata.data()));
2244
2245 // Disable all 3A routines
2246 uint8_t mode = static_cast<uint8_t>(ANDROID_CONTROL_MODE_OFF);
2247 ASSERT_EQ(::android::OK, requestMeta.update(ANDROID_CONTROL_MODE, &mode, 1));
2248 ASSERT_EQ(::android::OK,
2249 requestMeta.update(ANDROID_SENSOR_SENSITIVITY, &isoValues[i], 1));
2250 camera_metadata_t* metaBuffer = requestMeta.release();
2251 uint8_t* rawMetaBuffer = reinterpret_cast<uint8_t*>(metaBuffer);
2252 requestSettings[i].metadata = std::vector(
2253 rawMetaBuffer, rawMetaBuffer + get_camera_metadata_size(metaBuffer));
2254 overrideRotateAndCrop(&(requestSettings[i]));
2255
2256 request.frameNumber = frameNumber + i;
2257 request.fmqSettingsSize = 0;
2258 request.settings = requestSettings[i];
2259 request.inputBuffer = {
2260 -1, 0, NativeHandle(), BufferStatus::ERROR, NativeHandle(), NativeHandle()};
2261
2262 inflightReqs[i] = std::make_shared<InFlightRequest>(1, false, supportsPartialResults,
2263 partialResultCount, resultQueue);
2264 mInflightMap[frameNumber + i] = inflightReqs[i];
2265 }
2266
2267 int32_t numRequestProcessed = 0;
2268 std::vector<BufferCache> cachesToRemove;
2269
2270 ndk::ScopedAStatus returnStatus =
2271 mSession->processCaptureRequest(requests, cachesToRemove, &numRequestProcessed);
2272 ASSERT_TRUE(returnStatus.isOk());
2273 ASSERT_EQ(numRequestProcessed, kBurstFrameCount);
2274
2275 for (size_t i = 0; i < kBurstFrameCount; i++) {
2276 std::unique_lock<std::mutex> l(mLock);
2277 while (!inflightReqs[i]->errorCodeValid && ((0 < inflightReqs[i]->numBuffersLeft) ||
2278 (!inflightReqs[i]->haveResultMetadata))) {
2279 auto timeout = std::chrono::system_clock::now() +
2280 std::chrono::seconds(kStreamBufferTimeoutSec);
2281 ASSERT_NE(std::cv_status::timeout, mResultCondition.wait_until(l, timeout));
2282 }
2283
2284 ASSERT_FALSE(inflightReqs[i]->errorCodeValid);
2285 ASSERT_NE(inflightReqs[i]->resultOutputBuffers.size(), 0u);
2286 ASSERT_EQ(previewStream.id, inflightReqs[i]->resultOutputBuffers[0].buffer.streamId);
2287 ASSERT_FALSE(inflightReqs[i]->collectedResult.isEmpty());
2288 ASSERT_TRUE(inflightReqs[i]->collectedResult.exists(ANDROID_SENSOR_SENSITIVITY));
2289 camera_metadata_entry_t isoResult =
2290 inflightReqs[i]->collectedResult.find(ANDROID_SENSOR_SENSITIVITY);
2291 ASSERT_TRUE(std::abs(isoResult.data.i32[0] - isoValues[i]) <=
2292 std::round(isoValues[i] * isoTol));
2293 }
2294
2295 if (useHalBufManager) {
2296 verifyBuffersReturned(mSession, previewStream.id, cb);
2297 }
2298 ret = mSession->close();
2299 mSession = nullptr;
2300 ASSERT_TRUE(ret.isOk());
2301 }
2302}
2303
2304// Test whether an incorrect capture request with missing settings will
2305// be reported correctly.
2306TEST_P(CameraAidlTest, processCaptureRequestInvalidSinglePreview) {
2307 std::vector<std::string> cameraDeviceNames = getCameraDeviceNames(mProvider);
2308 std::vector<AvailableStream> outputPreviewStreams;
2309 AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
2310 static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
2311 int64_t bufferId = 1;
2312 int32_t frameNumber = 1;
2313 CameraMetadata settings;
2314
2315 for (const auto& name : cameraDeviceNames) {
2316 Stream previewStream;
2317 std::vector<HalStream> halStreams;
2318 std::shared_ptr<DeviceCb> cb;
2319 bool supportsPartialResults = false;
2320 bool useHalBufManager = false;
2321 int32_t partialResultCount = 0;
2322 configurePreviewStream(name, mProvider, &previewThreshold, &mSession /*out*/,
2323 &previewStream /*out*/, &halStreams /*out*/,
2324 &supportsPartialResults /*out*/, &partialResultCount /*out*/,
2325 &useHalBufManager /*out*/, &cb /*out*/);
2326 ASSERT_NE(mSession, nullptr);
2327 ASSERT_FALSE(halStreams.empty());
2328
2329 buffer_handle_t buffer_handle = nullptr;
2330
2331 if (useHalBufManager) {
2332 bufferId = 0;
2333 } else {
2334 allocateGraphicBuffer(previewStream.width, previewStream.height,
2335 android_convertGralloc1To0Usage(
2336 static_cast<uint64_t>(halStreams[0].producerUsage),
2337 static_cast<uint64_t>(halStreams[0].consumerUsage)),
2338 halStreams[0].overrideFormat, &buffer_handle);
2339 }
2340
2341 std::vector<CaptureRequest> requests(1);
2342 CaptureRequest& request = requests[0];
2343 std::vector<StreamBuffer>& outputBuffers = request.outputBuffers;
2344 outputBuffers.resize(1);
2345 StreamBuffer& outputBuffer = outputBuffers[0];
2346
2347 outputBuffer = {
2348 halStreams[0].id,
2349 bufferId,
2350 buffer_handle == nullptr ? NativeHandle() : ::android::makeToAidl(buffer_handle),
2351 BufferStatus::OK,
2352 NativeHandle(),
2353 NativeHandle()};
2354
2355 request.inputBuffer = {
2356 -1, 0, NativeHandle(), BufferStatus::ERROR, NativeHandle(), NativeHandle()};
2357 request.frameNumber = frameNumber;
2358 request.fmqSettingsSize = 0;
2359 request.settings = settings;
2360
2361 // Settings were not correctly initialized, we should fail here
2362 int32_t numRequestProcessed = 0;
2363 std::vector<BufferCache> cachesToRemove;
2364 ndk::ScopedAStatus ret =
2365 mSession->processCaptureRequest(requests, cachesToRemove, &numRequestProcessed);
2366 ASSERT_EQ(static_cast<int32_t>(Status::ILLEGAL_ARGUMENT), ret.getServiceSpecificError());
2367 ASSERT_EQ(numRequestProcessed, 0u);
2368
2369 ret = mSession->close();
2370 mSession = nullptr;
2371 ASSERT_TRUE(ret.isOk());
2372 }
2373}
2374
2375// Verify camera offline session behavior
2376TEST_P(CameraAidlTest, switchToOffline) {
2377 std::vector<std::string> cameraDeviceNames = getCameraDeviceNames(mProvider);
2378 AvailableStream threshold = {kMaxStillWidth, kMaxStillHeight,
2379 static_cast<int32_t>(PixelFormat::BLOB)};
2380 int64_t bufferId = 1;
2381 int32_t frameNumber = 1;
2382 CameraMetadata settings;
2383
2384 for (const auto& name : cameraDeviceNames) {
2385 CameraMetadata meta;
2386 {
2387 std::shared_ptr<ICameraDevice> unusedDevice;
2388 openEmptyDeviceSession(name, mProvider, &mSession /*out*/, &meta /*out*/,
2389 &unusedDevice);
2390 camera_metadata_t* staticMetaBuffer = clone_camera_metadata(
2391 reinterpret_cast<camera_metadata_t*>(meta.metadata.data()));
2392 ::android::hardware::camera::common::V1_0::helper::CameraMetadata staticMeta(
2393 staticMetaBuffer);
2394
2395 if (isOfflineSessionSupported(staticMetaBuffer) != Status::OK) {
2396 ndk::ScopedAStatus ret = mSession->close();
2397 mSession = nullptr;
2398 ASSERT_TRUE(ret.isOk());
2399 continue;
2400 }
2401 ndk::ScopedAStatus ret = mSession->close();
2402 mSession = nullptr;
2403 ASSERT_TRUE(ret.isOk());
2404 }
2405
2406 bool supportsPartialResults = false;
2407 int32_t partialResultCount = 0;
2408 Stream stream;
2409 std::vector<HalStream> halStreams;
2410 std::shared_ptr<DeviceCb> cb;
2411 int32_t jpegBufferSize;
Jayant Chowdhary4869ae72023-12-18 05:36:14 +00002412 std::set<int32_t> halBufManagedStreamIds;
Avichal Rakesh362242f2022-02-08 12:40:53 -08002413 configureOfflineStillStream(name, mProvider, &threshold, &mSession /*out*/, &stream /*out*/,
2414 &halStreams /*out*/, &supportsPartialResults /*out*/,
2415 &partialResultCount /*out*/, &cb /*out*/,
Jayant Chowdhary4869ae72023-12-18 05:36:14 +00002416 &jpegBufferSize /*out*/, &halBufManagedStreamIds /*out*/);
Avichal Rakesh362242f2022-02-08 12:40:53 -08002417
2418 auto ret = mSession->constructDefaultRequestSettings(RequestTemplate::STILL_CAPTURE,
2419 &settings);
2420 ASSERT_TRUE(ret.isOk());
2421
2422 ::aidl::android::hardware::common::fmq::MQDescriptor<
2423 int8_t, aidl::android::hardware::common::fmq::SynchronizedReadWrite>
2424 descriptor;
2425
2426 ndk::ScopedAStatus resultQueueRet = mSession->getCaptureResultMetadataQueue(&descriptor);
2427 ASSERT_TRUE(resultQueueRet.isOk());
2428 std::shared_ptr<ResultMetadataQueue> resultQueue =
2429 std::make_shared<ResultMetadataQueue>(descriptor);
2430 if (!resultQueue->isValid() || resultQueue->availableToWrite() <= 0) {
2431 ALOGE("%s: HAL returns empty result metadata fmq, not use it", __func__);
2432 resultQueue = nullptr;
2433 // Don't use the queue onwards.
2434 }
2435
2436 ::android::hardware::camera::common::V1_0::helper::CameraMetadata requestMeta;
2437
2438 std::vector<buffer_handle_t> buffers(kBurstFrameCount);
2439 std::vector<std::shared_ptr<InFlightRequest>> inflightReqs(kBurstFrameCount);
2440 std::vector<CameraMetadata> requestSettings(kBurstFrameCount);
2441
2442 std::vector<CaptureRequest> requests(kBurstFrameCount);
2443
2444 HalStream halStream = halStreams[0];
2445 for (uint32_t i = 0; i < kBurstFrameCount; i++) {
2446 CaptureRequest& request = requests[i];
2447 std::vector<StreamBuffer>& outputBuffers = request.outputBuffers;
2448 outputBuffers.resize(1);
2449 StreamBuffer& outputBuffer = outputBuffers[0];
2450
2451 std::unique_lock<std::mutex> l(mLock);
Jayant Chowdhary4869ae72023-12-18 05:36:14 +00002452 if (contains(halBufManagedStreamIds, halStream.id)) {
Avichal Rakesh362242f2022-02-08 12:40:53 -08002453 outputBuffer = {halStream.id, 0, NativeHandle(), BufferStatus::OK, NativeHandle(),
2454 NativeHandle()};
2455 } else {
2456 // jpeg buffer (w,h) = (blobLen, 1)
2457 allocateGraphicBuffer(jpegBufferSize, /*height*/ 1,
2458 android_convertGralloc1To0Usage(
2459 static_cast<uint64_t>(halStream.producerUsage),
2460 static_cast<uint64_t>(halStream.consumerUsage)),
2461 halStream.overrideFormat, &buffers[i]);
2462 outputBuffer = {halStream.id, bufferId + i, ::android::makeToAidl(buffers[i]),
2463 BufferStatus::OK, NativeHandle(), NativeHandle()};
2464 }
2465
2466 requestMeta.clear();
2467 requestMeta.append(reinterpret_cast<camera_metadata_t*>(settings.metadata.data()));
2468
2469 camera_metadata_t* metaBuffer = requestMeta.release();
2470 uint8_t* rawMetaBuffer = reinterpret_cast<uint8_t*>(metaBuffer);
2471 requestSettings[i].metadata = std::vector(
2472 rawMetaBuffer, rawMetaBuffer + get_camera_metadata_size(metaBuffer));
2473 overrideRotateAndCrop(&requestSettings[i]);
2474
2475 request.frameNumber = frameNumber + i;
2476 request.fmqSettingsSize = 0;
2477 request.settings = requestSettings[i];
2478 request.inputBuffer = {/*streamId*/ -1,
2479 /*bufferId*/ 0, NativeHandle(),
2480 BufferStatus::ERROR, NativeHandle(),
2481 NativeHandle()};
2482
2483 inflightReqs[i] = std::make_shared<InFlightRequest>(1, false, supportsPartialResults,
2484 partialResultCount, resultQueue);
2485 mInflightMap[frameNumber + i] = inflightReqs[i];
2486 }
2487
2488 int32_t numRequestProcessed = 0;
2489 std::vector<BufferCache> cachesToRemove;
2490
2491 ndk::ScopedAStatus returnStatus =
2492 mSession->processCaptureRequest(requests, cachesToRemove, &numRequestProcessed);
2493 ASSERT_TRUE(returnStatus.isOk());
2494 ASSERT_EQ(numRequestProcessed, kBurstFrameCount);
2495
2496 std::vector<int32_t> offlineStreamIds = {halStream.id};
2497 CameraOfflineSessionInfo offlineSessionInfo;
2498 std::shared_ptr<ICameraOfflineSession> offlineSession;
2499 returnStatus =
2500 mSession->switchToOffline(offlineStreamIds, &offlineSessionInfo, &offlineSession);
2501
2502 if (!halStreams[0].supportOffline) {
2503 ASSERT_EQ(static_cast<int32_t>(Status::ILLEGAL_ARGUMENT),
2504 returnStatus.getServiceSpecificError());
2505 ret = mSession->close();
2506 mSession = nullptr;
2507 ASSERT_TRUE(ret.isOk());
2508 continue;
2509 }
2510
2511 ASSERT_TRUE(returnStatus.isOk());
2512 // Hal might be unable to find any requests qualified for offline mode.
2513 if (offlineSession == nullptr) {
2514 ret = mSession->close();
2515 mSession = nullptr;
2516 ASSERT_TRUE(ret.isOk());
2517 continue;
2518 }
2519
2520 ASSERT_EQ(offlineSessionInfo.offlineStreams.size(), 1u);
2521 ASSERT_EQ(offlineSessionInfo.offlineStreams[0].id, halStream.id);
2522 ASSERT_NE(offlineSessionInfo.offlineRequests.size(), 0u);
2523
2524 // close device session to make sure offline session does not rely on it
2525 ret = mSession->close();
2526 mSession = nullptr;
2527 ASSERT_TRUE(ret.isOk());
2528
2529 ::aidl::android::hardware::common::fmq::MQDescriptor<
2530 int8_t, aidl::android::hardware::common::fmq::SynchronizedReadWrite>
2531 offlineResultDescriptor;
2532
2533 auto offlineResultQueueRet =
2534 offlineSession->getCaptureResultMetadataQueue(&offlineResultDescriptor);
2535 std::shared_ptr<ResultMetadataQueue> offlineResultQueue =
2536 std::make_shared<ResultMetadataQueue>(descriptor);
2537 if (!offlineResultQueue->isValid() || offlineResultQueue->availableToWrite() <= 0) {
2538 ALOGE("%s: offline session returns empty result metadata fmq, not use it", __func__);
2539 offlineResultQueue = nullptr;
2540 // Don't use the queue onwards.
2541 }
2542 ASSERT_TRUE(offlineResultQueueRet.isOk());
2543
2544 updateInflightResultQueue(offlineResultQueue);
2545
2546 ret = offlineSession->setCallback(cb);
2547 ASSERT_TRUE(ret.isOk());
2548
2549 for (size_t i = 0; i < kBurstFrameCount; i++) {
2550 std::unique_lock<std::mutex> l(mLock);
2551 while (!inflightReqs[i]->errorCodeValid && ((0 < inflightReqs[i]->numBuffersLeft) ||
2552 (!inflightReqs[i]->haveResultMetadata))) {
2553 auto timeout = std::chrono::system_clock::now() +
2554 std::chrono::seconds(kStreamBufferTimeoutSec);
2555 ASSERT_NE(std::cv_status::timeout, mResultCondition.wait_until(l, timeout));
2556 }
2557
2558 ASSERT_FALSE(inflightReqs[i]->errorCodeValid);
2559 ASSERT_NE(inflightReqs[i]->resultOutputBuffers.size(), 0u);
2560 ASSERT_EQ(stream.id, inflightReqs[i]->resultOutputBuffers[0].buffer.streamId);
2561 ASSERT_FALSE(inflightReqs[i]->collectedResult.isEmpty());
2562 }
2563
2564 ret = offlineSession->close();
2565 ASSERT_TRUE(ret.isOk());
2566 }
2567}
2568
2569// Check whether an invalid capture request with missing output buffers
2570// will be reported correctly.
2571TEST_P(CameraAidlTest, processCaptureRequestInvalidBuffer) {
2572 std::vector<std::string> cameraDeviceNames = getCameraDeviceNames(mProvider);
2573 std::vector<AvailableStream> outputBlobStreams;
2574 AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
2575 static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
2576 int32_t frameNumber = 1;
2577 CameraMetadata settings;
2578
2579 for (const auto& name : cameraDeviceNames) {
2580 Stream previewStream;
2581 std::vector<HalStream> halStreams;
2582 std::shared_ptr<DeviceCb> cb;
2583 bool supportsPartialResults = false;
2584 bool useHalBufManager = false;
2585 int32_t partialResultCount = 0;
2586 configurePreviewStream(name, mProvider, &previewThreshold, &mSession /*out*/,
2587 &previewStream /*out*/, &halStreams /*out*/,
2588 &supportsPartialResults /*out*/, &partialResultCount /*out*/,
2589 &useHalBufManager /*out*/, &cb /*out*/);
2590
2591 RequestTemplate reqTemplate = RequestTemplate::PREVIEW;
2592 ndk::ScopedAStatus ret = mSession->constructDefaultRequestSettings(reqTemplate, &settings);
2593 ASSERT_TRUE(ret.isOk());
2594 overrideRotateAndCrop(&settings);
2595
2596 std::vector<CaptureRequest> requests(1);
2597 CaptureRequest& request = requests[0];
2598 std::vector<StreamBuffer>& outputBuffers = request.outputBuffers;
2599 outputBuffers.resize(1);
2600 // Empty output buffer
2601 outputBuffers[0] = {
2602 -1, 0, NativeHandle(), BufferStatus::ERROR, NativeHandle(), NativeHandle()};
2603
2604 request.inputBuffer = {
2605 -1, 0, NativeHandle(), BufferStatus::ERROR, NativeHandle(), NativeHandle()};
2606 request.frameNumber = frameNumber;
2607 request.fmqSettingsSize = 0;
2608 request.settings = settings;
2609
2610 // Output buffers are missing, we should fail here
2611 int32_t numRequestProcessed = 0;
2612 std::vector<BufferCache> cachesToRemove;
2613 ret = mSession->processCaptureRequest(requests, cachesToRemove, &numRequestProcessed);
2614 ASSERT_EQ(static_cast<int32_t>(Status::ILLEGAL_ARGUMENT), ret.getServiceSpecificError());
2615 ASSERT_EQ(numRequestProcessed, 0u);
2616
2617 ret = mSession->close();
2618 mSession = nullptr;
2619 ASSERT_TRUE(ret.isOk());
2620 }
2621}
2622
2623// Generate, trigger and flush a preview request
2624TEST_P(CameraAidlTest, flushPreviewRequest) {
2625 std::vector<std::string> cameraDeviceNames = getCameraDeviceNames(mProvider);
2626 std::vector<AvailableStream> outputPreviewStreams;
2627 AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
2628 static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
2629 int64_t bufferId = 1;
2630 int32_t frameNumber = 1;
2631 CameraMetadata settings;
2632
2633 for (const auto& name : cameraDeviceNames) {
2634 Stream previewStream;
2635 std::vector<HalStream> halStreams;
2636 std::shared_ptr<DeviceCb> cb;
2637 bool supportsPartialResults = false;
2638 bool useHalBufManager = false;
2639 int32_t partialResultCount = 0;
2640
2641 configurePreviewStream(name, mProvider, &previewThreshold, &mSession /*out*/,
2642 &previewStream /*out*/, &halStreams /*out*/,
2643 &supportsPartialResults /*out*/, &partialResultCount /*out*/,
2644 &useHalBufManager /*out*/, &cb /*out*/);
2645
2646 ASSERT_NE(mSession, nullptr);
2647 ASSERT_NE(cb, nullptr);
2648 ASSERT_FALSE(halStreams.empty());
2649
2650 ::aidl::android::hardware::common::fmq::MQDescriptor<
2651 int8_t, aidl::android::hardware::common::fmq::SynchronizedReadWrite>
2652 descriptor;
2653
2654 auto resultQueueRet = mSession->getCaptureResultMetadataQueue(&descriptor);
2655 std::shared_ptr<ResultMetadataQueue> resultQueue =
2656 std::make_shared<ResultMetadataQueue>(descriptor);
2657 ASSERT_TRUE(resultQueueRet.isOk());
2658 if (!resultQueue->isValid() || resultQueue->availableToWrite() <= 0) {
2659 ALOGE("%s: HAL returns empty result metadata fmq, not use it", __func__);
2660 resultQueue = nullptr;
2661 // Don't use the queue onwards.
2662 }
2663
2664 std::shared_ptr<InFlightRequest> inflightReq = std::make_shared<InFlightRequest>(
2665 1, false, supportsPartialResults, partialResultCount, resultQueue);
2666 RequestTemplate reqTemplate = RequestTemplate::PREVIEW;
2667
2668 ndk::ScopedAStatus ret = mSession->constructDefaultRequestSettings(reqTemplate, &settings);
2669 ASSERT_TRUE(ret.isOk());
2670 overrideRotateAndCrop(&settings);
2671
2672 buffer_handle_t buffer_handle;
2673 std::vector<CaptureRequest> requests(1);
2674 CaptureRequest& request = requests[0];
2675 std::vector<StreamBuffer>& outputBuffers = request.outputBuffers;
2676 outputBuffers.resize(1);
2677 StreamBuffer& outputBuffer = outputBuffers[0];
2678 if (useHalBufManager) {
2679 bufferId = 0;
2680 outputBuffer = {halStreams[0].id, bufferId, NativeHandle(),
2681 BufferStatus::OK, NativeHandle(), NativeHandle()};
2682 } else {
2683 allocateGraphicBuffer(previewStream.width, previewStream.height,
2684 android_convertGralloc1To0Usage(
2685 static_cast<uint64_t>(halStreams[0].producerUsage),
2686 static_cast<uint64_t>(halStreams[0].consumerUsage)),
2687 halStreams[0].overrideFormat, &buffer_handle);
2688 outputBuffer = {halStreams[0].id, bufferId, ::android::makeToAidl(buffer_handle),
2689 BufferStatus::OK, NativeHandle(), NativeHandle()};
2690 }
2691
2692 request.frameNumber = frameNumber;
2693 request.fmqSettingsSize = 0;
2694 request.settings = settings;
2695 request.inputBuffer = {
2696 -1, 0, NativeHandle(), BufferStatus::ERROR, NativeHandle(), NativeHandle()};
2697
2698 {
2699 std::unique_lock<std::mutex> l(mLock);
2700 mInflightMap.clear();
2701 mInflightMap[frameNumber] = inflightReq;
2702 }
2703
2704 int32_t numRequestProcessed = 0;
2705 std::vector<BufferCache> cachesToRemove;
2706 ret = mSession->processCaptureRequest(requests, cachesToRemove, &numRequestProcessed);
2707 ASSERT_TRUE(ret.isOk());
2708 ASSERT_EQ(numRequestProcessed, 1u);
2709
2710 // Flush before waiting for request to complete.
2711 ndk::ScopedAStatus returnStatus = mSession->flush();
2712 ASSERT_TRUE(returnStatus.isOk());
2713
2714 {
2715 std::unique_lock<std::mutex> l(mLock);
2716 while (!inflightReq->errorCodeValid &&
2717 ((0 < inflightReq->numBuffersLeft) || (!inflightReq->haveResultMetadata))) {
2718 auto timeout = std::chrono::system_clock::now() +
2719 std::chrono::seconds(kStreamBufferTimeoutSec);
2720 ASSERT_NE(std::cv_status::timeout, mResultCondition.wait_until(l, timeout));
2721 }
2722
2723 if (!inflightReq->errorCodeValid) {
2724 ASSERT_NE(inflightReq->resultOutputBuffers.size(), 0u);
2725 ASSERT_EQ(previewStream.id, inflightReq->resultOutputBuffers[0].buffer.streamId);
2726 } else {
2727 switch (inflightReq->errorCode) {
2728 case ErrorCode::ERROR_REQUEST:
2729 case ErrorCode::ERROR_RESULT:
2730 case ErrorCode::ERROR_BUFFER:
2731 // Expected
2732 break;
2733 case ErrorCode::ERROR_DEVICE:
2734 default:
2735 FAIL() << "Unexpected error:"
2736 << static_cast<uint32_t>(inflightReq->errorCode);
2737 }
2738 }
2739 }
2740
2741 if (useHalBufManager) {
2742 verifyBuffersReturned(mSession, previewStream.id, cb);
2743 }
2744
2745 ret = mSession->close();
2746 mSession = nullptr;
2747 ASSERT_TRUE(ret.isOk());
2748 }
2749}
2750
2751// Verify that camera flushes correctly without any pending requests.
2752TEST_P(CameraAidlTest, flushEmpty) {
2753 std::vector<std::string> cameraDeviceNames = getCameraDeviceNames(mProvider);
2754 std::vector<AvailableStream> outputPreviewStreams;
2755 AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
2756 static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
2757
2758 for (const auto& name : cameraDeviceNames) {
2759 Stream previewStream;
2760 std::vector<HalStream> halStreams;
2761 std::shared_ptr<DeviceCb> cb;
2762 bool supportsPartialResults = false;
2763 bool useHalBufManager = false;
2764
2765 int32_t partialResultCount = 0;
2766 configurePreviewStream(name, mProvider, &previewThreshold, &mSession /*out*/,
2767 &previewStream /*out*/, &halStreams /*out*/,
2768 &supportsPartialResults /*out*/, &partialResultCount /*out*/,
2769 &useHalBufManager /*out*/, &cb /*out*/);
2770
2771 ndk::ScopedAStatus returnStatus = mSession->flush();
2772 ASSERT_TRUE(returnStatus.isOk());
2773
2774 {
2775 std::unique_lock<std::mutex> l(mLock);
2776 auto timeout = std::chrono::system_clock::now() +
2777 std::chrono::milliseconds(kEmptyFlushTimeoutMSec);
2778 ASSERT_EQ(std::cv_status::timeout, mResultCondition.wait_until(l, timeout));
2779 }
2780
2781 ndk::ScopedAStatus ret = mSession->close();
2782 mSession = nullptr;
2783 ASSERT_TRUE(ret.isOk());
2784 }
2785}
2786
2787// Test camera provider notify method
2788TEST_P(CameraAidlTest, providerDeviceStateNotification) {
2789 notifyDeviceState(ICameraProvider::DEVICE_STATE_BACK_COVERED);
2790 notifyDeviceState(ICameraProvider::DEVICE_STATE_NORMAL);
2791}
2792
2793// Verify that all supported stream formats and sizes can be configured
2794// successfully for injection camera.
2795TEST_P(CameraAidlTest, configureInjectionStreamsAvailableOutputs) {
2796 std::vector<std::string> cameraDeviceNames = getCameraDeviceNames(mProvider);
2797 std::vector<AvailableStream> outputStreams;
2798
2799 for (const auto& name : cameraDeviceNames) {
2800 CameraMetadata metadata;
2801
2802 std::shared_ptr<ICameraInjectionSession> injectionSession;
2803 std::shared_ptr<ICameraDevice> unusedDevice;
2804 openEmptyInjectionSession(name, mProvider, &injectionSession /*out*/, &metadata /*out*/,
2805 &unusedDevice /*out*/);
2806 if (injectionSession == nullptr) {
2807 continue;
2808 }
2809
2810 camera_metadata_t* staticMetaBuffer =
2811 reinterpret_cast<camera_metadata_t*>(metadata.metadata.data());
2812 CameraMetadata chars;
2813 chars.metadata = metadata.metadata;
2814
2815 outputStreams.clear();
2816 ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMetaBuffer, outputStreams));
2817 ASSERT_NE(0u, outputStreams.size());
2818
2819 int32_t jpegBufferSize = 0;
2820 ASSERT_EQ(Status::OK, getJpegBufferSize(staticMetaBuffer, &jpegBufferSize));
2821 ASSERT_NE(0u, jpegBufferSize);
2822
2823 int32_t streamId = 0;
2824 int32_t streamConfigCounter = 0;
2825 for (auto& it : outputStreams) {
2826 Dataspace dataspace = getDataspace(static_cast<PixelFormat>(it.format));
2827 Stream stream = {streamId,
2828 StreamType::OUTPUT,
2829 it.width,
2830 it.height,
2831 static_cast<PixelFormat>(it.format),
2832 static_cast<aidl::android::hardware::graphics::common::BufferUsage>(
2833 GRALLOC1_CONSUMER_USAGE_HWCOMPOSER),
2834 dataspace,
2835 StreamRotation::ROTATION_0,
2836 std::string(),
2837 jpegBufferSize,
2838 0,
Avichal Rakeshd3503a32022-02-25 06:23:14 +00002839 {SensorPixelMode::ANDROID_SENSOR_PIXEL_MODE_DEFAULT},
2840 RequestAvailableDynamicRangeProfilesMap::
2841 ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD};
Avichal Rakesh362242f2022-02-08 12:40:53 -08002842
2843 std::vector<Stream> streams = {stream};
2844 StreamConfiguration config;
2845 createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE, &config,
2846 jpegBufferSize);
2847
2848 config.streamConfigCounter = streamConfigCounter++;
2849 ndk::ScopedAStatus s = injectionSession->configureInjectionStreams(config, chars);
2850 ASSERT_TRUE(s.isOk());
2851 streamId++;
2852 }
2853
2854 std::shared_ptr<ICameraDeviceSession> session;
2855 ndk::ScopedAStatus ret = injectionSession->getCameraDeviceSession(&session);
2856 ASSERT_TRUE(ret.isOk());
2857 ASSERT_NE(session, nullptr);
2858 ret = session->close();
2859 ASSERT_TRUE(ret.isOk());
2860 }
2861}
2862
2863// Check for correct handling of invalid/incorrect configuration parameters for injection camera.
2864TEST_P(CameraAidlTest, configureInjectionStreamsInvalidOutputs) {
2865 std::vector<std::string> cameraDeviceNames = getCameraDeviceNames(mProvider);
2866 std::vector<AvailableStream> outputStreams;
2867
2868 for (const auto& name : cameraDeviceNames) {
2869 CameraMetadata metadata;
2870 std::shared_ptr<ICameraInjectionSession> injectionSession;
2871 std::shared_ptr<ICameraDevice> unusedDevice;
2872 openEmptyInjectionSession(name, mProvider, &injectionSession /*out*/, &metadata /*out*/,
2873 &unusedDevice);
2874 if (injectionSession == nullptr) {
2875 continue;
2876 }
2877
2878 camera_metadata_t* staticMetaBuffer =
2879 reinterpret_cast<camera_metadata_t*>(metadata.metadata.data());
2880 std::shared_ptr<ICameraDeviceSession> session;
2881 ndk::ScopedAStatus ret = injectionSession->getCameraDeviceSession(&session);
2882 ASSERT_TRUE(ret.isOk());
2883 ASSERT_NE(session, nullptr);
2884
2885 CameraMetadata chars;
2886 chars.metadata = metadata.metadata;
2887
2888 outputStreams.clear();
2889 ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMetaBuffer, outputStreams));
2890 ASSERT_NE(0u, outputStreams.size());
2891
2892 int32_t jpegBufferSize = 0;
2893 ASSERT_EQ(Status::OK, getJpegBufferSize(staticMetaBuffer, &jpegBufferSize));
2894 ASSERT_NE(0u, jpegBufferSize);
2895
2896 int32_t streamId = 0;
2897 Stream stream = {streamId++,
2898 StreamType::OUTPUT,
2899 0,
2900 0,
2901 static_cast<PixelFormat>(outputStreams[0].format),
2902 static_cast<aidl::android::hardware::graphics::common::BufferUsage>(
2903 GRALLOC1_CONSUMER_USAGE_HWCOMPOSER),
2904 Dataspace::UNKNOWN,
2905 StreamRotation::ROTATION_0,
2906 std::string(),
2907 jpegBufferSize,
2908 0,
Avichal Rakeshd3503a32022-02-25 06:23:14 +00002909 {SensorPixelMode::ANDROID_SENSOR_PIXEL_MODE_DEFAULT},
2910 RequestAvailableDynamicRangeProfilesMap::
2911 ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD};
Avichal Rakesh362242f2022-02-08 12:40:53 -08002912
2913 int32_t streamConfigCounter = 0;
2914 std::vector<Stream> streams = {stream};
2915 StreamConfiguration config;
2916 createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE, &config,
2917 jpegBufferSize);
2918
2919 config.streamConfigCounter = streamConfigCounter++;
2920 ndk::ScopedAStatus s = injectionSession->configureInjectionStreams(config, chars);
2921 ASSERT_TRUE(
2922 (static_cast<int32_t>(Status::ILLEGAL_ARGUMENT) == s.getServiceSpecificError()) ||
2923 (static_cast<int32_t>(Status::INTERNAL_ERROR) == s.getServiceSpecificError()));
2924
2925 stream = {streamId++,
2926 StreamType::OUTPUT,
2927 INT32_MAX,
2928 INT32_MAX,
2929 static_cast<PixelFormat>(outputStreams[0].format),
2930 static_cast<aidl::android::hardware::graphics::common::BufferUsage>(
2931 GRALLOC1_CONSUMER_USAGE_HWCOMPOSER),
2932 Dataspace::UNKNOWN,
2933 StreamRotation::ROTATION_0,
2934 std::string(),
2935 jpegBufferSize,
2936 0,
Avichal Rakeshd3503a32022-02-25 06:23:14 +00002937 {SensorPixelMode::ANDROID_SENSOR_PIXEL_MODE_DEFAULT},
2938 RequestAvailableDynamicRangeProfilesMap::
2939 ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD};
2940
Avichal Rakesh362242f2022-02-08 12:40:53 -08002941 streams[0] = stream;
2942 createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE, &config,
2943 jpegBufferSize);
2944 config.streamConfigCounter = streamConfigCounter++;
2945 s = injectionSession->configureInjectionStreams(config, chars);
2946 ASSERT_EQ(static_cast<int32_t>(Status::ILLEGAL_ARGUMENT), s.getServiceSpecificError());
2947
2948 for (auto& it : outputStreams) {
2949 stream = {streamId++,
2950 StreamType::OUTPUT,
2951 it.width,
2952 it.height,
2953 static_cast<PixelFormat>(INT32_MAX),
2954 static_cast<aidl::android::hardware::graphics::common::BufferUsage>(
2955 GRALLOC1_CONSUMER_USAGE_HWCOMPOSER),
2956 Dataspace::UNKNOWN,
2957 StreamRotation::ROTATION_0,
2958 std::string(),
2959 jpegBufferSize,
2960 0,
Avichal Rakeshd3503a32022-02-25 06:23:14 +00002961 {SensorPixelMode::ANDROID_SENSOR_PIXEL_MODE_DEFAULT},
2962 RequestAvailableDynamicRangeProfilesMap::
2963 ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD};
Avichal Rakesh362242f2022-02-08 12:40:53 -08002964 streams[0] = stream;
2965 createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE, &config,
2966 jpegBufferSize);
2967 config.streamConfigCounter = streamConfigCounter++;
2968 s = injectionSession->configureInjectionStreams(config, chars);
2969 ASSERT_EQ(static_cast<int32_t>(Status::ILLEGAL_ARGUMENT), s.getServiceSpecificError());
2970
2971 stream = {streamId++,
2972 StreamType::OUTPUT,
2973 it.width,
2974 it.height,
2975 static_cast<PixelFormat>(it.format),
2976 static_cast<aidl::android::hardware::graphics::common::BufferUsage>(
2977 GRALLOC1_CONSUMER_USAGE_HWCOMPOSER),
2978 Dataspace::UNKNOWN,
2979 static_cast<StreamRotation>(INT32_MAX),
2980 std::string(),
2981 jpegBufferSize,
2982 0,
Avichal Rakeshd3503a32022-02-25 06:23:14 +00002983 {SensorPixelMode::ANDROID_SENSOR_PIXEL_MODE_DEFAULT},
2984 RequestAvailableDynamicRangeProfilesMap::
2985 ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD};
Avichal Rakesh362242f2022-02-08 12:40:53 -08002986 streams[0] = stream;
2987 createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE, &config,
2988 jpegBufferSize);
2989 config.streamConfigCounter = streamConfigCounter++;
2990 s = injectionSession->configureInjectionStreams(config, chars);
2991 ASSERT_EQ(static_cast<int32_t>(Status::ILLEGAL_ARGUMENT), s.getServiceSpecificError());
2992 }
2993
2994 ret = session->close();
2995 ASSERT_TRUE(ret.isOk());
2996 }
2997}
2998
2999// Check whether session parameters are supported for injection camera. If Hal support for them
3000// exist, then try to configure a preview stream using them.
3001TEST_P(CameraAidlTest, configureInjectionStreamsWithSessionParameters) {
3002 std::vector<std::string> cameraDeviceNames = getCameraDeviceNames(mProvider);
3003 std::vector<AvailableStream> outputPreviewStreams;
3004 AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
3005 static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
3006
3007 for (const auto& name : cameraDeviceNames) {
3008 CameraMetadata metadata;
3009 std::shared_ptr<ICameraInjectionSession> injectionSession;
3010 std::shared_ptr<ICameraDevice> unusedDevice;
3011 openEmptyInjectionSession(name, mProvider, &injectionSession /*out*/, &metadata /*out*/,
3012 &unusedDevice /*out*/);
3013 if (injectionSession == nullptr) {
3014 continue;
3015 }
3016
3017 std::shared_ptr<ICameraDeviceSession> session;
3018 ndk::ScopedAStatus ret = injectionSession->getCameraDeviceSession(&session);
3019 ASSERT_TRUE(ret.isOk());
3020 ASSERT_NE(session, nullptr);
3021
3022 camera_metadata_t* staticMetaBuffer =
3023 reinterpret_cast<camera_metadata_t*>(metadata.metadata.data());
3024 CameraMetadata chars;
3025 chars.metadata = metadata.metadata;
3026
3027 std::unordered_set<int32_t> availableSessionKeys;
3028 Status rc = getSupportedKeys(staticMetaBuffer, ANDROID_REQUEST_AVAILABLE_SESSION_KEYS,
3029 &availableSessionKeys);
3030 ASSERT_EQ(Status::OK, rc);
3031 if (availableSessionKeys.empty()) {
3032 ret = session->close();
3033 ASSERT_TRUE(ret.isOk());
3034 continue;
3035 }
3036
3037 android::hardware::camera::common::V1_0::helper::CameraMetadata previewRequestSettings;
3038 android::hardware::camera::common::V1_0::helper::CameraMetadata sessionParams,
3039 modifiedSessionParams;
3040 constructFilteredSettings(session, availableSessionKeys, RequestTemplate::PREVIEW,
3041 &previewRequestSettings, &sessionParams);
3042 if (sessionParams.isEmpty()) {
3043 ret = session->close();
3044 ASSERT_TRUE(ret.isOk());
3045 continue;
3046 }
3047
3048 outputPreviewStreams.clear();
3049
3050 ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMetaBuffer, outputPreviewStreams,
3051 &previewThreshold));
3052 ASSERT_NE(0u, outputPreviewStreams.size());
3053
3054 Stream previewStream = {
3055 0,
3056 StreamType::OUTPUT,
3057 outputPreviewStreams[0].width,
3058 outputPreviewStreams[0].height,
3059 static_cast<PixelFormat>(outputPreviewStreams[0].format),
3060 static_cast<::aidl::android::hardware::graphics::common::BufferUsage>(
3061 GRALLOC1_CONSUMER_USAGE_HWCOMPOSER),
3062 Dataspace::UNKNOWN,
3063 StreamRotation::ROTATION_0,
3064 std::string(),
3065 0,
3066 -1,
Avichal Rakeshd3503a32022-02-25 06:23:14 +00003067 {SensorPixelMode::ANDROID_SENSOR_PIXEL_MODE_DEFAULT},
3068 RequestAvailableDynamicRangeProfilesMap::
3069 ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD};
Avichal Rakesh362242f2022-02-08 12:40:53 -08003070 std::vector<Stream> streams = {previewStream};
3071 StreamConfiguration config;
3072 config.streams = streams;
3073 config.operationMode = StreamConfigurationMode::NORMAL_MODE;
3074
3075 modifiedSessionParams = sessionParams;
3076 camera_metadata_t* sessionParamsBuffer = sessionParams.release();
3077 uint8_t* rawSessionParamsBuffer = reinterpret_cast<uint8_t*>(sessionParamsBuffer);
3078 config.sessionParams.metadata =
3079 std::vector(rawSessionParamsBuffer,
3080 rawSessionParamsBuffer + get_camera_metadata_size(sessionParamsBuffer));
3081
3082 config.streamConfigCounter = 0;
3083 config.streamConfigCounter = 0;
3084 config.multiResolutionInputImage = false;
3085
3086 ndk::ScopedAStatus s = injectionSession->configureInjectionStreams(config, chars);
3087 ASSERT_TRUE(s.isOk());
3088
3089 sessionParams.acquire(sessionParamsBuffer);
3090 free_camera_metadata(staticMetaBuffer);
3091 ret = session->close();
3092 ASSERT_TRUE(ret.isOk());
3093 }
3094}
3095
Jayant Chowdharyde1909e2022-11-23 17:18:38 +00003096TEST_P(CameraAidlTest, configureStreamsUseCasesCroppedRaw) {
3097 AvailableStream rawStreamThreshold =
3098 {INT_MAX, INT_MAX, static_cast<int32_t>(PixelFormat::RAW16)};
3099 configureStreamUseCaseInternal(rawStreamThreshold);
3100}
3101
Avichal Rakesh362242f2022-02-08 12:40:53 -08003102// Verify that valid stream use cases can be configured successfully, and invalid use cases
3103// fail stream configuration.
3104TEST_P(CameraAidlTest, configureStreamsUseCases) {
Jayant Chowdharyde1909e2022-11-23 17:18:38 +00003105 AvailableStream previewStreamThreshold =
3106 {kMaxPreviewWidth, kMaxPreviewHeight, static_cast<int32_t>(PixelFormat::YCBCR_420_888)};
3107 configureStreamUseCaseInternal(previewStreamThreshold);
Avichal Rakesh362242f2022-02-08 12:40:53 -08003108}
3109
Austin Borger0918fc82023-03-21 18:48:18 -07003110// Validate the integrity of stream configuration metadata
3111TEST_P(CameraAidlTest, validateStreamConfigurations) {
3112 std::vector<std::string> cameraDeviceNames = getCameraDeviceNames(mProvider);
3113 std::vector<AvailableStream> outputStreams;
3114
3115 const int32_t scalerSizesTag = ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS;
3116 const int32_t scalerMinFrameDurationsTag = ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS;
3117 const int32_t scalerStallDurationsTag = ANDROID_SCALER_AVAILABLE_STALL_DURATIONS;
3118
3119 for (const auto& name : cameraDeviceNames) {
3120 CameraMetadata meta;
3121 std::shared_ptr<ICameraDevice> cameraDevice;
3122
3123 openEmptyDeviceSession(name, mProvider, &mSession /*out*/, &meta /*out*/,
3124 &cameraDevice /*out*/);
3125 camera_metadata_t* staticMeta = reinterpret_cast<camera_metadata_t*>(meta.metadata.data());
3126
3127 if (is10BitDynamicRangeCapable(staticMeta)) {
3128 std::vector<std::tuple<size_t, size_t>> supportedP010Sizes, supportedBlobSizes;
3129
3130 getSupportedSizes(staticMeta, scalerSizesTag, HAL_PIXEL_FORMAT_BLOB,
3131 &supportedBlobSizes);
3132 getSupportedSizes(staticMeta, scalerSizesTag, HAL_PIXEL_FORMAT_YCBCR_P010,
3133 &supportedP010Sizes);
3134 ASSERT_FALSE(supportedP010Sizes.empty());
3135
3136 std::vector<int64_t> blobMinDurations, blobStallDurations;
3137 getSupportedDurations(staticMeta, scalerMinFrameDurationsTag, HAL_PIXEL_FORMAT_BLOB,
3138 supportedP010Sizes, &blobMinDurations);
3139 getSupportedDurations(staticMeta, scalerStallDurationsTag, HAL_PIXEL_FORMAT_BLOB,
3140 supportedP010Sizes, &blobStallDurations);
3141 ASSERT_FALSE(blobStallDurations.empty());
3142 ASSERT_FALSE(blobMinDurations.empty());
3143 ASSERT_EQ(supportedP010Sizes.size(), blobMinDurations.size());
3144 ASSERT_EQ(blobMinDurations.size(), blobStallDurations.size());
3145 }
3146
Austin Borger8e9ac022023-05-04 11:17:26 -07003147 // TODO (b/280887191): Validate other aspects of stream configuration metadata...
3148
3149 ndk::ScopedAStatus ret = mSession->close();
3150 mSession = nullptr;
3151 ASSERT_TRUE(ret.isOk());
Austin Borger0918fc82023-03-21 18:48:18 -07003152 }
3153}
3154
Avichal Rakesh362242f2022-02-08 12:40:53 -08003155GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(CameraAidlTest);
3156INSTANTIATE_TEST_SUITE_P(
3157 PerInstance, CameraAidlTest,
3158 testing::ValuesIn(android::getAidlHalInstanceNames(ICameraProvider::descriptor)),
Jayant Chowdharyde1909e2022-11-23 17:18:38 +00003159 android::hardware::PrintInstanceNameToString);