1 /*
2 * Copyright (c) 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 "driver_load_manager.h"
17
18 #include "iam_check.h"
19 #include "iam_logger.h"
20
21 #include "idevmgr_hdi.h"
22 #include "iservice_registry.h"
23 #include "iservmgr_hdi.h"
24 #include "relative_timer.h"
25 #include "system_ability_definition.h"
26 #include "system_param_manager.h"
27
28 #define LOG_TAG "PIN_AUTH_SA"
29
30 namespace OHOS {
31 namespace UserIam {
32 namespace PinAuth {
33 using namespace HDI;
34 using namespace HDI::ServiceManager::V1_0;
35 using namespace HDI::DeviceManager::V1_0;
36 const char *SERVICE_NAME = "pin_auth_interface_service";
37 class DriverManagerStatusListener : public ServStatListenerStub {
38 public:
39 DriverManagerStatusListener() = default;
40 ~DriverManagerStatusListener() override = default;
41
OnReceive(const ServiceStatus & status)42 void OnReceive(const ServiceStatus &status) override
43 {
44 if (status.serviceName != SERVICE_NAME) {
45 return;
46 }
47
48 IAM_LOGI("receive service %{public}s status %{public}d", status.serviceName.c_str(), status.status);
49 if (status.status == SERVIE_STATUS_START) {
50 DriverLoadManager::GetInstance().OnServiceStart();
51 } else if (status.status == SERVIE_STATUS_STOP) {
52 DriverLoadManager::GetInstance().OnServiceStop();
53 }
54 }
55 };
56
GetInstance()57 DriverLoadManager &DriverLoadManager::GetInstance()
58 {
59 static DriverLoadManager instance;
60 return instance;
61 }
62
StartSubscribe()63 void DriverLoadManager::StartSubscribe()
64 {
65 std::lock_guard<std::recursive_mutex> lock(mutex_);
66 if (isSubscribed_) {
67 return;
68 }
69
70 if (driverManagerStatusListener_ == nullptr) {
71 driverManagerStatusListener_ = SystemAbilityListener::Subscribe(
72 "DriverLoadManager", DEVICE_SERVICE_MANAGER_SA_ID,
73 []() { DriverLoadManager::GetInstance().OnDriverManagerAdd(); }, nullptr);
74 IF_FALSE_LOGE_AND_RETURN(driverManagerStatusListener_ != nullptr);
75 }
76
77 if (driverStatusListener_ == nullptr) {
78 driverStatusListener_ = new (std::nothrow) DriverManagerStatusListener();
79 IF_FALSE_LOGE_AND_RETURN(driverStatusListener_ != nullptr);
80 }
81
82 SystemParamManager::GetInstance().WatchParam(STOP_SA_KEY, [](const std::string &value) {
83 IAM_LOGI("%{public}s changed, value %{public}s", STOP_SA_KEY, value.c_str());
84 DriverLoadManager::GetInstance().OnSaStopping(value == TRUE_STR);
85 });
86 OnSaStopping(SystemParamManager::GetInstance().GetParam(STOP_SA_KEY, FALSE_STR) == TRUE_STR);
87
88 IAM_LOGI("success");
89 isSubscribed_ = true;
90 }
91
OnTimeout()92 void DriverLoadManager::OnTimeout()
93 {
94 std::lock_guard<std::recursive_mutex> lock(mutex_);
95 IAM_LOGI("timeout");
96 timerId_ = std::nullopt;
97 ProcessServiceStatus();
98 }
99
OnDriverManagerAdd()100 void DriverLoadManager::OnDriverManagerAdd()
101 {
102 std::lock_guard<std::recursive_mutex> lock(mutex_);
103 IAM_LOGI("start");
104 IF_FALSE_LOGE_AND_RETURN(driverStatusListener_ != nullptr);
105
106 auto servMgr = IServiceManager::Get();
107 IF_FALSE_LOGE_AND_RETURN(servMgr != nullptr);
108
109 (void)servMgr->UnregisterServiceStatusListener(driverStatusListener_);
110 int32_t ret = servMgr->RegisterServiceStatusListener(driverStatusListener_, DEVICE_CLASS_USERAUTH);
111 IF_FALSE_LOGE_AND_RETURN(ret == 0);
112
113 auto service = servMgr->GetService(SERVICE_NAME);
114 isDriverRunning_ = (service != nullptr);
115 IAM_LOGI("service %{public}s running: %{public}d", SERVICE_NAME, isDriverRunning_);
116
117 ProcessServiceStatus();
118 IAM_LOGI("end");
119 }
120
OnServiceStart()121 void DriverLoadManager::OnServiceStart()
122 {
123 std::lock_guard<std::recursive_mutex> lock(mutex_);
124 IAM_LOGI("service start");
125 isDriverRunning_ = true;
126 ProcessServiceStatus();
127 }
128
OnServiceStop()129 void DriverLoadManager::OnServiceStop()
130 {
131 std::lock_guard<std::recursive_mutex> lock(mutex_);
132 IAM_LOGI("service stop");
133 isDriverRunning_ = false;
134 ProcessServiceStatus();
135 }
136
OnSaStopping(bool isStopping)137 void DriverLoadManager::OnSaStopping(bool isStopping)
138 {
139 std::lock_guard<std::recursive_mutex> lock(mutex_);
140 isSaStopping_ = isStopping;
141 ProcessServiceStatus();
142 }
143
LoadDriver()144 bool DriverLoadManager::LoadDriver()
145 {
146 auto devMgr = IDeviceManager::Get();
147 IF_FALSE_LOGE_AND_RETURN_VAL(devMgr != nullptr, false);
148
149 IAM_LOGI("load hdi service begin");
150 int32_t loadDriverRet = devMgr->LoadDevice(SERVICE_NAME);
151 if (loadDriverRet != 0) {
152 IAM_LOGE("load %{public}s service failed, ret:%{public}d", SERVICE_NAME, loadDriverRet);
153 return false;
154 }
155 return true;
156 }
157
UnloadDriver()158 bool DriverLoadManager::UnloadDriver()
159 {
160 auto devMgr = IDeviceManager::Get();
161 IF_FALSE_LOGE_AND_RETURN_VAL(devMgr != nullptr, false);
162
163 if (devMgr->UnloadDevice(SERVICE_NAME) != 0) {
164 IAM_LOGE("unload %{public}s service failed", SERVICE_NAME);
165 return false;
166 }
167 return true;
168 }
169
ProcessServiceStatus()170 void DriverLoadManager::ProcessServiceStatus()
171 {
172 const uint32_t RETRY_LOAD_INTERVAL = 1000; // 1s
173
174 std::lock_guard<std::recursive_mutex> lock(mutex_);
175 bool shouldRunning = !isSaStopping_;
176 IAM_LOGI("process service %{public}s status %{public}d, isSaStopping_ %{public}d", SERVICE_NAME, isDriverRunning_,
177 isSaStopping_);
178 if (isDriverRunning_ != shouldRunning) {
179 if (shouldRunning) {
180 bool loadDriverRet = LoadDriver();
181 if (loadDriverRet) {
182 IAM_LOGI("load service %{public}s success", SERVICE_NAME);
183 isDriverRunning_ = true;
184 }
185 } else {
186 bool unloadDriverRet = UnloadDriver();
187 if (unloadDriverRet) {
188 IAM_LOGI("unload service %{public}s success", SERVICE_NAME);
189 isDriverRunning_ = false;
190 }
191 }
192 }
193
194 if (isDriverRunning_ == shouldRunning) {
195 if (timerId_ != std::nullopt) {
196 RelativeTimer::GetInstance().Unregister(timerId_.value());
197 timerId_ = std::nullopt;
198 }
199 } else {
200 if (timerId_ == std::nullopt) {
201 timerId_ = RelativeTimer::GetInstance().Register([this]() { OnTimeout(); }, RETRY_LOAD_INTERVAL);
202 IAM_LOGI("process fail, retry after %{public}d ms", RETRY_LOAD_INTERVAL);
203 }
204 }
205 }
206 } // namespace PinAuth
207 } // namespace UserIam
208 } // namespace OHOS
209