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 <system/camera_metadata.h>
23 #include <system/graphics.h>
24 
25 #include <fmq/MessageQueue.h>
26 #include <utils/Condition.h>
27 #include <utils/Mutex.h>
28 #include <utils/StrongPointer.h>
29 
30 #include <gtest/gtest.h>
31 #include <hidl/GtestPrinter.h>
32 #include <hidl/ServiceManagement.h>
33 #include <stdint.h>
34 #include <unistd.h>
35 
36 #include <stdio.h>
37 #include <algorithm>
38 #include <mutex>
39 #include <string>
40 #include <vector>
41 
42 #include <media/NdkImageReader.h>
43 
44 #include <android/log.h>
45 
46 #include <CameraMetadata.h>
47 
48 namespace android {
49 
50 using android::Condition;
51 using android::Mutex;
52 using android::sp;
53 using android::frameworks::cameraservice::common::V2_0::Status;
54 using android::frameworks::cameraservice::device::V2_0::CaptureRequest;
55 using android::frameworks::cameraservice::device::V2_0::CaptureResultExtras;
56 using android::frameworks::cameraservice::device::V2_0::ErrorCode;
57 using android::frameworks::cameraservice::device::V2_0::FmqSizeOrMetadata;
58 using android::frameworks::cameraservice::device::V2_0::ICameraDeviceCallback;
59 using android::frameworks::cameraservice::device::V2_0::ICameraDeviceUser;
60 using android::frameworks::cameraservice::device::V2_0::OutputConfiguration;
61 using android::frameworks::cameraservice::device::V2_0::PhysicalCaptureResultInfo;
62 using android::frameworks::cameraservice::device::V2_0::StreamConfigurationMode;
63 using android::frameworks::cameraservice::device::V2_0::SubmitInfo;
64 using android::frameworks::cameraservice::device::V2_0::TemplateId;
65 using android::frameworks::cameraservice::service::V2_0::CameraDeviceStatus;
66 using android::frameworks::cameraservice::service::V2_0::CameraStatusAndId;
67 using android::frameworks::cameraservice::service::V2_0::ICameraService;
68 using android::frameworks::cameraservice::service::V2_0::ICameraServiceListener;
69 using android::hardware::hidl_string;
70 using android::hardware::hidl_vec;
71 using android::hardware::Return;
72 using android::hardware::Void;
73 using android::hardware::camera::common::V1_0::helper::CameraMetadata;
74 using camera_metadata_enum_android_depth_available_depth_stream_configurations::
75     ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS_OUTPUT;
76 using RequestMetadataQueue = hardware::MessageQueue<uint8_t, hardware::kSynchronizedReadWrite>;
77 
78 static constexpr int kCaptureRequestCount = 10;
79 static constexpr int kVGAImageWidth = 640;
80 static constexpr int kVGAImageHeight = 480;
81 static constexpr int kNumRequests = 4;
82 
83 #define ASSERT_NOT_NULL(x) ASSERT_TRUE((x) != nullptr)
84 
85 #define SETUP_TIMEOUT 2000000000  // ns
86 #define IDLE_TIMEOUT 2000000000   // ns
87 
88 // Stub listener implementation
89 class CameraServiceListener : public ICameraServiceListener {
90     std::map<hidl_string, CameraDeviceStatus> mCameraStatuses;
91     mutable Mutex mLock;
92 
93    public:
~CameraServiceListener()94     virtual ~CameraServiceListener(){};
95 
onStatusChanged(const CameraStatusAndId & statusAndId)96     virtual Return<void> onStatusChanged(const CameraStatusAndId& statusAndId) override {
97         Mutex::Autolock l(mLock);
98         mCameraStatuses[statusAndId.cameraId] = statusAndId.deviceStatus;
99         return Void();
100     };
101 };
102 
103 // ICameraDeviceCallback implementation
104 class CameraDeviceCallbacks : public ICameraDeviceCallback {
105    public:
106     enum Status {
107         IDLE,
108         ERROR,
109         PREPARED,
110         RUNNING,
111         RESULT_RECEIVED,
112         UNINITIALIZED,
113         REPEATING_REQUEST_ERROR,
114     };
115 
116    protected:
117     bool mError = false;
118     Status mLastStatus = UNINITIALIZED;
119     mutable std::vector<Status> mStatusesHit;
120     mutable Mutex mLock;
121     mutable Condition mStatusCondition;
122 
123    public:
CameraDeviceCallbacks()124     CameraDeviceCallbacks() {}
125 
~CameraDeviceCallbacks()126     virtual ~CameraDeviceCallbacks() {}
127 
onDeviceError(ErrorCode errorCode,const CaptureResultExtras & resultExtras)128     virtual Return<void> onDeviceError(ErrorCode errorCode,
129                                        const CaptureResultExtras& resultExtras) override {
130         (void)resultExtras;
131         ALOGE("%s: onDeviceError occurred with: %d", __FUNCTION__, static_cast<int>(errorCode));
132         Mutex::Autolock l(mLock);
133         mError = true;
134         mLastStatus = ERROR;
135         mStatusesHit.push_back(mLastStatus);
136         mStatusCondition.broadcast();
137         return Void();
138     }
139 
onDeviceIdle()140     virtual Return<void> onDeviceIdle() override {
141         Mutex::Autolock l(mLock);
142         mLastStatus = IDLE;
143         mStatusesHit.push_back(mLastStatus);
144         mStatusCondition.broadcast();
145         return Void();
146     }
147 
onCaptureStarted(const CaptureResultExtras & resultExtras,uint64_t timestamp)148     virtual Return<void> onCaptureStarted(const CaptureResultExtras& resultExtras,
149                                           uint64_t timestamp) override {
150         (void)resultExtras;
151         (void)timestamp;
152         Mutex::Autolock l(mLock);
153         mLastStatus = RUNNING;
154         mStatusesHit.push_back(mLastStatus);
155         mStatusCondition.broadcast();
156         return Void();
157     }
158 
onResultReceived(const FmqSizeOrMetadata & sizeOrMetadata,const CaptureResultExtras & resultExtras,const hidl_vec<PhysicalCaptureResultInfo> & physicalResultInfos)159     virtual Return<void> onResultReceived(
160         const FmqSizeOrMetadata& sizeOrMetadata, const CaptureResultExtras& resultExtras,
161         const hidl_vec<PhysicalCaptureResultInfo>& physicalResultInfos) override {
162         (void)sizeOrMetadata;
163         (void)resultExtras;
164         (void)physicalResultInfos;
165         Mutex::Autolock l(mLock);
166         mLastStatus = RESULT_RECEIVED;
167         mStatusesHit.push_back(mLastStatus);
168         mStatusCondition.broadcast();
169         return Void();
170     }
171 
onRepeatingRequestError(uint64_t lastFrameNumber,int32_t stoppedSequenceId)172     virtual Return<void> onRepeatingRequestError(uint64_t lastFrameNumber,
173                                                  int32_t stoppedSequenceId) override {
174         (void)lastFrameNumber;
175         (void)stoppedSequenceId;
176         Mutex::Autolock l(mLock);
177         mLastStatus = REPEATING_REQUEST_ERROR;
178         mStatusesHit.push_back(mLastStatus);
179         mStatusCondition.broadcast();
180         return Void();
181     }
182 
183     // Test helper functions:
184 
hadError() const185     bool hadError() const {
186         Mutex::Autolock l(mLock);
187         return mError;
188     }
waitForStatus(Status status) const189     bool waitForStatus(Status status) const {
190         Mutex::Autolock l(mLock);
191         if (mLastStatus == status) {
192             return true;
193         }
194 
195         while (std::find(mStatusesHit.begin(), mStatusesHit.end(), status) == mStatusesHit.end()) {
196             if (mStatusCondition.waitRelative(mLock, IDLE_TIMEOUT) != android::OK) {
197                 mStatusesHit.clear();
198                 return false;
199             }
200         }
201         mStatusesHit.clear();
202 
203         return true;
204     }
205 
clearStatus() const206     void clearStatus() const {
207         Mutex::Autolock l(mLock);
208         mStatusesHit.clear();
209     }
210 
waitForIdle() const211     bool waitForIdle() const { return waitForStatus(IDLE); }
212 };
213 
convertFromHidlCloned(const hidl_vec<uint8_t> & metadata,CameraMetadata * rawMetadata)214 static bool convertFromHidlCloned(const hidl_vec<uint8_t>& metadata, CameraMetadata* rawMetadata) {
215     const camera_metadata* buffer = (camera_metadata_t*)(metadata.data());
216     size_t expectedSize = metadata.size();
217     int ret = validate_camera_metadata_structure(buffer, &expectedSize);
218     if (ret == OK || ret == CAMERA_METADATA_VALIDATION_SHIFTED) {
219         *rawMetadata = buffer;
220     } else {
221         ALOGE("%s: Malformed camera metadata received from caller", __FUNCTION__);
222         return false;
223     }
224     return true;
225 }
226 
227 struct StreamConfiguration {
228     int32_t width = -1;
229     int32_t height = -1;
230 };
231 
232 class VtsHalCameraServiceV2_0TargetTest : public ::testing::TestWithParam<std::string> {
233    public:
SetUp()234     void SetUp() override {
235         cs = ICameraService::getService(GetParam());
236     }
237 
TearDown()238     void TearDown() override {}
239     // creates an outputConfiguration with no deferred streams
createOutputConfiguration(const std::vector<native_handle_t * > & nhs)240     OutputConfiguration createOutputConfiguration(const std::vector<native_handle_t*>& nhs) {
241         OutputConfiguration output;
242         output.rotation = OutputConfiguration::Rotation::R0;
243         output.windowGroupId = -1;
244         output.windowHandles.resize(nhs.size());
245         output.width = 0;
246         output.height = 0;
247         output.isDeferred = false;
248         for (size_t i = 0; i < nhs.size(); i++) {
249             output.windowHandles[i] = nhs[i];
250         }
251         return output;
252     }
253 
initializeCaptureRequestPartial(CaptureRequest * captureRequest,int32_t streamId,const hidl_string & cameraId,size_t settingsSize)254     void initializeCaptureRequestPartial(CaptureRequest* captureRequest, int32_t streamId,
255                                          const hidl_string& cameraId, size_t settingsSize) {
256         captureRequest->physicalCameraSettings.resize(1);
257         captureRequest->physicalCameraSettings[0].id = cameraId;
258         captureRequest->streamAndWindowIds.resize(1);
259         captureRequest->streamAndWindowIds[0].streamId = streamId;
260         captureRequest->streamAndWindowIds[0].windowId = 0;
261         // Write the settings metadata into the fmq.
262         captureRequest->physicalCameraSettings[0].settings.fmqMetadataSize(settingsSize);
263     }
264 
doesCapabilityExist(const CameraMetadata & characteristics,int capability)265     bool doesCapabilityExist(const CameraMetadata& characteristics, int capability) {
266         camera_metadata_ro_entry rawEntry =
267             characteristics.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
268         EXPECT_TRUE(rawEntry.count > 0);
269         for (size_t i = 0; i < rawEntry.count; i++) {
270             if (rawEntry.data.u8[i] == capability) {
271                 return true;
272             }
273         }
274         return false;
275     }
276 
277     // Return the first advertised available depth stream sizes
getDepthStreamConfiguration(const CameraMetadata & characteristics)278     StreamConfiguration getDepthStreamConfiguration(const CameraMetadata& characteristics) {
279         camera_metadata_ro_entry rawEntry =
280             characteristics.find(ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS);
281         StreamConfiguration streamConfig;
282         const size_t STREAM_FORMAT_OFFSET = 0;
283         const size_t STREAM_WIDTH_OFFSET = 1;
284         const size_t STREAM_HEIGHT_OFFSET = 2;
285         const size_t STREAM_INOUT_OFFSET = 3;
286         const size_t STREAM_CONFIG_SIZE = 4;
287         if (rawEntry.count < STREAM_CONFIG_SIZE) {
288             return streamConfig;
289         }
290         EXPECT_TRUE((rawEntry.count % STREAM_CONFIG_SIZE) == 0);
291         for (size_t i = 0; i < rawEntry.count; i += STREAM_CONFIG_SIZE) {
292             int32_t format = rawEntry.data.i32[i + STREAM_FORMAT_OFFSET];
293             int32_t use = rawEntry.data.i32[i + STREAM_INOUT_OFFSET];
294             if (format == HAL_PIXEL_FORMAT_Y16 &&
295                 use == ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS_OUTPUT) {
296                 streamConfig.width = rawEntry.data.i32[i + STREAM_WIDTH_OFFSET];
297                 streamConfig.height = rawEntry.data.i32[i + STREAM_HEIGHT_OFFSET];
298                 return streamConfig;
299             }
300         }
301         return streamConfig;
302     }
303 
304     sp<ICameraService> cs = nullptr;
305 };
306 
307 // Basic HIDL calls for ICameraService
TEST_P(VtsHalCameraServiceV2_0TargetTest,BasicCameraLifeCycleTest)308 TEST_P(VtsHalCameraServiceV2_0TargetTest, BasicCameraLifeCycleTest) {
309     sp<CameraServiceListener> listener(new CameraServiceListener());
310     hidl_vec<CameraStatusAndId> cameraStatuses{};
311     Status status = Status::NO_ERROR;
312     auto remoteRet =
313         cs->addListener(listener, [&status, &cameraStatuses](Status s, auto& retStatuses) {
314             status = s;
315             cameraStatuses = retStatuses;
316         });
317     EXPECT_TRUE(remoteRet.isOk() && status == Status::NO_ERROR);
318     for (const auto& it : cameraStatuses) {
319         CameraMetadata rawMetadata;
320         listener->onStatusChanged(it);
321         if (it.deviceStatus != CameraDeviceStatus::STATUS_PRESENT) {
322             continue;
323         }
324         remoteRet = cs->getCameraCharacteristics(
325             it.cameraId, [&status, &rawMetadata](auto s, const hidl_vec<uint8_t>& metadata) {
326                 status = s;
327                 bool cStatus = convertFromHidlCloned(metadata, &rawMetadata);
328                 EXPECT_TRUE(cStatus);
329             });
330         EXPECT_TRUE(remoteRet.isOk() && status == Status::NO_ERROR);
331         EXPECT_FALSE(rawMetadata.isEmpty());
332         sp<CameraDeviceCallbacks> callbacks(new CameraDeviceCallbacks());
333         sp<ICameraDeviceUser> deviceRemote = nullptr;
334         remoteRet = cs->connectDevice(callbacks, it.cameraId,
335                                       [&status, &deviceRemote](auto s, auto& device) {
336                                           status = s;
337                                           deviceRemote = device;
338                                       });
339         EXPECT_TRUE(remoteRet.isOk() && status == Status::NO_ERROR);
340         EXPECT_TRUE(deviceRemote != nullptr);
341 
342         std::shared_ptr<RequestMetadataQueue> requestMQ = nullptr;
343         remoteRet = deviceRemote->getCaptureRequestMetadataQueue([&requestMQ](const auto& mqD) {
344             requestMQ = std::make_shared<RequestMetadataQueue>(mqD);
345             EXPECT_TRUE(requestMQ->isValid() && (requestMQ->availableToWrite() >= 0));
346         });
347         EXPECT_TRUE(remoteRet.isOk());
348         AImageReader* reader = nullptr;
349         bool isDepthOnlyDevice =
350             !doesCapabilityExist(rawMetadata,
351                                  ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE) &&
352             doesCapabilityExist(rawMetadata, ANDROID_REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT);
353         int chosenImageFormat = AIMAGE_FORMAT_YUV_420_888;
354         int chosenImageWidth = kVGAImageWidth;
355         int chosenImageHeight = kVGAImageHeight;
356         if (isDepthOnlyDevice) {
357             StreamConfiguration depthStreamConfig = getDepthStreamConfiguration(rawMetadata);
358             EXPECT_TRUE(depthStreamConfig.width != -1);
359             EXPECT_TRUE(depthStreamConfig.height != -1);
360             chosenImageFormat = AIMAGE_FORMAT_DEPTH16;
361             chosenImageWidth = depthStreamConfig.width;
362             chosenImageHeight = depthStreamConfig.height;
363         }
364 
365         auto mStatus = AImageReader_new(chosenImageWidth, chosenImageHeight, chosenImageFormat,
366                                         kCaptureRequestCount, &reader);
367         EXPECT_EQ(mStatus, AMEDIA_OK);
368         native_handle_t* wh = nullptr;
369         mStatus = AImageReader_getWindowNativeHandle(reader, &wh);
370         EXPECT_TRUE(mStatus == AMEDIA_OK && wh != nullptr);
371         OutputConfiguration output = createOutputConfiguration({wh});
372         Return<Status> ret = deviceRemote->beginConfigure();
373         EXPECT_TRUE(ret.isOk() && ret == Status::NO_ERROR);
374         int32_t streamId = -1;
375         remoteRet = deviceRemote->createStream(output, [&status, &streamId](Status s, auto sId) {
376             status = s;
377             streamId = sId;
378         });
379         EXPECT_TRUE(remoteRet.isOk() && status == Status::NO_ERROR);
380         EXPECT_TRUE(streamId >= 0);
381         hidl_vec<uint8_t> hidlParams;
382         ret = deviceRemote->endConfigure(StreamConfigurationMode::NORMAL_MODE, hidlParams);
383         EXPECT_TRUE(ret.isOk() && ret == Status::NO_ERROR);
384         hidl_vec<uint8_t> settingsMetadata;
385         remoteRet = deviceRemote->createDefaultRequest(
386             TemplateId::PREVIEW, [&status, &settingsMetadata](auto s, const hidl_vec<uint8_t> m) {
387                 status = s;
388                 settingsMetadata = m;
389             });
390         EXPECT_TRUE(remoteRet.isOk() && status == Status::NO_ERROR);
391         EXPECT_GE(settingsMetadata.size(), 0);
392         hidl_vec<CaptureRequest> captureRequests;
393         captureRequests.resize(kNumRequests);
394         for (int i = 0; i < kNumRequests; i++) {
395             CaptureRequest& captureRequest = captureRequests[i];
396             initializeCaptureRequestPartial(&captureRequest, streamId, it.cameraId,
397                                             settingsMetadata.size());
398             // Write the settings metadata into the fmq.
399             bool written = requestMQ->write(settingsMetadata.data(), settingsMetadata.size());
400             EXPECT_TRUE(written);
401         }
402         SubmitInfo info;
403 
404         // Test a single capture
405         remoteRet = deviceRemote->submitRequestList(captureRequests, false,
406                                                     [&status, &info](auto s, auto& submitInfo) {
407                                                         status = s;
408                                                         info = submitInfo;
409                                                     });
410         EXPECT_TRUE(remoteRet.isOk() && status == Status::NO_ERROR);
411         EXPECT_GE(info.requestId, 0);
412         EXPECT_TRUE(callbacks->waitForStatus(CameraDeviceCallbacks::Status::RESULT_RECEIVED));
413         EXPECT_TRUE(callbacks->waitForIdle());
414 
415         // Test repeating requests
416         CaptureRequest captureRequest;
417 
418         initializeCaptureRequestPartial(&captureRequest, streamId, it.cameraId,
419                                         settingsMetadata.size());
420 
421         bool written = requestMQ->write(settingsMetadata.data(), settingsMetadata.size());
422         EXPECT_TRUE(written);
423 
424         remoteRet = deviceRemote->submitRequestList({captureRequest}, true,
425                                                     [&status, &info](auto s, auto& submitInfo) {
426                                                         status = s;
427                                                         info = submitInfo;
428                                                     });
429         EXPECT_TRUE(callbacks->waitForStatus(CameraDeviceCallbacks::Status::RESULT_RECEIVED));
430         int64_t lastFrameNumber = -1;
431         remoteRet =
432             deviceRemote->cancelRepeatingRequest([&status, &lastFrameNumber](auto s, int64_t lf) {
433                 status = s;
434                 lastFrameNumber = lf;
435             });
436         EXPECT_TRUE(remoteRet.isOk() && status == Status::NO_ERROR);
437         EXPECT_GE(lastFrameNumber, 0);
438 
439         // Test waitUntilIdle()
440         auto statusRet = deviceRemote->waitUntilIdle();
441         EXPECT_TRUE(statusRet.isOk() && statusRet == Status::NO_ERROR);
442 
443         // Test deleteStream()
444         statusRet = deviceRemote->deleteStream(streamId);
445         EXPECT_TRUE(statusRet.isOk() && statusRet == Status::NO_ERROR);
446 
447         remoteRet = deviceRemote->disconnect();
448         EXPECT_TRUE(remoteRet.isOk());
449     }
450     Return<Status> ret = cs->removeListener(listener);
451     EXPECT_TRUE(ret.isOk() && ret == Status::NO_ERROR);
452 }
453 
454 INSTANTIATE_TEST_SUITE_P(
455         PerInstance, VtsHalCameraServiceV2_0TargetTest,
456         testing::ValuesIn(android::hardware::getAllHalInstanceNames(ICameraService::descriptor)),
457         android::hardware::PrintInstanceNameToString);
458 }  // namespace android
459