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