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 "CameraProviderTests"
18 #include <log/log.h>
19
20 #include <camera_provider.h>
21 #include <gtest/gtest.h>
22
23 #include "mock_provider_hwl.h"
24
25 namespace android {
26 namespace google_camera_hal {
27
28 class CameraProviderTest : public ::testing::Test {
29 protected:
CreateCameraProviderAndCheck(std::unique_ptr<MockProviderHwl> mock_provider_hwl=nullptr)30 void CreateCameraProviderAndCheck(
31 std::unique_ptr<MockProviderHwl> mock_provider_hwl = nullptr) {
32 if (mock_provider_hwl == nullptr) {
33 mock_provider_hwl = MockProviderHwl::Create();
34 }
35
36 DestroyCameraProvider();
37 provider_ = CameraProvider::Create(std::move(mock_provider_hwl));
38 ASSERT_NE(provider_, nullptr) << "Creating a CameraProvider failed.";
39 }
40
DestroyCameraProvider()41 void DestroyCameraProvider() {
42 provider_ = nullptr;
43 }
44
45 std::unique_ptr<CameraProvider> provider_;
46 };
47
TEST_F(CameraProviderTest,Create)48 TEST_F(CameraProviderTest, Create) {
49 CreateCameraProviderAndCheck();
50 }
51
TEST_F(CameraProviderTest,SetCallback)52 TEST_F(CameraProviderTest, SetCallback) {
53 CameraDeviceStatus device_status = CameraDeviceStatus::kNotPresent;
54 TorchModeStatus torch_status = TorchModeStatus::kAvailableOff;
55 CameraProviderCallback callback = {
56 .camera_device_status_change =
57 [&device_status](std::string /*camera_id*/,
58 CameraDeviceStatus new_status) {
59 device_status = new_status;
60 },
61 .torch_mode_status_change =
62 [&torch_status](std::string /*camera_id*/, TorchModeStatus new_status) {
63 torch_status = new_status;
64 },
65 };
66
67 static const std::vector<CameraDeviceStatus> kMockCameraDeviceStatus = {
68 CameraDeviceStatus::kNotPresent, CameraDeviceStatus::kPresent,
69 CameraDeviceStatus::kEnumerating};
70
71 // Verify the mock device status is same as set from callback.
72 for (auto mock_device_status : kMockCameraDeviceStatus) {
73 auto mock_provider_hwl = MockProviderHwl::Create();
74 mock_provider_hwl->camera_device_status_ = mock_device_status;
75
76 CreateCameraProviderAndCheck(std::move(mock_provider_hwl));
77
78 status_t res = provider_->SetCallback(&callback);
79 ASSERT_EQ(res, OK) << "Setting callback failed: " << strerror(res);
80
81 EXPECT_EQ(device_status, mock_device_status);
82 }
83
84 static const std::vector<TorchModeStatus> kMockTorchModeStatus = {
85 TorchModeStatus::kNotAvailable, TorchModeStatus::kAvailableOff,
86 TorchModeStatus::kAvailableOn};
87
88 // Verify the mock torch mode status is same as set from callback.
89 for (auto mock_torch_status : kMockTorchModeStatus) {
90 auto mock_provider_hwl = MockProviderHwl::Create();
91 mock_provider_hwl->torch_status_ = mock_torch_status;
92
93 CreateCameraProviderAndCheck(std::move(mock_provider_hwl));
94
95 status_t res = provider_->SetCallback(&callback);
96 ASSERT_EQ(res, OK) << "Setting callback failed: " << strerror(res);
97
98 EXPECT_EQ(torch_status, mock_torch_status);
99 }
100 }
101
102 // Test if camera provider passes all vendor tags specified in HWL.
TEST_F(CameraProviderTest,GetVendorTags)103 TEST_F(CameraProviderTest, GetVendorTags) {
104 static const uint32_t kMockTagIdOffset = 0x80000000;
105 static const std::vector<VendorTagSection> kMockVendorTagSections = {
106 {
107 .section_name = "vendor.section_0",
108 .tags =
109 {
110 {
111 .tag_id = kMockTagIdOffset + 0,
112 .tag_name = "tag0",
113 .tag_type = CameraMetadataType::kByte,
114 },
115 {
116 .tag_id = kMockTagIdOffset + 1,
117 .tag_name = "tag1",
118 .tag_type = CameraMetadataType::kInt32,
119 },
120 },
121 },
122 {
123 .section_name = "vendor.section_1",
124 .tags =
125 {
126 {
127 .tag_id = kMockTagIdOffset + 2,
128 .tag_name = "tag2",
129 .tag_type = CameraMetadataType::kFloat,
130 },
131 {
132 .tag_id = kMockTagIdOffset + 3,
133 .tag_name = "tag3",
134 .tag_type = CameraMetadataType::kInt64,
135 },
136 {
137 .tag_id = kMockTagIdOffset + 4,
138 .tag_name = "tag4",
139 .tag_type = CameraMetadataType::kRational,
140 },
141 },
142 },
143 };
144
145 auto mock_provider_hwl = MockProviderHwl::Create();
146 mock_provider_hwl->vendor_tag_sections_ = kMockVendorTagSections;
147
148 CreateCameraProviderAndCheck(std::move(mock_provider_hwl));
149
150 // Verify GetVendorTags(nullptr) returns an error.
151 EXPECT_NE(provider_->GetVendorTags(nullptr), OK);
152
153 std::vector<VendorTagSection> sections;
154 status_t res = provider_->GetVendorTags(§ions);
155 ASSERT_EQ(res, OK) << "Getting vendor tags failed: " << strerror(res);
156
157 // Verify the mock sections are included in the returned sections.
158 for (auto mock_section : kMockVendorTagSections) {
159 bool found_section = false;
160
161 for (auto returned_section : sections) {
162 if (returned_section.section_name == mock_section.section_name) {
163 found_section = true;
164
165 // Verify the mock tags are included in the returned tags.
166 for (auto mock_tag : mock_section.tags) {
167 bool found_tag = false;
168 for (auto returned_tag : returned_section.tags) {
169 if (returned_tag.tag_id == mock_tag.tag_id) {
170 found_tag = true;
171 EXPECT_EQ(returned_tag.tag_name, mock_tag.tag_name);
172 EXPECT_EQ(returned_tag.tag_type, mock_tag.tag_type);
173 break;
174 }
175 }
176 EXPECT_EQ(found_tag, true)
177 << "Mock tag " << std::to_string(mock_tag.tag_id)
178 << " in section " << mock_section.section_name << " is not found";
179 }
180 break;
181 }
182 }
183
184 EXPECT_EQ(found_section, true)
185 << "Mock section " << mock_section.section_name << " is not found";
186 }
187 }
188
189 // Test if GetCameraIdList() returns the right number of camera IDs visible
190 // to framework.
TEST_F(CameraProviderTest,GetCameraIdList)191 TEST_F(CameraProviderTest, GetCameraIdList) {
192 static const std::vector<CameraIdMap> id_maps = {
193 {
194 .id = 0,
195 .visible_to_framework = true,
196 },
197 {
198 .id = 1,
199 .visible_to_framework = false,
200 },
201 {
202 .id = 2,
203 .visible_to_framework = true,
204 },
205 };
206
207 // Calculate the number of public cameras.
208 uint32_t num_public_cameras = 0;
209 for (auto id_map : id_maps) {
210 if (id_map.visible_to_framework) {
211 num_public_cameras++;
212 }
213 }
214
215 auto mock_provider_hwl = MockProviderHwl::Create();
216 mock_provider_hwl->cameras_ = id_maps;
217
218 CreateCameraProviderAndCheck(std::move(mock_provider_hwl));
219
220 // Verify GetCameraIdList(nullptr) returns an error.
221 EXPECT_NE(provider_->GetCameraIdList(nullptr), OK);
222
223 std::vector<uint32_t> camera_ids;
224 status_t res = provider_->GetCameraIdList(&camera_ids);
225 ASSERT_EQ(res, OK) << "Getting camera IDs failed: " << strerror(res);
226
227 // Verify the returned number of public cameras.
228 EXPECT_EQ(camera_ids.size(), num_public_cameras);
229 }
230
231 // Test if IsSetTorchModeSupported() returns the same value that mock HWL
232 // returns.
TEST_F(CameraProviderTest,IsSetTorchModeSupported)233 TEST_F(CameraProviderTest, IsSetTorchModeSupported) {
234 static const bool kIsTorchSupported[] = {true, false};
235
236 for (auto is_torch_supported : kIsTorchSupported) {
237 auto mock_provider_hwl = MockProviderHwl::Create();
238 mock_provider_hwl->is_torch_supported_ = is_torch_supported;
239 CreateCameraProviderAndCheck(std::move(mock_provider_hwl));
240
241 EXPECT_EQ(provider_->IsSetTorchModeSupported(), is_torch_supported);
242 DestroyCameraProvider();
243 }
244 }
245
TEST_F(CameraProviderTest,CreateCameraDevice)246 TEST_F(CameraProviderTest, CreateCameraDevice) {
247 CreateCameraProviderAndCheck();
248
249 std::vector<uint32_t> camera_ids;
250 status_t res = provider_->GetCameraIdList(&camera_ids);
251 ASSERT_EQ(res, OK) << "Getting camera IDs failed: " << strerror(res);
252
253 for (auto camera_id : camera_ids) {
254 std::unique_ptr<CameraDevice> device;
255 provider_->CreateCameraDevice(camera_id, &device);
256 EXPECT_NE(device, nullptr)
257 << "Creating a CameraDevice for ID " << camera_id << " failed.";
258 }
259 }
260
261 } // namespace google_camera_hal
262 } // namespace android
263