1 /*
2 * Copyright (C) 2016-2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #define LOG_TAG "camera_hidl_hal_test"
18
19 #include <algorithm>
20 #include <chrono>
21 #include <mutex>
22 #include <regex>
23 #include <unordered_map>
24 #include <unordered_set>
25 #include <condition_variable>
26
27 #include <inttypes.h>
28
29 #include <android/hardware/camera/device/1.0/ICameraDevice.h>
30 #include <android/hardware/camera/device/3.2/ICameraDevice.h>
31 #include <android/hardware/camera/device/3.3/ICameraDeviceSession.h>
32 #include <android/hardware/camera/device/3.4/ICameraDeviceSession.h>
33 #include <android/hardware/camera/device/3.4/ICameraDeviceCallback.h>
34 #include <android/hardware/camera/provider/2.4/ICameraProvider.h>
35 #include <android/hidl/manager/1.0/IServiceManager.h>
36 #include <binder/MemoryHeapBase.h>
37 #include <CameraMetadata.h>
38 #include <CameraParameters.h>
39 #include <cutils/properties.h>
40 #include <fmq/MessageQueue.h>
41 #include <grallocusage/GrallocUsageConversion.h>
42 #include <gui/BufferItemConsumer.h>
43 #include <gui/BufferQueue.h>
44 #include <gui/Surface.h>
45 #include <hardware/gralloc.h>
46 #include <hardware/gralloc1.h>
47 #include <system/camera.h>
48 #include <system/camera_metadata.h>
49 #include <ui/GraphicBuffer.h>
50
51 #include <android/hardware/graphics/allocator/2.0/IAllocator.h>
52 #include <android/hardware/graphics/mapper/2.0/IMapper.h>
53 #include <android/hardware/graphics/mapper/2.0/types.h>
54 #include <android/hidl/allocator/1.0/IAllocator.h>
55 #include <android/hidl/memory/1.0/IMapper.h>
56 #include <android/hidl/memory/1.0/IMemory.h>
57
58 #include <VtsHalHidlTargetTestBase.h>
59 #include <VtsHalHidlTargetTestEnvBase.h>
60
61 using namespace ::android::hardware::camera::device;
62 using ::android::hardware::Return;
63 using ::android::hardware::Void;
64 using ::android::hardware::hidl_handle;
65 using ::android::hardware::hidl_string;
66 using ::android::hardware::hidl_vec;
67 using ::android::sp;
68 using ::android::wp;
69 using ::android::GraphicBuffer;
70 using ::android::IGraphicBufferProducer;
71 using ::android::IGraphicBufferConsumer;
72 using ::android::BufferQueue;
73 using ::android::BufferItemConsumer;
74 using ::android::Surface;
75 using ::android::hardware::graphics::common::V1_0::BufferUsage;
76 using ::android::hardware::graphics::common::V1_0::Dataspace;
77 using ::android::hardware::graphics::common::V1_0::PixelFormat;
78 using ::android::hardware::camera::common::V1_0::Status;
79 using ::android::hardware::camera::common::V1_0::CameraDeviceStatus;
80 using ::android::hardware::camera::common::V1_0::TorchMode;
81 using ::android::hardware::camera::common::V1_0::TorchModeStatus;
82 using ::android::hardware::camera::common::V1_0::helper::CameraParameters;
83 using ::android::hardware::camera::common::V1_0::helper::Size;
84 using ::android::hardware::camera::provider::V2_4::ICameraProvider;
85 using ::android::hardware::camera::provider::V2_4::ICameraProviderCallback;
86 using ::android::hardware::camera::device::V3_2::ICameraDevice;
87 using ::android::hardware::camera::device::V3_2::BufferCache;
88 using ::android::hardware::camera::device::V3_2::CaptureRequest;
89 using ::android::hardware::camera::device::V3_2::CaptureResult;
90 using ::android::hardware::camera::device::V3_2::ICameraDeviceCallback;
91 using ::android::hardware::camera::device::V3_2::ICameraDeviceSession;
92 using ::android::hardware::camera::device::V3_2::NotifyMsg;
93 using ::android::hardware::camera::device::V3_2::RequestTemplate;
94 using ::android::hardware::camera::device::V3_2::StreamType;
95 using ::android::hardware::camera::device::V3_2::StreamRotation;
96 using ::android::hardware::camera::device::V3_2::StreamConfiguration;
97 using ::android::hardware::camera::device::V3_2::StreamConfigurationMode;
98 using ::android::hardware::camera::device::V3_2::CameraMetadata;
99 using ::android::hardware::camera::device::V3_2::HalStreamConfiguration;
100 using ::android::hardware::camera::device::V3_2::BufferStatus;
101 using ::android::hardware::camera::device::V3_2::StreamBuffer;
102 using ::android::hardware::camera::device::V3_2::MsgType;
103 using ::android::hardware::camera::device::V3_2::ErrorMsg;
104 using ::android::hardware::camera::device::V3_2::ErrorCode;
105 using ::android::hardware::camera::device::V1_0::CameraFacing;
106 using ::android::hardware::camera::device::V1_0::NotifyCallbackMsg;
107 using ::android::hardware::camera::device::V1_0::CommandType;
108 using ::android::hardware::camera::device::V1_0::DataCallbackMsg;
109 using ::android::hardware::camera::device::V1_0::CameraFrameMetadata;
110 using ::android::hardware::camera::device::V1_0::ICameraDevicePreviewCallback;
111 using ::android::hardware::camera::device::V1_0::FrameCallbackFlag;
112 using ::android::hardware::camera::device::V1_0::HandleTimestampMessage;
113 using ::android::hardware::MessageQueue;
114 using ::android::hardware::kSynchronizedReadWrite;
115 using ::android::hidl::allocator::V1_0::IAllocator;
116 using ::android::hidl::memory::V1_0::IMemory;
117 using ::android::hidl::memory::V1_0::IMapper;
118 using ResultMetadataQueue = MessageQueue<uint8_t, kSynchronizedReadWrite>;
119 using ::android::hidl::manager::V1_0::IServiceManager;
120
121 using namespace ::android::hardware::camera;
122
123 const uint32_t kMaxPreviewWidth = 1920;
124 const uint32_t kMaxPreviewHeight = 1080;
125 const uint32_t kMaxVideoWidth = 4096;
126 const uint32_t kMaxVideoHeight = 2160;
127 const int64_t kStreamBufferTimeoutSec = 3;
128 const int64_t kAutoFocusTimeoutSec = 5;
129 const int64_t kTorchTimeoutSec = 1;
130 const int64_t kEmptyFlushTimeoutMSec = 200;
131 const char kDumpOutput[] = "/dev/null";
132 const uint32_t kBurstFrameCount = 10;
133
134 struct AvailableStream {
135 int32_t width;
136 int32_t height;
137 int32_t format;
138 };
139
140 struct AvailableZSLInputOutput {
141 int32_t inputFormat;
142 int32_t outputFormat;
143 };
144
145 namespace {
146 // "device@<version>/legacy/<id>"
147 const char *kDeviceNameRE = "device@([0-9]+\\.[0-9]+)/%s/(.+)";
148 const int CAMERA_DEVICE_API_VERSION_3_4 = 0x304;
149 const int CAMERA_DEVICE_API_VERSION_3_3 = 0x303;
150 const int CAMERA_DEVICE_API_VERSION_3_2 = 0x302;
151 const int CAMERA_DEVICE_API_VERSION_1_0 = 0x100;
152 const char *kHAL3_4 = "3.4";
153 const char *kHAL3_3 = "3.3";
154 const char *kHAL3_2 = "3.2";
155 const char *kHAL1_0 = "1.0";
156
matchDeviceName(const hidl_string & deviceName,const hidl_string & providerType,std::string * deviceVersion,std::string * cameraId)157 bool matchDeviceName(const hidl_string& deviceName,
158 const hidl_string &providerType,
159 std::string* deviceVersion,
160 std::string* cameraId) {
161 ::android::String8 pattern;
162 pattern.appendFormat(kDeviceNameRE, providerType.c_str());
163 std::regex e(pattern.string());
164 std::string deviceNameStd(deviceName.c_str());
165 std::smatch sm;
166 if (std::regex_match(deviceNameStd, sm, e)) {
167 if (deviceVersion != nullptr) {
168 *deviceVersion = sm[1];
169 }
170 if (cameraId != nullptr) {
171 *cameraId = sm[2];
172 }
173 return true;
174 }
175 return false;
176 }
177
getCameraDeviceVersion(const hidl_string & deviceName,const hidl_string & providerType)178 int getCameraDeviceVersion(const hidl_string& deviceName,
179 const hidl_string &providerType) {
180 std::string version;
181 bool match = matchDeviceName(deviceName, providerType, &version, nullptr);
182 if (!match) {
183 return -1;
184 }
185
186 if (version.compare(kHAL3_4) == 0) {
187 return CAMERA_DEVICE_API_VERSION_3_4;
188 } else if (version.compare(kHAL3_3) == 0) {
189 return CAMERA_DEVICE_API_VERSION_3_3;
190 } else if (version.compare(kHAL3_2) == 0) {
191 return CAMERA_DEVICE_API_VERSION_3_2;
192 } else if (version.compare(kHAL1_0) == 0) {
193 return CAMERA_DEVICE_API_VERSION_1_0;
194 }
195 return 0;
196 }
197
parseProviderName(const std::string & name,std::string * type,uint32_t * id)198 bool parseProviderName(const std::string& name, std::string *type /*out*/,
199 uint32_t *id /*out*/) {
200 if (!type || !id) {
201 ADD_FAILURE();
202 return false;
203 }
204
205 std::string::size_type slashIdx = name.find('/');
206 if (slashIdx == std::string::npos || slashIdx == name.size() - 1) {
207 ADD_FAILURE() << "Provider name does not have / separator between type"
208 "and id";
209 return false;
210 }
211
212 std::string typeVal = name.substr(0, slashIdx);
213
214 char *endPtr;
215 errno = 0;
216 long idVal = strtol(name.c_str() + slashIdx + 1, &endPtr, 10);
217 if (errno != 0) {
218 ADD_FAILURE() << "cannot parse provider id as an integer:" <<
219 name.c_str() << strerror(errno) << errno;
220 return false;
221 }
222 if (endPtr != name.c_str() + name.size()) {
223 ADD_FAILURE() << "provider id has unexpected length " << name.c_str();
224 return false;
225 }
226 if (idVal < 0) {
227 ADD_FAILURE() << "id is negative: " << name.c_str() << idVal;
228 return false;
229 }
230
231 *type = typeVal;
232 *id = static_cast<uint32_t>(idVal);
233
234 return true;
235 }
236
mapToStatus(::android::status_t s)237 Status mapToStatus(::android::status_t s) {
238 switch(s) {
239 case ::android::OK:
240 return Status::OK ;
241 case ::android::BAD_VALUE:
242 return Status::ILLEGAL_ARGUMENT ;
243 case -EBUSY:
244 return Status::CAMERA_IN_USE;
245 case -EUSERS:
246 return Status::MAX_CAMERAS_IN_USE;
247 case ::android::UNKNOWN_TRANSACTION:
248 return Status::METHOD_NOT_SUPPORTED;
249 case ::android::INVALID_OPERATION:
250 return Status::OPERATION_NOT_SUPPORTED;
251 case ::android::DEAD_OBJECT:
252 return Status::CAMERA_DISCONNECTED;
253 }
254 ALOGW("Unexpected HAL status code %d", s);
255 return Status::OPERATION_NOT_SUPPORTED;
256 }
257 }
258
259 // Test environment for camera
260 class CameraHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
261 public:
262 // get the test environment singleton
Instance()263 static CameraHidlEnvironment* Instance() {
264 static CameraHidlEnvironment* instance = new CameraHidlEnvironment;
265 return instance;
266 }
267
HidlSetUp()268 virtual void HidlSetUp() override { ALOGI("SetUp CameraHidlEnvironment"); }
269
HidlTearDown()270 virtual void HidlTearDown() override { ALOGI("TearDown CameraHidlEnvironment"); }
271
registerTestServices()272 virtual void registerTestServices() override { registerTestService<ICameraProvider>(); }
273
274 private:
CameraHidlEnvironment()275 CameraHidlEnvironment() {}
276
277 GTEST_DISALLOW_COPY_AND_ASSIGN_(CameraHidlEnvironment);
278 };
279
280 struct BufferItemHander: public BufferItemConsumer::FrameAvailableListener {
BufferItemHanderBufferItemHander281 BufferItemHander(wp<BufferItemConsumer> consumer) : mConsumer(consumer) {}
282
onFrameAvailableBufferItemHander283 void onFrameAvailable(const android::BufferItem&) override {
284 sp<BufferItemConsumer> consumer = mConsumer.promote();
285 ASSERT_NE(nullptr, consumer.get());
286
287 android::BufferItem buffer;
288 ASSERT_EQ(android::OK, consumer->acquireBuffer(&buffer, 0));
289 ASSERT_EQ(android::OK, consumer->releaseBuffer(buffer));
290 }
291
292 private:
293 wp<BufferItemConsumer> mConsumer;
294 };
295
296 struct PreviewWindowCb : public ICameraDevicePreviewCallback {
PreviewWindowCbPreviewWindowCb297 PreviewWindowCb(sp<ANativeWindow> anw) : mPreviewWidth(0),
298 mPreviewHeight(0), mFormat(0), mPreviewUsage(0),
299 mPreviewSwapInterval(-1), mCrop{-1, -1, -1, -1}, mAnw(anw) {}
300
301 using dequeueBuffer_cb =
302 std::function<void(Status status, uint64_t bufferId,
303 const hidl_handle& buffer, uint32_t stride)>;
304 Return<void> dequeueBuffer(dequeueBuffer_cb _hidl_cb) override;
305
306 Return<Status> enqueueBuffer(uint64_t bufferId) override;
307
308 Return<Status> cancelBuffer(uint64_t bufferId) override;
309
310 Return<Status> setBufferCount(uint32_t count) override;
311
312 Return<Status> setBuffersGeometry(uint32_t w,
313 uint32_t h, PixelFormat format) override;
314
315 Return<Status> setCrop(int32_t left, int32_t top,
316 int32_t right, int32_t bottom) override;
317
318 Return<Status> setUsage(BufferUsage usage) override;
319
320 Return<Status> setSwapInterval(int32_t interval) override;
321
322 using getMinUndequeuedBufferCount_cb =
323 std::function<void(Status status, uint32_t count)>;
324 Return<void> getMinUndequeuedBufferCount(
325 getMinUndequeuedBufferCount_cb _hidl_cb) override;
326
327 Return<Status> setTimestamp(int64_t timestamp) override;
328
329 private:
330 struct BufferHasher {
operator ()PreviewWindowCb::BufferHasher331 size_t operator()(const buffer_handle_t& buf) const {
332 if (buf == nullptr)
333 return 0;
334
335 size_t result = 1;
336 result = 31 * result + buf->numFds;
337 for (int i = 0; i < buf->numFds; i++) {
338 result = 31 * result + buf->data[i];
339 }
340 return result;
341 }
342 };
343
344 struct BufferComparator {
operator ()PreviewWindowCb::BufferComparator345 bool operator()(const buffer_handle_t& buf1,
346 const buffer_handle_t& buf2) const {
347 if (buf1->numFds == buf2->numFds) {
348 for (int i = 0; i < buf1->numFds; i++) {
349 if (buf1->data[i] != buf2->data[i]) {
350 return false;
351 }
352 }
353 return true;
354 }
355 return false;
356 }
357 };
358
359 std::pair<bool, uint64_t> getBufferId(ANativeWindowBuffer* anb);
360 void cleanupCirculatingBuffers();
361
362 std::mutex mBufferIdMapLock; // protecting mBufferIdMap and mNextBufferId
363 typedef std::unordered_map<const buffer_handle_t, uint64_t,
364 BufferHasher, BufferComparator> BufferIdMap;
365
366 BufferIdMap mBufferIdMap; // stream ID -> per stream buffer ID map
367 std::unordered_map<uint64_t, ANativeWindowBuffer*> mReversedBufMap;
368 uint64_t mNextBufferId = 1;
369
370 uint32_t mPreviewWidth, mPreviewHeight;
371 int mFormat, mPreviewUsage;
372 int32_t mPreviewSwapInterval;
373 android_native_rect_t mCrop;
374 sp<ANativeWindow> mAnw; //Native window reference
375 };
376
getBufferId(ANativeWindowBuffer * anb)377 std::pair<bool, uint64_t> PreviewWindowCb::getBufferId(
378 ANativeWindowBuffer* anb) {
379 std::lock_guard<std::mutex> lock(mBufferIdMapLock);
380
381 buffer_handle_t& buf = anb->handle;
382 auto it = mBufferIdMap.find(buf);
383 if (it == mBufferIdMap.end()) {
384 uint64_t bufId = mNextBufferId++;
385 mBufferIdMap[buf] = bufId;
386 mReversedBufMap[bufId] = anb;
387 return std::make_pair(true, bufId);
388 } else {
389 return std::make_pair(false, it->second);
390 }
391 }
392
cleanupCirculatingBuffers()393 void PreviewWindowCb::cleanupCirculatingBuffers() {
394 std::lock_guard<std::mutex> lock(mBufferIdMapLock);
395 mBufferIdMap.clear();
396 mReversedBufMap.clear();
397 }
398
dequeueBuffer(dequeueBuffer_cb _hidl_cb)399 Return<void> PreviewWindowCb::dequeueBuffer(dequeueBuffer_cb _hidl_cb) {
400 ANativeWindowBuffer* anb;
401 auto rc = native_window_dequeue_buffer_and_wait(mAnw.get(), &anb);
402 uint64_t bufferId = 0;
403 uint32_t stride = 0;
404 hidl_handle buf = nullptr;
405 if (rc == ::android::OK) {
406 auto pair = getBufferId(anb);
407 buf = (pair.first) ? anb->handle : nullptr;
408 bufferId = pair.second;
409 stride = anb->stride;
410 }
411
412 _hidl_cb(mapToStatus(rc), bufferId, buf, stride);
413 return Void();
414 }
415
enqueueBuffer(uint64_t bufferId)416 Return<Status> PreviewWindowCb::enqueueBuffer(uint64_t bufferId) {
417 if (mReversedBufMap.count(bufferId) == 0) {
418 ALOGE("%s: bufferId %" PRIu64 " not found", __FUNCTION__, bufferId);
419 return Status::ILLEGAL_ARGUMENT;
420 }
421 return mapToStatus(mAnw->queueBuffer(mAnw.get(),
422 mReversedBufMap.at(bufferId), -1));
423 }
424
cancelBuffer(uint64_t bufferId)425 Return<Status> PreviewWindowCb::cancelBuffer(uint64_t bufferId) {
426 if (mReversedBufMap.count(bufferId) == 0) {
427 ALOGE("%s: bufferId %" PRIu64 " not found", __FUNCTION__, bufferId);
428 return Status::ILLEGAL_ARGUMENT;
429 }
430 return mapToStatus(mAnw->cancelBuffer(mAnw.get(),
431 mReversedBufMap.at(bufferId), -1));
432 }
433
setBufferCount(uint32_t count)434 Return<Status> PreviewWindowCb::setBufferCount(uint32_t count) {
435 if (mAnw.get() != nullptr) {
436 // WAR for b/27039775
437 native_window_api_disconnect(mAnw.get(), NATIVE_WINDOW_API_CAMERA);
438 native_window_api_connect(mAnw.get(), NATIVE_WINDOW_API_CAMERA);
439 if (mPreviewWidth != 0) {
440 native_window_set_buffers_dimensions(mAnw.get(),
441 mPreviewWidth, mPreviewHeight);
442 native_window_set_buffers_format(mAnw.get(), mFormat);
443 }
444 if (mPreviewUsage != 0) {
445 native_window_set_usage(mAnw.get(), mPreviewUsage);
446 }
447 if (mPreviewSwapInterval >= 0) {
448 mAnw->setSwapInterval(mAnw.get(), mPreviewSwapInterval);
449 }
450 if (mCrop.left >= 0) {
451 native_window_set_crop(mAnw.get(), &(mCrop));
452 }
453 }
454
455 auto rc = native_window_set_buffer_count(mAnw.get(), count);
456 if (rc == ::android::OK) {
457 cleanupCirculatingBuffers();
458 }
459
460 return mapToStatus(rc);
461 }
462
setBuffersGeometry(uint32_t w,uint32_t h,PixelFormat format)463 Return<Status> PreviewWindowCb::setBuffersGeometry(uint32_t w, uint32_t h,
464 PixelFormat format) {
465 auto rc = native_window_set_buffers_dimensions(mAnw.get(), w, h);
466 if (rc == ::android::OK) {
467 mPreviewWidth = w;
468 mPreviewHeight = h;
469 rc = native_window_set_buffers_format(mAnw.get(),
470 static_cast<int>(format));
471 if (rc == ::android::OK) {
472 mFormat = static_cast<int>(format);
473 }
474 }
475
476 return mapToStatus(rc);
477 }
478
setCrop(int32_t left,int32_t top,int32_t right,int32_t bottom)479 Return<Status> PreviewWindowCb::setCrop(int32_t left, int32_t top,
480 int32_t right, int32_t bottom) {
481 android_native_rect_t crop = { left, top, right, bottom };
482 auto rc = native_window_set_crop(mAnw.get(), &crop);
483 if (rc == ::android::OK) {
484 mCrop = crop;
485 }
486 return mapToStatus(rc);
487 }
488
setUsage(BufferUsage usage)489 Return<Status> PreviewWindowCb::setUsage(BufferUsage usage) {
490 auto rc = native_window_set_usage(mAnw.get(), static_cast<int>(usage));
491 if (rc == ::android::OK) {
492 mPreviewUsage = static_cast<int>(usage);
493 }
494 return mapToStatus(rc);
495 }
496
setSwapInterval(int32_t interval)497 Return<Status> PreviewWindowCb::setSwapInterval(int32_t interval) {
498 auto rc = mAnw->setSwapInterval(mAnw.get(), interval);
499 if (rc == ::android::OK) {
500 mPreviewSwapInterval = interval;
501 }
502 return mapToStatus(rc);
503 }
504
getMinUndequeuedBufferCount(getMinUndequeuedBufferCount_cb _hidl_cb)505 Return<void> PreviewWindowCb::getMinUndequeuedBufferCount(
506 getMinUndequeuedBufferCount_cb _hidl_cb) {
507 int count = 0;
508 auto rc = mAnw->query(mAnw.get(),
509 NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &count);
510 _hidl_cb(mapToStatus(rc), count);
511 return Void();
512 }
513
setTimestamp(int64_t timestamp)514 Return<Status> PreviewWindowCb::setTimestamp(int64_t timestamp) {
515 return mapToStatus(native_window_set_buffers_timestamp(mAnw.get(),
516 timestamp));
517 }
518
519 // The main test class for camera HIDL HAL.
520 class CameraHidlTest : public ::testing::VtsHalHidlTargetTestBase {
521 public:
SetUp()522 virtual void SetUp() override {
523 string service_name = CameraHidlEnvironment::Instance()->getServiceName<ICameraProvider>();
524 ALOGI("get service with name: %s", service_name.c_str());
525 mProvider = ::testing::VtsHalHidlTargetTestBase::getService<ICameraProvider>(service_name);
526 ASSERT_NE(mProvider, nullptr);
527
528 uint32_t id;
529 ASSERT_TRUE(parseProviderName(service_name, &mProviderType, &id));
530 }
TearDown()531 virtual void TearDown() override {}
532
533 hidl_vec<hidl_string> getCameraDeviceNames(sp<ICameraProvider> provider);
534
535 struct EmptyDeviceCb : public ICameraDeviceCallback {
processCaptureResultCameraHidlTest::EmptyDeviceCb536 virtual Return<void> processCaptureResult(
537 const hidl_vec<CaptureResult>& /*results*/) override {
538 ALOGI("processCaptureResult callback");
539 ADD_FAILURE(); // Empty callback should not reach here
540 return Void();
541 }
542
notifyCameraHidlTest::EmptyDeviceCb543 virtual Return<void> notify(const hidl_vec<NotifyMsg>& /*msgs*/) override {
544 ALOGI("notify callback");
545 ADD_FAILURE(); // Empty callback should not reach here
546 return Void();
547 }
548 };
549
550 struct DeviceCb : public V3_4::ICameraDeviceCallback {
DeviceCbCameraHidlTest::DeviceCb551 DeviceCb(CameraHidlTest *parent) : mParent(parent) {}
552 Return<void> processCaptureResult_3_4(
553 const hidl_vec<V3_4::CaptureResult>& results) override;
554 Return<void> processCaptureResult(const hidl_vec<CaptureResult>& results) override;
555 Return<void> notify(const hidl_vec<NotifyMsg>& msgs) override;
556
557 private:
558 bool processCaptureResultLocked(const CaptureResult& results);
559
560 CameraHidlTest *mParent; // Parent object
561 };
562
563 struct TorchProviderCb : public ICameraProviderCallback {
TorchProviderCbCameraHidlTest::TorchProviderCb564 TorchProviderCb(CameraHidlTest *parent) : mParent(parent) {}
cameraDeviceStatusChangeCameraHidlTest::TorchProviderCb565 virtual Return<void> cameraDeviceStatusChange(
566 const hidl_string&, CameraDeviceStatus) override {
567 return Void();
568 }
569
torchModeStatusChangeCameraHidlTest::TorchProviderCb570 virtual Return<void> torchModeStatusChange(
571 const hidl_string&, TorchModeStatus newStatus) override {
572 std::lock_guard<std::mutex> l(mParent->mTorchLock);
573 mParent->mTorchStatus = newStatus;
574 mParent->mTorchCond.notify_one();
575 return Void();
576 }
577
578 private:
579 CameraHidlTest *mParent; // Parent object
580 };
581
582 struct Camera1DeviceCb :
583 public ::android::hardware::camera::device::V1_0::ICameraDeviceCallback {
Camera1DeviceCbCameraHidlTest::Camera1DeviceCb584 Camera1DeviceCb(CameraHidlTest *parent) : mParent(parent) {}
585
586 Return<void> notifyCallback(NotifyCallbackMsg msgType,
587 int32_t ext1, int32_t ext2) override;
588
589 Return<uint32_t> registerMemory(const hidl_handle& descriptor,
590 uint32_t bufferSize, uint32_t bufferCount) override;
591
592 Return<void> unregisterMemory(uint32_t memId) override;
593
594 Return<void> dataCallback(DataCallbackMsg msgType,
595 uint32_t data, uint32_t bufferIndex,
596 const CameraFrameMetadata& metadata) override;
597
598 Return<void> dataCallbackTimestamp(DataCallbackMsg msgType,
599 uint32_t data, uint32_t bufferIndex,
600 int64_t timestamp) override;
601
602 Return<void> handleCallbackTimestamp(DataCallbackMsg msgType,
603 const hidl_handle& frameData,uint32_t data,
604 uint32_t bufferIndex, int64_t timestamp) override;
605
606 Return<void> handleCallbackTimestampBatch(DataCallbackMsg msgType,
607 const ::android::hardware::hidl_vec<HandleTimestampMessage>& batch) override;
608
609
610 private:
611 CameraHidlTest *mParent; // Parent object
612 };
613
614 void openCameraDevice(const std::string &name, sp<ICameraProvider> provider,
615 sp<::android::hardware::camera::device::V1_0::ICameraDevice> *device /*out*/);
616 void setupPreviewWindow(
617 const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device,
618 sp<BufferItemConsumer> *bufferItemConsumer /*out*/,
619 sp<BufferItemHander> *bufferHandler /*out*/);
620 void stopPreviewAndClose(
621 const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device);
622 void startPreview(
623 const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device);
624 void enableMsgType(unsigned int msgType,
625 const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device);
626 void disableMsgType(unsigned int msgType,
627 const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device);
628 void getParameters(
629 const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device,
630 CameraParameters *cameraParams /*out*/);
631 void setParameters(
632 const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device,
633 const CameraParameters &cameraParams);
634 void allocateGraphicBuffer(uint32_t width, uint32_t height, uint64_t usage,
635 PixelFormat format, hidl_handle *buffer_handle /*out*/);
636 void waitForFrameLocked(DataCallbackMsg msgFrame,
637 std::unique_lock<std::mutex> &l);
638 void openEmptyDeviceSession(const std::string &name,
639 sp<ICameraProvider> provider,
640 sp<ICameraDeviceSession> *session /*out*/,
641 camera_metadata_t **staticMeta /*out*/);
642 void castSession(const sp<ICameraDeviceSession> &session, int32_t deviceVersion,
643 sp<device::V3_3::ICameraDeviceSession> *session3_3 /*out*/,
644 sp<device::V3_4::ICameraDeviceSession> *session3_4 /*out*/);
645 void createStreamConfiguration(const ::android::hardware::hidl_vec<V3_2::Stream>& streams3_2,
646 StreamConfigurationMode configMode,
647 ::android::hardware::camera::device::V3_2::StreamConfiguration *config3_2,
648 ::android::hardware::camera::device::V3_4::StreamConfiguration *config3_4);
649
650 void configurePreviewStreams3_4(const std::string &name, int32_t deviceVersion,
651 sp<ICameraProvider> provider,
652 const AvailableStream *previewThreshold,
653 const std::unordered_set<std::string>& physicalIds,
654 sp<device::V3_4::ICameraDeviceSession> *session3_4 /*out*/,
655 V3_2::Stream* previewStream /*out*/,
656 device::V3_4::HalStreamConfiguration *halStreamConfig /*out*/,
657 bool *supportsPartialResults /*out*/,
658 uint32_t *partialResultCount /*out*/);
659 void configurePreviewStream(const std::string &name, int32_t deviceVersion,
660 sp<ICameraProvider> provider,
661 const AvailableStream *previewThreshold,
662 sp<ICameraDeviceSession> *session /*out*/,
663 V3_2::Stream *previewStream /*out*/,
664 HalStreamConfiguration *halStreamConfig /*out*/,
665 bool *supportsPartialResults /*out*/,
666 uint32_t *partialResultCount /*out*/);
667 static Status getAvailableOutputStreams(camera_metadata_t *staticMeta,
668 std::vector<AvailableStream> &outputStreams,
669 const AvailableStream *threshold = nullptr);
670 static Status isConstrainedModeAvailable(camera_metadata_t *staticMeta);
671 static Status isLogicalMultiCamera(camera_metadata_t *staticMeta);
672 static Status getPhysicalCameraIds(camera_metadata_t *staticMeta,
673 std::unordered_set<std::string> *physicalIds/*out*/);
674 static Status getSupportedKeys(camera_metadata_t *staticMeta,
675 uint32_t tagId, std::unordered_set<int32_t> *requestIDs/*out*/);
676 static void constructFilteredSettings(const sp<ICameraDeviceSession>& session,
677 const std::unordered_set<int32_t>& availableKeys, RequestTemplate reqTemplate,
678 android::hardware::camera::common::V1_0::helper::CameraMetadata* defaultSettings/*out*/,
679 android::hardware::camera::common::V1_0::helper::CameraMetadata* filteredSettings
680 /*out*/);
681 static Status pickConstrainedModeSize(camera_metadata_t *staticMeta,
682 AvailableStream &hfrStream);
683 static Status isZSLModeAvailable(camera_metadata_t *staticMeta);
684 static Status getZSLInputOutputMap(camera_metadata_t *staticMeta,
685 std::vector<AvailableZSLInputOutput> &inputOutputMap);
686 static Status findLargestSize(
687 const std::vector<AvailableStream> &streamSizes,
688 int32_t format, AvailableStream &result);
689 static Status isAutoFocusModeAvailable(
690 CameraParameters &cameraParams, const char *mode) ;
691
692 protected:
693
694 // In-flight queue for tracking completion of capture requests.
695 struct InFlightRequest {
696 // Set by notify() SHUTTER call.
697 nsecs_t shutterTimestamp;
698
699 bool errorCodeValid;
700 ErrorCode errorCode;
701
702 //Is partial result supported
703 bool usePartialResult;
704
705 //Partial result count expected
706 uint32_t numPartialResults;
707
708 // Message queue
709 std::shared_ptr<ResultMetadataQueue> resultQueue;
710
711 // Set by process_capture_result call with valid metadata
712 bool haveResultMetadata;
713
714 // Decremented by calls to process_capture_result with valid output
715 // and input buffers
716 ssize_t numBuffersLeft;
717
718 // A 64bit integer to index the frame number associated with this result.
719 int64_t frameNumber;
720
721 // The partial result count (index) for this capture result.
722 int32_t partialResultCount;
723
724 // For buffer drop errors, the stream ID for the stream that lost a buffer.
725 // Otherwise -1.
726 int32_t errorStreamId;
727
728 // If this request has any input buffer
729 bool hasInputBuffer;
730
731 // Result metadata
732 ::android::hardware::camera::common::V1_0::helper::CameraMetadata collectedResult;
733
734 // Buffers are added by process_capture_result when output buffers
735 // return from HAL but framework.
736 ::android::Vector<StreamBuffer> resultOutputBuffers;
737
InFlightRequestCameraHidlTest::InFlightRequest738 InFlightRequest() :
739 shutterTimestamp(0),
740 errorCodeValid(false),
741 errorCode(ErrorCode::ERROR_BUFFER),
742 usePartialResult(false),
743 numPartialResults(0),
744 resultQueue(nullptr),
745 haveResultMetadata(false),
746 numBuffersLeft(0),
747 frameNumber(0),
748 partialResultCount(0),
749 errorStreamId(-1),
750 hasInputBuffer(false) {}
751
InFlightRequestCameraHidlTest::InFlightRequest752 InFlightRequest(ssize_t numBuffers, bool hasInput,
753 bool partialResults, uint32_t partialCount,
754 std::shared_ptr<ResultMetadataQueue> queue = nullptr) :
755 shutterTimestamp(0),
756 errorCodeValid(false),
757 errorCode(ErrorCode::ERROR_BUFFER),
758 usePartialResult(partialResults),
759 numPartialResults(partialCount),
760 resultQueue(queue),
761 haveResultMetadata(false),
762 numBuffersLeft(numBuffers),
763 frameNumber(0),
764 partialResultCount(0),
765 errorStreamId(-1),
766 hasInputBuffer(hasInput) {}
767 };
768
769 // Map from frame number to the in-flight request state
770 typedef ::android::KeyedVector<uint32_t, InFlightRequest*> InFlightMap;
771
772 std::mutex mLock; // Synchronize access to member variables
773 std::condition_variable mResultCondition; // Condition variable for incoming results
774 InFlightMap mInflightMap; // Map of all inflight requests
775
776 DataCallbackMsg mDataMessageTypeReceived; // Most recent message type received through data callbacks
777 uint32_t mVideoBufferIndex; // Buffer index of the most recent video buffer
778 uint32_t mVideoData; // Buffer data of the most recent video buffer
779 hidl_handle mVideoNativeHandle; // Most recent video buffer native handle
780 NotifyCallbackMsg mNotifyMessage; // Current notification message
781
782 std::mutex mTorchLock; // Synchronize access to torch status
783 std::condition_variable mTorchCond; // Condition variable for torch status
784 TorchModeStatus mTorchStatus; // Current torch status
785
786 // Holds camera registered buffers
787 std::unordered_map<uint32_t, sp<::android::MemoryHeapBase> > mMemoryPool;
788
789 // Camera provider service
790 sp<ICameraProvider> mProvider;
791 // Camera provider type.
792 std::string mProviderType;
793 };
794
notifyCallback(NotifyCallbackMsg msgType,int32_t ext1 __unused,int32_t ext2 __unused)795 Return<void> CameraHidlTest::Camera1DeviceCb::notifyCallback(
796 NotifyCallbackMsg msgType, int32_t ext1 __unused,
797 int32_t ext2 __unused) {
798 std::unique_lock<std::mutex> l(mParent->mLock);
799 mParent->mNotifyMessage = msgType;
800 mParent->mResultCondition.notify_one();
801
802 return Void();
803 }
804
registerMemory(const hidl_handle & descriptor,uint32_t bufferSize,uint32_t bufferCount)805 Return<uint32_t> CameraHidlTest::Camera1DeviceCb::registerMemory(
806 const hidl_handle& descriptor, uint32_t bufferSize,
807 uint32_t bufferCount) {
808 if (descriptor->numFds != 1) {
809 ADD_FAILURE() << "camera memory descriptor has"
810 " numFds " << descriptor->numFds << " (expect 1)" ;
811 return 0;
812 }
813 if (descriptor->data[0] < 0) {
814 ADD_FAILURE() << "camera memory descriptor has"
815 " FD " << descriptor->data[0] << " (expect >= 0)";
816 return 0;
817 }
818
819 sp<::android::MemoryHeapBase> pool = new ::android::MemoryHeapBase(
820 descriptor->data[0], bufferSize*bufferCount, 0, 0);
821 mParent->mMemoryPool.emplace(pool->getHeapID(), pool);
822
823 return pool->getHeapID();
824 }
825
unregisterMemory(uint32_t memId)826 Return<void> CameraHidlTest::Camera1DeviceCb::unregisterMemory(uint32_t memId) {
827 if (mParent->mMemoryPool.count(memId) == 0) {
828 ALOGE("%s: memory pool ID %d not found", __FUNCTION__, memId);
829 ADD_FAILURE();
830 return Void();
831 }
832
833 mParent->mMemoryPool.erase(memId);
834 return Void();
835 }
836
dataCallback(DataCallbackMsg msgType __unused,uint32_t data __unused,uint32_t bufferIndex __unused,const CameraFrameMetadata & metadata __unused)837 Return<void> CameraHidlTest::Camera1DeviceCb::dataCallback(
838 DataCallbackMsg msgType __unused, uint32_t data __unused,
839 uint32_t bufferIndex __unused,
840 const CameraFrameMetadata& metadata __unused) {
841 std::unique_lock<std::mutex> l(mParent->mLock);
842 mParent->mDataMessageTypeReceived = msgType;
843 mParent->mResultCondition.notify_one();
844
845 return Void();
846 }
847
dataCallbackTimestamp(DataCallbackMsg msgType,uint32_t data,uint32_t bufferIndex,int64_t timestamp __unused)848 Return<void> CameraHidlTest::Camera1DeviceCb::dataCallbackTimestamp(
849 DataCallbackMsg msgType, uint32_t data,
850 uint32_t bufferIndex, int64_t timestamp __unused) {
851 std::unique_lock<std::mutex> l(mParent->mLock);
852 mParent->mDataMessageTypeReceived = msgType;
853 mParent->mVideoBufferIndex = bufferIndex;
854 if (mParent->mMemoryPool.count(data) == 0) {
855 ADD_FAILURE() << "memory pool ID " << data << "not found";
856 }
857 mParent->mVideoData = data;
858 mParent->mResultCondition.notify_one();
859
860 return Void();
861 }
862
handleCallbackTimestamp(DataCallbackMsg msgType,const hidl_handle & frameData,uint32_t data __unused,uint32_t bufferIndex,int64_t timestamp __unused)863 Return<void> CameraHidlTest::Camera1DeviceCb::handleCallbackTimestamp(
864 DataCallbackMsg msgType, const hidl_handle& frameData,
865 uint32_t data __unused, uint32_t bufferIndex,
866 int64_t timestamp __unused) {
867 std::unique_lock<std::mutex> l(mParent->mLock);
868 mParent->mDataMessageTypeReceived = msgType;
869 mParent->mVideoBufferIndex = bufferIndex;
870 if (mParent->mMemoryPool.count(data) == 0) {
871 ADD_FAILURE() << "memory pool ID " << data << " not found";
872 }
873 mParent->mVideoData = data;
874 mParent->mVideoNativeHandle = frameData;
875 mParent->mResultCondition.notify_one();
876
877 return Void();
878 }
879
handleCallbackTimestampBatch(DataCallbackMsg msgType,const hidl_vec<HandleTimestampMessage> & batch)880 Return<void> CameraHidlTest::Camera1DeviceCb::handleCallbackTimestampBatch(
881 DataCallbackMsg msgType,
882 const hidl_vec<HandleTimestampMessage>& batch) {
883 std::unique_lock<std::mutex> l(mParent->mLock);
884 for (auto& msg : batch) {
885 mParent->mDataMessageTypeReceived = msgType;
886 mParent->mVideoBufferIndex = msg.bufferIndex;
887 if (mParent->mMemoryPool.count(msg.data) == 0) {
888 ADD_FAILURE() << "memory pool ID " << msg.data << " not found";
889 }
890 mParent->mVideoData = msg.data;
891 mParent->mVideoNativeHandle = msg.frameData;
892 mParent->mResultCondition.notify_one();
893 }
894 return Void();
895 }
896
processCaptureResult_3_4(const hidl_vec<V3_4::CaptureResult> & results)897 Return<void> CameraHidlTest::DeviceCb::processCaptureResult_3_4(
898 const hidl_vec<V3_4::CaptureResult>& results) {
899
900 if (nullptr == mParent) {
901 return Void();
902 }
903
904 bool notify = false;
905 std::unique_lock<std::mutex> l(mParent->mLock);
906 for (size_t i = 0 ; i < results.size(); i++) {
907 notify = processCaptureResultLocked(results[i].v3_2);
908 }
909
910 l.unlock();
911 if (notify) {
912 mParent->mResultCondition.notify_one();
913 }
914
915 return Void();
916 }
917
processCaptureResult(const hidl_vec<CaptureResult> & results)918 Return<void> CameraHidlTest::DeviceCb::processCaptureResult(
919 const hidl_vec<CaptureResult>& results) {
920 if (nullptr == mParent) {
921 return Void();
922 }
923
924 bool notify = false;
925 std::unique_lock<std::mutex> l(mParent->mLock);
926 for (size_t i = 0 ; i < results.size(); i++) {
927 notify = processCaptureResultLocked(results[i]);
928 }
929
930 l.unlock();
931 if (notify) {
932 mParent->mResultCondition.notify_one();
933 }
934
935 return Void();
936 }
937
processCaptureResultLocked(const CaptureResult & results)938 bool CameraHidlTest::DeviceCb::processCaptureResultLocked(const CaptureResult& results) {
939 bool notify = false;
940 uint32_t frameNumber = results.frameNumber;
941
942 if ((results.result.size() == 0) &&
943 (results.outputBuffers.size() == 0) &&
944 (results.inputBuffer.buffer == nullptr) &&
945 (results.fmqResultSize == 0)) {
946 ALOGE("%s: No result data provided by HAL for frame %d result count: %d",
947 __func__, frameNumber, (int) results.fmqResultSize);
948 ADD_FAILURE();
949 return notify;
950 }
951
952 ssize_t idx = mParent->mInflightMap.indexOfKey(frameNumber);
953 if (::android::NAME_NOT_FOUND == idx) {
954 ALOGE("%s: Unexpected frame number! received: %u",
955 __func__, frameNumber);
956 ADD_FAILURE();
957 return notify;
958 }
959
960 bool isPartialResult = false;
961 bool hasInputBufferInRequest = false;
962 InFlightRequest *request = mParent->mInflightMap.editValueAt(idx);
963 ::android::hardware::camera::device::V3_2::CameraMetadata resultMetadata;
964 size_t resultSize = 0;
965 if (results.fmqResultSize > 0) {
966 resultMetadata.resize(results.fmqResultSize);
967 if (request->resultQueue == nullptr) {
968 ADD_FAILURE();
969 return notify;
970 }
971 if (!request->resultQueue->read(resultMetadata.data(),
972 results.fmqResultSize)) {
973 ALOGE("%s: Frame %d: Cannot read camera metadata from fmq,"
974 "size = %" PRIu64, __func__, frameNumber,
975 results.fmqResultSize);
976 ADD_FAILURE();
977 return notify;
978 }
979 resultSize = resultMetadata.size();
980 } else if (results.result.size() > 0) {
981 resultMetadata.setToExternal(const_cast<uint8_t *>(
982 results.result.data()), results.result.size());
983 resultSize = resultMetadata.size();
984 }
985
986 if (!request->usePartialResult && (resultSize > 0) &&
987 (results.partialResult != 1)) {
988 ALOGE("%s: Result is malformed for frame %d: partial_result %u "
989 "must be 1 if partial result is not supported", __func__,
990 frameNumber, results.partialResult);
991 ADD_FAILURE();
992 return notify;
993 }
994
995 if (results.partialResult != 0) {
996 request->partialResultCount = results.partialResult;
997 }
998
999 // Check if this result carries only partial metadata
1000 if (request->usePartialResult && (resultSize > 0)) {
1001 if ((results.partialResult > request->numPartialResults) ||
1002 (results.partialResult < 1)) {
1003 ALOGE("%s: Result is malformed for frame %d: partial_result %u"
1004 " must be in the range of [1, %d] when metadata is "
1005 "included in the result", __func__, frameNumber,
1006 results.partialResult, request->numPartialResults);
1007 ADD_FAILURE();
1008 return notify;
1009 }
1010 request->collectedResult.append(
1011 reinterpret_cast<const camera_metadata_t*>(
1012 resultMetadata.data()));
1013
1014 isPartialResult =
1015 (results.partialResult < request->numPartialResults);
1016 } else if (resultSize > 0) {
1017 request->collectedResult.append(reinterpret_cast<const camera_metadata_t*>(
1018 resultMetadata.data()));
1019 isPartialResult = false;
1020 }
1021
1022 hasInputBufferInRequest = request->hasInputBuffer;
1023
1024 // Did we get the (final) result metadata for this capture?
1025 if ((resultSize > 0) && !isPartialResult) {
1026 if (request->haveResultMetadata) {
1027 ALOGE("%s: Called multiple times with metadata for frame %d",
1028 __func__, frameNumber);
1029 ADD_FAILURE();
1030 return notify;
1031 }
1032 request->haveResultMetadata = true;
1033 request->collectedResult.sort();
1034 }
1035
1036 uint32_t numBuffersReturned = results.outputBuffers.size();
1037 if (results.inputBuffer.buffer != nullptr) {
1038 if (hasInputBufferInRequest) {
1039 numBuffersReturned += 1;
1040 } else {
1041 ALOGW("%s: Input buffer should be NULL if there is no input"
1042 " buffer sent in the request", __func__);
1043 }
1044 }
1045 request->numBuffersLeft -= numBuffersReturned;
1046 if (request->numBuffersLeft < 0) {
1047 ALOGE("%s: Too many buffers returned for frame %d", __func__,
1048 frameNumber);
1049 ADD_FAILURE();
1050 return notify;
1051 }
1052
1053 request->resultOutputBuffers.appendArray(results.outputBuffers.data(),
1054 results.outputBuffers.size());
1055 // If shutter event is received notify the pending threads.
1056 if (request->shutterTimestamp != 0) {
1057 notify = true;
1058 }
1059 return notify;
1060 }
1061
notify(const hidl_vec<NotifyMsg> & messages)1062 Return<void> CameraHidlTest::DeviceCb::notify(
1063 const hidl_vec<NotifyMsg>& messages) {
1064 std::lock_guard<std::mutex> l(mParent->mLock);
1065
1066 for (size_t i = 0; i < messages.size(); i++) {
1067 ssize_t idx = mParent->mInflightMap.indexOfKey(
1068 messages[i].msg.shutter.frameNumber);
1069 if (::android::NAME_NOT_FOUND == idx) {
1070 ALOGE("%s: Unexpected frame number! received: %u",
1071 __func__, messages[i].msg.shutter.frameNumber);
1072 ADD_FAILURE();
1073 break;
1074 }
1075 InFlightRequest *r = mParent->mInflightMap.editValueAt(idx);
1076
1077 switch(messages[i].type) {
1078 case MsgType::ERROR:
1079 if (ErrorCode::ERROR_DEVICE == messages[i].msg.error.errorCode) {
1080 ALOGE("%s: Camera reported serious device error",
1081 __func__);
1082 ADD_FAILURE();
1083 } else {
1084 r->errorCodeValid = true;
1085 r->errorCode = messages[i].msg.error.errorCode;
1086 r->errorStreamId = messages[i].msg.error.errorStreamId;
1087 }
1088 break;
1089 case MsgType::SHUTTER:
1090 r->shutterTimestamp = messages[i].msg.shutter.timestamp;
1091 break;
1092 default:
1093 ALOGE("%s: Unsupported notify message %d", __func__,
1094 messages[i].type);
1095 ADD_FAILURE();
1096 break;
1097 }
1098 }
1099
1100 mParent->mResultCondition.notify_one();
1101 return Void();
1102 }
1103
getCameraDeviceNames(sp<ICameraProvider> provider)1104 hidl_vec<hidl_string> CameraHidlTest::getCameraDeviceNames(sp<ICameraProvider> provider) {
1105 std::vector<std::string> cameraDeviceNames;
1106 Return<void> ret;
1107 ret = provider->getCameraIdList(
1108 [&](auto status, const auto& idList) {
1109 ALOGI("getCameraIdList returns status:%d", (int)status);
1110 for (size_t i = 0; i < idList.size(); i++) {
1111 ALOGI("Camera Id[%zu] is %s", i, idList[i].c_str());
1112 }
1113 ASSERT_EQ(Status::OK, status);
1114 for (const auto& id : idList) {
1115 cameraDeviceNames.push_back(id);
1116 }
1117 });
1118 if (!ret.isOk()) {
1119 ADD_FAILURE();
1120 }
1121
1122 // External camera devices are reported through cameraDeviceStatusChange
1123 struct ProviderCb : public ICameraProviderCallback {
1124 virtual Return<void> cameraDeviceStatusChange(
1125 const hidl_string& devName,
1126 CameraDeviceStatus newStatus) override {
1127 ALOGI("camera device status callback name %s, status %d",
1128 devName.c_str(), (int) newStatus);
1129 if (newStatus == CameraDeviceStatus::PRESENT) {
1130 externalCameraDeviceNames.push_back(devName);
1131
1132 }
1133 return Void();
1134 }
1135
1136 virtual Return<void> torchModeStatusChange(
1137 const hidl_string&, TorchModeStatus) override {
1138 return Void();
1139 }
1140
1141 std::vector<std::string> externalCameraDeviceNames;
1142 };
1143 sp<ProviderCb> cb = new ProviderCb;
1144 auto status = mProvider->setCallback(cb);
1145
1146 for (const auto& devName : cb->externalCameraDeviceNames) {
1147 if (cameraDeviceNames.end() == std::find(
1148 cameraDeviceNames.begin(), cameraDeviceNames.end(), devName)) {
1149 cameraDeviceNames.push_back(devName);
1150 }
1151 }
1152
1153 hidl_vec<hidl_string> retList(cameraDeviceNames.size());
1154 for (size_t i = 0; i < cameraDeviceNames.size(); i++) {
1155 retList[i] = cameraDeviceNames[i];
1156 }
1157 return retList;
1158 }
1159
1160 // Test devices with first_api_level >= P does not advertise device@1.0
TEST_F(CameraHidlTest,noHal1AfterP)1161 TEST_F(CameraHidlTest, noHal1AfterP) {
1162 constexpr int32_t HAL1_PHASE_OUT_API_LEVEL = 28;
1163 int32_t firstApiLevel = property_get_int32("ro.product.first_api_level", /*default*/-1);
1164 if (firstApiLevel < 0) {
1165 firstApiLevel = property_get_int32("ro.build.version.sdk", /*default*/-1);
1166 }
1167 ASSERT_GT(firstApiLevel, 0); // first_api_level must exist
1168
1169 if (firstApiLevel >= HAL1_PHASE_OUT_API_LEVEL) {
1170 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
1171 for (const auto& name : cameraDeviceNames) {
1172 int deviceVersion = getCameraDeviceVersion(name, mProviderType);
1173 ASSERT_NE(deviceVersion, 0); // Must be a valid device version
1174 ASSERT_NE(deviceVersion, CAMERA_DEVICE_API_VERSION_1_0); // Must not be device@1.0
1175 }
1176 }
1177 }
1178
1179 // Test if ICameraProvider::isTorchModeSupported returns Status::OK
TEST_F(CameraHidlTest,isTorchModeSupported)1180 TEST_F(CameraHidlTest, isTorchModeSupported) {
1181 Return<void> ret;
1182 ret = mProvider->isSetTorchModeSupported([&](auto status, bool support) {
1183 ALOGI("isSetTorchModeSupported returns status:%d supported:%d", (int)status, support);
1184 ASSERT_EQ(Status::OK, status);
1185 });
1186 ASSERT_TRUE(ret.isOk());
1187 }
1188
1189 // TODO: consider removing this test if getCameraDeviceNames() has the same coverage
TEST_F(CameraHidlTest,getCameraIdList)1190 TEST_F(CameraHidlTest, getCameraIdList) {
1191 Return<void> ret;
1192 ret = mProvider->getCameraIdList([&](auto status, const auto& idList) {
1193 ALOGI("getCameraIdList returns status:%d", (int)status);
1194 for (size_t i = 0; i < idList.size(); i++) {
1195 ALOGI("Camera Id[%zu] is %s", i, idList[i].c_str());
1196 }
1197 ASSERT_EQ(Status::OK, status);
1198 });
1199 ASSERT_TRUE(ret.isOk());
1200 }
1201
1202 // Test if ICameraProvider::getVendorTags returns Status::OK
TEST_F(CameraHidlTest,getVendorTags)1203 TEST_F(CameraHidlTest, getVendorTags) {
1204 Return<void> ret;
1205 ret = mProvider->getVendorTags([&](auto status, const auto& vendorTagSecs) {
1206 ALOGI("getVendorTags returns status:%d numSections %zu", (int)status, vendorTagSecs.size());
1207 for (size_t i = 0; i < vendorTagSecs.size(); i++) {
1208 ALOGI("Vendor tag section %zu name %s", i, vendorTagSecs[i].sectionName.c_str());
1209 for (size_t j = 0; j < vendorTagSecs[i].tags.size(); j++) {
1210 const auto& tag = vendorTagSecs[i].tags[j];
1211 ALOGI("Vendor tag id %u name %s type %d", tag.tagId, tag.tagName.c_str(),
1212 (int)tag.tagType);
1213 }
1214 }
1215 ASSERT_EQ(Status::OK, status);
1216 });
1217 ASSERT_TRUE(ret.isOk());
1218 }
1219
1220 // Test if ICameraProvider::setCallback returns Status::OK
TEST_F(CameraHidlTest,setCallback)1221 TEST_F(CameraHidlTest, setCallback) {
1222 struct ProviderCb : public ICameraProviderCallback {
1223 virtual Return<void> cameraDeviceStatusChange(
1224 const hidl_string& cameraDeviceName,
1225 CameraDeviceStatus newStatus) override {
1226 ALOGI("camera device status callback name %s, status %d",
1227 cameraDeviceName.c_str(), (int) newStatus);
1228 return Void();
1229 }
1230
1231 virtual Return<void> torchModeStatusChange(
1232 const hidl_string& cameraDeviceName,
1233 TorchModeStatus newStatus) override {
1234 ALOGI("Torch mode status callback name %s, status %d",
1235 cameraDeviceName.c_str(), (int) newStatus);
1236 return Void();
1237 }
1238 };
1239 sp<ProviderCb> cb = new ProviderCb;
1240 auto status = mProvider->setCallback(cb);
1241 ASSERT_TRUE(status.isOk());
1242 ASSERT_EQ(Status::OK, status);
1243 status = mProvider->setCallback(nullptr);
1244 ASSERT_TRUE(status.isOk());
1245 ASSERT_EQ(Status::OK, status);
1246 }
1247
1248 // Test if ICameraProvider::getCameraDeviceInterface returns Status::OK and non-null device
TEST_F(CameraHidlTest,getCameraDeviceInterface)1249 TEST_F(CameraHidlTest, getCameraDeviceInterface) {
1250 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
1251
1252 for (const auto& name : cameraDeviceNames) {
1253 int deviceVersion = getCameraDeviceVersion(name, mProviderType);
1254 switch (deviceVersion) {
1255 case CAMERA_DEVICE_API_VERSION_3_4:
1256 case CAMERA_DEVICE_API_VERSION_3_3:
1257 case CAMERA_DEVICE_API_VERSION_3_2: {
1258 Return<void> ret;
1259 ret = mProvider->getCameraDeviceInterface_V3_x(
1260 name, [&](auto status, const auto& device3_x) {
1261 ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
1262 ASSERT_EQ(Status::OK, status);
1263 ASSERT_NE(device3_x, nullptr);
1264 });
1265 ASSERT_TRUE(ret.isOk());
1266 }
1267 break;
1268 case CAMERA_DEVICE_API_VERSION_1_0: {
1269 Return<void> ret;
1270 ret = mProvider->getCameraDeviceInterface_V1_x(
1271 name, [&](auto status, const auto& device1) {
1272 ALOGI("getCameraDeviceInterface_V1_x returns status:%d", (int)status);
1273 ASSERT_EQ(Status::OK, status);
1274 ASSERT_NE(device1, nullptr);
1275 });
1276 ASSERT_TRUE(ret.isOk());
1277 }
1278 break;
1279 default: {
1280 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
1281 ADD_FAILURE();
1282 }
1283 break;
1284 }
1285 }
1286 }
1287
1288 // Verify that the device resource cost can be retrieved and the values are
1289 // sane.
TEST_F(CameraHidlTest,getResourceCost)1290 TEST_F(CameraHidlTest, getResourceCost) {
1291 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
1292
1293 for (const auto& name : cameraDeviceNames) {
1294 int deviceVersion = getCameraDeviceVersion(name, mProviderType);
1295 switch (deviceVersion) {
1296 case CAMERA_DEVICE_API_VERSION_3_4:
1297 case CAMERA_DEVICE_API_VERSION_3_3:
1298 case CAMERA_DEVICE_API_VERSION_3_2: {
1299 ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_x;
1300 ALOGI("getResourceCost: Testing camera device %s", name.c_str());
1301 Return<void> ret;
1302 ret = mProvider->getCameraDeviceInterface_V3_x(
1303 name, [&](auto status, const auto& device) {
1304 ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
1305 ASSERT_EQ(Status::OK, status);
1306 ASSERT_NE(device, nullptr);
1307 device3_x = device;
1308 });
1309 ASSERT_TRUE(ret.isOk());
1310
1311 ret = device3_x->getResourceCost([&](auto status, const auto& resourceCost) {
1312 ALOGI("getResourceCost returns status:%d", (int)status);
1313 ASSERT_EQ(Status::OK, status);
1314 ALOGI(" Resource cost is %d", resourceCost.resourceCost);
1315 ASSERT_LE(resourceCost.resourceCost, 100u);
1316 for (const auto& name : resourceCost.conflictingDevices) {
1317 ALOGI(" Conflicting device: %s", name.c_str());
1318 }
1319 });
1320 ASSERT_TRUE(ret.isOk());
1321 }
1322 break;
1323 case CAMERA_DEVICE_API_VERSION_1_0: {
1324 ::android::sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
1325 ALOGI("getResourceCost: Testing camera device %s", name.c_str());
1326 Return<void> ret;
1327 ret = mProvider->getCameraDeviceInterface_V1_x(
1328 name, [&](auto status, const auto& device) {
1329 ALOGI("getCameraDeviceInterface_V1_x returns status:%d", (int)status);
1330 ASSERT_EQ(Status::OK, status);
1331 ASSERT_NE(device, nullptr);
1332 device1 = device;
1333 });
1334 ASSERT_TRUE(ret.isOk());
1335
1336 ret = device1->getResourceCost([&](auto status, const auto& resourceCost) {
1337 ALOGI("getResourceCost returns status:%d", (int)status);
1338 ASSERT_EQ(Status::OK, status);
1339 ALOGI(" Resource cost is %d", resourceCost.resourceCost);
1340 ASSERT_LE(resourceCost.resourceCost, 100u);
1341 for (const auto& name : resourceCost.conflictingDevices) {
1342 ALOGI(" Conflicting device: %s", name.c_str());
1343 }
1344 });
1345 ASSERT_TRUE(ret.isOk());
1346 }
1347 break;
1348 default: {
1349 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
1350 ADD_FAILURE();
1351 }
1352 break;
1353 }
1354 }
1355 }
1356
1357 // Verify that the static camera info can be retrieved
1358 // successfully.
TEST_F(CameraHidlTest,getCameraInfo)1359 TEST_F(CameraHidlTest, getCameraInfo) {
1360 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
1361
1362 for (const auto& name : cameraDeviceNames) {
1363 if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_1_0) {
1364 ::android::sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
1365 ALOGI("getCameraCharacteristics: Testing camera device %s", name.c_str());
1366 Return<void> ret;
1367 ret = mProvider->getCameraDeviceInterface_V1_x(
1368 name, [&](auto status, const auto& device) {
1369 ALOGI("getCameraDeviceInterface_V1_x returns status:%d", (int)status);
1370 ASSERT_EQ(Status::OK, status);
1371 ASSERT_NE(device, nullptr);
1372 device1 = device;
1373 });
1374 ASSERT_TRUE(ret.isOk());
1375
1376 ret = device1->getCameraInfo([&](auto status, const auto& info) {
1377 ALOGI("getCameraInfo returns status:%d", (int)status);
1378 ASSERT_EQ(Status::OK, status);
1379 switch (info.orientation) {
1380 case 0:
1381 case 90:
1382 case 180:
1383 case 270:
1384 // Expected cases
1385 ALOGI("camera orientation: %d", info.orientation);
1386 break;
1387 default:
1388 FAIL() << "Unexpected camera orientation:" << info.orientation;
1389 }
1390 switch (info.facing) {
1391 case CameraFacing::BACK:
1392 case CameraFacing::FRONT:
1393 case CameraFacing::EXTERNAL:
1394 // Expected cases
1395 ALOGI("camera facing: %d", info.facing);
1396 break;
1397 default:
1398 FAIL() << "Unexpected camera facing:" << static_cast<uint32_t>(info.facing);
1399 }
1400 });
1401 ASSERT_TRUE(ret.isOk());
1402 }
1403 }
1404 }
1405
1406 // Check whether preview window can be configured
TEST_F(CameraHidlTest,setPreviewWindow)1407 TEST_F(CameraHidlTest, setPreviewWindow) {
1408 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
1409
1410 for (const auto& name : cameraDeviceNames) {
1411 if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_1_0) {
1412 sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
1413 openCameraDevice(name, mProvider, &device1 /*out*/);
1414 ASSERT_NE(nullptr, device1.get());
1415 sp<BufferItemConsumer> bufferItemConsumer;
1416 sp<BufferItemHander> bufferHandler;
1417 setupPreviewWindow(device1, &bufferItemConsumer /*out*/, &bufferHandler /*out*/);
1418
1419 Return<void> ret;
1420 ret = device1->close();
1421 ASSERT_TRUE(ret.isOk());
1422 }
1423 }
1424 }
1425
1426 // Verify that setting preview window fails in case device is not open
TEST_F(CameraHidlTest,setPreviewWindowInvalid)1427 TEST_F(CameraHidlTest, setPreviewWindowInvalid) {
1428 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
1429
1430 for (const auto& name : cameraDeviceNames) {
1431 if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_1_0) {
1432 ::android::sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
1433 ALOGI("getCameraCharacteristics: Testing camera device %s", name.c_str());
1434 Return<void> ret;
1435 ret = mProvider->getCameraDeviceInterface_V1_x(
1436 name, [&](auto status, const auto& device) {
1437 ALOGI("getCameraDeviceInterface_V1_x returns status:%d", (int)status);
1438 ASSERT_EQ(Status::OK, status);
1439 ASSERT_NE(device, nullptr);
1440 device1 = device;
1441 });
1442 ASSERT_TRUE(ret.isOk());
1443
1444 Return<Status> returnStatus = device1->setPreviewWindow(nullptr);
1445 ASSERT_TRUE(returnStatus.isOk());
1446 ASSERT_EQ(Status::OPERATION_NOT_SUPPORTED, returnStatus);
1447 }
1448 }
1449 }
1450
1451 // Start and stop preview checking whether it gets enabled in between.
TEST_F(CameraHidlTest,startStopPreview)1452 TEST_F(CameraHidlTest, startStopPreview) {
1453 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
1454
1455 for (const auto& name : cameraDeviceNames) {
1456 if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_1_0) {
1457 sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
1458 openCameraDevice(name, mProvider, &device1 /*out*/);
1459 ASSERT_NE(nullptr, device1.get());
1460 sp<BufferItemConsumer> bufferItemConsumer;
1461 sp<BufferItemHander> bufferHandler;
1462 setupPreviewWindow(device1, &bufferItemConsumer /*out*/, &bufferHandler /*out*/);
1463
1464 startPreview(device1);
1465
1466 Return<bool> returnBoolStatus = device1->previewEnabled();
1467 ASSERT_TRUE(returnBoolStatus.isOk());
1468 ASSERT_TRUE(returnBoolStatus);
1469
1470 stopPreviewAndClose(device1);
1471 }
1472 }
1473 }
1474
1475 // Start preview without active preview window. Preview should start as soon
1476 // as a valid active window gets configured.
TEST_F(CameraHidlTest,startStopPreviewDelayed)1477 TEST_F(CameraHidlTest, startStopPreviewDelayed) {
1478 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
1479
1480 for (const auto& name : cameraDeviceNames) {
1481 if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_1_0) {
1482 sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
1483 openCameraDevice(name, mProvider, &device1 /*out*/);
1484 ASSERT_NE(nullptr, device1.get());
1485
1486 Return<Status> returnStatus = device1->setPreviewWindow(nullptr);
1487 ASSERT_TRUE(returnStatus.isOk());
1488 ASSERT_EQ(Status::OK, returnStatus);
1489
1490 startPreview(device1);
1491
1492 sp<BufferItemConsumer> bufferItemConsumer;
1493 sp<BufferItemHander> bufferHandler;
1494 setupPreviewWindow(device1, &bufferItemConsumer /*out*/, &bufferHandler /*out*/);
1495
1496 // Preview should get enabled now
1497 Return<bool> returnBoolStatus = device1->previewEnabled();
1498 ASSERT_TRUE(returnBoolStatus.isOk());
1499 ASSERT_TRUE(returnBoolStatus);
1500
1501 stopPreviewAndClose(device1);
1502 }
1503 }
1504 }
1505
1506 // Verify that image capture behaves as expected along with preview callbacks.
TEST_F(CameraHidlTest,takePicture)1507 TEST_F(CameraHidlTest, takePicture) {
1508 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
1509
1510 for (const auto& name : cameraDeviceNames) {
1511 if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_1_0) {
1512 sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
1513 openCameraDevice(name, mProvider, &device1 /*out*/);
1514 ASSERT_NE(nullptr, device1.get());
1515 sp<BufferItemConsumer> bufferItemConsumer;
1516 sp<BufferItemHander> bufferHandler;
1517 setupPreviewWindow(device1, &bufferItemConsumer /*out*/, &bufferHandler /*out*/);
1518
1519 {
1520 std::unique_lock<std::mutex> l(mLock);
1521 mDataMessageTypeReceived = DataCallbackMsg::RAW_IMAGE_NOTIFY;
1522 }
1523
1524 enableMsgType((unsigned int)DataCallbackMsg::PREVIEW_FRAME, device1);
1525 startPreview(device1);
1526
1527 {
1528 std::unique_lock<std::mutex> l(mLock);
1529 waitForFrameLocked(DataCallbackMsg::PREVIEW_FRAME, l);
1530 }
1531
1532 disableMsgType((unsigned int)DataCallbackMsg::PREVIEW_FRAME, device1);
1533 enableMsgType((unsigned int)DataCallbackMsg::COMPRESSED_IMAGE, device1);
1534
1535 {
1536 std::unique_lock<std::mutex> l(mLock);
1537 mDataMessageTypeReceived = DataCallbackMsg::RAW_IMAGE_NOTIFY;
1538 }
1539
1540 Return<Status> returnStatus = device1->takePicture();
1541 ASSERT_TRUE(returnStatus.isOk());
1542 ASSERT_EQ(Status::OK, returnStatus);
1543
1544 {
1545 std::unique_lock<std::mutex> l(mLock);
1546 waitForFrameLocked(DataCallbackMsg::COMPRESSED_IMAGE, l);
1547 }
1548
1549 disableMsgType((unsigned int)DataCallbackMsg::COMPRESSED_IMAGE, device1);
1550 stopPreviewAndClose(device1);
1551 }
1552 }
1553 }
1554
1555 // Image capture should fail in case preview didn't get enabled first.
TEST_F(CameraHidlTest,takePictureFail)1556 TEST_F(CameraHidlTest, takePictureFail) {
1557 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
1558
1559 for (const auto& name : cameraDeviceNames) {
1560 if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_1_0) {
1561 sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
1562 openCameraDevice(name, mProvider, &device1 /*out*/);
1563 ASSERT_NE(nullptr, device1.get());
1564
1565 Return<Status> returnStatus = device1->takePicture();
1566 ASSERT_TRUE(returnStatus.isOk());
1567 ASSERT_NE(Status::OK, returnStatus);
1568
1569 Return<void> ret = device1->close();
1570 ASSERT_TRUE(ret.isOk());
1571 }
1572 }
1573 }
1574
1575 // Verify that image capture can be cancelled.
TEST_F(CameraHidlTest,cancelPicture)1576 TEST_F(CameraHidlTest, cancelPicture) {
1577 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
1578
1579 for (const auto& name : cameraDeviceNames) {
1580 if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_1_0) {
1581 sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
1582 openCameraDevice(name, mProvider, &device1 /*out*/);
1583 ASSERT_NE(nullptr, device1.get());
1584 sp<BufferItemConsumer> bufferItemConsumer;
1585 sp<BufferItemHander> bufferHandler;
1586 setupPreviewWindow(device1, &bufferItemConsumer /*out*/, &bufferHandler /*out*/);
1587 startPreview(device1);
1588
1589 Return<Status> returnStatus = device1->takePicture();
1590 ASSERT_TRUE(returnStatus.isOk());
1591 ASSERT_EQ(Status::OK, returnStatus);
1592
1593 returnStatus = device1->cancelPicture();
1594 ASSERT_TRUE(returnStatus.isOk());
1595 ASSERT_EQ(Status::OK, returnStatus);
1596
1597 stopPreviewAndClose(device1);
1598 }
1599 }
1600 }
1601
1602 // Image capture cancel is a no-op when image capture is not running.
TEST_F(CameraHidlTest,cancelPictureNOP)1603 TEST_F(CameraHidlTest, cancelPictureNOP) {
1604 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
1605
1606 for (const auto& name : cameraDeviceNames) {
1607 if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_1_0) {
1608 sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
1609 openCameraDevice(name, mProvider, &device1 /*out*/);
1610 ASSERT_NE(nullptr, device1.get());
1611 sp<BufferItemConsumer> bufferItemConsumer;
1612 sp<BufferItemHander> bufferHandler;
1613 setupPreviewWindow(device1, &bufferItemConsumer /*out*/, &bufferHandler /*out*/);
1614 startPreview(device1);
1615
1616 Return<Status> returnStatus = device1->cancelPicture();
1617 ASSERT_TRUE(returnStatus.isOk());
1618 ASSERT_EQ(Status::OK, returnStatus);
1619
1620 stopPreviewAndClose(device1);
1621 }
1622 }
1623 }
1624
1625 // Test basic video recording.
TEST_F(CameraHidlTest,startStopRecording)1626 TEST_F(CameraHidlTest, startStopRecording) {
1627 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
1628
1629 for (const auto& name : cameraDeviceNames) {
1630 if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_1_0) {
1631 sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
1632 openCameraDevice(name, mProvider, &device1 /*out*/);
1633 ASSERT_NE(nullptr, device1.get());
1634 sp<BufferItemConsumer> bufferItemConsumer;
1635 sp<BufferItemHander> bufferHandler;
1636 setupPreviewWindow(device1, &bufferItemConsumer /*out*/, &bufferHandler /*out*/);
1637
1638 {
1639 std::unique_lock<std::mutex> l(mLock);
1640 mDataMessageTypeReceived = DataCallbackMsg::RAW_IMAGE_NOTIFY;
1641 }
1642
1643 enableMsgType((unsigned int)DataCallbackMsg::PREVIEW_FRAME, device1);
1644 startPreview(device1);
1645
1646 {
1647 std::unique_lock<std::mutex> l(mLock);
1648 waitForFrameLocked(DataCallbackMsg::PREVIEW_FRAME, l);
1649 mDataMessageTypeReceived = DataCallbackMsg::RAW_IMAGE_NOTIFY;
1650 mVideoBufferIndex = UINT32_MAX;
1651 }
1652
1653 disableMsgType((unsigned int)DataCallbackMsg::PREVIEW_FRAME, device1);
1654
1655 bool videoMetaEnabled = false;
1656 Return<Status> returnStatus = device1->storeMetaDataInBuffers(true);
1657 ASSERT_TRUE(returnStatus.isOk());
1658 // It is allowed for devices to not support this feature
1659 ASSERT_TRUE((Status::OK == returnStatus) ||
1660 (Status::OPERATION_NOT_SUPPORTED == returnStatus));
1661 if (Status::OK == returnStatus) {
1662 videoMetaEnabled = true;
1663 }
1664
1665 enableMsgType((unsigned int)DataCallbackMsg::VIDEO_FRAME, device1);
1666 Return<bool> returnBoolStatus = device1->recordingEnabled();
1667 ASSERT_TRUE(returnBoolStatus.isOk());
1668 ASSERT_FALSE(returnBoolStatus);
1669
1670 returnStatus = device1->startRecording();
1671 ASSERT_TRUE(returnStatus.isOk());
1672 ASSERT_EQ(Status::OK, returnStatus);
1673
1674 {
1675 std::unique_lock<std::mutex> l(mLock);
1676 waitForFrameLocked(DataCallbackMsg::VIDEO_FRAME, l);
1677 ASSERT_NE(UINT32_MAX, mVideoBufferIndex);
1678 disableMsgType((unsigned int)DataCallbackMsg::VIDEO_FRAME, device1);
1679 }
1680
1681 returnBoolStatus = device1->recordingEnabled();
1682 ASSERT_TRUE(returnBoolStatus.isOk());
1683 ASSERT_TRUE(returnBoolStatus);
1684
1685 Return<void> ret;
1686 if (videoMetaEnabled) {
1687 ret = device1->releaseRecordingFrameHandle(mVideoData, mVideoBufferIndex,
1688 mVideoNativeHandle);
1689 ASSERT_TRUE(ret.isOk());
1690 } else {
1691 ret = device1->releaseRecordingFrame(mVideoData, mVideoBufferIndex);
1692 ASSERT_TRUE(ret.isOk());
1693 }
1694
1695 ret = device1->stopRecording();
1696 ASSERT_TRUE(ret.isOk());
1697
1698 stopPreviewAndClose(device1);
1699 }
1700 }
1701 }
1702
1703 // It shouldn't be possible to start recording without enabling preview first.
TEST_F(CameraHidlTest,startRecordingFail)1704 TEST_F(CameraHidlTest, startRecordingFail) {
1705 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
1706
1707 for (const auto& name : cameraDeviceNames) {
1708 if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_1_0) {
1709 sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
1710 openCameraDevice(name, mProvider, &device1 /*out*/);
1711 ASSERT_NE(nullptr, device1.get());
1712
1713 Return<bool> returnBoolStatus = device1->recordingEnabled();
1714 ASSERT_TRUE(returnBoolStatus.isOk());
1715 ASSERT_FALSE(returnBoolStatus);
1716
1717 Return<Status> returnStatus = device1->startRecording();
1718 ASSERT_TRUE(returnStatus.isOk());
1719 ASSERT_NE(Status::OK, returnStatus);
1720
1721 Return<void> ret = device1->close();
1722 ASSERT_TRUE(ret.isOk());
1723 }
1724 }
1725 }
1726
1727 // Check autofocus support if available.
TEST_F(CameraHidlTest,autoFocus)1728 TEST_F(CameraHidlTest, autoFocus) {
1729 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
1730 std::vector<const char*> focusModes = {CameraParameters::FOCUS_MODE_AUTO,
1731 CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE,
1732 CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO};
1733
1734 for (const auto& name : cameraDeviceNames) {
1735 if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_1_0) {
1736 sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
1737 openCameraDevice(name, mProvider, &device1 /*out*/);
1738 ASSERT_NE(nullptr, device1.get());
1739
1740 CameraParameters cameraParams;
1741 getParameters(device1, &cameraParams /*out*/);
1742
1743 if (Status::OK !=
1744 isAutoFocusModeAvailable(cameraParams, CameraParameters::FOCUS_MODE_AUTO)) {
1745 Return<void> ret = device1->close();
1746 ASSERT_TRUE(ret.isOk());
1747 continue;
1748 }
1749
1750 sp<BufferItemConsumer> bufferItemConsumer;
1751 sp<BufferItemHander> bufferHandler;
1752 setupPreviewWindow(device1, &bufferItemConsumer /*out*/, &bufferHandler /*out*/);
1753 startPreview(device1);
1754 enableMsgType((unsigned int)NotifyCallbackMsg::FOCUS, device1);
1755
1756 for (auto& iter : focusModes) {
1757 if (Status::OK != isAutoFocusModeAvailable(cameraParams, iter)) {
1758 continue;
1759 }
1760
1761 cameraParams.set(CameraParameters::KEY_FOCUS_MODE, iter);
1762 setParameters(device1, cameraParams);
1763 {
1764 std::unique_lock<std::mutex> l(mLock);
1765 mNotifyMessage = NotifyCallbackMsg::ERROR;
1766 }
1767
1768 Return<Status> returnStatus = device1->autoFocus();
1769 ASSERT_TRUE(returnStatus.isOk());
1770 ASSERT_EQ(Status::OK, returnStatus);
1771
1772 {
1773 std::unique_lock<std::mutex> l(mLock);
1774 while (NotifyCallbackMsg::FOCUS != mNotifyMessage) {
1775 auto timeout = std::chrono::system_clock::now() +
1776 std::chrono::seconds(kAutoFocusTimeoutSec);
1777 ASSERT_NE(std::cv_status::timeout, mResultCondition.wait_until(l, timeout));
1778 }
1779 }
1780 }
1781
1782 disableMsgType((unsigned int)NotifyCallbackMsg::FOCUS, device1);
1783 stopPreviewAndClose(device1);
1784 }
1785 }
1786 }
1787
1788 // In case autofocus is supported verify that it can be cancelled.
TEST_F(CameraHidlTest,cancelAutoFocus)1789 TEST_F(CameraHidlTest, cancelAutoFocus) {
1790 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
1791
1792 for (const auto& name : cameraDeviceNames) {
1793 if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_1_0) {
1794 sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
1795 openCameraDevice(name, mProvider, &device1 /*out*/);
1796 ASSERT_NE(nullptr, device1.get());
1797
1798 CameraParameters cameraParams;
1799 getParameters(device1, &cameraParams /*out*/);
1800
1801 if (Status::OK !=
1802 isAutoFocusModeAvailable(cameraParams, CameraParameters::FOCUS_MODE_AUTO)) {
1803 Return<void> ret = device1->close();
1804 ASSERT_TRUE(ret.isOk());
1805 continue;
1806 }
1807
1808 // It should be fine to call before preview starts.
1809 ASSERT_EQ(Status::OK, device1->cancelAutoFocus());
1810
1811 sp<BufferItemConsumer> bufferItemConsumer;
1812 sp<BufferItemHander> bufferHandler;
1813 setupPreviewWindow(device1, &bufferItemConsumer /*out*/, &bufferHandler /*out*/);
1814 startPreview(device1);
1815
1816 // It should be fine to call after preview starts too.
1817 Return<Status> returnStatus = device1->cancelAutoFocus();
1818 ASSERT_TRUE(returnStatus.isOk());
1819 ASSERT_EQ(Status::OK, returnStatus);
1820
1821 returnStatus = device1->autoFocus();
1822 ASSERT_TRUE(returnStatus.isOk());
1823 ASSERT_EQ(Status::OK, returnStatus);
1824
1825 returnStatus = device1->cancelAutoFocus();
1826 ASSERT_TRUE(returnStatus.isOk());
1827 ASSERT_EQ(Status::OK, returnStatus);
1828
1829 stopPreviewAndClose(device1);
1830 }
1831 }
1832 }
1833
1834 // Check whether face detection is available and try to enable&disable.
TEST_F(CameraHidlTest,sendCommandFaceDetection)1835 TEST_F(CameraHidlTest, sendCommandFaceDetection) {
1836 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
1837
1838 for (const auto& name : cameraDeviceNames) {
1839 if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_1_0) {
1840 sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
1841 openCameraDevice(name, mProvider, &device1 /*out*/);
1842 ASSERT_NE(nullptr, device1.get());
1843
1844 CameraParameters cameraParams;
1845 getParameters(device1, &cameraParams /*out*/);
1846
1847 int32_t hwFaces = cameraParams.getInt(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_HW);
1848 int32_t swFaces = cameraParams.getInt(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_SW);
1849 if ((0 >= hwFaces) && (0 >= swFaces)) {
1850 Return<void> ret = device1->close();
1851 ASSERT_TRUE(ret.isOk());
1852 continue;
1853 }
1854
1855 sp<BufferItemConsumer> bufferItemConsumer;
1856 sp<BufferItemHander> bufferHandler;
1857 setupPreviewWindow(device1, &bufferItemConsumer /*out*/, &bufferHandler /*out*/);
1858 startPreview(device1);
1859
1860 if (0 < hwFaces) {
1861 Return<Status> returnStatus = device1->sendCommand(
1862 CommandType::START_FACE_DETECTION, CAMERA_FACE_DETECTION_HW, 0);
1863 ASSERT_TRUE(returnStatus.isOk());
1864 ASSERT_EQ(Status::OK, returnStatus);
1865 // TODO(epeev) : Enable and check for face notifications
1866 returnStatus = device1->sendCommand(CommandType::STOP_FACE_DETECTION,
1867 CAMERA_FACE_DETECTION_HW, 0);
1868 ASSERT_TRUE(returnStatus.isOk());
1869 ASSERT_EQ(Status::OK, returnStatus);
1870 }
1871
1872 if (0 < swFaces) {
1873 Return<Status> returnStatus = device1->sendCommand(
1874 CommandType::START_FACE_DETECTION, CAMERA_FACE_DETECTION_SW, 0);
1875 ASSERT_TRUE(returnStatus.isOk());
1876 ASSERT_EQ(Status::OK, returnStatus);
1877 // TODO(epeev) : Enable and check for face notifications
1878 returnStatus = device1->sendCommand(CommandType::STOP_FACE_DETECTION,
1879 CAMERA_FACE_DETECTION_SW, 0);
1880 ASSERT_TRUE(returnStatus.isOk());
1881 ASSERT_EQ(Status::OK, returnStatus);
1882 }
1883
1884 stopPreviewAndClose(device1);
1885 }
1886 }
1887 }
1888
1889 // Check whether smooth zoom is available and try to enable&disable.
TEST_F(CameraHidlTest,sendCommandSmoothZoom)1890 TEST_F(CameraHidlTest, sendCommandSmoothZoom) {
1891 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
1892
1893 for (const auto& name : cameraDeviceNames) {
1894 if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_1_0) {
1895 sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
1896 openCameraDevice(name, mProvider, &device1 /*out*/);
1897 ASSERT_NE(nullptr, device1.get());
1898
1899 CameraParameters cameraParams;
1900 getParameters(device1, &cameraParams /*out*/);
1901
1902 const char* smoothZoomStr =
1903 cameraParams.get(CameraParameters::KEY_SMOOTH_ZOOM_SUPPORTED);
1904 bool smoothZoomSupported =
1905 ((nullptr != smoothZoomStr) && (strcmp(smoothZoomStr, CameraParameters::TRUE) == 0))
1906 ? true
1907 : false;
1908 if (!smoothZoomSupported) {
1909 Return<void> ret = device1->close();
1910 ASSERT_TRUE(ret.isOk());
1911 continue;
1912 }
1913
1914 int32_t maxZoom = cameraParams.getInt(CameraParameters::KEY_MAX_ZOOM);
1915 ASSERT_TRUE(0 < maxZoom);
1916
1917 sp<BufferItemConsumer> bufferItemConsumer;
1918 sp<BufferItemHander> bufferHandler;
1919 setupPreviewWindow(device1, &bufferItemConsumer /*out*/, &bufferHandler /*out*/);
1920 startPreview(device1);
1921 setParameters(device1, cameraParams);
1922
1923 Return<Status> returnStatus =
1924 device1->sendCommand(CommandType::START_SMOOTH_ZOOM, maxZoom, 0);
1925 ASSERT_TRUE(returnStatus.isOk());
1926 ASSERT_EQ(Status::OK, returnStatus);
1927 // TODO(epeev) : Enable and check for face notifications
1928 returnStatus = device1->sendCommand(CommandType::STOP_SMOOTH_ZOOM, 0, 0);
1929 ASSERT_TRUE(returnStatus.isOk());
1930 ASSERT_EQ(Status::OK, returnStatus);
1931
1932 stopPreviewAndClose(device1);
1933 }
1934 }
1935 }
1936
1937 // Basic sanity tests related to camera parameters.
TEST_F(CameraHidlTest,getSetParameters)1938 TEST_F(CameraHidlTest, getSetParameters) {
1939 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
1940
1941 for (const auto& name : cameraDeviceNames) {
1942 if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_1_0) {
1943 sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
1944 openCameraDevice(name, mProvider, &device1 /*out*/);
1945 ASSERT_NE(nullptr, device1.get());
1946
1947 CameraParameters cameraParams;
1948 getParameters(device1, &cameraParams /*out*/);
1949
1950 int32_t width, height;
1951 cameraParams.getPictureSize(&width, &height);
1952 ASSERT_TRUE((0 < width) && (0 < height));
1953 cameraParams.getPreviewSize(&width, &height);
1954 ASSERT_TRUE((0 < width) && (0 < height));
1955 int32_t minFps, maxFps;
1956 cameraParams.getPreviewFpsRange(&minFps, &maxFps);
1957 ASSERT_TRUE((0 < minFps) && (0 < maxFps));
1958 ASSERT_NE(nullptr, cameraParams.getPreviewFormat());
1959 ASSERT_NE(nullptr, cameraParams.getPictureFormat());
1960 ASSERT_TRUE(
1961 strcmp(CameraParameters::PIXEL_FORMAT_JPEG, cameraParams.getPictureFormat()) == 0);
1962
1963 const char* flashMode = cameraParams.get(CameraParameters::KEY_FLASH_MODE);
1964 ASSERT_TRUE((nullptr == flashMode) ||
1965 (strcmp(CameraParameters::FLASH_MODE_OFF, flashMode) == 0));
1966
1967 const char* wbMode = cameraParams.get(CameraParameters::KEY_WHITE_BALANCE);
1968 ASSERT_TRUE((nullptr == wbMode) ||
1969 (strcmp(CameraParameters::WHITE_BALANCE_AUTO, wbMode) == 0));
1970
1971 const char* effect = cameraParams.get(CameraParameters::KEY_EFFECT);
1972 ASSERT_TRUE((nullptr == effect) ||
1973 (strcmp(CameraParameters::EFFECT_NONE, effect) == 0));
1974
1975 ::android::Vector<Size> previewSizes;
1976 cameraParams.getSupportedPreviewSizes(previewSizes);
1977 ASSERT_FALSE(previewSizes.empty());
1978 ::android::Vector<Size> pictureSizes;
1979 cameraParams.getSupportedPictureSizes(pictureSizes);
1980 ASSERT_FALSE(pictureSizes.empty());
1981 const char* previewFormats =
1982 cameraParams.get(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS);
1983 ASSERT_NE(nullptr, previewFormats);
1984 ::android::String8 previewFormatsString(previewFormats);
1985 ASSERT_TRUE(previewFormatsString.contains(CameraParameters::PIXEL_FORMAT_YUV420SP));
1986 ASSERT_NE(nullptr, cameraParams.get(CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS));
1987 ASSERT_NE(nullptr,
1988 cameraParams.get(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES));
1989 const char* focusModes = cameraParams.get(CameraParameters::KEY_SUPPORTED_FOCUS_MODES);
1990 ASSERT_NE(nullptr, focusModes);
1991 ::android::String8 focusModesString(focusModes);
1992 const char* focusMode = cameraParams.get(CameraParameters::KEY_FOCUS_MODE);
1993 ASSERT_NE(nullptr, focusMode);
1994 // Auto focus mode should be default
1995 if (focusModesString.contains(CameraParameters::FOCUS_MODE_AUTO)) {
1996 ASSERT_TRUE(strcmp(CameraParameters::FOCUS_MODE_AUTO, focusMode) == 0);
1997 }
1998 ASSERT_TRUE(0 < cameraParams.getInt(CameraParameters::KEY_FOCAL_LENGTH));
1999 int32_t horizontalViewAngle =
2000 cameraParams.getInt(CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE);
2001 ASSERT_TRUE((0 < horizontalViewAngle) && (360 >= horizontalViewAngle));
2002 int32_t verticalViewAngle =
2003 cameraParams.getInt(CameraParameters::KEY_VERTICAL_VIEW_ANGLE);
2004 ASSERT_TRUE((0 < verticalViewAngle) && (360 >= verticalViewAngle));
2005 int32_t jpegQuality = cameraParams.getInt(CameraParameters::KEY_JPEG_QUALITY);
2006 ASSERT_TRUE((1 <= jpegQuality) && (100 >= jpegQuality));
2007 int32_t jpegThumbQuality =
2008 cameraParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY);
2009 ASSERT_TRUE((1 <= jpegThumbQuality) && (100 >= jpegThumbQuality));
2010
2011 cameraParams.setPictureSize(pictureSizes[0].width, pictureSizes[0].height);
2012 cameraParams.setPreviewSize(previewSizes[0].width, previewSizes[0].height);
2013
2014 setParameters(device1, cameraParams);
2015 getParameters(device1, &cameraParams /*out*/);
2016
2017 cameraParams.getPictureSize(&width, &height);
2018 ASSERT_TRUE((pictureSizes[0].width == width) && (pictureSizes[0].height == height));
2019 cameraParams.getPreviewSize(&width, &height);
2020 ASSERT_TRUE((previewSizes[0].width == width) && (previewSizes[0].height == height));
2021
2022 Return<void> ret = device1->close();
2023 ASSERT_TRUE(ret.isOk());
2024 }
2025 }
2026 }
2027
2028 // Verify that the static camera characteristics can be retrieved
2029 // successfully.
TEST_F(CameraHidlTest,getCameraCharacteristics)2030 TEST_F(CameraHidlTest, getCameraCharacteristics) {
2031 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
2032
2033 for (const auto& name : cameraDeviceNames) {
2034 int deviceVersion = getCameraDeviceVersion(name, mProviderType);
2035 switch (deviceVersion) {
2036 case CAMERA_DEVICE_API_VERSION_3_4:
2037 case CAMERA_DEVICE_API_VERSION_3_3:
2038 case CAMERA_DEVICE_API_VERSION_3_2: {
2039 ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_x;
2040 ALOGI("getCameraCharacteristics: Testing camera device %s", name.c_str());
2041 Return<void> ret;
2042 ret = mProvider->getCameraDeviceInterface_V3_x(
2043 name, [&](auto status, const auto& device) {
2044 ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
2045 ASSERT_EQ(Status::OK, status);
2046 ASSERT_NE(device, nullptr);
2047 device3_x = device;
2048 });
2049 ASSERT_TRUE(ret.isOk());
2050
2051 ret = device3_x->getCameraCharacteristics([&](auto status, const auto& chars) {
2052 ALOGI("getCameraCharacteristics returns status:%d", (int)status);
2053 ASSERT_EQ(Status::OK, status);
2054 const camera_metadata_t* metadata = (camera_metadata_t*)chars.data();
2055 size_t expectedSize = chars.size();
2056 int result = validate_camera_metadata_structure(metadata, &expectedSize);
2057 ASSERT_TRUE((result == 0) || (result == CAMERA_METADATA_VALIDATION_SHIFTED));
2058 size_t entryCount = get_camera_metadata_entry_count(metadata);
2059 // TODO: we can do better than 0 here. Need to check how many required
2060 // characteristics keys we've defined.
2061 ASSERT_GT(entryCount, 0u);
2062 ALOGI("getCameraCharacteristics metadata entry count is %zu", entryCount);
2063
2064 camera_metadata_ro_entry entry;
2065 int retcode = find_camera_metadata_ro_entry(metadata,
2066 ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL, &entry);
2067 if ((0 == retcode) && (entry.count > 0)) {
2068 uint8_t hardwareLevel = entry.data.u8[0];
2069 ASSERT_TRUE(
2070 hardwareLevel == ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED ||
2071 hardwareLevel == ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_FULL ||
2072 hardwareLevel == ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_3 ||
2073 hardwareLevel == ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_EXTERNAL);
2074 } else {
2075 ADD_FAILURE() << "Get camera hardware level failed!";
2076 }
2077 });
2078 ASSERT_TRUE(ret.isOk());
2079 }
2080 break;
2081 case CAMERA_DEVICE_API_VERSION_1_0: {
2082 //Not applicable
2083 }
2084 break;
2085 default: {
2086 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
2087 ADD_FAILURE();
2088 }
2089 break;
2090 }
2091 }
2092 }
2093
2094 //In case it is supported verify that torch can be enabled.
2095 //Check for corresponding toch callbacks as well.
TEST_F(CameraHidlTest,setTorchMode)2096 TEST_F(CameraHidlTest, setTorchMode) {
2097 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
2098 bool torchControlSupported = false;
2099 Return<void> ret;
2100
2101 ret = mProvider->isSetTorchModeSupported([&](auto status, bool support) {
2102 ALOGI("isSetTorchModeSupported returns status:%d supported:%d", (int)status, support);
2103 ASSERT_EQ(Status::OK, status);
2104 torchControlSupported = support;
2105 });
2106
2107 sp<TorchProviderCb> cb = new TorchProviderCb(this);
2108 Return<Status> returnStatus = mProvider->setCallback(cb);
2109 ASSERT_TRUE(returnStatus.isOk());
2110 ASSERT_EQ(Status::OK, returnStatus);
2111
2112 for (const auto& name : cameraDeviceNames) {
2113 int deviceVersion = getCameraDeviceVersion(name, mProviderType);
2114 switch (deviceVersion) {
2115 case CAMERA_DEVICE_API_VERSION_3_4:
2116 case CAMERA_DEVICE_API_VERSION_3_3:
2117 case CAMERA_DEVICE_API_VERSION_3_2: {
2118 ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_x;
2119 ALOGI("setTorchMode: Testing camera device %s", name.c_str());
2120 ret = mProvider->getCameraDeviceInterface_V3_x(
2121 name, [&](auto status, const auto& device) {
2122 ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
2123 ASSERT_EQ(Status::OK, status);
2124 ASSERT_NE(device, nullptr);
2125 device3_x = device;
2126 });
2127 ASSERT_TRUE(ret.isOk());
2128
2129 mTorchStatus = TorchModeStatus::NOT_AVAILABLE;
2130 returnStatus = device3_x->setTorchMode(TorchMode::ON);
2131 ASSERT_TRUE(returnStatus.isOk());
2132 if (!torchControlSupported) {
2133 ASSERT_EQ(Status::METHOD_NOT_SUPPORTED, returnStatus);
2134 } else {
2135 ASSERT_TRUE(returnStatus == Status::OK ||
2136 returnStatus == Status::OPERATION_NOT_SUPPORTED);
2137 if (returnStatus == Status::OK) {
2138 {
2139 std::unique_lock<std::mutex> l(mTorchLock);
2140 while (TorchModeStatus::NOT_AVAILABLE == mTorchStatus) {
2141 auto timeout = std::chrono::system_clock::now() +
2142 std::chrono::seconds(kTorchTimeoutSec);
2143 ASSERT_NE(std::cv_status::timeout, mTorchCond.wait_until(l, timeout));
2144 }
2145 ASSERT_EQ(TorchModeStatus::AVAILABLE_ON, mTorchStatus);
2146 mTorchStatus = TorchModeStatus::NOT_AVAILABLE;
2147 }
2148
2149 returnStatus = device3_x->setTorchMode(TorchMode::OFF);
2150 ASSERT_TRUE(returnStatus.isOk());
2151 ASSERT_EQ(Status::OK, returnStatus);
2152
2153 {
2154 std::unique_lock<std::mutex> l(mTorchLock);
2155 while (TorchModeStatus::NOT_AVAILABLE == mTorchStatus) {
2156 auto timeout = std::chrono::system_clock::now() +
2157 std::chrono::seconds(kTorchTimeoutSec);
2158 ASSERT_NE(std::cv_status::timeout, mTorchCond.wait_until(l, timeout));
2159 }
2160 ASSERT_EQ(TorchModeStatus::AVAILABLE_OFF, mTorchStatus);
2161 }
2162 }
2163 }
2164 }
2165 break;
2166 case CAMERA_DEVICE_API_VERSION_1_0: {
2167 ::android::sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
2168 ALOGI("dumpState: Testing camera device %s", name.c_str());
2169 ret = mProvider->getCameraDeviceInterface_V1_x(
2170 name, [&](auto status, const auto& device) {
2171 ALOGI("getCameraDeviceInterface_V1_x returns status:%d", (int)status);
2172 ASSERT_EQ(Status::OK, status);
2173 ASSERT_NE(device, nullptr);
2174 device1 = device;
2175 });
2176 ASSERT_TRUE(ret.isOk());
2177
2178 mTorchStatus = TorchModeStatus::NOT_AVAILABLE;
2179 returnStatus = device1->setTorchMode(TorchMode::ON);
2180 ASSERT_TRUE(returnStatus.isOk());
2181 if (!torchControlSupported) {
2182 ASSERT_EQ(Status::METHOD_NOT_SUPPORTED, returnStatus);
2183 } else {
2184 ASSERT_TRUE(returnStatus == Status::OK ||
2185 returnStatus == Status::OPERATION_NOT_SUPPORTED);
2186 if (returnStatus == Status::OK) {
2187 {
2188 std::unique_lock<std::mutex> l(mTorchLock);
2189 while (TorchModeStatus::NOT_AVAILABLE == mTorchStatus) {
2190 auto timeout = std::chrono::system_clock::now() +
2191 std::chrono::seconds(kTorchTimeoutSec);
2192 ASSERT_NE(std::cv_status::timeout, mTorchCond.wait_until(l,
2193 timeout));
2194 }
2195 ASSERT_EQ(TorchModeStatus::AVAILABLE_ON, mTorchStatus);
2196 mTorchStatus = TorchModeStatus::NOT_AVAILABLE;
2197 }
2198
2199 returnStatus = device1->setTorchMode(TorchMode::OFF);
2200 ASSERT_TRUE(returnStatus.isOk());
2201 ASSERT_EQ(Status::OK, returnStatus);
2202
2203 {
2204 std::unique_lock<std::mutex> l(mTorchLock);
2205 while (TorchModeStatus::NOT_AVAILABLE == mTorchStatus) {
2206 auto timeout = std::chrono::system_clock::now() +
2207 std::chrono::seconds(kTorchTimeoutSec);
2208 ASSERT_NE(std::cv_status::timeout, mTorchCond.wait_until(l,
2209 timeout));
2210 }
2211 ASSERT_EQ(TorchModeStatus::AVAILABLE_OFF, mTorchStatus);
2212 }
2213 }
2214 }
2215 ret = device1->close();
2216 ASSERT_TRUE(ret.isOk());
2217 }
2218 break;
2219 default: {
2220 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
2221 ADD_FAILURE();
2222 }
2223 break;
2224 }
2225 }
2226
2227 returnStatus = mProvider->setCallback(nullptr);
2228 ASSERT_TRUE(returnStatus.isOk());
2229 ASSERT_EQ(Status::OK, returnStatus);
2230 }
2231
2232 // Check dump functionality.
TEST_F(CameraHidlTest,dumpState)2233 TEST_F(CameraHidlTest, dumpState) {
2234 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
2235 Return<void> ret;
2236
2237 for (const auto& name : cameraDeviceNames) {
2238 int deviceVersion = getCameraDeviceVersion(name, mProviderType);
2239 switch (deviceVersion) {
2240 case CAMERA_DEVICE_API_VERSION_3_4:
2241 case CAMERA_DEVICE_API_VERSION_3_3:
2242 case CAMERA_DEVICE_API_VERSION_3_2: {
2243 ::android::sp<ICameraDevice> device3_x;
2244 ALOGI("dumpState: Testing camera device %s", name.c_str());
2245 ret = mProvider->getCameraDeviceInterface_V3_x(
2246 name, [&](auto status, const auto& device) {
2247 ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
2248 ASSERT_EQ(Status::OK, status);
2249 ASSERT_NE(device, nullptr);
2250 device3_x = device;
2251 });
2252 ASSERT_TRUE(ret.isOk());
2253
2254 native_handle_t* raw_handle = native_handle_create(1, 0);
2255 raw_handle->data[0] = open(kDumpOutput, O_RDWR);
2256 ASSERT_GE(raw_handle->data[0], 0);
2257 hidl_handle handle = raw_handle;
2258 ret = device3_x->dumpState(handle);
2259 ASSERT_TRUE(ret.isOk());
2260 close(raw_handle->data[0]);
2261 native_handle_delete(raw_handle);
2262 }
2263 break;
2264 case CAMERA_DEVICE_API_VERSION_1_0: {
2265 ::android::sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
2266 ALOGI("dumpState: Testing camera device %s", name.c_str());
2267 ret = mProvider->getCameraDeviceInterface_V1_x(
2268 name, [&](auto status, const auto& device) {
2269 ALOGI("getCameraDeviceInterface_V1_x returns status:%d", (int)status);
2270 ASSERT_EQ(Status::OK, status);
2271 ASSERT_NE(device, nullptr);
2272 device1 = device;
2273 });
2274 ASSERT_TRUE(ret.isOk());
2275
2276 native_handle_t* raw_handle = native_handle_create(1, 0);
2277 raw_handle->data[0] = open(kDumpOutput, O_RDWR);
2278 ASSERT_GE(raw_handle->data[0], 0);
2279 hidl_handle handle = raw_handle;
2280 Return<Status> returnStatus = device1->dumpState(handle);
2281 ASSERT_TRUE(returnStatus.isOk());
2282 ASSERT_EQ(Status::OK, returnStatus);
2283 close(raw_handle->data[0]);
2284 native_handle_delete(raw_handle);
2285 }
2286 break;
2287 default: {
2288 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
2289 ADD_FAILURE();
2290 }
2291 break;
2292 }
2293 }
2294 }
2295
2296 // Open, dumpStates, then close
TEST_F(CameraHidlTest,openClose)2297 TEST_F(CameraHidlTest, openClose) {
2298 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
2299 Return<void> ret;
2300
2301 for (const auto& name : cameraDeviceNames) {
2302 int deviceVersion = getCameraDeviceVersion(name, mProviderType);
2303 switch (deviceVersion) {
2304 case CAMERA_DEVICE_API_VERSION_3_4:
2305 case CAMERA_DEVICE_API_VERSION_3_3:
2306 case CAMERA_DEVICE_API_VERSION_3_2: {
2307 ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_x;
2308 ALOGI("openClose: Testing camera device %s", name.c_str());
2309 ret = mProvider->getCameraDeviceInterface_V3_x(
2310 name, [&](auto status, const auto& device) {
2311 ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
2312 ASSERT_EQ(Status::OK, status);
2313 ASSERT_NE(device, nullptr);
2314 device3_x = device;
2315 });
2316 ASSERT_TRUE(ret.isOk());
2317
2318 sp<EmptyDeviceCb> cb = new EmptyDeviceCb;
2319 sp<ICameraDeviceSession> session;
2320 ret = device3_x->open(cb, [&](auto status, const auto& newSession) {
2321 ALOGI("device::open returns status:%d", (int)status);
2322 ASSERT_EQ(Status::OK, status);
2323 ASSERT_NE(newSession, nullptr);
2324 session = newSession;
2325 });
2326 ASSERT_TRUE(ret.isOk());
2327 // Ensure that a device labeling itself as 3.3/3.4 can have its session interface
2328 // cast the 3.3/3.4 interface, and that lower versions can't be cast to it.
2329 sp<device::V3_3::ICameraDeviceSession> sessionV3_3;
2330 sp<device::V3_4::ICameraDeviceSession> sessionV3_4;
2331 castSession(session, deviceVersion, &sessionV3_3, &sessionV3_4);
2332 if (deviceVersion == CAMERA_DEVICE_API_VERSION_3_4) {
2333 ASSERT_TRUE(sessionV3_4.get() != nullptr);
2334 } else if (deviceVersion == CAMERA_DEVICE_API_VERSION_3_3) {
2335 ASSERT_TRUE(sessionV3_3.get() != nullptr);
2336 } else {
2337 ASSERT_TRUE(sessionV3_3.get() == nullptr);
2338 }
2339 native_handle_t* raw_handle = native_handle_create(1, 0);
2340 raw_handle->data[0] = open(kDumpOutput, O_RDWR);
2341 ASSERT_GE(raw_handle->data[0], 0);
2342 hidl_handle handle = raw_handle;
2343 ret = device3_x->dumpState(handle);
2344 ASSERT_TRUE(ret.isOk());
2345 close(raw_handle->data[0]);
2346 native_handle_delete(raw_handle);
2347
2348 ret = session->close();
2349 ASSERT_TRUE(ret.isOk());
2350 // TODO: test all session API calls return INTERNAL_ERROR after close
2351 // TODO: keep a wp copy here and verify session cannot be promoted out of this scope
2352 }
2353 break;
2354 case CAMERA_DEVICE_API_VERSION_1_0: {
2355 sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
2356 openCameraDevice(name, mProvider, &device1 /*out*/);
2357 ASSERT_NE(nullptr, device1.get());
2358
2359 native_handle_t* raw_handle = native_handle_create(1, 0);
2360 raw_handle->data[0] = open(kDumpOutput, O_RDWR);
2361 ASSERT_GE(raw_handle->data[0], 0);
2362 hidl_handle handle = raw_handle;
2363 Return<Status> returnStatus = device1->dumpState(handle);
2364 ASSERT_TRUE(returnStatus.isOk());
2365 ASSERT_EQ(Status::OK, returnStatus);
2366 close(raw_handle->data[0]);
2367 native_handle_delete(raw_handle);
2368
2369 ret = device1->close();
2370 ASSERT_TRUE(ret.isOk());
2371 }
2372 break;
2373 default: {
2374 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
2375 ADD_FAILURE();
2376 }
2377 break;
2378 }
2379 }
2380 }
2381
2382 // Check whether all common default request settings can be sucessfully
2383 // constructed.
TEST_F(CameraHidlTest,constructDefaultRequestSettings)2384 TEST_F(CameraHidlTest, constructDefaultRequestSettings) {
2385 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
2386
2387 for (const auto& name : cameraDeviceNames) {
2388 int deviceVersion = getCameraDeviceVersion(name, mProviderType);
2389 switch (deviceVersion) {
2390 case CAMERA_DEVICE_API_VERSION_3_4:
2391 case CAMERA_DEVICE_API_VERSION_3_3:
2392 case CAMERA_DEVICE_API_VERSION_3_2: {
2393 ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_x;
2394 Return<void> ret;
2395 ALOGI("constructDefaultRequestSettings: Testing camera device %s", name.c_str());
2396 ret = mProvider->getCameraDeviceInterface_V3_x(
2397 name, [&](auto status, const auto& device) {
2398 ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
2399 ASSERT_EQ(Status::OK, status);
2400 ASSERT_NE(device, nullptr);
2401 device3_x = device;
2402 });
2403 ASSERT_TRUE(ret.isOk());
2404
2405 sp<EmptyDeviceCb> cb = new EmptyDeviceCb;
2406 sp<ICameraDeviceSession> session;
2407 ret = device3_x->open(cb, [&](auto status, const auto& newSession) {
2408 ALOGI("device::open returns status:%d", (int)status);
2409 ASSERT_EQ(Status::OK, status);
2410 ASSERT_NE(newSession, nullptr);
2411 session = newSession;
2412 });
2413 ASSERT_TRUE(ret.isOk());
2414
2415 for (uint32_t t = (uint32_t)RequestTemplate::PREVIEW;
2416 t <= (uint32_t)RequestTemplate::MANUAL; t++) {
2417 RequestTemplate reqTemplate = (RequestTemplate)t;
2418 ret =
2419 session->constructDefaultRequestSettings(
2420 reqTemplate, [&](auto status, const auto& req) {
2421 ALOGI("constructDefaultRequestSettings returns status:%d",
2422 (int)status);
2423 if (reqTemplate == RequestTemplate::ZERO_SHUTTER_LAG ||
2424 reqTemplate == RequestTemplate::MANUAL) {
2425 // optional templates
2426 ASSERT_TRUE((status == Status::OK) ||
2427 (status == Status::ILLEGAL_ARGUMENT));
2428 } else {
2429 ASSERT_EQ(Status::OK, status);
2430 }
2431
2432 if (status == Status::OK) {
2433 const camera_metadata_t* metadata =
2434 (camera_metadata_t*) req.data();
2435 size_t expectedSize = req.size();
2436 int result = validate_camera_metadata_structure(
2437 metadata, &expectedSize);
2438 ASSERT_TRUE((result == 0) ||
2439 (result == CAMERA_METADATA_VALIDATION_SHIFTED));
2440 size_t entryCount =
2441 get_camera_metadata_entry_count(metadata);
2442 // TODO: we can do better than 0 here. Need to check how many required
2443 // request keys we've defined for each template
2444 ASSERT_GT(entryCount, 0u);
2445 ALOGI("template %u metadata entry count is %zu",
2446 t, entryCount);
2447 } else {
2448 ASSERT_EQ(0u, req.size());
2449 }
2450 });
2451 ASSERT_TRUE(ret.isOk());
2452 }
2453 ret = session->close();
2454 ASSERT_TRUE(ret.isOk());
2455 }
2456 break;
2457 case CAMERA_DEVICE_API_VERSION_1_0: {
2458 //Not applicable
2459 }
2460 break;
2461 default: {
2462 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
2463 ADD_FAILURE();
2464 }
2465 break;
2466 }
2467 }
2468 }
2469
2470
2471 // Verify that all supported stream formats and sizes can be configured
2472 // successfully.
TEST_F(CameraHidlTest,configureStreamsAvailableOutputs)2473 TEST_F(CameraHidlTest, configureStreamsAvailableOutputs) {
2474 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
2475 std::vector<AvailableStream> outputStreams;
2476
2477 for (const auto& name : cameraDeviceNames) {
2478 int deviceVersion = getCameraDeviceVersion(name, mProviderType);
2479 if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) {
2480 continue;
2481 } else if (deviceVersion <= 0) {
2482 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
2483 ADD_FAILURE();
2484 return;
2485 }
2486
2487 camera_metadata_t* staticMeta;
2488 Return<void> ret;
2489 sp<ICameraDeviceSession> session;
2490 sp<device::V3_3::ICameraDeviceSession> session3_3;
2491 sp<device::V3_4::ICameraDeviceSession> session3_4;
2492 openEmptyDeviceSession(name, mProvider,
2493 &session /*out*/, &staticMeta /*out*/);
2494 castSession(session, deviceVersion, &session3_3, &session3_4);
2495
2496 outputStreams.clear();
2497 ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta, outputStreams));
2498 ASSERT_NE(0u, outputStreams.size());
2499
2500 int32_t streamId = 0;
2501 for (auto& it : outputStreams) {
2502 V3_2::Stream stream3_2;
2503 bool isJpeg = static_cast<PixelFormat>(it.format) == PixelFormat::BLOB;
2504 stream3_2 = {streamId,
2505 StreamType::OUTPUT,
2506 static_cast<uint32_t>(it.width),
2507 static_cast<uint32_t>(it.height),
2508 static_cast<PixelFormat>(it.format),
2509 GRALLOC1_CONSUMER_USAGE_HWCOMPOSER,
2510 (isJpeg) ? static_cast<V3_2::DataspaceFlags>(Dataspace::V0_JFIF) : 0,
2511 StreamRotation::ROTATION_0};
2512 ::android::hardware::hidl_vec<V3_2::Stream> streams3_2 = {stream3_2};
2513 ::android::hardware::camera::device::V3_4::StreamConfiguration config3_4;
2514 ::android::hardware::camera::device::V3_2::StreamConfiguration config3_2;
2515 createStreamConfiguration(streams3_2, StreamConfigurationMode::NORMAL_MODE,
2516 &config3_2, &config3_4);
2517 if (session3_4 != nullptr) {
2518 ret = session3_4->configureStreams_3_4(config3_4,
2519 [streamId](Status s, device::V3_4::HalStreamConfiguration halConfig) {
2520 ASSERT_EQ(Status::OK, s);
2521 ASSERT_EQ(1u, halConfig.streams.size());
2522 ASSERT_EQ(halConfig.streams[0].v3_3.v3_2.id, streamId);
2523 });
2524 } else if (session3_3 != nullptr) {
2525 ret = session3_3->configureStreams_3_3(config3_2,
2526 [streamId](Status s, device::V3_3::HalStreamConfiguration halConfig) {
2527 ASSERT_EQ(Status::OK, s);
2528 ASSERT_EQ(1u, halConfig.streams.size());
2529 ASSERT_EQ(halConfig.streams[0].v3_2.id, streamId);
2530 });
2531 } else {
2532 ret = session->configureStreams(config3_2,
2533 [streamId](Status s, HalStreamConfiguration halConfig) {
2534 ASSERT_EQ(Status::OK, s);
2535 ASSERT_EQ(1u, halConfig.streams.size());
2536 ASSERT_EQ(halConfig.streams[0].id, streamId);
2537 });
2538 }
2539 ASSERT_TRUE(ret.isOk());
2540 streamId++;
2541 }
2542
2543 free_camera_metadata(staticMeta);
2544 ret = session->close();
2545 ASSERT_TRUE(ret.isOk());
2546 }
2547 }
2548
2549 // Check for correct handling of invalid/incorrect configuration parameters.
TEST_F(CameraHidlTest,configureStreamsInvalidOutputs)2550 TEST_F(CameraHidlTest, configureStreamsInvalidOutputs) {
2551 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
2552 std::vector<AvailableStream> outputStreams;
2553
2554 for (const auto& name : cameraDeviceNames) {
2555 int deviceVersion = getCameraDeviceVersion(name, mProviderType);
2556 if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) {
2557 continue;
2558 } else if (deviceVersion <= 0) {
2559 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
2560 ADD_FAILURE();
2561 return;
2562 }
2563
2564 camera_metadata_t* staticMeta;
2565 Return<void> ret;
2566 sp<ICameraDeviceSession> session;
2567 sp<device::V3_3::ICameraDeviceSession> session3_3;
2568 sp<device::V3_4::ICameraDeviceSession> session3_4;
2569 openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/);
2570 castSession(session, deviceVersion, &session3_3, &session3_4);
2571
2572 outputStreams.clear();
2573 ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta, outputStreams));
2574 ASSERT_NE(0u, outputStreams.size());
2575
2576 int32_t streamId = 0;
2577 V3_2::Stream stream3_2 = {streamId++,
2578 StreamType::OUTPUT,
2579 static_cast<uint32_t>(0),
2580 static_cast<uint32_t>(0),
2581 static_cast<PixelFormat>(outputStreams[0].format),
2582 GRALLOC1_CONSUMER_USAGE_HWCOMPOSER,
2583 0,
2584 StreamRotation::ROTATION_0};
2585 ::android::hardware::hidl_vec<V3_2::Stream> streams = {stream3_2};
2586 ::android::hardware::camera::device::V3_4::StreamConfiguration config3_4;
2587 ::android::hardware::camera::device::V3_2::StreamConfiguration config3_2;
2588 createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE,
2589 &config3_2, &config3_4);
2590 if(session3_4 != nullptr) {
2591 ret = session3_4->configureStreams_3_4(config3_4,
2592 [](Status s, device::V3_4::HalStreamConfiguration) {
2593 ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) ||
2594 (Status::INTERNAL_ERROR == s));
2595 });
2596 } else if(session3_3 != nullptr) {
2597 ret = session3_3->configureStreams_3_3(config3_2,
2598 [](Status s, device::V3_3::HalStreamConfiguration) {
2599 ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) ||
2600 (Status::INTERNAL_ERROR == s));
2601 });
2602 } else {
2603 ret = session->configureStreams(config3_2,
2604 [](Status s, HalStreamConfiguration) {
2605 ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) ||
2606 (Status::INTERNAL_ERROR == s));
2607 });
2608 }
2609 ASSERT_TRUE(ret.isOk());
2610
2611 stream3_2 = {streamId++,
2612 StreamType::OUTPUT,
2613 static_cast<uint32_t>(UINT32_MAX),
2614 static_cast<uint32_t>(UINT32_MAX),
2615 static_cast<PixelFormat>(outputStreams[0].format),
2616 GRALLOC1_CONSUMER_USAGE_HWCOMPOSER,
2617 0,
2618 StreamRotation::ROTATION_0};
2619 streams[0] = stream3_2;
2620 createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE,
2621 &config3_2, &config3_4);
2622 if(session3_4 != nullptr) {
2623 ret = session3_4->configureStreams_3_4(config3_4, [](Status s,
2624 device::V3_4::HalStreamConfiguration) {
2625 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
2626 });
2627 } else if(session3_3 != nullptr) {
2628 ret = session3_3->configureStreams_3_3(config3_2, [](Status s,
2629 device::V3_3::HalStreamConfiguration) {
2630 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
2631 });
2632 } else {
2633 ret = session->configureStreams(config3_2, [](Status s,
2634 HalStreamConfiguration) {
2635 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
2636 });
2637 }
2638 ASSERT_TRUE(ret.isOk());
2639
2640 for (auto& it : outputStreams) {
2641 stream3_2 = {streamId++,
2642 StreamType::OUTPUT,
2643 static_cast<uint32_t>(it.width),
2644 static_cast<uint32_t>(it.height),
2645 static_cast<PixelFormat>(UINT32_MAX),
2646 GRALLOC1_CONSUMER_USAGE_HWCOMPOSER,
2647 0,
2648 StreamRotation::ROTATION_0};
2649 streams[0] = stream3_2;
2650 createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE,
2651 &config3_2, &config3_4);
2652 if(session3_4 != nullptr) {
2653 ret = session3_4->configureStreams_3_4(config3_4,
2654 [](Status s, device::V3_4::HalStreamConfiguration) {
2655 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
2656 });
2657 } else if(session3_3 != nullptr) {
2658 ret = session3_3->configureStreams_3_3(config3_2,
2659 [](Status s, device::V3_3::HalStreamConfiguration) {
2660 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
2661 });
2662 } else {
2663 ret = session->configureStreams(config3_2,
2664 [](Status s, HalStreamConfiguration) {
2665 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
2666 });
2667 }
2668 ASSERT_TRUE(ret.isOk());
2669
2670 stream3_2 = {streamId++,
2671 StreamType::OUTPUT,
2672 static_cast<uint32_t>(it.width),
2673 static_cast<uint32_t>(it.height),
2674 static_cast<PixelFormat>(it.format),
2675 GRALLOC1_CONSUMER_USAGE_HWCOMPOSER,
2676 0,
2677 static_cast<StreamRotation>(UINT32_MAX)};
2678 streams[0] = stream3_2;
2679 createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE,
2680 &config3_2, &config3_4);
2681 if(session3_4 != nullptr) {
2682 ret = session3_4->configureStreams_3_4(config3_4,
2683 [](Status s, device::V3_4::HalStreamConfiguration) {
2684 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
2685 });
2686 } else if(session3_3 != nullptr) {
2687 ret = session3_3->configureStreams_3_3(config3_2,
2688 [](Status s, device::V3_3::HalStreamConfiguration) {
2689 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
2690 });
2691 } else {
2692 ret = session->configureStreams(config3_2,
2693 [](Status s, HalStreamConfiguration) {
2694 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
2695 });
2696 }
2697 ASSERT_TRUE(ret.isOk());
2698 }
2699
2700 free_camera_metadata(staticMeta);
2701 ret = session->close();
2702 ASSERT_TRUE(ret.isOk());
2703 }
2704 }
2705
2706 // Check whether all supported ZSL output stream combinations can be
2707 // configured successfully.
TEST_F(CameraHidlTest,configureStreamsZSLInputOutputs)2708 TEST_F(CameraHidlTest, configureStreamsZSLInputOutputs) {
2709 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
2710 std::vector<AvailableStream> inputStreams;
2711 std::vector<AvailableZSLInputOutput> inputOutputMap;
2712
2713 for (const auto& name : cameraDeviceNames) {
2714 int deviceVersion = getCameraDeviceVersion(name, mProviderType);
2715 if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) {
2716 continue;
2717 } else if (deviceVersion <= 0) {
2718 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
2719 ADD_FAILURE();
2720 return;
2721 }
2722
2723 camera_metadata_t* staticMeta;
2724 Return<void> ret;
2725 sp<ICameraDeviceSession> session;
2726 sp<device::V3_3::ICameraDeviceSession> session3_3;
2727 sp<device::V3_4::ICameraDeviceSession> session3_4;
2728 openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/);
2729 castSession(session, deviceVersion, &session3_3, &session3_4);
2730
2731 Status rc = isZSLModeAvailable(staticMeta);
2732 if (Status::METHOD_NOT_SUPPORTED == rc) {
2733 ret = session->close();
2734 ASSERT_TRUE(ret.isOk());
2735 continue;
2736 }
2737 ASSERT_EQ(Status::OK, rc);
2738
2739 inputStreams.clear();
2740 ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta, inputStreams));
2741 ASSERT_NE(0u, inputStreams.size());
2742
2743 inputOutputMap.clear();
2744 ASSERT_EQ(Status::OK, getZSLInputOutputMap(staticMeta, inputOutputMap));
2745 ASSERT_NE(0u, inputOutputMap.size());
2746
2747 int32_t streamId = 0;
2748 for (auto& inputIter : inputOutputMap) {
2749 AvailableStream input;
2750 ASSERT_EQ(Status::OK, findLargestSize(inputStreams, inputIter.inputFormat,
2751 input));
2752 ASSERT_NE(0u, inputStreams.size());
2753
2754 AvailableStream outputThreshold = {INT32_MAX, INT32_MAX,
2755 inputIter.outputFormat};
2756 std::vector<AvailableStream> outputStreams;
2757 ASSERT_EQ(Status::OK,
2758 getAvailableOutputStreams(staticMeta, outputStreams,
2759 &outputThreshold));
2760 for (auto& outputIter : outputStreams) {
2761 V3_2::Stream zslStream = {streamId++,
2762 StreamType::OUTPUT,
2763 static_cast<uint32_t>(input.width),
2764 static_cast<uint32_t>(input.height),
2765 static_cast<PixelFormat>(input.format),
2766 GRALLOC_USAGE_HW_CAMERA_ZSL,
2767 0,
2768 StreamRotation::ROTATION_0};
2769 V3_2::Stream inputStream = {streamId++,
2770 StreamType::INPUT,
2771 static_cast<uint32_t>(input.width),
2772 static_cast<uint32_t>(input.height),
2773 static_cast<PixelFormat>(input.format),
2774 0,
2775 0,
2776 StreamRotation::ROTATION_0};
2777 V3_2::Stream outputStream = {streamId++,
2778 StreamType::OUTPUT,
2779 static_cast<uint32_t>(outputIter.width),
2780 static_cast<uint32_t>(outputIter.height),
2781 static_cast<PixelFormat>(outputIter.format),
2782 GRALLOC1_CONSUMER_USAGE_HWCOMPOSER,
2783 0,
2784 StreamRotation::ROTATION_0};
2785
2786 ::android::hardware::hidl_vec<V3_2::Stream> streams = {inputStream, zslStream,
2787 outputStream};
2788 ::android::hardware::camera::device::V3_4::StreamConfiguration config3_4;
2789 ::android::hardware::camera::device::V3_2::StreamConfiguration config3_2;
2790 createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE,
2791 &config3_2, &config3_4);
2792 if (session3_4 != nullptr) {
2793 ret = session3_4->configureStreams_3_4(config3_4,
2794 [](Status s, device::V3_4::HalStreamConfiguration halConfig) {
2795 ASSERT_EQ(Status::OK, s);
2796 ASSERT_EQ(3u, halConfig.streams.size());
2797 });
2798 } else if (session3_3 != nullptr) {
2799 ret = session3_3->configureStreams_3_3(config3_2,
2800 [](Status s, device::V3_3::HalStreamConfiguration halConfig) {
2801 ASSERT_EQ(Status::OK, s);
2802 ASSERT_EQ(3u, halConfig.streams.size());
2803 });
2804 } else {
2805 ret = session->configureStreams(config3_2,
2806 [](Status s, HalStreamConfiguration halConfig) {
2807 ASSERT_EQ(Status::OK, s);
2808 ASSERT_EQ(3u, halConfig.streams.size());
2809 });
2810 }
2811 ASSERT_TRUE(ret.isOk());
2812 }
2813 }
2814
2815 free_camera_metadata(staticMeta);
2816 ret = session->close();
2817 ASSERT_TRUE(ret.isOk());
2818 }
2819 }
2820
2821 // Check wehether session parameters are supported. If Hal support for them
2822 // exist, then try to configure a preview stream using them.
TEST_F(CameraHidlTest,configureStreamsWithSessionParameters)2823 TEST_F(CameraHidlTest, configureStreamsWithSessionParameters) {
2824 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
2825 std::vector<AvailableStream> outputPreviewStreams;
2826 AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
2827 static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
2828
2829 for (const auto& name : cameraDeviceNames) {
2830 int deviceVersion = getCameraDeviceVersion(name, mProviderType);
2831 if (deviceVersion <= 0) {
2832 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
2833 ADD_FAILURE();
2834 return;
2835 } else if (deviceVersion < CAMERA_DEVICE_API_VERSION_3_4) {
2836 continue;
2837 }
2838
2839 camera_metadata_t* staticMetaBuffer;
2840 Return<void> ret;
2841 sp<ICameraDeviceSession> session;
2842 sp<device::V3_3::ICameraDeviceSession> session3_3;
2843 sp<device::V3_4::ICameraDeviceSession> session3_4;
2844 openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMetaBuffer /*out*/);
2845 castSession(session, deviceVersion, &session3_3, &session3_4);
2846 ASSERT_NE(session3_4, nullptr);
2847
2848 std::unordered_set<int32_t> availableSessionKeys;
2849 auto rc = getSupportedKeys(staticMetaBuffer, ANDROID_REQUEST_AVAILABLE_SESSION_KEYS,
2850 &availableSessionKeys);
2851 ASSERT_TRUE(Status::OK == rc);
2852 if (availableSessionKeys.empty()) {
2853 free_camera_metadata(staticMetaBuffer);
2854 ret = session->close();
2855 ASSERT_TRUE(ret.isOk());
2856 continue;
2857 }
2858
2859 android::hardware::camera::common::V1_0::helper::CameraMetadata previewRequestSettings;
2860 android::hardware::camera::common::V1_0::helper::CameraMetadata sessionParams;
2861 constructFilteredSettings(session, availableSessionKeys, RequestTemplate::PREVIEW,
2862 &previewRequestSettings, &sessionParams);
2863 if (sessionParams.isEmpty()) {
2864 free_camera_metadata(staticMetaBuffer);
2865 ret = session->close();
2866 ASSERT_TRUE(ret.isOk());
2867 continue;
2868 }
2869
2870 ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMetaBuffer, outputPreviewStreams,
2871 &previewThreshold));
2872 ASSERT_NE(0u, outputPreviewStreams.size());
2873
2874 V3_4::Stream previewStream;
2875 previewStream.v3_2 = {0,
2876 StreamType::OUTPUT,
2877 static_cast<uint32_t>(outputPreviewStreams[0].width),
2878 static_cast<uint32_t>(outputPreviewStreams[0].height),
2879 static_cast<PixelFormat>(outputPreviewStreams[0].format),
2880 GRALLOC1_CONSUMER_USAGE_HWCOMPOSER,
2881 0,
2882 StreamRotation::ROTATION_0};
2883 ::android::hardware::hidl_vec<V3_4::Stream> streams = {previewStream};
2884 ::android::hardware::camera::device::V3_4::StreamConfiguration config;
2885 config.streams = streams;
2886 config.operationMode = StreamConfigurationMode::NORMAL_MODE;
2887 const camera_metadata_t *sessionParamsBuffer = sessionParams.getAndLock();
2888 config.sessionParams.setToExternal(
2889 reinterpret_cast<uint8_t *> (const_cast<camera_metadata_t *> (sessionParamsBuffer)),
2890 get_camera_metadata_size(sessionParamsBuffer));
2891 ret = session3_4->configureStreams_3_4(config,
2892 [](Status s, device::V3_4::HalStreamConfiguration halConfig) {
2893 ASSERT_EQ(Status::OK, s);
2894 ASSERT_EQ(1u, halConfig.streams.size());
2895 });
2896 ASSERT_TRUE(ret.isOk());
2897
2898 free_camera_metadata(staticMetaBuffer);
2899 ret = session->close();
2900 ASSERT_TRUE(ret.isOk());
2901 }
2902 }
2903
2904 // Verify that all supported preview + still capture stream combinations
2905 // can be configured successfully.
TEST_F(CameraHidlTest,configureStreamsPreviewStillOutputs)2906 TEST_F(CameraHidlTest, configureStreamsPreviewStillOutputs) {
2907 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
2908 std::vector<AvailableStream> outputBlobStreams;
2909 std::vector<AvailableStream> outputPreviewStreams;
2910 AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
2911 static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
2912 AvailableStream blobThreshold = {INT32_MAX, INT32_MAX,
2913 static_cast<int32_t>(PixelFormat::BLOB)};
2914
2915 for (const auto& name : cameraDeviceNames) {
2916 int deviceVersion = getCameraDeviceVersion(name, mProviderType);
2917 if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) {
2918 continue;
2919 } else if (deviceVersion <= 0) {
2920 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
2921 ADD_FAILURE();
2922 return;
2923 }
2924
2925 camera_metadata_t* staticMeta;
2926 Return<void> ret;
2927 sp<ICameraDeviceSession> session;
2928 sp<device::V3_3::ICameraDeviceSession> session3_3;
2929 sp<device::V3_4::ICameraDeviceSession> session3_4;
2930 openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/);
2931 castSession(session, deviceVersion, &session3_3, &session3_4);
2932
2933 outputBlobStreams.clear();
2934 ASSERT_EQ(Status::OK,
2935 getAvailableOutputStreams(staticMeta, outputBlobStreams,
2936 &blobThreshold));
2937 ASSERT_NE(0u, outputBlobStreams.size());
2938
2939 outputPreviewStreams.clear();
2940 ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta, outputPreviewStreams,
2941 &previewThreshold));
2942 ASSERT_NE(0u, outputPreviewStreams.size());
2943
2944 int32_t streamId = 0;
2945 for (auto& blobIter : outputBlobStreams) {
2946 for (auto& previewIter : outputPreviewStreams) {
2947 V3_2::Stream previewStream = {streamId++,
2948 StreamType::OUTPUT,
2949 static_cast<uint32_t>(previewIter.width),
2950 static_cast<uint32_t>(previewIter.height),
2951 static_cast<PixelFormat>(previewIter.format),
2952 GRALLOC1_CONSUMER_USAGE_HWCOMPOSER,
2953 0,
2954 StreamRotation::ROTATION_0};
2955 V3_2::Stream blobStream = {streamId++,
2956 StreamType::OUTPUT,
2957 static_cast<uint32_t>(blobIter.width),
2958 static_cast<uint32_t>(blobIter.height),
2959 static_cast<PixelFormat>(blobIter.format),
2960 GRALLOC1_CONSUMER_USAGE_CPU_READ,
2961 static_cast<V3_2::DataspaceFlags>(Dataspace::V0_JFIF),
2962 StreamRotation::ROTATION_0};
2963 ::android::hardware::hidl_vec<V3_2::Stream> streams = {previewStream,
2964 blobStream};
2965 ::android::hardware::camera::device::V3_4::StreamConfiguration config3_4;
2966 ::android::hardware::camera::device::V3_2::StreamConfiguration config3_2;
2967 createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE,
2968 &config3_2, &config3_4);
2969 if (session3_4 != nullptr) {
2970 ret = session3_4->configureStreams_3_4(config3_4,
2971 [](Status s, device::V3_4::HalStreamConfiguration halConfig) {
2972 ASSERT_EQ(Status::OK, s);
2973 ASSERT_EQ(2u, halConfig.streams.size());
2974 });
2975 } else if (session3_3 != nullptr) {
2976 ret = session3_3->configureStreams_3_3(config3_2,
2977 [](Status s, device::V3_3::HalStreamConfiguration halConfig) {
2978 ASSERT_EQ(Status::OK, s);
2979 ASSERT_EQ(2u, halConfig.streams.size());
2980 });
2981 } else {
2982 ret = session->configureStreams(config3_2,
2983 [](Status s, HalStreamConfiguration halConfig) {
2984 ASSERT_EQ(Status::OK, s);
2985 ASSERT_EQ(2u, halConfig.streams.size());
2986 });
2987 }
2988 ASSERT_TRUE(ret.isOk());
2989 }
2990 }
2991
2992 free_camera_metadata(staticMeta);
2993 ret = session->close();
2994 ASSERT_TRUE(ret.isOk());
2995 }
2996 }
2997
2998 // In case constrained mode is supported, test whether it can be
2999 // configured. Additionally check for common invalid inputs when
3000 // using this mode.
TEST_F(CameraHidlTest,configureStreamsConstrainedOutputs)3001 TEST_F(CameraHidlTest, configureStreamsConstrainedOutputs) {
3002 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
3003
3004 for (const auto& name : cameraDeviceNames) {
3005 int deviceVersion = getCameraDeviceVersion(name, mProviderType);
3006 if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) {
3007 continue;
3008 } else if (deviceVersion <= 0) {
3009 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
3010 ADD_FAILURE();
3011 return;
3012 }
3013
3014 camera_metadata_t* staticMeta;
3015 Return<void> ret;
3016 sp<ICameraDeviceSession> session;
3017 sp<device::V3_3::ICameraDeviceSession> session3_3;
3018 sp<device::V3_4::ICameraDeviceSession> session3_4;
3019 openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/);
3020 castSession(session, deviceVersion, &session3_3, &session3_4);
3021
3022 Status rc = isConstrainedModeAvailable(staticMeta);
3023 if (Status::METHOD_NOT_SUPPORTED == rc) {
3024 ret = session->close();
3025 ASSERT_TRUE(ret.isOk());
3026 continue;
3027 }
3028 ASSERT_EQ(Status::OK, rc);
3029
3030 AvailableStream hfrStream;
3031 rc = pickConstrainedModeSize(staticMeta, hfrStream);
3032 ASSERT_EQ(Status::OK, rc);
3033
3034 int32_t streamId = 0;
3035 V3_2::Stream stream = {streamId,
3036 StreamType::OUTPUT,
3037 static_cast<uint32_t>(hfrStream.width),
3038 static_cast<uint32_t>(hfrStream.height),
3039 static_cast<PixelFormat>(hfrStream.format),
3040 GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER,
3041 0,
3042 StreamRotation::ROTATION_0};
3043 ::android::hardware::hidl_vec<V3_2::Stream> streams = {stream};
3044 ::android::hardware::camera::device::V3_4::StreamConfiguration config3_4;
3045 ::android::hardware::camera::device::V3_2::StreamConfiguration config3_2;
3046 createStreamConfiguration(streams, StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE,
3047 &config3_2, &config3_4);
3048 if (session3_4 != nullptr) {
3049 ret = session3_4->configureStreams_3_4(config3_4,
3050 [streamId](Status s, device::V3_4::HalStreamConfiguration halConfig) {
3051 ASSERT_EQ(Status::OK, s);
3052 ASSERT_EQ(1u, halConfig.streams.size());
3053 ASSERT_EQ(halConfig.streams[0].v3_3.v3_2.id, streamId);
3054 });
3055 } else if (session3_3 != nullptr) {
3056 ret = session3_3->configureStreams_3_3(config3_2,
3057 [streamId](Status s, device::V3_3::HalStreamConfiguration halConfig) {
3058 ASSERT_EQ(Status::OK, s);
3059 ASSERT_EQ(1u, halConfig.streams.size());
3060 ASSERT_EQ(halConfig.streams[0].v3_2.id, streamId);
3061 });
3062 } else {
3063 ret = session->configureStreams(config3_2,
3064 [streamId](Status s, HalStreamConfiguration halConfig) {
3065 ASSERT_EQ(Status::OK, s);
3066 ASSERT_EQ(1u, halConfig.streams.size());
3067 ASSERT_EQ(halConfig.streams[0].id, streamId);
3068 });
3069 }
3070 ASSERT_TRUE(ret.isOk());
3071
3072 stream = {streamId++,
3073 StreamType::OUTPUT,
3074 static_cast<uint32_t>(0),
3075 static_cast<uint32_t>(0),
3076 static_cast<PixelFormat>(hfrStream.format),
3077 GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER,
3078 0,
3079 StreamRotation::ROTATION_0};
3080 streams[0] = stream;
3081 createStreamConfiguration(streams, StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE,
3082 &config3_2, &config3_4);
3083 if (session3_4 != nullptr) {
3084 ret = session3_4->configureStreams_3_4(config3_4,
3085 [](Status s, device::V3_4::HalStreamConfiguration) {
3086 ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) ||
3087 (Status::INTERNAL_ERROR == s));
3088 });
3089 } else if (session3_3 != nullptr) {
3090 ret = session3_3->configureStreams_3_3(config3_2,
3091 [](Status s, device::V3_3::HalStreamConfiguration) {
3092 ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) ||
3093 (Status::INTERNAL_ERROR == s));
3094 });
3095 } else {
3096 ret = session->configureStreams(config3_2,
3097 [](Status s, HalStreamConfiguration) {
3098 ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) ||
3099 (Status::INTERNAL_ERROR == s));
3100 });
3101 }
3102 ASSERT_TRUE(ret.isOk());
3103
3104 stream = {streamId++,
3105 StreamType::OUTPUT,
3106 static_cast<uint32_t>(UINT32_MAX),
3107 static_cast<uint32_t>(UINT32_MAX),
3108 static_cast<PixelFormat>(hfrStream.format),
3109 GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER,
3110 0,
3111 StreamRotation::ROTATION_0};
3112 streams[0] = stream;
3113 createStreamConfiguration(streams, StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE,
3114 &config3_2, &config3_4);
3115 if (session3_4 != nullptr) {
3116 ret = session3_4->configureStreams_3_4(config3_4,
3117 [](Status s, device::V3_4::HalStreamConfiguration) {
3118 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
3119 });
3120 } else if (session3_3 != nullptr) {
3121 ret = session3_3->configureStreams_3_3(config3_2,
3122 [](Status s, device::V3_3::HalStreamConfiguration) {
3123 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
3124 });
3125 } else {
3126 ret = session->configureStreams(config3_2,
3127 [](Status s, HalStreamConfiguration) {
3128 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
3129 });
3130 }
3131 ASSERT_TRUE(ret.isOk());
3132
3133 stream = {streamId++,
3134 StreamType::OUTPUT,
3135 static_cast<uint32_t>(hfrStream.width),
3136 static_cast<uint32_t>(hfrStream.height),
3137 static_cast<PixelFormat>(UINT32_MAX),
3138 GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER,
3139 0,
3140 StreamRotation::ROTATION_0};
3141 streams[0] = stream;
3142 createStreamConfiguration(streams, StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE,
3143 &config3_2, &config3_4);
3144 if (session3_4 != nullptr) {
3145 ret = session3_4->configureStreams_3_4(config3_4,
3146 [](Status s, device::V3_4::HalStreamConfiguration) {
3147 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
3148 });
3149 } else if (session3_3 != nullptr) {
3150 ret = session3_3->configureStreams_3_3(config3_2,
3151 [](Status s, device::V3_3::HalStreamConfiguration) {
3152 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
3153 });
3154 } else {
3155 ret = session->configureStreams(config3_2,
3156 [](Status s, HalStreamConfiguration) {
3157 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
3158 });
3159 }
3160 ASSERT_TRUE(ret.isOk());
3161
3162 free_camera_metadata(staticMeta);
3163 ret = session->close();
3164 ASSERT_TRUE(ret.isOk());
3165 }
3166 }
3167
3168 // Verify that all supported video + snapshot stream combinations can
3169 // be configured successfully.
TEST_F(CameraHidlTest,configureStreamsVideoStillOutputs)3170 TEST_F(CameraHidlTest, configureStreamsVideoStillOutputs) {
3171 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
3172 std::vector<AvailableStream> outputBlobStreams;
3173 std::vector<AvailableStream> outputVideoStreams;
3174 AvailableStream videoThreshold = {kMaxVideoWidth, kMaxVideoHeight,
3175 static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
3176 AvailableStream blobThreshold = {kMaxVideoWidth, kMaxVideoHeight,
3177 static_cast<int32_t>(PixelFormat::BLOB)};
3178
3179 for (const auto& name : cameraDeviceNames) {
3180 int deviceVersion = getCameraDeviceVersion(name, mProviderType);
3181 if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) {
3182 continue;
3183 } else if (deviceVersion <= 0) {
3184 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
3185 ADD_FAILURE();
3186 return;
3187 }
3188
3189 camera_metadata_t* staticMeta;
3190 Return<void> ret;
3191 sp<ICameraDeviceSession> session;
3192 sp<device::V3_3::ICameraDeviceSession> session3_3;
3193 sp<device::V3_4::ICameraDeviceSession> session3_4;
3194 openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/);
3195 castSession(session, deviceVersion, &session3_3, &session3_4);
3196
3197 outputBlobStreams.clear();
3198 ASSERT_EQ(Status::OK,
3199 getAvailableOutputStreams(staticMeta, outputBlobStreams,
3200 &blobThreshold));
3201 ASSERT_NE(0u, outputBlobStreams.size());
3202
3203 outputVideoStreams.clear();
3204 ASSERT_EQ(Status::OK,
3205 getAvailableOutputStreams(staticMeta, outputVideoStreams,
3206 &videoThreshold));
3207 ASSERT_NE(0u, outputVideoStreams.size());
3208
3209 int32_t streamId = 0;
3210 for (auto& blobIter : outputBlobStreams) {
3211 for (auto& videoIter : outputVideoStreams) {
3212 V3_2::Stream videoStream = {streamId++,
3213 StreamType::OUTPUT,
3214 static_cast<uint32_t>(videoIter.width),
3215 static_cast<uint32_t>(videoIter.height),
3216 static_cast<PixelFormat>(videoIter.format),
3217 GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER,
3218 0,
3219 StreamRotation::ROTATION_0};
3220 V3_2::Stream blobStream = {streamId++,
3221 StreamType::OUTPUT,
3222 static_cast<uint32_t>(blobIter.width),
3223 static_cast<uint32_t>(blobIter.height),
3224 static_cast<PixelFormat>(blobIter.format),
3225 GRALLOC1_CONSUMER_USAGE_CPU_READ,
3226 static_cast<V3_2::DataspaceFlags>(Dataspace::V0_JFIF),
3227 StreamRotation::ROTATION_0};
3228 ::android::hardware::hidl_vec<V3_2::Stream> streams = {videoStream, blobStream};
3229 ::android::hardware::camera::device::V3_4::StreamConfiguration config3_4;
3230 ::android::hardware::camera::device::V3_2::StreamConfiguration config3_2;
3231 createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE,
3232 &config3_2, &config3_4);
3233 if (session3_4 != nullptr) {
3234 ret = session3_4->configureStreams_3_4(config3_4,
3235 [](Status s, device::V3_4::HalStreamConfiguration halConfig) {
3236 ASSERT_EQ(Status::OK, s);
3237 ASSERT_EQ(2u, halConfig.streams.size());
3238 });
3239 } else if (session3_3 != nullptr) {
3240 ret = session3_3->configureStreams_3_3(config3_2,
3241 [](Status s, device::V3_3::HalStreamConfiguration halConfig) {
3242 ASSERT_EQ(Status::OK, s);
3243 ASSERT_EQ(2u, halConfig.streams.size());
3244 });
3245 } else {
3246 ret = session->configureStreams(config3_2,
3247 [](Status s, HalStreamConfiguration halConfig) {
3248 ASSERT_EQ(Status::OK, s);
3249 ASSERT_EQ(2u, halConfig.streams.size());
3250 });
3251 }
3252 ASSERT_TRUE(ret.isOk());
3253 }
3254 }
3255
3256 free_camera_metadata(staticMeta);
3257 ret = session->close();
3258 ASSERT_TRUE(ret.isOk());
3259 }
3260 }
3261
3262 // Generate and verify a camera capture request
TEST_F(CameraHidlTest,processCaptureRequestPreview)3263 TEST_F(CameraHidlTest, processCaptureRequestPreview) {
3264 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
3265 AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
3266 static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
3267 uint64_t bufferId = 1;
3268 uint32_t frameNumber = 1;
3269 ::android::hardware::hidl_vec<uint8_t> settings;
3270
3271 for (const auto& name : cameraDeviceNames) {
3272 int deviceVersion = getCameraDeviceVersion(name, mProviderType);
3273 if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) {
3274 continue;
3275 } else if (deviceVersion <= 0) {
3276 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
3277 ADD_FAILURE();
3278 return;
3279 }
3280
3281 V3_2::Stream previewStream;
3282 HalStreamConfiguration halStreamConfig;
3283 sp<ICameraDeviceSession> session;
3284 bool supportsPartialResults = false;
3285 uint32_t partialResultCount = 0;
3286 configurePreviewStream(name, deviceVersion, mProvider, &previewThreshold, &session /*out*/,
3287 &previewStream /*out*/, &halStreamConfig /*out*/,
3288 &supportsPartialResults /*out*/,
3289 &partialResultCount /*out*/);
3290
3291 std::shared_ptr<ResultMetadataQueue> resultQueue;
3292 auto resultQueueRet =
3293 session->getCaptureResultMetadataQueue(
3294 [&resultQueue](const auto& descriptor) {
3295 resultQueue = std::make_shared<ResultMetadataQueue>(
3296 descriptor);
3297 if (!resultQueue->isValid() ||
3298 resultQueue->availableToWrite() <= 0) {
3299 ALOGE("%s: HAL returns empty result metadata fmq,"
3300 " not use it", __func__);
3301 resultQueue = nullptr;
3302 // Don't use the queue onwards.
3303 }
3304 });
3305 ASSERT_TRUE(resultQueueRet.isOk());
3306
3307 InFlightRequest inflightReq = {1, false, supportsPartialResults,
3308 partialResultCount, resultQueue};
3309
3310 RequestTemplate reqTemplate = RequestTemplate::PREVIEW;
3311 Return<void> ret;
3312 ret = session->constructDefaultRequestSettings(reqTemplate,
3313 [&](auto status, const auto& req) {
3314 ASSERT_EQ(Status::OK, status);
3315 settings = req;
3316 });
3317 ASSERT_TRUE(ret.isOk());
3318
3319 hidl_handle buffer_handle;
3320 allocateGraphicBuffer(previewStream.width, previewStream.height,
3321 android_convertGralloc1To0Usage(halStreamConfig.streams[0].producerUsage,
3322 halStreamConfig.streams[0].consumerUsage),
3323 halStreamConfig.streams[0].overrideFormat, &buffer_handle);
3324
3325 StreamBuffer outputBuffer = {halStreamConfig.streams[0].id,
3326 bufferId,
3327 buffer_handle,
3328 BufferStatus::OK,
3329 nullptr,
3330 nullptr};
3331 ::android::hardware::hidl_vec<StreamBuffer> outputBuffers = {outputBuffer};
3332 StreamBuffer emptyInputBuffer = {-1, 0, nullptr, BufferStatus::ERROR, nullptr,
3333 nullptr};
3334 CaptureRequest request = {frameNumber, 0 /* fmqSettingsSize */, settings,
3335 emptyInputBuffer, outputBuffers};
3336
3337 {
3338 std::unique_lock<std::mutex> l(mLock);
3339 mInflightMap.clear();
3340 mInflightMap.add(frameNumber, &inflightReq);
3341 }
3342
3343 Status status = Status::INTERNAL_ERROR;
3344 uint32_t numRequestProcessed = 0;
3345 hidl_vec<BufferCache> cachesToRemove;
3346 Return<void> returnStatus = session->processCaptureRequest(
3347 {request}, cachesToRemove, [&status, &numRequestProcessed](auto s,
3348 uint32_t n) {
3349 status = s;
3350 numRequestProcessed = n;
3351 });
3352 ASSERT_TRUE(returnStatus.isOk());
3353 ASSERT_EQ(Status::OK, status);
3354 ASSERT_EQ(numRequestProcessed, 1u);
3355
3356 {
3357 std::unique_lock<std::mutex> l(mLock);
3358 while (!inflightReq.errorCodeValid &&
3359 ((0 < inflightReq.numBuffersLeft) ||
3360 (!inflightReq.haveResultMetadata))) {
3361 auto timeout = std::chrono::system_clock::now() +
3362 std::chrono::seconds(kStreamBufferTimeoutSec);
3363 ASSERT_NE(std::cv_status::timeout,
3364 mResultCondition.wait_until(l, timeout));
3365 }
3366
3367 ASSERT_FALSE(inflightReq.errorCodeValid);
3368 ASSERT_NE(inflightReq.resultOutputBuffers.size(), 0u);
3369 ASSERT_EQ(previewStream.id, inflightReq.resultOutputBuffers[0].streamId);
3370
3371 request.frameNumber++;
3372 // Empty settings should be supported after the first call
3373 // for repeating requests.
3374 request.settings.setToExternal(nullptr, 0, true);
3375 // The buffer has been registered to HAL by bufferId, so per
3376 // API contract we should send a null handle for this buffer
3377 request.outputBuffers[0].buffer = nullptr;
3378 mInflightMap.clear();
3379 inflightReq = {1, false, supportsPartialResults, partialResultCount,
3380 resultQueue};
3381 mInflightMap.add(request.frameNumber, &inflightReq);
3382 }
3383
3384 returnStatus = session->processCaptureRequest(
3385 {request}, cachesToRemove, [&status, &numRequestProcessed](auto s,
3386 uint32_t n) {
3387 status = s;
3388 numRequestProcessed = n;
3389 });
3390 ASSERT_TRUE(returnStatus.isOk());
3391 ASSERT_EQ(Status::OK, status);
3392 ASSERT_EQ(numRequestProcessed, 1u);
3393
3394 {
3395 std::unique_lock<std::mutex> l(mLock);
3396 while (!inflightReq.errorCodeValid &&
3397 ((0 < inflightReq.numBuffersLeft) ||
3398 (!inflightReq.haveResultMetadata))) {
3399 auto timeout = std::chrono::system_clock::now() +
3400 std::chrono::seconds(kStreamBufferTimeoutSec);
3401 ASSERT_NE(std::cv_status::timeout,
3402 mResultCondition.wait_until(l, timeout));
3403 }
3404
3405 ASSERT_FALSE(inflightReq.errorCodeValid);
3406 ASSERT_NE(inflightReq.resultOutputBuffers.size(), 0u);
3407 ASSERT_EQ(previewStream.id, inflightReq.resultOutputBuffers[0].streamId);
3408 }
3409
3410 ret = session->close();
3411 ASSERT_TRUE(ret.isOk());
3412 }
3413 }
3414
3415 // Generate and verify a multi-camera capture request
TEST_F(CameraHidlTest,processMultiCaptureRequestPreview)3416 TEST_F(CameraHidlTest, processMultiCaptureRequestPreview) {
3417 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
3418 AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
3419 static_cast<int32_t>(PixelFormat::YCBCR_420_888)};
3420 uint64_t bufferId = 1;
3421 uint32_t frameNumber = 1;
3422 ::android::hardware::hidl_vec<uint8_t> settings;
3423 ::android::hardware::hidl_vec<uint8_t> emptySettings;
3424 hidl_string invalidPhysicalId = "-1";
3425
3426 for (const auto& name : cameraDeviceNames) {
3427 int deviceVersion = getCameraDeviceVersion(name, mProviderType);
3428 if (deviceVersion < CAMERA_DEVICE_API_VERSION_3_4) {
3429 continue;
3430 }
3431 std::string version, deviceId;
3432 ASSERT_TRUE(::matchDeviceName(name, mProviderType, &version, &deviceId));
3433 camera_metadata_t* staticMeta;
3434 Return<void> ret;
3435 sp<ICameraDeviceSession> session;
3436 openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/);
3437
3438 Status rc = isLogicalMultiCamera(staticMeta);
3439 if (Status::METHOD_NOT_SUPPORTED == rc) {
3440 free_camera_metadata(staticMeta);
3441 ret = session->close();
3442 ASSERT_TRUE(ret.isOk());
3443 continue;
3444 }
3445 std::unordered_set<std::string> physicalIds;
3446 rc = getPhysicalCameraIds(staticMeta, &physicalIds);
3447 ASSERT_TRUE(Status::OK == rc);
3448 ASSERT_TRUE(physicalIds.size() > 1);
3449
3450 std::unordered_set<int32_t> physicalRequestKeyIDs;
3451 rc = getSupportedKeys(staticMeta,
3452 ANDROID_REQUEST_AVAILABLE_PHYSICAL_CAMERA_REQUEST_KEYS, &physicalRequestKeyIDs);
3453 ASSERT_TRUE(Status::OK == rc);
3454 if (physicalRequestKeyIDs.empty()) {
3455 free_camera_metadata(staticMeta);
3456 ret = session->close();
3457 ASSERT_TRUE(ret.isOk());
3458 // The logical camera doesn't support any individual physical requests.
3459 continue;
3460 }
3461
3462 android::hardware::camera::common::V1_0::helper::CameraMetadata defaultPreviewSettings;
3463 android::hardware::camera::common::V1_0::helper::CameraMetadata filteredSettings;
3464 constructFilteredSettings(session, physicalRequestKeyIDs, RequestTemplate::PREVIEW,
3465 &defaultPreviewSettings, &filteredSettings);
3466 if (filteredSettings.isEmpty()) {
3467 // No physical device settings in default request.
3468 free_camera_metadata(staticMeta);
3469 ret = session->close();
3470 ASSERT_TRUE(ret.isOk());
3471 continue;
3472 }
3473
3474 const camera_metadata_t *settingsBuffer = defaultPreviewSettings.getAndLock();
3475 settings.setToExternal(
3476 reinterpret_cast<uint8_t *> (const_cast<camera_metadata_t *> (settingsBuffer)),
3477 get_camera_metadata_size(settingsBuffer));
3478
3479 free_camera_metadata(staticMeta);
3480 ret = session->close();
3481 ASSERT_TRUE(ret.isOk());
3482
3483 // Leave only 2 physical devices in the id set.
3484 auto it = physicalIds.begin();
3485 string physicalDeviceId = *it; it++;
3486 physicalIds.erase(++it, physicalIds.end());
3487 ASSERT_EQ(physicalIds.size(), 2u);
3488
3489 V3_4::HalStreamConfiguration halStreamConfig;
3490 bool supportsPartialResults = false;
3491 uint32_t partialResultCount = 0;
3492 V3_2::Stream previewStream;
3493 sp<device::V3_4::ICameraDeviceSession> session3_4;
3494 configurePreviewStreams3_4(name, deviceVersion, mProvider, &previewThreshold, physicalIds,
3495 &session3_4, &previewStream, &halStreamConfig /*out*/,
3496 &supportsPartialResults /*out*/, &partialResultCount /*out*/);
3497 ASSERT_NE(session3_4, nullptr);
3498
3499 std::shared_ptr<ResultMetadataQueue> resultQueue;
3500 auto resultQueueRet =
3501 session3_4->getCaptureResultMetadataQueue(
3502 [&resultQueue](const auto& descriptor) {
3503 resultQueue = std::make_shared<ResultMetadataQueue>(
3504 descriptor);
3505 if (!resultQueue->isValid() ||
3506 resultQueue->availableToWrite() <= 0) {
3507 ALOGE("%s: HAL returns empty result metadata fmq,"
3508 " not use it", __func__);
3509 resultQueue = nullptr;
3510 // Don't use the queue onwards.
3511 }
3512 });
3513 ASSERT_TRUE(resultQueueRet.isOk());
3514
3515 InFlightRequest inflightReq = {static_cast<ssize_t> (halStreamConfig.streams.size()), false,
3516 supportsPartialResults, partialResultCount, resultQueue};
3517
3518 std::vector<hidl_handle> graphicBuffers;
3519 graphicBuffers.reserve(halStreamConfig.streams.size());
3520 ::android::hardware::hidl_vec<StreamBuffer> outputBuffers;
3521 outputBuffers.resize(halStreamConfig.streams.size());
3522 size_t k = 0;
3523 for (const auto& halStream : halStreamConfig.streams) {
3524 hidl_handle buffer_handle;
3525 allocateGraphicBuffer(previewStream.width, previewStream.height,
3526 android_convertGralloc1To0Usage(halStream.v3_3.v3_2.producerUsage,
3527 halStream.v3_3.v3_2.consumerUsage),
3528 halStream.v3_3.v3_2.overrideFormat, &buffer_handle);
3529 graphicBuffers.push_back(buffer_handle);
3530 outputBuffers[k] = {halStream.v3_3.v3_2.id, bufferId, buffer_handle,
3531 BufferStatus::OK, nullptr, nullptr};
3532 bufferId++;
3533 k++;
3534 }
3535 hidl_vec<V3_4::PhysicalCameraSetting> camSettings(1);
3536 const camera_metadata_t *filteredSettingsBuffer = filteredSettings.getAndLock();
3537 camSettings[0].settings.setToExternal(
3538 reinterpret_cast<uint8_t *> (const_cast<camera_metadata_t *> (
3539 filteredSettingsBuffer)),
3540 get_camera_metadata_size(filteredSettingsBuffer));
3541 camSettings[0].fmqSettingsSize = 0;
3542 camSettings[0].physicalCameraId = physicalDeviceId;
3543
3544 StreamBuffer emptyInputBuffer = {-1, 0, nullptr, BufferStatus::ERROR, nullptr, nullptr};
3545 V3_4::CaptureRequest request = {{frameNumber, 0 /* fmqSettingsSize */, settings,
3546 emptyInputBuffer, outputBuffers}, camSettings};
3547
3548 {
3549 std::unique_lock<std::mutex> l(mLock);
3550 mInflightMap.clear();
3551 mInflightMap.add(frameNumber, &inflightReq);
3552 }
3553
3554 Status stat = Status::INTERNAL_ERROR;
3555 uint32_t numRequestProcessed = 0;
3556 hidl_vec<BufferCache> cachesToRemove;
3557 Return<void> returnStatus = session3_4->processCaptureRequest_3_4(
3558 {request}, cachesToRemove, [&stat, &numRequestProcessed](auto s, uint32_t n) {
3559 stat = s;
3560 numRequestProcessed = n;
3561 });
3562 ASSERT_TRUE(returnStatus.isOk());
3563 ASSERT_EQ(Status::OK, stat);
3564 ASSERT_EQ(numRequestProcessed, 1u);
3565
3566 {
3567 std::unique_lock<std::mutex> l(mLock);
3568 while (!inflightReq.errorCodeValid &&
3569 ((0 < inflightReq.numBuffersLeft) ||
3570 (!inflightReq.haveResultMetadata))) {
3571 auto timeout = std::chrono::system_clock::now() +
3572 std::chrono::seconds(kStreamBufferTimeoutSec);
3573 ASSERT_NE(std::cv_status::timeout,
3574 mResultCondition.wait_until(l, timeout));
3575 }
3576
3577 ASSERT_FALSE(inflightReq.errorCodeValid);
3578 ASSERT_NE(inflightReq.resultOutputBuffers.size(), 0u);
3579
3580 request.v3_2.frameNumber++;
3581 // Empty settings should be supported after the first call
3582 // for repeating requests.
3583 request.v3_2.settings.setToExternal(nullptr, 0, true);
3584 request.physicalCameraSettings[0].settings.setToExternal(nullptr, 0, true);
3585 // The buffer has been registered to HAL by bufferId, so per
3586 // API contract we should send a null handle for this buffer
3587 request.v3_2.outputBuffers[0].buffer = nullptr;
3588 mInflightMap.clear();
3589 inflightReq = {static_cast<ssize_t> (physicalIds.size()), false,
3590 supportsPartialResults, partialResultCount, resultQueue};
3591 mInflightMap.add(request.v3_2.frameNumber, &inflightReq);
3592 }
3593
3594 returnStatus = session3_4->processCaptureRequest_3_4(
3595 {request}, cachesToRemove, [&stat, &numRequestProcessed](auto s, uint32_t n) {
3596 stat = s;
3597 numRequestProcessed = n;
3598 });
3599 ASSERT_TRUE(returnStatus.isOk());
3600 ASSERT_EQ(Status::OK, stat);
3601 ASSERT_EQ(numRequestProcessed, 1u);
3602
3603 {
3604 std::unique_lock<std::mutex> l(mLock);
3605 while (!inflightReq.errorCodeValid &&
3606 ((0 < inflightReq.numBuffersLeft) ||
3607 (!inflightReq.haveResultMetadata))) {
3608 auto timeout = std::chrono::system_clock::now() +
3609 std::chrono::seconds(kStreamBufferTimeoutSec);
3610 ASSERT_NE(std::cv_status::timeout,
3611 mResultCondition.wait_until(l, timeout));
3612 }
3613
3614 ASSERT_FALSE(inflightReq.errorCodeValid);
3615 ASSERT_NE(inflightReq.resultOutputBuffers.size(), 0u);
3616 }
3617
3618 // Invalid physical camera id should fail process requests
3619 frameNumber++;
3620 camSettings[0].physicalCameraId = invalidPhysicalId;
3621 camSettings[0].settings = settings;
3622 request = {{frameNumber, 0 /* fmqSettingsSize */, settings,
3623 emptyInputBuffer, outputBuffers}, camSettings};
3624 returnStatus = session3_4->processCaptureRequest_3_4(
3625 {request}, cachesToRemove, [&stat, &numRequestProcessed](auto s, uint32_t n) {
3626 stat = s;
3627 numRequestProcessed = n;
3628 });
3629 ASSERT_TRUE(returnStatus.isOk());
3630 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, stat);
3631
3632 defaultPreviewSettings.unlock(settingsBuffer);
3633 filteredSettings.unlock(filteredSettingsBuffer);
3634 ret = session3_4->close();
3635 ASSERT_TRUE(ret.isOk());
3636 }
3637 }
3638
3639 // Generate and verify a burst containing alternating sensor sensitivity values
TEST_F(CameraHidlTest,processCaptureRequestBurstISO)3640 TEST_F(CameraHidlTest, processCaptureRequestBurstISO) {
3641 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
3642 AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
3643 static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
3644 uint64_t bufferId = 1;
3645 uint32_t frameNumber = 1;
3646 ::android::hardware::hidl_vec<uint8_t> settings;
3647
3648 for (const auto& name : cameraDeviceNames) {
3649 int deviceVersion = getCameraDeviceVersion(name, mProviderType);
3650 if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) {
3651 continue;
3652 } else if (deviceVersion <= 0) {
3653 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
3654 ADD_FAILURE();
3655 return;
3656 }
3657 camera_metadata_t* staticMetaBuffer;
3658 Return<void> ret;
3659 sp<ICameraDeviceSession> session;
3660 openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMetaBuffer /*out*/);
3661 ::android::hardware::camera::common::V1_0::helper::CameraMetadata staticMeta(
3662 staticMetaBuffer);
3663
3664 camera_metadata_entry_t hwLevel = staticMeta.find(ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL);
3665 ASSERT_TRUE(0 < hwLevel.count);
3666 if (ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED == hwLevel.data.u8[0] ||
3667 ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_EXTERNAL == hwLevel.data.u8[0]) {
3668 //Limited/External devices can skip this test
3669 ret = session->close();
3670 ASSERT_TRUE(ret.isOk());
3671 continue;
3672 }
3673
3674 camera_metadata_entry_t isoRange = staticMeta.find(ANDROID_SENSOR_INFO_SENSITIVITY_RANGE);
3675 ASSERT_EQ(isoRange.count, 2u);
3676
3677 ret = session->close();
3678 ASSERT_TRUE(ret.isOk());
3679
3680 bool supportsPartialResults = false;
3681 uint32_t partialResultCount = 0;
3682 V3_2::Stream previewStream;
3683 HalStreamConfiguration halStreamConfig;
3684 configurePreviewStream(name, deviceVersion, mProvider, &previewThreshold,
3685 &session /*out*/, &previewStream /*out*/, &halStreamConfig /*out*/,
3686 &supportsPartialResults /*out*/, &partialResultCount /*out*/);
3687 std::shared_ptr<ResultMetadataQueue> resultQueue;
3688
3689 auto resultQueueRet = session->getCaptureResultMetadataQueue(
3690 [&resultQueue](const auto& descriptor) {
3691 resultQueue = std::make_shared<ResultMetadataQueue>(descriptor);
3692 if (!resultQueue->isValid() || resultQueue->availableToWrite() <= 0) {
3693 ALOGE("%s: HAL returns empty result metadata fmq,"
3694 " not use it", __func__);
3695 resultQueue = nullptr;
3696 // Don't use the queue onwards.
3697 }
3698 });
3699 ASSERT_TRUE(resultQueueRet.isOk());
3700 ASSERT_NE(nullptr, resultQueue);
3701
3702 ret = session->constructDefaultRequestSettings(RequestTemplate::PREVIEW,
3703 [&](auto status, const auto& req) {
3704 ASSERT_EQ(Status::OK, status);
3705 settings = req; });
3706 ASSERT_TRUE(ret.isOk());
3707
3708 ::android::hardware::camera::common::V1_0::helper::CameraMetadata requestMeta;
3709 StreamBuffer emptyInputBuffer = {-1, 0, nullptr, BufferStatus::ERROR, nullptr, nullptr};
3710 hidl_handle buffers[kBurstFrameCount];
3711 StreamBuffer outputBuffers[kBurstFrameCount];
3712 CaptureRequest requests[kBurstFrameCount];
3713 InFlightRequest inflightReqs[kBurstFrameCount];
3714 int32_t isoValues[kBurstFrameCount];
3715 hidl_vec<uint8_t> requestSettings[kBurstFrameCount];
3716 for (uint32_t i = 0; i < kBurstFrameCount; i++) {
3717 std::unique_lock<std::mutex> l(mLock);
3718
3719 isoValues[i] = ((i % 2) == 0) ? isoRange.data.i32[0] : isoRange.data.i32[1];
3720 allocateGraphicBuffer(previewStream.width, previewStream.height,
3721 android_convertGralloc1To0Usage(halStreamConfig.streams[0].producerUsage,
3722 halStreamConfig.streams[0].consumerUsage),
3723 halStreamConfig.streams[0].overrideFormat, &buffers[i]);
3724
3725 outputBuffers[i] = {halStreamConfig.streams[0].id, bufferId + i,
3726 buffers[i], BufferStatus::OK, nullptr, nullptr};
3727 requestMeta.append(reinterpret_cast<camera_metadata_t *> (settings.data()));
3728
3729 // Disable all 3A routines
3730 uint8_t mode = static_cast<uint8_t>(ANDROID_CONTROL_MODE_OFF);
3731 ASSERT_EQ(::android::OK, requestMeta.update(ANDROID_CONTROL_MODE, &mode, 1));
3732 ASSERT_EQ(::android::OK, requestMeta.update(ANDROID_SENSOR_SENSITIVITY, &isoValues[i],
3733 1));
3734 camera_metadata_t *metaBuffer = requestMeta.release();
3735 requestSettings[i].setToExternal(reinterpret_cast<uint8_t *> (metaBuffer),
3736 get_camera_metadata_size(metaBuffer), true);
3737
3738 requests[i] = {frameNumber + i, 0 /* fmqSettingsSize */, requestSettings[i],
3739 emptyInputBuffer, {outputBuffers[i]}};
3740
3741 inflightReqs[i] = {1, false, supportsPartialResults, partialResultCount, resultQueue};
3742 mInflightMap.add(frameNumber + i, &inflightReqs[i]);
3743 }
3744
3745 Status status = Status::INTERNAL_ERROR;
3746 uint32_t numRequestProcessed = 0;
3747 hidl_vec<BufferCache> cachesToRemove;
3748 hidl_vec<CaptureRequest> burstRequest;
3749 burstRequest.setToExternal(requests, kBurstFrameCount);
3750 Return<void> returnStatus = session->processCaptureRequest(burstRequest, cachesToRemove,
3751 [&status, &numRequestProcessed] (auto s, uint32_t n) {
3752 status = s;
3753 numRequestProcessed = n;
3754 });
3755 ASSERT_TRUE(returnStatus.isOk());
3756 ASSERT_EQ(Status::OK, status);
3757 ASSERT_EQ(numRequestProcessed, kBurstFrameCount);
3758
3759 for (size_t i = 0; i < kBurstFrameCount; i++) {
3760 std::unique_lock<std::mutex> l(mLock);
3761 while (!inflightReqs[i].errorCodeValid && ((0 < inflightReqs[i].numBuffersLeft) ||
3762 (!inflightReqs[i].haveResultMetadata))) {
3763 auto timeout = std::chrono::system_clock::now() +
3764 std::chrono::seconds(kStreamBufferTimeoutSec);
3765 ASSERT_NE(std::cv_status::timeout, mResultCondition.wait_until(l, timeout));
3766 }
3767
3768 ASSERT_FALSE(inflightReqs[i].errorCodeValid);
3769 ASSERT_NE(inflightReqs[i].resultOutputBuffers.size(), 0u);
3770 ASSERT_EQ(previewStream.id, inflightReqs[i].resultOutputBuffers[0].streamId);
3771 ASSERT_FALSE(inflightReqs[i].collectedResult.isEmpty());
3772 ASSERT_TRUE(inflightReqs[i].collectedResult.exists(ANDROID_SENSOR_SENSITIVITY));
3773 camera_metadata_entry_t isoResult = inflightReqs[i].collectedResult.find(
3774 ANDROID_SENSOR_SENSITIVITY);
3775 ASSERT_TRUE(isoResult.data.i32[0] == isoValues[i]);
3776 }
3777
3778 ret = session->close();
3779 ASSERT_TRUE(ret.isOk());
3780 }
3781 }
3782
3783 // Test whether an incorrect capture request with missing settings will
3784 // be reported correctly.
TEST_F(CameraHidlTest,processCaptureRequestInvalidSinglePreview)3785 TEST_F(CameraHidlTest, processCaptureRequestInvalidSinglePreview) {
3786 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
3787 std::vector<AvailableStream> outputPreviewStreams;
3788 AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
3789 static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
3790 uint64_t bufferId = 1;
3791 uint32_t frameNumber = 1;
3792 ::android::hardware::hidl_vec<uint8_t> settings;
3793
3794 for (const auto& name : cameraDeviceNames) {
3795 int deviceVersion = getCameraDeviceVersion(name, mProviderType);
3796 if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) {
3797 continue;
3798 } else if (deviceVersion <= 0) {
3799 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
3800 ADD_FAILURE();
3801 return;
3802 }
3803
3804 V3_2::Stream previewStream;
3805 HalStreamConfiguration halStreamConfig;
3806 sp<ICameraDeviceSession> session;
3807 bool supportsPartialResults = false;
3808 uint32_t partialResultCount = 0;
3809 configurePreviewStream(name, deviceVersion, mProvider, &previewThreshold, &session /*out*/,
3810 &previewStream /*out*/, &halStreamConfig /*out*/,
3811 &supportsPartialResults /*out*/,
3812 &partialResultCount /*out*/);
3813
3814 hidl_handle buffer_handle;
3815 allocateGraphicBuffer(previewStream.width, previewStream.height,
3816 android_convertGralloc1To0Usage(halStreamConfig.streams[0].producerUsage,
3817 halStreamConfig.streams[0].consumerUsage),
3818 halStreamConfig.streams[0].overrideFormat, &buffer_handle);
3819
3820 StreamBuffer outputBuffer = {halStreamConfig.streams[0].id,
3821 bufferId,
3822 buffer_handle,
3823 BufferStatus::OK,
3824 nullptr,
3825 nullptr};
3826 ::android::hardware::hidl_vec<StreamBuffer> outputBuffers = {outputBuffer};
3827 StreamBuffer emptyInputBuffer = {-1, 0, nullptr, BufferStatus::ERROR, nullptr,
3828 nullptr};
3829 CaptureRequest request = {frameNumber, 0 /* fmqSettingsSize */, settings,
3830 emptyInputBuffer, outputBuffers};
3831
3832 // Settings were not correctly initialized, we should fail here
3833 Status status = Status::OK;
3834 uint32_t numRequestProcessed = 0;
3835 hidl_vec<BufferCache> cachesToRemove;
3836 Return<void> ret = session->processCaptureRequest(
3837 {request}, cachesToRemove, [&status, &numRequestProcessed](auto s,
3838 uint32_t n) {
3839 status = s;
3840 numRequestProcessed = n;
3841 });
3842 ASSERT_TRUE(ret.isOk());
3843 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, status);
3844 ASSERT_EQ(numRequestProcessed, 0u);
3845
3846 ret = session->close();
3847 ASSERT_TRUE(ret.isOk());
3848 }
3849 }
3850
3851 // Check whether an invalid capture request with missing output buffers
3852 // will be reported correctly.
TEST_F(CameraHidlTest,processCaptureRequestInvalidBuffer)3853 TEST_F(CameraHidlTest, processCaptureRequestInvalidBuffer) {
3854 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
3855 std::vector<AvailableStream> outputBlobStreams;
3856 AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
3857 static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
3858 uint32_t frameNumber = 1;
3859 ::android::hardware::hidl_vec<uint8_t> settings;
3860
3861 for (const auto& name : cameraDeviceNames) {
3862 int deviceVersion = getCameraDeviceVersion(name, mProviderType);
3863 if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) {
3864 continue;
3865 } else if (deviceVersion <= 0) {
3866 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
3867 ADD_FAILURE();
3868 return;
3869 }
3870
3871 V3_2::Stream previewStream;
3872 HalStreamConfiguration halStreamConfig;
3873 sp<ICameraDeviceSession> session;
3874 bool supportsPartialResults = false;
3875 uint32_t partialResultCount = 0;
3876 configurePreviewStream(name, deviceVersion, mProvider, &previewThreshold, &session /*out*/,
3877 &previewStream /*out*/, &halStreamConfig /*out*/,
3878 &supportsPartialResults /*out*/,
3879 &partialResultCount /*out*/);
3880
3881 RequestTemplate reqTemplate = RequestTemplate::PREVIEW;
3882 Return<void> ret;
3883 ret = session->constructDefaultRequestSettings(reqTemplate,
3884 [&](auto status, const auto& req) {
3885 ASSERT_EQ(Status::OK, status);
3886 settings = req;
3887 });
3888 ASSERT_TRUE(ret.isOk());
3889
3890 ::android::hardware::hidl_vec<StreamBuffer> emptyOutputBuffers;
3891 StreamBuffer emptyInputBuffer = {-1, 0, nullptr, BufferStatus::ERROR, nullptr,
3892 nullptr};
3893 CaptureRequest request = {frameNumber, 0 /* fmqSettingsSize */, settings,
3894 emptyInputBuffer, emptyOutputBuffers};
3895
3896 // Output buffers are missing, we should fail here
3897 Status status = Status::OK;
3898 uint32_t numRequestProcessed = 0;
3899 hidl_vec<BufferCache> cachesToRemove;
3900 ret = session->processCaptureRequest(
3901 {request}, cachesToRemove, [&status, &numRequestProcessed](auto s,
3902 uint32_t n) {
3903 status = s;
3904 numRequestProcessed = n;
3905 });
3906 ASSERT_TRUE(ret.isOk());
3907 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, status);
3908 ASSERT_EQ(numRequestProcessed, 0u);
3909
3910 ret = session->close();
3911 ASSERT_TRUE(ret.isOk());
3912 }
3913 }
3914
3915 // Generate, trigger and flush a preview request
TEST_F(CameraHidlTest,flushPreviewRequest)3916 TEST_F(CameraHidlTest, flushPreviewRequest) {
3917 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
3918 std::vector<AvailableStream> outputPreviewStreams;
3919 AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
3920 static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
3921 uint64_t bufferId = 1;
3922 uint32_t frameNumber = 1;
3923 ::android::hardware::hidl_vec<uint8_t> settings;
3924
3925 for (const auto& name : cameraDeviceNames) {
3926 int deviceVersion = getCameraDeviceVersion(name, mProviderType);
3927 if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) {
3928 continue;
3929 } else if (deviceVersion <= 0) {
3930 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
3931 ADD_FAILURE();
3932 return;
3933 }
3934
3935 V3_2::Stream previewStream;
3936 HalStreamConfiguration halStreamConfig;
3937 sp<ICameraDeviceSession> session;
3938 bool supportsPartialResults = false;
3939 uint32_t partialResultCount = 0;
3940 configurePreviewStream(name, deviceVersion, mProvider, &previewThreshold, &session /*out*/,
3941 &previewStream /*out*/, &halStreamConfig /*out*/,
3942 &supportsPartialResults /*out*/,
3943 &partialResultCount /*out*/);
3944
3945 std::shared_ptr<ResultMetadataQueue> resultQueue;
3946 auto resultQueueRet =
3947 session->getCaptureResultMetadataQueue(
3948 [&resultQueue](const auto& descriptor) {
3949 resultQueue = std::make_shared<ResultMetadataQueue>(
3950 descriptor);
3951 if (!resultQueue->isValid() ||
3952 resultQueue->availableToWrite() <= 0) {
3953 ALOGE("%s: HAL returns empty result metadata fmq,"
3954 " not use it", __func__);
3955 resultQueue = nullptr;
3956 // Don't use the queue onwards.
3957 }
3958 });
3959 ASSERT_TRUE(resultQueueRet.isOk());
3960
3961 InFlightRequest inflightReq = {1, false, supportsPartialResults,
3962 partialResultCount, resultQueue};
3963 RequestTemplate reqTemplate = RequestTemplate::PREVIEW;
3964 Return<void> ret;
3965 ret = session->constructDefaultRequestSettings(reqTemplate,
3966 [&](auto status, const auto& req) {
3967 ASSERT_EQ(Status::OK, status);
3968 settings = req;
3969 });
3970 ASSERT_TRUE(ret.isOk());
3971
3972 hidl_handle buffer_handle;
3973 allocateGraphicBuffer(previewStream.width, previewStream.height,
3974 android_convertGralloc1To0Usage(halStreamConfig.streams[0].producerUsage,
3975 halStreamConfig.streams[0].consumerUsage),
3976 halStreamConfig.streams[0].overrideFormat, &buffer_handle);
3977
3978 StreamBuffer outputBuffer = {halStreamConfig.streams[0].id,
3979 bufferId,
3980 buffer_handle,
3981 BufferStatus::OK,
3982 nullptr,
3983 nullptr};
3984 ::android::hardware::hidl_vec<StreamBuffer> outputBuffers = {outputBuffer};
3985 const StreamBuffer emptyInputBuffer = {-1, 0, nullptr,
3986 BufferStatus::ERROR, nullptr, nullptr};
3987 CaptureRequest request = {frameNumber, 0 /* fmqSettingsSize */, settings,
3988 emptyInputBuffer, outputBuffers};
3989
3990 {
3991 std::unique_lock<std::mutex> l(mLock);
3992 mInflightMap.clear();
3993 mInflightMap.add(frameNumber, &inflightReq);
3994 }
3995
3996 Status status = Status::INTERNAL_ERROR;
3997 uint32_t numRequestProcessed = 0;
3998 hidl_vec<BufferCache> cachesToRemove;
3999 ret = session->processCaptureRequest(
4000 {request}, cachesToRemove, [&status, &numRequestProcessed](auto s,
4001 uint32_t n) {
4002 status = s;
4003 numRequestProcessed = n;
4004 });
4005
4006 ASSERT_TRUE(ret.isOk());
4007 ASSERT_EQ(Status::OK, status);
4008 ASSERT_EQ(numRequestProcessed, 1u);
4009 // Flush before waiting for request to complete.
4010 Return<Status> returnStatus = session->flush();
4011 ASSERT_TRUE(returnStatus.isOk());
4012 ASSERT_EQ(Status::OK, returnStatus);
4013
4014 {
4015 std::unique_lock<std::mutex> l(mLock);
4016 while (!inflightReq.errorCodeValid &&
4017 ((0 < inflightReq.numBuffersLeft) ||
4018 (!inflightReq.haveResultMetadata))) {
4019 auto timeout = std::chrono::system_clock::now() +
4020 std::chrono::seconds(kStreamBufferTimeoutSec);
4021 ASSERT_NE(std::cv_status::timeout, mResultCondition.wait_until(l,
4022 timeout));
4023 }
4024
4025 if (!inflightReq.errorCodeValid) {
4026 ASSERT_NE(inflightReq.resultOutputBuffers.size(), 0u);
4027 ASSERT_EQ(previewStream.id, inflightReq.resultOutputBuffers[0].streamId);
4028 } else {
4029 switch (inflightReq.errorCode) {
4030 case ErrorCode::ERROR_REQUEST:
4031 case ErrorCode::ERROR_RESULT:
4032 case ErrorCode::ERROR_BUFFER:
4033 // Expected
4034 break;
4035 case ErrorCode::ERROR_DEVICE:
4036 default:
4037 FAIL() << "Unexpected error:"
4038 << static_cast<uint32_t>(inflightReq.errorCode);
4039 }
4040 }
4041
4042 ret = session->close();
4043 ASSERT_TRUE(ret.isOk());
4044 }
4045 }
4046 }
4047
4048 // Verify that camera flushes correctly without any pending requests.
TEST_F(CameraHidlTest,flushEmpty)4049 TEST_F(CameraHidlTest, flushEmpty) {
4050 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
4051 std::vector<AvailableStream> outputPreviewStreams;
4052 AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
4053 static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
4054
4055 for (const auto& name : cameraDeviceNames) {
4056 int deviceVersion = getCameraDeviceVersion(name, mProviderType);
4057 if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) {
4058 continue;
4059 } else if (deviceVersion <= 0) {
4060 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
4061 ADD_FAILURE();
4062 return;
4063 }
4064
4065 V3_2::Stream previewStream;
4066 HalStreamConfiguration halStreamConfig;
4067 sp<ICameraDeviceSession> session;
4068 bool supportsPartialResults = false;
4069 uint32_t partialResultCount = 0;
4070 configurePreviewStream(name, deviceVersion, mProvider, &previewThreshold, &session /*out*/,
4071 &previewStream /*out*/, &halStreamConfig /*out*/,
4072 &supportsPartialResults /*out*/,
4073 &partialResultCount /*out*/);
4074
4075 Return<Status> returnStatus = session->flush();
4076 ASSERT_TRUE(returnStatus.isOk());
4077 ASSERT_EQ(Status::OK, returnStatus);
4078
4079 {
4080 std::unique_lock<std::mutex> l(mLock);
4081 auto timeout = std::chrono::system_clock::now() +
4082 std::chrono::milliseconds(kEmptyFlushTimeoutMSec);
4083 ASSERT_EQ(std::cv_status::timeout, mResultCondition.wait_until(l, timeout));
4084 }
4085
4086 Return<void> ret = session->close();
4087 ASSERT_TRUE(ret.isOk());
4088 }
4089 }
4090
4091 // Retrieve all valid output stream resolutions from the camera
4092 // static characteristics.
getAvailableOutputStreams(camera_metadata_t * staticMeta,std::vector<AvailableStream> & outputStreams,const AvailableStream * threshold)4093 Status CameraHidlTest::getAvailableOutputStreams(camera_metadata_t *staticMeta,
4094 std::vector<AvailableStream> &outputStreams,
4095 const AvailableStream *threshold) {
4096 if (nullptr == staticMeta) {
4097 return Status::ILLEGAL_ARGUMENT;
4098 }
4099
4100 camera_metadata_ro_entry entry;
4101 int rc = find_camera_metadata_ro_entry(staticMeta,
4102 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS, &entry);
4103 if ((0 != rc) || (0 != (entry.count % 4))) {
4104 return Status::ILLEGAL_ARGUMENT;
4105 }
4106
4107 for (size_t i = 0; i < entry.count; i+=4) {
4108 if (ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT ==
4109 entry.data.i32[i + 3]) {
4110 if(nullptr == threshold) {
4111 AvailableStream s = {entry.data.i32[i+1],
4112 entry.data.i32[i+2], entry.data.i32[i]};
4113 outputStreams.push_back(s);
4114 } else {
4115 if ((threshold->format == entry.data.i32[i]) &&
4116 (threshold->width >= entry.data.i32[i+1]) &&
4117 (threshold->height >= entry.data.i32[i+2])) {
4118 AvailableStream s = {entry.data.i32[i+1],
4119 entry.data.i32[i+2], threshold->format};
4120 outputStreams.push_back(s);
4121 }
4122 }
4123 }
4124
4125 }
4126
4127 return Status::OK;
4128 }
4129
4130 // Check if the camera device has logical multi-camera capability.
isLogicalMultiCamera(camera_metadata_t * staticMeta)4131 Status CameraHidlTest::isLogicalMultiCamera(camera_metadata_t *staticMeta) {
4132 Status ret = Status::METHOD_NOT_SUPPORTED;
4133 if (nullptr == staticMeta) {
4134 return Status::ILLEGAL_ARGUMENT;
4135 }
4136
4137 camera_metadata_ro_entry entry;
4138 int rc = find_camera_metadata_ro_entry(staticMeta,
4139 ANDROID_REQUEST_AVAILABLE_CAPABILITIES, &entry);
4140 if (0 != rc) {
4141 return Status::ILLEGAL_ARGUMENT;
4142 }
4143
4144 for (size_t i = 0; i < entry.count; i++) {
4145 if (ANDROID_REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA == entry.data.u8[i]) {
4146 ret = Status::OK;
4147 break;
4148 }
4149 }
4150
4151 return ret;
4152 }
4153
4154 // Generate a list of physical camera ids backing a logical multi-camera.
getPhysicalCameraIds(camera_metadata_t * staticMeta,std::unordered_set<std::string> * physicalIds)4155 Status CameraHidlTest::getPhysicalCameraIds(camera_metadata_t *staticMeta,
4156 std::unordered_set<std::string> *physicalIds) {
4157 if ((nullptr == staticMeta) || (nullptr == physicalIds)) {
4158 return Status::ILLEGAL_ARGUMENT;
4159 }
4160
4161 camera_metadata_ro_entry entry;
4162 int rc = find_camera_metadata_ro_entry(staticMeta, ANDROID_LOGICAL_MULTI_CAMERA_PHYSICAL_IDS,
4163 &entry);
4164 if (0 != rc) {
4165 return Status::ILLEGAL_ARGUMENT;
4166 }
4167
4168 const uint8_t* ids = entry.data.u8;
4169 size_t start = 0;
4170 for (size_t i = 0; i < entry.count; i++) {
4171 if (ids[i] == '\0') {
4172 if (start != i) {
4173 std::string currentId(reinterpret_cast<const char *> (ids + start));
4174 physicalIds->emplace(currentId);
4175 }
4176 start = i + 1;
4177 }
4178 }
4179
4180 return Status::OK;
4181 }
4182
4183 // Generate a set of suported camera key ids.
getSupportedKeys(camera_metadata_t * staticMeta,uint32_t tagId,std::unordered_set<int32_t> * requestIDs)4184 Status CameraHidlTest::getSupportedKeys(camera_metadata_t *staticMeta,
4185 uint32_t tagId, std::unordered_set<int32_t> *requestIDs) {
4186 if ((nullptr == staticMeta) || (nullptr == requestIDs)) {
4187 return Status::ILLEGAL_ARGUMENT;
4188 }
4189
4190 camera_metadata_ro_entry entry;
4191 int rc = find_camera_metadata_ro_entry(staticMeta, tagId, &entry);
4192 if ((0 != rc) || (entry.count == 0)) {
4193 return Status::OK;
4194 }
4195
4196 requestIDs->insert(entry.data.i32, entry.data.i32 + entry.count);
4197
4198 return Status::OK;
4199 }
4200
constructFilteredSettings(const sp<ICameraDeviceSession> & session,const std::unordered_set<int32_t> & availableKeys,RequestTemplate reqTemplate,android::hardware::camera::common::V1_0::helper::CameraMetadata * defaultSettings,android::hardware::camera::common::V1_0::helper::CameraMetadata * filteredSettings)4201 void CameraHidlTest::constructFilteredSettings(const sp<ICameraDeviceSession>& session,
4202 const std::unordered_set<int32_t>& availableKeys, RequestTemplate reqTemplate,
4203 android::hardware::camera::common::V1_0::helper::CameraMetadata* defaultSettings,
4204 android::hardware::camera::common::V1_0::helper::CameraMetadata* filteredSettings) {
4205 ASSERT_NE(defaultSettings, nullptr);
4206 ASSERT_NE(filteredSettings, nullptr);
4207
4208 auto ret = session->constructDefaultRequestSettings(reqTemplate,
4209 [&defaultSettings] (auto status, const auto& req) mutable {
4210 ASSERT_EQ(Status::OK, status);
4211
4212 const camera_metadata_t *metadata = reinterpret_cast<const camera_metadata_t*> (
4213 req.data());
4214 size_t expectedSize = req.size();
4215 int result = validate_camera_metadata_structure(metadata, &expectedSize);
4216 ASSERT_TRUE((result == 0) || (result == CAMERA_METADATA_VALIDATION_SHIFTED));
4217
4218 size_t entryCount = get_camera_metadata_entry_count(metadata);
4219 ASSERT_GT(entryCount, 0u);
4220 *defaultSettings = metadata;
4221 });
4222 ASSERT_TRUE(ret.isOk());
4223 const android::hardware::camera::common::V1_0::helper::CameraMetadata &constSettings =
4224 *defaultSettings;
4225 for (const auto& keyIt : availableKeys) {
4226 camera_metadata_ro_entry entry = constSettings.find(keyIt);
4227 if (entry.count > 0) {
4228 filteredSettings->update(entry);
4229 }
4230 }
4231 }
4232
4233 // Check if constrained mode is supported by using the static
4234 // camera characteristics.
isConstrainedModeAvailable(camera_metadata_t * staticMeta)4235 Status CameraHidlTest::isConstrainedModeAvailable(camera_metadata_t *staticMeta) {
4236 Status ret = Status::METHOD_NOT_SUPPORTED;
4237 if (nullptr == staticMeta) {
4238 return Status::ILLEGAL_ARGUMENT;
4239 }
4240
4241 camera_metadata_ro_entry entry;
4242 int rc = find_camera_metadata_ro_entry(staticMeta,
4243 ANDROID_REQUEST_AVAILABLE_CAPABILITIES, &entry);
4244 if (0 != rc) {
4245 return Status::ILLEGAL_ARGUMENT;
4246 }
4247
4248 for (size_t i = 0; i < entry.count; i++) {
4249 if (ANDROID_REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO ==
4250 entry.data.u8[i]) {
4251 ret = Status::OK;
4252 break;
4253 }
4254 }
4255
4256 return ret;
4257 }
4258
4259 // Pick the largest supported HFR mode from the static camera
4260 // characteristics.
pickConstrainedModeSize(camera_metadata_t * staticMeta,AvailableStream & hfrStream)4261 Status CameraHidlTest::pickConstrainedModeSize(camera_metadata_t *staticMeta,
4262 AvailableStream &hfrStream) {
4263 if (nullptr == staticMeta) {
4264 return Status::ILLEGAL_ARGUMENT;
4265 }
4266
4267 camera_metadata_ro_entry entry;
4268 int rc = find_camera_metadata_ro_entry(staticMeta,
4269 ANDROID_CONTROL_AVAILABLE_HIGH_SPEED_VIDEO_CONFIGURATIONS, &entry);
4270 if (0 != rc) {
4271 return Status::METHOD_NOT_SUPPORTED;
4272 } else if (0 != (entry.count % 5)) {
4273 return Status::ILLEGAL_ARGUMENT;
4274 }
4275
4276 hfrStream = {0, 0,
4277 static_cast<uint32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
4278 for (size_t i = 0; i < entry.count; i+=5) {
4279 int32_t w = entry.data.i32[i];
4280 int32_t h = entry.data.i32[i+1];
4281 if ((hfrStream.width * hfrStream.height) < (w *h)) {
4282 hfrStream.width = w;
4283 hfrStream.height = h;
4284 }
4285 }
4286
4287 return Status::OK;
4288 }
4289
4290 // Check whether ZSL is available using the static camera
4291 // characteristics.
isZSLModeAvailable(camera_metadata_t * staticMeta)4292 Status CameraHidlTest::isZSLModeAvailable(camera_metadata_t *staticMeta) {
4293 Status ret = Status::METHOD_NOT_SUPPORTED;
4294 if (nullptr == staticMeta) {
4295 return Status::ILLEGAL_ARGUMENT;
4296 }
4297
4298 camera_metadata_ro_entry entry;
4299 int rc = find_camera_metadata_ro_entry(staticMeta,
4300 ANDROID_REQUEST_AVAILABLE_CAPABILITIES, &entry);
4301 if (0 != rc) {
4302 return Status::ILLEGAL_ARGUMENT;
4303 }
4304
4305 for (size_t i = 0; i < entry.count; i++) {
4306 if ((ANDROID_REQUEST_AVAILABLE_CAPABILITIES_PRIVATE_REPROCESSING ==
4307 entry.data.u8[i]) ||
4308 (ANDROID_REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING ==
4309 entry.data.u8[i]) ){
4310 ret = Status::OK;
4311 break;
4312 }
4313 }
4314
4315 return ret;
4316 }
4317
4318 // Retrieve the reprocess input-output format map from the static
4319 // camera characteristics.
getZSLInputOutputMap(camera_metadata_t * staticMeta,std::vector<AvailableZSLInputOutput> & inputOutputMap)4320 Status CameraHidlTest::getZSLInputOutputMap(camera_metadata_t *staticMeta,
4321 std::vector<AvailableZSLInputOutput> &inputOutputMap) {
4322 if (nullptr == staticMeta) {
4323 return Status::ILLEGAL_ARGUMENT;
4324 }
4325
4326 camera_metadata_ro_entry entry;
4327 int rc = find_camera_metadata_ro_entry(staticMeta,
4328 ANDROID_SCALER_AVAILABLE_INPUT_OUTPUT_FORMATS_MAP, &entry);
4329 if ((0 != rc) || (0 >= entry.count)) {
4330 return Status::ILLEGAL_ARGUMENT;
4331 }
4332
4333 const int32_t* contents = &entry.data.i32[0];
4334 for (size_t i = 0; i < entry.count; ) {
4335 int32_t inputFormat = contents[i++];
4336 int32_t length = contents[i++];
4337 for (int32_t j = 0; j < length; j++) {
4338 int32_t outputFormat = contents[i+j];
4339 AvailableZSLInputOutput zslEntry = {inputFormat, outputFormat};
4340 inputOutputMap.push_back(zslEntry);
4341 }
4342 i += length;
4343 }
4344
4345 return Status::OK;
4346 }
4347
4348 // Search for the largest stream size for a given format.
findLargestSize(const std::vector<AvailableStream> & streamSizes,int32_t format,AvailableStream & result)4349 Status CameraHidlTest::findLargestSize(
4350 const std::vector<AvailableStream> &streamSizes, int32_t format,
4351 AvailableStream &result) {
4352 result = {0, 0, 0};
4353 for (auto &iter : streamSizes) {
4354 if (format == iter.format) {
4355 if ((result.width * result.height) < (iter.width * iter.height)) {
4356 result = iter;
4357 }
4358 }
4359 }
4360
4361 return (result.format == format) ? Status::OK : Status::ILLEGAL_ARGUMENT;
4362 }
4363
4364 // Check whether the camera device supports specific focus mode.
isAutoFocusModeAvailable(CameraParameters & cameraParams,const char * mode)4365 Status CameraHidlTest::isAutoFocusModeAvailable(
4366 CameraParameters &cameraParams,
4367 const char *mode) {
4368 ::android::String8 focusModes(cameraParams.get(
4369 CameraParameters::KEY_SUPPORTED_FOCUS_MODES));
4370 if (focusModes.contains(mode)) {
4371 return Status::OK;
4372 }
4373
4374 return Status::METHOD_NOT_SUPPORTED;
4375 }
4376
createStreamConfiguration(const::android::hardware::hidl_vec<V3_2::Stream> & streams3_2,StreamConfigurationMode configMode,::android::hardware::camera::device::V3_2::StreamConfiguration * config3_2,::android::hardware::camera::device::V3_4::StreamConfiguration * config3_4)4377 void CameraHidlTest::createStreamConfiguration(
4378 const ::android::hardware::hidl_vec<V3_2::Stream>& streams3_2,
4379 StreamConfigurationMode configMode,
4380 ::android::hardware::camera::device::V3_2::StreamConfiguration *config3_2 /*out*/,
4381 ::android::hardware::camera::device::V3_4::StreamConfiguration *config3_4 /*out*/) {
4382 ASSERT_NE(nullptr, config3_2);
4383 ASSERT_NE(nullptr, config3_4);
4384
4385 ::android::hardware::hidl_vec<V3_4::Stream> streams3_4(streams3_2.size());
4386 size_t idx = 0;
4387 for (auto& stream3_2 : streams3_2) {
4388 V3_4::Stream stream;
4389 stream.v3_2 = stream3_2;
4390 streams3_4[idx++] = stream;
4391 }
4392 *config3_4 = {streams3_4, configMode, {}};
4393 *config3_2 = {streams3_2, configMode};
4394 }
4395
4396 // Configure multiple preview streams using different physical ids.
configurePreviewStreams3_4(const std::string & name,int32_t deviceVersion,sp<ICameraProvider> provider,const AvailableStream * previewThreshold,const std::unordered_set<std::string> & physicalIds,sp<device::V3_4::ICameraDeviceSession> * session3_4,V3_2::Stream * previewStream,device::V3_4::HalStreamConfiguration * halStreamConfig,bool * supportsPartialResults,uint32_t * partialResultCount)4397 void CameraHidlTest::configurePreviewStreams3_4(const std::string &name, int32_t deviceVersion,
4398 sp<ICameraProvider> provider,
4399 const AvailableStream *previewThreshold,
4400 const std::unordered_set<std::string>& physicalIds,
4401 sp<device::V3_4::ICameraDeviceSession> *session3_4 /*out*/,
4402 V3_2::Stream *previewStream /*out*/,
4403 device::V3_4::HalStreamConfiguration *halStreamConfig /*out*/,
4404 bool *supportsPartialResults /*out*/,
4405 uint32_t *partialResultCount /*out*/) {
4406 ASSERT_NE(nullptr, session3_4);
4407 ASSERT_NE(nullptr, halStreamConfig);
4408 ASSERT_NE(nullptr, previewStream);
4409 ASSERT_NE(nullptr, supportsPartialResults);
4410 ASSERT_NE(nullptr, partialResultCount);
4411 ASSERT_FALSE(physicalIds.empty());
4412
4413 std::vector<AvailableStream> outputPreviewStreams;
4414 ::android::sp<ICameraDevice> device3_x;
4415 ALOGI("configureStreams: Testing camera device %s", name.c_str());
4416 Return<void> ret;
4417 ret = provider->getCameraDeviceInterface_V3_x(
4418 name,
4419 [&](auto status, const auto& device) {
4420 ALOGI("getCameraDeviceInterface_V3_x returns status:%d",
4421 (int)status);
4422 ASSERT_EQ(Status::OK, status);
4423 ASSERT_NE(device, nullptr);
4424 device3_x = device;
4425 });
4426 ASSERT_TRUE(ret.isOk());
4427
4428 sp<DeviceCb> cb = new DeviceCb(this);
4429 sp<ICameraDeviceSession> session;
4430 ret = device3_x->open(
4431 cb,
4432 [&session](auto status, const auto& newSession) {
4433 ALOGI("device::open returns status:%d", (int)status);
4434 ASSERT_EQ(Status::OK, status);
4435 ASSERT_NE(newSession, nullptr);
4436 session = newSession;
4437 });
4438 ASSERT_TRUE(ret.isOk());
4439
4440 sp<device::V3_3::ICameraDeviceSession> session3_3;
4441 castSession(session, deviceVersion, &session3_3, session3_4);
4442 ASSERT_NE(nullptr, session3_4);
4443
4444 camera_metadata_t *staticMeta;
4445 ret = device3_x->getCameraCharacteristics([&] (Status s,
4446 CameraMetadata metadata) {
4447 ASSERT_EQ(Status::OK, s);
4448 staticMeta = clone_camera_metadata(
4449 reinterpret_cast<const camera_metadata_t*>(metadata.data()));
4450 ASSERT_NE(nullptr, staticMeta);
4451 });
4452 ASSERT_TRUE(ret.isOk());
4453
4454 camera_metadata_ro_entry entry;
4455 auto status = find_camera_metadata_ro_entry(staticMeta,
4456 ANDROID_REQUEST_PARTIAL_RESULT_COUNT, &entry);
4457 if ((0 == status) && (entry.count > 0)) {
4458 *partialResultCount = entry.data.i32[0];
4459 *supportsPartialResults = (*partialResultCount > 1);
4460 }
4461
4462 outputPreviewStreams.clear();
4463 auto rc = getAvailableOutputStreams(staticMeta,
4464 outputPreviewStreams, previewThreshold);
4465 free_camera_metadata(staticMeta);
4466 ASSERT_EQ(Status::OK, rc);
4467 ASSERT_FALSE(outputPreviewStreams.empty());
4468
4469 ::android::hardware::hidl_vec<V3_4::Stream> streams3_4(physicalIds.size());
4470 int32_t streamId = 0;
4471 for (auto const& physicalId : physicalIds) {
4472 V3_4::Stream stream3_4 = {{streamId, StreamType::OUTPUT,
4473 static_cast<uint32_t> (outputPreviewStreams[0].width),
4474 static_cast<uint32_t> (outputPreviewStreams[0].height),
4475 static_cast<PixelFormat> (outputPreviewStreams[0].format),
4476 GRALLOC1_CONSUMER_USAGE_HWCOMPOSER, 0, StreamRotation::ROTATION_0},
4477 physicalId.c_str(), /*bufferSize*/ 0};
4478 streams3_4[streamId++] = stream3_4;
4479 }
4480
4481 ::android::hardware::camera::device::V3_4::StreamConfiguration config3_4;
4482 config3_4 = {streams3_4, StreamConfigurationMode::NORMAL_MODE, {}};
4483 RequestTemplate reqTemplate = RequestTemplate::PREVIEW;
4484 ret = (*session3_4)->constructDefaultRequestSettings(reqTemplate,
4485 [&config3_4](auto status, const auto& req) {
4486 ASSERT_EQ(Status::OK, status);
4487 config3_4.sessionParams = req;
4488 });
4489 ASSERT_TRUE(ret.isOk());
4490
4491 ret = (*session3_4)->configureStreams_3_4(config3_4,
4492 [&] (Status s, device::V3_4::HalStreamConfiguration halConfig) {
4493 ASSERT_EQ(Status::OK, s);
4494 ASSERT_EQ(physicalIds.size(), halConfig.streams.size());
4495 *halStreamConfig = halConfig;
4496 });
4497 *previewStream = streams3_4[0].v3_2;
4498 ASSERT_TRUE(ret.isOk());
4499 }
4500
4501 // Open a device session and configure a preview stream.
configurePreviewStream(const std::string & name,int32_t deviceVersion,sp<ICameraProvider> provider,const AvailableStream * previewThreshold,sp<ICameraDeviceSession> * session,V3_2::Stream * previewStream,HalStreamConfiguration * halStreamConfig,bool * supportsPartialResults,uint32_t * partialResultCount)4502 void CameraHidlTest::configurePreviewStream(const std::string &name, int32_t deviceVersion,
4503 sp<ICameraProvider> provider,
4504 const AvailableStream *previewThreshold,
4505 sp<ICameraDeviceSession> *session /*out*/,
4506 V3_2::Stream *previewStream /*out*/,
4507 HalStreamConfiguration *halStreamConfig /*out*/,
4508 bool *supportsPartialResults /*out*/,
4509 uint32_t *partialResultCount /*out*/) {
4510 ASSERT_NE(nullptr, session);
4511 ASSERT_NE(nullptr, previewStream);
4512 ASSERT_NE(nullptr, halStreamConfig);
4513 ASSERT_NE(nullptr, supportsPartialResults);
4514 ASSERT_NE(nullptr, partialResultCount);
4515
4516 std::vector<AvailableStream> outputPreviewStreams;
4517 ::android::sp<ICameraDevice> device3_x;
4518 ALOGI("configureStreams: Testing camera device %s", name.c_str());
4519 Return<void> ret;
4520 ret = provider->getCameraDeviceInterface_V3_x(
4521 name,
4522 [&](auto status, const auto& device) {
4523 ALOGI("getCameraDeviceInterface_V3_x returns status:%d",
4524 (int)status);
4525 ASSERT_EQ(Status::OK, status);
4526 ASSERT_NE(device, nullptr);
4527 device3_x = device;
4528 });
4529 ASSERT_TRUE(ret.isOk());
4530
4531 sp<DeviceCb> cb = new DeviceCb(this);
4532 ret = device3_x->open(
4533 cb,
4534 [&](auto status, const auto& newSession) {
4535 ALOGI("device::open returns status:%d", (int)status);
4536 ASSERT_EQ(Status::OK, status);
4537 ASSERT_NE(newSession, nullptr);
4538 *session = newSession;
4539 });
4540 ASSERT_TRUE(ret.isOk());
4541
4542 sp<device::V3_3::ICameraDeviceSession> session3_3;
4543 sp<device::V3_4::ICameraDeviceSession> session3_4;
4544 castSession(*session, deviceVersion, &session3_3, &session3_4);
4545
4546 camera_metadata_t *staticMeta;
4547 ret = device3_x->getCameraCharacteristics([&] (Status s,
4548 CameraMetadata metadata) {
4549 ASSERT_EQ(Status::OK, s);
4550 staticMeta = clone_camera_metadata(
4551 reinterpret_cast<const camera_metadata_t*>(metadata.data()));
4552 ASSERT_NE(nullptr, staticMeta);
4553 });
4554 ASSERT_TRUE(ret.isOk());
4555
4556 camera_metadata_ro_entry entry;
4557 auto status = find_camera_metadata_ro_entry(staticMeta,
4558 ANDROID_REQUEST_PARTIAL_RESULT_COUNT, &entry);
4559 if ((0 == status) && (entry.count > 0)) {
4560 *partialResultCount = entry.data.i32[0];
4561 *supportsPartialResults = (*partialResultCount > 1);
4562 }
4563
4564 outputPreviewStreams.clear();
4565 auto rc = getAvailableOutputStreams(staticMeta,
4566 outputPreviewStreams, previewThreshold);
4567 free_camera_metadata(staticMeta);
4568 ASSERT_EQ(Status::OK, rc);
4569 ASSERT_FALSE(outputPreviewStreams.empty());
4570
4571 V3_2::Stream stream3_2 = {0, StreamType::OUTPUT,
4572 static_cast<uint32_t> (outputPreviewStreams[0].width),
4573 static_cast<uint32_t> (outputPreviewStreams[0].height),
4574 static_cast<PixelFormat> (outputPreviewStreams[0].format),
4575 GRALLOC1_CONSUMER_USAGE_HWCOMPOSER, 0, StreamRotation::ROTATION_0};
4576 ::android::hardware::hidl_vec<V3_2::Stream> streams3_2 = {stream3_2};
4577 ::android::hardware::camera::device::V3_2::StreamConfiguration config3_2;
4578 ::android::hardware::camera::device::V3_4::StreamConfiguration config3_4;
4579 createStreamConfiguration(streams3_2, StreamConfigurationMode::NORMAL_MODE,
4580 &config3_2, &config3_4);
4581 if (session3_4 != nullptr) {
4582 RequestTemplate reqTemplate = RequestTemplate::PREVIEW;
4583 ret = session3_4->constructDefaultRequestSettings(reqTemplate,
4584 [&config3_4](auto status, const auto& req) {
4585 ASSERT_EQ(Status::OK, status);
4586 config3_4.sessionParams = req;
4587 });
4588 ASSERT_TRUE(ret.isOk());
4589 ret = session3_4->configureStreams_3_4(config3_4,
4590 [&] (Status s, device::V3_4::HalStreamConfiguration halConfig) {
4591 ASSERT_EQ(Status::OK, s);
4592 ASSERT_EQ(1u, halConfig.streams.size());
4593 halStreamConfig->streams.resize(halConfig.streams.size());
4594 for (size_t i = 0; i < halConfig.streams.size(); i++) {
4595 halStreamConfig->streams[i] = halConfig.streams[i].v3_3.v3_2;
4596 }
4597 });
4598 } else if (session3_3 != nullptr) {
4599 ret = session3_3->configureStreams_3_3(config3_2,
4600 [&] (Status s, device::V3_3::HalStreamConfiguration halConfig) {
4601 ASSERT_EQ(Status::OK, s);
4602 ASSERT_EQ(1u, halConfig.streams.size());
4603 halStreamConfig->streams.resize(halConfig.streams.size());
4604 for (size_t i = 0; i < halConfig.streams.size(); i++) {
4605 halStreamConfig->streams[i] = halConfig.streams[i].v3_2;
4606 }
4607 });
4608 } else {
4609 ret = (*session)->configureStreams(config3_2,
4610 [&] (Status s, HalStreamConfiguration halConfig) {
4611 ASSERT_EQ(Status::OK, s);
4612 ASSERT_EQ(1u, halConfig.streams.size());
4613 *halStreamConfig = halConfig;
4614 });
4615 }
4616 *previewStream = stream3_2;
4617 ASSERT_TRUE(ret.isOk());
4618 }
4619
4620 //Cast camera device session to corresponding version
castSession(const sp<ICameraDeviceSession> & session,int32_t deviceVersion,sp<device::V3_3::ICameraDeviceSession> * session3_3,sp<device::V3_4::ICameraDeviceSession> * session3_4)4621 void CameraHidlTest::castSession(const sp<ICameraDeviceSession> &session, int32_t deviceVersion,
4622 sp<device::V3_3::ICameraDeviceSession> *session3_3 /*out*/,
4623 sp<device::V3_4::ICameraDeviceSession> *session3_4 /*out*/) {
4624 ASSERT_NE(nullptr, session3_3);
4625 ASSERT_NE(nullptr, session3_4);
4626
4627 switch (deviceVersion) {
4628 case CAMERA_DEVICE_API_VERSION_3_4: {
4629 auto castResult = device::V3_4::ICameraDeviceSession::castFrom(session);
4630 ASSERT_TRUE(castResult.isOk());
4631 *session3_4 = castResult;
4632 break;
4633 }
4634 case CAMERA_DEVICE_API_VERSION_3_3: {
4635 auto castResult = device::V3_3::ICameraDeviceSession::castFrom(session);
4636 ASSERT_TRUE(castResult.isOk());
4637 *session3_3 = castResult;
4638 break;
4639 }
4640 default:
4641 //no-op
4642 return;
4643 }
4644 }
4645
4646 // Open a device session with empty callbacks and return static metadata.
openEmptyDeviceSession(const std::string & name,sp<ICameraProvider> provider,sp<ICameraDeviceSession> * session,camera_metadata_t ** staticMeta)4647 void CameraHidlTest::openEmptyDeviceSession(const std::string &name,
4648 sp<ICameraProvider> provider,
4649 sp<ICameraDeviceSession> *session /*out*/,
4650 camera_metadata_t **staticMeta /*out*/) {
4651 ASSERT_NE(nullptr, session);
4652 ASSERT_NE(nullptr, staticMeta);
4653
4654 ::android::sp<ICameraDevice> device3_x;
4655 ALOGI("configureStreams: Testing camera device %s", name.c_str());
4656 Return<void> ret;
4657 ret = provider->getCameraDeviceInterface_V3_x(
4658 name,
4659 [&](auto status, const auto& device) {
4660 ALOGI("getCameraDeviceInterface_V3_x returns status:%d",
4661 (int)status);
4662 ASSERT_EQ(Status::OK, status);
4663 ASSERT_NE(device, nullptr);
4664 device3_x = device;
4665 });
4666 ASSERT_TRUE(ret.isOk());
4667
4668 sp<EmptyDeviceCb> cb = new EmptyDeviceCb();
4669 ret = device3_x->open(cb, [&](auto status, const auto& newSession) {
4670 ALOGI("device::open returns status:%d", (int)status);
4671 ASSERT_EQ(Status::OK, status);
4672 ASSERT_NE(newSession, nullptr);
4673 *session = newSession;
4674 });
4675 ASSERT_TRUE(ret.isOk());
4676
4677 ret = device3_x->getCameraCharacteristics([&] (Status s,
4678 CameraMetadata metadata) {
4679 ASSERT_EQ(Status::OK, s);
4680 *staticMeta = clone_camera_metadata(
4681 reinterpret_cast<const camera_metadata_t*>(metadata.data()));
4682 ASSERT_NE(nullptr, *staticMeta);
4683 });
4684 ASSERT_TRUE(ret.isOk());
4685 }
4686
4687 // Open a particular camera device.
openCameraDevice(const std::string & name,sp<ICameraProvider> provider,sp<::android::hardware::camera::device::V1_0::ICameraDevice> * device1)4688 void CameraHidlTest::openCameraDevice(const std::string &name,
4689 sp<ICameraProvider> provider,
4690 sp<::android::hardware::camera::device::V1_0::ICameraDevice> *device1 /*out*/) {
4691 ASSERT_TRUE(nullptr != device1);
4692
4693 Return<void> ret;
4694 ret = provider->getCameraDeviceInterface_V1_x(
4695 name,
4696 [&](auto status, const auto& device) {
4697 ALOGI("getCameraDeviceInterface_V1_x returns status:%d",
4698 (int)status);
4699 ASSERT_EQ(Status::OK, status);
4700 ASSERT_NE(device, nullptr);
4701 *device1 = device;
4702 });
4703 ASSERT_TRUE(ret.isOk());
4704
4705 sp<Camera1DeviceCb> deviceCb = new Camera1DeviceCb(this);
4706 Return<Status> returnStatus = (*device1)->open(deviceCb);
4707 ASSERT_TRUE(returnStatus.isOk());
4708 ASSERT_EQ(Status::OK, returnStatus);
4709 }
4710
4711 // Initialize and configure a preview window.
setupPreviewWindow(const sp<::android::hardware::camera::device::V1_0::ICameraDevice> & device,sp<BufferItemConsumer> * bufferItemConsumer,sp<BufferItemHander> * bufferHandler)4712 void CameraHidlTest::setupPreviewWindow(
4713 const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device,
4714 sp<BufferItemConsumer> *bufferItemConsumer /*out*/,
4715 sp<BufferItemHander> *bufferHandler /*out*/) {
4716 ASSERT_NE(nullptr, device.get());
4717 ASSERT_NE(nullptr, bufferItemConsumer);
4718 ASSERT_NE(nullptr, bufferHandler);
4719
4720 sp<IGraphicBufferProducer> producer;
4721 sp<IGraphicBufferConsumer> consumer;
4722 BufferQueue::createBufferQueue(&producer, &consumer);
4723 *bufferItemConsumer = new BufferItemConsumer(consumer,
4724 GraphicBuffer::USAGE_HW_TEXTURE); //Use GLConsumer default usage flags
4725 ASSERT_NE(nullptr, (*bufferItemConsumer).get());
4726 *bufferHandler = new BufferItemHander(*bufferItemConsumer);
4727 ASSERT_NE(nullptr, (*bufferHandler).get());
4728 (*bufferItemConsumer)->setFrameAvailableListener(*bufferHandler);
4729 sp<Surface> surface = new Surface(producer);
4730 sp<PreviewWindowCb> previewCb = new PreviewWindowCb(surface);
4731
4732 auto rc = device->setPreviewWindow(previewCb);
4733 ASSERT_TRUE(rc.isOk());
4734 ASSERT_EQ(Status::OK, rc);
4735 }
4736
4737 // Stop camera preview and close camera.
stopPreviewAndClose(const sp<::android::hardware::camera::device::V1_0::ICameraDevice> & device)4738 void CameraHidlTest::stopPreviewAndClose(
4739 const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device) {
4740 Return<void> ret = device->stopPreview();
4741 ASSERT_TRUE(ret.isOk());
4742
4743 ret = device->close();
4744 ASSERT_TRUE(ret.isOk());
4745 }
4746
4747 // Enable a specific camera message type.
enableMsgType(unsigned int msgType,const sp<::android::hardware::camera::device::V1_0::ICameraDevice> & device)4748 void CameraHidlTest::enableMsgType(unsigned int msgType,
4749 const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device) {
4750 Return<void> ret = device->enableMsgType(msgType);
4751 ASSERT_TRUE(ret.isOk());
4752
4753 Return<bool> returnBoolStatus = device->msgTypeEnabled(msgType);
4754 ASSERT_TRUE(returnBoolStatus.isOk());
4755 ASSERT_TRUE(returnBoolStatus);
4756 }
4757
4758 // Disable a specific camera message type.
disableMsgType(unsigned int msgType,const sp<::android::hardware::camera::device::V1_0::ICameraDevice> & device)4759 void CameraHidlTest::disableMsgType(unsigned int msgType,
4760 const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device) {
4761 Return<void> ret = device->disableMsgType(msgType);
4762 ASSERT_TRUE(ret.isOk());
4763
4764 Return<bool> returnBoolStatus = device->msgTypeEnabled(msgType);
4765 ASSERT_TRUE(returnBoolStatus.isOk());
4766 ASSERT_FALSE(returnBoolStatus);
4767 }
4768
4769 // Wait until a specific frame notification arrives.
waitForFrameLocked(DataCallbackMsg msgFrame,std::unique_lock<std::mutex> & l)4770 void CameraHidlTest::waitForFrameLocked(DataCallbackMsg msgFrame,
4771 std::unique_lock<std::mutex> &l) {
4772 while (msgFrame != mDataMessageTypeReceived) {
4773 auto timeout = std::chrono::system_clock::now() +
4774 std::chrono::seconds(kStreamBufferTimeoutSec);
4775 ASSERT_NE(std::cv_status::timeout,
4776 mResultCondition.wait_until(l, timeout));
4777 }
4778 }
4779
4780 // Start preview on a particular camera device
startPreview(const sp<::android::hardware::camera::device::V1_0::ICameraDevice> & device)4781 void CameraHidlTest::startPreview(
4782 const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device) {
4783 Return<Status> returnStatus = device->startPreview();
4784 ASSERT_TRUE(returnStatus.isOk());
4785 ASSERT_EQ(Status::OK, returnStatus);
4786 }
4787
4788 // Retrieve camera parameters.
getParameters(const sp<::android::hardware::camera::device::V1_0::ICameraDevice> & device,CameraParameters * cameraParams)4789 void CameraHidlTest::getParameters(
4790 const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device,
4791 CameraParameters *cameraParams /*out*/) {
4792 ASSERT_NE(nullptr, cameraParams);
4793
4794 Return<void> ret;
4795 ret = device->getParameters([&] (const ::android::hardware::hidl_string& params) {
4796 ASSERT_FALSE(params.empty());
4797 ::android::String8 paramString(params.c_str());
4798 (*cameraParams).unflatten(paramString);
4799 });
4800 ASSERT_TRUE(ret.isOk());
4801 }
4802
4803 // Set camera parameters.
setParameters(const sp<::android::hardware::camera::device::V1_0::ICameraDevice> & device,const CameraParameters & cameraParams)4804 void CameraHidlTest::setParameters(
4805 const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device,
4806 const CameraParameters &cameraParams) {
4807 Return<Status> returnStatus = device->setParameters(
4808 cameraParams.flatten().string());
4809 ASSERT_TRUE(returnStatus.isOk());
4810 ASSERT_EQ(Status::OK, returnStatus);
4811 }
4812
allocateGraphicBuffer(uint32_t width,uint32_t height,uint64_t usage,PixelFormat format,hidl_handle * buffer_handle)4813 void CameraHidlTest::allocateGraphicBuffer(uint32_t width, uint32_t height, uint64_t usage,
4814 PixelFormat format, hidl_handle *buffer_handle /*out*/) {
4815 ASSERT_NE(buffer_handle, nullptr);
4816
4817 sp<android::hardware::graphics::allocator::V2_0::IAllocator> allocator =
4818 android::hardware::graphics::allocator::V2_0::IAllocator::getService();
4819 ASSERT_NE(nullptr, allocator.get());
4820
4821 sp<android::hardware::graphics::mapper::V2_0::IMapper> mapper =
4822 android::hardware::graphics::mapper::V2_0::IMapper::getService();
4823 ASSERT_NE(mapper.get(), nullptr);
4824
4825 android::hardware::graphics::mapper::V2_0::IMapper::BufferDescriptorInfo descriptorInfo {};
4826 descriptorInfo.width = width;
4827 descriptorInfo.height = height;
4828 descriptorInfo.layerCount = 1;
4829 descriptorInfo.format = format;
4830 descriptorInfo.usage = usage;
4831
4832 ::android::hardware::hidl_vec<uint32_t> descriptor;
4833 auto ret = mapper->createDescriptor(
4834 descriptorInfo, [&descriptor](android::hardware::graphics::mapper::V2_0::Error err,
4835 ::android::hardware::hidl_vec<uint32_t> desc) {
4836 ASSERT_EQ(err, android::hardware::graphics::mapper::V2_0::Error::NONE);
4837 descriptor = desc;
4838 });
4839 ASSERT_TRUE(ret.isOk());
4840
4841 ret = allocator->allocate(descriptor, 1u,
4842 [&](android::hardware::graphics::mapper::V2_0::Error err, uint32_t /*stride*/,
4843 const ::android::hardware::hidl_vec<::android::hardware::hidl_handle>& buffers) {
4844 ASSERT_EQ(android::hardware::graphics::mapper::V2_0::Error::NONE, err);
4845 ASSERT_EQ(buffers.size(), 1u);
4846 *buffer_handle = buffers[0];
4847 });
4848 ASSERT_TRUE(ret.isOk());
4849 }
4850
main(int argc,char ** argv)4851 int main(int argc, char **argv) {
4852 ::testing::AddGlobalTestEnvironment(CameraHidlEnvironment::Instance());
4853 ::testing::InitGoogleTest(&argc, argv);
4854 CameraHidlEnvironment::Instance()->init(&argc, argv);
4855 int status = RUN_ALL_TESTS();
4856 ALOGI("Test result = %d", status);
4857 return status;
4858 }
4859