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