• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019 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 "VtsHalCameraServiceV2_0TargetTest"
18 //#define LOG_NDEBUG 0
19 
20 #include <android/frameworks/cameraservice/device/2.0/ICameraDeviceUser.h>
21 #include <android/frameworks/cameraservice/service/2.0/ICameraService.h>
22 #include <android/frameworks/cameraservice/service/2.1/ICameraService.h>
23 #include <system/camera_metadata.h>
24 #include <system/graphics.h>
25 
26 #include <fmq/MessageQueue.h>
27 #include <utils/Condition.h>
28 #include <utils/Mutex.h>
29 #include <utils/StrongPointer.h>
30 
31 #include <gtest/gtest.h>
32 #include <hidl/GtestPrinter.h>
33 #include <hidl/ServiceManagement.h>
34 #include <stdint.h>
35 #include <unistd.h>
36 
37 #include <stdio.h>
38 #include <algorithm>
39 #include <mutex>
40 #include <string>
41 #include <unordered_set>
42 #include <vector>
43 
44 #include <media/NdkImageReader.h>
45 
46 #include <android/log.h>
47 
48 #include <CameraMetadata.h>
49 
50 namespace android {
51 
52 using android::Condition;
53 using android::Mutex;
54 using android::sp;
55 using android::frameworks::cameraservice::common::V2_0::Status;
56 using android::frameworks::cameraservice::device::V2_0::CaptureRequest;
57 using android::frameworks::cameraservice::device::V2_0::CaptureResultExtras;
58 using android::frameworks::cameraservice::device::V2_0::ErrorCode;
59 using android::frameworks::cameraservice::device::V2_0::FmqSizeOrMetadata;
60 using android::frameworks::cameraservice::device::V2_0::ICameraDeviceCallback;
61 using android::frameworks::cameraservice::device::V2_0::ICameraDeviceUser;
62 using android::frameworks::cameraservice::device::V2_0::OutputConfiguration;
63 using android::frameworks::cameraservice::device::V2_0::PhysicalCaptureResultInfo;
64 using android::frameworks::cameraservice::device::V2_0::StreamConfigurationMode;
65 using android::frameworks::cameraservice::device::V2_0::SubmitInfo;
66 using android::frameworks::cameraservice::device::V2_0::TemplateId;
67 using android::frameworks::cameraservice::service::V2_0::CameraDeviceStatus;
68 using android::frameworks::cameraservice::service::V2_0::CameraStatusAndId;
69 using android::frameworks::cameraservice::service::V2_0::ICameraService;
70 using android::frameworks::cameraservice::service::V2_0::ICameraServiceListener;
71 using android::frameworks::cameraservice::service::V2_1::PhysicalCameraStatusAndId;
72 using android::hardware::hidl_string;
73 using android::hardware::hidl_vec;
74 using android::hardware::Return;
75 using android::hardware::Void;
76 using android::hardware::camera::common::V1_0::helper::CameraMetadata;
77 using camera_metadata_enum_android_depth_available_depth_stream_configurations::
78     ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS_OUTPUT;
79 using RequestMetadataQueue = hardware::MessageQueue<uint8_t, hardware::kSynchronizedReadWrite>;
80 
81 static constexpr int kCaptureRequestCount = 10;
82 static constexpr int kVGAImageWidth = 640;
83 static constexpr int kVGAImageHeight = 480;
84 static constexpr int kNumRequests = 4;
85 
86 #define ASSERT_NOT_NULL(x) ASSERT_TRUE((x) != nullptr)
87 
88 #define SETUP_TIMEOUT 2000000000  // ns
89 #define IDLE_TIMEOUT 2000000000   // ns
90 
91 // Stub listener implementation
92 class CameraServiceListener : public ICameraServiceListener {
93     std::map<hidl_string, CameraDeviceStatus> mCameraStatuses;
94     mutable Mutex mLock;
95 
96    public:
~CameraServiceListener()97     virtual ~CameraServiceListener(){};
98 
onStatusChanged(const CameraStatusAndId & statusAndId)99     virtual Return<void> onStatusChanged(const CameraStatusAndId& statusAndId) override {
100         Mutex::Autolock l(mLock);
101         mCameraStatuses[statusAndId.cameraId] = statusAndId.deviceStatus;
102         return Void();
103     };
104 };
105 
106 class CameraServiceListener2_1
107     : public android::frameworks::cameraservice::service::V2_1::ICameraServiceListener {
108     std::map<hidl_string, CameraDeviceStatus> mCameraStatuses;
109     std::map<hidl_string, std::set<hidl_string>> mUnavailablePhysicalCameras;
110     mutable Mutex mLock;
111 
112    public:
~CameraServiceListener2_1()113     virtual ~CameraServiceListener2_1(){};
114 
onStatusChanged(const CameraStatusAndId & statusAndId)115     virtual Return<void> onStatusChanged(const CameraStatusAndId& statusAndId) override {
116         Mutex::Autolock l(mLock);
117         mCameraStatuses[statusAndId.cameraId] = statusAndId.deviceStatus;
118         return Void();
119     };
120 
onPhysicalCameraStatusChanged(const PhysicalCameraStatusAndId & statusAndId)121     virtual Return<void> onPhysicalCameraStatusChanged(
122         const PhysicalCameraStatusAndId& statusAndId) override {
123         Mutex::Autolock l(mLock);
124         ALOGI("%s: Physical camera %s : %s status changed to %d", __FUNCTION__,
125               statusAndId.cameraId.c_str(), statusAndId.physicalCameraId.c_str(),
126               statusAndId.deviceStatus);
127 
128         EXPECT_NE(mCameraStatuses.find(statusAndId.cameraId), mCameraStatuses.end());
129         EXPECT_EQ(mCameraStatuses[statusAndId.cameraId], CameraDeviceStatus::STATUS_PRESENT);
130 
131         if (statusAndId.deviceStatus == CameraDeviceStatus::STATUS_NOT_PRESENT) {
132             auto res = mUnavailablePhysicalCameras[statusAndId.cameraId].emplace(
133                 statusAndId.physicalCameraId);
134             EXPECT_TRUE(res.second);
135         } else {
136             auto res = mUnavailablePhysicalCameras[statusAndId.cameraId].erase(
137                 statusAndId.physicalCameraId);
138             EXPECT_EQ(res, 1);
139         }
140         return Void();
141     };
142 
initializeStatuses(const hidl_vec<android::frameworks::cameraservice::service::V2_1::CameraStatusAndId> & statuses)143     void initializeStatuses(
144         const hidl_vec<android::frameworks::cameraservice::service::V2_1::CameraStatusAndId>&
145             statuses) {
146         Mutex::Autolock l(mLock);
147 
148         for (auto& status : statuses) {
149             mCameraStatuses[status.v2_0.cameraId] = status.v2_0.deviceStatus;
150             for (auto& physicalId : status.unavailPhysicalCameraIds) {
151                 mUnavailablePhysicalCameras[status.v2_0.cameraId].emplace(physicalId);
152             }
153         }
154     }
155 };
156 
157 // ICameraDeviceCallback implementation
158 class CameraDeviceCallbacks : public ICameraDeviceCallback {
159    public:
160     enum Status {
161         IDLE,
162         ERROR,
163         PREPARED,
164         RUNNING,
165         RESULT_RECEIVED,
166         UNINITIALIZED,
167         REPEATING_REQUEST_ERROR,
168     };
169 
170    protected:
171     bool mError = false;
172     Status mLastStatus = UNINITIALIZED;
173     mutable std::vector<Status> mStatusesHit;
174     mutable Mutex mLock;
175     mutable Condition mStatusCondition;
176 
177    public:
CameraDeviceCallbacks()178     CameraDeviceCallbacks() {}
179 
~CameraDeviceCallbacks()180     virtual ~CameraDeviceCallbacks() {}
181 
onDeviceError(ErrorCode errorCode,const CaptureResultExtras & resultExtras)182     virtual Return<void> onDeviceError(ErrorCode errorCode,
183                                        const CaptureResultExtras& resultExtras) override {
184         (void)resultExtras;
185         ALOGE("%s: onDeviceError occurred with: %d", __FUNCTION__, static_cast<int>(errorCode));
186         Mutex::Autolock l(mLock);
187         mError = true;
188         mLastStatus = ERROR;
189         mStatusesHit.push_back(mLastStatus);
190         mStatusCondition.broadcast();
191         return Void();
192     }
193 
onDeviceIdle()194     virtual Return<void> onDeviceIdle() override {
195         Mutex::Autolock l(mLock);
196         mLastStatus = IDLE;
197         mStatusesHit.push_back(mLastStatus);
198         mStatusCondition.broadcast();
199         return Void();
200     }
201 
onCaptureStarted(const CaptureResultExtras & resultExtras,uint64_t timestamp)202     virtual Return<void> onCaptureStarted(const CaptureResultExtras& resultExtras,
203                                           uint64_t timestamp) override {
204         (void)resultExtras;
205         (void)timestamp;
206         Mutex::Autolock l(mLock);
207         mLastStatus = RUNNING;
208         mStatusesHit.push_back(mLastStatus);
209         mStatusCondition.broadcast();
210         return Void();
211     }
212 
onResultReceived(const FmqSizeOrMetadata & sizeOrMetadata,const CaptureResultExtras & resultExtras,const hidl_vec<PhysicalCaptureResultInfo> & physicalResultInfos)213     virtual Return<void> onResultReceived(
214         const FmqSizeOrMetadata& sizeOrMetadata, const CaptureResultExtras& resultExtras,
215         const hidl_vec<PhysicalCaptureResultInfo>& physicalResultInfos) override {
216         (void)sizeOrMetadata;
217         (void)resultExtras;
218         (void)physicalResultInfos;
219         Mutex::Autolock l(mLock);
220         mLastStatus = RESULT_RECEIVED;
221         mStatusesHit.push_back(mLastStatus);
222         mStatusCondition.broadcast();
223         return Void();
224     }
225 
onRepeatingRequestError(uint64_t lastFrameNumber,int32_t stoppedSequenceId)226     virtual Return<void> onRepeatingRequestError(uint64_t lastFrameNumber,
227                                                  int32_t stoppedSequenceId) override {
228         (void)lastFrameNumber;
229         (void)stoppedSequenceId;
230         Mutex::Autolock l(mLock);
231         mLastStatus = REPEATING_REQUEST_ERROR;
232         mStatusesHit.push_back(mLastStatus);
233         mStatusCondition.broadcast();
234         return Void();
235     }
236 
237     // Test helper functions:
238 
hadError() const239     bool hadError() const {
240         Mutex::Autolock l(mLock);
241         return mError;
242     }
waitForStatus(Status status) const243     bool waitForStatus(Status status) const {
244         Mutex::Autolock l(mLock);
245         if (mLastStatus == status) {
246             return true;
247         }
248 
249         while (std::find(mStatusesHit.begin(), mStatusesHit.end(), status) == mStatusesHit.end()) {
250             if (mStatusCondition.waitRelative(mLock, IDLE_TIMEOUT) != android::OK) {
251                 mStatusesHit.clear();
252                 return false;
253             }
254         }
255         mStatusesHit.clear();
256 
257         return true;
258     }
259 
clearStatus() const260     void clearStatus() const {
261         Mutex::Autolock l(mLock);
262         mStatusesHit.clear();
263     }
264 
waitForIdle() const265     bool waitForIdle() const { return waitForStatus(IDLE); }
266 };
267 
convertFromHidlCloned(const hidl_vec<uint8_t> & metadata,CameraMetadata * rawMetadata)268 static bool convertFromHidlCloned(const hidl_vec<uint8_t>& metadata, CameraMetadata* rawMetadata) {
269     const camera_metadata* buffer = (camera_metadata_t*)(metadata.data());
270     size_t expectedSize = metadata.size();
271     int ret = validate_camera_metadata_structure(buffer, &expectedSize);
272     if (ret == OK || ret == CAMERA_METADATA_VALIDATION_SHIFTED) {
273         *rawMetadata = buffer;
274     } else {
275         ALOGE("%s: Malformed camera metadata received from caller", __FUNCTION__);
276         return false;
277     }
278     return true;
279 }
280 
281 struct StreamConfiguration {
282     int32_t width = -1;
283     int32_t height = -1;
284 };
285 
286 class VtsHalCameraServiceV2_0TargetTest : public ::testing::TestWithParam<std::string> {
287    public:
SetUp()288     void SetUp() override {
289         cs = ICameraService::getService(GetParam());
290 
291         auto castResult =
292             android::frameworks::cameraservice::service::V2_1::ICameraService::castFrom(cs);
293         if (castResult.isOk()) {
294             cs2_1 = castResult;
295         }
296     }
297 
TearDown()298     void TearDown() override {}
299     // creates an outputConfiguration with no deferred streams
createOutputConfiguration(const std::vector<native_handle_t * > & nhs)300     OutputConfiguration createOutputConfiguration(const std::vector<native_handle_t*>& nhs) {
301         OutputConfiguration output;
302         output.rotation = OutputConfiguration::Rotation::R0;
303         output.windowGroupId = -1;
304         output.windowHandles.resize(nhs.size());
305         output.width = 0;
306         output.height = 0;
307         output.isDeferred = false;
308         for (size_t i = 0; i < nhs.size(); i++) {
309             output.windowHandles[i] = nhs[i];
310         }
311         return output;
312     }
313 
initializeCaptureRequestPartial(CaptureRequest * captureRequest,int32_t streamId,const hidl_string & cameraId,size_t settingsSize)314     void initializeCaptureRequestPartial(CaptureRequest* captureRequest, int32_t streamId,
315                                          const hidl_string& cameraId, size_t settingsSize) {
316         captureRequest->physicalCameraSettings.resize(1);
317         captureRequest->physicalCameraSettings[0].id = cameraId;
318         captureRequest->streamAndWindowIds.resize(1);
319         captureRequest->streamAndWindowIds[0].streamId = streamId;
320         captureRequest->streamAndWindowIds[0].windowId = 0;
321         // Write the settings metadata into the fmq.
322         captureRequest->physicalCameraSettings[0].settings.fmqMetadataSize(settingsSize);
323     }
324 
doesCapabilityExist(const CameraMetadata & characteristics,int capability)325     bool doesCapabilityExist(const CameraMetadata& characteristics, int capability) {
326         camera_metadata_ro_entry rawEntry =
327             characteristics.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
328         EXPECT_TRUE(rawEntry.count > 0);
329         for (size_t i = 0; i < rawEntry.count; i++) {
330             if (rawEntry.data.u8[i] == capability) {
331                 return true;
332             }
333         }
334         return false;
335     }
336 
isSecureOnlyDevice(const CameraMetadata & characteristics)337     bool isSecureOnlyDevice(const CameraMetadata& characteristics) {
338         camera_metadata_ro_entry rawEntry =
339             characteristics.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
340         EXPECT_TRUE(rawEntry.count > 0);
341         if (rawEntry.count == 1 &&
342             rawEntry.data.u8[0] == ANDROID_REQUEST_AVAILABLE_CAPABILITIES_SECURE_IMAGE_DATA) {
343             return true;
344         }
345         return false;
346     }
347 
348     // Return the first advertised available stream sizes for the given format
349     // and use-case.
getStreamConfiguration(const CameraMetadata & characteristics,uint32_t tag,int32_t chosenUse,int32_t chosenFormat)350     StreamConfiguration getStreamConfiguration(const CameraMetadata& characteristics, uint32_t tag,
351                                                int32_t chosenUse, int32_t chosenFormat) {
352         camera_metadata_ro_entry rawEntry = characteristics.find(tag);
353         StreamConfiguration streamConfig;
354         const size_t STREAM_FORMAT_OFFSET = 0;
355         const size_t STREAM_WIDTH_OFFSET = 1;
356         const size_t STREAM_HEIGHT_OFFSET = 2;
357         const size_t STREAM_INOUT_OFFSET = 3;
358         const size_t STREAM_CONFIG_SIZE = 4;
359         if (rawEntry.count < STREAM_CONFIG_SIZE) {
360             return streamConfig;
361         }
362         EXPECT_TRUE((rawEntry.count % STREAM_CONFIG_SIZE) == 0);
363         for (size_t i = 0; i < rawEntry.count; i += STREAM_CONFIG_SIZE) {
364             int32_t format = rawEntry.data.i32[i + STREAM_FORMAT_OFFSET];
365             int32_t use = rawEntry.data.i32[i + STREAM_INOUT_OFFSET];
366             if (format == chosenFormat && use == chosenUse) {
367                 streamConfig.width = rawEntry.data.i32[i + STREAM_WIDTH_OFFSET];
368                 streamConfig.height = rawEntry.data.i32[i + STREAM_HEIGHT_OFFSET];
369                 return streamConfig;
370             }
371         }
372         return streamConfig;
373     }
374 
375     sp<ICameraService> cs = nullptr;
376     sp<android::frameworks::cameraservice::service::V2_1::ICameraService> cs2_1 = nullptr;
377 };
378 
379 // Basic HIDL calls for ICameraService
TEST_P(VtsHalCameraServiceV2_0TargetTest,BasicCameraLifeCycleTest)380 TEST_P(VtsHalCameraServiceV2_0TargetTest, BasicCameraLifeCycleTest) {
381     sp<CameraServiceListener> listener(new CameraServiceListener());
382     hidl_vec<CameraStatusAndId> cameraStatuses{};
383     Status status = Status::NO_ERROR;
384     auto remoteRet =
385         cs->addListener(listener, [&status, &cameraStatuses](Status s, auto& retStatuses) {
386             status = s;
387             cameraStatuses = retStatuses;
388         });
389     EXPECT_TRUE(remoteRet.isOk() && status == Status::NO_ERROR);
390     for (const auto& it : cameraStatuses) {
391         CameraMetadata rawMetadata;
392         if (it.deviceStatus != CameraDeviceStatus::STATUS_PRESENT) {
393             continue;
394         }
395         remoteRet = cs->getCameraCharacteristics(
396             it.cameraId, [&status, &rawMetadata](auto s, const hidl_vec<uint8_t>& metadata) {
397                 status = s;
398                 bool cStatus = convertFromHidlCloned(metadata, &rawMetadata);
399                 EXPECT_TRUE(cStatus);
400             });
401         EXPECT_TRUE(remoteRet.isOk() && status == Status::NO_ERROR);
402         EXPECT_FALSE(rawMetadata.isEmpty());
403         sp<CameraDeviceCallbacks> callbacks(new CameraDeviceCallbacks());
404         sp<ICameraDeviceUser> deviceRemote = nullptr;
405         remoteRet = cs->connectDevice(callbacks, it.cameraId,
406                                       [&status, &deviceRemote](auto s, auto& device) {
407                                           status = s;
408                                           deviceRemote = device;
409                                       });
410         EXPECT_TRUE(remoteRet.isOk() && status == Status::NO_ERROR);
411         EXPECT_TRUE(deviceRemote != nullptr);
412 
413         std::shared_ptr<RequestMetadataQueue> requestMQ = nullptr;
414         remoteRet = deviceRemote->getCaptureRequestMetadataQueue([&requestMQ](const auto& mqD) {
415             requestMQ = std::make_shared<RequestMetadataQueue>(mqD);
416             EXPECT_TRUE(requestMQ->isValid() && (requestMQ->availableToWrite() >= 0));
417         });
418         EXPECT_TRUE(remoteRet.isOk());
419         AImageReader* reader = nullptr;
420         bool isDepthOnlyDevice =
421             !doesCapabilityExist(rawMetadata,
422                                  ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE) &&
423             doesCapabilityExist(rawMetadata, ANDROID_REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT);
424         int chosenImageFormat = AIMAGE_FORMAT_YUV_420_888;
425         int chosenImageWidth = kVGAImageWidth;
426         int chosenImageHeight = kVGAImageHeight;
427         bool isSecureOnlyCamera = isSecureOnlyDevice(rawMetadata);
428         status_t mStatus = OK;
429         if (isSecureOnlyCamera) {
430             StreamConfiguration secureStreamConfig =
431                 getStreamConfiguration(rawMetadata, ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
432                                        ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT,
433                                        HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED);
434             EXPECT_TRUE(secureStreamConfig.width != -1);
435             EXPECT_TRUE(secureStreamConfig.height != -1);
436             chosenImageFormat = AIMAGE_FORMAT_PRIVATE;
437             chosenImageWidth = secureStreamConfig.width;
438             chosenImageHeight = secureStreamConfig.height;
439             mStatus = AImageReader_newWithUsage(
440                 chosenImageWidth, chosenImageHeight, chosenImageFormat,
441                 AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT, kCaptureRequestCount, &reader);
442 
443         } else {
444             if (isDepthOnlyDevice) {
445                 StreamConfiguration depthStreamConfig = getStreamConfiguration(
446                     rawMetadata, ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS,
447                     ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS_OUTPUT,
448                     HAL_PIXEL_FORMAT_Y16);
449                 EXPECT_TRUE(depthStreamConfig.width != -1);
450                 EXPECT_TRUE(depthStreamConfig.height != -1);
451                 chosenImageFormat = AIMAGE_FORMAT_DEPTH16;
452                 chosenImageWidth = depthStreamConfig.width;
453                 chosenImageHeight = depthStreamConfig.height;
454             }
455             mStatus = AImageReader_new(chosenImageWidth, chosenImageHeight, chosenImageFormat,
456                                        kCaptureRequestCount, &reader);
457         }
458 
459         EXPECT_EQ(mStatus, AMEDIA_OK);
460         native_handle_t* wh = nullptr;
461         mStatus = AImageReader_getWindowNativeHandle(reader, &wh);
462         EXPECT_TRUE(mStatus == AMEDIA_OK && wh != nullptr);
463         OutputConfiguration output = createOutputConfiguration({wh});
464         Return<Status> ret = deviceRemote->beginConfigure();
465         EXPECT_TRUE(ret.isOk() && ret == Status::NO_ERROR);
466         int32_t streamId = -1;
467         remoteRet = deviceRemote->createStream(output, [&status, &streamId](Status s, auto sId) {
468             status = s;
469             streamId = sId;
470         });
471         EXPECT_TRUE(remoteRet.isOk() && status == Status::NO_ERROR);
472         EXPECT_TRUE(streamId >= 0);
473         hidl_vec<uint8_t> hidlParams;
474         ret = deviceRemote->endConfigure(StreamConfigurationMode::NORMAL_MODE, hidlParams);
475         EXPECT_TRUE(ret.isOk() && ret == Status::NO_ERROR);
476         hidl_vec<uint8_t> settingsMetadata;
477         remoteRet = deviceRemote->createDefaultRequest(
478             TemplateId::PREVIEW, [&status, &settingsMetadata](auto s, const hidl_vec<uint8_t> m) {
479                 status = s;
480                 settingsMetadata = m;
481             });
482         EXPECT_TRUE(remoteRet.isOk() && status == Status::NO_ERROR);
483         EXPECT_GE(settingsMetadata.size(), 0);
484         hidl_vec<CaptureRequest> captureRequests;
485         captureRequests.resize(kNumRequests);
486         for (int i = 0; i < kNumRequests; i++) {
487             CaptureRequest& captureRequest = captureRequests[i];
488             initializeCaptureRequestPartial(&captureRequest, streamId, it.cameraId,
489                                             settingsMetadata.size());
490             // Write the settings metadata into the fmq.
491             bool written = requestMQ->write(settingsMetadata.data(), settingsMetadata.size());
492             EXPECT_TRUE(written);
493         }
494         SubmitInfo info;
495 
496         // Test a single capture
497         remoteRet = deviceRemote->submitRequestList(captureRequests, false,
498                                                     [&status, &info](auto s, auto& submitInfo) {
499                                                         status = s;
500                                                         info = submitInfo;
501                                                     });
502         EXPECT_TRUE(remoteRet.isOk() && status == Status::NO_ERROR);
503         EXPECT_GE(info.requestId, 0);
504         EXPECT_TRUE(callbacks->waitForStatus(CameraDeviceCallbacks::Status::RESULT_RECEIVED));
505         EXPECT_TRUE(callbacks->waitForIdle());
506 
507         // Test repeating requests
508         CaptureRequest captureRequest;
509 
510         initializeCaptureRequestPartial(&captureRequest, streamId, it.cameraId,
511                                         settingsMetadata.size());
512 
513         bool written = requestMQ->write(settingsMetadata.data(), settingsMetadata.size());
514         EXPECT_TRUE(written);
515 
516         remoteRet = deviceRemote->submitRequestList({captureRequest}, true,
517                                                     [&status, &info](auto s, auto& submitInfo) {
518                                                         status = s;
519                                                         info = submitInfo;
520                                                     });
521         EXPECT_TRUE(callbacks->waitForStatus(CameraDeviceCallbacks::Status::RESULT_RECEIVED));
522         int64_t lastFrameNumber = -1;
523         remoteRet =
524             deviceRemote->cancelRepeatingRequest([&status, &lastFrameNumber](auto s, int64_t lf) {
525                 status = s;
526                 lastFrameNumber = lf;
527             });
528         EXPECT_TRUE(remoteRet.isOk() && status == Status::NO_ERROR);
529         EXPECT_GE(lastFrameNumber, 0);
530 
531         // Test waitUntilIdle()
532         auto statusRet = deviceRemote->waitUntilIdle();
533         EXPECT_TRUE(statusRet.isOk() && statusRet == Status::NO_ERROR);
534 
535         // Test deleteStream()
536         statusRet = deviceRemote->deleteStream(streamId);
537         EXPECT_TRUE(statusRet.isOk() && statusRet == Status::NO_ERROR);
538 
539         remoteRet = deviceRemote->disconnect();
540         EXPECT_TRUE(remoteRet.isOk());
541     }
542     Return<Status> ret = cs->removeListener(listener);
543     EXPECT_TRUE(ret.isOk() && ret == Status::NO_ERROR);
544 }
545 
TEST_P(VtsHalCameraServiceV2_0TargetTest,CameraServiceListener2_1Test)546 TEST_P(VtsHalCameraServiceV2_0TargetTest, CameraServiceListener2_1Test) {
547     sp<CameraServiceListener2_1> listener2_1(new CameraServiceListener2_1());
548     hidl_vec<android::frameworks::cameraservice::service::V2_1::CameraStatusAndId>
549         cameraStatuses2_1{};
550     Status status = Status::NO_ERROR;
551 
552     if (cs2_1 == nullptr) return;
553 
554     auto remoteRet = cs2_1->addListener_2_1(
555         listener2_1, [&status, &cameraStatuses2_1](Status s, auto& retStatuses) {
556             status = s;
557             cameraStatuses2_1 = retStatuses;
558         });
559     EXPECT_TRUE(remoteRet.isOk() && status == Status::NO_ERROR);
560     listener2_1->initializeStatuses(cameraStatuses2_1);
561 
562     for (const auto& it : cameraStatuses2_1) {
563         CameraMetadata rawMetadata;
564         remoteRet = cs2_1->getCameraCharacteristics(
565             it.v2_0.cameraId, [&status, &rawMetadata](auto s, const hidl_vec<uint8_t>& metadata) {
566                 status = s;
567                 bool cStatus = convertFromHidlCloned(metadata, &rawMetadata);
568                 EXPECT_TRUE(cStatus);
569             });
570         EXPECT_TRUE(remoteRet.isOk() && status == Status::NO_ERROR);
571         EXPECT_FALSE(rawMetadata.isEmpty());
572         bool isLogicalCamera = doesCapabilityExist(
573             rawMetadata, ANDROID_REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA);
574         if (!isLogicalCamera) {
575             EXPECT_TRUE(it.unavailPhysicalCameraIds.size() == 0);
576             continue;
577         }
578         camera_metadata_entry entry = rawMetadata.find(ANDROID_LOGICAL_MULTI_CAMERA_PHYSICAL_IDS);
579         EXPECT_GT(entry.count, 0);
580 
581         std::unordered_set<std::string> validPhysicalIds;
582         const uint8_t* ids = entry.data.u8;
583         size_t start = 0;
584         for (size_t i = 0; i < entry.count; i++) {
585             if (ids[i] == '\0') {
586                 if (start != i) {
587                     std::string currentId(reinterpret_cast<const char*>(ids + start));
588                     validPhysicalIds.emplace(currentId);
589                 }
590                 start = i + 1;
591             }
592         }
593 
594         std::unordered_set<std::string> unavailablePhysicalIds(it.unavailPhysicalCameraIds.begin(),
595                                                                it.unavailPhysicalCameraIds.end());
596         EXPECT_EQ(unavailablePhysicalIds.size(), it.unavailPhysicalCameraIds.size());
597         for (auto& unavailablePhysicalId : unavailablePhysicalIds) {
598             EXPECT_NE(validPhysicalIds.find(unavailablePhysicalId), validPhysicalIds.end());
599         }
600     }
601 
602     auto remoteStatus = cs2_1->removeListener(listener2_1);
603     EXPECT_TRUE(remoteStatus.isOk() && remoteStatus == Status::NO_ERROR);
604 }
605 
606 INSTANTIATE_TEST_SUITE_P(
607         PerInstance, VtsHalCameraServiceV2_0TargetTest,
608         testing::ValuesIn(android::hardware::getAllHalInstanceNames(ICameraService::descriptor)),
609         android::hardware::PrintInstanceNameToString);
610 }  // namespace android
611