1/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_NDEBUG 0
18#define LOG_TAG "CameraProviderManagerTest"
19
20#include "../common/CameraProviderManager.h"
21#include <android/hidl/manager/1.0/IServiceManager.h>
22#include <android/hidl/manager/1.0/IServiceNotification.h>
23#include <android/hardware/camera/device/3.2/ICameraDeviceCallback.h>
24#include <android/hardware/camera/device/3.2/ICameraDeviceSession.h>
25#include <camera_metadata_hidden.h>
26#include <gtest/gtest.h>
27
28using namespace android;
29using namespace android::hardware::camera;
30using android::hardware::camera::common::V1_0::Status;
31using android::hardware::camera::common::V1_0::VendorTag;
32using android::hardware::camera::common::V1_0::VendorTagSection;
33using android::hardware::camera::common::V1_0::CameraMetadataType;
34using android::hardware::camera::device::V3_2::ICameraDeviceCallback;
35using android::hardware::camera::device::V3_2::ICameraDeviceSession;
36
37/**
38 * Basic test implementation of a camera ver. 3.2 device interface
39 */
40struct TestDeviceInterface : public device::V3_2::ICameraDevice {
41    std::vector<hardware::hidl_string> mDeviceNames;
42    TestDeviceInterface(std::vector<hardware::hidl_string> deviceNames) :
43        mDeviceNames(deviceNames) {}
44    using getResourceCost_cb = std::function<void(
45            hardware::camera::common::V1_0::Status status,
46            const hardware::camera::common::V1_0::CameraResourceCost& resourceCost)>;
47    virtual ::android::hardware::Return<void> getResourceCost(
48            getResourceCost_cb _hidl_cb) override {
49        hardware::camera::common::V1_0::CameraResourceCost resourceCost = {100,
50                mDeviceNames};
51        _hidl_cb(Status::OK, resourceCost);
52        return hardware::Void();
53    }
54
55    using getCameraCharacteristics_cb = std::function<void(
56            hardware::camera::common::V1_0::Status status,
57            const hardware::hidl_vec<uint8_t>& cameraCharacteristics)>;
58    hardware::Return<void> getCameraCharacteristics(
59            getCameraCharacteristics_cb _hidl_cb) override {
60        hardware::hidl_vec<uint8_t> cameraCharacteristics;
61        _hidl_cb(Status::OK, cameraCharacteristics);
62        return hardware::Void();
63    }
64
65    hardware::Return<hardware::camera::common::V1_0::Status> setTorchMode(
66            ::android::hardware::camera::common::V1_0::TorchMode) override {
67        return Status::OK;
68    }
69
70    using open_cb = std::function<void(
71            ::android::hardware::camera::common::V1_0::Status status,
72             const ::android::sp<ICameraDeviceSession>& session)>;
73    hardware::Return<void> open(
74            const ::android::sp<ICameraDeviceCallback>&,
75            open_cb _hidl_cb) override {
76        sp<ICameraDeviceSession> deviceSession = nullptr;
77        _hidl_cb(Status::OK, deviceSession);
78        return hardware::Void();
79    }
80
81    hardware::Return<void> dumpState(
82            const ::android::hardware::hidl_handle&) override {
83        return hardware::Void();
84    }
85};
86
87/**
88 * Basic test implementation of a camera provider
89 */
90struct TestICameraProvider : virtual public provider::V2_4::ICameraProvider {
91    sp<provider::V2_4::ICameraProviderCallback> mCallbacks;
92    std::vector<hardware::hidl_string> mDeviceNames;
93    sp<device::V3_2::ICameraDevice> mDeviceInterface;
94    hardware::hidl_vec<common::V1_0::VendorTagSection> mVendorTagSections;
95
96    TestICameraProvider(const std::vector<hardware::hidl_string> &devices,
97            const hardware::hidl_vec<common::V1_0::VendorTagSection> &vendorSection) :
98        mDeviceNames(devices),
99        mDeviceInterface(new TestDeviceInterface(devices)),
100        mVendorTagSections (vendorSection) {}
101
102    virtual hardware::Return<Status> setCallback(
103            const sp<provider::V2_4::ICameraProviderCallback>& callbacks) override {
104        mCallbacks = callbacks;
105        return hardware::Return<Status>(Status::OK);
106    }
107
108    using getVendorTags_cb = std::function<void(Status status,
109            const hardware::hidl_vec<common::V1_0::VendorTagSection>& sections)>;
110    hardware::Return<void> getVendorTags(getVendorTags_cb _hidl_cb) override {
111        _hidl_cb(Status::OK, mVendorTagSections);
112        return hardware::Void();
113    }
114
115    using isSetTorchModeSupported_cb = std::function<void(
116            ::android::hardware::camera::common::V1_0::Status status,
117             bool support)>;
118    virtual ::hardware::Return<void> isSetTorchModeSupported(
119            isSetTorchModeSupported_cb _hidl_cb) override {
120        _hidl_cb(Status::OK, false);
121        return hardware::Void();
122    }
123
124    using getCameraIdList_cb = std::function<void(Status status,
125            const hardware::hidl_vec<hardware::hidl_string>& cameraDeviceNames)>;
126    virtual hardware::Return<void> getCameraIdList(getCameraIdList_cb _hidl_cb) override {
127        _hidl_cb(Status::OK, mDeviceNames);
128        return hardware::Void();
129    }
130
131    using getCameraDeviceInterface_V1_x_cb = std::function<void(Status status,
132            const sp<device::V1_0::ICameraDevice>& device)>;
133    virtual hardware::Return<void> getCameraDeviceInterface_V1_x(
134            const hardware::hidl_string& cameraDeviceName,
135            getCameraDeviceInterface_V1_x_cb _hidl_cb) override {
136        (void) cameraDeviceName;
137        _hidl_cb(Status::OK, nullptr); //TODO: impl. of ver. 1.0 device interface
138                                       //      otherwise enumeration will fail.
139        return hardware::Void();
140    }
141
142    using getCameraDeviceInterface_V3_x_cb = std::function<void(Status status,
143            const sp<device::V3_2::ICameraDevice>& device)>;
144    virtual hardware::Return<void> getCameraDeviceInterface_V3_x(
145            const hardware::hidl_string&,
146            getCameraDeviceInterface_V3_x_cb _hidl_cb) override {
147        _hidl_cb(Status::OK, mDeviceInterface);
148        return hardware::Void();
149    }
150
151};
152
153/**
154 * Simple test version of the interaction proxy, to use to inject onRegistered calls to the
155 * CameraProviderManager
156 */
157struct TestInteractionProxy : public CameraProviderManager::ServiceInteractionProxy {
158    sp<hidl::manager::V1_0::IServiceNotification> mManagerNotificationInterface;
159    sp<TestICameraProvider> mTestCameraProvider;
160
161    TestInteractionProxy() {}
162    void setProvider(sp<TestICameraProvider> provider) {
163        mTestCameraProvider = provider;
164    }
165
166    std::string mLastRequestedServiceName;
167
168    virtual ~TestInteractionProxy() {}
169
170    virtual bool registerForNotifications(
171            const std::string &serviceName,
172            const sp<hidl::manager::V1_0::IServiceNotification> &notification) override {
173        (void) serviceName;
174        mManagerNotificationInterface = notification;
175        return true;
176    }
177
178    virtual sp<hardware::camera::provider::V2_4::ICameraProvider> getService(
179            const std::string &serviceName) override {
180        mLastRequestedServiceName = serviceName;
181        return mTestCameraProvider;
182    }
183
184};
185
186struct TestStatusListener : public CameraProviderManager::StatusListener {
187    ~TestStatusListener() {}
188
189    void onDeviceStatusChanged(const String8 &,
190            hardware::camera::common::V1_0::CameraDeviceStatus) override {}
191    void onTorchStatusChanged(const String8 &,
192            hardware::camera::common::V1_0::TorchModeStatus) override {}
193};
194
195TEST(CameraProviderManagerTest, InitializeTest) {
196    std::vector<hardware::hidl_string> deviceNames;
197    deviceNames.push_back("device@3.2/test/0");
198    deviceNames.push_back("device@1.0/test/0");
199    deviceNames.push_back("device@3.2/test/1");
200    hardware::hidl_vec<common::V1_0::VendorTagSection> vendorSection;
201    status_t res;
202    sp<CameraProviderManager> providerManager = new CameraProviderManager();
203    sp<TestStatusListener> statusListener = new TestStatusListener();
204    TestInteractionProxy serviceProxy;
205    sp<TestICameraProvider> provider =  new TestICameraProvider(deviceNames,
206            vendorSection);
207    serviceProxy.setProvider(provider);
208
209    res = providerManager->initialize(statusListener, &serviceProxy);
210    ASSERT_EQ(res, OK) << "Unable to initialize provider manager";
211
212    hardware::hidl_string legacyInstanceName = "legacy/0";
213    ASSERT_EQ(serviceProxy.mLastRequestedServiceName, legacyInstanceName) <<
214            "Legacy instance not requested from service manager";
215
216    hardware::hidl_string testProviderFqInterfaceName =
217            "android.hardware.camera.provider@2.4::ICameraProvider";
218    hardware::hidl_string testProviderInstanceName = "test/0";
219    serviceProxy.mManagerNotificationInterface->onRegistration(
220            testProviderFqInterfaceName,
221            testProviderInstanceName, false);
222
223    ASSERT_EQ(serviceProxy.mLastRequestedServiceName, testProviderInstanceName) <<
224            "Incorrect instance requested from service manager";
225}
226
227TEST(CameraProviderManagerTest, MultipleVendorTagTest) {
228    hardware::hidl_string sectionName = "VendorTestSection";
229    hardware::hidl_string tagName = "VendorTestTag";
230    uint32_t tagId = VENDOR_SECTION << 16;
231    hardware::hidl_vec<common::V1_0::VendorTagSection> vendorSection;
232    CameraMetadataType tagType = CameraMetadataType::BYTE;
233    vendorSection.resize(1);
234    vendorSection[0].sectionName = sectionName;
235    vendorSection[0].tags.resize(1);
236    vendorSection[0].tags[0].tagId = tagId;
237    vendorSection[0].tags[0].tagName = tagName;
238    vendorSection[0].tags[0].tagType = tagType;
239    std::vector<hardware::hidl_string> deviceNames = {"device@3.2/test/0"};
240
241    sp<CameraProviderManager> providerManager = new CameraProviderManager();
242    sp<TestStatusListener> statusListener = new TestStatusListener();
243    TestInteractionProxy serviceProxy;
244
245    sp<TestICameraProvider> provider =  new TestICameraProvider(deviceNames,
246            vendorSection);
247    serviceProxy.setProvider(provider);
248
249    auto res = providerManager->initialize(statusListener, &serviceProxy);
250    ASSERT_EQ(res, OK) << "Unable to initialize provider manager";
251
252    hardware::hidl_string testProviderInstanceName = "test/0";
253    hardware::hidl_string testProviderFqInterfaceName =
254            "android.hardware.camera.provider@2.4::ICameraProvider";
255    serviceProxy.mManagerNotificationInterface->onRegistration(
256            testProviderFqInterfaceName, testProviderInstanceName, false);
257    ASSERT_EQ(serviceProxy.mLastRequestedServiceName, testProviderInstanceName) <<
258            "Incorrect instance requested from service manager";
259
260    hardware::hidl_string sectionNameSecond = "SecondVendorTestSection";
261    hardware::hidl_string secondTagName = "SecondVendorTestTag";
262    CameraMetadataType secondTagType = CameraMetadataType::DOUBLE;
263    vendorSection[0].sectionName = sectionNameSecond;
264    vendorSection[0].tags[0].tagId = tagId;
265    vendorSection[0].tags[0].tagName = secondTagName;
266    vendorSection[0].tags[0].tagType = secondTagType;
267    deviceNames = {"device@3.2/test2/1"};
268
269    sp<TestICameraProvider> secondProvider =  new TestICameraProvider(
270            deviceNames, vendorSection);
271    serviceProxy.setProvider(secondProvider);
272    hardware::hidl_string testProviderSecondInstanceName = "test2/0";
273    serviceProxy.mManagerNotificationInterface->onRegistration(
274            testProviderFqInterfaceName, testProviderSecondInstanceName, false);
275    ASSERT_EQ(serviceProxy.mLastRequestedServiceName,
276              testProviderSecondInstanceName) <<
277            "Incorrect instance requested from service manager";
278
279    ASSERT_EQ(NO_ERROR , providerManager->setUpVendorTags());
280    sp<VendorTagDescriptorCache> vendorCache =
281            VendorTagDescriptorCache::getGlobalVendorTagCache();
282    ASSERT_NE(nullptr, vendorCache.get());
283
284    metadata_vendor_id_t vendorId = std::hash<std::string> {} (
285            testProviderInstanceName.c_str());
286    metadata_vendor_id_t vendorIdSecond = std::hash<std::string> {} (
287            testProviderSecondInstanceName.c_str());
288
289    hardware::hidl_string resultTag = vendorCache->getTagName(tagId, vendorId);
290    ASSERT_EQ(resultTag, tagName);
291
292    resultTag = vendorCache->getTagName(tagId, vendorIdSecond);
293    ASSERT_EQ(resultTag, secondTagName);
294
295    // Check whether we can create two separate CameraMetadata instances
296    // using different tag vendor vendors.
297    camera_metadata *metaBuffer = allocate_camera_metadata(10, 20);
298    ASSERT_NE(nullptr, metaBuffer);
299    set_camera_metadata_vendor_id(metaBuffer, vendorId);
300    CameraMetadata metadata(metaBuffer);
301
302    uint8_t byteVal = 10;
303    ASSERT_TRUE(metadata.isEmpty());
304    ASSERT_EQ(OK, metadata.update(tagId, &byteVal, 1));
305    ASSERT_FALSE(metadata.isEmpty());
306    ASSERT_TRUE(metadata.exists(tagId));
307
308    metaBuffer = allocate_camera_metadata(10, 20);
309    ASSERT_NE(nullptr, metaBuffer);
310    set_camera_metadata_vendor_id(metaBuffer, vendorIdSecond);
311    CameraMetadata secondMetadata(metaBuffer);
312
313    ASSERT_TRUE(secondMetadata.isEmpty());
314    double doubleVal = 1.0f;
315    ASSERT_EQ(OK, secondMetadata.update(tagId, &doubleVal, 1));
316    ASSERT_FALSE(secondMetadata.isEmpty());
317    ASSERT_TRUE(secondMetadata.exists(tagId));
318
319    // Check whether CameraMetadata copying works as expected
320    CameraMetadata metadataCopy(metadata);
321    ASSERT_FALSE(metadataCopy.isEmpty());
322    ASSERT_TRUE(metadataCopy.exists(tagId));
323    ASSERT_EQ(OK, metadataCopy.update(tagId, &byteVal, 1));
324    ASSERT_TRUE(metadataCopy.exists(tagId));
325
326    // Check whether values are as expected
327    camera_metadata_entry_t entry = metadata.find(tagId);
328    ASSERT_EQ(1u, entry.count);
329    ASSERT_EQ(byteVal, entry.data.u8[0]);
330    entry = secondMetadata.find(tagId);
331    ASSERT_EQ(1u, entry.count);
332    ASSERT_EQ(doubleVal, entry.data.d[0]);
333
334    // Swap and erase
335    secondMetadata.swap(metadataCopy);
336    ASSERT_TRUE(metadataCopy.exists(tagId));
337    ASSERT_TRUE(secondMetadata.exists(tagId));
338    ASSERT_EQ(OK, secondMetadata.erase(tagId));
339    ASSERT_TRUE(secondMetadata.isEmpty());
340    doubleVal = 0.0f;
341    ASSERT_EQ(OK, metadataCopy.update(tagId, &doubleVal, 1));
342    entry = metadataCopy.find(tagId);
343    ASSERT_EQ(1u, entry.count);
344    ASSERT_EQ(doubleVal, entry.data.d[0]);
345
346    // Append
347    uint8_t sceneMode = ANDROID_CONTROL_SCENE_MODE_ACTION;
348    secondMetadata.update(ANDROID_CONTROL_SCENE_MODE, &sceneMode, 1);
349    // Append from two different vendor tag providers is not supported!
350    ASSERT_NE(OK, metadataCopy.append(secondMetadata));
351    ASSERT_EQ(OK, metadataCopy.erase(tagId));
352    metadataCopy.update(ANDROID_CONTROL_SCENE_MODE, &sceneMode, 1);
353    // However appending from same vendor tag provider should be fine
354    ASSERT_EQ(OK, metadata.append(secondMetadata));
355    // Append from a metadata without vendor tag provider should be supported
356    CameraMetadata regularMetadata(10, 20);
357    uint8_t controlMode = ANDROID_CONTROL_MODE_AUTO;
358    regularMetadata.update(ANDROID_CONTROL_MODE, &controlMode, 1);
359    ASSERT_EQ(OK, secondMetadata.append(regularMetadata));
360    ASSERT_EQ(2u, secondMetadata.entryCount());
361    ASSERT_EQ(2u, metadata.entryCount());
362
363    // Dump
364    metadata.dump(1, 2);
365    metadataCopy.dump(1, 2);
366    secondMetadata.dump(1, 2);
367}
368