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