• 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 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 &currentCameraId)
286 {
287     auto itr = std::find_if(cameraIdInfoList_.begin(), cameraIdInfoList_.end(),
288         [&currentCameraId](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 &currentCameraId)
301 {
302     auto itr = std::find_if(cameraIdInfoList_.begin(), cameraIdInfoList_.end(),
303         [&currentCameraId](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