• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 "widget_client.h"
17 
18 #include "system_ability_definition.h"
19 
20 #include "auth_common.h"
21 #include "iam_check.h"
22 #include "iam_logger.h"
23 #include "iam_time.h"
24 #include "nlohmann/json.hpp"
25 #include "widget_callback_interface.h"
26 #include "hisysevent_adapter.h"
27 
28 #define LOG_LABEL UserIam::Common::LABEL_USER_AUTH_SA
29 
30 namespace OHOS {
31 namespace UserIam {
32 namespace UserAuth {
33 
34 const std::string PIN_SUB_TYPE_SIX = "PIN_SIX";
35 const std::string PIN_SUB_TYPE_NUMBER = "PIN_NUMBER";
36 const std::string PIN_SUB_TYPE_MIXED = "PIN_MIXED";
37 const std::string PIN_SUB_TYPE_MAX = "PIN_MAX";
38 
Instance()39 WidgetClient &WidgetClient::Instance()
40 {
41     static WidgetClient widgetClient;
42     return widgetClient;
43 }
44 
SetWidgetSchedule(const std::shared_ptr<WidgetScheduleNode> & schedule)45 void WidgetClient::SetWidgetSchedule(const std::shared_ptr<WidgetScheduleNode> &schedule)
46 {
47     IF_FALSE_LOGE_AND_RETURN(schedule != nullptr);
48     schedule_ = schedule;
49 }
50 
OnNotice(NoticeType type,const std::string & eventData)51 ResultCode WidgetClient::OnNotice(NoticeType type, const std::string &eventData)
52 {
53     // handle notice from widget
54     if (type != WIDGET_NOTICE) {
55         IAM_LOGE("Invalid notice type");
56         return ResultCode::INVALID_PARAMETERS;
57     }
58     if (eventData.empty()) {
59         IAM_LOGE("Invalid notice event data");
60         return ResultCode::INVALID_PARAMETERS;
61     }
62     IAM_LOGI("recv notice eventData: %{public}s", eventData.c_str());
63     auto root = nlohmann::json::parse(eventData.c_str(), nullptr, false);
64     if (root.is_null() || root.is_discarded()) {
65         IAM_LOGE("OnNotice eventData is not json format");
66         return ResultCode::INVALID_PARAMETERS;
67     }
68     WidgetNotice notice = root.get<WidgetNotice>();
69     if (notice.widgetContextId == 0) {
70         IAM_LOGE("Invalid widget context id");
71         return ResultCode::INVALID_PARAMETERS;
72     }
73     if (!IsValidNoticeType(notice)) {
74         IAM_LOGE("Not support notice event");
75         return ResultCode::INVALID_PARAMETERS;
76     }
77     if (schedule_ == nullptr) {
78         IAM_LOGE("Invalid schedule node, report auth false");
79         return ResultCode::GENERAL_ERROR;
80     }
81     std::vector<AuthType> authTypeList = {};
82     if (!GetAuthTypeList(notice, authTypeList)) {
83         IAM_LOGE("Invalid auth type list");
84         return ResultCode::INVALID_PARAMETERS;
85     }
86     if (notice.event == NOTICE_EVENT_AUTH_READY) {
87         schedule_->StartAuthList(authTypeList);
88     } else if (notice.event == NOTICE_EVENT_CANCEL_AUTH) {
89         if (authTypeList.size() == 1 && authTypeList[0] == AuthType::ALL) {
90             schedule_->StopSchedule();
91         } else {
92             schedule_->StopAuthList(authTypeList);
93         }
94     } else if (notice.event == NOTICE_EVENT_USER_NAVIGATION) {
95         schedule_->NaviPinAuth();
96     }
97     return ResultCode::SUCCESS;
98 }
99 
SendCommand(const WidgetCommand & command)100 void WidgetClient::SendCommand(const WidgetCommand &command)
101 {
102     if (widgetCallback_ == nullptr) {
103         IAM_LOGE("SendCommand widget callback is null");
104         return;
105     }
106     nlohmann::json root = command;
107     std::string cmdData = root.dump();
108     IAM_LOGI("SendCommand cmdData: %{public}s", cmdData.c_str());
109     widgetCallback_->SendCommand(cmdData);
110 }
111 
ReportWidgetResult(int32_t result,AuthType authType,int32_t lockoutDuration,int32_t remainAttempts)112 void WidgetClient::ReportWidgetResult(int32_t result, AuthType authType,
113     int32_t lockoutDuration, int32_t remainAttempts)
114 {
115     // sendCommand of CMD_NOTIFY_AUTH_RESULT
116     WidgetCommand::Cmd cmd {
117         .event = "CMD_NOTIFY_AUTH_RESULT",
118         .version = NOTICE_VERSION_STR,
119         .type = AuthType2Str(authType),
120         .result = result,
121         .lockoutDuration = lockoutDuration,
122         .remainAttempts = remainAttempts
123     };
124     if (authType == AuthType::FINGERPRINT && !sensorInfo_.empty()) {
125         cmd.sensorInfo = sensorInfo_;
126     }
127     WidgetCommand widgetCmd {
128         .widgetContextId = widgetContextId_,
129         .title = widgetParam_.title,
130         .windowModeType = WinModeType2Str(widgetParam_.windowMode),
131         .navigationButtonText = widgetParam_.navigationButtonText,
132         .cmdList = { cmd }
133     };
134     for (auto &type : authTypeList_) {
135         widgetCmd.typeList.emplace_back(AuthType2Str(type));
136     }
137     if (!pinSubType_.empty()) {
138         widgetCmd.pinSubType = pinSubType_;
139     }
140     SendCommand(widgetCmd);
141 }
142 
SetWidgetContextId(uint64_t contextId)143 void WidgetClient::SetWidgetContextId(uint64_t contextId)
144 {
145     widgetContextId_ = contextId;
146 }
147 
SetWidgetParam(const WidgetParam & param)148 void WidgetClient::SetWidgetParam(const WidgetParam &param)
149 {
150     widgetParam_ = param;
151 }
152 
SetAuthTypeList(const std::vector<AuthType> & authTypeList)153 void WidgetClient::SetAuthTypeList(const std::vector<AuthType> &authTypeList)
154 {
155     authTypeList_ = authTypeList;
156 }
157 
SetWidgetCallback(const sptr<WidgetCallbackInterface> & callback)158 void WidgetClient::SetWidgetCallback(const sptr<WidgetCallbackInterface> &callback)
159 {
160     widgetCallback_ = callback;
161 }
162 
SetAuthTokenId(uint32_t tokenId)163 void WidgetClient::SetAuthTokenId(uint32_t tokenId)
164 {
165     authTokenId_ = tokenId;
166     IAM_LOGI("WidgetClient SetAuthTokenId authTokenId: %{public}u", authTokenId_);
167 }
168 
GetAuthTokenId() const169 uint32_t WidgetClient::GetAuthTokenId() const
170 {
171     return authTokenId_;
172 }
173 
Reset()174 void WidgetClient::Reset()
175 {
176     IAM_LOGI("WidgetClient Reset");
177     widgetParam_.title.clear();
178     widgetParam_.navigationButtonText.clear();
179     widgetParam_.windowMode = WindowModeType::DIALOG_BOX;
180     widgetContextId_ = 0;
181     authTokenId_ = 0;
182     schedule_ = nullptr;
183     widgetCallback_ = nullptr;
184     pinSubType_.clear();
185     sensorInfo_.clear();
186 }
187 
ForceStopAuth()188 void WidgetClient::ForceStopAuth()
189 {
190     IAM_LOGE("Stop Auth process forcely by disconnect");
191     if (widgetContextId_ != 0) {
192         IAM_LOGE("widget context id hasn't been reset");
193         UserIam::UserAuth::ReportSystemFault(Common::GetNowTimeString(), "AuthWidget");
194     }
195     if (schedule_ != nullptr) {
196         schedule_->StopSchedule();
197     }
198 }
199 
SetPinSubType(const PinSubType & subType)200 void WidgetClient::SetPinSubType(const PinSubType &subType)
201 {
202     pinSubType_ = PIN_SUB_TYPE_SIX;
203     switch (subType) {
204         case PinSubType::PIN_NUMBER:
205             pinSubType_ = PIN_SUB_TYPE_NUMBER;
206             break;
207         case PinSubType::PIN_MIXED:
208             pinSubType_ = PIN_SUB_TYPE_MIXED;
209             break;
210         case PinSubType::PIN_MAX:
211             pinSubType_ = PIN_SUB_TYPE_MAX;
212             break;
213         default:
214             break;
215     }
216 }
217 
SetSensorInfo(const std::string & info)218 void WidgetClient::SetSensorInfo(const std::string &info)
219 {
220     sensorInfo_ = info;
221 }
222 
GetAuthTypeList(const WidgetNotice & notice,std::vector<AuthType> & authTypeList)223 bool WidgetClient::GetAuthTypeList(const WidgetNotice &notice, std::vector<AuthType> &authTypeList)
224 {
225     if (authTypeList_.empty()) {
226         IAM_LOGE("inner auth type list is empty");
227         return false;
228     }
229     std::vector<AuthType> tempList = notice.AuthTypeList();
230     if (tempList.empty()) {
231         IAM_LOGE("auth type list is empty");
232         return false;
233     }
234     if (tempList.size() == 1 && tempList[0] == AuthType::ALL) {
235         if (notice.event != NOTICE_EVENT_CANCEL_AUTH) {
236             IAM_LOGE("invalid type all case event type: %{public}s", notice.event.c_str());
237             return false;
238         }
239         authTypeList.emplace_back(AuthType::ALL);
240         return true;
241     }
242     for (auto &type : tempList) {
243         if (std::find(authTypeList_.begin(), authTypeList_.end(), type) == authTypeList_.end()) {
244             IAM_LOGE("invalid auth type: %{public}d", type);
245             return false;
246         }
247         authTypeList.emplace_back(type);
248     }
249     if (authTypeList.size() == authTypeList_.size() && notice.event == NOTICE_EVENT_CANCEL_AUTH) {
250         authTypeList.clear();
251         authTypeList.emplace_back(AuthType::ALL);
252     }
253     return true;
254 }
255 
IsValidNoticeType(const WidgetNotice & notice)256 bool WidgetClient::IsValidNoticeType(const WidgetNotice &notice)
257 {
258     if (notice.event != NOTICE_EVENT_AUTH_READY &&
259         notice.event != NOTICE_EVENT_CANCEL_AUTH &&
260         notice.event != NOTICE_EVENT_USER_NAVIGATION) {
261         return false;
262     }
263     return true;
264 }
265 } // namespace UserAuth
266 } // namespace UserIam
267 } // namespace OHOS