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