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 CameraHalHicollie cameraHalHicollie("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 CameraHalHicollie cameraHalHicollie("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_LOGD("ctor, instance");
143 }
144
~CameraHostService()145 CameraHostService::~CameraHostService()
146 {
147 HdfCloseVdiLoaderList(cameraHostVdiLoaderList_);
148 CAMERA_LOGD("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 CameraHalHicollie cameraHalHicollie("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 ICameraHostVdi* cameraHostVdi = GetCameraHostVdi(cameraId);
211 CHECK_IF_PTR_NULL_RETURN_VALUE(cameraHostVdi, OHOS::HDI::Camera::V1_0::INVALID_ARGUMENT);
212
213 std::string vdiCameraId = GetVendorCameraId(cameraId);
214 if (vdiCameraId == "") {
215 CAMERA_LOGE("Get vendor camera id failed");
216 return OHOS::HDI::Camera::V1_0::INVALID_ARGUMENT;
217 }
218
219 OHOS::sptr<ICameraDeviceVdi> deviceVdi = nullptr;
220 OHOS::sptr<ICameraDeviceVdiCallback> vdiCallbackObj = new CameraDeviceServiceCallback(callbackObj);
221 if (vdiCallbackObj == nullptr) {
222 CAMERA_LOGE("Open camera error, vdiCallbackObj is nullptr");
223 return OHOS::HDI::Camera::V1_0::INSUFFICIENT_RESOURCES;
224 }
225 int32_t ret = cameraHostVdi->OpenCamera(vdiCameraId, vdiCallbackObj, deviceVdi);
226 if (ret != OHOS::HDI::Camera::V1_0::NO_ERROR) {
227 CAMERA_LOGE("Open camera error, ret=%{public}d", ret);
228 return ret;
229 }
230 if (deviceVdi == nullptr) {
231 CAMERA_LOGE("Open camera error, deviceVdi is nullptr");
232 return OHOS::HDI::Camera::V1_0::INSUFFICIENT_RESOURCES;
233 }
234 device = new CameraDeviceService(deviceVdi);
235 if (device == nullptr) {
236 CAMERA_LOGE("Open camera error, device is nullptr");
237 return OHOS::HDI::Camera::V1_0::INSUFFICIENT_RESOURCES;
238 }
239
240 return OHOS::HDI::Camera::V1_0::NO_ERROR;
241 }
242
SetFlashlight(const std::string & cameraId,bool isEnable)243 int32_t CameraHostService::SetFlashlight(const std::string &cameraId, bool isEnable)
244 {
245 ICameraHostVdi* cameraHostVdi = GetCameraHostVdi(cameraId);
246 CHECK_IF_PTR_NULL_RETURN_VALUE(cameraHostVdi, OHOS::HDI::Camera::V1_0::INVALID_ARGUMENT);
247
248 std::string vdiCameraId = GetVendorCameraId(cameraId);
249 if (vdiCameraId == "") {
250 CAMERA_LOGE("Get vendor camera id failed");
251 return OHOS::HDI::Camera::V1_0::INVALID_ARGUMENT;
252 }
253
254 return cameraHostVdi->SetFlashlight(vdiCameraId, isEnable);
255 }
256
UpdateCameraIdMapList()257 int32_t CameraHostService::UpdateCameraIdMapList()
258 {
259 std::vector<CameraIdInfo>().swap(cameraIdInfoList_);
260 int32_t currentCameraIndex = 1;
261 for (auto cameraHostVdi : cameraHostVdiList_) {
262 CHECK_IF_PTR_NULL_RETURN_VALUE(cameraHostVdi, OHOS::HDI::Camera::V1_0::INVALID_ARGUMENT);
263
264 std::vector<std::string> vdiCameraIds;
265 int32_t ret = cameraHostVdi->GetCameraIds(vdiCameraIds);
266 if (ret != OHOS::HDI::Camera::V1_0::NO_ERROR) {
267 CAMERA_LOGE("Camera host service set callback failed");
268 return ret;
269 }
270 for (auto id : vdiCameraIds) {
271 struct CameraIdInfo cameraIdInfo;
272 std::string currentCameraId = "lcam00" + std::to_string(currentCameraIndex);
273 cameraIdInfo.currentCameraId = currentCameraId;
274 cameraIdInfo.cameraHostVdi = cameraHostVdi;
275 cameraIdInfo.vendorCameraId = id;
276 cameraIdInfo.isDeleted = false;
277 cameraIdInfoList_.push_back(cameraIdInfo);
278 currentCameraIndex++;
279 }
280 }
281
282 return OHOS::HDI::Camera::V1_0::NO_ERROR;
283 }
284
GetCameraHostVdi(const std::string & currentCameraId)285 ICameraHostVdi* CameraHostService::GetCameraHostVdi(const std::string ¤tCameraId)
286 {
287 auto itr = std::find_if(cameraIdInfoList_.begin(), cameraIdInfoList_.end(),
288 [¤tCameraId](const struct CameraIdInfo &cameraIdInfo) {
289 return currentCameraId == cameraIdInfo.currentCameraId;
290 });
291 if (itr == cameraIdInfoList_.end()) {
292 CAMERA_LOGE("Get camera host vdi failed, current camera id = %{public}s doesn't exist",
293 currentCameraId.c_str());
294 return nullptr;
295 }
296
297 return itr->cameraHostVdi;
298 }
299
GetVendorCameraId(const std::string & currentCameraId)300 const std::string CameraHostService::GetVendorCameraId(const std::string ¤tCameraId)
301 {
302 auto itr = std::find_if(cameraIdInfoList_.begin(), cameraIdInfoList_.end(),
303 [¤tCameraId](const struct CameraIdInfo &cameraIdInfo) {
304 return currentCameraId == cameraIdInfo.currentCameraId;
305 });
306 if (itr == cameraIdInfoList_.end()) {
307 CAMERA_LOGE("Get vendor camera id failed, current camera id = %{public}s doesn't exist",
308 currentCameraId.c_str());
309 return std::string("");
310 }
311
312 return itr->vendorCameraId;
313 }
314 } // end namespace OHOS::Camera
315