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