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 "auto_fill_extension_callback.h"
16
17 #include "auto_fill_error.h"
18 #include "auto_fill_manager.h"
19 #include "auto_fill_manager_util.h"
20 #include "hilog_tag_wrapper.h"
21 #include "int_wrapper.h"
22 #include "string_wrapper.h"
23 #include "view_data.h"
24
25 namespace OHOS {
26 namespace AbilityRuntime {
27 namespace {
28 constexpr const char* WANT_PARAMS_VIEW_DATA_KEY = "ohos.ability.params.viewData";
29 constexpr const char* WANT_PARAMS_AUTO_FILL_CMD_KEY = "ohos.ability.params.autoFillCmd";
30 constexpr const char* WANT_PARAMS_FILL_CONTENT = "ohos.ability.params.fillContent";
31 constexpr const char* WANT_PARAMS_CUSTOM_DATA_KEY = "ohos.ability.params.customData";
32 constexpr const char* WANT_PARAMS_AUTO_FILL_EVENT_KEY = "ability.want.params.AutoFillEvent";
33 constexpr const char* WANT_PARAMS_UPDATE_POPUP_WIDTH = "ohos.ability.params.popupWidth";
34 constexpr const char* WANT_PARAMS_UPDATE_POPUP_HEIGHT = "ohos.ability.params.popupHeight";
35 constexpr const char* WANT_PARAMS_UPDATE_POPUP_PLACEMENT = "ohos.ability.params.popupPlacement";
36 constexpr const char* WANT_PARAMS_EXTENSION_TYPE_KEY = "ability.want.params.uiExtensionType";
37 constexpr const char* WANT_PARAMS_EXTENSION_TYPE = "autoFill/password";
38 constexpr const char* WANT_PARAMS_SMART_EXTENSION_TYPE = "autoFill/smart";
39 constexpr const char* WANT_PARAMS_AUTO_FILL_TYPE_KEY = "ability.want.params.AutoFillType";
40 constexpr const char* WANT_PARAMS_AUTO_FILL_POPUP_WINDOW_KEY = "ohos.ability.params.popupWindow";
41 } // namespace
42
AutoFillExtensionCallback()43 AutoFillExtensionCallback::AutoFillExtensionCallback()
44 {
45 callbackId_ = GenerateCallbackId();
46 }
47
OnResult(int32_t errCode,const AAFwk::Want & want)48 void AutoFillExtensionCallback::OnResult(int32_t errCode, const AAFwk::Want &want)
49 {
50 TAG_LOGD(AAFwkTag::AUTOFILLMGR, "Called, result code: %{public}d", errCode);
51 AutoFillManager::GetInstance().RemoveEvent(callbackId_);
52 CloseUIExtension();
53 if (autoFillWindowType_ == AutoFill::AutoFillWindowType::POPUP_WINDOW) {
54 isOnResult_ = true;
55 want_ = want;
56 errCode_ = errCode;
57 return;
58 }
59
60 if (errCode == AutoFill::AUTO_FILL_SUCCESS) {
61 SendAutoFillSuccess(want);
62 } else {
63 auto resultCode = (errCode == AutoFill::AUTO_FILL_CANCEL) ?
64 AutoFill::AUTO_FILL_CANCEL : AutoFill::AUTO_FILL_FAILED;
65 SendAutoFillFailed(resultCode, want);
66 }
67 }
68
OnRelease(int32_t errCode)69 void AutoFillExtensionCallback::OnRelease(int32_t errCode)
70 {
71 TAG_LOGD(AAFwkTag::AUTOFILLMGR, "Called, result code: %{public}d", errCode);
72 AutoFillManager::GetInstance().RemoveEvent(callbackId_);
73 CloseUIExtension();
74 if (errCode != 0) {
75 SendAutoFillFailed(AutoFill::AUTO_FILL_RELEASE_FAILED);
76 }
77 }
78
OnError(int32_t errCode,const std::string & name,const std::string & message)79 void AutoFillExtensionCallback::OnError(int32_t errCode, const std::string &name, const std::string &message)
80 {
81 TAG_LOGD(AAFwkTag::AUTOFILLMGR, "Called, errcode: %{public}d, name: %{public}s, message: %{public}s",
82 errCode, name.c_str(), message.c_str());
83 AutoFillManager::GetInstance().RemoveEvent(callbackId_);
84 CloseUIExtension();
85 if (errCode != 0) {
86 SendAutoFillFailed(AutoFill::AUTO_FILL_ON_ERROR);
87 }
88 }
89
HandleReloadInModal(const AAFwk::WantParams & wantParams)90 void AutoFillExtensionCallback::HandleReloadInModal(const AAFwk::WantParams &wantParams)
91 {
92 TAG_LOGD(AAFwkTag::AUTOFILLMGR, "called");
93 SetModalUIExtensionProxy(nullptr);
94
95 auto oldWindowType = autoFillWindowType_;
96 auto oldSessionId = sessionId_;
97 int32_t resultCode = ReloadInModal(wantParams);
98 if (resultCode != AutoFill::AUTO_FILL_SUCCESS) {
99 SendAutoFillFailed(resultCode);
100 }
101
102 auto uiContent = GetUIContent();
103 if (uiContent == nullptr) {
104 TAG_LOGE(AAFwkTag::AUTOFILLMGR, "null uiContent");
105 return;
106 }
107
108 if (oldWindowType == AutoFill::AutoFillWindowType::POPUP_WINDOW) {
109 isReloadInModal_ = true;
110 uiContent->DestroyCustomPopupUIExtension(oldSessionId);
111 } else {
112 TAG_LOGW(AAFwkTag::AUTOFILLMGR, "Window type not popup, can not be destroyed");
113 }
114 }
115
ReloadInModal(const AAFwk::WantParams & wantParams)116 int32_t AutoFillExtensionCallback::ReloadInModal(const AAFwk::WantParams &wantParams)
117 {
118 TAG_LOGD(AAFwkTag::AUTOFILLMGR, "called");
119 std::lock_guard<std::mutex> lock(closeMutex_);
120 auto uiContent = GetUIContent();
121 if (uiContent == nullptr) {
122 TAG_LOGE(AAFwkTag::AUTOFILLMGR, "null uiContent");
123 return AutoFill::AUTO_FILL_OBJECT_IS_NULL;
124 }
125
126 AutoFillManager::GetInstance().SetTimeOutEvent(callbackId_);
127 AAFwk::Want want;
128 want.SetParam(WANT_PARAMS_AUTO_FILL_CMD_KEY, static_cast<int32_t>(AutoFill::AutoFillCommand::RELOAD_IN_MODAL));
129 want.SetParam(WANT_PARAMS_CUSTOM_DATA_KEY, wantParams.GetStringParam(WANT_PARAMS_CUSTOM_DATA_KEY));
130 isSmartAutoFill_ ? want.SetParam(WANT_PARAMS_EXTENSION_TYPE_KEY, std::string(WANT_PARAMS_SMART_EXTENSION_TYPE)) :
131 want.SetParam(WANT_PARAMS_EXTENSION_TYPE_KEY, std::string(WANT_PARAMS_EXTENSION_TYPE));
132 want.SetParam(WANT_PARAMS_AUTO_FILL_TYPE_KEY, static_cast<int32_t>(request_.autoFillType));
133 want.SetParam(WANT_PARAMS_VIEW_DATA_KEY, request_.viewData.ToJsonString());
134 want.SetParam(WANT_PARAMS_AUTO_FILL_POPUP_WINDOW_KEY, false);
135 Ace::ModalUIExtensionCallbacks callback;
136 AutoFillManager::GetInstance().BindModalUIExtensionCallback(shared_from_this(), callback);
137 Ace::ModalUIExtensionConfig config;
138 config.isAsyncModalBinding = true;
139 int32_t sessionId = 0;
140 sessionId = uiContent->CreateModalUIExtension(want, callback, config);
141 if (sessionId == 0) {
142 TAG_LOGE(AAFwkTag::AUTOFILLMGR, "Create ui extension failed");
143 AutoFillManager::GetInstance().RemoveEvent(callbackId_);
144 return AutoFill::AUTO_FILL_CREATE_MODULE_UI_EXTENSION_FAILED;
145 }
146 SetSessionId(sessionId);
147 SetWindowType(AutoFill::AutoFillWindowType::MODAL_WINDOW);
148 return AutoFill::AUTO_FILL_SUCCESS;
149 }
150
OnReceive(const AAFwk::WantParams & wantParams)151 void AutoFillExtensionCallback::OnReceive(const AAFwk::WantParams &wantParams)
152 {
153 TAG_LOGD(AAFwkTag::AUTOFILLMGR, "called");
154 int32_t cmdValue = wantParams.GetIntParam(WANT_PARAMS_AUTO_FILL_CMD_KEY, 0);
155 if (cmdValue == static_cast<int32_t>(AutoFill::AutoFillCommand::RELOAD_IN_MODAL)) {
156 HandleReloadInModal(wantParams);
157 return;
158 } else if (cmdValue == static_cast<int32_t>(AutoFill::AutoFillCommand::RESIZE)) {
159 UpdateCustomPopupConfig(wantParams);
160 }
161 if (wantParams.GetIntParam(WANT_PARAMS_AUTO_FILL_EVENT_KEY, 0) == AutoFill::AUTO_FILL_CANCEL_TIME_OUT) {
162 AutoFillManager::GetInstance().RemoveEvent(callbackId_);
163 }
164 }
165
UpdateCustomPopupConfig(const AAFwk::WantParams & wantParams)166 void AutoFillExtensionCallback::UpdateCustomPopupConfig(const AAFwk::WantParams &wantParams)
167 {
168 TAG_LOGD(AAFwkTag::AUTOFILLMGR, "called");
169 AutoFill::AutoFillCustomConfig autoFillCustomConfig = request_.config;
170 if (wantParams.HasParam(WANT_PARAMS_UPDATE_POPUP_WIDTH) &&
171 wantParams.HasParam(WANT_PARAMS_UPDATE_POPUP_HEIGHT)) {
172 AutoFill::PopupSize popupSize;
173 popupSize.width = wantParams.GetIntParam(WANT_PARAMS_UPDATE_POPUP_WIDTH, 0);
174 popupSize.height = wantParams.GetIntParam(WANT_PARAMS_UPDATE_POPUP_HEIGHT, 0);
175 autoFillCustomConfig.targetSize = popupSize;
176 }
177 if (wantParams.HasParam(WANT_PARAMS_UPDATE_POPUP_PLACEMENT)) {
178 autoFillCustomConfig.placement =
179 static_cast<AutoFill::PopupPlacement>(wantParams.GetIntParam(WANT_PARAMS_UPDATE_POPUP_PLACEMENT, 0));
180 }
181 {
182 std::lock_guard<std::mutex> lock(requestCallbackMutex_);
183 if (fillCallback_ != nullptr) {
184 fillCallback_->onPopupConfigWillUpdate(autoFillCustomConfig);
185 }
186 }
187 Ace::CustomPopupUIExtensionConfig popupConfig;
188 AutoFillManagerUtil::ConvertToPopupUIExtensionConfig(autoFillCustomConfig, popupConfig);
189 auto uiContent = GetUIContent();
190 if (uiContent == nullptr) {
191 TAG_LOGE(AAFwkTag::AUTOFILLMGR, "null uiContent");
192 return;
193 }
194 uiContent->UpdateCustomPopupUIExtension(popupConfig);
195 }
196
onRemoteReady(const std::shared_ptr<Ace::ModalUIExtensionProxy> & modalUIExtensionProxy)197 void AutoFillExtensionCallback::onRemoteReady(const std::shared_ptr<Ace::ModalUIExtensionProxy> &modalUIExtensionProxy)
198 {
199 TAG_LOGD(AAFwkTag::AUTOFILLMGR, "called");
200 if (modalUIExtensionProxy == nullptr) {
201 TAG_LOGE(AAFwkTag::AUTOFILLMGR, "null proxy");
202 return;
203 }
204 SetModalUIExtensionProxy(modalUIExtensionProxy);
205 if (request_.onUIExtensionProxyReady) {
206 request_.onUIExtensionProxyReady();
207 }
208 }
209
onDestroy()210 void AutoFillExtensionCallback::onDestroy()
211 {
212 TAG_LOGD(AAFwkTag::AUTOFILLMGR, "called");
213 if (isReloadInModal_) {
214 isReloadInModal_ = false;
215 return;
216 }
217 if (isOnResult_ && autoFillWindowType_ == AutoFill::AutoFillWindowType::POPUP_WINDOW) {
218 isOnResult_ = false;
219 if (errCode_ == AutoFill::AUTO_FILL_SUCCESS) {
220 SendAutoFillSuccess(want_);
221 } else {
222 auto resultCode = (errCode_ == AutoFill::AUTO_FILL_CANCEL) ?
223 AutoFill::AUTO_FILL_CANCEL : AutoFill::AUTO_FILL_FAILED;
224 SendAutoFillFailed(resultCode);
225 }
226 return;
227 }
228 CloseUIExtension();
229 SendAutoFillFailed(AutoFill::AUTO_FILL_FAILED);
230 }
231
SetFillRequestCallback(const std::shared_ptr<IFillRequestCallback> & callback)232 void AutoFillExtensionCallback::SetFillRequestCallback(const std::shared_ptr<IFillRequestCallback> &callback)
233 {
234 std::lock_guard<std::mutex> lock(requestCallbackMutex_);
235 fillCallback_ = callback;
236 }
237
SetSaveRequestCallback(const std::shared_ptr<ISaveRequestCallback> & callback)238 void AutoFillExtensionCallback::SetSaveRequestCallback(const std::shared_ptr<ISaveRequestCallback> &callback)
239 {
240 std::lock_guard<std::mutex> lock(requestCallbackMutex_);
241 saveCallback_ = callback;
242 }
243
SetSessionId(int32_t sessionId)244 void AutoFillExtensionCallback::SetSessionId(int32_t sessionId)
245 {
246 sessionId_= sessionId;
247 }
248
SetInstanceId(int32_t instanceId)249 void AutoFillExtensionCallback::SetInstanceId(int32_t instanceId)
250 {
251 instanceId_.store(instanceId);
252 }
253
GetInstanceId()254 int32_t AutoFillExtensionCallback::GetInstanceId()
255 {
256 return instanceId_.load();
257 }
258
GetUIContent()259 Ace::UIContent* AutoFillExtensionCallback::GetUIContent()
260 {
261 return Ace::UIContent::GetUIContent(GetInstanceId());
262 }
263
SetWindowType(const AutoFill::AutoFillWindowType & autoFillWindowType)264 void AutoFillExtensionCallback::SetWindowType(const AutoFill::AutoFillWindowType &autoFillWindowType)
265 {
266 autoFillWindowType_ = autoFillWindowType;
267 }
268
GetWindowType() const269 AutoFill::AutoFillWindowType AutoFillExtensionCallback::GetWindowType() const
270 {
271 return autoFillWindowType_;
272 }
273
SetAutoFillRequest(const AutoFill::AutoFillRequest & request)274 void AutoFillExtensionCallback::SetAutoFillRequest(const AutoFill::AutoFillRequest &request)
275 {
276 request_ = request;
277 }
278
SetExtensionType(bool isSmartAutoFill)279 void AutoFillExtensionCallback::SetExtensionType(bool isSmartAutoFill)
280 {
281 isSmartAutoFill_ = isSmartAutoFill;
282 }
283
HandleTimeOut()284 void AutoFillExtensionCallback::HandleTimeOut()
285 {
286 CloseUIExtension();
287 SendAutoFillFailed(AutoFill::AUTO_FILL_REQUEST_TIME_OUT);
288 }
289
GenerateCallbackId()290 uint32_t AutoFillExtensionCallback::GenerateCallbackId()
291 {
292 static std::atomic<uint32_t> callbackId(0);
293 ++callbackId;
294 return callbackId.load();
295 }
296
GetCallbackId() const297 uint32_t AutoFillExtensionCallback::GetCallbackId() const
298 {
299 return callbackId_;
300 }
301
SetModalUIExtensionProxy(const std::shared_ptr<Ace::ModalUIExtensionProxy> & proxy)302 void AutoFillExtensionCallback::SetModalUIExtensionProxy(const std::shared_ptr<Ace::ModalUIExtensionProxy>& proxy)
303 {
304 std::lock_guard<std::mutex> lock(proxyMutex_);
305 modalUIExtensionProxy_ = proxy;
306 }
307
GetModalUIExtensionProxy()308 std::shared_ptr<Ace::ModalUIExtensionProxy> AutoFillExtensionCallback::GetModalUIExtensionProxy()
309 {
310 std::lock_guard<std::mutex> lock(proxyMutex_);
311 return modalUIExtensionProxy_;
312 }
313
UpdateCustomPopupUIExtension(const AbilityBase::ViewData & viewData)314 void AutoFillExtensionCallback::UpdateCustomPopupUIExtension(const AbilityBase::ViewData &viewData)
315 {
316 auto modalUIExtensionProxy = GetModalUIExtensionProxy();
317 if (modalUIExtensionProxy == nullptr) {
318 TAG_LOGE(AAFwkTag::AUTOFILLMGR, "null UIExtensionProxy");
319 return;
320 }
321 AAFwk::WantParams wantParams;
322 wantParams.SetParam(WANT_PARAMS_AUTO_FILL_CMD_KEY,
323 AAFwk::Integer::Box(static_cast<int32_t>(AutoFill::AutoFillCommand::UPDATE)));
324 wantParams.SetParam(WANT_PARAMS_VIEW_DATA_KEY, AAFwk::String::Box(viewData.ToJsonString()));
325 modalUIExtensionProxy->SendData(wantParams);
326 }
327
SendAutoFillSuccess(const AAFwk::Want & want)328 void AutoFillExtensionCallback::SendAutoFillSuccess(const AAFwk::Want &want)
329 {
330 TAG_LOGI(AAFwkTag::AUTOFILLMGR, "called");
331 std::lock_guard<std::mutex> lock(requestCallbackMutex_);
332 if (fillCallback_ != nullptr) {
333 std::string dataStr = want.GetStringParam(WANT_PARAMS_VIEW_DATA_KEY);
334 AbilityBase::ViewData viewData;
335 viewData.FromJsonString(dataStr.c_str());
336 fillCallback_->OnFillRequestSuccess(viewData);
337 fillCallback_ = nullptr;
338 }
339
340 if (saveCallback_ != nullptr) {
341 saveCallback_->OnSaveRequestSuccess();
342 saveCallback_ = nullptr;
343 }
344 AutoFillManager::GetInstance().RemoveAutoFillExtensionCallback(callbackId_);
345 }
346
SendAutoFillFailed(int32_t errCode,const AAFwk::Want & want)347 void AutoFillExtensionCallback::SendAutoFillFailed(int32_t errCode, const AAFwk::Want &want)
348 {
349 TAG_LOGI(AAFwkTag::AUTOFILLMGR, "called");
350 std::lock_guard<std::mutex> lock(requestCallbackMutex_);
351 if (fillCallback_ != nullptr) {
352 std::string fillContent = want.GetStringParam(WANT_PARAMS_FILL_CONTENT);
353 bool isPopup = (autoFillWindowType_ == AutoFill::AutoFillWindowType::POPUP_WINDOW);
354 fillCallback_->OnFillRequestFailed(errCode, fillContent, isPopup);
355 fillCallback_ = nullptr;
356 }
357
358 if (saveCallback_ != nullptr) {
359 saveCallback_->OnSaveRequestFailed();
360 saveCallback_ = nullptr;
361 }
362 AutoFillManager::GetInstance().RemoveAutoFillExtensionCallback(callbackId_);
363 }
364
CloseUIExtension()365 void AutoFillExtensionCallback::CloseUIExtension()
366 {
367 Ace::UIContent* uiContent = nullptr;
368 {
369 std::lock_guard<std::mutex> lock(closeMutex_);
370 uiContent = GetUIContent();
371 if (uiContent == nullptr) {
372 TAG_LOGD(AAFwkTag::AUTOFILLMGR, "null uiContent");
373 return;
374 }
375 SetInstanceId(-1);
376 }
377
378 if (autoFillWindowType_ == AutoFill::AutoFillWindowType::POPUP_WINDOW) {
379 uiContent->DestroyCustomPopupUIExtension(sessionId_);
380 } else if (autoFillWindowType_ == AutoFill::AutoFillWindowType::MODAL_WINDOW) {
381 uiContent->CloseModalUIExtension(sessionId_);
382 }
383 SetModalUIExtensionProxy(nullptr);
384 }
385 } // namespace AbilityRuntime
386 } // namespace OHOS
387