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 namespace {
GetParam(const std::string & key,const std::string & defaultValue)39 std::string GetParam(const std::string &key, const std::string &defaultValue)
40 {
41 constexpr uint32_t MAX_VALUE_LEN = 128;
42 char valueBuffer[MAX_VALUE_LEN] = { 0 };
43 int32_t ret = GetParameter(key.c_str(), defaultValue.c_str(), valueBuffer, MAX_VALUE_LEN);
44 if (ret < 0) {
45 IAM_LOGE("get param failed, key %{public}s, ret %{public}d, use default value %{public}s", key.c_str(), ret,
46 defaultValue.c_str());
47 return defaultValue;
48 }
49 IAM_LOGI("get param key %{public}s value %{public}s", key.c_str(), valueBuffer);
50 return std::string(valueBuffer);
51 }
52 }
53 using namespace HDI::ServiceManager::V1_0;
54 const char IAM_EVENT_KEY[] = "bootevent.useriam.fwkready";
DriverManager()55 DriverManager::DriverManager()
56 {
57 SubscribeServiceStatus();
58 SubscribeFrameworkReadyEvent();
59 }
60
Start(const std::map<std::string,HdiConfig> & hdiName2Config)61 int32_t DriverManager::Start(const std::map<std::string, HdiConfig> &hdiName2Config)
62 {
63 IAM_LOGI("start");
64 if (!HdiConfigIsValid(hdiName2Config)) {
65 IAM_LOGE("service config is not valid");
66 return USERAUTH_ERROR;
67 }
68 std::lock_guard<std::mutex> lock(mutex_);
69 bool isFwkReady = GetParam(IAM_EVENT_KEY, "false") == "true";
70 auto servMgr = IServiceManager::Get();
71 IF_FALSE_LOGE_AND_RETURN_VAL(servMgr != nullptr, USERAUTH_ERROR);
72 for (auto const &[hdiName, config] : hdiName2Config) {
73 if (serviceName2Driver_.find(hdiName) != serviceName2Driver_.end()) {
74 IAM_LOGI("%{public}s already added, skip", hdiName.c_str());
75 continue;
76 }
77 auto driver = Common::MakeShared<Driver>(hdiName, config);
78 if (driver == nullptr) {
79 IAM_LOGE("MakeShared for driver %{public}s failed", hdiName.c_str());
80 continue;
81 }
82 serviceName2Driver_[hdiName] = driver;
83 auto service = servMgr->GetService(hdiName.c_str());
84 if (service != nullptr) {
85 driver->OnHdiConnect();
86 }
87 if (isFwkReady) {
88 driver->OnFrameworkReady();
89 }
90
91 IAM_LOGI("add driver %{public}s", hdiName.c_str());
92 }
93 IAM_LOGI("success");
94 return USERAUTH_SUCCESS;
95 }
96
HdiConfigIsValid(const std::map<std::string,HdiConfig> & hdiName2Config)97 bool DriverManager::HdiConfigIsValid(const std::map<std::string, HdiConfig> &hdiName2Config)
98 {
99 std::set<uint16_t> idSet;
100 for (auto const &[hdiName, config] : hdiName2Config) {
101 uint16_t id = config.id;
102 if (idSet.find(id) != idSet.end()) {
103 IAM_LOGE("duplicate hdi id %{public}hu", id);
104 return false;
105 }
106 if (config.driver == nullptr) {
107 IAM_LOGE("driver is nullptr");
108 return false;
109 }
110 idSet.insert(id);
111 }
112 return true;
113 }
114
SubscribeHdiDriverStatus()115 void DriverManager::SubscribeHdiDriverStatus()
116 {
117 IAM_LOGI("start");
118 auto servMgr = IServiceManager::Get();
119 if (servMgr == nullptr) {
120 IAM_LOGE("failed to get IServiceManager");
121 return;
122 }
123
124 std::lock_guard<std::mutex> lock(mutex_);
125 if (hdiServiceStatusListener_ != nullptr) {
126 int32_t ret = servMgr->UnregisterServiceStatusListener(hdiServiceStatusListener_);
127 hdiServiceStatusListener_ = nullptr;
128 IAM_LOGI("UnregisterServiceStatusListener result %{public}d", ret);
129 }
130
131 HdiServiceStatusListener::StatusCallback callback = [](const ServiceStatus &status) {
132 auto driver = DriverManager::GetInstance().GetDriverByServiceName(status.serviceName);
133 if (driver == nullptr) {
134 return;
135 }
136
137 IAM_LOGI("service %{public}s receive status %{public}d", status.serviceName.c_str(), status.status);
138 switch (status.status) {
139 case SERVIE_STATUS_START:
140 IAM_LOGI("service %{public}s status change to start", status.serviceName.c_str());
141 driver->OnHdiConnect();
142 break;
143 case SERVIE_STATUS_STOP:
144 UserIam::UserAuth::ReportSystemFault(Common::GetNowTimeString(), status.serviceName);
145 IAM_LOGI("service %{public}s status change to stop", status.serviceName.c_str());
146 driver->OnHdiDisconnect();
147 break;
148 default:
149 IAM_LOGI("service %{public}s status ignored", status.serviceName.c_str());
150 }
151 };
152
153 hdiServiceStatusListener_ = sptr<HdiServiceStatusListener>(new (std::nothrow) HdiServiceStatusListener(callback));
154 IF_FALSE_LOGE_AND_RETURN(hdiServiceStatusListener_ != nullptr);
155 int32_t ret = servMgr->RegisterServiceStatusListener(hdiServiceStatusListener_, DEVICE_CLASS_USERAUTH);
156 if (ret != USERAUTH_SUCCESS) {
157 IAM_LOGE("failed to register service status listener");
158 hdiServiceStatusListener_ = nullptr;
159 return;
160 }
161 IAM_LOGI("success");
162 }
163
SubscribeServiceStatus()164 void DriverManager::SubscribeServiceStatus()
165 {
166 IAM_LOGI("start");
167 auto sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
168 if (sam == nullptr) {
169 IAM_LOGE("failed to get SA manager");
170 return;
171 }
172
173 auto driverManagerStatuslistener = DriverManagerStatusListener::GetInstance();
174 IF_FALSE_LOGE_AND_RETURN(driverManagerStatuslistener != nullptr);
175 int32_t ret = sam->SubscribeSystemAbility(DEVICE_SERVICE_MANAGER_SA_ID, driverManagerStatuslistener);
176 if (ret != USERAUTH_SUCCESS) {
177 IAM_LOGE("failed to subscribe driver manager status");
178 return;
179 }
180
181 auto authExecutorMgrStatuslistener = AuthExecutorMgrStatusListener::GetInstance();
182 IF_FALSE_LOGE_AND_RETURN(authExecutorMgrStatuslistener != nullptr);
183 ret = sam->SubscribeSystemAbility(SUBSYS_USERIAM_SYS_ABILITY_AUTHEXECUTORMGR,
184 authExecutorMgrStatuslistener);
185 if (ret != USERAUTH_SUCCESS) {
186 IAM_LOGE("failed to subscribe auto executor mgr status");
187 return;
188 }
189 IAM_LOGI("success");
190 }
191
SubscribeFrameworkReadyEvent()192 void DriverManager::SubscribeFrameworkReadyEvent()
193 {
194 IAM_LOGI("start");
195 auto eventCallback = [](const char *key, const char *value, void *context) {
196 IAM_LOGI("receive useriam.fwkready event");
197 IF_FALSE_LOGE_AND_RETURN(key != nullptr);
198 IF_FALSE_LOGE_AND_RETURN(value != nullptr);
199 if (strcmp(key, IAM_EVENT_KEY) != 0) {
200 IAM_LOGE("event key mismatch");
201 return;
202 }
203 if (strcmp(value, "true")) {
204 IAM_LOGI("event value is not true");
205 DriverManager::GetInstance().OnFrameworkDown();
206 } else {
207 IAM_LOGI("event value is true");
208 DriverManager::GetInstance().OnFrameworkReady();
209 }
210 };
211 int32_t ret = WatchParameter(IAM_EVENT_KEY, eventCallback, nullptr);
212 if (ret != USERAUTH_SUCCESS) {
213 IAM_LOGE("WatchParameter fail");
214 return;
215 }
216 IAM_LOGI("success");
217 }
218
OnAllHdiDisconnect()219 void DriverManager::OnAllHdiDisconnect()
220 {
221 IAM_LOGI("start");
222 std::lock_guard<std::mutex> lock(mutex_);
223 if (hdiServiceStatusListener_ == nullptr) {
224 IAM_LOGE("HdiServiceStatusListener not added");
225 return;
226 }
227 auto servMgr = IServiceManager::Get();
228 if (servMgr != nullptr) {
229 int32_t ret = servMgr->UnregisterServiceStatusListener(hdiServiceStatusListener_);
230 IAM_LOGI("UnregisterServiceStatusListener result %{public}d", ret);
231 }
232 hdiServiceStatusListener_ = nullptr;
233 for (auto const &pair : serviceName2Driver_) {
234 if (pair.second == nullptr) {
235 IAM_LOGE("pair.second is null");
236 continue;
237 }
238 pair.second->OnHdiDisconnect();
239 }
240 IAM_LOGI("success");
241 }
242
OnFrameworkReady()243 void DriverManager::OnFrameworkReady()
244 {
245 IAM_LOGI("start");
246 std::lock_guard<std::mutex> lock(mutex_);
247 for (auto const &pair : serviceName2Driver_) {
248 if (pair.second == nullptr) {
249 IAM_LOGE("pair.second is null");
250 continue;
251 }
252 pair.second->OnFrameworkReady();
253 }
254 IAM_LOGI("success");
255 }
256
OnFrameworkDown()257 void DriverManager::OnFrameworkDown()
258 {
259 IAM_LOGI("start");
260 std::lock_guard<std::mutex> lock(mutex_);
261 for (auto const &pair : serviceName2Driver_) {
262 if (pair.second == nullptr) {
263 IAM_LOGE("pair.second is null");
264 continue;
265 }
266 pair.second->OnFrameworkDown();
267 }
268 IAM_LOGI("success");
269 }
270
GetDriverByServiceName(const std::string & serviceName)271 std::shared_ptr<Driver> DriverManager::GetDriverByServiceName(const std::string &serviceName)
272 {
273 IAM_LOGI("start");
274 std::lock_guard<std::mutex> lock(mutex_);
275 auto driverIter = serviceName2Driver_.find(serviceName);
276 if (driverIter == serviceName2Driver_.end()) {
277 return nullptr;
278 }
279 return driverIter->second;
280 }
281 } // namespace UserAuth
282 } // namespace UserIam
283 } // namespace OHOS
284