1 /*
2 * Copyright (c) 2022 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_manager.h"
17
18 #include <set>
19
20 #include "iservice_registry.h"
21 #include "iservmgr_hdi.h"
22 #include "parameter.h"
23 #include "system_ability_definition.h"
24 #include "hisysevent_adapter.h"
25
26 #include "auth_executor_mgr_status_listener.h"
27 #include "driver_manager_status_listener.h"
28 #include "iam_check.h"
29 #include "iam_logger.h"
30 #include "iam_ptr.h"
31 #include "iam_time.h"
32
33 #define LOG_TAG "USER_AUTH_EXECUTOR"
34
35 namespace OHOS {
36 namespace UserIam {
37 namespace UserAuth {
38 using namespace HDI::ServiceManager::V1_0;
39 const char IAM_EVENT_KEY[] = "bootevent.useriam.fwkready";
DriverManager()40 DriverManager::DriverManager()
41 {
42 SubscribeServiceStatus();
43 SubscribeFrameworkReadyEvent();
44 }
45
Start(const std::map<std::string,HdiConfig> & hdiName2Config)46 int32_t DriverManager::Start(const std::map<std::string, HdiConfig> &hdiName2Config)
47 {
48 IAM_LOGI("start");
49 if (!HdiConfigIsValid(hdiName2Config)) {
50 IAM_LOGE("service config is not valid");
51 return USERAUTH_ERROR;
52 }
53 std::lock_guard<std::mutex> lock(mutex_);
54 for (auto const &[hdiName, config] : hdiName2Config) {
55 if (serviceName2Driver_.find(hdiName) != serviceName2Driver_.end()) {
56 IAM_LOGI("%{public}s already added, skip", hdiName.c_str());
57 continue;
58 }
59 auto driver = Common::MakeShared<Driver>(hdiName, config);
60 if (driver == nullptr) {
61 IAM_LOGE("MakeShared for driver %{public}s failed", hdiName.c_str());
62 continue;
63 }
64 serviceName2Driver_[hdiName] = driver;
65 driver->OnHdiConnect();
66 IAM_LOGI("add driver %{public}s", hdiName.c_str());
67 }
68 IAM_LOGI("success");
69 return USERAUTH_SUCCESS;
70 }
71
HdiConfigIsValid(const std::map<std::string,HdiConfig> & hdiName2Config)72 bool DriverManager::HdiConfigIsValid(const std::map<std::string, HdiConfig> &hdiName2Config)
73 {
74 std::set<uint16_t> idSet;
75 for (auto const &[hdiName, config] : hdiName2Config) {
76 uint16_t id = config.id;
77 if (idSet.find(id) != idSet.end()) {
78 IAM_LOGE("duplicate hdi id %{public}hu", id);
79 return false;
80 }
81 if (config.driver == nullptr) {
82 IAM_LOGE("driver is nullptr");
83 return false;
84 }
85 idSet.insert(id);
86 }
87 return true;
88 }
89
SubscribeHdiDriverStatus()90 void DriverManager::SubscribeHdiDriverStatus()
91 {
92 IAM_LOGI("start");
93 auto servMgr = IServiceManager::Get();
94 if (servMgr == nullptr) {
95 IAM_LOGE("failed to get IServiceManager");
96 return;
97 }
98
99 std::lock_guard<std::mutex> lock(mutex_);
100 if (hdiServiceStatusListener_ != nullptr) {
101 int32_t ret = servMgr->UnregisterServiceStatusListener(hdiServiceStatusListener_);
102 hdiServiceStatusListener_ = nullptr;
103 IAM_LOGI("UnregisterServiceStatusListener result %{public}d", ret);
104 }
105
106 HdiServiceStatusListener::StatusCallback callback = [](const ServiceStatus &status) {
107 auto driver = DriverManager::GetInstance().GetDriverByServiceName(status.serviceName);
108 if (driver == nullptr) {
109 return;
110 }
111
112 IAM_LOGI("service %{public}s receive status %{public}d", status.serviceName.c_str(), status.status);
113 switch (status.status) {
114 case SERVIE_STATUS_START:
115 IAM_LOGI("service %{public}s status change to start", status.serviceName.c_str());
116 driver->OnHdiConnect();
117 break;
118 case SERVIE_STATUS_STOP:
119 UserIam::UserAuth::ReportSystemFault(Common::GetNowTimeString(), status.serviceName);
120 IAM_LOGI("service %{public}s status change to stop", status.serviceName.c_str());
121 driver->OnHdiDisconnect();
122 break;
123 default:
124 IAM_LOGI("service %{public}s status ignored", status.serviceName.c_str());
125 }
126 };
127
128 hdiServiceStatusListener_ = sptr<HdiServiceStatusListener>(new (std::nothrow) HdiServiceStatusListener(callback));
129 IF_FALSE_LOGE_AND_RETURN(hdiServiceStatusListener_ != nullptr);
130 int32_t ret = servMgr->RegisterServiceStatusListener(hdiServiceStatusListener_, DEVICE_CLASS_USERAUTH);
131 if (ret != USERAUTH_SUCCESS) {
132 IAM_LOGE("failed to register service status listener");
133 hdiServiceStatusListener_ = nullptr;
134 return;
135 }
136 IAM_LOGI("success");
137 }
138
SubscribeServiceStatus()139 void DriverManager::SubscribeServiceStatus()
140 {
141 IAM_LOGI("start");
142 auto sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
143 if (sam == nullptr) {
144 IAM_LOGE("failed to get SA manager");
145 return;
146 }
147
148 auto driverManagerStatuslistener = DriverManagerStatusListener::GetInstance();
149 IF_FALSE_LOGE_AND_RETURN(driverManagerStatuslistener != nullptr);
150 int32_t ret = sam->SubscribeSystemAbility(DEVICE_SERVICE_MANAGER_SA_ID, driverManagerStatuslistener);
151 if (ret != USERAUTH_SUCCESS) {
152 IAM_LOGE("failed to subscribe driver manager status");
153 return;
154 }
155
156 auto authExecutorMgrStatuslistener = AuthExecutorMgrStatusListener::GetInstance();
157 IF_FALSE_LOGE_AND_RETURN(authExecutorMgrStatuslistener != nullptr);
158 ret = sam->SubscribeSystemAbility(SUBSYS_USERIAM_SYS_ABILITY_AUTHEXECUTORMGR,
159 authExecutorMgrStatuslistener);
160 if (ret != USERAUTH_SUCCESS) {
161 IAM_LOGE("failed to subscribe auto executor mgr status");
162 return;
163 }
164 IAM_LOGI("success");
165 }
166
SubscribeFrameworkReadyEvent()167 void DriverManager::SubscribeFrameworkReadyEvent()
168 {
169 IAM_LOGI("start");
170 auto eventCallback = [](const char *key, const char *value, void *context) {
171 IAM_LOGI("receive useriam.fwkready event");
172 IF_FALSE_LOGE_AND_RETURN(key != nullptr);
173 IF_FALSE_LOGE_AND_RETURN(value != nullptr);
174 if (strcmp(key, IAM_EVENT_KEY) != 0) {
175 IAM_LOGE("event key mismatch");
176 return;
177 }
178 if (strcmp(value, "true")) {
179 IAM_LOGE("event value is not true");
180 return;
181 }
182 DriverManager::GetInstance().OnFrameworkReady();
183 };
184 int32_t ret = WatchParameter(IAM_EVENT_KEY, eventCallback, nullptr);
185 if (ret != USERAUTH_SUCCESS) {
186 IAM_LOGE("WatchParameter fail");
187 return;
188 }
189 IAM_LOGI("success");
190 }
191
OnAllHdiDisconnect()192 void DriverManager::OnAllHdiDisconnect()
193 {
194 IAM_LOGI("start");
195 std::lock_guard<std::mutex> lock(mutex_);
196 if (hdiServiceStatusListener_ == nullptr) {
197 IAM_LOGE("HdiServiceStatusListener not added");
198 return;
199 }
200 auto servMgr = IServiceManager::Get();
201 if (servMgr != nullptr) {
202 int32_t ret = servMgr->UnregisterServiceStatusListener(hdiServiceStatusListener_);
203 IAM_LOGI("UnregisterServiceStatusListener result %{public}d", ret);
204 }
205 hdiServiceStatusListener_ = nullptr;
206 for (auto const &pair : serviceName2Driver_) {
207 if (pair.second == nullptr) {
208 IAM_LOGE("pair.second is null");
209 continue;
210 }
211 pair.second->OnHdiDisconnect();
212 }
213 IAM_LOGI("success");
214 }
215
OnFrameworkReady()216 void DriverManager::OnFrameworkReady()
217 {
218 IAM_LOGI("start");
219 std::lock_guard<std::mutex> lock(mutex_);
220 for (auto const &pair : serviceName2Driver_) {
221 if (pair.second == nullptr) {
222 IAM_LOGE("pair.second is null");
223 continue;
224 }
225 pair.second->OnFrameworkReady();
226 }
227 IAM_LOGI("success");
228 }
229
GetDriverByServiceName(const std::string & serviceName)230 std::shared_ptr<Driver> DriverManager::GetDriverByServiceName(const std::string &serviceName)
231 {
232 IAM_LOGI("start");
233 std::lock_guard<std::mutex> lock(mutex_);
234 auto driverIter = serviceName2Driver_.find(serviceName);
235 if (driverIter == serviceName2Driver_.end()) {
236 return nullptr;
237 }
238 return driverIter->second;
239 }
240 } // namespace UserAuth
241 } // namespace UserIam
242 } // namespace OHOS
243