1 /*
2 * Copyright (c) 2022-2025 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 "dcamera_hdf_operate.h"
17
18 #include <hdf_base.h>
19 #include <hdf_device_class.h>
20
21 #include "anonymous_string.h"
22 #include "distributed_camera_errno.h"
23 #include "distributed_hardware_log.h"
24 #include "iproxy_broker.h"
25
26 #undef DH_LOG_TAG
27 #define DH_LOG_TAG "DCameraHdfOperate"
28
29 namespace OHOS {
30 namespace DistributedHardware {
31 IMPLEMENT_SINGLE_INSTANCE(DCameraHdfOperate);
LoadDcameraHDFImpl(std::shared_ptr<HdfDeathCallback> callback)32 int32_t DCameraHdfOperate::LoadDcameraHDFImpl(std::shared_ptr<HdfDeathCallback> callback)
33 {
34 DHLOGI("Load camera hdf impl begin!");
35 int32_t ret = LoadDevice();
36 if (ret != DCAMERA_OK) {
37 DHLOGE("LoadDevice failed, ret: %{public}d.", ret);
38 return ret;
39 }
40 ret = RegisterHdfListener();
41 if (ret != DCAMERA_OK) {
42 DHLOGE("RegisterHdfListener failed, ret: %{public}d.", ret);
43 UnLoadDevice();
44 return ret;
45 }
46 hdfDeathCallback_ = callback;
47 ret = AddHdfDeathBind();
48 if (ret != DCAMERA_OK) {
49 DHLOGE("AddHdfDeathBind failed, ret: %{public}d.", ret);
50 UnRegisterHdfListener();
51 UnLoadDevice();
52 return ret;
53 }
54 DHLOGI("Load camera hdf impl end!");
55 return DCAMERA_OK;
56 }
57
UnLoadDcameraHDFImpl()58 int32_t DCameraHdfOperate::UnLoadDcameraHDFImpl()
59 {
60 DHLOGI("UnLoad camera hdf impl begin!");
61 int32_t ret = RemoveHdfDeathBind();
62 if (ret != DCAMERA_OK) {
63 DHLOGE("RemoveHdfDeathBind failed, ret: %{public}d.", ret);
64 }
65 ret = UnRegisterHdfListener();
66 if (ret != DCAMERA_OK) {
67 DHLOGE("UnRegisterHdfListener failed, ret: %{public}d.", ret);
68 }
69 ret = UnLoadDevice();
70 if (ret != DCAMERA_OK) {
71 DHLOGE("UnLoadDevice failed, ret: %{public}d.", ret);
72 }
73 DHLOGI("UnLoad camera hdf impl end!");
74 return DCAMERA_OK;
75 }
76
OnHdfHostDied()77 void DCameraHdfOperate::OnHdfHostDied()
78 {
79 DHLOGI("On hdf host died begin!");
80 if (hdfDeathCallback_) {
81 DHLOGI("Call hdf host died callback!");
82 hdfDeathCallback_->OnHdfHostDied();
83 }
84 DHLOGI("On hdf host died end!");
85 }
86
WaitLoadCameraService()87 int32_t DCameraHdfOperate::WaitLoadCameraService()
88 {
89 DHLOGI("wait Load camera service.");
90 std::unique_lock<std::mutex> lock(hdfOperateMutex_);
91 hdfOperateCon_.wait_for(lock, std::chrono::milliseconds(CAMERA_WAIT_TIME), [this] {
92 return (this->cameraServStatus_.load() == OHOS::HDI::ServiceManager::V1_0::SERVIE_STATUS_START);
93 });
94 if (cameraServStatus_.load() != OHOS::HDI::ServiceManager::V1_0::SERVIE_STATUS_START) {
95 DHLOGE("wait load cameraService failed, status %{public}d", cameraServStatus_.load());
96 return DCAMERA_BAD_OPERATE;
97 }
98 return DCAMERA_OK;
99 }
100
WaitLoadProviderService()101 int32_t DCameraHdfOperate::WaitLoadProviderService()
102 {
103 DHLOGI("wait Load provider service.");
104 std::unique_lock<std::mutex> lock(hdfOperateMutex_);
105 hdfOperateCon_.wait_for(lock, std::chrono::milliseconds(CAMERA_WAIT_TIME), [this] {
106 return (this->providerServStatus_.load() == OHOS::HDI::ServiceManager::V1_0::SERVIE_STATUS_START);
107 });
108 if (providerServStatus_.load() != OHOS::HDI::ServiceManager::V1_0::SERVIE_STATUS_START) {
109 DHLOGE("wait load providerService failed, status %{public}d", providerServStatus_.load());
110 return DCAMERA_BAD_OPERATE;
111 }
112 return DCAMERA_OK;
113 }
114
MakeServStatListener()115 OHOS::sptr<IServStatListener> DCameraHdfOperate::MakeServStatListener()
116 {
117 return OHOS::sptr<IServStatListener>(
118 new DCameraHdfServStatListener(DCameraHdfServStatListener::StatusCallback([&](const ServiceStatus& status) {
119 DHLOGI("LoadCameraService service status callback, serviceName: %{public}s, status: %{public}d",
120 status.serviceName.c_str(), status.status);
121 std::unique_lock<std::mutex> lock(hdfOperateMutex_);
122 if (status.serviceName == CAMERA_SERVICE_NAME) {
123 cameraServStatus_.store(status.status);
124 hdfOperateCon_.notify_one();
125 } else if (status.serviceName == PROVIDER_SERVICE_NAME) {
126 providerServStatus_.store(status.status);
127 hdfOperateCon_.notify_one();
128 }
129 }))
130 );
131 }
132
LoadDevice()133 int32_t DCameraHdfOperate::LoadDevice()
134 {
135 DHLOGI("LoadDevice for camera begin!");
136 servMgr_ = IServiceManager::Get();
137 devmgr_ = IDeviceManager::Get();
138 if (servMgr_ == nullptr || devmgr_ == nullptr) {
139 DHLOGE("get hdi service manager or device manager failed!");
140 return DCAMERA_BAD_VALUE;
141 }
142 OHOS::sptr<IServStatListener> listener = MakeServStatListener();
143 if (servMgr_->RegisterServiceStatusListener(listener, DEVICE_CLASS_CAMERA) != 0) {
144 DHLOGE("RegisterServiceStatusListener failed!");
145 return DCAMERA_BAD_OPERATE;
146 }
147 DHLOGI("Load camera service.");
148 int32_t ret = devmgr_->LoadDevice(CAMERA_SERVICE_NAME);
149 if (ret != HDF_SUCCESS && ret != HDF_ERR_DEVICE_BUSY) {
150 DHLOGE("Load camera service failed!");
151 servMgr_->UnregisterServiceStatusListener(listener);
152 return DCAMERA_BAD_OPERATE;
153 }
154 if (WaitLoadCameraService() != DCAMERA_OK) {
155 DHLOGE("Wait load camera service failed!");
156 servMgr_->UnregisterServiceStatusListener(listener);
157 return DCAMERA_BAD_OPERATE;
158 }
159 ret = devmgr_->LoadDevice(PROVIDER_SERVICE_NAME);
160 if (ret != HDF_SUCCESS && ret != HDF_ERR_DEVICE_BUSY) {
161 DHLOGE("Load camera provider service failed!");
162 devmgr_->UnloadDevice(CAMERA_SERVICE_NAME);
163 servMgr_->UnregisterServiceStatusListener(listener);
164 return DCAMERA_BAD_OPERATE;
165 }
166 if (WaitLoadProviderService() != DCAMERA_OK) {
167 DHLOGE("Wait load camera provider service failed!");
168 devmgr_->UnloadDevice(CAMERA_SERVICE_NAME);
169 servMgr_->UnregisterServiceStatusListener(listener);
170 return DCAMERA_BAD_OPERATE;
171 }
172 if (servMgr_->UnregisterServiceStatusListener(listener) != 0) {
173 DHLOGE("UnregisterServiceStatusListener failed!");
174 }
175 DHLOGI("LoadDevice for camera end!");
176 return DCAMERA_OK;
177 }
178
UnLoadDevice()179 int32_t DCameraHdfOperate::UnLoadDevice()
180 {
181 DHLOGI("UnLoadDevice for camera begin!");
182 if (devmgr_ == nullptr) {
183 DHLOGE("hdi device manager is nullptr!");
184 return DCAMERA_BAD_VALUE;
185 }
186 int32_t ret = devmgr_->UnloadDevice(CAMERA_SERVICE_NAME);
187 if (ret != 0) {
188 DHLOGE("Unload camera service failed, ret: %{public}d", ret);
189 }
190 ret = devmgr_->UnloadDevice(PROVIDER_SERVICE_NAME);
191 if (ret != 0) {
192 DHLOGE("Unload provider service failed, ret: %d", ret);
193 }
194 cameraServStatus_.store(CAMERA_INVALID_VALUE);
195 providerServStatus_.store(CAMERA_INVALID_VALUE);
196 DHLOGI("UnLoadDevice for camera end!");
197 return DCAMERA_OK;
198 }
199
RegisterHdfListener()200 int32_t DCameraHdfOperate::RegisterHdfListener()
201 {
202 DHLOGI("RegisterHdfListener for camera begin!");
203 camHdiProvider_ = IDCameraProvider::Get(PROVIDER_SERVICE_NAME);
204 if (camHdiProvider_ == nullptr) {
205 DHLOGE("Get hdi camera provider failed.");
206 return DCAMERA_BAD_VALUE;
207 }
208 if (fwkDCameraHdfCallback_ == nullptr) {
209 if (MakeFwkDCameraHdfCallback() != DCAMERA_OK) {
210 DHLOGE("Create FwkDCameraHdfCallback failed.");
211 return DCAMERA_BAD_VALUE;
212 }
213 }
214 int32_t ret = camHdiProvider_->RegisterCameraHdfListener(HDF_LISTENER_SERVICE_NAME, fwkDCameraHdfCallback_);
215 if (ret != DCAMERA_OK) {
216 DHLOGE("Call hdf proxy RegisterCameraHdfListener failed, ret: %{public}d.", ret);
217 return ret;
218 }
219 DHLOGI("RegisterHdfListener for camera end!");
220 return DCAMERA_OK;
221 }
222
UnRegisterHdfListener()223 int32_t DCameraHdfOperate::UnRegisterHdfListener()
224 {
225 DHLOGI("UnRegisterHdfListener for camera begin!");
226 if (camHdiProvider_ == nullptr) {
227 DHLOGE("hdi camera provider is nullptr.");
228 return DCAMERA_BAD_VALUE;
229 }
230 int32_t ret = camHdiProvider_->UnRegisterCameraHdfListener(HDF_LISTENER_SERVICE_NAME);
231 if (ret != DCAMERA_OK) {
232 DHLOGE("Call hdf proxy UnRegisterCameraHdfListener failed, ret: %{public}d.", ret);
233 return ret;
234 }
235 DHLOGI("UnRegisterHdfListener for camera end!");
236 return DCAMERA_OK;
237 }
238
AddHdfDeathBind()239 int32_t DCameraHdfOperate::AddHdfDeathBind()
240 {
241 DHLOGI("AddHdfDeathBind for dcamera begin!");
242 if (camHdiProvider_ == nullptr) {
243 DHLOGE("hdi dcamera manager is nullptr!");
244 return DCAMERA_BAD_VALUE;
245 }
246 sptr<IRemoteObject> remote = OHOS::HDI::hdi_objcast<IDCameraProvider>(camHdiProvider_);
247 if (remote == nullptr) {
248 DHLOGE("Get remote from hdi dcamera manager failed!");
249 return DCAMERA_BAD_VALUE;
250 }
251 if (remote->AddDeathRecipient(hdfDeathRecipient_) == false) {
252 DHLOGE("Call AddDeathRecipient failed!");
253 return DCAMERA_BAD_VALUE;
254 }
255 DHLOGI("AddHdfDeathBind for dcamera end!");
256 return DCAMERA_OK;
257 }
258
RemoveHdfDeathBind()259 int32_t DCameraHdfOperate::RemoveHdfDeathBind()
260 {
261 DHLOGI("RemoveHdfDeathBind for dcamera begin!");
262 if (camHdiProvider_ == nullptr) {
263 DHLOGE("hdi dcamera manager is nullptr!");
264 return DCAMERA_BAD_VALUE;
265 }
266 sptr<IRemoteObject> remote = OHOS::HDI::hdi_objcast<IDCameraProvider>(camHdiProvider_);
267 if (remote == nullptr) {
268 DHLOGE("Get remote from hdi dcamera manager failed!");
269 return DCAMERA_BAD_VALUE;
270 }
271 if (remote->RemoveDeathRecipient(hdfDeathRecipient_) == false) {
272 DHLOGE("Call RemoveDeathRecipient failed!");
273 return DCAMERA_BAD_OPERATE;
274 }
275 DHLOGI("RemoveHdfDeathBind for dcamera end!");
276 return DCAMERA_OK;
277 }
278
MakeFwkDCameraHdfCallback()279 int32_t DCameraHdfOperate::MakeFwkDCameraHdfCallback()
280 {
281 std::lock_guard<std::mutex> locker(fwkDCameraHdfCallbackMutex_);
282 if (fwkDCameraHdfCallback_ == nullptr) {
283 fwkDCameraHdfCallback_ = OHOS::sptr<FwkDCameraHdfCallback>(new FwkDCameraHdfCallback());
284 if (fwkDCameraHdfCallback_ == nullptr) {
285 return DCAMERA_BAD_VALUE;
286 }
287 }
288 return DCAMERA_OK;
289 }
290
OnReceive(const ServiceStatus & status)291 void DCameraHdfServStatListener::OnReceive(const ServiceStatus& status)
292 {
293 DHLOGI("service status on receive");
294 if (status.serviceName == CAMERA_SERVICE_NAME || status.serviceName == PROVIDER_SERVICE_NAME) {
295 callback_(status);
296 }
297 }
298
NotifyEvent(int32_t devId,const DCameraHDFEvent & event)299 int32_t FwkDCameraHdfCallback::NotifyEvent(int32_t devId, const DCameraHDFEvent& event)
300 {
301 (void)devId;
302 (void)event;
303 return DCAMERA_OK;
304 }
305
OnRemoteDied(const wptr<IRemoteObject> & remote)306 void HdfDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
307 {
308 DHLOGI("On remote died!");
309 DCameraHdfOperate::GetInstance().OnHdfHostDied();
310 }
311 } // namespace DistributedHardware
312 } // namespace OHOS
313