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