1 /*
2  * Copyright (c) 2023-2024 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 #include "widget_context.h"
16 
17 #include <algorithm>
18 
19 #include "accesstoken_kit.h"
20 #include "auth_widget_helper.h"
21 #include "context_helper.h"
22 #include "context_pool.h"
23 #include "context_death_recipient.h"
24 #include "iam_check.h"
25 #include "iam_logger.h"
26 #include "iam_para2str.h"
27 #include "iam_ptr.h"
28 #include "iam_time.h"
29 #include "schedule_node.h"
30 #include "schedule_node_callback.h"
31 #include "widget_schedule_node_impl.h"
32 #include "widget_context_callback_impl.h"
33 #include "widget_client.h"
34 #include "bool_wrapper.h"
35 #include "double_wrapper.h"
36 #include "int_wrapper.h"
37 #include "string_wrapper.h"
38 #include "want_params_wrapper.h"
39 #include "ability_connection.h"
40 #include "ability_connect_callback.h"
41 #include "refbase.h"
42 #include "hisysevent_adapter.h"
43 #include "system_ability_definition.h"
44 
45 #define LOG_TAG "USER_AUTH_SA"
46 
47 namespace OHOS {
48 namespace UserIam {
49 namespace UserAuth {
50 constexpr int32_t DEFAULT_VALUE = -1;
51 const std::string UI_EXTENSION_TYPE_SET = "sysDialog/userAuth";
52 const uint32_t SYSDIALOG_ZORDER_DEFAULT = 1;
53 const uint32_t SYSDIALOG_ZORDER_UPPER = 2;
54 const uint32_t ORIENTATION_LANDSCAPE = 1;
55 const uint32_t ORIENTATION_PORTRAIT_INVERTED = 2;
56 const uint32_t ORIENTATION_LANDSCAPE_INVERTED = 3;
57 const std::string TO_PORTRAIT = "90";
58 const std::string TO_INVERTED = "180";
59 const std::string TO_PORTRAIT_INVERTED = "270";
60 const uint32_t NOT_SUPPORT_ORIENTATION_INVERTED = 2;
61 
WidgetContext(uint64_t contextId, const ContextFactory::AuthWidgetContextPara &para, std::shared_ptr<ContextCallback> callback)62 WidgetContext::WidgetContext(uint64_t contextId, const ContextFactory::AuthWidgetContextPara &para,
63     std::shared_ptr<ContextCallback> callback)
64     : contextId_(contextId), description_("UserAuthWidget"), callerCallback_(callback), hasStarted_(false),
65     latestError_(ResultCode::GENERAL_ERROR), para_(para), schedule_(nullptr), connection_(nullptr)
66 {
67     AddDeathRecipient(callerCallback_, contextId_);
68     SubscribeAppState(callerCallback_, contextId_);
69 }
70 
~WidgetContext()71 WidgetContext::~WidgetContext()
72 {
73     IAM_LOGI("release WidgetContext");
74     RemoveDeathRecipient(callerCallback_);
75     UnSubscribeAppState();
76 }
77 
Start()78 bool WidgetContext::Start()
79 {
80     std::lock_guard<std::recursive_mutex> lock(mutex_);
81     IAM_LOGI("%{public}s start", description_.c_str());
82     if (hasStarted_) {
83         IAM_LOGI("%{public}s context has started, cannot start again", description_.c_str());
84         return false;
85     }
86     hasStarted_ = true;
87     return OnStart();
88 }
89 
Stop()90 bool WidgetContext::Stop()
91 {
92     IAM_LOGI("%{public}s start", description_.c_str());
93     return OnStop();
94 }
95 
GetContextId() const96 uint64_t WidgetContext::GetContextId() const
97 {
98     return contextId_;
99 }
100 
GetContextType() const101 ContextType WidgetContext::GetContextType() const
102 {
103     return WIDGET_AUTH_CONTEXT;
104 }
105 
GetScheduleNode(uint64_t scheduleId) const106 std::shared_ptr<ScheduleNode> WidgetContext::GetScheduleNode(uint64_t scheduleId) const
107 {
108     return nullptr;
109 }
110 
GetTokenId() const111 uint32_t WidgetContext::GetTokenId() const
112 {
113     return para_.tokenId;
114 }
115 
GetUserId() const116 int32_t WidgetContext::GetUserId() const
117 {
118     return para_.userId;
119 }
120 
GetLatestError() const121 int32_t WidgetContext::GetLatestError() const
122 {
123     return latestError_;
124 }
125 
SetLatestError(int32_t error)126 void WidgetContext::SetLatestError(int32_t error)
127 {
128     if (error != ResultCode::SUCCESS) {
129         latestError_ = error;
130     }
131 }
132 
BuildSchedule()133 bool WidgetContext::BuildSchedule()
134 {
135     schedule_ = Common::MakeShared<WidgetScheduleNodeImpl>();
136     IF_FALSE_LOGE_AND_RETURN_VAL(schedule_ != nullptr, false);
137     schedule_->SetCallback(shared_from_this());
138     return true;
139 }
140 
GetAuthContextCallback(AuthType authType, AuthTrustLevel authTrustLevel, sptr<IamCallbackInterface> &iamCallback)141 std::shared_ptr<ContextCallback> WidgetContext::GetAuthContextCallback(AuthType authType,
142     AuthTrustLevel authTrustLevel, sptr<IamCallbackInterface> &iamCallback)
143 {
144     auto widgetCallback = ContextCallback::NewInstance(iamCallback, TRACE_AUTH_USER_SECURITY);
145     if (widgetCallback == nullptr) {
146         IAM_LOGE("failed to construct context callback");
147         Attributes extraInfo;
148         iamCallback->OnResult(ResultCode::GENERAL_ERROR, extraInfo);
149         return nullptr;
150     }
151     widgetCallback->SetTraceCallerName(para_.callerName);
152     widgetCallback->SetTraceCallerType(para_.callerType);
153     widgetCallback->SetTraceRequestContextId(contextId_);
154     widgetCallback->SetTraceAuthTrustLevel(authTrustLevel);
155     widgetCallback->SetTraceAuthType(authType);
156     return widgetCallback;
157 }
158 
BuildTask(const std::vector<uint8_t> &challenge, AuthType authType, AuthTrustLevel authTrustLevel, bool endAfterFirstFail, AuthIntent authIntent)159 std::shared_ptr<Context> WidgetContext::BuildTask(const std::vector<uint8_t> &challenge,
160     AuthType authType, AuthTrustLevel authTrustLevel, bool endAfterFirstFail, AuthIntent authIntent)
161 {
162     IF_FALSE_LOGE_AND_RETURN_VAL(callerCallback_ != nullptr, nullptr);
163     auto userId = para_.userId;
164     auto tokenId = WidgetClient::Instance().GetAuthTokenId();
165     IAM_LOGI("Real userId: %{public}d, Real tokenId: %{public}s", userId, GET_MASKED_STRING(tokenId).c_str());
166     sptr<IamCallbackInterface> iamCallback(new (std::nothrow) WidgetContextCallbackImpl(weak_from_this(),
167         static_cast<int32_t>(authType)));
168     IF_FALSE_LOGE_AND_RETURN_VAL(iamCallback != nullptr, nullptr);
169     auto widgetCallback = GetAuthContextCallback(authType, authTrustLevel, iamCallback);
170     IF_FALSE_LOGE_AND_RETURN_VAL(widgetCallback != nullptr, nullptr);
171 
172     Authentication::AuthenticationPara para = {};
173     para.tokenId = tokenId;
174     para.userId = userId;
175     para.authType = authType;
176     para.atl = authTrustLevel;
177     para.challenge = challenge;
178     para.endAfterFirstFail = endAfterFirstFail;
179     para.callerName = para_.callerName;
180     para.callerType = para_.callerType;
181     para.sdkVersion = para_.sdkVersion;
182     para.authIntent = authIntent;
183     para.isOsAccountVerified = para_.isOsAccountVerified;
184     auto context = ContextFactory::CreateSimpleAuthContext(para, widgetCallback);
185     if (context == nullptr || !ContextPool::Instance().Insert(context)) {
186         IAM_LOGE("failed to insert context");
187         Attributes extraInfo;
188         widgetCallback->SetTraceAuthFinishReason("WidgetContext BuildTask insert context fail");
189         widgetCallback->OnResult(ResultCode::GENERAL_ERROR, extraInfo);
190         return nullptr;
191     }
192     widgetCallback->SetTraceAuthContextId(context->GetContextId());
193     widgetCallback->SetCleaner(ContextHelper::Cleaner(context));
194     std::lock_guard<std::recursive_mutex> lock(mutex_);
195     return context;
196 }
197 
OnStart()198 bool WidgetContext::OnStart()
199 {
200     IAM_LOGI("%{public}s start", description_.c_str());
201     if (!BuildSchedule()) {
202         IAM_LOGE("failed to create widget schedule");
203         return false;
204     }
205     IF_FALSE_LOGE_AND_RETURN_VAL(schedule_ != nullptr, false);
206     WidgetClient::Instance().SetWidgetContextId(GetContextId());
207     WidgetClient::Instance().SetWidgetParam(para_.widgetParam);
208     WidgetClient::Instance().SetAuthTypeList(para_.authTypeList);
209     WidgetClient::Instance().SetWidgetSchedule(schedule_);
210     WidgetClient::Instance().SetChallenge(para_.challenge);
211     WidgetClient::Instance().SetCallingBundleName(GetCallingBundleName());
212     schedule_->StartSchedule();
213 
214     IAM_LOGI("WidgetContext start success.");
215     return true;
216 }
217 
OnResult(int32_t resultCode, const std::shared_ptr<Attributes> &scheduleResultAttr)218 void WidgetContext::OnResult(int32_t resultCode, const std::shared_ptr<Attributes> &scheduleResultAttr)
219 {
220     IAM_LOGI("%{public}s receive result code %{public}d", description_.c_str(), resultCode);
221 }
222 
OnStop()223 bool WidgetContext::OnStop()
224 {
225     // response app.cancel()
226     IAM_LOGI("%{public}s start", description_.c_str());
227     End(ResultCode::CANCELED);
228     return true;
229 }
230 
AuthResult(int32_t resultCode, int32_t authType, const Attributes &finalResult)231 void WidgetContext::AuthResult(int32_t resultCode, int32_t authType, const Attributes &finalResult)
232 {
233     IAM_LOGI("recv task result: %{public}d, authType: %{public}d", resultCode, authType);
234     int32_t remainTimes = -1;
235     int32_t freezingTime = -1;
236     if (!finalResult.GetInt32Value(Attributes::ATTR_REMAIN_TIMES, remainTimes)) {
237         IAM_LOGI("get remainTimes failed.");
238     }
239     if (!finalResult.GetInt32Value(Attributes::ATTR_FREEZING_TIME, freezingTime)) {
240         IAM_LOGI("get freezingTime failed.");
241     }
242     AuthType authTypeTmp = static_cast<AuthType>(authType);
243     WidgetClient::Instance().ReportWidgetResult(resultCode, authTypeTmp, freezingTime, remainTimes);
244     IF_FALSE_LOGE_AND_RETURN(schedule_ != nullptr);
245     IF_FALSE_LOGE_AND_RETURN(callerCallback_ != nullptr);
246     callerCallback_->SetTraceAuthType(authTypeTmp);
247     IAM_LOGI("call schedule:");
248     if (resultCode == ResultCode::SUCCESS) {
249         finalResult.GetUint8ArrayValue(Attributes::ATTR_SIGNATURE, authResultInfo_.token);
250         finalResult.GetUint64Value(Attributes::ATTR_CREDENTIAL_DIGEST, authResultInfo_.credentialDigest);
251         finalResult.GetUint16Value(Attributes::ATTR_CREDENTIAL_COUNT, authResultInfo_.credentialCount);
252         authResultInfo_.authType = authTypeTmp;
253         schedule_->SuccessAuth(authTypeTmp);
254     } else {
255         // failed
256         SetLatestError(resultCode);
257         schedule_->StopAuthList({authTypeTmp});
258     }
259 }
260 
AuthTipInfo(int32_t tipType, int32_t authType, const Attributes &extraInfo)261 void WidgetContext::AuthTipInfo(int32_t tipType, int32_t authType, const Attributes &extraInfo)
262 {
263     IAM_LOGI("recv tip: %{public}d, authType: %{public}d", tipType, authType);
264     std::vector<uint8_t> tipInfo;
265     bool getTipInfoRet = extraInfo.GetUint8ArrayValue(Attributes::ATTR_EXTRA_INFO, tipInfo);
266     IF_FALSE_LOGE_AND_RETURN(getTipInfoRet);
267     WidgetClient::Instance().ReportWidgetTip(tipType, static_cast<AuthType>(authType), tipInfo);
268 }
269 
270 // WidgetScheduleNodeCallback
LaunchWidget()271 bool WidgetContext::LaunchWidget()
272 {
273     IAM_LOGI("launch widget");
274     WidgetRotatePara widgetRotatePara;
275     widgetRotatePara.isReload = false;
276     widgetRotatePara.needRotate = 0;
277     if (!ConnectExtension(widgetRotatePara)) {
278         IAM_LOGE("failed to launch widget.");
279         return false;
280     }
281     return true;
282 }
283 
ExecuteAuthList(const std::set<AuthType> &authTypeList, bool endAfterFirstFail, AuthIntent authIntent)284 void WidgetContext::ExecuteAuthList(const std::set<AuthType> &authTypeList, bool endAfterFirstFail,
285     AuthIntent authIntent)
286 {
287     IAM_LOGI("execute auth list");
288     // create task, and start it
289     std::lock_guard<std::recursive_mutex> lock(mutex_);
290     for (auto &authType : authTypeList) {
291         auto task = BuildTask(para_.challenge, authType, para_.atl, endAfterFirstFail, authIntent);
292         if (task == nullptr) {
293             IAM_LOGE("failed to create task, authType: %{public}s", AuthType2Str(authType).c_str());
294             continue;
295         }
296         if (!task->Start()) {
297             IAM_LOGE("BeginAuthentication failed");
298             static const int32_t INVALID_VAL = -1;
299             WidgetClient::Instance().ReportWidgetResult(task->GetLatestError(), authType, INVALID_VAL, INVALID_VAL);
300             return;
301         }
302         if (authType == FACE) {
303             faceReload_ = 1;
304             IAM_LOGI("faceReload_: %{public}d", faceReload_);
305         }
306         TaskInfo taskInfo {
307             .authType = authType,
308             .task = task
309         };
310         runTaskInfoList_.push_back(taskInfo);
311     }
312 }
313 
EndAuthAsCancel()314 void WidgetContext::EndAuthAsCancel()
315 {
316     IAM_LOGI("end auth as cancel");
317     std::lock_guard<std::recursive_mutex> lock(mutex_);
318     if (latestError_ == COMPLEXITY_CHECK_FAILED) {
319         IAM_LOGE("complexity check failed");
320         return End(TRUST_LEVEL_NOT_SUPPORT);
321     }
322     // report CANCELED to App
323     End(ResultCode::CANCELED);
324 }
325 
EndAuthAsNaviPin()326 void WidgetContext::EndAuthAsNaviPin()
327 {
328     IAM_LOGI("end auth as navi pin");
329     std::lock_guard<std::recursive_mutex> lock(mutex_);
330     // report CANCELED_FROM_WIDGET to App
331     End(ResultCode::CANCELED_FROM_WIDGET);
332 }
333 
EndAuthAsWidgetParaInvalid()334 void WidgetContext::EndAuthAsWidgetParaInvalid()
335 {
336     IAM_LOGI("end auth as widget para invalid");
337     std::lock_guard<std::recursive_mutex> lock(mutex_);
338     End(ResultCode::INVALID_PARAMETERS);
339 }
340 
AuthWidgetReloadInit()341 void WidgetContext::AuthWidgetReloadInit()
342 {
343     IAM_LOGI("auth widget reload init");
344     std::lock_guard<std::recursive_mutex> lock(mutex_);
345     if (!DisconnectExtension()) {
346         IAM_LOGE("failed to release launch widget");
347     }
348 }
349 
AuthWidgetReload(uint32_t orientation, uint32_t needRotate, uint32_t alreadyLoad, AuthType &rotateAuthType)350 bool WidgetContext::AuthWidgetReload(uint32_t orientation, uint32_t needRotate, uint32_t alreadyLoad,
351     AuthType &rotateAuthType)
352 {
353     IAM_LOGI("auth widget reload");
354     std::lock_guard<std::recursive_mutex> lock(mutex_);
355     WidgetRotatePara widgetRotatePara;
356     widgetRotatePara.isReload = true;
357     widgetRotatePara.orientation = orientation;
358     widgetRotatePara.needRotate = needRotate;
359     widgetRotatePara.alreadyLoad = alreadyLoad;
360     widgetRotatePara.rotateAuthType = rotateAuthType;
361     if (alreadyLoad) {
362         widgetAlreadyLoad_ = 1;
363     }
364     if (!isValidRotate(widgetRotatePara)) {
365         IAM_LOGE("check rotate failed");
366         return false;
367     }
368     if (!ConnectExtension(widgetRotatePara)) {
369         IAM_LOGE("failed to reload widget");
370         return false;
371     }
372     return true;
373 }
374 
isValidRotate(const WidgetRotatePara &widgetRotatePara)375 bool WidgetContext::isValidRotate(const WidgetRotatePara &widgetRotatePara)
376 {
377     IAM_LOGI("check rotate, needRotate: %{public}u, orientation: %{public}u, orientation_: %{public}u",
378         widgetRotatePara.needRotate, widgetRotatePara.orientation, widgetRotateOrientation_);
379     if (widgetRotatePara.needRotate) {
380         IAM_LOGI("check rotate, widgetAlreadyLoad_: %{public}u", widgetAlreadyLoad_);
381         if (widgetRotatePara.orientation == ORIENTATION_PORTRAIT_INVERTED && !widgetAlreadyLoad_) {
382             IAM_LOGI("only support first");
383             return true;
384         }
385         if (widgetRotatePara.orientation > widgetRotateOrientation_ &&
386             widgetRotatePara.orientation - widgetRotateOrientation_ == NOT_SUPPORT_ORIENTATION_INVERTED) {
387             return false;
388         }
389         if (widgetRotatePara.orientation < widgetRotateOrientation_ &&
390             widgetRotateOrientation_ - widgetRotatePara.orientation == NOT_SUPPORT_ORIENTATION_INVERTED) {
391             return false;
392         }
393     }
394     return true;
395 }
396 
StopAuthList(const std::vector<AuthType> &authTypeList)397 void WidgetContext::StopAuthList(const std::vector<AuthType> &authTypeList)
398 {
399     IAM_LOGI("stop auth list");
400     std::lock_guard<std::recursive_mutex> lock(mutex_);
401     for (auto &authType : authTypeList) {
402         auto it = std::find_if(runTaskInfoList_.begin(),
403             runTaskInfoList_.end(), [authType] (const TaskInfo &taskInfo) {
404             return (taskInfo.authType == authType);
405         });
406         if (it != runTaskInfoList_.end()) {
407             if (it->task == nullptr) {
408                 IAM_LOGE("task is nullptr");
409                 return;
410             }
411             it->task->Stop();
412             runTaskInfoList_.erase(it);
413         }
414     }
415 }
416 
SuccessAuth(AuthType authType)417 void WidgetContext::SuccessAuth(AuthType authType)
418 {
419     IAM_LOGI("success auth. authType:%{public}d", static_cast<int32_t>(authType));
420     std::lock_guard<std::recursive_mutex> lock(mutex_);
421     // report success to App
422     End(ResultCode::SUCCESS);
423 }
424 
ConnectExtensionAbility(const AAFwk::Want &want, const std::string commandStr)425 int32_t WidgetContext::ConnectExtensionAbility(const AAFwk::Want &want, const std::string commandStr)
426 {
427     IAM_LOGI("ConnectExtensionAbility start");
428     if (connection_ != nullptr) {
429         IAM_LOGE("invalid connection_");
430         return ERR_INVALID_OPERATION;
431     }
432     connection_ = sptr<UIExtensionAbilityConnection>(new (std::nothrow) UIExtensionAbilityConnection(commandStr));
433     if (connection_ == nullptr) {
434         IAM_LOGE("new connection error.");
435         return ERR_NO_MEMORY;
436     }
437 
438     std::string identity = IPCSkeleton::ResetCallingIdentity();
439     auto ret = AAFwk::ExtensionManagerClient::GetInstance().ConnectServiceExtensionAbility(want, connection_, nullptr,
440         DEFAULT_VALUE);
441     IPCSkeleton::SetCallingIdentity(identity);
442     IAM_LOGI("ConnectExtensionAbility errCode=%{public}d", ret);
443     return ret;
444 }
445 
ConnectExtension(const WidgetRotatePara &widgetRotatePara)446 bool WidgetContext::ConnectExtension(const WidgetRotatePara &widgetRotatePara)
447 {
448     if (widgetRotatePara.isReload) {
449         for (auto &authType : para_.authTypeList) {
450             ContextFactory::AuthProfile profile;
451             if (!AuthWidgetHelper::GetUserAuthProfile(para_.userId, authType, profile)) {
452                 IAM_LOGE("get user authType:%{public}d profile failed", static_cast<int32_t>(authType));
453                 return false;
454             }
455             para_.authProfileMap[authType] = profile;
456         }
457     }
458     std::string tmp = BuildStartCommand(widgetRotatePara);
459     IAM_LOGI("start command: %{public}s", tmp.c_str());
460 
461     AAFwk::Want want;
462     std::string bundleName = "com.ohos.systemui";
463     std::string abilityName = "com.ohos.systemui.dialog";
464     want.SetElementName(bundleName, abilityName);
465     auto ret = ConnectExtensionAbility(want, tmp);
466     if (ret != ERR_OK) {
467         UserIam::UserAuth::ReportSystemFault(Common::GetNowTimeString(), "userauthservice");
468         IAM_LOGE("ConnectExtensionAbility failed.");
469         return false;
470     }
471     return true;
472 }
473 
DisconnectExtension()474 bool WidgetContext::DisconnectExtension()
475 {
476     if (connection_ == nullptr) {
477         IAM_LOGE("invalid connection handle");
478         return false;
479     }
480     WidgetClient::Instance().ForceStopAuth();
481     connection_->ReleaseUIExtensionComponent();
482     ErrCode ret = AAFwk::ExtensionManagerClient::GetInstance().DisconnectAbility(connection_);
483     connection_ = nullptr;
484     if (ret != ERR_OK) {
485         IAM_LOGE("disconnect extension ability failed ret: %{public}d.", ret);
486         return false;
487     }
488     return true;
489 }
490 
End(const ResultCode &resultCode)491 void WidgetContext::End(const ResultCode &resultCode)
492 {
493     IAM_LOGI("in End, resultCode: %{public}d", static_cast<int32_t>(resultCode));
494     WidgetClient::Instance().Reset();
495     StopAllRunTask();
496     if (resultCode != ResultCode::SUCCESS) {
497         IAM_LOGI("Try to disconnect extesnion");
498         if (!DisconnectExtension()) {
499             IAM_LOGE("failed to release launch widget.");
500         }
501     }
502     IF_FALSE_LOGE_AND_RETURN(callerCallback_ != nullptr);
503     Attributes attr;
504     if (resultCode == ResultCode::SUCCESS) {
505         if (!attr.SetInt32Value(Attributes::ATTR_AUTH_TYPE, authResultInfo_.authType)) {
506             IAM_LOGE("set auth type failed.");
507             callerCallback_->SetTraceAuthFinishReason("WidgetContext End set authType fail");
508             callerCallback_->OnResult(ResultCode::GENERAL_ERROR, attr);
509             return;
510         }
511         if (authResultInfo_.token.size() > 0) {
512             if (!attr.SetUint8ArrayValue(Attributes::ATTR_SIGNATURE, authResultInfo_.token)) {
513                 IAM_LOGE("set signature token failed.");
514                 callerCallback_->SetTraceAuthFinishReason("WidgetContext End set token fail");
515                 callerCallback_->OnResult(ResultCode::GENERAL_ERROR, attr);
516                 return;
517             }
518         }
519         if (!attr.SetUint64Value(Attributes::ATTR_CREDENTIAL_DIGEST, authResultInfo_.credentialDigest)) {
520             IAM_LOGE("set credential digest failed.");
521             callerCallback_->SetTraceAuthFinishReason("WidgetContext End set credentialDigest fail");
522             callerCallback_->OnResult(ResultCode::GENERAL_ERROR, attr);
523             return;
524         }
525         if (!attr.SetUint16Value(Attributes::ATTR_CREDENTIAL_COUNT, authResultInfo_.credentialCount)) {
526             IAM_LOGE("set credential count failed.");
527             callerCallback_->SetTraceAuthFinishReason("WidgetContext End set credentialCount fail");
528             callerCallback_->OnResult(ResultCode::GENERAL_ERROR, attr);
529             return;
530         }
531     }
532     callerCallback_->SetTraceAuthFinishReason("WidgetContext End fail");
533     callerCallback_->OnResult(resultCode, attr);
534 }
535 
StopAllRunTask()536 void WidgetContext::StopAllRunTask()
537 {
538     std::lock_guard<std::recursive_mutex> lock(mutex_);
539     for (auto &taskInfo : runTaskInfoList_) {
540         IAM_LOGI("stop task");
541         if (taskInfo.task == nullptr) {
542             IAM_LOGE("task is null");
543             continue;
544         }
545         taskInfo.task->Stop();
546     }
547     runTaskInfoList_.clear();
548 }
549 
BuildStartCommand(const WidgetRotatePara &widgetRotatePara)550 std::string WidgetContext::BuildStartCommand(const WidgetRotatePara &widgetRotatePara)
551 {
552     WidgetCmdParameters widgetCmdParameters;
553     widgetCmdParameters.uiExtensionType = UI_EXTENSION_TYPE_SET;
554     widgetCmdParameters.useriamCmdData.widgetContextId = GetContextId();
555     widgetCmdParameters.useriamCmdData.title = para_.widgetParam.title;
556     widgetCmdParameters.useriamCmdData.windowModeType = WinModeType2Str(para_.widgetParam.windowMode);
557     widgetCmdParameters.useriamCmdData.navigationButtonText = para_.widgetParam.navigationButtonText;
558     auto it = para_.authProfileMap.find(AuthType::PIN);
559     if (it != para_.authProfileMap.end()) {
560         widgetCmdParameters.useriamCmdData.pinSubType = PinSubType2Str(static_cast<PinSubType>(it->second.pinSubType));
561     }
562     widgetCmdParameters.sysDialogZOrder = SYSDIALOG_ZORDER_DEFAULT;
563     if (ContextAppStateObserverManager::GetInstance().GetScreenLockState()) {
564         IAM_LOGI("the screen is currently locked, set zOrder");
565         widgetCmdParameters.sysDialogZOrder = SYSDIALOG_ZORDER_UPPER;
566     }
567     std::vector<std::string> typeList;
568     for (auto &item : para_.authProfileMap) {
569         auto &at = item.first;
570         auto &profile = item.second;
571         typeList.push_back(AuthType2Str(at));
572         WidgetCommand::Cmd cmd {
573             .event = CMD_NOTIFY_AUTH_START,
574             .version = NOTICE_VERSION_STR,
575             .type = AuthType2Str(at)
576         };
577         if (at == AuthType::FINGERPRINT && !profile.sensorInfo.empty()) {
578             cmd.sensorInfo = profile.sensorInfo;
579         }
580         if (para_.isPinExpired) {
581             cmd.result = PIN_EXPIRED;
582         }
583         cmd.remainAttempts = profile.remainTimes;
584         cmd.lockoutDuration = profile.freezingTime;
585         WidgetCommand::ExtraInfo extraInfo {
586             .callingBundleName = GetCallingBundleName(),
587             .challenge = para_.challenge
588         };
589         cmd.extraInfo = extraInfo;
590         widgetCmdParameters.useriamCmdData.cmdList.push_back(cmd);
591     }
592     widgetCmdParameters.useriamCmdData.typeList = typeList;
593     widgetCmdParameters.useriamCmdData.callingAppID = para_.callingAppID;
594     ProcessRotatePara(widgetCmdParameters, widgetRotatePara);
595     nlohmann::json root = widgetCmdParameters;
596     std::string cmdData = root.dump();
597     return cmdData;
598 }
599 
ProcessRotatePara(WidgetCmdParameters &widgetCmdParameters, const WidgetRotatePara &widgetRotatePara)600 void WidgetContext::ProcessRotatePara(WidgetCmdParameters &widgetCmdParameters,
601     const WidgetRotatePara &widgetRotatePara)
602 {
603     if (widgetRotatePara.isReload) {
604         widgetCmdParameters.useriamCmdData.isReload = 1;
605         if (widgetRotatePara.rotateAuthType == FACE) {
606             widgetCmdParameters.useriamCmdData.isReload = faceReload_;
607         }
608         widgetCmdParameters.useriamCmdData.rotateAuthType = AuthType2Str(widgetRotatePara.rotateAuthType);
609     }
610     IAM_LOGI("needRotate: %{public}u, orientation: %{public}u", widgetRotatePara.needRotate,
611         widgetRotatePara.orientation);
612     widgetRotateOrientation_ = widgetRotatePara.orientation;
613     if (widgetRotatePara.needRotate) {
614         if (widgetRotatePara.orientation == ORIENTATION_LANDSCAPE) {
615             widgetCmdParameters.uiExtNodeAngle = TO_PORTRAIT;
616         }
617         if (widgetRotatePara.orientation == ORIENTATION_PORTRAIT_INVERTED) {
618             widgetCmdParameters.uiExtNodeAngle = TO_INVERTED;
619         }
620         if (widgetRotatePara.orientation == ORIENTATION_LANDSCAPE_INVERTED) {
621             widgetCmdParameters.uiExtNodeAngle = TO_PORTRAIT_INVERTED;
622         }
623     }
624 }
625 
GetCallingBundleName()626 std::string WidgetContext::GetCallingBundleName()
627 {
628     if (para_.callerType == Security::AccessToken::TOKEN_HAP) {
629         return para_.callerName;
630     }
631     return "";
632 }
633 } // namespace UserAuth
634 } // namespace UserIam
635 } // namespace OHOS
636