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 "CameraIDManagerTests"
18 #include <log/log.h>
19
20 #include <camera_id_manager.h>
21 #include <gtest/gtest.h>
22
23 namespace android {
24 namespace google_camera_hal {
25
TEST(CameraIdMangerTest,TestNoCameras)26 TEST(CameraIdMangerTest, TestNoCameras) {
27 auto id_manager = CameraIdManager::Create({});
28
29 EXPECT_NE(id_manager, nullptr)
30 << "Creating CameraIDManager with an empty list of cameras failed";
31 }
32
TEST(CameraIdMangerTest,InvalidLogicalCameras)33 TEST(CameraIdMangerTest, InvalidLogicalCameras) {
34 std::vector<CameraIdMap> cameras;
35 cameras.push_back(CameraIdMap({0, false, {}}));
36 cameras.push_back(CameraIdMap({1, false, {}}));
37 cameras.push_back(CameraIdMap({2, false, {0, 1}}));
38
39 // Create with a logical camera that is not visible to the framework
40 auto id_manager = CameraIdManager::Create(cameras);
41
42 EXPECT_EQ(id_manager, nullptr)
43 << "Creating CameraIDManager with a logical camera that is not visible to"
44 "the framework succeeded";
45
46 cameras.clear();
47 cameras.push_back(CameraIdMap({0, true, {0, 1}}));
48 cameras.push_back(CameraIdMap({1, false, {}}));
49
50 // Test for logical cameras that list logical cameras in their physical
51 // camera ID list
52 id_manager = CameraIdManager::Create(cameras);
53
54 EXPECT_EQ(id_manager, nullptr)
55 << "Creating CameraIDManager with a logical camera which lists a "
56 "logical camera in its physical ID list succeeded";
57
58 // Same test as above, different variation
59 cameras.clear();
60 cameras.push_back(CameraIdMap({0, true, {1, 2}}));
61 cameras.push_back(CameraIdMap({1, true, {}}));
62 cameras.push_back(CameraIdMap({2, true, {}}));
63 cameras.push_back(CameraIdMap({3, true, {0, 1}}));
64
65 id_manager = CameraIdManager::Create(cameras);
66
67 EXPECT_EQ(id_manager, nullptr)
68 << "Creating CameraIDManager with a logical camera which lists a "
69 "logical camera in its physical ID list succeeded";
70 }
71
TEST(CameraIdMangerTest,NoVisibleCameras)72 TEST(CameraIdMangerTest, NoVisibleCameras) {
73 std::vector<CameraIdMap> cameras;
74 cameras.push_back(CameraIdMap({0, false, {}}));
75 cameras.push_back(CameraIdMap({1, false, {}}));
76 cameras.push_back(CameraIdMap({2, false, {0, 1}}));
77
78 // Create with a list of cameras none of which are visible to the framework
79 auto id_manager = CameraIdManager::Create(cameras);
80
81 EXPECT_EQ(id_manager, nullptr)
82 << "Creating CameraIDManager with no visible cameras succeeded";
83 }
84
TEST(CameraIdMangerTest,InvalidParameters)85 TEST(CameraIdMangerTest, InvalidParameters) {
86 std::vector<CameraIdMap> cameras;
87 cameras.push_back(CameraIdMap({0, true, {1, 2}}));
88 cameras.push_back(CameraIdMap({1, false, {}}));
89 cameras.push_back(CameraIdMap({2, false, {}}));
90 cameras.push_back(CameraIdMap({3, false, {}}));
91 cameras.push_back(CameraIdMap({4, true, {1, 3}}));
92
93 auto id_manager = CameraIdManager::Create(cameras);
94 ASSERT_NE(id_manager, nullptr);
95
96 uint32_t dummy = 0;
97 status_t res;
98 // Test for invalid IDs or bad parameters
99 res = id_manager->GetInternalCameraId(cameras.size(), &dummy);
100 EXPECT_NE(res, OK) << "GetInternalCameraId() succeeded with an invalid ID";
101 res = id_manager->GetInternalCameraId(cameras.size(), nullptr);
102 EXPECT_NE(res, OK) << "GetInternalCameraId() succeeded with a null parameter";
103 res = id_manager->GetPublicCameraId(cameras.size(), &dummy);
104 EXPECT_NE(res, OK) << "GetPublicCameraId() succeeded with an invalid ID";
105 res = id_manager->GetPublicCameraId(cameras.size(), nullptr);
106 EXPECT_NE(res, OK) << "GetPublicCameraId() succeeded with a null parameter";
107
108 // Test for failure when IDs are not unique
109 cameras.clear();
110 cameras.push_back(CameraIdMap({0, true, {}}));
111 cameras.push_back(CameraIdMap({1, false, {}}));
112 cameras.push_back(CameraIdMap({1, true, {}}));
113
114 id_manager = CameraIdManager::Create(cameras);
115 EXPECT_EQ(id_manager, nullptr) << "Creating camera manager with duplicate"
116 "camera IDs succeeded";
117 }
118
TEST(CameraIdMangerTest,GetCameraIds)119 TEST(CameraIdMangerTest, GetCameraIds) {
120 std::vector<CameraIdMap> cameras;
121 cameras.push_back(CameraIdMap({0, true, {1, 2}}));
122 cameras.push_back(CameraIdMap({1, false, {}}));
123 cameras.push_back(CameraIdMap({2, false, {}}));
124 cameras.push_back(CameraIdMap({3, false, {}}));
125 cameras.push_back(CameraIdMap({4, true, {1, 3}}));
126
127 auto id_manager = CameraIdManager::Create(cameras);
128 ASSERT_NE(id_manager, nullptr);
129
130 status_t res;
131 uint32_t internal_id = 0;
132 uint32_t public_id = 0;
133
134 // Loop over public IDs and map public -> internal -> public to ensure
135 // we get the same ID back
136 for (uint32_t i = 0; i < cameras.size(); i++) {
137 res = id_manager->GetInternalCameraId(i, &internal_id);
138 EXPECT_EQ(res, OK);
139
140 res = id_manager->GetPublicCameraId(internal_id, &public_id);
141 EXPECT_EQ(res, OK);
142
143 EXPECT_EQ(public_id, i);
144 }
145 }
146
147 // Helper function to verify that the given CameraIdManager maps to the
148 // expected output.
149 // 'expected_internal_ids' is the expected mapping, using index as public ID
150 // and value as expected internal ID
ValidateCameraIds(CameraIdManager * id_manager,std::vector<CameraIdMap> & cameras,std::vector<uint32_t> & expected_internal_ids)151 void ValidateCameraIds(CameraIdManager* id_manager,
152 std::vector<CameraIdMap>& cameras,
153 std::vector<uint32_t>& expected_internal_ids) {
154 status_t res;
155 uint32_t internal_id;
156 uint32_t public_id;
157
158 ASSERT_EQ(expected_internal_ids.size(), cameras.size())
159 << "Mismatching test vector, did you forget to update the test?";
160
161 // Test GetInternalCameraId()
162 for (uint32_t i = 0; i < cameras.size(); i++) {
163 public_id = i;
164 res = id_manager->GetInternalCameraId(public_id, &internal_id);
165
166 EXPECT_EQ(res, OK) << "GetInternalCameraId() failed!";
167
168 if (res == OK) {
169 EXPECT_EQ(internal_id, expected_internal_ids[public_id])
170 << "Expected public ID " << public_id << " to map to internal ID "
171 << expected_internal_ids[public_id] << " but instead got "
172 << internal_id;
173 }
174 }
175
176 // Test GetPublicCameraId()
177 for (uint32_t i = 0; i < cameras.size(); i++) {
178 internal_id = expected_internal_ids[i];
179 res = id_manager->GetPublicCameraId(internal_id, &public_id);
180
181 EXPECT_EQ(res, OK) << "GetInternalCameraId() failed!";
182
183 if (res == OK) {
184 ASSERT_EQ(public_id, i)
185 << "Expected internal ID " << internal_id << " to map to public ID "
186 << i << " but instead got " << public_id;
187 }
188 }
189
190 // Test GetPhysicalCameraIds()
191 for (uint32_t public_id : id_manager->GetCameraIds()) {
192 res = id_manager->GetInternalCameraId(public_id, &internal_id);
193 EXPECT_EQ(res, OK);
194 ASSERT_LE(internal_id, cameras.size());
195
196 auto physical_camera_ids = id_manager->GetPhysicalCameraIds(public_id);
197 // Test to see if the physical IDs of logical cameras are mapped correctly
198 for (uint32_t i = 0; i < physical_camera_ids.size(); i++) {
199 // Public ID of the physical camera
200 uint32_t phys_public_id = physical_camera_ids[i];
201 uint32_t phys_internal_id = 0;
202 uint32_t phys_internal_id_expected =
203 cameras[internal_id].physical_camera_ids[i];
204
205 res = id_manager->GetInternalCameraId(phys_public_id, &phys_internal_id);
206 EXPECT_EQ(res, OK);
207 if (res == OK) {
208 EXPECT_EQ(phys_internal_id_expected, phys_internal_id);
209 }
210 }
211 }
212
213 // Test GetVisibleCameraIds()
214 std::vector<uint32_t> public_ids = id_manager->GetVisibleCameraIds();
215 size_t visible_camera_count = 0;
216 for (auto camera : cameras) {
217 if (camera.visible_to_framework) {
218 visible_camera_count++;
219 }
220 }
221 ASSERT_EQ(visible_camera_count, public_ids.size());
222
223 // Ensure that all cameras marked as visible appear in the public ID list
224 for (uint32_t public_id = 0; public_id < visible_camera_count; public_id++) {
225 auto it = std::find(public_ids.begin(), public_ids.end(), public_id);
226 EXPECT_NE(it, public_ids.end());
227 }
228 }
229
TEST(CameraIdMangerTest,LogicalCamera)230 TEST(CameraIdMangerTest, LogicalCamera) {
231 std::vector<CameraIdMap> cameras;
232
233 /* Create the following list of cameras:
234 *
235 * ID Visible Physical IDs
236 *--------------------------
237 * 0 N
238 * 1 N
239 * 2 N
240 * 3 N
241 * 4 N
242 * 5 Y 0, 1
243 * 6 Y 2, 3, 4
244 * 7 Y 3, 4
245 *
246 *
247 * Expected public camera list:
248 * Public ID Internal ID Physical IDs Visible
249 *----------------------------------------------
250 * 0 5 3, 4 Y
251 * 1 6 5, 6, 7 Y
252 * 2 7 6, 7 Y
253 * 3 0 N
254 * 4 1 N
255 * 5 2 N
256 * 6 3 N
257 * 7 4 N
258 */
259 cameras.push_back(CameraIdMap({0, false, {}}));
260 cameras.push_back(CameraIdMap({1, false, {}}));
261 cameras.push_back(CameraIdMap({2, false, {}}));
262 cameras.push_back(CameraIdMap({3, false, {}}));
263 cameras.push_back(CameraIdMap({4, false, {}}));
264 cameras.push_back(CameraIdMap({5, true, {0, 1}}));
265 cameras.push_back(CameraIdMap({6, true, {2, 3, 4}}));
266 cameras.push_back(CameraIdMap({7, true, {3, 4}}));
267
268 // Expected mapping, using index as public ID and value as internal ID
269 std::vector<uint32_t> expected_internal_ids = {5, 6, 7, 0, 1, 2, 3, 4};
270
271 // Create with a list of cameras none of which are visible to the framework
272 auto id_manager = CameraIdManager::Create(cameras);
273 ASSERT_NE(id_manager, nullptr) << "Creating CameraIDManager failed!";
274
275 ValidateCameraIds(id_manager.get(), cameras, expected_internal_ids);
276
277 // Now mark all cameras as visible and repeat the test:
278 expected_internal_ids.clear();
279 for (auto& camera : cameras) {
280 camera.visible_to_framework = true;
281 // IDs should now be identical to internal ones since all are visible
282 expected_internal_ids.push_back(camera.id);
283 }
284
285 id_manager = CameraIdManager::Create(cameras);
286 ASSERT_NE(id_manager, nullptr) << "Creating CameraIDManager failed!";
287
288 ValidateCameraIds(id_manager.get(), cameras, expected_internal_ids);
289
290 /* Create the following list of cameras:
291 *
292 * ID Visible Physical IDs
293 *--------------------------
294 * 0 N
295 * 1 Y 0, 2
296 * 2 Y
297 * 3 Y
298 *
299 *
300 * Expected public camera list:
301 * Public ID Internal ID Physical IDs Visible
302 *----------------------------------------------
303 * 0 1 3, 1 Y
304 * 1 2 Y
305 * 2 3 Y
306 * 3 0 N
307 */
308 cameras.clear();
309 cameras.push_back(CameraIdMap({0, false, {}}));
310 cameras.push_back(CameraIdMap({1, true, {0, 2}}));
311 cameras.push_back(CameraIdMap({2, true, {}}));
312 cameras.push_back(CameraIdMap({3, true, {}}));
313
314 // Expected mapping, using index as public ID and value as internal ID
315 expected_internal_ids = {1, 2, 3, 0};
316
317 // Create with a list of cameras none of which are visible to the framework
318 id_manager = CameraIdManager::Create(cameras);
319 ASSERT_NE(id_manager, nullptr) << "Creating CameraIDManager failed!";
320
321 ValidateCameraIds(id_manager.get(), cameras, expected_internal_ids);
322 }
323
324 } // namespace google_camera_hal
325 } // namespace android
326