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