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