• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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