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