1 /*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <dlfcn.h>
17 #include <algorithm>
18 #include "camera_host_service.h"
19 #include "camera_device_service.h"
20 #include "v1_0/icamera_device.h"
21 #include "camera_host_service_callback.h"
22 #include "camera_device_service_callback.h"
23 #include "camera_hal_hisysevent.h"
24
25 constexpr int NAME_START_POS = 6;
26
27 namespace OHOS::Camera {
28 OHOS::sptr<CameraHostService> CameraHostService::cameraHostService_ = nullptr;
29
CameraHostServiceGetInstance(void)30 extern "C" ICameraHost *CameraHostServiceGetInstance(void)
31 {
32 OHOS::sptr<CameraHostService> service = CameraHostService::GetInstance();
33 if (service == nullptr) {
34 CAMERA_LOGE("Camera host service is nullptr");
35 return nullptr;
36 }
37
38 return service.GetRefPtr();
39 }
40
GetVdiLibList(std::vector<std::string> & vdiLibList)41 int32_t CameraHostService::GetVdiLibList(std::vector<std::string> &vdiLibList)
42 {
43 CameraHalHicollie cameraHalHicollie("CameraHost:GetVdiLibList");
44 std::vector<std::string>().swap(vdiLibList);
45 ReleaseHcsTree();
46 const struct DeviceResourceIface *pDevResIns = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
47 if (pDevResIns == nullptr) {
48 CAMERA_LOGE("get hcs interface failed.");
49 return OHOS::HDI::Camera::V1_0::INVALID_ARGUMENT;
50 }
51
52 SetHcsBlobPath(CONFIG_PATH_NAME);
53 const struct DeviceResourceNode *pRootNode = pDevResIns->GetRootNode();
54 if (pRootNode == nullptr) {
55 CAMERA_LOGE("GetRootNode failed");
56 return OHOS::HDI::Camera::V1_0::INVALID_ARGUMENT;
57 }
58 if (pRootNode->name != nullptr) {
59 CAMERA_LOGI("pRootNode = %{public}s", pRootNode->name);
60 }
61
62 const char *vdiLib = nullptr;
63 int32_t elemNum = pDevResIns->GetElemNum(pRootNode, "vdiLibList");
64 for (int i = 0; i < elemNum; i++) {
65 pDevResIns->GetStringArrayElem(pRootNode, "vdiLibList", i, &vdiLib, nullptr);
66 if (vdiLib == nullptr) {
67 CAMERA_LOGE("Get vdi lib list failed");
68 return OHOS::HDI::Camera::V1_0::INVALID_ARGUMENT;
69 }
70 vdiLibList.push_back(std::string(vdiLib));
71 }
72
73 if (vdiLibList.size() == 0) {
74 CAMERA_LOGE("Vdi library list is empty");
75 return OHOS::HDI::Camera::V1_0::INVALID_ARGUMENT;
76 }
77
78 return OHOS::HDI::Camera::V1_0::NO_ERROR;
79 }
80
HdfCloseVdiLoaderList(std::vector<struct HdfVdiObject * > & cameraHostVdiLoaderList)81 void CameraHostService::HdfCloseVdiLoaderList(std::vector<struct HdfVdiObject *> &cameraHostVdiLoaderList)
82 {
83 CameraHalHicollie cameraHalHicollie("CameraHost:HdfCloseVdiLoaderList");
84 for (auto cameraHostVdiLoader : cameraHostVdiLoaderList) {
85 if (cameraHostVdiLoader != nullptr) {
86 HdfCloseVdi(cameraHostVdiLoader);
87 cameraHostVdiLoader = nullptr;
88 }
89 }
90 std::vector<struct HdfVdiObject *>().swap(cameraHostVdiLoaderList);
91 }
92
GetInstance()93 OHOS::sptr<CameraHostService> CameraHostService::GetInstance()
94 {
95 if (cameraHostService_ != nullptr) {
96 return cameraHostService_;
97 }
98 std::vector<std::string> vdiLibList;
99 if (GetVdiLibList(vdiLibList) != OHOS::HDI::Camera::V1_0::NO_ERROR) {
100 CAMERA_LOGE("Can not get vdi lib name");
101 return nullptr;
102 }
103 std::vector<ICameraHostVdi*> cameraHostVdiList;
104 std::vector<struct HdfVdiObject *> cameraHostVdiLoaderList;
105 for (auto vdiLib : vdiLibList) {
106 struct HdfVdiObject *cameraHostVdiLoader = HdfLoadVdi(vdiLib.c_str());
107 if (cameraHostVdiLoader == nullptr || cameraHostVdiLoader->vdiBase == nullptr) {
108 CAMERA_LOGE("Hdf load camera host vdi failed!");
109 return nullptr;
110 }
111 uint32_t version = HdfGetVdiVersion(cameraHostVdiLoader);
112 if (version != 1) {
113 HdfCloseVdi(cameraHostVdiLoader);
114 HdfCloseVdiLoaderList(cameraHostVdiLoaderList);
115 CAMERA_LOGE("Get camera host vdi version failed!");
116 return nullptr;
117 }
118 struct VdiWrapperCameraHost *vdiWrapper = reinterpret_cast<struct VdiWrapperCameraHost *>(
119 cameraHostVdiLoader->vdiBase);
120 if (vdiWrapper->module == nullptr) {
121 HdfCloseVdi(cameraHostVdiLoader);
122 HdfCloseVdiLoaderList(cameraHostVdiLoaderList);
123 CAMERA_LOGE("Hdf load camera host vdi failed, module is nullptr!");
124 return nullptr;
125 }
126 ICameraHostVdi *cameraHostVdi = reinterpret_cast<ICameraHostVdi *>(vdiWrapper->module);
127 cameraHostVdiList.push_back(cameraHostVdi);
128 cameraHostVdiLoaderList.push_back(cameraHostVdiLoader);
129 }
130 cameraHostService_ = new (std::nothrow) CameraHostService(cameraHostVdiList, cameraHostVdiLoaderList);
131 if (cameraHostService_ == nullptr) {
132 CAMERA_LOGE("Camera host service is nullptr");
133 HdfCloseVdiLoaderList(cameraHostVdiLoaderList);
134 return nullptr;
135 }
136
137 return cameraHostService_;
138 }
139
CameraHostService(std::vector<ICameraHostVdi * > cameraHostVdiList,std::vector<struct HdfVdiObject * > cameraHostVdiLoaderList)140 CameraHostService::CameraHostService(std::vector<ICameraHostVdi*> cameraHostVdiList,
141 std::vector<struct HdfVdiObject *> cameraHostVdiLoaderList)
142 : cameraHostVdiList_(cameraHostVdiList), cameraHostVdiLoaderList_(cameraHostVdiLoaderList)
143 {
144 CAMERA_LOGD("ctor, instance");
145 }
146
~CameraHostService()147 CameraHostService::~CameraHostService()
148 {
149 HdfCloseVdiLoaderList(cameraHostVdiLoaderList_);
150 CAMERA_LOGD("dtor, instance");
151 }
152
SetCallback(const OHOS::sptr<ICameraHostCallback> & callbackObj)153 int32_t CameraHostService::SetCallback(const OHOS::sptr<ICameraHostCallback> &callbackObj)
154 {
155 for (auto cameraHostVdi : cameraHostVdiList_) {
156 CHECK_IF_PTR_NULL_RETURN_VALUE(cameraHostVdi, OHOS::HDI::Camera::V1_0::INVALID_ARGUMENT);
157 OHOS::sptr<ICameraHostVdiCallback> vdiCallbackObj = new CameraHostServiceCallback(callbackObj,
158 cameraHostVdi, cameraIdInfoList_);
159 if (vdiCallbackObj == nullptr) {
160 CAMERA_LOGE("Camera host service set callback failed, vdiCallbackObj is nullptr");
161 return OHOS::HDI::Camera::V1_0::INSUFFICIENT_RESOURCES;
162 }
163 int32_t ret = cameraHostVdi->SetCallback(vdiCallbackObj);
164 if (ret != OHOS::HDI::Camera::V1_0::NO_ERROR) {
165 CAMERA_LOGE("Camera host service set callback failed");
166 return ret;
167 }
168 }
169
170 return OHOS::HDI::Camera::V1_0::NO_ERROR;
171 }
172
GetCameraIds(std::vector<std::string> & cameraIds)173 int32_t CameraHostService::GetCameraIds(std::vector<std::string> &cameraIds)
174 {
175 CameraHalHicollie cameraHalHicollie("CameraHost:GetCameraIds");
176 std::vector<std::string>().swap(cameraIds);
177 if (cameraIdInfoList_.size() == 0) {
178 int32_t ret = UpdateCameraIdMapList();
179 if (ret != OHOS::HDI::Camera::V1_0::NO_ERROR) {
180 CAMERA_LOGE("Camera get cameraIds failed");
181 return ret;
182 }
183 }
184 for (auto cameraIdInfo : cameraIdInfoList_) {
185 if (cameraIdInfo.isDeleted == false) {
186 cameraIds.push_back(cameraIdInfo.currentCameraId);
187 }
188 }
189
190 return OHOS::HDI::Camera::V1_0::NO_ERROR;
191 }
192
GetCameraAbility(const std::string & cameraId,std::vector<uint8_t> & cameraAbility)193 int32_t CameraHostService::GetCameraAbility(const std::string &cameraId,
194 std::vector<uint8_t> &cameraAbility)
195 {
196 ICameraHostVdi* cameraHostVdi = GetCameraHostVdi(cameraId);
197 CHECK_IF_PTR_NULL_RETURN_VALUE(cameraHostVdi, OHOS::HDI::Camera::V1_0::INVALID_ARGUMENT);
198
199 std::string vdiCameraId = GetVendorCameraId(cameraId);
200 if (vdiCameraId == "") {
201 CAMERA_LOGE("Get vendor camera id failed");
202 return OHOS::HDI::Camera::V1_0::INVALID_ARGUMENT;
203 }
204
205 return cameraHostVdi->GetCameraAbility(vdiCameraId, cameraAbility);
206 }
207
OpenCamera(const std::string & cameraId,const sptr<ICameraDeviceCallback> & callbackObj,sptr<ICameraDevice> & device)208 int32_t CameraHostService::OpenCamera(const std::string &cameraId, const sptr<ICameraDeviceCallback> &callbackObj,
209 sptr<ICameraDevice> &device)
210 {
211 CAMERAHALPERFSYSEVENT(TIME_FOR_OPEN_CAMERA);
212 ICameraHostVdi* cameraHostVdi = GetCameraHostVdi(cameraId);
213 CHECK_IF_PTR_NULL_RETURN_VALUE(cameraHostVdi, OHOS::HDI::Camera::V1_0::INVALID_ARGUMENT);
214
215 std::string vdiCameraId = GetVendorCameraId(cameraId);
216 if (vdiCameraId == "") {
217 CAMERA_LOGE("Get vendor camera id failed");
218 return OHOS::HDI::Camera::V1_0::INVALID_ARGUMENT;
219 }
220
221 OHOS::sptr<ICameraDeviceVdi> deviceVdi = nullptr;
222 OHOS::sptr<ICameraDeviceVdiCallback> vdiCallbackObj = new CameraDeviceServiceCallback(callbackObj);
223 if (vdiCallbackObj == nullptr) {
224 CAMERA_LOGE("Open camera error, vdiCallbackObj is nullptr");
225 return OHOS::HDI::Camera::V1_0::INSUFFICIENT_RESOURCES;
226 }
227 int32_t ret = cameraHostVdi->OpenCamera(vdiCameraId, vdiCallbackObj, deviceVdi);
228 if (ret != OHOS::HDI::Camera::V1_0::NO_ERROR) {
229 CAMERA_LOGE("Open camera error, ret=%{public}d", ret);
230 return ret;
231 }
232 if (deviceVdi == nullptr) {
233 CAMERA_LOGE("Open camera error, deviceVdi is nullptr");
234 return OHOS::HDI::Camera::V1_0::INSUFFICIENT_RESOURCES;
235 }
236 device = new CameraDeviceService(deviceVdi);
237 if (device == nullptr) {
238 CAMERA_LOGE("Open camera error, device is nullptr");
239 return OHOS::HDI::Camera::V1_0::INSUFFICIENT_RESOURCES;
240 }
241
242 return OHOS::HDI::Camera::V1_0::NO_ERROR;
243 }
244
SetFlashlight(const std::string & cameraId,bool isEnable)245 int32_t CameraHostService::SetFlashlight(const std::string &cameraId, bool isEnable)
246 {
247 ICameraHostVdi* cameraHostVdi = GetCameraHostVdi(cameraId);
248 CHECK_IF_PTR_NULL_RETURN_VALUE(cameraHostVdi, OHOS::HDI::Camera::V1_0::INVALID_ARGUMENT);
249
250 std::string vdiCameraId = GetVendorCameraId(cameraId);
251 if (vdiCameraId == "") {
252 CAMERA_LOGE("Get vendor camera id failed");
253 return OHOS::HDI::Camera::V1_0::INVALID_ARGUMENT;
254 }
255
256 return cameraHostVdi->SetFlashlight(vdiCameraId, isEnable);
257 }
258
vdiCameraIdToPrefix(const std::string & id)259 static inline const std::string vdiCameraIdToPrefix(const std::string &id)
260 {
261 size_t startPos;
262 size_t endPos;
263 std::string preFix = "lcam00";
264 if ((startPos = id.find("&name=")) != std::string::npos) {
265 startPos += NAME_START_POS;
266 endPos = id.find("&id=");
267 preFix = id.substr(startPos, endPos - startPos);
268 preFix += "/";
269 }
270 return preFix;
271 }
272
UpdateCameraIdMapList()273 int32_t CameraHostService::UpdateCameraIdMapList()
274 {
275 std::vector<CameraIdInfo>().swap(cameraIdInfoList_);
276 int32_t currentCameraIndex = 1;
277 for (auto cameraHostVdi : cameraHostVdiList_) {
278 CHECK_IF_PTR_NULL_RETURN_VALUE(cameraHostVdi, OHOS::HDI::Camera::V1_0::INVALID_ARGUMENT);
279
280 std::vector<std::string> vdiCameraIds;
281 int32_t ret = cameraHostVdi->GetCameraIds(vdiCameraIds);
282 if (ret != OHOS::HDI::Camera::V1_0::NO_ERROR) {
283 CAMERA_LOGE("Camera host service set callback failed");
284 return ret;
285 }
286 for (auto id : vdiCameraIds) {
287 struct CameraIdInfo cameraIdInfo;
288 cameraIdInfo.index = currentCameraIndex;
289 std::string currentCameraId = vdiCameraIdToPrefix(id) + std::to_string(currentCameraIndex);
290 cameraIdInfo.currentCameraId = currentCameraId;
291 cameraIdInfo.cameraHostVdi = cameraHostVdi;
292 cameraIdInfo.vendorCameraId = id;
293 cameraIdInfo.isDeleted = false;
294 cameraIdInfoList_.push_back(cameraIdInfo);
295 currentCameraIndex++;
296 }
297 }
298
299 return OHOS::HDI::Camera::V1_0::NO_ERROR;
300 }
301
GetCameraHostVdi(const std::string & currentCameraId)302 ICameraHostVdi* CameraHostService::GetCameraHostVdi(const std::string ¤tCameraId)
303 {
304 auto itr = std::find_if(cameraIdInfoList_.begin(), cameraIdInfoList_.end(),
305 [¤tCameraId](const struct CameraIdInfo &cameraIdInfo) {
306 return currentCameraId == cameraIdInfo.currentCameraId;
307 });
308 if (itr == cameraIdInfoList_.end()) {
309 CAMERA_LOGE("Get camera host vdi failed, current camera id = %{public}s doesn't exist",
310 currentCameraId.c_str());
311 return nullptr;
312 }
313
314 return itr->cameraHostVdi;
315 }
316
GetVendorCameraId(const std::string & currentCameraId)317 const std::string CameraHostService::GetVendorCameraId(const std::string ¤tCameraId)
318 {
319 auto itr = std::find_if(cameraIdInfoList_.begin(), cameraIdInfoList_.end(),
320 [¤tCameraId](const struct CameraIdInfo &cameraIdInfo) {
321 return currentCameraId == cameraIdInfo.currentCameraId;
322 });
323 if (itr == cameraIdInfoList_.end()) {
324 CAMERA_LOGE("Get vendor camera id failed, current camera id = %{public}s doesn't exist",
325 currentCameraId.c_str());
326 return std::string("");
327 }
328
329 return itr->vendorCameraId;
330 }
331 } // end namespace OHOS::Camera
332