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