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 ¶,
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