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