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