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