1 /*
2  * Copyright (c) 2021 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 "camera_host.h"
17 #include "camera.h"
18 #include "camera_device.h"
19 #include "camera_device_callback_wrapper.h"
20 #include "camera_host_callback_wrapper.h"
21 #include <dlfcn.h>
22 
23 namespace OHOS::Camera {
CreateCameraHost()24 std::shared_ptr<CameraHost> CameraHost::CreateCameraHost()
25 {
26     std::shared_ptr<CameraHost> cameraHost = std::make_shared<CameraHost>();
27     if (cameraHost == nullptr) {
28         CAMERA_LOGE("new camera host implement failed.");
29         return nullptr;
30     }
31 
32     CamRetCode rc = cameraHost->Init();
33     if (rc != NO_ERROR) {
34         CAMERA_LOGE("camera host init failed.");
35         return nullptr;
36     }
37 
38     return cameraHost;
39 }
40 
CameraHost()41 CameraHost::CameraHost() {}
42 
~CameraHost()43 CameraHost::~CameraHost()
44 {
45     if (host_ != nullptr) {
46         delete host_;
47         host_ = nullptr;
48     }
49 
50     if (handler_ != nullptr) {
51         ::dlclose(handler_);
52     }
53 }
54 
SetCallback(const OHOS::sptr<ICameraHostCallback> & callback)55 CamRetCode CameraHost::SetCallback(const OHOS::sptr<ICameraHostCallback>& callback)
56 {
57     CameraHostCallbackCIF cb;
58     BindCameraHostCallback(callback);
59 
60     cb.OnCameraStatus = HostCBOnCameraStatus;
61     cb.OnFlashlightStatus = HostCBOnFlashlightStatus;
62 
63     host_->SetCallback(cb);
64 
65     return NO_ERROR;
66 }
67 
GetCameraIds(std::vector<std::string> & cameraIds)68 CamRetCode CameraHost::GetCameraIds(std::vector<std::string>& cameraIds)
69 {
70     char** ids = nullptr;
71     int size = 0;
72     int ret = host_->GetCameraIds(&ids, &size);
73     if (ret != NO_ERROR) {
74         return static_cast<CamRetCode>(ret);
75     }
76     for (int i = 0; i < size; i++) {
77         cameraIds.push_back(ids[i]);
78     }
79 
80     return NO_ERROR;
81 }
82 
GetCameraAbility(const std::string & cameraId,std::shared_ptr<CameraAbility> & ability)83 CamRetCode CameraHost::GetCameraAbility(const std::string& cameraId, std::shared_ptr<CameraAbility>& ability)
84 {
85     CameraAbilityCIF* meta = nullptr;
86     int ret = host_->GetCameraAbility(cameraId.c_str(), meta);
87     ability = std::make_shared<CameraAbility>(0, 0);
88     return static_cast<CamRetCode>(ret);
89 }
90 
OpenCamera(const std::string & cameraId,const OHOS::sptr<ICameraDeviceCallback> & callback,OHOS::sptr<ICameraDevice> & pDevice)91 CamRetCode CameraHost::OpenCamera(const std::string& cameraId,
92                                   const OHOS::sptr<ICameraDeviceCallback>& callback,
93                                   OHOS::sptr<ICameraDevice>& pDevice)
94 {
95     CameraDeviceCallbackCIF cb;
96     BindCameraDeviceCallback(callback);
97 
98     cb.OnError = DeviceCBOnError;
99     cb.OnResult = DeviceCBOnResult;
100 
101     CameraDeviceCIF* device = nullptr;
102     const char* id = cameraId.c_str();
103     int ret = host_->OpenCamera(id, cb, device);
104 
105     auto cd = new CameraDevice;
106     if (cd == nullptr) {
107         return INSUFFICIENT_RESOURCES;
108     }
109     cd->Init(device);
110     pDevice = cd;
111     return static_cast<CamRetCode>(ret);
112 }
113 
SetFlashlight(const std::string & cameraId,bool & isEnable)114 CamRetCode CameraHost::SetFlashlight(const std::string& cameraId, bool& isEnable)
115 {
116     if (host_ == nullptr) {
117         return INSUFFICIENT_RESOURCES;
118     }
119 
120     const char* id = cameraId.c_str();
121     int ret = host_->SetFlashlight(id, reinterpret_cast<int*>(&isEnable));
122     return static_cast<CamRetCode>(ret);
123 }
124 
Init()125 CamRetCode CameraHost::Init()
126 {
127     host_ = new CameraHostCIF();
128     if (host_ == nullptr) {
129         CAMERA_LOGE("%{public}s, create camera host failed.", __FUNCTION__);
130         return INSUFFICIENT_RESOURCES;
131     }
132 
133     handler_ = ::dlopen(CAMERA_C_HAL_LIB_PATH, RTLD_NOW);
134     if (handler_ == nullptr) {
135         CAMERA_LOGE("%{public}s, dlopen %{public}s failed, %{public}s",
136             __FUNCTION__, CAMERA_C_HAL_LIB_PATH, ::dlerror());
137         return INSUFFICIENT_RESOURCES;
138     }
139 
140     host_->SetCallback = reinterpret_cast<HOST_C_FUNC_SETCALLBACK>(::dlsym(handler_, "SetCallback"));
141     if (host_->SetCallback == nullptr) {
142         CAMERA_LOGE("%{public}s, can't get symbol of function SetCallback, %{public}s", __FUNCTION__, ::dlerror());
143         return INSUFFICIENT_RESOURCES;
144     }
145 
146     host_->GetCameraIds = reinterpret_cast<HOST_C_FUNC_GETCAMERAIDS>(::dlsym(handler_, "GetCameraIds"));
147     if (host_->GetCameraIds == nullptr) {
148         CAMERA_LOGE("%{public}s, can't get symbol of function GetCameraIds, %{public}s", __FUNCTION__, ::dlerror());
149         return INSUFFICIENT_RESOURCES;
150     }
151 
152     host_->GetCameraAbility = reinterpret_cast<HOST_C_FUNC_GETCAMERAABILITY>(::dlsym(handler_, "GetCameraAbility"));
153     if (host_->GetCameraAbility == nullptr) {
154         CAMERA_LOGE("%{public}s, can't get symbol of function GetCameraAbility, %{public}s", __FUNCTION__, ::dlerror());
155         return INSUFFICIENT_RESOURCES;
156     }
157 
158     host_->OpenCamera = reinterpret_cast<HOST_C_FUNC_OPENCAMERA>(::dlsym(handler_, "OpenCamera"));
159     if (host_->OpenCamera == nullptr) {
160         CAMERA_LOGE("%{public}s, can't get symbol of function OpenCamera, %{public}s", __FUNCTION__, ::dlerror());
161         return INSUFFICIENT_RESOURCES;
162     }
163 
164     host_->SetFlashlight = reinterpret_cast<HOST_C_FUNC_SETFLASHLIGHT>(::dlsym(handler_, "SetFlashlight"));
165     if (host_->SetFlashlight == nullptr) {
166         CAMERA_LOGE("%{public}s, can't get symbol of function SetFlashlight, %{public}s", __FUNCTION__, ::dlerror());
167         return INSUFFICIENT_RESOURCES;
168     }
169 
170     return NO_ERROR;
171 }
172 } // namespace OHOS::Camera
173