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