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_NDEBUG 0
18 #define LOG_TAG "GCH_CameraIdManager"
19 #include <log/log.h>
20 
21 #include "camera_id_manager.h"
22 
23 namespace android {
24 namespace google_camera_hal {
25 
Create(const std::vector<CameraIdMap> & id_maps)26 std::unique_ptr<CameraIdManager> CameraIdManager::Create(
27     const std::vector<CameraIdMap>& id_maps) {
28   auto camera_id_manager =
29       std::unique_ptr<CameraIdManager>(new CameraIdManager());
30 
31   if (camera_id_manager == nullptr) {
32     ALOGE("%s: Creating CameraIdManager failed.", __FUNCTION__);
33     return nullptr;
34   }
35 
36   status_t res = camera_id_manager->Initialize(id_maps);
37   if (res != OK) {
38     ALOGE("%s: Initializing CameraIdManager failed: %s (%d).", __FUNCTION__,
39           strerror(-res), res);
40     return nullptr;
41   }
42 
43   return camera_id_manager;
44 }
45 
Initialize(const std::vector<CameraIdMap> & id_maps)46 status_t CameraIdManager::Initialize(const std::vector<CameraIdMap>& id_maps) {
47   if (id_maps.size() == 0) {
48     ALOGW("%s: camera_ids is empty.", __FUNCTION__);
49     return OK;
50   }
51 
52   status_t res = ValidateInput(id_maps);
53   if (res != OK) {
54     return res;
55   }
56 
57   // First, add the internal camera IDs for cameras visible to the framework
58   for (auto camera : id_maps) {
59     if (camera.visible_to_framework) {
60       visible_camera_count_++;
61       public_camera_internal_ids_.push_back(camera.id);
62       physical_camera_ids_.push_back(camera.physical_camera_ids);
63     }
64   }
65 
66   // Next, add the non-visible public IDs to the end of the list
67   for (auto camera : id_maps) {
68     if (!camera.visible_to_framework) {
69       public_camera_internal_ids_.push_back(camera.id);
70       physical_camera_ids_.push_back(camera.physical_camera_ids);
71     }
72   }
73 
74   // Change the internal cameras' IDs to public framework IDs
75   for (auto& physical_ids : physical_camera_ids_) {
76     for (size_t i = 0; i < physical_ids.size(); i++) {
77       // Remap the original physical camera ID to the new public ID domain
78       if (GetPublicCameraId(physical_ids[i], &physical_ids[i]) != OK) {
79         return BAD_VALUE;
80       }
81     }
82   }
83 
84   res = ValidateMappedIds();
85   if (res != OK) {
86     return res;
87   }
88 
89   PrintCameraIdMapping();
90   return OK;
91 }
92 
ValidateInput(const std::vector<CameraIdMap> & id_maps)93 status_t CameraIdManager::ValidateInput(const std::vector<CameraIdMap>& id_maps) {
94   bool has_visible_camera = false;
95 
96   std::vector<uint32_t> physical_ids;
97   // Check for logical cameras that may not be visible to the framework
98   for (auto camera : id_maps) {
99     if (camera.physical_camera_ids.size() > 0 && !camera.visible_to_framework) {
100       ALOGE("%s: Logical cameras should be visible to the framework.",
101             __FUNCTION__);
102       return BAD_VALUE;
103     } else if (camera.physical_camera_ids.size() == 0) {
104       physical_ids.push_back(camera.id);
105     }
106 
107     if (camera.visible_to_framework) {
108       has_visible_camera = true;
109     }
110   }
111 
112   // There should be at least one visible camera unless we are initialized with
113   // an empty camera list
114   if (id_maps.size() > 0 && !has_visible_camera) {
115     ALOGE("%s: There is no public camera ID visiable to the framework.",
116           __FUNCTION__);
117     return BAD_VALUE;
118   }
119 
120   // Check to see if physical camera IDs are not re-used as logical cameras
121   for (auto logical_camera : id_maps) {
122     if (logical_camera.physical_camera_ids.size() > 0) {
123       for (uint32_t physical_id : logical_camera.physical_camera_ids) {
124         auto it =
125             std::find(physical_ids.begin(), physical_ids.end(), physical_id);
126         if (it == physical_ids.end()) {
127           ALOGE(
128               "%s: Logical camera with ID %u lists physical camera id %u,"
129               "which is not a physical camera",
130               __FUNCTION__, logical_camera.id, physical_id);
131           return BAD_VALUE;
132         }
133       }
134     }
135   }
136 
137   return OK;
138 }
139 
ValidateMappedIds()140 status_t CameraIdManager::ValidateMappedIds() {
141   // Make a copy of the internal IDs
142   auto v = public_camera_internal_ids_;
143   // Camera IDs must be unique, except for kInvalidCameraId values
144   v.erase(std::remove(v.begin(), v.end(), kInvalidCameraId), v.end());
145   if (std::unique(v.begin(), v.end()) != v.end()) {
146     ALOGE("%s: Camera IDs should be unique.", __FUNCTION__);
147     return BAD_VALUE;
148   }
149 
150   return OK;
151 }
152 
PrintCameraIdMapping()153 void CameraIdManager::PrintCameraIdMapping() {
154   ALOGI("%s: Found %zu public camera IDs with %zu visible to the framework.",
155         __FUNCTION__, public_camera_internal_ids_.size(), visible_camera_count_);
156 
157   for (uint32_t i = 0; i < public_camera_internal_ids_.size(); i++) {
158     const char* visibility =
159         (i + 1 <= visible_camera_count_ ? "visible" : "NOT visible");
160     ALOGI("%s: Public camera ID %u is %s, and maps to internal camera ID %u",
161           __FUNCTION__, i, visibility, public_camera_internal_ids_[i]);
162   }
163 
164   uint32_t public_id = 0;
165   for (auto physical_id_list : physical_camera_ids_) {
166     for (uint32_t phys_id : physical_id_list) {
167       ALOGI("%s: Public camera ID %u uses physical camera ID %u", __FUNCTION__,
168             public_id, phys_id);
169     }
170     public_id++;
171   }
172 }
173 
GetVisibleCameraIds() const174 std::vector<std::uint32_t> CameraIdManager::GetVisibleCameraIds() const {
175   std::vector<std::uint32_t> camera_ids;
176 
177   for (uint32_t i = 0; i < visible_camera_count_; i++) {
178     camera_ids.push_back(i);
179   }
180 
181   return camera_ids;
182 }
183 
GetCameraIds() const184 std::vector<std::uint32_t> CameraIdManager::GetCameraIds() const {
185   std::vector<std::uint32_t> camera_ids;
186 
187   for (uint32_t i = 0; i < public_camera_internal_ids_.size(); i++) {
188     camera_ids.push_back(i);
189   }
190 
191   return camera_ids;
192 }
193 
GetPhysicalCameraIds(uint32_t public_camera_id) const194 std::vector<std::uint32_t> CameraIdManager::GetPhysicalCameraIds(
195     uint32_t public_camera_id) const {
196   if (public_camera_id >= public_camera_internal_ids_.size()) {
197     return {};
198   }
199 
200   return physical_camera_ids_[public_camera_id];
201 }
202 
GetPublicCameraId(uint32_t internal_camera_id,uint32_t * public_camera_id) const203 status_t CameraIdManager::GetPublicCameraId(uint32_t internal_camera_id,
204                                             uint32_t* public_camera_id) const {
205   if (public_camera_id == nullptr) {
206     return BAD_VALUE;
207   }
208 
209   for (uint32_t i = 0; i < public_camera_internal_ids_.size(); i++) {
210     if (public_camera_internal_ids_[i] == internal_camera_id) {
211       *public_camera_id = i;
212       return OK;
213     }
214   }
215 
216   return NAME_NOT_FOUND;
217 }
218 
GetInternalCameraId(uint32_t public_camera_id,uint32_t * internal_camera_id) const219 status_t CameraIdManager::GetInternalCameraId(
220     uint32_t public_camera_id, uint32_t* internal_camera_id) const {
221   if (internal_camera_id == nullptr) {
222     return BAD_VALUE;
223   }
224 
225   if (public_camera_id >= public_camera_internal_ids_.size()) {
226     return BAD_VALUE;
227   }
228 
229   *internal_camera_id = public_camera_internal_ids_[public_camera_id];
230 
231   return OK;
232 }
233 
234 }  // namespace google_camera_hal
235 }  // namespace android
236