1 /*
2 * Copyright (C) 2016 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 #include <VtsHalHidlTargetTestBase.h>
19 #include <android/hardware/camera/device/1.0/ICameraDevice.h>
20 #include <android/hardware/camera/device/3.2/ICameraDevice.h>
21 #include <android/hardware/camera/provider/2.4/ICameraProvider.h>
22 #include <android/log.h>
23 #include <binder/MemoryHeapBase.h>
24 #include <grallocusage/GrallocUsageConversion.h>
25 #include <gui/BufferItemConsumer.h>
26 #include <gui/BufferQueue.h>
27 #include <gui/Surface.h>
28 #include <hardware/gralloc.h>
29 #include <hardware/gralloc1.h>
30 #include <inttypes.h>
31 #include <system/camera.h>
32 #include <ui/GraphicBuffer.h>
33 #include <utils/Errors.h>
34 #include <chrono>
35 #include <condition_variable>
36 #include <mutex>
37 #include <regex>
38 #include <unordered_map>
39 #include "CameraParameters.h"
40 #include "system/camera_metadata.h"
41
42 using ::android::hardware::Return;
43 using ::android::hardware::Void;
44 using ::android::hardware::hidl_handle;
45 using ::android::hardware::hidl_string;
46 using ::android::hardware::hidl_vec;
47 using ::android::sp;
48 using ::android::wp;
49 using ::android::GraphicBuffer;
50 using ::android::IGraphicBufferProducer;
51 using ::android::IGraphicBufferConsumer;
52 using ::android::BufferQueue;
53 using ::android::BufferItemConsumer;
54 using ::android::Surface;
55 using ::android::CameraParameters;
56 using ::android::hardware::graphics::common::V1_0::BufferUsage;
57 using ::android::hardware::graphics::common::V1_0::PixelFormat;
58 using ::android::hardware::camera::common::V1_0::Status;
59 using ::android::hardware::camera::common::V1_0::CameraDeviceStatus;
60 using ::android::hardware::camera::common::V1_0::TorchMode;
61 using ::android::hardware::camera::common::V1_0::TorchModeStatus;
62 using ::android::hardware::camera::provider::V2_4::ICameraProvider;
63 using ::android::hardware::camera::provider::V2_4::ICameraProviderCallback;
64 using ::android::hardware::camera::device::V3_2::ICameraDevice;
65 using ::android::hardware::camera::device::V3_2::BufferCache;
66 using ::android::hardware::camera::device::V3_2::CaptureRequest;
67 using ::android::hardware::camera::device::V3_2::CaptureResult;
68 using ::android::hardware::camera::device::V3_2::ICameraDeviceCallback;
69 using ::android::hardware::camera::device::V3_2::ICameraDeviceSession;
70 using ::android::hardware::camera::device::V3_2::NotifyMsg;
71 using ::android::hardware::camera::device::V3_2::RequestTemplate;
72 using ::android::hardware::camera::device::V3_2::Stream;
73 using ::android::hardware::camera::device::V3_2::StreamType;
74 using ::android::hardware::camera::device::V3_2::StreamRotation;
75 using ::android::hardware::camera::device::V3_2::StreamConfiguration;
76 using ::android::hardware::camera::device::V3_2::StreamConfigurationMode;
77 using ::android::hardware::camera::device::V3_2::CameraMetadata;
78 using ::android::hardware::camera::device::V3_2::HalStreamConfiguration;
79 using ::android::hardware::camera::device::V3_2::BufferStatus;
80 using ::android::hardware::camera::device::V3_2::StreamBuffer;
81 using ::android::hardware::camera::device::V3_2::MsgType;
82 using ::android::hardware::camera::device::V3_2::ErrorMsg;
83 using ::android::hardware::camera::device::V3_2::ErrorCode;
84 using ::android::hardware::camera::device::V1_0::CameraFacing;
85 using ::android::hardware::camera::device::V1_0::NotifyCallbackMsg;
86 using ::android::hardware::camera::device::V1_0::CommandType;
87 using ::android::hardware::camera::device::V1_0::DataCallbackMsg;
88 using ::android::hardware::camera::device::V1_0::CameraFrameMetadata;
89 using ::android::hardware::camera::device::V1_0::ICameraDevicePreviewCallback;
90 using ::android::hardware::camera::device::V1_0::FrameCallbackFlag;
91 using ::android::hardware::camera::device::V1_0::HandleTimestampMessage;
92
93 const char kCameraPassthroughServiceName[] = "legacy/0";
94 const uint32_t kMaxPreviewWidth = 1920;
95 const uint32_t kMaxPreviewHeight = 1080;
96 const uint32_t kMaxVideoWidth = 4096;
97 const uint32_t kMaxVideoHeight = 2160;
98 const int64_t kStreamBufferTimeoutSec = 3;
99 const int64_t kAutoFocusTimeoutSec = 5;
100 const int64_t kTorchTimeoutSec = 1;
101 const int64_t kEmptyFlushTimeoutMSec = 200;
102 const char kDumpOutput[] = "/dev/null";
103
104 struct AvailableStream {
105 int32_t width;
106 int32_t height;
107 int32_t format;
108 };
109
110 struct AvailableZSLInputOutput {
111 int32_t inputFormat;
112 int32_t outputFormat;
113 };
114
115 namespace {
116 // "device@<version>/legacy/<id>"
117 const char *kDeviceNameRE = "device@([0-9]+\\.[0-9]+)/legacy/(.+)";
118 const int CAMERA_DEVICE_API_VERSION_3_2 = 0x302;
119 const int CAMERA_DEVICE_API_VERSION_1_0 = 0x100;
120 const char *kHAL3_2 = "3.2";
121 const char *kHAL1_0 = "1.0";
122
matchDeviceName(const hidl_string & deviceName,std::smatch & sm)123 bool matchDeviceName(const hidl_string& deviceName, std::smatch& sm) {
124 std::regex e(kDeviceNameRE);
125 std::string deviceNameStd(deviceName.c_str());
126 return std::regex_match(deviceNameStd, sm, e);
127 }
128
getCameraDeviceVersion(const hidl_string & deviceName)129 int getCameraDeviceVersion(const hidl_string& deviceName) {
130 std::smatch sm;
131 bool match = matchDeviceName(deviceName, sm);
132 if (!match) {
133 return -1;
134 }
135 std::string version = sm[1].str();
136 if (version.compare(kHAL3_2) == 0) {
137 // maybe switched to 3.4 or define the hidl version enumlater
138 return CAMERA_DEVICE_API_VERSION_3_2;
139 } else if (version.compare(kHAL1_0) == 0) {
140 return CAMERA_DEVICE_API_VERSION_1_0;
141 }
142 return 0;
143 }
144
mapToStatus(::android::status_t s)145 Status mapToStatus(::android::status_t s) {
146 switch(s) {
147 case ::android::OK:
148 return Status::OK ;
149 case ::android::BAD_VALUE:
150 return Status::ILLEGAL_ARGUMENT ;
151 case -EBUSY:
152 return Status::CAMERA_IN_USE;
153 case -EUSERS:
154 return Status::MAX_CAMERAS_IN_USE;
155 case ::android::UNKNOWN_TRANSACTION:
156 return Status::METHOD_NOT_SUPPORTED;
157 case ::android::INVALID_OPERATION:
158 return Status::OPERATION_NOT_SUPPORTED;
159 case ::android::DEAD_OBJECT:
160 return Status::CAMERA_DISCONNECTED;
161 }
162 ALOGW("Unexpected HAL status code %d", s);
163 return Status::OPERATION_NOT_SUPPORTED;
164 }
165 }
166
167 // Test environment for camera
168 class CameraHidlEnvironment : public ::testing::Environment {
169 public:
170 // get the test environment singleton
Instance()171 static CameraHidlEnvironment* Instance() {
172 static CameraHidlEnvironment* instance = new CameraHidlEnvironment;
173 return instance;
174 }
175
176 virtual void SetUp() override;
177 virtual void TearDown() override;
178
179 sp<ICameraProvider> mProvider;
180
181 private:
CameraHidlEnvironment()182 CameraHidlEnvironment() {}
183
184 GTEST_DISALLOW_COPY_AND_ASSIGN_(CameraHidlEnvironment);
185 };
186
SetUp()187 void CameraHidlEnvironment::SetUp() {
188 // TODO: test the binderized mode
189 mProvider = ::testing::VtsHalHidlTargetTestBase::getService<ICameraProvider>(kCameraPassthroughServiceName);
190 // TODO: handle the device doesn't have any camera case
191 ALOGI_IF(mProvider, "provider is not nullptr, %p", mProvider.get());
192 ASSERT_NE(mProvider, nullptr);
193 }
194
TearDown()195 void CameraHidlEnvironment::TearDown() {
196 ALOGI("TearDown CameraHidlEnvironment");
197 }
198
199 struct BufferItemHander: public BufferItemConsumer::FrameAvailableListener {
BufferItemHanderBufferItemHander200 BufferItemHander(wp<BufferItemConsumer> consumer) : mConsumer(consumer) {}
201
onFrameAvailableBufferItemHander202 void onFrameAvailable(const android::BufferItem&) override {
203 sp<BufferItemConsumer> consumer = mConsumer.promote();
204 ASSERT_NE(nullptr, consumer.get());
205
206 android::BufferItem buffer;
207 ASSERT_EQ(android::OK, consumer->acquireBuffer(&buffer, 0));
208 ASSERT_EQ(android::OK, consumer->releaseBuffer(buffer));
209 }
210
211 private:
212 wp<BufferItemConsumer> mConsumer;
213 };
214
215 struct PreviewWindowCb : public ICameraDevicePreviewCallback {
PreviewWindowCbPreviewWindowCb216 PreviewWindowCb(sp<ANativeWindow> anw) : mPreviewWidth(0),
217 mPreviewHeight(0), mFormat(0), mPreviewUsage(0),
218 mPreviewSwapInterval(-1), mCrop{-1, -1, -1, -1}, mAnw(anw) {}
219
220 using dequeueBuffer_cb =
221 std::function<void(Status status, uint64_t bufferId,
222 const hidl_handle& buffer, uint32_t stride)>;
223 Return<void> dequeueBuffer(dequeueBuffer_cb _hidl_cb) override;
224
225 Return<Status> enqueueBuffer(uint64_t bufferId) override;
226
227 Return<Status> cancelBuffer(uint64_t bufferId) override;
228
229 Return<Status> setBufferCount(uint32_t count) override;
230
231 Return<Status> setBuffersGeometry(uint32_t w,
232 uint32_t h, PixelFormat format) override;
233
234 Return<Status> setCrop(int32_t left, int32_t top,
235 int32_t right, int32_t bottom) override;
236
237 Return<Status> setUsage(BufferUsage usage) override;
238
239 Return<Status> setSwapInterval(int32_t interval) override;
240
241 using getMinUndequeuedBufferCount_cb =
242 std::function<void(Status status, uint32_t count)>;
243 Return<void> getMinUndequeuedBufferCount(
244 getMinUndequeuedBufferCount_cb _hidl_cb) override;
245
246 Return<Status> setTimestamp(int64_t timestamp) override;
247
248 private:
249 struct BufferHasher {
operator ()PreviewWindowCb::BufferHasher250 size_t operator()(const buffer_handle_t& buf) const {
251 if (buf == nullptr)
252 return 0;
253
254 size_t result = 1;
255 result = 31 * result + buf->numFds;
256 result = 31 * result + buf->numInts;
257 int length = buf->numFds + buf->numInts;
258 for (int i = 0; i < length; i++) {
259 result = 31 * result + buf->data[i];
260 }
261 return result;
262 }
263 };
264
265 struct BufferComparator {
operator ()PreviewWindowCb::BufferComparator266 bool operator()(const buffer_handle_t& buf1,
267 const buffer_handle_t& buf2) const {
268 if ((buf1->numFds == buf2->numFds) &&
269 (buf1->numInts == buf2->numInts)) {
270 int length = buf1->numFds + buf1->numInts;
271 for (int i = 0; i < length; i++) {
272 if (buf1->data[i] != buf2->data[i]) {
273 return false;
274 }
275 }
276 return true;
277 }
278 return false;
279 }
280 };
281
282 std::pair<bool, uint64_t> getBufferId(ANativeWindowBuffer* anb);
283 void cleanupCirculatingBuffers();
284
285 std::mutex mBufferIdMapLock; // protecting mBufferIdMap and mNextBufferId
286 typedef std::unordered_map<const buffer_handle_t, uint64_t,
287 BufferHasher, BufferComparator> BufferIdMap;
288
289 BufferIdMap mBufferIdMap; // stream ID -> per stream buffer ID map
290 std::unordered_map<uint64_t, ANativeWindowBuffer*> mReversedBufMap;
291 uint64_t mNextBufferId = 1;
292
293 uint32_t mPreviewWidth, mPreviewHeight;
294 int mFormat, mPreviewUsage;
295 int32_t mPreviewSwapInterval;
296 android_native_rect_t mCrop;
297 sp<ANativeWindow> mAnw; //Native window reference
298 };
299
getBufferId(ANativeWindowBuffer * anb)300 std::pair<bool, uint64_t> PreviewWindowCb::getBufferId(
301 ANativeWindowBuffer* anb) {
302 std::lock_guard<std::mutex> lock(mBufferIdMapLock);
303
304 buffer_handle_t& buf = anb->handle;
305 auto it = mBufferIdMap.find(buf);
306 if (it == mBufferIdMap.end()) {
307 uint64_t bufId = mNextBufferId++;
308 mBufferIdMap[buf] = bufId;
309 mReversedBufMap[bufId] = anb;
310 return std::make_pair(true, bufId);
311 } else {
312 return std::make_pair(false, it->second);
313 }
314 }
315
cleanupCirculatingBuffers()316 void PreviewWindowCb::cleanupCirculatingBuffers() {
317 std::lock_guard<std::mutex> lock(mBufferIdMapLock);
318 mBufferIdMap.clear();
319 mReversedBufMap.clear();
320 }
321
dequeueBuffer(dequeueBuffer_cb _hidl_cb)322 Return<void> PreviewWindowCb::dequeueBuffer(dequeueBuffer_cb _hidl_cb) {
323 ANativeWindowBuffer* anb;
324 auto rc = native_window_dequeue_buffer_and_wait(mAnw.get(), &anb);
325 uint64_t bufferId = 0;
326 uint32_t stride = 0;
327 hidl_handle buf = nullptr;
328 if (rc == ::android::OK) {
329 auto pair = getBufferId(anb);
330 buf = (pair.first) ? anb->handle : nullptr;
331 bufferId = pair.second;
332 stride = anb->stride;
333 }
334
335 _hidl_cb(mapToStatus(rc), bufferId, buf, stride);
336 return Void();
337 }
338
enqueueBuffer(uint64_t bufferId)339 Return<Status> PreviewWindowCb::enqueueBuffer(uint64_t bufferId) {
340 if (mReversedBufMap.count(bufferId) == 0) {
341 ALOGE("%s: bufferId %" PRIu64 " not found", __FUNCTION__, bufferId);
342 return Status::ILLEGAL_ARGUMENT;
343 }
344 return mapToStatus(mAnw->queueBuffer(mAnw.get(),
345 mReversedBufMap.at(bufferId), -1));
346 }
347
cancelBuffer(uint64_t bufferId)348 Return<Status> PreviewWindowCb::cancelBuffer(uint64_t bufferId) {
349 if (mReversedBufMap.count(bufferId) == 0) {
350 ALOGE("%s: bufferId %" PRIu64 " not found", __FUNCTION__, bufferId);
351 return Status::ILLEGAL_ARGUMENT;
352 }
353 return mapToStatus(mAnw->cancelBuffer(mAnw.get(),
354 mReversedBufMap.at(bufferId), -1));
355 }
356
setBufferCount(uint32_t count)357 Return<Status> PreviewWindowCb::setBufferCount(uint32_t count) {
358 if (mAnw.get() != nullptr) {
359 // WAR for b/27039775
360 native_window_api_disconnect(mAnw.get(), NATIVE_WINDOW_API_CAMERA);
361 native_window_api_connect(mAnw.get(), NATIVE_WINDOW_API_CAMERA);
362 if (mPreviewWidth != 0) {
363 native_window_set_buffers_dimensions(mAnw.get(),
364 mPreviewWidth, mPreviewHeight);
365 native_window_set_buffers_format(mAnw.get(), mFormat);
366 }
367 if (mPreviewUsage != 0) {
368 native_window_set_usage(mAnw.get(), mPreviewUsage);
369 }
370 if (mPreviewSwapInterval >= 0) {
371 mAnw->setSwapInterval(mAnw.get(), mPreviewSwapInterval);
372 }
373 if (mCrop.left >= 0) {
374 native_window_set_crop(mAnw.get(), &(mCrop));
375 }
376 }
377
378 auto rc = native_window_set_buffer_count(mAnw.get(), count);
379 if (rc == ::android::OK) {
380 cleanupCirculatingBuffers();
381 }
382
383 return mapToStatus(rc);
384 }
385
setBuffersGeometry(uint32_t w,uint32_t h,PixelFormat format)386 Return<Status> PreviewWindowCb::setBuffersGeometry(uint32_t w, uint32_t h,
387 PixelFormat format) {
388 auto rc = native_window_set_buffers_dimensions(mAnw.get(), w, h);
389 if (rc == ::android::OK) {
390 mPreviewWidth = w;
391 mPreviewHeight = h;
392 rc = native_window_set_buffers_format(mAnw.get(),
393 static_cast<int>(format));
394 if (rc == ::android::OK) {
395 mFormat = static_cast<int>(format);
396 }
397 }
398
399 return mapToStatus(rc);
400 }
401
setCrop(int32_t left,int32_t top,int32_t right,int32_t bottom)402 Return<Status> PreviewWindowCb::setCrop(int32_t left, int32_t top,
403 int32_t right, int32_t bottom) {
404 android_native_rect_t crop = { left, top, right, bottom };
405 auto rc = native_window_set_crop(mAnw.get(), &crop);
406 if (rc == ::android::OK) {
407 mCrop = crop;
408 }
409 return mapToStatus(rc);
410 }
411
setUsage(BufferUsage usage)412 Return<Status> PreviewWindowCb::setUsage(BufferUsage usage) {
413 auto rc = native_window_set_usage(mAnw.get(), static_cast<int>(usage));
414 if (rc == ::android::OK) {
415 mPreviewUsage = static_cast<int>(usage);
416 }
417 return mapToStatus(rc);
418 }
419
setSwapInterval(int32_t interval)420 Return<Status> PreviewWindowCb::setSwapInterval(int32_t interval) {
421 auto rc = mAnw->setSwapInterval(mAnw.get(), interval);
422 if (rc == ::android::OK) {
423 mPreviewSwapInterval = interval;
424 }
425 return mapToStatus(rc);
426 }
427
getMinUndequeuedBufferCount(getMinUndequeuedBufferCount_cb _hidl_cb)428 Return<void> PreviewWindowCb::getMinUndequeuedBufferCount(
429 getMinUndequeuedBufferCount_cb _hidl_cb) {
430 int count = 0;
431 auto rc = mAnw->query(mAnw.get(),
432 NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &count);
433 _hidl_cb(mapToStatus(rc), count);
434 return Void();
435 }
436
setTimestamp(int64_t timestamp)437 Return<Status> PreviewWindowCb::setTimestamp(int64_t timestamp) {
438 return mapToStatus(native_window_set_buffers_timestamp(mAnw.get(),
439 timestamp));
440 }
441
442 // The main test class for camera HIDL HAL.
443 class CameraHidlTest : public ::testing::VtsHalHidlTargetTestBase {
444 public:
SetUp()445 virtual void SetUp() override {}
TearDown()446 virtual void TearDown() override {}
447
448 hidl_vec<hidl_string> getCameraDeviceNames();
449
450 struct EmptyDeviceCb : public ICameraDeviceCallback {
processCaptureResultCameraHidlTest::EmptyDeviceCb451 virtual Return<void> processCaptureResult(const hidl_vec<CaptureResult>& /*results*/) override {
452 ALOGI("processCaptureResult callback");
453 ADD_FAILURE(); // Empty callback should not reach here
454 return Void();
455 }
456
notifyCameraHidlTest::EmptyDeviceCb457 virtual Return<void> notify(const hidl_vec<NotifyMsg>& /*msgs*/) override {
458 ALOGI("notify callback");
459 ADD_FAILURE(); // Empty callback should not reach here
460 return Void();
461 }
462 };
463
464 struct DeviceCb : public ICameraDeviceCallback {
DeviceCbCameraHidlTest::DeviceCb465 DeviceCb(CameraHidlTest *parent) : mParent(parent) {}
466 Return<void> processCaptureResult(const hidl_vec<CaptureResult>& results) override;
467 Return<void> notify(const hidl_vec<NotifyMsg>& msgs) override;
468
469 private:
470 CameraHidlTest *mParent; // Parent object
471 };
472
473 struct TorchProviderCb : public ICameraProviderCallback {
TorchProviderCbCameraHidlTest::TorchProviderCb474 TorchProviderCb(CameraHidlTest *parent) : mParent(parent) {}
cameraDeviceStatusChangeCameraHidlTest::TorchProviderCb475 virtual Return<void> cameraDeviceStatusChange(
476 const hidl_string&, CameraDeviceStatus) override {
477 return Void();
478 }
479
torchModeStatusChangeCameraHidlTest::TorchProviderCb480 virtual Return<void> torchModeStatusChange(
481 const hidl_string&, TorchModeStatus newStatus) override {
482 std::lock_guard<std::mutex> l(mParent->mTorchLock);
483 mParent->mTorchStatus = newStatus;
484 mParent->mTorchCond.notify_one();
485 return Void();
486 }
487
488 private:
489 CameraHidlTest *mParent; // Parent object
490 };
491
492 struct Camera1DeviceCb :
493 public ::android::hardware::camera::device::V1_0::ICameraDeviceCallback {
Camera1DeviceCbCameraHidlTest::Camera1DeviceCb494 Camera1DeviceCb(CameraHidlTest *parent) : mParent(parent) {}
495
496 Return<void> notifyCallback(NotifyCallbackMsg msgType,
497 int32_t ext1, int32_t ext2) override;
498
499 Return<uint32_t> registerMemory(const hidl_handle& descriptor,
500 uint32_t bufferSize, uint32_t bufferCount) override;
501
502 Return<void> unregisterMemory(uint32_t memId) override;
503
504 Return<void> dataCallback(DataCallbackMsg msgType,
505 uint32_t data, uint32_t bufferIndex,
506 const CameraFrameMetadata& metadata) override;
507
508 Return<void> dataCallbackTimestamp(DataCallbackMsg msgType,
509 uint32_t data, uint32_t bufferIndex,
510 int64_t timestamp) override;
511
512 Return<void> handleCallbackTimestamp(DataCallbackMsg msgType,
513 const hidl_handle& frameData,uint32_t data,
514 uint32_t bufferIndex, int64_t timestamp) override;
515
516 Return<void> handleCallbackTimestampBatch(DataCallbackMsg msgType,
517 const ::android::hardware::hidl_vec<HandleTimestampMessage>& batch) override;
518
519
520 private:
521 CameraHidlTest *mParent; // Parent object
522 };
523
524 void openCameraDevice(const std::string &name,const CameraHidlEnvironment* env,
525 sp<::android::hardware::camera::device::V1_0::ICameraDevice> *device /*out*/);
526 void setupPreviewWindow(
527 const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device,
528 sp<BufferItemConsumer> *bufferItemConsumer /*out*/,
529 sp<BufferItemHander> *bufferHandler /*out*/);
530 void stopPreviewAndClose(
531 const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device);
532 void startPreview(
533 const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device);
534 void enableMsgType(unsigned int msgType,
535 const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device);
536 void disableMsgType(unsigned int msgType,
537 const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device);
538 void getParameters(
539 const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device,
540 CameraParameters *cameraParams /*out*/);
541 void setParameters(
542 const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device,
543 const CameraParameters &cameraParams);
544 void waitForFrameLocked(DataCallbackMsg msgFrame,
545 std::unique_lock<std::mutex> &l);
546 void openEmptyDeviceSession(const std::string &name,
547 const CameraHidlEnvironment* env,
548 sp<ICameraDeviceSession> *session /*out*/,
549 camera_metadata_t **staticMeta /*out*/);
550 void configurePreviewStream(const std::string &name,
551 const CameraHidlEnvironment* env,
552 const AvailableStream *previewThreshold,
553 sp<ICameraDeviceSession> *session /*out*/,
554 Stream *previewStream /*out*/,
555 HalStreamConfiguration *halStreamConfig /*out*/);
556 static Status getAvailableOutputStreams(camera_metadata_t *staticMeta,
557 std::vector<AvailableStream> &outputStreams,
558 const AvailableStream *threshold = nullptr);
559 static Status isConstrainedModeAvailable(camera_metadata_t *staticMeta);
560 static Status pickConstrainedModeSize(camera_metadata_t *staticMeta,
561 AvailableStream &hfrStream);
562 static Status isZSLModeAvailable(camera_metadata_t *staticMeta);
563 static Status getZSLInputOutputMap(camera_metadata_t *staticMeta,
564 std::vector<AvailableZSLInputOutput> &inputOutputMap);
565 static Status findLargestSize(
566 const std::vector<AvailableStream> &streamSizes,
567 int32_t format, AvailableStream &result);
568 static Status isAutoFocusModeAvailable(
569 ::android::CameraParameters &cameraParams, const char *mode) ;
570
571 protected:
572 std::mutex mLock; // Synchronize access to member variables
573 std::condition_variable mResultCondition; // Condition variable for incoming results
574 uint32_t mResultFrameNumber; // Expected result frame number
575 std::vector<StreamBuffer> mResultBuffers; // Holds stream buffers from capture result
576 std::vector<ErrorMsg> mErrors; // Holds incoming error notifications
577 DataCallbackMsg mDataMessageTypeReceived; // Most recent message type received through data callbacks
578 uint32_t mVideoBufferIndex; // Buffer index of the most recent video buffer
579 uint32_t mVideoData; // Buffer data of the most recent video buffer
580 hidl_handle mVideoNativeHandle; // Most recent video buffer native handle
581 NotifyCallbackMsg mNotifyMessage; // Current notification message
582
583 std::mutex mTorchLock; // Synchronize access to torch status
584 std::condition_variable mTorchCond; // Condition variable for torch status
585 TorchModeStatus mTorchStatus; // Current torch status
586
587 // Holds camera registered buffers
588 std::unordered_map<uint32_t, sp<::android::MemoryHeapBase> > mMemoryPool;
589 };
590
notifyCallback(NotifyCallbackMsg msgType,int32_t ext1 __unused,int32_t ext2 __unused)591 Return<void> CameraHidlTest::Camera1DeviceCb::notifyCallback(
592 NotifyCallbackMsg msgType, int32_t ext1 __unused,
593 int32_t ext2 __unused) {
594 std::unique_lock<std::mutex> l(mParent->mLock);
595 mParent->mNotifyMessage = msgType;
596 mParent->mResultCondition.notify_one();
597
598 return Void();
599 }
600
registerMemory(const hidl_handle & descriptor,uint32_t bufferSize,uint32_t bufferCount)601 Return<uint32_t> CameraHidlTest::Camera1DeviceCb::registerMemory(
602 const hidl_handle& descriptor, uint32_t bufferSize,
603 uint32_t bufferCount) {
604 if (descriptor->numFds != 1) {
605 ADD_FAILURE() << "camera memory descriptor has"
606 " numFds " << descriptor->numFds << " (expect 1)" ;
607 return 0;
608 }
609 if (descriptor->data[0] < 0) {
610 ADD_FAILURE() << "camera memory descriptor has"
611 " FD " << descriptor->data[0] << " (expect >= 0)";
612 return 0;
613 }
614
615 sp<::android::MemoryHeapBase> pool = new ::android::MemoryHeapBase(
616 descriptor->data[0], bufferSize*bufferCount, 0, 0);
617 mParent->mMemoryPool.emplace(pool->getHeapID(), pool);
618
619 return pool->getHeapID();
620 }
621
unregisterMemory(uint32_t memId)622 Return<void> CameraHidlTest::Camera1DeviceCb::unregisterMemory(uint32_t memId) {
623 if (mParent->mMemoryPool.count(memId) == 0) {
624 ALOGE("%s: memory pool ID %d not found", __FUNCTION__, memId);
625 ADD_FAILURE();
626 return Void();
627 }
628
629 mParent->mMemoryPool.erase(memId);
630 return Void();
631 }
632
dataCallback(DataCallbackMsg msgType __unused,uint32_t data __unused,uint32_t bufferIndex __unused,const CameraFrameMetadata & metadata __unused)633 Return<void> CameraHidlTest::Camera1DeviceCb::dataCallback(
634 DataCallbackMsg msgType __unused, uint32_t data __unused,
635 uint32_t bufferIndex __unused,
636 const CameraFrameMetadata& metadata __unused) {
637 std::unique_lock<std::mutex> l(mParent->mLock);
638 mParent->mDataMessageTypeReceived = msgType;
639 mParent->mResultCondition.notify_one();
640
641 return Void();
642 }
643
dataCallbackTimestamp(DataCallbackMsg msgType,uint32_t data,uint32_t bufferIndex,int64_t timestamp __unused)644 Return<void> CameraHidlTest::Camera1DeviceCb::dataCallbackTimestamp(
645 DataCallbackMsg msgType, uint32_t data,
646 uint32_t bufferIndex, int64_t timestamp __unused) {
647 std::unique_lock<std::mutex> l(mParent->mLock);
648 mParent->mDataMessageTypeReceived = msgType;
649 mParent->mVideoBufferIndex = bufferIndex;
650 if (mParent->mMemoryPool.count(data) == 0) {
651 ADD_FAILURE() << "memory pool ID " << data << "not found";
652 }
653 mParent->mVideoData = data;
654 mParent->mResultCondition.notify_one();
655
656 return Void();
657 }
658
handleCallbackTimestamp(DataCallbackMsg msgType,const hidl_handle & frameData,uint32_t data __unused,uint32_t bufferIndex,int64_t timestamp __unused)659 Return<void> CameraHidlTest::Camera1DeviceCb::handleCallbackTimestamp(
660 DataCallbackMsg msgType, const hidl_handle& frameData,
661 uint32_t data __unused, uint32_t bufferIndex,
662 int64_t timestamp __unused) {
663 std::unique_lock<std::mutex> l(mParent->mLock);
664 mParent->mDataMessageTypeReceived = msgType;
665 mParent->mVideoBufferIndex = bufferIndex;
666 if (mParent->mMemoryPool.count(data) == 0) {
667 ADD_FAILURE() << "memory pool ID " << data << " not found";
668 }
669 mParent->mVideoData = data;
670 mParent->mVideoNativeHandle = frameData;
671 mParent->mResultCondition.notify_one();
672
673 return Void();
674 }
675
handleCallbackTimestampBatch(DataCallbackMsg msgType,const hidl_vec<HandleTimestampMessage> & batch)676 Return<void> CameraHidlTest::Camera1DeviceCb::handleCallbackTimestampBatch(
677 DataCallbackMsg msgType,
678 const hidl_vec<HandleTimestampMessage>& batch) {
679 std::unique_lock<std::mutex> l(mParent->mLock);
680 for (auto& msg : batch) {
681 mParent->mDataMessageTypeReceived = msgType;
682 mParent->mVideoBufferIndex = msg.bufferIndex;
683 if (mParent->mMemoryPool.count(msg.data) == 0) {
684 ADD_FAILURE() << "memory pool ID " << msg.data << " not found";
685 }
686 mParent->mVideoData = msg.data;
687 mParent->mVideoNativeHandle = msg.frameData;
688 mParent->mResultCondition.notify_one();
689 }
690 return Void();
691 }
692
processCaptureResult(const hidl_vec<CaptureResult> & results)693 Return<void> CameraHidlTest::DeviceCb::processCaptureResult(
694 const hidl_vec<CaptureResult>& results) {
695 if (nullptr == mParent) {
696 return Void();
697 }
698
699 std::unique_lock<std::mutex> l(mParent->mLock);
700 const CaptureResult& result = results[0];
701
702 if(mParent->mResultFrameNumber != result.frameNumber) {
703 ALOGE("%s: Unexpected frame number! Expected: %u received: %u",
704 __func__, mParent->mResultFrameNumber, result.frameNumber);
705 ADD_FAILURE();
706 }
707
708 size_t resultLength = result.outputBuffers.size();
709 for (size_t i = 0; i < resultLength; i++) {
710 mParent->mResultBuffers.push_back(result.outputBuffers[i]);
711 }
712
713 // TODO(epeev): Handle partial results in case client supports them and
714 // verify the result against request settings.
715
716 l.unlock();
717 mParent->mResultCondition.notify_one();
718
719 return Void();
720 }
721
notify(const hidl_vec<NotifyMsg> & messages)722 Return<void> CameraHidlTest::DeviceCb::notify(
723 const hidl_vec<NotifyMsg>& messages) {
724 const NotifyMsg& message = messages[0];
725
726 if (MsgType::ERROR == message.type) {
727 {
728 std::lock_guard<std::mutex> l(mParent->mLock);
729 mParent->mErrors.push_back(message.msg.error);
730 }
731
732 if ((ErrorCode::ERROR_REQUEST == message.msg.error.errorCode)
733 || (ErrorCode::ERROR_BUFFER == message.msg.error.errorCode)) {
734 mParent->mResultCondition.notify_one();
735 }
736 }
737
738 return Void();
739 }
740
getCameraDeviceNames()741 hidl_vec<hidl_string> CameraHidlTest::getCameraDeviceNames() {
742 CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
743 hidl_vec<hidl_string> cameraDeviceNames;
744 Return<void> ret;
745 ret = env->mProvider->getCameraIdList(
746 [&](auto status, const auto& idList) {
747 ALOGI("getCameraIdList returns status:%d", (int)status);
748 for (size_t i = 0; i < idList.size(); i++) {
749 ALOGI("Camera Id[%zu] is %s", i, idList[i].c_str());
750 }
751 ASSERT_EQ(Status::OK, status);
752 cameraDeviceNames = idList;
753 });
754 if (!ret.isOk()) {
755 ADD_FAILURE();
756 }
757 return cameraDeviceNames;
758 }
759
760 // Test if ICameraProvider::isTorchModeSupported returns Status::OK
TEST_F(CameraHidlTest,isTorchModeSupported)761 TEST_F(CameraHidlTest, isTorchModeSupported) {
762 Return<void> ret;
763 ret = CameraHidlEnvironment::Instance()->mProvider->isSetTorchModeSupported(
764 [&](auto status, bool support) {
765 ALOGI("isSetTorchModeSupported returns status:%d supported:%d",
766 (int)status, support);
767 ASSERT_EQ(Status::OK, status);
768 });
769 ASSERT_TRUE(ret.isOk());
770 }
771
772 // TODO: consider removing this test if getCameraDeviceNames() has the same coverage
TEST_F(CameraHidlTest,getCameraIdList)773 TEST_F(CameraHidlTest, getCameraIdList) {
774 Return<void> ret;
775 ret = CameraHidlEnvironment::Instance()->mProvider->getCameraIdList(
776 [&](auto status, const auto& idList) {
777 ALOGI("getCameraIdList returns status:%d", (int)status);
778 for (size_t i = 0; i < idList.size(); i++) {
779 ALOGI("Camera Id[%zu] is %s", i, idList[i].c_str());
780 }
781 ASSERT_EQ(Status::OK, status);
782 // This is true for internal camera provider.
783 // Not necessary hold for external cameras providers
784 ASSERT_GT(idList.size(), 0u);
785 });
786 ASSERT_TRUE(ret.isOk());
787 }
788
789 // Test if ICameraProvider::getVendorTags returns Status::OK
TEST_F(CameraHidlTest,getVendorTags)790 TEST_F(CameraHidlTest, getVendorTags) {
791 Return<void> ret;
792 ret = CameraHidlEnvironment::Instance()->mProvider->getVendorTags(
793 [&](auto status, const auto& vendorTagSecs) {
794 ALOGI("getVendorTags returns status:%d numSections %zu",
795 (int)status, vendorTagSecs.size());
796 for (size_t i = 0; i < vendorTagSecs.size(); i++) {
797 ALOGI("Vendor tag section %zu name %s",
798 i, vendorTagSecs[i].sectionName.c_str());
799 for (size_t j = 0; j < vendorTagSecs[i].tags.size(); j++) {
800 const auto& tag = vendorTagSecs[i].tags[j];
801 ALOGI("Vendor tag id %u name %s type %d",
802 tag.tagId,
803 tag.tagName.c_str(),
804 (int) tag.tagType);
805 }
806 }
807 ASSERT_EQ(Status::OK, status);
808 });
809 ASSERT_TRUE(ret.isOk());
810 }
811
812 // Test if ICameraProvider::setCallback returns Status::OK
TEST_F(CameraHidlTest,setCallback)813 TEST_F(CameraHidlTest, setCallback) {
814 CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
815 struct ProviderCb : public ICameraProviderCallback {
816 virtual Return<void> cameraDeviceStatusChange(
817 const hidl_string& cameraDeviceName,
818 CameraDeviceStatus newStatus) override {
819 ALOGI("camera device status callback name %s, status %d",
820 cameraDeviceName.c_str(), (int) newStatus);
821 return Void();
822 }
823
824 virtual Return<void> torchModeStatusChange(
825 const hidl_string& cameraDeviceName,
826 TorchModeStatus newStatus) override {
827 ALOGI("Torch mode status callback name %s, status %d",
828 cameraDeviceName.c_str(), (int) newStatus);
829 return Void();
830 }
831 };
832 sp<ProviderCb> cb = new ProviderCb;
833 auto status = env->mProvider->setCallback(cb);
834 ASSERT_TRUE(status.isOk());
835 ASSERT_EQ(Status::OK, status);
836 }
837
838 // Test if ICameraProvider::getCameraDeviceInterface returns Status::OK and non-null device
TEST_F(CameraHidlTest,getCameraDeviceInterface)839 TEST_F(CameraHidlTest, getCameraDeviceInterface) {
840 CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
841 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
842
843 for (const auto& name : cameraDeviceNames) {
844 if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
845 Return<void> ret;
846 ret = env->mProvider->getCameraDeviceInterface_V3_x(
847 name,
848 [&](auto status, const auto& device3_2) {
849 ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
850 ASSERT_EQ(Status::OK, status);
851 ASSERT_NE(device3_2, nullptr);
852 });
853 ASSERT_TRUE(ret.isOk());
854 } else if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
855 Return<void> ret;
856 ret = env->mProvider->getCameraDeviceInterface_V1_x(
857 name,
858 [&](auto status, const auto& device1) {
859 ALOGI("getCameraDeviceInterface_V1_x returns status:%d", (int)status);
860 ASSERT_EQ(Status::OK, status);
861 ASSERT_NE(device1, nullptr);
862 });
863 ASSERT_TRUE(ret.isOk());
864 }
865 }
866 }
867
868 // Verify that the device resource cost can be retrieved and the values are
869 // sane.
TEST_F(CameraHidlTest,getResourceCost)870 TEST_F(CameraHidlTest, getResourceCost) {
871 CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
872 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
873
874 for (const auto& name : cameraDeviceNames) {
875 if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
876 ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_2;
877 ALOGI("getResourceCost: Testing camera device %s", name.c_str());
878 Return<void> ret;
879 ret = env->mProvider->getCameraDeviceInterface_V3_x(
880 name,
881 [&](auto status, const auto& device) {
882 ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
883 ASSERT_EQ(Status::OK, status);
884 ASSERT_NE(device, nullptr);
885 device3_2 = device;
886 });
887 ASSERT_TRUE(ret.isOk());
888
889 ret = device3_2->getResourceCost(
890 [&](auto status, const auto& resourceCost) {
891 ALOGI("getResourceCost returns status:%d", (int)status);
892 ASSERT_EQ(Status::OK, status);
893 ALOGI(" Resource cost is %d", resourceCost.resourceCost);
894 ASSERT_LE(resourceCost.resourceCost, 100u);
895 for (const auto& name : resourceCost.conflictingDevices) {
896 ALOGI(" Conflicting device: %s", name.c_str());
897 }
898 });
899 ASSERT_TRUE(ret.isOk());
900 } else {
901 ::android::sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
902 ALOGI("getResourceCost: Testing camera device %s", name.c_str());
903 Return<void> ret;
904 ret = env->mProvider->getCameraDeviceInterface_V1_x(
905 name,
906 [&](auto status, const auto& device) {
907 ALOGI("getCameraDeviceInterface_V1_x returns status:%d", (int)status);
908 ASSERT_EQ(Status::OK, status);
909 ASSERT_NE(device, nullptr);
910 device1 = device;
911 });
912 ASSERT_TRUE(ret.isOk());
913
914 ret = device1->getResourceCost(
915 [&](auto status, const auto& resourceCost) {
916 ALOGI("getResourceCost returns status:%d", (int)status);
917 ASSERT_EQ(Status::OK, status);
918 ALOGI(" Resource cost is %d", resourceCost.resourceCost);
919 ASSERT_LE(resourceCost.resourceCost, 100u);
920 for (const auto& name : resourceCost.conflictingDevices) {
921 ALOGI(" Conflicting device: %s", name.c_str());
922 }
923 });
924 ASSERT_TRUE(ret.isOk());
925 }
926 }
927 }
928
929 // Verify that the static camera info can be retrieved
930 // successfully.
TEST_F(CameraHidlTest,getCameraInfo)931 TEST_F(CameraHidlTest, getCameraInfo) {
932 CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
933 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
934
935 for (const auto& name : cameraDeviceNames) {
936 if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
937 ::android::sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
938 ALOGI("getCameraCharacteristics: Testing camera device %s", name.c_str());
939 Return<void> ret;
940 ret = env->mProvider->getCameraDeviceInterface_V1_x(
941 name,
942 [&](auto status, const auto& device) {
943 ALOGI("getCameraDeviceInterface_V1_x returns status:%d", (int)status);
944 ASSERT_EQ(Status::OK, status);
945 ASSERT_NE(device, nullptr);
946 device1 = device;
947 });
948 ASSERT_TRUE(ret.isOk());
949
950 ret = device1->getCameraInfo(
951 [&](auto status, const auto& info) {
952 ALOGI("getCameraInfo returns status:%d", (int)status);
953 ASSERT_EQ(Status::OK, status);
954 switch(info.orientation) {
955 case 0:
956 case 90:
957 case 180:
958 case 270:
959 //Expected cases
960 ALOGI("camera orientation: %d", info.orientation);
961 break;
962 default:
963 FAIL() << "Unexpected camera orientation:" << info.orientation;
964 }
965 switch(info.facing) {
966 case CameraFacing::BACK:
967 case CameraFacing::FRONT:
968 case CameraFacing::EXTERNAL:
969 //Expected cases
970 ALOGI("camera facing: %d", info.facing);
971 break;
972 default:
973 FAIL() << "Unexpected camera facing:" << static_cast<uint32_t> (info.facing);
974 }
975 });
976 ASSERT_TRUE(ret.isOk());
977 }
978 }
979 }
980
981 // Check whether preview window can be configured
TEST_F(CameraHidlTest,setPreviewWindow)982 TEST_F(CameraHidlTest, setPreviewWindow) {
983 CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
984 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
985
986 for (const auto& name : cameraDeviceNames) {
987 if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
988 sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
989 openCameraDevice(name, env, &device1 /*out*/);
990 ASSERT_NE(nullptr, device1.get());
991 sp<BufferItemConsumer> bufferItemConsumer;
992 sp<BufferItemHander> bufferHandler;
993 setupPreviewWindow(device1,
994 &bufferItemConsumer /*out*/, &bufferHandler /*out*/);
995
996 Return<void> ret;
997 ret = device1->close();
998 ASSERT_TRUE(ret.isOk());
999 }
1000 }
1001 }
1002
1003 // Verify that setting preview window fails in case device is not open
TEST_F(CameraHidlTest,setPreviewWindowInvalid)1004 TEST_F(CameraHidlTest, setPreviewWindowInvalid) {
1005 CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
1006 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
1007
1008 for (const auto& name : cameraDeviceNames) {
1009 if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
1010 ::android::sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
1011 ALOGI("getCameraCharacteristics: Testing camera device %s", name.c_str());
1012 Return<void> ret;
1013 ret = env->mProvider->getCameraDeviceInterface_V1_x(
1014 name,
1015 [&](auto status, const auto& device) {
1016 ALOGI("getCameraDeviceInterface_V1_x returns status:%d", (int)status);
1017 ASSERT_EQ(Status::OK, status);
1018 ASSERT_NE(device, nullptr);
1019 device1 = device;
1020 });
1021 ASSERT_TRUE(ret.isOk());
1022
1023 Return<Status> returnStatus = device1->setPreviewWindow(nullptr);
1024 ASSERT_TRUE(returnStatus.isOk());
1025 ASSERT_EQ(Status::OPERATION_NOT_SUPPORTED, returnStatus);
1026 }
1027 }
1028 }
1029
1030 // Start and stop preview checking whether it gets enabled in between.
TEST_F(CameraHidlTest,startStopPreview)1031 TEST_F(CameraHidlTest, startStopPreview) {
1032 CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
1033 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
1034
1035 for (const auto& name : cameraDeviceNames) {
1036 if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
1037 sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
1038 openCameraDevice(name, env, &device1 /*out*/);
1039 ASSERT_NE(nullptr, device1.get());
1040 sp<BufferItemConsumer> bufferItemConsumer;
1041 sp<BufferItemHander> bufferHandler;
1042 setupPreviewWindow(device1,
1043 &bufferItemConsumer /*out*/, &bufferHandler /*out*/);
1044
1045 startPreview(device1);
1046
1047 Return<bool> returnBoolStatus = device1->previewEnabled();
1048 ASSERT_TRUE(returnBoolStatus.isOk());
1049 ASSERT_TRUE(returnBoolStatus);
1050
1051 stopPreviewAndClose(device1);
1052 }
1053 }
1054 }
1055
1056 // Start preview without active preview window. Preview should start as soon
1057 // as a valid active window gets configured.
TEST_F(CameraHidlTest,startStopPreviewDelayed)1058 TEST_F(CameraHidlTest, startStopPreviewDelayed) {
1059 CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
1060 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
1061
1062 for (const auto& name : cameraDeviceNames) {
1063 if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
1064 sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
1065 openCameraDevice(name, env, &device1 /*out*/);
1066 ASSERT_NE(nullptr, device1.get());
1067
1068 Return<Status> returnStatus = device1->setPreviewWindow(nullptr);
1069 ASSERT_TRUE(returnStatus.isOk());
1070 ASSERT_EQ(Status::OK, returnStatus);
1071
1072 startPreview(device1);
1073
1074 sp<BufferItemConsumer> bufferItemConsumer;
1075 sp<BufferItemHander> bufferHandler;
1076 setupPreviewWindow(device1, &bufferItemConsumer /*out*/,
1077 &bufferHandler /*out*/);
1078
1079 //Preview should get enabled now
1080 Return<bool> returnBoolStatus = device1->previewEnabled();
1081 ASSERT_TRUE(returnBoolStatus.isOk());
1082 ASSERT_TRUE(returnBoolStatus);
1083
1084 stopPreviewAndClose(device1);
1085 }
1086 }
1087 }
1088
1089 // Verify that image capture behaves as expected along with preview callbacks.
TEST_F(CameraHidlTest,takePicture)1090 TEST_F(CameraHidlTest, takePicture) {
1091 CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
1092 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
1093
1094 for (const auto& name : cameraDeviceNames) {
1095 if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
1096 sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
1097 openCameraDevice(name, env, &device1 /*out*/);
1098 ASSERT_NE(nullptr, device1.get());
1099 sp<BufferItemConsumer> bufferItemConsumer;
1100 sp<BufferItemHander> bufferHandler;
1101 setupPreviewWindow(device1, &bufferItemConsumer /*out*/,
1102 &bufferHandler /*out*/);
1103
1104 {
1105 std::unique_lock<std::mutex> l(mLock);
1106 mDataMessageTypeReceived = DataCallbackMsg::RAW_IMAGE_NOTIFY;
1107 }
1108
1109 enableMsgType((unsigned int)DataCallbackMsg::PREVIEW_FRAME, device1);
1110 startPreview(device1);
1111
1112 {
1113 std::unique_lock<std::mutex> l(mLock);
1114 waitForFrameLocked(DataCallbackMsg::PREVIEW_FRAME, l);
1115 }
1116
1117 disableMsgType((unsigned int)DataCallbackMsg::PREVIEW_FRAME,
1118 device1);
1119 enableMsgType((unsigned int)DataCallbackMsg::COMPRESSED_IMAGE,
1120 device1);
1121
1122 {
1123 std::unique_lock<std::mutex> l(mLock);
1124 mDataMessageTypeReceived = DataCallbackMsg::RAW_IMAGE_NOTIFY;
1125 }
1126
1127 Return<Status> returnStatus = device1->takePicture();
1128 ASSERT_TRUE(returnStatus.isOk());
1129 ASSERT_EQ(Status::OK, returnStatus);
1130
1131 {
1132 std::unique_lock<std::mutex> l(mLock);
1133 waitForFrameLocked(DataCallbackMsg::COMPRESSED_IMAGE, l);
1134 }
1135
1136 disableMsgType((unsigned int)DataCallbackMsg::COMPRESSED_IMAGE,
1137 device1);
1138 stopPreviewAndClose(device1);
1139 }
1140 }
1141 }
1142
1143 // Image capture should fail in case preview didn't get enabled first.
TEST_F(CameraHidlTest,takePictureFail)1144 TEST_F(CameraHidlTest, takePictureFail) {
1145 CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
1146 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
1147
1148 for (const auto& name : cameraDeviceNames) {
1149 if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
1150 sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
1151 openCameraDevice(name, env, &device1 /*out*/);
1152 ASSERT_NE(nullptr, device1.get());
1153
1154 Return<Status> returnStatus = device1->takePicture();
1155 ASSERT_TRUE(returnStatus.isOk());
1156 ASSERT_NE(Status::OK, returnStatus);
1157
1158 Return<void> ret = device1->close();
1159 ASSERT_TRUE(ret.isOk());
1160 }
1161 }
1162 }
1163
1164 // Verify that image capture can be cancelled.
TEST_F(CameraHidlTest,cancelPicture)1165 TEST_F(CameraHidlTest, cancelPicture) {
1166 CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
1167 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
1168
1169 for (const auto& name : cameraDeviceNames) {
1170 if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
1171 sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
1172 openCameraDevice(name, env, &device1 /*out*/);
1173 ASSERT_NE(nullptr, device1.get());
1174 sp<BufferItemConsumer> bufferItemConsumer;
1175 sp<BufferItemHander> bufferHandler;
1176 setupPreviewWindow(device1, &bufferItemConsumer /*out*/,
1177 &bufferHandler /*out*/);
1178 startPreview(device1);
1179
1180 Return<Status> returnStatus = device1->takePicture();
1181 ASSERT_TRUE(returnStatus.isOk());
1182 ASSERT_EQ(Status::OK, returnStatus);
1183
1184 returnStatus = device1->cancelPicture();
1185 ASSERT_TRUE(returnStatus.isOk());
1186 ASSERT_EQ(Status::OK, returnStatus);
1187
1188 stopPreviewAndClose(device1);
1189 }
1190 }
1191 }
1192
1193 // Image capture cancel should fail when image capture is not running.
TEST_F(CameraHidlTest,cancelPictureFail)1194 TEST_F(CameraHidlTest, cancelPictureFail) {
1195 CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
1196 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
1197
1198 for (const auto& name : cameraDeviceNames) {
1199 if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
1200 sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
1201 openCameraDevice(name, env, &device1 /*out*/);
1202 ASSERT_NE(nullptr, device1.get());
1203 sp<BufferItemConsumer> bufferItemConsumer;
1204 sp<BufferItemHander> bufferHandler;
1205 setupPreviewWindow(device1, &bufferItemConsumer /*out*/,
1206 &bufferHandler /*out*/);
1207 startPreview(device1);
1208
1209 Return<Status> returnStatus = device1->cancelPicture();
1210 ASSERT_TRUE(returnStatus.isOk());
1211 ASSERT_NE(Status::OK, returnStatus);
1212
1213 stopPreviewAndClose(device1);
1214 }
1215 }
1216 }
1217
1218 // Test basic video recording.
TEST_F(CameraHidlTest,startStopRecording)1219 TEST_F(CameraHidlTest, startStopRecording) {
1220 CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
1221 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
1222
1223 for (const auto& name : cameraDeviceNames) {
1224 if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
1225 sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
1226 openCameraDevice(name, env, &device1 /*out*/);
1227 ASSERT_NE(nullptr, device1.get());
1228 sp<BufferItemConsumer> bufferItemConsumer;
1229 sp<BufferItemHander> bufferHandler;
1230 setupPreviewWindow(device1, &bufferItemConsumer /*out*/,
1231 &bufferHandler /*out*/);
1232
1233 {
1234 std::unique_lock<std::mutex> l(mLock);
1235 mDataMessageTypeReceived = DataCallbackMsg::RAW_IMAGE_NOTIFY;
1236 }
1237
1238 enableMsgType((unsigned int)DataCallbackMsg::PREVIEW_FRAME, device1);
1239 startPreview(device1);
1240
1241 {
1242 std::unique_lock<std::mutex> l(mLock);
1243 waitForFrameLocked(DataCallbackMsg::PREVIEW_FRAME, l);
1244 mDataMessageTypeReceived = DataCallbackMsg::RAW_IMAGE_NOTIFY;
1245 mVideoBufferIndex = UINT32_MAX;
1246 }
1247
1248 disableMsgType((unsigned int)DataCallbackMsg::PREVIEW_FRAME, device1);
1249
1250 bool videoMetaEnabled = false;
1251 Return<Status> returnStatus = device1->storeMetaDataInBuffers(true);
1252 ASSERT_TRUE(returnStatus.isOk());
1253 // It is allowed for devices to not support this feature
1254 ASSERT_TRUE((Status::OK == returnStatus) ||
1255 (Status::OPERATION_NOT_SUPPORTED == returnStatus));
1256 if (Status::OK == returnStatus) {
1257 videoMetaEnabled = true;
1258 }
1259
1260 enableMsgType((unsigned int)DataCallbackMsg::VIDEO_FRAME, device1);
1261 Return<bool> returnBoolStatus = device1->recordingEnabled();
1262 ASSERT_TRUE(returnBoolStatus.isOk());
1263 ASSERT_FALSE(returnBoolStatus);
1264
1265 returnStatus = device1->startRecording();
1266 ASSERT_TRUE(returnStatus.isOk());
1267 ASSERT_EQ(Status::OK, returnStatus);
1268
1269 {
1270 std::unique_lock<std::mutex> l(mLock);
1271 waitForFrameLocked(DataCallbackMsg::VIDEO_FRAME, l);
1272 ASSERT_NE(UINT32_MAX, mVideoBufferIndex);
1273 disableMsgType((unsigned int)DataCallbackMsg::VIDEO_FRAME,
1274 device1);
1275 }
1276
1277 returnBoolStatus = device1->recordingEnabled();
1278 ASSERT_TRUE(returnBoolStatus.isOk());
1279 ASSERT_TRUE(returnBoolStatus);
1280
1281 Return<void> ret;
1282 if (videoMetaEnabled) {
1283 ret = device1->releaseRecordingFrameHandle(mVideoData,
1284 mVideoBufferIndex, mVideoNativeHandle);
1285 ASSERT_TRUE(ret.isOk());
1286 } else {
1287 ret = device1->releaseRecordingFrame(mVideoData, mVideoBufferIndex);
1288 ASSERT_TRUE(ret.isOk());
1289 }
1290
1291 ret = device1->stopRecording();
1292 ASSERT_TRUE(ret.isOk());
1293
1294 stopPreviewAndClose(device1);
1295 }
1296 }
1297 }
1298
1299 // It shouldn't be possible to start recording without enabling preview first.
TEST_F(CameraHidlTest,startRecordingFail)1300 TEST_F(CameraHidlTest, startRecordingFail) {
1301 CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
1302 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
1303
1304 for (const auto& name : cameraDeviceNames) {
1305 if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
1306 sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
1307 openCameraDevice(name, env, &device1 /*out*/);
1308 ASSERT_NE(nullptr, device1.get());
1309
1310 Return<bool> returnBoolStatus = device1->recordingEnabled();
1311 ASSERT_TRUE(returnBoolStatus.isOk());
1312 ASSERT_FALSE(returnBoolStatus);
1313
1314 Return<Status> returnStatus = device1->startRecording();
1315 ASSERT_TRUE(returnStatus.isOk());
1316 ASSERT_NE(Status::OK, returnStatus);
1317
1318 Return<void> ret = device1->close();
1319 ASSERT_TRUE(ret.isOk());
1320 }
1321 }
1322 }
1323
1324 // Check autofocus support if available.
TEST_F(CameraHidlTest,autoFocus)1325 TEST_F(CameraHidlTest, autoFocus) {
1326 CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
1327 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
1328 std::vector<const char *> focusModes = {CameraParameters::FOCUS_MODE_AUTO,
1329 CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE,
1330 CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO};
1331
1332 for (const auto& name : cameraDeviceNames) {
1333 if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
1334 sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
1335 openCameraDevice(name, env, &device1 /*out*/);
1336 ASSERT_NE(nullptr, device1.get());
1337
1338 ::android::CameraParameters cameraParams;
1339 getParameters(device1, &cameraParams /*out*/);
1340
1341 if (Status::OK != isAutoFocusModeAvailable(cameraParams,
1342 CameraParameters::FOCUS_MODE_AUTO)) {
1343 Return<void> ret = device1->close();
1344 ASSERT_TRUE(ret.isOk());
1345 continue;
1346 }
1347
1348 sp<BufferItemConsumer> bufferItemConsumer;
1349 sp<BufferItemHander> bufferHandler;
1350 setupPreviewWindow(device1, &bufferItemConsumer /*out*/,
1351 &bufferHandler /*out*/);
1352 startPreview(device1);
1353 enableMsgType((unsigned int)NotifyCallbackMsg::FOCUS, device1);
1354
1355 for (auto &iter : focusModes) {
1356 if (Status::OK != isAutoFocusModeAvailable(cameraParams,
1357 iter)) {
1358 continue;
1359 }
1360
1361 cameraParams.set(CameraParameters::KEY_FOCUS_MODE, iter);
1362 setParameters(device1, cameraParams);
1363 {
1364 std::unique_lock<std::mutex> l(mLock);
1365 mNotifyMessage = NotifyCallbackMsg::ERROR;
1366 }
1367
1368 Return<Status> returnStatus = device1->autoFocus();
1369 ASSERT_TRUE(returnStatus.isOk());
1370 ASSERT_EQ(Status::OK, returnStatus);
1371
1372 {
1373 std::unique_lock<std::mutex> l(mLock);
1374 while (NotifyCallbackMsg::FOCUS != mNotifyMessage) {
1375 auto timeout = std::chrono::system_clock::now() +
1376 std::chrono::seconds(kAutoFocusTimeoutSec);
1377 ASSERT_NE(std::cv_status::timeout,
1378 mResultCondition.wait_until(l, timeout));
1379 }
1380 }
1381 }
1382
1383 disableMsgType((unsigned int)NotifyCallbackMsg::FOCUS, device1);
1384 stopPreviewAndClose(device1);
1385 }
1386 }
1387 }
1388
1389 // In case autofocus is supported verify that it can be cancelled.
TEST_F(CameraHidlTest,cancelAutoFocus)1390 TEST_F(CameraHidlTest, cancelAutoFocus) {
1391 CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
1392 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
1393
1394 for (const auto& name : cameraDeviceNames) {
1395 if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
1396 sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
1397 openCameraDevice(name, env, &device1 /*out*/);
1398 ASSERT_NE(nullptr, device1.get());
1399
1400 ::android::CameraParameters cameraParams;
1401 getParameters(device1, &cameraParams /*out*/);
1402
1403 if (Status::OK != isAutoFocusModeAvailable(cameraParams,
1404 CameraParameters::FOCUS_MODE_AUTO)) {
1405 Return<void> ret = device1->close();
1406 ASSERT_TRUE(ret.isOk());
1407 continue;
1408 }
1409
1410 // It should be fine to call before preview starts.
1411 ASSERT_EQ(Status::OK, device1->cancelAutoFocus());
1412
1413 sp<BufferItemConsumer> bufferItemConsumer;
1414 sp<BufferItemHander> bufferHandler;
1415 setupPreviewWindow(device1, &bufferItemConsumer /*out*/,
1416 &bufferHandler /*out*/);
1417 startPreview(device1);
1418
1419 // It should be fine to call after preview starts too.
1420 Return<Status> returnStatus = device1->cancelAutoFocus();
1421 ASSERT_TRUE(returnStatus.isOk());
1422 ASSERT_EQ(Status::OK, returnStatus);
1423
1424 returnStatus = device1->autoFocus();
1425 ASSERT_TRUE(returnStatus.isOk());
1426 ASSERT_EQ(Status::OK, returnStatus);
1427
1428 returnStatus = device1->cancelAutoFocus();
1429 ASSERT_TRUE(returnStatus.isOk());
1430 ASSERT_EQ(Status::OK, returnStatus);
1431
1432 stopPreviewAndClose(device1);
1433 }
1434 }
1435 }
1436
1437 // Check whether face detection is available and try to enable&disable.
TEST_F(CameraHidlTest,sendCommandFaceDetection)1438 TEST_F(CameraHidlTest, sendCommandFaceDetection) {
1439 CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
1440 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
1441
1442 for (const auto& name : cameraDeviceNames) {
1443 if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
1444 sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
1445 openCameraDevice(name, env, &device1 /*out*/);
1446 ASSERT_NE(nullptr, device1.get());
1447
1448 ::android::CameraParameters cameraParams;
1449 getParameters(device1, &cameraParams /*out*/);
1450
1451 int32_t hwFaces = cameraParams.getInt(
1452 CameraParameters::KEY_MAX_NUM_DETECTED_FACES_HW);
1453 int32_t swFaces = cameraParams.getInt(
1454 CameraParameters::KEY_MAX_NUM_DETECTED_FACES_SW);
1455 if ((0 >= hwFaces) && (0 >= swFaces)) {
1456 Return<void> ret = device1->close();
1457 ASSERT_TRUE(ret.isOk());
1458 continue;
1459 }
1460
1461 sp<BufferItemConsumer> bufferItemConsumer;
1462 sp<BufferItemHander> bufferHandler;
1463 setupPreviewWindow(device1, &bufferItemConsumer /*out*/,
1464 &bufferHandler /*out*/);
1465 startPreview(device1);
1466
1467 if (0 < hwFaces) {
1468 Return<Status> returnStatus = device1->sendCommand(
1469 CommandType::START_FACE_DETECTION,
1470 CAMERA_FACE_DETECTION_HW, 0);
1471 ASSERT_TRUE(returnStatus.isOk());
1472 ASSERT_EQ(Status::OK, returnStatus);
1473 // TODO(epeev) : Enable and check for face notifications
1474 returnStatus = device1->sendCommand(
1475 CommandType::STOP_FACE_DETECTION,
1476 CAMERA_FACE_DETECTION_HW, 0);
1477 ASSERT_TRUE(returnStatus.isOk());
1478 ASSERT_EQ(Status::OK, returnStatus);
1479 }
1480
1481 if (0 < swFaces) {
1482 Return<Status> returnStatus = device1->sendCommand(
1483 CommandType::START_FACE_DETECTION,
1484 CAMERA_FACE_DETECTION_SW, 0);
1485 ASSERT_TRUE(returnStatus.isOk());
1486 ASSERT_EQ(Status::OK, returnStatus);
1487 // TODO(epeev) : Enable and check for face notifications
1488 returnStatus = device1->sendCommand(
1489 CommandType::STOP_FACE_DETECTION,
1490 CAMERA_FACE_DETECTION_SW, 0);
1491 ASSERT_TRUE(returnStatus.isOk());
1492 ASSERT_EQ(Status::OK, returnStatus);
1493 }
1494
1495 stopPreviewAndClose(device1);
1496 }
1497 }
1498 }
1499
1500 // Check whether smooth zoom is available and try to enable&disable.
TEST_F(CameraHidlTest,sendCommandSmoothZoom)1501 TEST_F(CameraHidlTest, sendCommandSmoothZoom) {
1502 CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
1503 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
1504
1505 for (const auto& name : cameraDeviceNames) {
1506 if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
1507 sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
1508 openCameraDevice(name, env, &device1 /*out*/);
1509 ASSERT_NE(nullptr, device1.get());
1510
1511 ::android::CameraParameters cameraParams;
1512 getParameters(device1, &cameraParams /*out*/);
1513
1514 const char *smoothZoomStr = cameraParams.get(
1515 CameraParameters::KEY_SMOOTH_ZOOM_SUPPORTED);
1516 bool smoothZoomSupported = ((nullptr != smoothZoomStr) &&
1517 (strcmp(smoothZoomStr, CameraParameters::TRUE) == 0)) ?
1518 true : false;
1519 if (!smoothZoomSupported) {
1520 Return<void> ret = device1->close();
1521 ASSERT_TRUE(ret.isOk());
1522 continue;
1523 }
1524
1525 int32_t maxZoom = cameraParams.getInt(
1526 CameraParameters::KEY_MAX_ZOOM);
1527 ASSERT_TRUE(0 < maxZoom);
1528
1529 sp<BufferItemConsumer> bufferItemConsumer;
1530 sp<BufferItemHander> bufferHandler;
1531 setupPreviewWindow(device1, &bufferItemConsumer /*out*/,
1532 &bufferHandler /*out*/);
1533 startPreview(device1);
1534 setParameters(device1, cameraParams);
1535
1536 Return<Status> returnStatus = device1->sendCommand(
1537 CommandType::START_SMOOTH_ZOOM, maxZoom, 0);
1538 ASSERT_TRUE(returnStatus.isOk());
1539 ASSERT_EQ(Status::OK, returnStatus);
1540 // TODO(epeev) : Enable and check for face notifications
1541 returnStatus = device1->sendCommand(CommandType::STOP_SMOOTH_ZOOM,
1542 0, 0);
1543 ASSERT_TRUE(returnStatus.isOk());
1544 ASSERT_EQ(Status::OK, returnStatus);
1545
1546 stopPreviewAndClose(device1);
1547 }
1548 }
1549 }
1550
1551 // Basic sanity tests related to camera parameters.
TEST_F(CameraHidlTest,getSetParameters)1552 TEST_F(CameraHidlTest, getSetParameters) {
1553 CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
1554 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
1555
1556 for (const auto& name : cameraDeviceNames) {
1557 if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
1558 sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
1559 openCameraDevice(name, env, &device1 /*out*/);
1560 ASSERT_NE(nullptr, device1.get());
1561
1562 ::android::CameraParameters cameraParams;
1563 getParameters(device1, &cameraParams /*out*/);
1564
1565 int32_t width, height;
1566 cameraParams.getPictureSize(&width, &height);
1567 ASSERT_TRUE((0 < width) && (0 < height));
1568 cameraParams.getPreviewSize(&width, &height);
1569 ASSERT_TRUE((0 < width) && (0 < height));
1570 int32_t minFps, maxFps;
1571 cameraParams.getPreviewFpsRange(&minFps, &maxFps);
1572 ASSERT_TRUE((0 < minFps) && (0 < maxFps));
1573 ASSERT_NE(nullptr, cameraParams.getPreviewFormat());
1574 ASSERT_NE(nullptr, cameraParams.getPictureFormat());
1575 ASSERT_TRUE(strcmp(CameraParameters::PIXEL_FORMAT_JPEG,
1576 cameraParams.getPictureFormat()) == 0);
1577
1578 const char *flashMode = cameraParams.get(
1579 CameraParameters::KEY_FLASH_MODE);
1580 ASSERT_TRUE((nullptr == flashMode) || (strcmp(
1581 CameraParameters::FLASH_MODE_OFF, flashMode) == 0));
1582
1583 const char *wbMode = cameraParams.get(
1584 CameraParameters::KEY_WHITE_BALANCE);
1585 ASSERT_TRUE((nullptr == wbMode) || (strcmp(
1586 CameraParameters::WHITE_BALANCE_AUTO, wbMode) == 0));
1587
1588 const char *effect = cameraParams.get(CameraParameters::KEY_EFFECT);
1589 ASSERT_TRUE((nullptr == effect) || (strcmp(
1590 CameraParameters::EFFECT_NONE, effect) == 0));
1591
1592 ::android::Vector<::android::Size> previewSizes;
1593 cameraParams.getSupportedPreviewSizes(previewSizes);
1594 ASSERT_FALSE(previewSizes.empty());
1595 ::android::Vector<::android::Size> pictureSizes;
1596 cameraParams.getSupportedPictureSizes(pictureSizes);
1597 ASSERT_FALSE(pictureSizes.empty());
1598 const char *previewFormats = cameraParams.get(
1599 CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS);
1600 ASSERT_NE(nullptr, previewFormats);
1601 ::android::String8 previewFormatsString(previewFormats);
1602 ASSERT_TRUE(previewFormatsString.contains(
1603 CameraParameters::PIXEL_FORMAT_YUV420SP));
1604 ASSERT_NE(nullptr, cameraParams.get(
1605 CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS));
1606 ASSERT_NE(nullptr, cameraParams.get(
1607 CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES));
1608 const char *focusModes = cameraParams.get(
1609 CameraParameters::KEY_SUPPORTED_FOCUS_MODES);
1610 ASSERT_NE(nullptr, focusModes);
1611 ::android::String8 focusModesString(focusModes);
1612 const char *focusMode = cameraParams.get(
1613 CameraParameters::KEY_FOCUS_MODE);
1614 ASSERT_NE(nullptr, focusMode);
1615 // Auto focus mode should be default
1616 if (focusModesString.contains(CameraParameters::FOCUS_MODE_AUTO)) {
1617 ASSERT_TRUE(strcmp(
1618 CameraParameters::FOCUS_MODE_AUTO, focusMode) == 0);
1619 }
1620 ASSERT_TRUE(0 < cameraParams.getInt(
1621 CameraParameters::KEY_FOCAL_LENGTH));
1622 int32_t horizontalViewAngle = cameraParams.getInt(
1623 CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE);
1624 ASSERT_TRUE((0 < horizontalViewAngle) && (360 >= horizontalViewAngle));
1625 int32_t verticalViewAngle = cameraParams.getInt(
1626 CameraParameters::KEY_VERTICAL_VIEW_ANGLE);
1627 ASSERT_TRUE((0 < verticalViewAngle) && (360 >= verticalViewAngle));
1628 int32_t jpegQuality = cameraParams.getInt(
1629 CameraParameters::KEY_JPEG_QUALITY);
1630 ASSERT_TRUE((1 <= jpegQuality) && (100 >= jpegQuality));
1631 int32_t jpegThumbQuality = cameraParams.getInt(
1632 CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY);
1633 ASSERT_TRUE((1 <= jpegThumbQuality) && (100 >= jpegThumbQuality));
1634
1635 cameraParams.setPictureSize(pictureSizes[0].width,
1636 pictureSizes[0].height);
1637 cameraParams.setPreviewSize(previewSizes[0].width,
1638 previewSizes[0].height);
1639
1640 setParameters(device1, cameraParams);
1641 getParameters(device1, &cameraParams /*out*/);
1642
1643 cameraParams.getPictureSize(&width, &height);
1644 ASSERT_TRUE((pictureSizes[0].width == width) &&
1645 (pictureSizes[0].height == height));
1646 cameraParams.getPreviewSize(&width, &height);
1647 ASSERT_TRUE((previewSizes[0].width == width) &&
1648 (previewSizes[0].height == height));
1649
1650 Return<void> ret = device1->close();
1651 ASSERT_TRUE(ret.isOk());
1652 }
1653 }
1654 }
1655
1656 // Verify that the static camera characteristics can be retrieved
1657 // successfully.
TEST_F(CameraHidlTest,getCameraCharacteristics)1658 TEST_F(CameraHidlTest, getCameraCharacteristics) {
1659 CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
1660 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
1661
1662 for (const auto& name : cameraDeviceNames) {
1663 if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
1664 ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_2;
1665 ALOGI("getCameraCharacteristics: Testing camera device %s", name.c_str());
1666 Return<void> ret;
1667 ret = env->mProvider->getCameraDeviceInterface_V3_x(
1668 name,
1669 [&](auto status, const auto& device) {
1670 ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
1671 ASSERT_EQ(Status::OK, status);
1672 ASSERT_NE(device, nullptr);
1673 device3_2 = device;
1674 });
1675 ASSERT_TRUE(ret.isOk());
1676
1677 ret = device3_2->getCameraCharacteristics(
1678 [&](auto status, const auto& chars) {
1679 ALOGI("getCameraCharacteristics returns status:%d", (int)status);
1680 ASSERT_EQ(Status::OK, status);
1681 const camera_metadata_t* metadata = (camera_metadata_t*) chars.data();
1682 size_t expectedSize = chars.size();
1683 int result = validate_camera_metadata_structure(metadata, &expectedSize);
1684 ASSERT_TRUE(result == 0 || result == CAMERA_METADATA_VALIDATION_SHIFTED);
1685 size_t entryCount = get_camera_metadata_entry_count(metadata);
1686 // TODO: we can do better than 0 here. Need to check how many required
1687 // characteristics keys we've defined.
1688 ASSERT_GT(entryCount, 0u);
1689 ALOGI("getCameraCharacteristics metadata entry count is %zu", entryCount);
1690 });
1691 ASSERT_TRUE(ret.isOk());
1692 }
1693 }
1694 }
1695
1696 //In case it is supported verify that torch can be enabled.
1697 //Check for corresponding toch callbacks as well.
TEST_F(CameraHidlTest,setTorchMode)1698 TEST_F(CameraHidlTest, setTorchMode) {
1699 CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
1700 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
1701 bool torchControlSupported = false;
1702 Return<void> ret;
1703
1704 ret = CameraHidlEnvironment::Instance()->mProvider->isSetTorchModeSupported(
1705 [&](auto status, bool support) {
1706 ALOGI("isSetTorchModeSupported returns status:%d supported:%d",
1707 (int)status, support);
1708 ASSERT_EQ(Status::OK, status);
1709 torchControlSupported = support;
1710 });
1711
1712
1713 sp<TorchProviderCb> cb = new TorchProviderCb(this);
1714 Return<Status> returnStatus = env->mProvider->setCallback(cb);
1715 ASSERT_TRUE(returnStatus.isOk());
1716 ASSERT_EQ(Status::OK, returnStatus);
1717
1718 for (const auto& name : cameraDeviceNames) {
1719 if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
1720 ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_2;
1721 ALOGI("setTorchMode: Testing camera device %s", name.c_str());
1722 ret = env->mProvider->getCameraDeviceInterface_V3_x(
1723 name,
1724 [&](auto status, const auto& device) {
1725 ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
1726 ASSERT_EQ(Status::OK, status);
1727 ASSERT_NE(device, nullptr);
1728 device3_2 = device;
1729 });
1730 ASSERT_TRUE(ret.isOk());
1731
1732 mTorchStatus = TorchModeStatus::NOT_AVAILABLE;
1733 returnStatus = device3_2->setTorchMode(TorchMode::ON);
1734 ASSERT_TRUE(returnStatus.isOk());
1735 if (!torchControlSupported) {
1736 ASSERT_EQ(Status::METHOD_NOT_SUPPORTED, returnStatus);
1737 } else {
1738 ASSERT_TRUE(returnStatus == Status::OK ||
1739 returnStatus == Status::OPERATION_NOT_SUPPORTED);
1740 if (returnStatus == Status::OK) {
1741 {
1742 std::unique_lock<std::mutex> l(mTorchLock);
1743 while (TorchModeStatus::NOT_AVAILABLE == mTorchStatus) {
1744 auto timeout = std::chrono::system_clock::now() +
1745 std::chrono::seconds(kTorchTimeoutSec);
1746 ASSERT_NE(std::cv_status::timeout,
1747 mTorchCond.wait_until(l, timeout));
1748 }
1749 ASSERT_EQ(TorchModeStatus::AVAILABLE_ON, mTorchStatus);
1750 mTorchStatus = TorchModeStatus::NOT_AVAILABLE;
1751 }
1752
1753 returnStatus = device3_2->setTorchMode(TorchMode::OFF);
1754 ASSERT_TRUE(returnStatus.isOk());
1755 ASSERT_EQ(Status::OK, returnStatus);
1756
1757 {
1758 std::unique_lock<std::mutex> l(mTorchLock);
1759 while (TorchModeStatus::NOT_AVAILABLE == mTorchStatus) {
1760 auto timeout = std::chrono::system_clock::now() +
1761 std::chrono::seconds(kTorchTimeoutSec);
1762 ASSERT_NE(std::cv_status::timeout,
1763 mTorchCond.wait_until(l, timeout));
1764 }
1765 ASSERT_EQ(TorchModeStatus::AVAILABLE_OFF, mTorchStatus);
1766 }
1767 }
1768 }
1769 } else if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
1770 ::android::sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
1771 ALOGI("dumpState: Testing camera device %s", name.c_str());
1772 ret = env->mProvider->getCameraDeviceInterface_V1_x(
1773 name,
1774 [&](auto status, const auto& device) {
1775 ALOGI("getCameraDeviceInterface_V1_x returns status:%d", (int)status);
1776 ASSERT_EQ(Status::OK, status);
1777 ASSERT_NE(device, nullptr);
1778 device1 = device;
1779 });
1780 ASSERT_TRUE(ret.isOk());
1781
1782 mTorchStatus = TorchModeStatus::NOT_AVAILABLE;
1783 returnStatus = device1->setTorchMode(TorchMode::ON);
1784 ASSERT_TRUE(returnStatus.isOk());
1785 if (!torchControlSupported) {
1786 ASSERT_EQ(Status::METHOD_NOT_SUPPORTED, returnStatus);
1787 } else {
1788 ASSERT_TRUE(returnStatus == Status::OK ||
1789 returnStatus == Status::OPERATION_NOT_SUPPORTED);
1790 if (returnStatus == Status::OK) {
1791 {
1792 std::unique_lock<std::mutex> l(mTorchLock);
1793 while (TorchModeStatus::NOT_AVAILABLE == mTorchStatus) {
1794 auto timeout = std::chrono::system_clock::now() +
1795 std::chrono::seconds(kTorchTimeoutSec);
1796 ASSERT_NE(std::cv_status::timeout,
1797 mTorchCond.wait_until(l, timeout));
1798 }
1799 ASSERT_EQ(TorchModeStatus::AVAILABLE_ON, mTorchStatus);
1800 mTorchStatus = TorchModeStatus::NOT_AVAILABLE;
1801 }
1802
1803 returnStatus = device1->setTorchMode(TorchMode::OFF);
1804 ASSERT_TRUE(returnStatus.isOk());
1805 ASSERT_EQ(Status::OK, returnStatus);
1806
1807 {
1808 std::unique_lock<std::mutex> l(mTorchLock);
1809 while (TorchModeStatus::NOT_AVAILABLE == mTorchStatus) {
1810 auto timeout = std::chrono::system_clock::now() +
1811 std::chrono::seconds(kTorchTimeoutSec);
1812 ASSERT_NE(std::cv_status::timeout,
1813 mTorchCond.wait_until(l, timeout));
1814 }
1815 ASSERT_EQ(TorchModeStatus::AVAILABLE_OFF, mTorchStatus);
1816 }
1817 }
1818 }
1819 ret = device1->close();
1820 ASSERT_TRUE(ret.isOk());
1821 }
1822 }
1823
1824 returnStatus = env->mProvider->setCallback(nullptr);
1825 ASSERT_TRUE(returnStatus.isOk());
1826 ASSERT_EQ(Status::OK, returnStatus);
1827 }
1828
1829 // Check dump functionality.
TEST_F(CameraHidlTest,dumpState)1830 TEST_F(CameraHidlTest, dumpState) {
1831 CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
1832 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
1833 Return<void> ret;
1834
1835 for (const auto& name : cameraDeviceNames) {
1836 if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
1837 ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_2;
1838 ALOGI("dumpState: Testing camera device %s", name.c_str());
1839 ret = env->mProvider->getCameraDeviceInterface_V3_x(
1840 name,
1841 [&](auto status, const auto& device) {
1842 ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
1843 ASSERT_EQ(Status::OK, status);
1844 ASSERT_NE(device, nullptr);
1845 device3_2 = device;
1846 });
1847 ASSERT_TRUE(ret.isOk());
1848
1849 native_handle_t* raw_handle = native_handle_create(1, 0);
1850 raw_handle->data[0] = open(kDumpOutput, O_RDWR);
1851 ASSERT_GE(raw_handle->data[0], 0);
1852 hidl_handle handle = raw_handle;
1853 ret= device3_2->dumpState(handle);
1854 ASSERT_TRUE(ret.isOk());
1855 close(raw_handle->data[0]);
1856 native_handle_delete(raw_handle);
1857 } else if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
1858 ::android::sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
1859 ALOGI("dumpState: Testing camera device %s", name.c_str());
1860 ret = env->mProvider->getCameraDeviceInterface_V1_x(
1861 name,
1862 [&](auto status, const auto& device) {
1863 ALOGI("getCameraDeviceInterface_V1_x returns status:%d", (int)status);
1864 ASSERT_EQ(Status::OK, status);
1865 ASSERT_NE(device, nullptr);
1866 device1 = device;
1867 });
1868 ASSERT_TRUE(ret.isOk());
1869
1870 native_handle_t* raw_handle = native_handle_create(1, 0);
1871 raw_handle->data[0] = open(kDumpOutput, O_RDWR);
1872 ASSERT_GE(raw_handle->data[0], 0);
1873 hidl_handle handle = raw_handle;
1874 Return<Status> returnStatus = device1->dumpState(handle);
1875 ASSERT_TRUE(returnStatus.isOk());
1876 ASSERT_EQ(Status::OK, returnStatus);
1877 close(raw_handle->data[0]);
1878 native_handle_delete(raw_handle);
1879 }
1880 }
1881 }
1882
1883 // Open, dumpStates, then close
TEST_F(CameraHidlTest,openClose)1884 TEST_F(CameraHidlTest, openClose) {
1885 CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
1886 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
1887 Return<void> ret;
1888
1889 for (const auto& name : cameraDeviceNames) {
1890 if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
1891 ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_2;
1892 ALOGI("openClose: Testing camera device %s", name.c_str());
1893 ret = env->mProvider->getCameraDeviceInterface_V3_x(
1894 name,
1895 [&](auto status, const auto& device) {
1896 ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
1897 ASSERT_EQ(Status::OK, status);
1898 ASSERT_NE(device, nullptr);
1899 device3_2 = device;
1900 });
1901 ASSERT_TRUE(ret.isOk());
1902
1903 sp<EmptyDeviceCb> cb = new EmptyDeviceCb;
1904 sp<ICameraDeviceSession> session;
1905 ret = device3_2->open(
1906 cb,
1907 [&](auto status, const auto& newSession) {
1908 ALOGI("device::open returns status:%d", (int)status);
1909 ASSERT_EQ(Status::OK, status);
1910 ASSERT_NE(newSession, nullptr);
1911 session = newSession;
1912 });
1913 ASSERT_TRUE(ret.isOk());
1914
1915 native_handle_t* raw_handle = native_handle_create(1, 0);
1916 raw_handle->data[0] = open(kDumpOutput, O_RDWR);
1917 ASSERT_GE(raw_handle->data[0], 0);
1918 hidl_handle handle = raw_handle;
1919 ret = device3_2->dumpState(handle);
1920 ASSERT_TRUE(ret.isOk());
1921 close(raw_handle->data[0]);
1922 native_handle_delete(raw_handle);
1923
1924 ret = session->close();
1925 ASSERT_TRUE(ret.isOk());
1926 // TODO: test all session API calls return INTERNAL_ERROR after close
1927 // TODO: keep a wp copy here and verify session cannot be promoted out of this scope
1928 } else if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
1929 sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
1930 openCameraDevice(name, env, &device1 /*out*/);
1931 ASSERT_NE(nullptr, device1.get());
1932
1933 native_handle_t* raw_handle = native_handle_create(1, 0);
1934 raw_handle->data[0] = open(kDumpOutput, O_RDWR);
1935 ASSERT_GE(raw_handle->data[0], 0);
1936 hidl_handle handle = raw_handle;
1937 Return<Status> returnStatus = device1->dumpState(handle);
1938 ASSERT_TRUE(returnStatus.isOk());
1939 ASSERT_EQ(Status::OK, returnStatus);
1940 close(raw_handle->data[0]);
1941 native_handle_delete(raw_handle);
1942
1943 ret = device1->close();
1944 ASSERT_TRUE(ret.isOk());
1945 }
1946 }
1947 }
1948
1949 // Check whether all common default request settings can be sucessfully
1950 // constructed.
TEST_F(CameraHidlTest,constructDefaultRequestSettings)1951 TEST_F(CameraHidlTest, constructDefaultRequestSettings) {
1952 CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
1953 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
1954
1955 for (const auto& name : cameraDeviceNames) {
1956 if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
1957 ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_2;
1958 Return<void> ret;
1959 ALOGI("constructDefaultRequestSettings: Testing camera device %s", name.c_str());
1960 ret = env->mProvider->getCameraDeviceInterface_V3_x(
1961 name,
1962 [&](auto status, const auto& device) {
1963 ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
1964 ASSERT_EQ(Status::OK, status);
1965 ASSERT_NE(device, nullptr);
1966 device3_2 = device;
1967 });
1968 ASSERT_TRUE(ret.isOk());
1969
1970 sp<EmptyDeviceCb> cb = new EmptyDeviceCb;
1971 sp<ICameraDeviceSession> session;
1972 ret = device3_2->open(
1973 cb,
1974 [&](auto status, const auto& newSession) {
1975 ALOGI("device::open returns status:%d", (int)status);
1976 ASSERT_EQ(Status::OK, status);
1977 ASSERT_NE(newSession, nullptr);
1978 session = newSession;
1979 });
1980 ASSERT_TRUE(ret.isOk());
1981
1982 for (uint32_t t = (uint32_t) RequestTemplate::PREVIEW;
1983 t <= (uint32_t) RequestTemplate::MANUAL; t++) {
1984 RequestTemplate reqTemplate = (RequestTemplate) t;
1985 ret = session->constructDefaultRequestSettings(
1986 reqTemplate,
1987 [&](auto status, const auto& req) {
1988 ALOGI("constructDefaultRequestSettings returns status:%d", (int)status);
1989 if (reqTemplate == RequestTemplate::ZERO_SHUTTER_LAG ||
1990 reqTemplate == RequestTemplate::MANUAL) {
1991 // optional templates
1992 ASSERT_TRUE(status == Status::OK || status == Status::ILLEGAL_ARGUMENT);
1993 } else {
1994 ASSERT_EQ(Status::OK, status);
1995 }
1996
1997 if (status == Status::OK) {
1998 const camera_metadata_t* metadata =
1999 (camera_metadata_t*) req.data();
2000 size_t expectedSize = req.size();
2001 int result = validate_camera_metadata_structure(
2002 metadata, &expectedSize);
2003 ASSERT_TRUE(result == 0 || result == CAMERA_METADATA_VALIDATION_SHIFTED);
2004 size_t entryCount = get_camera_metadata_entry_count(metadata);
2005 // TODO: we can do better than 0 here. Need to check how many required
2006 // request keys we've defined for each template
2007 ASSERT_GT(entryCount, 0u);
2008 ALOGI("template %u metadata entry count is %zu", t, entryCount);
2009 } else {
2010 ASSERT_EQ(0u, req.size());
2011 }
2012 });
2013 ASSERT_TRUE(ret.isOk());
2014 }
2015 ret = session->close();
2016 ASSERT_TRUE(ret.isOk());
2017 }
2018 }
2019 }
2020
2021 // Verify that all supported stream formats and sizes can be configured
2022 // successfully.
TEST_F(CameraHidlTest,configureStreamsAvailableOutputs)2023 TEST_F(CameraHidlTest, configureStreamsAvailableOutputs) {
2024 CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
2025 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
2026 std::vector<AvailableStream> outputStreams;
2027
2028 for (const auto& name : cameraDeviceNames) {
2029 if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
2030 camera_metadata_t *staticMeta;
2031 Return<void> ret;
2032 sp<ICameraDeviceSession> session;
2033 openEmptyDeviceSession(name, env, &session /*out*/,
2034 &staticMeta /*out*/);
2035
2036 outputStreams.clear();
2037 ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta,
2038 outputStreams));
2039 ASSERT_NE(0u, outputStreams.size());
2040
2041 int32_t streamId = 0;
2042 for (auto &it : outputStreams) {
2043 Stream stream = {streamId, StreamType::OUTPUT,
2044 static_cast<uint32_t> (it.width),
2045 static_cast<uint32_t> (it.height),
2046 static_cast<PixelFormat> (it.format), 0, 0,
2047 StreamRotation::ROTATION_0};
2048 ::android::hardware::hidl_vec<Stream> streams = {stream};
2049 StreamConfiguration config = {streams,
2050 StreamConfigurationMode::NORMAL_MODE};
2051 ret = session->configureStreams(config, [streamId] (Status s,
2052 HalStreamConfiguration halConfig) {
2053 ASSERT_EQ(Status::OK, s);
2054 ASSERT_EQ(1u, halConfig.streams.size());
2055 ASSERT_EQ(halConfig.streams[0].id, streamId);
2056 });
2057 ASSERT_TRUE(ret.isOk());
2058 streamId++;
2059 }
2060
2061 free_camera_metadata(staticMeta);
2062 ret = session->close();
2063 ASSERT_TRUE(ret.isOk());
2064 }
2065 }
2066 }
2067
2068 // Check for correct handling of invalid/incorrect configuration parameters.
TEST_F(CameraHidlTest,configureStreamsInvalidOutputs)2069 TEST_F(CameraHidlTest, configureStreamsInvalidOutputs) {
2070 CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
2071 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
2072 std::vector<AvailableStream> outputStreams;
2073
2074 for (const auto& name : cameraDeviceNames) {
2075 if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
2076 camera_metadata_t *staticMeta;
2077 Return<void> ret;
2078 sp<ICameraDeviceSession> session;
2079 openEmptyDeviceSession(name, env, &session /*out*/,
2080 &staticMeta /*out*/);
2081
2082 outputStreams.clear();
2083 ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta,
2084 outputStreams));
2085 ASSERT_NE(0u, outputStreams.size());
2086
2087 int32_t streamId = 0;
2088 Stream stream = {streamId++, StreamType::OUTPUT,
2089 static_cast<uint32_t> (0),
2090 static_cast<uint32_t> (0),
2091 static_cast<PixelFormat> (outputStreams[0].format),
2092 0, 0, StreamRotation::ROTATION_0};
2093 ::android::hardware::hidl_vec<Stream> streams = {stream};
2094 StreamConfiguration config = {streams,
2095 StreamConfigurationMode::NORMAL_MODE};
2096 ret = session->configureStreams(config, [] (Status s,
2097 HalStreamConfiguration) {
2098 ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) ||
2099 (Status::INTERNAL_ERROR == s));
2100 });
2101 ASSERT_TRUE(ret.isOk());
2102
2103 stream = {streamId++, StreamType::OUTPUT,
2104 static_cast<uint32_t> (UINT32_MAX),
2105 static_cast<uint32_t> (UINT32_MAX),
2106 static_cast<PixelFormat> (outputStreams[0].format),
2107 0, 0, StreamRotation::ROTATION_0};
2108 streams[0] = stream;
2109 config = {streams,
2110 StreamConfigurationMode::NORMAL_MODE};
2111 ret = session->configureStreams(config, [] (Status s,
2112 HalStreamConfiguration) {
2113 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
2114 });
2115 ASSERT_TRUE(ret.isOk());
2116
2117 for (auto &it : outputStreams) {
2118 stream = {streamId++, StreamType::OUTPUT,
2119 static_cast<uint32_t> (it.width),
2120 static_cast<uint32_t> (it.height),
2121 static_cast<PixelFormat> (UINT32_MAX),
2122 0, 0, StreamRotation::ROTATION_0};
2123 streams[0] = stream;
2124 config = {streams,
2125 StreamConfigurationMode::NORMAL_MODE};
2126 ret = session->configureStreams(config, [] (Status s,
2127 HalStreamConfiguration) {
2128 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
2129 });
2130 ASSERT_TRUE(ret.isOk());
2131
2132 stream = {streamId++, StreamType::OUTPUT,
2133 static_cast<uint32_t> (it.width),
2134 static_cast<uint32_t> (it.height),
2135 static_cast<PixelFormat> (it.format),
2136 0, 0, static_cast<StreamRotation> (UINT32_MAX)};
2137 streams[0] = stream;
2138 config = {streams,
2139 StreamConfigurationMode::NORMAL_MODE};
2140 ret = session->configureStreams(config, [] (Status s,
2141 HalStreamConfiguration) {
2142 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
2143 });
2144 ASSERT_TRUE(ret.isOk());
2145 }
2146
2147 free_camera_metadata(staticMeta);
2148 ret = session->close();
2149 ASSERT_TRUE(ret.isOk());
2150 }
2151 }
2152 }
2153
2154 // Check whether all supported ZSL output stream combinations can be
2155 // configured successfully.
TEST_F(CameraHidlTest,configureStreamsZSLInputOutputs)2156 TEST_F(CameraHidlTest, configureStreamsZSLInputOutputs) {
2157 CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
2158 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
2159 std::vector<AvailableStream> inputStreams;
2160 std::vector<AvailableZSLInputOutput> inputOutputMap;
2161
2162 for (const auto& name : cameraDeviceNames) {
2163 if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
2164 camera_metadata_t *staticMeta;
2165 Return<void> ret;
2166 sp<ICameraDeviceSession> session;
2167 openEmptyDeviceSession(name, env, &session /*out*/,
2168 &staticMeta /*out*/);
2169
2170 Status rc = isZSLModeAvailable(staticMeta);
2171 if (Status::METHOD_NOT_SUPPORTED == rc) {
2172 ret = session->close();
2173 ASSERT_TRUE(ret.isOk());
2174 continue;
2175 }
2176 ASSERT_EQ(Status::OK, rc);
2177
2178 inputStreams.clear();
2179 ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta,
2180 inputStreams));
2181 ASSERT_NE(0u, inputStreams.size());
2182
2183 inputOutputMap.clear();
2184 ASSERT_EQ(Status::OK, getZSLInputOutputMap(staticMeta,
2185 inputOutputMap));
2186 ASSERT_NE(0u, inputOutputMap.size());
2187
2188 int32_t streamId = 0;
2189 for (auto &inputIter : inputOutputMap) {
2190 AvailableStream input;
2191 ASSERT_EQ(Status::OK,
2192 findLargestSize(inputStreams, inputIter.inputFormat, input));
2193 ASSERT_NE(0u, inputStreams.size());
2194
2195 AvailableStream outputThreshold = {INT32_MAX, INT32_MAX,
2196 inputIter.outputFormat};
2197 std::vector<AvailableStream> outputStreams;
2198 ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta,
2199 outputStreams, &outputThreshold));
2200 for (auto &outputIter : outputStreams) {
2201 Stream zslStream = {streamId++, StreamType::OUTPUT,
2202 static_cast<uint32_t> (input.width),
2203 static_cast<uint32_t> (input.height),
2204 static_cast<PixelFormat> (input.format),
2205 GRALLOC_USAGE_HW_CAMERA_ZSL, 0,
2206 StreamRotation::ROTATION_0};
2207 Stream inputStream = {streamId++, StreamType::INPUT,
2208 static_cast<uint32_t> (input.width),
2209 static_cast<uint32_t> (input.height),
2210 static_cast<PixelFormat> (input.format), 0, 0,
2211 StreamRotation::ROTATION_0};
2212 Stream outputStream = {streamId++, StreamType::OUTPUT,
2213 static_cast<uint32_t> (outputIter.width),
2214 static_cast<uint32_t> (outputIter.height),
2215 static_cast<PixelFormat> (outputIter.format), 0, 0,
2216 StreamRotation::ROTATION_0};
2217
2218 ::android::hardware::hidl_vec<Stream> streams = {
2219 inputStream, zslStream, outputStream};
2220 StreamConfiguration config = {streams,
2221 StreamConfigurationMode::NORMAL_MODE};
2222 ret = session->configureStreams(config, [streamId] (Status s,
2223 HalStreamConfiguration halConfig) {
2224 ASSERT_EQ(Status::OK, s);
2225 ASSERT_EQ(3u, halConfig.streams.size());
2226 });
2227 ASSERT_TRUE(ret.isOk());
2228 }
2229 }
2230
2231 free_camera_metadata(staticMeta);
2232 ret = session->close();
2233 ASSERT_TRUE(ret.isOk());
2234 }
2235 }
2236 }
2237
2238 // Verify that all supported preview + still capture stream combinations
2239 // can be configured successfully.
TEST_F(CameraHidlTest,configureStreamsPreviewStillOutputs)2240 TEST_F(CameraHidlTest, configureStreamsPreviewStillOutputs) {
2241 CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
2242 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
2243 std::vector<AvailableStream> outputBlobStreams;
2244 std::vector<AvailableStream> outputPreviewStreams;
2245 AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
2246 static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
2247 AvailableStream blobThreshold = {INT32_MAX, INT32_MAX,
2248 static_cast<int32_t>(PixelFormat::BLOB)};
2249
2250 for (const auto& name : cameraDeviceNames) {
2251 if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
2252 camera_metadata_t *staticMeta;
2253 Return<void> ret;
2254 sp<ICameraDeviceSession> session;
2255 openEmptyDeviceSession(name, env, &session /*out*/,
2256 &staticMeta /*out*/);
2257
2258 outputBlobStreams.clear();
2259 ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta,
2260 outputBlobStreams, &blobThreshold));
2261 ASSERT_NE(0u, outputBlobStreams.size());
2262
2263 outputPreviewStreams.clear();
2264 ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta,
2265 outputPreviewStreams, &previewThreshold));
2266 ASSERT_NE(0u, outputPreviewStreams.size());
2267
2268 int32_t streamId = 0;
2269 for (auto &blobIter : outputBlobStreams) {
2270 for (auto &previewIter : outputPreviewStreams) {
2271 Stream previewStream = {streamId++, StreamType::OUTPUT,
2272 static_cast<uint32_t> (previewIter.width),
2273 static_cast<uint32_t> (previewIter.height),
2274 static_cast<PixelFormat> (previewIter.format), 0, 0,
2275 StreamRotation::ROTATION_0};
2276 Stream blobStream = {streamId++, StreamType::OUTPUT,
2277 static_cast<uint32_t> (blobIter.width),
2278 static_cast<uint32_t> (blobIter.height),
2279 static_cast<PixelFormat> (blobIter.format), 0, 0,
2280 StreamRotation::ROTATION_0};
2281 ::android::hardware::hidl_vec<Stream> streams = {
2282 previewStream, blobStream};
2283 StreamConfiguration config = {streams,
2284 StreamConfigurationMode::NORMAL_MODE};
2285 ret = session->configureStreams(config, [streamId] (Status s,
2286 HalStreamConfiguration halConfig) {
2287 ASSERT_EQ(Status::OK, s);
2288 ASSERT_EQ(2u, halConfig.streams.size());
2289 });
2290 ASSERT_TRUE(ret.isOk());
2291 }
2292 }
2293
2294 free_camera_metadata(staticMeta);
2295 ret = session->close();
2296 ASSERT_TRUE(ret.isOk());
2297 }
2298 }
2299 }
2300
2301 // In case constrained mode is supported, test whether it can be
2302 // configured. Additionally check for common invalid inputs when
2303 // using this mode.
TEST_F(CameraHidlTest,configureStreamsConstrainedOutputs)2304 TEST_F(CameraHidlTest, configureStreamsConstrainedOutputs) {
2305 CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
2306 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
2307
2308 for (const auto& name : cameraDeviceNames) {
2309 if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
2310 camera_metadata_t *staticMeta;
2311 Return<void> ret;
2312 sp<ICameraDeviceSession> session;
2313 openEmptyDeviceSession(name, env, &session /*out*/,
2314 &staticMeta /*out*/);
2315
2316 Status rc = isConstrainedModeAvailable(staticMeta);
2317 if (Status::METHOD_NOT_SUPPORTED == rc) {
2318 ret = session->close();
2319 ASSERT_TRUE(ret.isOk());
2320 continue;
2321 }
2322 ASSERT_EQ(Status::OK, rc);
2323
2324 AvailableStream hfrStream;
2325 rc = pickConstrainedModeSize(staticMeta, hfrStream);
2326 ASSERT_EQ(Status::OK, rc);
2327
2328 int32_t streamId = 0;
2329 Stream stream = {streamId, StreamType::OUTPUT,
2330 static_cast<uint32_t> (hfrStream.width),
2331 static_cast<uint32_t> (hfrStream.height),
2332 static_cast<PixelFormat> (hfrStream.format), 0, 0,
2333 StreamRotation::ROTATION_0};
2334 ::android::hardware::hidl_vec<Stream> streams = {stream};
2335 StreamConfiguration config = {streams,
2336 StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE};
2337 ret = session->configureStreams(config, [streamId] (Status s,
2338 HalStreamConfiguration halConfig) {
2339 ASSERT_EQ(Status::OK, s);
2340 ASSERT_EQ(1u, halConfig.streams.size());
2341 ASSERT_EQ(halConfig.streams[0].id, streamId);
2342 });
2343 ASSERT_TRUE(ret.isOk());
2344
2345 stream = {streamId++, StreamType::OUTPUT,
2346 static_cast<uint32_t> (0),
2347 static_cast<uint32_t> (0),
2348 static_cast<PixelFormat> (hfrStream.format), 0, 0,
2349 StreamRotation::ROTATION_0};
2350 streams[0] = stream;
2351 config = {streams,
2352 StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE};
2353 ret = session->configureStreams(config, [streamId] (Status s,
2354 HalStreamConfiguration) {
2355 ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) ||
2356 (Status::INTERNAL_ERROR == s));
2357 });
2358 ASSERT_TRUE(ret.isOk());
2359
2360 stream = {streamId++, StreamType::OUTPUT,
2361 static_cast<uint32_t> (UINT32_MAX),
2362 static_cast<uint32_t> (UINT32_MAX),
2363 static_cast<PixelFormat> (hfrStream.format), 0, 0,
2364 StreamRotation::ROTATION_0};
2365 streams[0] = stream;
2366 config = {streams,
2367 StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE};
2368 ret = session->configureStreams(config, [streamId] (Status s,
2369 HalStreamConfiguration) {
2370 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
2371 });
2372 ASSERT_TRUE(ret.isOk());
2373
2374 stream = {streamId++, StreamType::OUTPUT,
2375 static_cast<uint32_t> (hfrStream.width),
2376 static_cast<uint32_t> (hfrStream.height),
2377 static_cast<PixelFormat> (UINT32_MAX), 0, 0,
2378 StreamRotation::ROTATION_0};
2379 streams[0] = stream;
2380 config = {streams,
2381 StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE};
2382 ret = session->configureStreams(config, [streamId] (Status s,
2383 HalStreamConfiguration) {
2384 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
2385 });
2386 ASSERT_TRUE(ret.isOk());
2387
2388 free_camera_metadata(staticMeta);
2389 ret = session->close();
2390 ASSERT_TRUE(ret.isOk());
2391 }
2392 }
2393 }
2394
2395 // Verify that all supported video + snapshot stream combinations can
2396 // be configured successfully.
TEST_F(CameraHidlTest,configureStreamsVideoStillOutputs)2397 TEST_F(CameraHidlTest, configureStreamsVideoStillOutputs) {
2398 CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
2399 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
2400 std::vector<AvailableStream> outputBlobStreams;
2401 std::vector<AvailableStream> outputVideoStreams;
2402 AvailableStream videoThreshold = {kMaxVideoWidth, kMaxVideoHeight,
2403 static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
2404 AvailableStream blobThreshold = {kMaxVideoWidth, kMaxVideoHeight,
2405 static_cast<int32_t>(PixelFormat::BLOB)};
2406
2407 for (const auto& name : cameraDeviceNames) {
2408 if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
2409 camera_metadata_t *staticMeta;
2410 Return<void> ret;
2411 sp<ICameraDeviceSession> session;
2412 openEmptyDeviceSession(name, env, &session /*out*/,
2413 &staticMeta /*out*/);
2414
2415 outputBlobStreams.clear();
2416 ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta,
2417 outputBlobStreams, &blobThreshold));
2418 ASSERT_NE(0u, outputBlobStreams.size());
2419
2420 outputVideoStreams.clear();
2421 ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta,
2422 outputVideoStreams, &videoThreshold));
2423 ASSERT_NE(0u, outputVideoStreams.size());
2424
2425 int32_t streamId = 0;
2426 for (auto &blobIter : outputBlobStreams) {
2427 for (auto &videoIter : outputVideoStreams) {
2428 Stream videoStream = {streamId++, StreamType::OUTPUT,
2429 static_cast<uint32_t> (videoIter.width),
2430 static_cast<uint32_t> (videoIter.height),
2431 static_cast<PixelFormat> (videoIter.format), 0, 0,
2432 StreamRotation::ROTATION_0};
2433 Stream blobStream = {streamId++, StreamType::OUTPUT,
2434 static_cast<uint32_t> (blobIter.width),
2435 static_cast<uint32_t> (blobIter.height),
2436 static_cast<PixelFormat> (blobIter.format),
2437 GRALLOC_USAGE_HW_VIDEO_ENCODER, 0,
2438 StreamRotation::ROTATION_0};
2439 ::android::hardware::hidl_vec<Stream> streams = {
2440 videoStream, blobStream};
2441 StreamConfiguration config = {streams,
2442 StreamConfigurationMode::NORMAL_MODE};
2443 ret = session->configureStreams(config, [streamId] (Status s,
2444 HalStreamConfiguration halConfig) {
2445 ASSERT_EQ(Status::OK, s);
2446 ASSERT_EQ(2u, halConfig.streams.size());
2447 });
2448 ASSERT_TRUE(ret.isOk());
2449 }
2450 }
2451
2452 free_camera_metadata(staticMeta);
2453 ret = session->close();
2454 ASSERT_TRUE(ret.isOk());
2455 }
2456 }
2457 }
2458
2459 // Generate and verify a camera capture request
TEST_F(CameraHidlTest,processCaptureRequestPreview)2460 TEST_F(CameraHidlTest, processCaptureRequestPreview) {
2461 CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
2462 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
2463 AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
2464 static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
2465 uint64_t bufferId = 1;
2466 uint32_t frameNumber = 1;
2467 ::android::hardware::hidl_vec<uint8_t> settings;
2468
2469 for (const auto& name : cameraDeviceNames) {
2470 if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
2471 Stream previewStream;
2472 HalStreamConfiguration halStreamConfig;
2473 sp<ICameraDeviceSession> session;
2474 configurePreviewStream(name, env, &previewThreshold,
2475 &session /*out*/, &previewStream /*out*/,
2476 &halStreamConfig /*out*/);
2477
2478 RequestTemplate reqTemplate = RequestTemplate::PREVIEW;
2479 Return<void> ret;
2480 ret = session->constructDefaultRequestSettings(reqTemplate,
2481 [&](auto status, const auto& req) {
2482 ASSERT_EQ(Status::OK, status);
2483 settings = req; });
2484 ASSERT_TRUE(ret.isOk());
2485
2486 sp<GraphicBuffer> gb = new GraphicBuffer(
2487 previewStream.width, previewStream.height,
2488 static_cast<int32_t>(halStreamConfig.streams[0].overrideFormat),
2489 1, android_convertGralloc1To0Usage(
2490 halStreamConfig.streams[0].producerUsage,
2491 halStreamConfig.streams[0].consumerUsage));
2492 ASSERT_NE(nullptr, gb.get());
2493 StreamBuffer outputBuffer = {halStreamConfig.streams[0].id,
2494 bufferId, hidl_handle(gb->getNativeBuffer()->handle),
2495 BufferStatus::OK, nullptr, nullptr};
2496 ::android::hardware::hidl_vec<StreamBuffer> outputBuffers = {
2497 outputBuffer};
2498 StreamBuffer emptyInputBuffer = {-1, 0, nullptr,
2499 BufferStatus::ERROR, nullptr, nullptr};
2500 CaptureRequest request = {frameNumber, 0 /* fmqSettingsSize */, settings,
2501 emptyInputBuffer, outputBuffers};
2502
2503 {
2504 std::unique_lock<std::mutex> l(mLock);
2505 mResultBuffers.clear();
2506 mResultFrameNumber = frameNumber;
2507 }
2508
2509 Status status = Status::INTERNAL_ERROR;
2510 uint32_t numRequestProcessed = 0;
2511 hidl_vec<BufferCache> cachesToRemove;
2512 Return<void> returnStatus = session->processCaptureRequest(
2513 {request},
2514 cachesToRemove,
2515 [&status, &numRequestProcessed] (auto s, uint32_t n) {
2516 status = s;
2517 numRequestProcessed = n;
2518 });
2519 ASSERT_TRUE(returnStatus.isOk());
2520 ASSERT_EQ(Status::OK, status);
2521 ASSERT_EQ(numRequestProcessed, 1u);
2522
2523 {
2524 std::unique_lock<std::mutex> l(mLock);
2525 while (0 == mResultBuffers.size()) {
2526 auto timeout = std::chrono::system_clock::now() +
2527 std::chrono::seconds(kStreamBufferTimeoutSec);
2528 ASSERT_NE(std::cv_status::timeout,
2529 mResultCondition.wait_until(l, timeout));
2530 }
2531
2532 ASSERT_EQ(BufferStatus::OK, mResultBuffers[0].status);
2533 ASSERT_EQ(previewStream.id, mResultBuffers[0].streamId);
2534
2535 request.frameNumber++;
2536 //Empty settings should be supported after the first call
2537 //for repeating requests.
2538 request.settings.setToExternal(nullptr, 0, true);
2539 mResultBuffers.clear();
2540 mResultFrameNumber++;
2541 }
2542
2543 returnStatus = session->processCaptureRequest(
2544 {request},
2545 cachesToRemove,
2546 [&status, &numRequestProcessed] (auto s, uint32_t n) {
2547 status = s;
2548 numRequestProcessed = n;
2549 });
2550 ASSERT_TRUE(returnStatus.isOk());
2551 ASSERT_EQ(Status::OK, status);
2552 ASSERT_EQ(numRequestProcessed, 1u);
2553
2554 {
2555 std::unique_lock<std::mutex> l(mLock);
2556 while (0 == mResultBuffers.size()) {
2557 auto timeout = std::chrono::system_clock::now() +
2558 std::chrono::seconds(kStreamBufferTimeoutSec);
2559 ASSERT_NE(std::cv_status::timeout,
2560 mResultCondition.wait_until(l, timeout));
2561 }
2562 ASSERT_EQ(BufferStatus::OK, mResultBuffers[0].status);
2563 ASSERT_EQ(previewStream.id, mResultBuffers[0].streamId);
2564 }
2565
2566 ret = session->close();
2567 ASSERT_TRUE(ret.isOk());
2568 }
2569 }
2570 }
2571
2572 // Test whether an incorrect capture request with missing settings will
2573 // be reported correctly.
TEST_F(CameraHidlTest,processCaptureRequestInvalidSinglePreview)2574 TEST_F(CameraHidlTest, processCaptureRequestInvalidSinglePreview) {
2575 CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
2576 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
2577 std::vector<AvailableStream> outputPreviewStreams;
2578 AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
2579 static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
2580 uint64_t bufferId = 1;
2581 uint32_t frameNumber = 1;
2582 ::android::hardware::hidl_vec<uint8_t> settings;
2583
2584 for (const auto& name : cameraDeviceNames) {
2585 if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
2586 Stream previewStream;
2587 HalStreamConfiguration halStreamConfig;
2588 sp<ICameraDeviceSession> session;
2589 configurePreviewStream(name, env, &previewThreshold,
2590 &session /*out*/, &previewStream /*out*/,
2591 &halStreamConfig /*out*/);
2592
2593 sp<GraphicBuffer> gb = new GraphicBuffer(
2594 previewStream.width, previewStream.height,
2595 static_cast<int32_t>(halStreamConfig.streams[0].overrideFormat),
2596 1, android_convertGralloc1To0Usage(
2597 halStreamConfig.streams[0].producerUsage,
2598 halStreamConfig.streams[0].consumerUsage));
2599
2600 StreamBuffer outputBuffer = {halStreamConfig.streams[0].id,
2601 bufferId, hidl_handle(gb->getNativeBuffer()->handle),
2602 BufferStatus::OK, nullptr, nullptr};
2603 ::android::hardware::hidl_vec<StreamBuffer> outputBuffers = {
2604 outputBuffer};
2605 StreamBuffer emptyInputBuffer = {-1, 0, nullptr,
2606 BufferStatus::ERROR, nullptr, nullptr};
2607 CaptureRequest request = {frameNumber, 0 /* fmqSettingsSize */, settings,
2608 emptyInputBuffer, outputBuffers};
2609
2610 //Settings were not correctly initialized, we should fail here
2611 Status status = Status::OK;
2612 uint32_t numRequestProcessed = 0;
2613 hidl_vec<BufferCache> cachesToRemove;
2614 Return<void> ret = session->processCaptureRequest(
2615 {request},
2616 cachesToRemove,
2617 [&status, &numRequestProcessed] (auto s, uint32_t n) {
2618 status = s;
2619 numRequestProcessed = n;
2620 });
2621 ASSERT_TRUE(ret.isOk());
2622 ASSERT_EQ(Status::INTERNAL_ERROR, status);
2623 ASSERT_EQ(numRequestProcessed, 0u);
2624
2625 ret = session->close();
2626 ASSERT_TRUE(ret.isOk());
2627 }
2628 }
2629 }
2630
2631 // Check whether an invalid capture request with missing output buffers
2632 // will be reported correctly.
TEST_F(CameraHidlTest,processCaptureRequestInvalidBuffer)2633 TEST_F(CameraHidlTest, processCaptureRequestInvalidBuffer) {
2634 CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
2635 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
2636 std::vector<AvailableStream> outputBlobStreams;
2637 AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
2638 static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
2639 uint32_t frameNumber = 1;
2640 ::android::hardware::hidl_vec<uint8_t> settings;
2641
2642 for (const auto& name : cameraDeviceNames) {
2643 if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
2644 Stream previewStream;
2645 HalStreamConfiguration halStreamConfig;
2646 sp<ICameraDeviceSession> session;
2647 configurePreviewStream(name, env, &previewThreshold,
2648 &session /*out*/, &previewStream /*out*/,
2649 &halStreamConfig /*out*/);
2650
2651 RequestTemplate reqTemplate = RequestTemplate::PREVIEW;
2652 Return<void> ret;
2653 ret = session->constructDefaultRequestSettings(reqTemplate,
2654 [&](auto status, const auto& req) {
2655 ASSERT_EQ(Status::OK, status);
2656 settings = req; });
2657 ASSERT_TRUE(ret.isOk());
2658
2659 ::android::hardware::hidl_vec<StreamBuffer> emptyOutputBuffers;
2660 StreamBuffer emptyInputBuffer = {-1, 0, nullptr,
2661 BufferStatus::ERROR, nullptr, nullptr};
2662 CaptureRequest request = {frameNumber, 0/* fmqSettingsSize */, settings,
2663 emptyInputBuffer, emptyOutputBuffers};
2664
2665 //Output buffers are missing, we should fail here
2666 Status status = Status::OK;
2667 uint32_t numRequestProcessed = 0;
2668 hidl_vec<BufferCache> cachesToRemove;
2669 ret = session->processCaptureRequest(
2670 {request},
2671 cachesToRemove,
2672 [&status, &numRequestProcessed] (auto s, uint32_t n) {
2673 status = s;
2674 numRequestProcessed = n;
2675 });
2676 ASSERT_TRUE(ret.isOk());
2677 ASSERT_EQ(Status::INTERNAL_ERROR, status);
2678 ASSERT_EQ(numRequestProcessed, 0u);
2679
2680 ret = session->close();
2681 ASSERT_TRUE(ret.isOk());
2682 }
2683 }
2684 }
2685
2686 // Generate, trigger and flush a preview request
TEST_F(CameraHidlTest,flushPreviewRequest)2687 TEST_F(CameraHidlTest, flushPreviewRequest) {
2688 CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
2689 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
2690 std::vector<AvailableStream> outputPreviewStreams;
2691 AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
2692 static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
2693 uint64_t bufferId = 1;
2694 uint32_t frameNumber = 1;
2695 ::android::hardware::hidl_vec<uint8_t> settings;
2696
2697 for (const auto& name : cameraDeviceNames) {
2698 if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
2699 Stream previewStream;
2700 HalStreamConfiguration halStreamConfig;
2701 sp<ICameraDeviceSession> session;
2702 configurePreviewStream(name, env, &previewThreshold,
2703 &session /*out*/, &previewStream /*out*/,
2704 &halStreamConfig /*out*/);
2705
2706 RequestTemplate reqTemplate = RequestTemplate::PREVIEW;
2707 Return<void> ret;
2708 ret = session->constructDefaultRequestSettings(reqTemplate,
2709 [&](auto status, const auto& req) {
2710 ASSERT_EQ(Status::OK, status);
2711 settings = req; });
2712 ASSERT_TRUE(ret.isOk());
2713
2714 sp<GraphicBuffer> gb = new GraphicBuffer(
2715 previewStream.width, previewStream.height,
2716 static_cast<int32_t>(halStreamConfig.streams[0].overrideFormat),
2717 1, android_convertGralloc1To0Usage(
2718 halStreamConfig.streams[0].producerUsage,
2719 halStreamConfig.streams[0].consumerUsage));
2720 ASSERT_NE(nullptr, gb.get());
2721 StreamBuffer outputBuffer = {halStreamConfig.streams[0].id,
2722 bufferId, hidl_handle(gb->getNativeBuffer()->handle),
2723 BufferStatus::OK, nullptr, nullptr};
2724 ::android::hardware::hidl_vec<StreamBuffer> outputBuffers = {
2725 outputBuffer};
2726 const StreamBuffer emptyInputBuffer = {-1, 0, nullptr,
2727 BufferStatus::ERROR, nullptr, nullptr};
2728 CaptureRequest request = {frameNumber, 0 /* fmqSettingsSize */, settings,
2729 emptyInputBuffer, outputBuffers};
2730
2731 {
2732 std::unique_lock<std::mutex> l(mLock);
2733 mResultBuffers.clear();
2734 mErrors.clear();
2735 mResultFrameNumber = frameNumber;
2736 }
2737
2738 Status status = Status::INTERNAL_ERROR;
2739 uint32_t numRequestProcessed = 0;
2740 hidl_vec<BufferCache> cachesToRemove;
2741 ret = session->processCaptureRequest(
2742 {request},
2743 cachesToRemove,
2744 [&status, &numRequestProcessed] (auto s, uint32_t n) {
2745 status = s;
2746 numRequestProcessed = n;
2747 });
2748
2749 ASSERT_TRUE(ret.isOk());
2750 ASSERT_EQ(Status::OK, status);
2751 ASSERT_EQ(numRequestProcessed, 1u);
2752 //Flush before waiting for request to complete.
2753 Return<Status> returnStatus = session->flush();
2754 ASSERT_TRUE(returnStatus.isOk());
2755 ASSERT_EQ(Status::OK, returnStatus);
2756
2757 {
2758 std::unique_lock<std::mutex> l(mLock);
2759 while ((0 == mResultBuffers.size()) && (0 == mErrors.size())) {
2760 auto timeout = std::chrono::system_clock::now() +
2761 std::chrono::seconds(kStreamBufferTimeoutSec);
2762 ASSERT_NE(std::cv_status::timeout,
2763 mResultCondition.wait_until(l, timeout));
2764 }
2765
2766 if (mErrors.empty()) {
2767 ASSERT_EQ(BufferStatus::OK, mResultBuffers[0].status);
2768 ASSERT_EQ(previewStream.id, mResultBuffers[0].streamId);
2769 } else {
2770 for (auto &error : mErrors) {
2771 switch (error.errorCode) {
2772 case ErrorCode::ERROR_REQUEST:
2773 case ErrorCode::ERROR_RESULT:
2774 //Expected
2775 break;
2776 case ErrorCode::ERROR_BUFFER:
2777 //Expected as well
2778 ASSERT_EQ(frameNumber, error.frameNumber);
2779 ASSERT_EQ(previewStream.id, error.errorStreamId);
2780 break;
2781 case ErrorCode::ERROR_DEVICE:
2782 default:
2783 FAIL() <<"Unexpected error:" << static_cast<uint32_t> (error.errorCode);
2784 }
2785 }
2786 }
2787 }
2788
2789 ret = session->close();
2790 ASSERT_TRUE(ret.isOk());
2791 }
2792 }
2793 }
2794
2795 // Verify that camera flushes correctly without any pending requests.
TEST_F(CameraHidlTest,flushEmpty)2796 TEST_F(CameraHidlTest, flushEmpty) {
2797 CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
2798 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
2799 std::vector<AvailableStream> outputPreviewStreams;
2800 AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
2801 static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
2802
2803 for (const auto& name : cameraDeviceNames) {
2804 if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
2805 Stream previewStream;
2806 HalStreamConfiguration halStreamConfig;
2807 sp<ICameraDeviceSession> session;
2808 configurePreviewStream(name, env, &previewThreshold,
2809 &session /*out*/, &previewStream /*out*/,
2810 &halStreamConfig /*out*/);
2811
2812 {
2813 std::unique_lock<std::mutex> l(mLock);
2814 mResultBuffers.clear();
2815 mErrors.clear();
2816 mResultFrameNumber = 0;
2817 }
2818
2819 Return<Status> returnStatus = session->flush();
2820 ASSERT_TRUE(returnStatus.isOk());
2821 ASSERT_EQ(Status::OK, returnStatus);
2822
2823 {
2824 std::unique_lock<std::mutex> l(mLock);
2825 auto timeout = std::chrono::system_clock::now() +
2826 std::chrono::milliseconds(kEmptyFlushTimeoutMSec);
2827 ASSERT_EQ(std::cv_status::timeout,
2828 mResultCondition.wait_until(l, timeout));
2829 ASSERT_TRUE(mErrors.empty());
2830 ASSERT_TRUE(mResultBuffers.empty());
2831 }
2832
2833 Return<void> ret = session->close();
2834 ASSERT_TRUE(ret.isOk());
2835 }
2836 }
2837 }
2838
2839 // Retrieve all valid output stream resolutions from the camera
2840 // static characteristics.
getAvailableOutputStreams(camera_metadata_t * staticMeta,std::vector<AvailableStream> & outputStreams,const AvailableStream * threshold)2841 Status CameraHidlTest::getAvailableOutputStreams(camera_metadata_t *staticMeta,
2842 std::vector<AvailableStream> &outputStreams,
2843 const AvailableStream *threshold) {
2844 if (nullptr == staticMeta) {
2845 return Status::ILLEGAL_ARGUMENT;
2846 }
2847
2848 camera_metadata_ro_entry entry;
2849 int rc = find_camera_metadata_ro_entry(staticMeta,
2850 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS, &entry);
2851 if ((0 != rc) || (0 != (entry.count % 4))) {
2852 return Status::ILLEGAL_ARGUMENT;
2853 }
2854
2855 for (size_t i = 0; i < entry.count; i+=4) {
2856 if (ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT ==
2857 entry.data.i32[i + 3]) {
2858 if(nullptr == threshold) {
2859 AvailableStream s = {entry.data.i32[i+1],
2860 entry.data.i32[i+2], entry.data.i32[i]};
2861 outputStreams.push_back(s);
2862 } else {
2863 if ((threshold->format == entry.data.i32[i]) &&
2864 (threshold->width >= entry.data.i32[i+1]) &&
2865 (threshold->height >= entry.data.i32[i+2])) {
2866 AvailableStream s = {entry.data.i32[i+1],
2867 entry.data.i32[i+2], threshold->format};
2868 outputStreams.push_back(s);
2869 }
2870 }
2871 }
2872
2873 }
2874
2875 return Status::OK;
2876 }
2877
2878 // Check if constrained mode is supported by using the static
2879 // camera characteristics.
isConstrainedModeAvailable(camera_metadata_t * staticMeta)2880 Status CameraHidlTest::isConstrainedModeAvailable(camera_metadata_t *staticMeta) {
2881 Status ret = Status::METHOD_NOT_SUPPORTED;
2882 if (nullptr == staticMeta) {
2883 return Status::ILLEGAL_ARGUMENT;
2884 }
2885
2886 camera_metadata_ro_entry entry;
2887 int rc = find_camera_metadata_ro_entry(staticMeta,
2888 ANDROID_REQUEST_AVAILABLE_CAPABILITIES, &entry);
2889 if (0 != rc) {
2890 return Status::ILLEGAL_ARGUMENT;
2891 }
2892
2893 for (size_t i = 0; i < entry.count; i++) {
2894 if (ANDROID_REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO ==
2895 entry.data.u8[i]) {
2896 ret = Status::OK;
2897 break;
2898 }
2899 }
2900
2901 return ret;
2902 }
2903
2904 // Pick the largest supported HFR mode from the static camera
2905 // characteristics.
pickConstrainedModeSize(camera_metadata_t * staticMeta,AvailableStream & hfrStream)2906 Status CameraHidlTest::pickConstrainedModeSize(camera_metadata_t *staticMeta,
2907 AvailableStream &hfrStream) {
2908 if (nullptr == staticMeta) {
2909 return Status::ILLEGAL_ARGUMENT;
2910 }
2911
2912 camera_metadata_ro_entry entry;
2913 int rc = find_camera_metadata_ro_entry(staticMeta,
2914 ANDROID_CONTROL_AVAILABLE_HIGH_SPEED_VIDEO_CONFIGURATIONS, &entry);
2915 if (0 != rc) {
2916 return Status::METHOD_NOT_SUPPORTED;
2917 } else if (0 != (entry.count % 5)) {
2918 return Status::ILLEGAL_ARGUMENT;
2919 }
2920
2921 hfrStream = {0, 0,
2922 static_cast<uint32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
2923 for (size_t i = 0; i < entry.count; i+=5) {
2924 int32_t w = entry.data.i32[i];
2925 int32_t h = entry.data.i32[i+1];
2926 if ((hfrStream.width * hfrStream.height) < (w *h)) {
2927 hfrStream.width = w;
2928 hfrStream.height = h;
2929 }
2930 }
2931
2932 return Status::OK;
2933 }
2934
2935 // Check whether ZSL is available using the static camera
2936 // characteristics.
isZSLModeAvailable(camera_metadata_t * staticMeta)2937 Status CameraHidlTest::isZSLModeAvailable(camera_metadata_t *staticMeta) {
2938 Status ret = Status::METHOD_NOT_SUPPORTED;
2939 if (nullptr == staticMeta) {
2940 return Status::ILLEGAL_ARGUMENT;
2941 }
2942
2943 camera_metadata_ro_entry entry;
2944 int rc = find_camera_metadata_ro_entry(staticMeta,
2945 ANDROID_REQUEST_AVAILABLE_CAPABILITIES, &entry);
2946 if (0 != rc) {
2947 return Status::ILLEGAL_ARGUMENT;
2948 }
2949
2950 for (size_t i = 0; i < entry.count; i++) {
2951 if ((ANDROID_REQUEST_AVAILABLE_CAPABILITIES_PRIVATE_REPROCESSING ==
2952 entry.data.u8[i]) ||
2953 (ANDROID_REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING ==
2954 entry.data.u8[i]) ){
2955 ret = Status::OK;
2956 break;
2957 }
2958 }
2959
2960 return ret;
2961 }
2962
2963 // Retrieve the reprocess input-output format map from the static
2964 // camera characteristics.
getZSLInputOutputMap(camera_metadata_t * staticMeta,std::vector<AvailableZSLInputOutput> & inputOutputMap)2965 Status CameraHidlTest::getZSLInputOutputMap(camera_metadata_t *staticMeta,
2966 std::vector<AvailableZSLInputOutput> &inputOutputMap) {
2967 if (nullptr == staticMeta) {
2968 return Status::ILLEGAL_ARGUMENT;
2969 }
2970
2971 camera_metadata_ro_entry entry;
2972 int rc = find_camera_metadata_ro_entry(staticMeta,
2973 ANDROID_SCALER_AVAILABLE_INPUT_OUTPUT_FORMATS_MAP, &entry);
2974 if ((0 != rc) || (0 >= entry.count)) {
2975 return Status::ILLEGAL_ARGUMENT;
2976 }
2977
2978 const int32_t* contents = &entry.data.i32[0];
2979 for (size_t i = 0; i < entry.count; ) {
2980 int32_t inputFormat = contents[i++];
2981 int32_t length = contents[i++];
2982 for (int32_t j = 0; j < length; j++) {
2983 int32_t outputFormat = contents[i+j];
2984 AvailableZSLInputOutput zslEntry = {inputFormat, outputFormat};
2985 inputOutputMap.push_back(zslEntry);
2986 }
2987 i += length;
2988 }
2989
2990 return Status::OK;
2991 }
2992
2993 // Search for the largest stream size for a given format.
findLargestSize(const std::vector<AvailableStream> & streamSizes,int32_t format,AvailableStream & result)2994 Status CameraHidlTest::findLargestSize(
2995 const std::vector<AvailableStream> &streamSizes, int32_t format,
2996 AvailableStream &result) {
2997 result = {0, 0, 0};
2998 for (auto &iter : streamSizes) {
2999 if (format == iter.format) {
3000 if ((result.width * result.height) < (iter.width * iter.height)) {
3001 result = iter;
3002 }
3003 }
3004 }
3005
3006 return (result.format == format) ? Status::OK : Status::ILLEGAL_ARGUMENT;
3007 }
3008
3009 // Check whether the camera device supports specific focus mode.
isAutoFocusModeAvailable(::android::CameraParameters & cameraParams,const char * mode)3010 Status CameraHidlTest::isAutoFocusModeAvailable(
3011 ::android::CameraParameters &cameraParams,
3012 const char *mode) {
3013 ::android::String8 focusModes(cameraParams.get(
3014 CameraParameters::KEY_SUPPORTED_FOCUS_MODES));
3015 if (focusModes.contains(mode)) {
3016 return Status::OK;
3017 }
3018
3019 return Status::METHOD_NOT_SUPPORTED;
3020 }
3021
3022 // Open a device session and configure a preview stream.
configurePreviewStream(const std::string & name,const CameraHidlEnvironment * env,const AvailableStream * previewThreshold,sp<ICameraDeviceSession> * session,Stream * previewStream,HalStreamConfiguration * halStreamConfig)3023 void CameraHidlTest::configurePreviewStream(const std::string &name,
3024 const CameraHidlEnvironment* env,
3025 const AvailableStream *previewThreshold,
3026 sp<ICameraDeviceSession> *session /*out*/,
3027 Stream *previewStream /*out*/,
3028 HalStreamConfiguration *halStreamConfig /*out*/) {
3029 ASSERT_NE(nullptr, env);
3030 ASSERT_NE(nullptr, session);
3031 ASSERT_NE(nullptr, previewStream);
3032 ASSERT_NE(nullptr, halStreamConfig);
3033
3034 std::vector<AvailableStream> outputPreviewStreams;
3035 ::android::sp<ICameraDevice> device3_2;
3036 ALOGI("configureStreams: Testing camera device %s", name.c_str());
3037 Return<void> ret;
3038 ret = env->mProvider->getCameraDeviceInterface_V3_x(
3039 name,
3040 [&](auto status, const auto& device) {
3041 ALOGI("getCameraDeviceInterface_V3_x returns status:%d",
3042 (int)status);
3043 ASSERT_EQ(Status::OK, status);
3044 ASSERT_NE(device, nullptr);
3045 device3_2 = device;
3046 });
3047 ASSERT_TRUE(ret.isOk());
3048
3049 sp<DeviceCb> cb = new DeviceCb(this);
3050 ret = device3_2->open(
3051 cb,
3052 [&](auto status, const auto& newSession) {
3053 ALOGI("device::open returns status:%d", (int)status);
3054 ASSERT_EQ(Status::OK, status);
3055 ASSERT_NE(newSession, nullptr);
3056 *session = newSession;
3057 });
3058 ASSERT_TRUE(ret.isOk());
3059
3060 camera_metadata_t *staticMeta;
3061 ret = device3_2->getCameraCharacteristics([&] (Status s,
3062 CameraMetadata metadata) {
3063 ASSERT_EQ(Status::OK, s);
3064 staticMeta = clone_camera_metadata(
3065 reinterpret_cast<const camera_metadata_t*>(metadata.data()));
3066 ASSERT_NE(nullptr, staticMeta);
3067 });
3068 ASSERT_TRUE(ret.isOk());
3069
3070 outputPreviewStreams.clear();
3071 auto rc = getAvailableOutputStreams(staticMeta,
3072 outputPreviewStreams, previewThreshold);
3073 free_camera_metadata(staticMeta);
3074 ASSERT_EQ(Status::OK, rc);
3075 ASSERT_FALSE(outputPreviewStreams.empty());
3076
3077 *previewStream = {0, StreamType::OUTPUT,
3078 static_cast<uint32_t> (outputPreviewStreams[0].width),
3079 static_cast<uint32_t> (outputPreviewStreams[0].height),
3080 static_cast<PixelFormat> (outputPreviewStreams[0].format),
3081 0, 0, StreamRotation::ROTATION_0};
3082 ::android::hardware::hidl_vec<Stream> streams = {*previewStream};
3083 StreamConfiguration config = {streams,
3084 StreamConfigurationMode::NORMAL_MODE};
3085 ret = (*session)->configureStreams(config, [&] (Status s,
3086 HalStreamConfiguration halConfig) {
3087 ASSERT_EQ(Status::OK, s);
3088 ASSERT_EQ(1u, halConfig.streams.size());
3089 *halStreamConfig = halConfig;
3090 });
3091 ASSERT_TRUE(ret.isOk());
3092 }
3093
3094 // Open a device session with empty callbacks and return static metadata.
openEmptyDeviceSession(const std::string & name,const CameraHidlEnvironment * env,sp<ICameraDeviceSession> * session,camera_metadata_t ** staticMeta)3095 void CameraHidlTest::openEmptyDeviceSession(const std::string &name,
3096 const CameraHidlEnvironment* env,
3097 sp<ICameraDeviceSession> *session /*out*/,
3098 camera_metadata_t **staticMeta /*out*/) {
3099 ASSERT_NE(nullptr, env);
3100 ASSERT_NE(nullptr, session);
3101 ASSERT_NE(nullptr, staticMeta);
3102
3103 ::android::sp<ICameraDevice> device3_2;
3104 ALOGI("configureStreams: Testing camera device %s", name.c_str());
3105 Return<void> ret;
3106 ret = env->mProvider->getCameraDeviceInterface_V3_x(
3107 name,
3108 [&](auto status, const auto& device) {
3109 ALOGI("getCameraDeviceInterface_V3_x returns status:%d",
3110 (int)status);
3111 ASSERT_EQ(Status::OK, status);
3112 ASSERT_NE(device, nullptr);
3113 device3_2 = device;
3114 });
3115 ASSERT_TRUE(ret.isOk());
3116
3117 sp<EmptyDeviceCb> cb = new EmptyDeviceCb();
3118 ret = device3_2->open(cb, [&](auto status, const auto& newSession) {
3119 ALOGI("device::open returns status:%d", (int)status);
3120 ASSERT_EQ(Status::OK, status);
3121 ASSERT_NE(newSession, nullptr);
3122 *session = newSession;
3123 });
3124 ASSERT_TRUE(ret.isOk());
3125
3126 ret = device3_2->getCameraCharacteristics([&] (Status s,
3127 CameraMetadata metadata) {
3128 ASSERT_EQ(Status::OK, s);
3129 *staticMeta = clone_camera_metadata(
3130 reinterpret_cast<const camera_metadata_t*>(metadata.data()));
3131 ASSERT_NE(nullptr, *staticMeta);
3132 });
3133 ASSERT_TRUE(ret.isOk());
3134 }
3135
3136 // Open a particular camera device.
openCameraDevice(const std::string & name,const CameraHidlEnvironment * env,sp<::android::hardware::camera::device::V1_0::ICameraDevice> * device1)3137 void CameraHidlTest::openCameraDevice(const std::string &name,
3138 const CameraHidlEnvironment* env,
3139 sp<::android::hardware::camera::device::V1_0::ICameraDevice> *device1 /*out*/) {
3140 ASSERT_TRUE(nullptr != env);
3141 ASSERT_TRUE(nullptr != device1);
3142
3143 Return<void> ret;
3144 ret = env->mProvider->getCameraDeviceInterface_V1_x(
3145 name,
3146 [&](auto status, const auto& device) {
3147 ALOGI("getCameraDeviceInterface_V1_x returns status:%d",
3148 (int)status);
3149 ASSERT_EQ(Status::OK, status);
3150 ASSERT_NE(device, nullptr);
3151 *device1 = device;
3152 });
3153 ASSERT_TRUE(ret.isOk());
3154
3155 sp<Camera1DeviceCb> deviceCb = new Camera1DeviceCb(this);
3156 Return<Status> returnStatus = (*device1)->open(deviceCb);
3157 ASSERT_TRUE(returnStatus.isOk());
3158 ASSERT_EQ(Status::OK, returnStatus);
3159 }
3160
3161 // Initialize and configure a preview window.
setupPreviewWindow(const sp<::android::hardware::camera::device::V1_0::ICameraDevice> & device,sp<BufferItemConsumer> * bufferItemConsumer,sp<BufferItemHander> * bufferHandler)3162 void CameraHidlTest::setupPreviewWindow(
3163 const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device,
3164 sp<BufferItemConsumer> *bufferItemConsumer /*out*/,
3165 sp<BufferItemHander> *bufferHandler /*out*/) {
3166 ASSERT_NE(nullptr, device.get());
3167 ASSERT_NE(nullptr, bufferItemConsumer);
3168 ASSERT_NE(nullptr, bufferHandler);
3169
3170 sp<IGraphicBufferProducer> producer;
3171 sp<IGraphicBufferConsumer> consumer;
3172 BufferQueue::createBufferQueue(&producer, &consumer);
3173 *bufferItemConsumer = new BufferItemConsumer(consumer,
3174 GraphicBuffer::USAGE_HW_TEXTURE); //Use GLConsumer default usage flags
3175 ASSERT_NE(nullptr, (*bufferItemConsumer).get());
3176 *bufferHandler = new BufferItemHander(*bufferItemConsumer);
3177 ASSERT_NE(nullptr, (*bufferHandler).get());
3178 (*bufferItemConsumer)->setFrameAvailableListener(*bufferHandler);
3179 sp<Surface> surface = new Surface(producer);
3180 sp<PreviewWindowCb> previewCb = new PreviewWindowCb(surface);
3181
3182 auto rc = device->setPreviewWindow(previewCb);
3183 ASSERT_TRUE(rc.isOk());
3184 ASSERT_EQ(Status::OK, rc);
3185 }
3186
3187 // Stop camera preview and close camera.
stopPreviewAndClose(const sp<::android::hardware::camera::device::V1_0::ICameraDevice> & device)3188 void CameraHidlTest::stopPreviewAndClose(
3189 const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device) {
3190 Return<void> ret = device->stopPreview();
3191 ASSERT_TRUE(ret.isOk());
3192
3193 ret = device->close();
3194 ASSERT_TRUE(ret.isOk());
3195 }
3196
3197 // Enable a specific camera message type.
enableMsgType(unsigned int msgType,const sp<::android::hardware::camera::device::V1_0::ICameraDevice> & device)3198 void CameraHidlTest::enableMsgType(unsigned int msgType,
3199 const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device) {
3200 Return<void> ret = device->enableMsgType(msgType);
3201 ASSERT_TRUE(ret.isOk());
3202
3203 Return<bool> returnBoolStatus = device->msgTypeEnabled(msgType);
3204 ASSERT_TRUE(returnBoolStatus.isOk());
3205 ASSERT_TRUE(returnBoolStatus);
3206 }
3207
3208 // Disable a specific camera message type.
disableMsgType(unsigned int msgType,const sp<::android::hardware::camera::device::V1_0::ICameraDevice> & device)3209 void CameraHidlTest::disableMsgType(unsigned int msgType,
3210 const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device) {
3211 Return<void> ret = device->disableMsgType(msgType);
3212 ASSERT_TRUE(ret.isOk());
3213
3214 Return<bool> returnBoolStatus = device->msgTypeEnabled(msgType);
3215 ASSERT_TRUE(returnBoolStatus.isOk());
3216 ASSERT_FALSE(returnBoolStatus);
3217 }
3218
3219 // Wait until a specific frame notification arrives.
waitForFrameLocked(DataCallbackMsg msgFrame,std::unique_lock<std::mutex> & l)3220 void CameraHidlTest::waitForFrameLocked(DataCallbackMsg msgFrame,
3221 std::unique_lock<std::mutex> &l) {
3222 while (msgFrame != mDataMessageTypeReceived) {
3223 auto timeout = std::chrono::system_clock::now() +
3224 std::chrono::seconds(kStreamBufferTimeoutSec);
3225 ASSERT_NE(std::cv_status::timeout,
3226 mResultCondition.wait_until(l, timeout));
3227 }
3228 }
3229
3230 // Start preview on a particular camera device
startPreview(const sp<::android::hardware::camera::device::V1_0::ICameraDevice> & device)3231 void CameraHidlTest::startPreview(
3232 const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device) {
3233 Return<Status> returnStatus = device->startPreview();
3234 ASSERT_TRUE(returnStatus.isOk());
3235 ASSERT_EQ(Status::OK, returnStatus);
3236 }
3237
3238 // Retrieve camera parameters.
getParameters(const sp<::android::hardware::camera::device::V1_0::ICameraDevice> & device,CameraParameters * cameraParams)3239 void CameraHidlTest::getParameters(
3240 const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device,
3241 CameraParameters *cameraParams /*out*/) {
3242 ASSERT_NE(nullptr, cameraParams);
3243
3244 Return<void> ret;
3245 ret = device->getParameters([&] (const ::android::hardware::hidl_string& params) {
3246 ASSERT_FALSE(params.empty());
3247 ::android::String8 paramString(params.c_str());
3248 (*cameraParams).unflatten(paramString);
3249 });
3250 ASSERT_TRUE(ret.isOk());
3251 }
3252
3253 // Set camera parameters.
setParameters(const sp<::android::hardware::camera::device::V1_0::ICameraDevice> & device,const CameraParameters & cameraParams)3254 void CameraHidlTest::setParameters(
3255 const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device,
3256 const CameraParameters &cameraParams) {
3257 Return<Status> returnStatus = device->setParameters(
3258 cameraParams.flatten().string());
3259 ASSERT_TRUE(returnStatus.isOk());
3260 ASSERT_EQ(Status::OK, returnStatus);
3261 }
3262
main(int argc,char ** argv)3263 int main(int argc, char **argv) {
3264 ::testing::AddGlobalTestEnvironment(CameraHidlEnvironment::Instance());
3265 ::testing::InitGoogleTest(&argc, argv);
3266 int status = RUN_ALL_TESTS();
3267 ALOGI("Test result = %d", status);
3268 return status;
3269 }
3270