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<OHOS::sptr<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<OHOS::sptr<ICameraHostVdi>> cameraHostVdiList,std::vector<struct HdfVdiObject * > cameraHostVdiLoaderList)135 CameraHostService::CameraHostService(std::vector<OHOS::sptr<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 for (auto cameraHostVdi : cameraHostVdiList_) {
151 CHECK_IF_PTR_NULL_RETURN_VALUE(cameraHostVdi, OHOS::HDI::Camera::V1_0::INVALID_ARGUMENT);
152 OHOS::sptr<ICameraHostVdiCallback> vdiCallbackObj = new CameraHostServiceCallback(callbackObj,
153 cameraHostVdi, cameraIdInfoList_);
154 if (vdiCallbackObj == nullptr) {
155 CAMERA_LOGE("Camera host service set callback failed, vdiCallbackObj is nullptr");
156 return OHOS::HDI::Camera::V1_0::INSUFFICIENT_RESOURCES;
157 }
158 int32_t ret = cameraHostVdi->SetCallback(vdiCallbackObj);
159 if (ret != OHOS::HDI::Camera::V1_0::NO_ERROR) {
160 CAMERA_LOGE("Camera host service set callback failed");
161 return ret;
162 }
163 }
164
165 return OHOS::HDI::Camera::V1_0::NO_ERROR;
166 }
167
GetCameraIds(std::vector<std::string> & cameraIds)168 int32_t CameraHostService::GetCameraIds(std::vector<std::string> &cameraIds)
169 {
170 std::vector<std::string>().swap(cameraIds);
171 if (cameraIdInfoList_.size() == 0) {
172 int32_t ret = UpdateCameraIdMapList();
173 if (ret != OHOS::HDI::Camera::V1_0::NO_ERROR) {
174 CAMERA_LOGE("Camera get cameraIds failed");
175 return ret;
176 }
177 }
178 for (auto cameraIdInfo : cameraIdInfoList_) {
179 if (cameraIdInfo.isDeleted == false) {
180 cameraIds.push_back(cameraIdInfo.currentCameraId);
181 }
182 }
183
184 return OHOS::HDI::Camera::V1_0::NO_ERROR;
185 }
186
GetCameraAbility(const std::string & cameraId,std::vector<uint8_t> & cameraAbility)187 int32_t CameraHostService::GetCameraAbility(const std::string &cameraId,
188 std::vector<uint8_t> &cameraAbility)
189 {
190 OHOS::sptr<ICameraHostVdi> cameraHostVdi = GetCameraHostVdi(cameraId);
191 CHECK_IF_PTR_NULL_RETURN_VALUE(cameraHostVdi, OHOS::HDI::Camera::V1_0::INVALID_ARGUMENT);
192
193 std::string vdiCameraId = GetVendorCameraId(cameraId);
194 if (vdiCameraId == "") {
195 CAMERA_LOGE("Get vendor camera id failed");
196 return OHOS::HDI::Camera::V1_0::INVALID_ARGUMENT;
197 }
198
199 return cameraHostVdi->GetCameraAbility(vdiCameraId, cameraAbility);
200 }
201
OpenCamera(const std::string & cameraId,const sptr<ICameraDeviceCallback> & callbackObj,sptr<ICameraDevice> & device)202 int32_t CameraHostService::OpenCamera(const std::string &cameraId, const sptr<ICameraDeviceCallback> &callbackObj,
203 sptr<ICameraDevice> &device)
204 {
205 OHOS::sptr<ICameraHostVdi> cameraHostVdi = GetCameraHostVdi(cameraId);
206 CHECK_IF_PTR_NULL_RETURN_VALUE(cameraHostVdi, OHOS::HDI::Camera::V1_0::INVALID_ARGUMENT);
207
208 std::string vdiCameraId = GetVendorCameraId(cameraId);
209 if (vdiCameraId == "") {
210 CAMERA_LOGE("Get vendor camera id failed");
211 return OHOS::HDI::Camera::V1_0::INVALID_ARGUMENT;
212 }
213
214 OHOS::sptr<ICameraDeviceVdi> deviceVdi = nullptr;
215 OHOS::sptr<ICameraDeviceVdiCallback> vdiCallbackObj = new CameraDeviceServiceCallback(callbackObj);
216 if (vdiCallbackObj == nullptr) {
217 CAMERA_LOGE("Open camera error, vdiCallbackObj is nullptr");
218 return OHOS::HDI::Camera::V1_0::INSUFFICIENT_RESOURCES;
219 }
220 int32_t ret = cameraHostVdi->OpenCamera(vdiCameraId, vdiCallbackObj, deviceVdi);
221 if (ret != OHOS::HDI::Camera::V1_0::NO_ERROR) {
222 CAMERA_LOGE("Open camera error, ret=%{public}d", ret);
223 return ret;
224 }
225 if (deviceVdi == nullptr) {
226 CAMERA_LOGE("Open camera error, deviceVdi is nullptr");
227 return OHOS::HDI::Camera::V1_0::INSUFFICIENT_RESOURCES;
228 }
229 device = new CameraDeviceService(deviceVdi);
230 if (device == nullptr) {
231 CAMERA_LOGE("Open camera error, device is nullptr");
232 return OHOS::HDI::Camera::V1_0::INSUFFICIENT_RESOURCES;
233 }
234
235 return OHOS::HDI::Camera::V1_0::NO_ERROR;
236 }
237
SetFlashlight(const std::string & cameraId,bool isEnable)238 int32_t CameraHostService::SetFlashlight(const std::string &cameraId, bool isEnable)
239 {
240 OHOS::sptr<ICameraHostVdi> cameraHostVdi = GetCameraHostVdi(cameraId);
241 CHECK_IF_PTR_NULL_RETURN_VALUE(cameraHostVdi, OHOS::HDI::Camera::V1_0::INVALID_ARGUMENT);
242
243 std::string vdiCameraId = GetVendorCameraId(cameraId);
244 if (vdiCameraId == "") {
245 CAMERA_LOGE("Get vendor camera id failed");
246 return OHOS::HDI::Camera::V1_0::INVALID_ARGUMENT;
247 }
248
249 return cameraHostVdi->SetFlashlight(vdiCameraId, isEnable);
250 }
251
UpdateCameraIdMapList()252 int32_t CameraHostService::UpdateCameraIdMapList()
253 {
254 std::vector<CameraIdInfo>().swap(cameraIdInfoList_);
255 int32_t currentCameraIndex = 1;
256 for (auto cameraHostVdi : cameraHostVdiList_) {
257 CHECK_IF_PTR_NULL_RETURN_VALUE(cameraHostVdi, OHOS::HDI::Camera::V1_0::INVALID_ARGUMENT);
258
259 std::vector<std::string> vdiCameraIds;
260 int32_t ret = cameraHostVdi->GetCameraIds(vdiCameraIds);
261 if (ret != OHOS::HDI::Camera::V1_0::NO_ERROR) {
262 CAMERA_LOGE("Camera host service set callback failed");
263 return ret;
264 }
265 for (auto id : vdiCameraIds) {
266 struct CameraIdInfo cameraIdInfo;
267 std::string currentCameraId = "lcam00" + std::to_string(currentCameraIndex);
268 cameraIdInfo.currentCameraId = currentCameraId;
269 cameraIdInfo.cameraHostVdi = cameraHostVdi;
270 cameraIdInfo.vendorCameraId = id;
271 cameraIdInfo.isDeleted = false;
272 cameraIdInfoList_.push_back(cameraIdInfo);
273 currentCameraIndex++;
274 }
275 }
276
277 return OHOS::HDI::Camera::V1_0::NO_ERROR;
278 }
279
GetCameraHostVdi(const std::string & currentCameraId)280 OHOS::sptr<ICameraHostVdi> CameraHostService::GetCameraHostVdi(const std::string ¤tCameraId)
281 {
282 auto itr = std::find_if(cameraIdInfoList_.begin(), cameraIdInfoList_.end(),
283 [¤tCameraId](const struct CameraIdInfo &cameraIdInfo) {
284 return currentCameraId == cameraIdInfo.currentCameraId;
285 });
286 if (itr == cameraIdInfoList_.end()) {
287 CAMERA_LOGE("Get camera host vdi failed, current camera id = %{public}s doesn't exist",
288 currentCameraId.c_str());
289 return nullptr;
290 }
291
292 return itr->cameraHostVdi;
293 }
294
GetVendorCameraId(const std::string & currentCameraId)295 const std::string CameraHostService::GetVendorCameraId(const std::string ¤tCameraId)
296 {
297 auto itr = std::find_if(cameraIdInfoList_.begin(), cameraIdInfoList_.end(),
298 [¤tCameraId](const struct CameraIdInfo &cameraIdInfo) {
299 return currentCameraId == cameraIdInfo.currentCameraId;
300 });
301 if (itr == cameraIdInfoList_.end()) {
302 CAMERA_LOGE("Get vendor camera id failed, current camera id = %{public}s doesn't exist",
303 currentCameraId.c_str());
304 return std::string("");
305 }
306
307 return itr->vendorCameraId;
308 }
309 } // end namespace OHOS::Camera
310