• 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_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