1 /*
2  * Copyright (c) 2022-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 "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 
25 namespace OHOS {
26 namespace DistributedHardware {
27 IMPLEMENT_SINGLE_INSTANCE(DCameraHdfOperate);
28 
OnReceive(const ServiceStatus & status)29 void DCameraHdfServStatListener::OnReceive(const ServiceStatus& status)
30 {
31     DHLOGI("service status on receive");
32     if (status.serviceName == CAMERA_SERVICE_NAME || status.serviceName == PROVIDER_SERVICE_NAME) {
33         callback_(status);
34     }
35 }
36 
LoadDcameraHDFImpl()37 int32_t DCameraHdfOperate::LoadDcameraHDFImpl()
38 {
39     if (cameraServStatus_.load() == OHOS::HDI::ServiceManager::V1_0::SERVIE_STATUS_START &&
40         providerServStatus_.load() == OHOS::HDI::ServiceManager::V1_0::SERVIE_STATUS_START) {
41         DHLOGI("service has already start");
42         return DCAMERA_OK;
43     }
44     OHOS::sptr<IServiceManager> servMgr = IServiceManager::Get();
45     OHOS::sptr<IDeviceManager> devmgr = IDeviceManager::Get();
46     if (servMgr == nullptr || devmgr == nullptr) {
47         DHLOGE("get hdi service manager or device manager failed!");
48         return DCAMERA_BAD_VALUE;
49     }
50 
51     ::OHOS::sptr<IServStatListener> listener(
52         new DCameraHdfServStatListener(DCameraHdfServStatListener::StatusCallback([&](const ServiceStatus& status) {
53             DHLOGI("LoadCameraService service status callback, serviceName: %{public}s, status: %{public}d",
54                 status.serviceName.c_str(), status.status);
55             std::unique_lock<std::mutex> lock(hdfOperateMutex_);
56             if (status.serviceName == CAMERA_SERVICE_NAME) {
57                 cameraServStatus_.store(status.status);
58                 hdfOperateCon_.notify_one();
59             } else if (status.serviceName == PROVIDER_SERVICE_NAME) {
60                 providerServStatus_.store(status.status);
61                 hdfOperateCon_.notify_one();
62             }
63         })));
64     if (servMgr->RegisterServiceStatusListener(listener, DEVICE_CLASS_CAMERA) != 0) {
65         DHLOGE("RegisterServiceStatusListener failed!");
66         return DCAMERA_BAD_VALUE;
67     }
68 
69     DHLOGI("Load camera service.");
70     int32_t ret = devmgr->LoadDevice(CAMERA_SERVICE_NAME);
71     if (ret != HDF_SUCCESS && ret != HDF_ERR_DEVICE_BUSY) {
72         return DCAMERA_BAD_OPERATE;
73     }
74     if (WaitLoadCameraService() != DCAMERA_OK) {
75         return DCAMERA_BAD_OPERATE;
76     }
77 
78     ret = devmgr->LoadDevice(PROVIDER_SERVICE_NAME);
79     if (ret != HDF_SUCCESS && ret != HDF_ERR_DEVICE_BUSY) {
80         DHLOGE("Load provider service failed!");
81         return DCAMERA_BAD_OPERATE;
82     }
83     if (WaitLoadProviderService() != DCAMERA_OK) {
84         return DCAMERA_BAD_OPERATE;
85     }
86 
87     if (servMgr->UnregisterServiceStatusListener(listener) != 0) {
88         DHLOGE("UnregisterServiceStatusListener failed!");
89     }
90     return DCAMERA_OK;
91 }
92 
WaitLoadCameraService()93 int32_t DCameraHdfOperate::WaitLoadCameraService()
94 {
95     DHLOGI("wait Load camera service.");
96     std::unique_lock<std::mutex> lock(hdfOperateMutex_);
97     hdfOperateCon_.wait_for(lock, std::chrono::milliseconds(WAIT_TIME), [this] {
98         return (this->cameraServStatus_.load() == OHOS::HDI::ServiceManager::V1_0::SERVIE_STATUS_START);
99     });
100 
101     if (cameraServStatus_.load() != OHOS::HDI::ServiceManager::V1_0::SERVIE_STATUS_START) {
102         DHLOGE("wait load cameraService failed, status %{public}d", cameraServStatus_.load());
103         return DCAMERA_BAD_OPERATE;
104     }
105 
106     return DCAMERA_OK;
107 }
108 
WaitLoadProviderService()109 int32_t DCameraHdfOperate::WaitLoadProviderService()
110 {
111     DHLOGI("wait Load provider service.");
112     std::unique_lock<std::mutex> lock(hdfOperateMutex_);
113     hdfOperateCon_.wait_for(lock, std::chrono::milliseconds(WAIT_TIME), [this] {
114         return (this->providerServStatus_.load() == OHOS::HDI::ServiceManager::V1_0::SERVIE_STATUS_START);
115     });
116 
117     if (providerServStatus_.load() != OHOS::HDI::ServiceManager::V1_0::SERVIE_STATUS_START) {
118         DHLOGE("wait load providerService failed, status %{public}d", providerServStatus_.load());
119         return DCAMERA_BAD_OPERATE;
120     }
121 
122     return DCAMERA_OK;
123 }
124 
UnLoadDcameraHDFImpl()125 int32_t DCameraHdfOperate::UnLoadDcameraHDFImpl()
126 {
127     DHLOGI("UnLoadCameraHDFImpl begin!");
128     OHOS::sptr<IDeviceManager> devmgr = IDeviceManager::Get();
129     if (devmgr == nullptr) {
130         DHLOGE("get hdi device manager failed!");
131         return DCAMERA_BAD_VALUE;
132     }
133 
134     int32_t ret = devmgr->UnloadDevice(CAMERA_SERVICE_NAME);
135     if (ret != 0) {
136         DHLOGE("Unload camera service failed, ret: %{public}d", ret);
137     }
138     ret = devmgr->UnloadDevice(PROVIDER_SERVICE_NAME);
139     if (ret != 0) {
140         DHLOGE("Unload provider service failed, ret: %d", ret);
141     }
142     cameraServStatus_.store(INVALID_VALUE);
143     providerServStatus_.store(INVALID_VALUE);
144     DHLOGI("UnLoadCameraHDFImpl end!");
145     return DCAMERA_OK;
146 }
147 } // namespace DistributedHardware
148 } // namespace OHOS
149