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 namespace OHOS::Camera {
26 OHOS::sptr<CameraHostService> CameraHostService::cameraHostService_ = nullptr;
27
CameraHostServiceGetInstance(void)28 extern "C" ICameraHost *CameraHostServiceGetInstance(void)
29 {
30 OHOS::sptr<CameraHostService> service = CameraHostService::GetInstance();
31 if (service == nullptr) {
32 CAMERA_LOGE("Camera host service is nullptr");
33 return nullptr;
34 }
35
36 return service.GetRefPtr();
37 }
38
GetVdiLibList(std::vector<std::string> & vdiLibList)39 int32_t CameraHostService::GetVdiLibList(std::vector<std::string> &vdiLibList)
40 {
41 std::vector<std::string>().swap(vdiLibList);
42 ReleaseHcsTree();
43 const struct DeviceResourceIface *pDevResIns = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
44 if (pDevResIns == nullptr) {
45 CAMERA_LOGE("get hcs interface failed.");
46 return OHOS::HDI::Camera::V1_0::INVALID_ARGUMENT;
47 }
48
49 SetHcsBlobPath(CONFIG_PATH_NAME);
50 const struct DeviceResourceNode *pRootNode = pDevResIns->GetRootNode();
51 if (pRootNode == nullptr) {
52 CAMERA_LOGE("GetRootNode failed");
53 return OHOS::HDI::Camera::V1_0::INVALID_ARGUMENT;
54 }
55 if (pRootNode->name != nullptr) {
56 CAMERA_LOGI("pRootNode = %{public}s", pRootNode->name);
57 }
58
59 const char *vdiLib = nullptr;
60 int32_t elemNum = pDevResIns->GetElemNum(pRootNode, "vdiLibList");
61 for (int i = 0; i < elemNum; i++) {
62 pDevResIns->GetStringArrayElem(pRootNode, "vdiLibList", i, &vdiLib, nullptr);
63 if (vdiLib == nullptr) {
64 CAMERA_LOGE("Get vdi lib list failed");
65 return OHOS::HDI::Camera::V1_0::INVALID_ARGUMENT;
66 }
67 vdiLibList.push_back(std::string(vdiLib));
68 }
69
70 if (vdiLibList.size() == 0) {
71 CAMERA_LOGE("Vdi library list is empty");
72 return OHOS::HDI::Camera::V1_0::INVALID_ARGUMENT;
73 }
74
75 return OHOS::HDI::Camera::V1_0::NO_ERROR;
76 }
77
HdfCloseVdiLoaderList(std::vector<struct HdfVdiObject * > & cameraHostVdiLoaderList)78 void CameraHostService::HdfCloseVdiLoaderList(std::vector<struct HdfVdiObject *> &cameraHostVdiLoaderList)
79 {
80 for (auto cameraHostVdiLoader : cameraHostVdiLoaderList) {
81 if (cameraHostVdiLoader != nullptr) {
82 HdfCloseVdi(cameraHostVdiLoader);
83 cameraHostVdiLoader = nullptr;
84 }
85 }
86 std::vector<struct HdfVdiObject *>().swap(cameraHostVdiLoaderList);
87 }
88
GetInstance()89 OHOS::sptr<CameraHostService> CameraHostService::GetInstance()
90 {
91 if (cameraHostService_ != nullptr) {
92 return cameraHostService_;
93 }
94 std::vector<std::string> vdiLibList;
95 if (GetVdiLibList(vdiLibList) != OHOS::HDI::Camera::V1_0::NO_ERROR) {
96 CAMERA_LOGE("Can not get vdi lib name");
97 return nullptr;
98 }
99 std::vector<ICameraHostVdi*> cameraHostVdiList;
100 std::vector<struct HdfVdiObject *> cameraHostVdiLoaderList;
101 for (auto vdiLib : vdiLibList) {
102 struct HdfVdiObject *cameraHostVdiLoader = HdfLoadVdi(vdiLib.c_str());
103 if (cameraHostVdiLoader == nullptr || cameraHostVdiLoader->vdiBase == nullptr) {
104 CAMERA_LOGE("Hdf load camera host vdi failed!");
105 return nullptr;
106 }
107 uint32_t version = HdfGetVdiVersion(cameraHostVdiLoader);
108 if (version != 1) {
109 HdfCloseVdi(cameraHostVdiLoader);
110 HdfCloseVdiLoaderList(cameraHostVdiLoaderList);
111 CAMERA_LOGE("Get camera host vdi version failed!");
112 return nullptr;
113 }
114 struct VdiWrapperCameraHost *vdiWrapper = reinterpret_cast<struct VdiWrapperCameraHost *>(
115 cameraHostVdiLoader->vdiBase);
116 if (vdiWrapper->module == nullptr) {
117 HdfCloseVdi(cameraHostVdiLoader);
118 HdfCloseVdiLoaderList(cameraHostVdiLoaderList);
119 CAMERA_LOGE("Hdf load camera host vdi failed, module is nullptr!");
120 return nullptr;
121 }
122 ICameraHostVdi *cameraHostVdi = reinterpret_cast<ICameraHostVdi *>(vdiWrapper->module);
123 cameraHostVdiList.push_back(cameraHostVdi);
124 cameraHostVdiLoaderList.push_back(cameraHostVdiLoader);
125 }
126 cameraHostService_ = new (std::nothrow) CameraHostService(cameraHostVdiList, cameraHostVdiLoaderList);
127 if (cameraHostService_ == nullptr) {
128 CAMERA_LOGE("Camera host service is nullptr");
129 HdfCloseVdiLoaderList(cameraHostVdiLoaderList);
130 return nullptr;
131 }
132
133 return cameraHostService_;
134 }
135
CameraHostService(std::vector<ICameraHostVdi * > cameraHostVdiList,std::vector<struct HdfVdiObject * > cameraHostVdiLoaderList)136 CameraHostService::CameraHostService(std::vector<ICameraHostVdi*> cameraHostVdiList,
137 std::vector<struct HdfVdiObject *> cameraHostVdiLoaderList)
138 : cameraHostVdiList_(cameraHostVdiList), cameraHostVdiLoaderList_(cameraHostVdiLoaderList)
139 {
140 CAMERA_LOGD("ctor, instance");
141 }
142
~CameraHostService()143 CameraHostService::~CameraHostService()
144 {
145 HdfCloseVdiLoaderList(cameraHostVdiLoaderList_);
146 CAMERA_LOGD("dtor, instance");
147 }
148
SetCallback(const OHOS::sptr<ICameraHostCallback> & callbackObj)149 int32_t CameraHostService::SetCallback(const OHOS::sptr<ICameraHostCallback> &callbackObj)
150 {
151 for (auto cameraHostVdi : cameraHostVdiList_) {
152 CHECK_IF_PTR_NULL_RETURN_VALUE(cameraHostVdi, OHOS::HDI::Camera::V1_0::INVALID_ARGUMENT);
153 OHOS::sptr<ICameraHostVdiCallback> vdiCallbackObj = new CameraHostServiceCallback(callbackObj,
154 cameraHostVdi, cameraIdInfoList_);
155 if (vdiCallbackObj == nullptr) {
156 CAMERA_LOGE("Camera host service set callback failed, vdiCallbackObj is nullptr");
157 return OHOS::HDI::Camera::V1_0::INSUFFICIENT_RESOURCES;
158 }
159 int32_t ret = cameraHostVdi->SetCallback(vdiCallbackObj);
160 if (ret != OHOS::HDI::Camera::V1_0::NO_ERROR) {
161 CAMERA_LOGE("Camera host service set callback failed");
162 return ret;
163 }
164 }
165
166 return OHOS::HDI::Camera::V1_0::NO_ERROR;
167 }
168
GetCameraIds(std::vector<std::string> & cameraIds)169 int32_t CameraHostService::GetCameraIds(std::vector<std::string> &cameraIds)
170 {
171 std::vector<std::string>().swap(cameraIds);
172 if (cameraIdInfoList_.size() == 0) {
173 int32_t ret = UpdateCameraIdMapList();
174 if (ret != OHOS::HDI::Camera::V1_0::NO_ERROR) {
175 CAMERA_LOGE("Camera get cameraIds failed");
176 return ret;
177 }
178 }
179 for (auto cameraIdInfo : cameraIdInfoList_) {
180 if (cameraIdInfo.isDeleted == false) {
181 cameraIds.push_back(cameraIdInfo.currentCameraId);
182 }
183 }
184
185 return OHOS::HDI::Camera::V1_0::NO_ERROR;
186 }
187
GetCameraAbility(const std::string & cameraId,std::vector<uint8_t> & cameraAbility)188 int32_t CameraHostService::GetCameraAbility(const std::string &cameraId,
189 std::vector<uint8_t> &cameraAbility)
190 {
191 ICameraHostVdi* cameraHostVdi = GetCameraHostVdi(cameraId);
192 CHECK_IF_PTR_NULL_RETURN_VALUE(cameraHostVdi, OHOS::HDI::Camera::V1_0::INVALID_ARGUMENT);
193
194 std::string vdiCameraId = GetVendorCameraId(cameraId);
195 if (vdiCameraId == "") {
196 CAMERA_LOGE("Get vendor camera id failed");
197 return OHOS::HDI::Camera::V1_0::INVALID_ARGUMENT;
198 }
199
200 return cameraHostVdi->GetCameraAbility(vdiCameraId, cameraAbility);
201 }
202
OpenCamera(const std::string & cameraId,const sptr<ICameraDeviceCallback> & callbackObj,sptr<ICameraDevice> & device)203 int32_t CameraHostService::OpenCamera(const std::string &cameraId, const sptr<ICameraDeviceCallback> &callbackObj,
204 sptr<ICameraDevice> &device)
205 {
206 CAMERAHALPERFSYSEVENT(TIME_FOR_OPEN_CAMERA);
207 ICameraHostVdi* cameraHostVdi = GetCameraHostVdi(cameraId);
208 CHECK_IF_PTR_NULL_RETURN_VALUE(cameraHostVdi, OHOS::HDI::Camera::V1_0::INVALID_ARGUMENT);
209
210 std::string vdiCameraId = GetVendorCameraId(cameraId);
211 if (vdiCameraId == "") {
212 CAMERA_LOGE("Get vendor camera id failed");
213 return OHOS::HDI::Camera::V1_0::INVALID_ARGUMENT;
214 }
215
216 OHOS::sptr<ICameraDeviceVdi> deviceVdi = nullptr;
217 OHOS::sptr<ICameraDeviceVdiCallback> vdiCallbackObj = new CameraDeviceServiceCallback(callbackObj);
218 if (vdiCallbackObj == nullptr) {
219 CAMERA_LOGE("Open camera error, vdiCallbackObj is nullptr");
220 return OHOS::HDI::Camera::V1_0::INSUFFICIENT_RESOURCES;
221 }
222 int32_t ret = cameraHostVdi->OpenCamera(vdiCameraId, vdiCallbackObj, deviceVdi);
223 if (ret != OHOS::HDI::Camera::V1_0::NO_ERROR) {
224 CAMERA_LOGE("Open camera error, ret=%{public}d", ret);
225 return ret;
226 }
227 if (deviceVdi == nullptr) {
228 CAMERA_LOGE("Open camera error, deviceVdi is nullptr");
229 return OHOS::HDI::Camera::V1_0::INSUFFICIENT_RESOURCES;
230 }
231 device = new CameraDeviceService(deviceVdi);
232 if (device == nullptr) {
233 CAMERA_LOGE("Open camera error, device is nullptr");
234 return OHOS::HDI::Camera::V1_0::INSUFFICIENT_RESOURCES;
235 }
236
237 return OHOS::HDI::Camera::V1_0::NO_ERROR;
238 }
239
SetFlashlight(const std::string & cameraId,bool isEnable)240 int32_t CameraHostService::SetFlashlight(const std::string &cameraId, bool isEnable)
241 {
242 ICameraHostVdi* cameraHostVdi = GetCameraHostVdi(cameraId);
243 CHECK_IF_PTR_NULL_RETURN_VALUE(cameraHostVdi, OHOS::HDI::Camera::V1_0::INVALID_ARGUMENT);
244
245 std::string vdiCameraId = GetVendorCameraId(cameraId);
246 if (vdiCameraId == "") {
247 CAMERA_LOGE("Get vendor camera id failed");
248 return OHOS::HDI::Camera::V1_0::INVALID_ARGUMENT;
249 }
250
251 return cameraHostVdi->SetFlashlight(vdiCameraId, isEnable);
252 }
253
UpdateCameraIdMapList()254 int32_t CameraHostService::UpdateCameraIdMapList()
255 {
256 std::vector<CameraIdInfo>().swap(cameraIdInfoList_);
257 int32_t currentCameraIndex = 1;
258 for (auto cameraHostVdi : cameraHostVdiList_) {
259 CHECK_IF_PTR_NULL_RETURN_VALUE(cameraHostVdi, OHOS::HDI::Camera::V1_0::INVALID_ARGUMENT);
260
261 std::vector<std::string> vdiCameraIds;
262 int32_t ret = cameraHostVdi->GetCameraIds(vdiCameraIds);
263 if (ret != OHOS::HDI::Camera::V1_0::NO_ERROR) {
264 CAMERA_LOGE("Camera host service set callback failed");
265 return ret;
266 }
267 for (auto id : vdiCameraIds) {
268 struct CameraIdInfo cameraIdInfo;
269 std::string currentCameraId = "lcam00" + std::to_string(currentCameraIndex);
270 cameraIdInfo.currentCameraId = currentCameraId;
271 cameraIdInfo.cameraHostVdi = cameraHostVdi;
272 cameraIdInfo.vendorCameraId = id;
273 cameraIdInfo.isDeleted = false;
274 cameraIdInfoList_.push_back(cameraIdInfo);
275 currentCameraIndex++;
276 }
277 }
278
279 return OHOS::HDI::Camera::V1_0::NO_ERROR;
280 }
281
GetCameraHostVdi(const std::string & currentCameraId)282 ICameraHostVdi* CameraHostService::GetCameraHostVdi(const std::string ¤tCameraId)
283 {
284 auto itr = std::find_if(cameraIdInfoList_.begin(), cameraIdInfoList_.end(),
285 [¤tCameraId](const struct CameraIdInfo &cameraIdInfo) {
286 return currentCameraId == cameraIdInfo.currentCameraId;
287 });
288 if (itr == cameraIdInfoList_.end()) {
289 CAMERA_LOGE("Get camera host vdi failed, current camera id = %{public}s doesn't exist",
290 currentCameraId.c_str());
291 return nullptr;
292 }
293
294 return itr->cameraHostVdi;
295 }
296
GetVendorCameraId(const std::string & currentCameraId)297 const std::string CameraHostService::GetVendorCameraId(const std::string ¤tCameraId)
298 {
299 auto itr = std::find_if(cameraIdInfoList_.begin(), cameraIdInfoList_.end(),
300 [¤tCameraId](const struct CameraIdInfo &cameraIdInfo) {
301 return currentCameraId == cameraIdInfo.currentCameraId;
302 });
303 if (itr == cameraIdInfoList_.end()) {
304 CAMERA_LOGE("Get vendor camera id failed, current camera id = %{public}s doesn't exist",
305 currentCameraId.c_str());
306 return std::string("");
307 }
308
309 return itr->vendorCameraId;
310 }
311 } // end namespace OHOS::Camera
312