1 /*
2 * Copyright (c) 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
16 #include "user_auth_modal_callback.h"
17
18 #include "ability.h"
19 #include "system_ability_definition.h"
20 #include "ui_holder_extension_context.h"
21 #include "want.h"
22
23 #include "iam_logger.h"
24 #include "iam_ptr.h"
25
26 #include "user_auth_napi_client_impl.h"
27
28 #define LOG_TAG "USER_AUTH_SDK"
29
30 namespace OHOS {
31 namespace UserIam {
32 namespace UserAuth {
UserAuthModalCallback(const std::shared_ptr<AbilityRuntime::Context> context)33 UserAuthModalCallback::UserAuthModalCallback(const std::shared_ptr<AbilityRuntime::Context> context)
34 : context_(context)
35 {}
36
~UserAuthModalCallback()37 UserAuthModalCallback::~UserAuthModalCallback()
38 {}
39
SendCommand(uint64_t contextId,const std::string & cmdData)40 void UserAuthModalCallback::SendCommand(uint64_t contextId, const std::string &cmdData)
41 {
42 IAM_LOGI("SendCommand start");
43 std::lock_guard<std::recursive_mutex> lock(mutex_);
44 if (context_ != nullptr) {
45 if (contextId == contextId_ && cmdData.empty()) {
46 IAM_LOGI("stop modal");
47 ReleaseModal();
48 return;
49 }
50 IAM_LOGI("widgetParam context not null, process as modal application");
51 if (contextId == 0 || cmdData.empty()) {
52 IAM_LOGI("stop modal for invalid request");
53 isInitError_ = true;
54 CancelAuthentication(contextId, CancelReason::MODAL_CREATE_ERROR);
55 return;
56 }
57 contextId_ = contextId;
58 bool createModalRet = CreateUIExtension(context_, contextId, cmdData);
59 // Cancel for failed
60 if (!createModalRet) {
61 IAM_LOGE("create modal error, createModalRet: %{public}d", createModalRet);
62 isInitError_ = true;
63 CancelAuthentication(contextId, CancelReason::MODAL_CREATE_ERROR);
64 return;
65 }
66 IAM_LOGI("create modal success");
67 isInit_ = true;
68 return;
69 }
70 IAM_LOGI("widgetParam.context is nullptr");
71 }
72
IsModalInit()73 bool UserAuthModalCallback::IsModalInit()
74 {
75 IAM_LOGD("get is modal init");
76 std::lock_guard<std::recursive_mutex> lock(mutex_);
77 return isInit_;
78 }
79
IsModalDestroy()80 bool UserAuthModalCallback::IsModalDestroy()
81 {
82 IAM_LOGD("get is modal on destroy");
83 std::lock_guard<std::recursive_mutex> lock(mutex_);
84 if (isInitError_ || (uiExtCallback_ != nullptr && uiExtCallback_->IsModalDestroy())) {
85 IAM_LOGI("modal on destroy");
86 return true;
87 }
88 return false;
89 }
90
InitAndGetUIContent(const std::shared_ptr<OHOS::AbilityRuntime::Context> context)91 Ace::UIContent* UserAuthModalCallback::InitAndGetUIContent(
92 const std::shared_ptr<OHOS::AbilityRuntime::Context> context)
93 {
94 if (context == nullptr) {
95 IAM_LOGE("context is nullptr");
96 return nullptr;
97 }
98 Ace::UIContent* uiContent = nullptr;
99 auto abilityContext = AbilityRuntime::Context::ConvertTo<AbilityRuntime::AbilityContext>(context);
100 std::shared_ptr<AbilityRuntime::UIHolderExtensionContext> holderContext;
101 if (abilityContext == nullptr) {
102 IAM_LOGE("abilityContext is nullptr");
103 holderContext = AbilityRuntime::Context::ConvertTo<AbilityRuntime::UIHolderExtensionContext>(context);
104 if (holderContext == nullptr) {
105 IAM_LOGE("uiExtensionContext is nullptr");
106 return nullptr;
107 }
108 uiContent = holderContext->GetUIContent();
109 if (uiContent == nullptr) {
110 IAM_LOGE("uiContent is nullptr");
111 return nullptr;
112 }
113 } else {
114 uiContent = abilityContext->GetUIContent();
115 if (uiContent == nullptr) {
116 IAM_LOGE("uiContent is nullptr");
117 return nullptr;
118 }
119 }
120
121 uiExtCallback_ = std::make_shared<ModalExtensionCallback>();
122 uiExtCallback_->SetAbilityContext(abilityContext);
123 uiExtCallback_->SetHolderContext(holderContext);
124
125 return uiContent;
126 }
127
CreateUIExtension(const std::shared_ptr<OHOS::AbilityRuntime::Context> context,uint64_t contextId,const std::string & cmdData)128 bool UserAuthModalCallback::CreateUIExtension(const std::shared_ptr<OHOS::AbilityRuntime::Context> context,
129 uint64_t contextId, const std::string &cmdData)
130 {
131 Ace::UIContent* uiContent = InitAndGetUIContent(context);
132 if (uiContent == nullptr) {
133 IAM_LOGE("uiContent invalid");
134 return false;
135 }
136
137 AAFwk::Want want;
138 std::string targetBundleName = "com.ohos.useriam.authwidget";
139 std::string targetAbilityName = "UserAuthModalUIAbility";
140 want.SetElementName(targetBundleName, targetAbilityName);
141
142 std::string typeKey = "ability.want.params.uiExtensionType";
143 std::string typeValue = "sys/commonUI";
144 want.SetParam(typeKey, typeValue);
145 std::string commandKey = "parameters";
146 want.SetParam(commandKey, cmdData);
147
148 uiExtCallback_->SetContextId(contextId);
149 Ace::ModalUIExtensionCallbacks uiExtensionCallbacks = {
150 .onRelease = std::bind(&ModalExtensionCallback::OnRelease, uiExtCallback_, std::placeholders::_1),
151 .onResult = std::bind(&ModalExtensionCallback::OnResult, uiExtCallback_,
152 std::placeholders::_1, std::placeholders::_2),
153 .onReceive = std::bind(&ModalExtensionCallback::OnReceive, uiExtCallback_, std::placeholders::_1),
154 .onError = std::bind(&ModalExtensionCallback::OnError, uiExtCallback_,
155 std::placeholders::_1, std::placeholders::_2, std::placeholders::_3),
156 .onRemoteReady = std::bind(&ModalExtensionCallback::OnRemoteReady, uiExtCallback_, std::placeholders::_1),
157 .onDestroy = std::bind(&ModalExtensionCallback::OnDestroy, uiExtCallback_),
158 };
159
160 Ace::ModalUIExtensionConfig config;
161 config.isProhibitBack = true;
162
163 int32_t sessionId = uiContent->CreateModalUIExtension(want, uiExtensionCallbacks, config);
164 IAM_LOGI("Create end, sessionId: %{public}d", sessionId);
165 if (sessionId == 0) {
166 IAM_LOGE("Create component failed, sessionId is 0");
167 return false;
168 }
169 uiExtCallback_->SetSessionId(sessionId);
170 return true;
171 }
172
CancelAuthentication(uint64_t contextId,int32_t cancelReason)173 void UserAuthModalCallback::CancelAuthentication(uint64_t contextId, int32_t cancelReason)
174 {
175 // cancel for failed
176 int32_t code = UserAuthNapiClientImpl::Instance().CancelAuthentication(contextId, cancelReason);
177 IAM_LOGI("CancelAuthentication, code: %{public}d, contextId: ****%{public}hx, code: %{public}d", code,
178 static_cast<uint16_t>(contextId), cancelReason);
179 ReleaseModal();
180 }
181
ReleaseModal()182 void UserAuthModalCallback::ReleaseModal()
183 {
184 // release modal widget
185 if (uiExtCallback_ != nullptr) {
186 IAM_LOGI("release modal");
187 isInitError_ = true;
188 uiExtCallback_->ReleaseOrErrorHandle(0);
189 }
190 }
191 } // namespace UserAuth
192 } // namespace UserIam
193 } // namespace OHOS