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 auto uiContent = GetUIContent();
127 if (uiContent == nullptr) {
128 TAG_LOGE(AAFwkTag::AUTOFILLMGR, "null uiContent");
129 return AutoFill::AUTO_FILL_OBJECT_IS_NULL;
130 }
131
132 AutoFillManager::GetInstance().SetTimeOutEvent(callbackId_);
133 AAFwk::Want want;
134 want.SetParam(WANT_PARAMS_AUTO_FILL_CMD_KEY, static_cast<int32_t>(AutoFill::AutoFillCommand::RELOAD_IN_MODAL));
135 want.SetParam(WANT_PARAMS_CUSTOM_DATA_KEY, wantParams.GetStringParam(WANT_PARAMS_CUSTOM_DATA_KEY));
136 isSmartAutoFill_ ? want.SetParam(WANT_PARAMS_EXTENSION_TYPE_KEY, std::string(WANT_PARAMS_SMART_EXTENSION_TYPE)) :
137 want.SetParam(WANT_PARAMS_EXTENSION_TYPE_KEY, std::string(WANT_PARAMS_EXTENSION_TYPE));
138 want.SetParam(WANT_PARAMS_AUTO_FILL_TYPE_KEY, static_cast<int32_t>(request_.autoFillType));
139 want.SetParam(WANT_PARAMS_VIEW_DATA_KEY, request_.viewData.ToJsonString());
140 want.SetParam(WANT_PARAMS_AUTO_FILL_POPUP_WINDOW_KEY, false);
141 Ace::ModalUIExtensionCallbacks callback;
142 AutoFillManager::GetInstance().BindModalUIExtensionCallback(shared_from_this(), callback);
143 Ace::ModalUIExtensionConfig config;
144 config.isAsyncModalBinding = true;
145 int32_t sessionId = 0;
146 sessionId = uiContent->CreateModalUIExtension(want, callback, config);
147 if (sessionId == 0) {
148 TAG_LOGE(AAFwkTag::AUTOFILLMGR, "Create ui extension failed");
149 AutoFillManager::GetInstance().RemoveEvent(callbackId_);
150 return AutoFill::AUTO_FILL_CREATE_MODULE_UI_EXTENSION_FAILED;
151 }
152 SetSessionId(sessionId);
153 SetWindowType(AutoFill::AutoFillWindowType::MODAL_WINDOW);
154 return AutoFill::AUTO_FILL_SUCCESS;
155 }
156
OnReceive(const AAFwk::WantParams & wantParams)157 void AutoFillExtensionCallback::OnReceive(const AAFwk::WantParams &wantParams)
158 {
159 TAG_LOGD(AAFwkTag::AUTOFILLMGR, "called");
160 int32_t cmdValue = wantParams.GetIntParam(WANT_PARAMS_AUTO_FILL_CMD_KEY, 0);
161 if (cmdValue == static_cast<int32_t>(AutoFill::AutoFillCommand::RELOAD_IN_MODAL)) {
162 HandleReloadInModal(wantParams);
163 return;
164 } else if (cmdValue == static_cast<int32_t>(AutoFill::AutoFillCommand::RESIZE)) {
165 UpdateCustomPopupConfig(wantParams);
166 }
167 if (wantParams.GetIntParam(WANT_PARAMS_AUTO_FILL_EVENT_KEY, 0) == AutoFill::AUTO_FILL_CANCEL_TIME_OUT) {
168 AutoFillManager::GetInstance().RemoveEvent(callbackId_);
169 }
170 }
171
UpdateCustomPopupConfig(const AAFwk::WantParams & wantParams)172 void AutoFillExtensionCallback::UpdateCustomPopupConfig(const AAFwk::WantParams &wantParams)
173 {
174 TAG_LOGD(AAFwkTag::AUTOFILLMGR, "called");
175 AutoFill::AutoFillCustomConfig autoFillCustomConfig = request_.config;
176 if (wantParams.HasParam(WANT_PARAMS_UPDATE_POPUP_WIDTH) &&
177 wantParams.HasParam(WANT_PARAMS_UPDATE_POPUP_HEIGHT)) {
178 AutoFill::PopupSize popupSize;
179 popupSize.width = wantParams.GetIntParam(WANT_PARAMS_UPDATE_POPUP_WIDTH, 0);
180 popupSize.height = wantParams.GetIntParam(WANT_PARAMS_UPDATE_POPUP_HEIGHT, 0);
181 autoFillCustomConfig.targetSize = popupSize;
182 }
183 if (wantParams.HasParam(WANT_PARAMS_UPDATE_POPUP_PLACEMENT)) {
184 autoFillCustomConfig.placement =
185 static_cast<AutoFill::PopupPlacement>(wantParams.GetIntParam(WANT_PARAMS_UPDATE_POPUP_PLACEMENT, 0));
186 }
187 {
188 std::lock_guard<std::mutex> lock(requestCallbackMutex_);
189 if (fillCallback_ != nullptr) {
190 fillCallback_->onPopupConfigWillUpdate(autoFillCustomConfig);
191 }
192 }
193 Ace::CustomPopupUIExtensionConfig popupConfig;
194 AutoFillManagerUtil::ConvertToPopupUIExtensionConfig(autoFillCustomConfig, popupConfig);
195 auto uiContent = GetUIContent();
196 if (uiContent == nullptr) {
197 TAG_LOGE(AAFwkTag::AUTOFILLMGR, "null uiContent");
198 return;
199 }
200 uiContent->UpdateCustomPopupUIExtension(popupConfig);
201 }
202
onRemoteReady(const std::shared_ptr<Ace::ModalUIExtensionProxy> & modalUIExtensionProxy)203 void AutoFillExtensionCallback::onRemoteReady(const std::shared_ptr<Ace::ModalUIExtensionProxy> &modalUIExtensionProxy)
204 {
205 TAG_LOGD(AAFwkTag::AUTOFILLMGR, "called");
206 if (modalUIExtensionProxy == nullptr) {
207 TAG_LOGE(AAFwkTag::AUTOFILLMGR, "null proxy");
208 return;
209 }
210 SetModalUIExtensionProxy(modalUIExtensionProxy);
211 if (request_.onUIExtensionProxyReady) {
212 request_.onUIExtensionProxyReady();
213 }
214 }
215
onDestroy()216 void AutoFillExtensionCallback::onDestroy()
217 {
218 TAG_LOGD(AAFwkTag::AUTOFILLMGR, "called");
219 if (isReloadInModal_) {
220 isReloadInModal_ = false;
221 return;
222 }
223 if (isOnResult_ && autoFillWindowType_ == AutoFill::AutoFillWindowType::POPUP_WINDOW) {
224 isOnResult_ = false;
225 if (errCode_ == AutoFill::AUTO_FILL_SUCCESS) {
226 SendAutoFillSuccess(want_);
227 } else {
228 auto resultCode = (errCode_ == AutoFill::AUTO_FILL_CANCEL) ?
229 AutoFill::AUTO_FILL_CANCEL : AutoFill::AUTO_FILL_FAILED;
230 SendAutoFillFailed(resultCode);
231 }
232 return;
233 }
234 CloseUIExtension();
235 SendAutoFillFailed(AutoFill::AUTO_FILL_FAILED);
236 }
237
SetFillRequestCallback(const std::shared_ptr<IFillRequestCallback> & callback)238 void AutoFillExtensionCallback::SetFillRequestCallback(const std::shared_ptr<IFillRequestCallback> &callback)
239 {
240 std::lock_guard<std::mutex> lock(requestCallbackMutex_);
241 fillCallback_ = callback;
242 }
243
SetSaveRequestCallback(const std::shared_ptr<ISaveRequestCallback> & callback)244 void AutoFillExtensionCallback::SetSaveRequestCallback(const std::shared_ptr<ISaveRequestCallback> &callback)
245 {
246 std::lock_guard<std::mutex> lock(requestCallbackMutex_);
247 saveCallback_ = callback;
248 }
249
SetSessionId(int32_t sessionId)250 void AutoFillExtensionCallback::SetSessionId(int32_t sessionId)
251 {
252 sessionId_= sessionId;
253 }
254
SetInstanceId(int32_t instanceId)255 void AutoFillExtensionCallback::SetInstanceId(int32_t instanceId)
256 {
257 instanceId_.store(instanceId);
258 }
259
GetInstanceId()260 int32_t AutoFillExtensionCallback::GetInstanceId()
261 {
262 return instanceId_.load();
263 }
264
GetUIContent()265 Ace::UIContent* AutoFillExtensionCallback::GetUIContent()
266 {
267 return Ace::UIContent::GetUIContent(GetInstanceId());
268 }
269
SetWindowType(const AutoFill::AutoFillWindowType & autoFillWindowType)270 void AutoFillExtensionCallback::SetWindowType(const AutoFill::AutoFillWindowType &autoFillWindowType)
271 {
272 autoFillWindowType_ = autoFillWindowType;
273 }
274
GetWindowType() const275 AutoFill::AutoFillWindowType AutoFillExtensionCallback::GetWindowType() const
276 {
277 return autoFillWindowType_;
278 }
279
SetAutoFillRequest(const AutoFill::AutoFillRequest & request)280 void AutoFillExtensionCallback::SetAutoFillRequest(const AutoFill::AutoFillRequest &request)
281 {
282 request_ = request;
283 }
284
SetExtensionType(bool isSmartAutoFill)285 void AutoFillExtensionCallback::SetExtensionType(bool isSmartAutoFill)
286 {
287 isSmartAutoFill_ = isSmartAutoFill;
288 }
289
HandleTimeOut()290 void AutoFillExtensionCallback::HandleTimeOut()
291 {
292 CloseUIExtension();
293 SendAutoFillFailed(AutoFill::AUTO_FILL_REQUEST_TIME_OUT);
294 }
295
GenerateCallbackId()296 uint32_t AutoFillExtensionCallback::GenerateCallbackId()
297 {
298 static std::atomic<uint32_t> callbackId(0);
299 ++callbackId;
300 return callbackId.load();
301 }
302
GetCallbackId() const303 uint32_t AutoFillExtensionCallback::GetCallbackId() const
304 {
305 return callbackId_;
306 }
307
SetModalUIExtensionProxy(const std::shared_ptr<Ace::ModalUIExtensionProxy> & proxy)308 void AutoFillExtensionCallback::SetModalUIExtensionProxy(const std::shared_ptr<Ace::ModalUIExtensionProxy>& proxy)
309 {
310 std::lock_guard<std::mutex> lock(proxyMutex_);
311 modalUIExtensionProxy_ = proxy;
312 }
313
GetModalUIExtensionProxy()314 std::shared_ptr<Ace::ModalUIExtensionProxy> AutoFillExtensionCallback::GetModalUIExtensionProxy()
315 {
316 std::lock_guard<std::mutex> lock(proxyMutex_);
317 return modalUIExtensionProxy_;
318 }
319
UpdateCustomPopupUIExtension(const AbilityBase::ViewData & viewData)320 void AutoFillExtensionCallback::UpdateCustomPopupUIExtension(const AbilityBase::ViewData &viewData)
321 {
322 auto modalUIExtensionProxy = GetModalUIExtensionProxy();
323 if (modalUIExtensionProxy == nullptr) {
324 TAG_LOGE(AAFwkTag::AUTOFILLMGR, "null UIExtensionProxy");
325 return;
326 }
327 AAFwk::WantParams wantParams;
328 wantParams.SetParam(WANT_PARAMS_AUTO_FILL_CMD_KEY,
329 AAFwk::Integer::Box(static_cast<int32_t>(AutoFill::AutoFillCommand::UPDATE)));
330 wantParams.SetParam(WANT_PARAMS_VIEW_DATA_KEY, AAFwk::String::Box(viewData.ToJsonString()));
331 modalUIExtensionProxy->SendData(wantParams);
332 }
333
SendAutoFillSuccess(const AAFwk::Want & want)334 void AutoFillExtensionCallback::SendAutoFillSuccess(const AAFwk::Want &want)
335 {
336 TAG_LOGI(AAFwkTag::AUTOFILLMGR, "called");
337 std::lock_guard<std::mutex> lock(requestCallbackMutex_);
338 if (fillCallback_ != nullptr) {
339 std::string dataStr = want.GetStringParam(WANT_PARAMS_VIEW_DATA_KEY);
340 AbilityBase::ViewData viewData;
341 viewData.FromJsonString(dataStr.c_str());
342 fillCallback_->OnFillRequestSuccess(viewData);
343 fillCallback_ = nullptr;
344 }
345
346 if (saveCallback_ != nullptr) {
347 saveCallback_->OnSaveRequestSuccess();
348 saveCallback_ = nullptr;
349 }
350 AutoFillManager::GetInstance().RemoveAutoFillExtensionCallback(callbackId_);
351 }
352
SendAutoFillFailed(int32_t errCode,const AAFwk::Want & want)353 void AutoFillExtensionCallback::SendAutoFillFailed(int32_t errCode, const AAFwk::Want &want)
354 {
355 TAG_LOGI(AAFwkTag::AUTOFILLMGR, "called");
356 std::lock_guard<std::mutex> lock(requestCallbackMutex_);
357 if (fillCallback_ != nullptr) {
358 std::string fillContent = want.GetStringParam(WANT_PARAMS_FILL_CONTENT);
359 bool isPopup = (autoFillWindowType_ == AutoFill::AutoFillWindowType::POPUP_WINDOW);
360 fillCallback_->OnFillRequestFailed(errCode, fillContent, isPopup);
361 fillCallback_ = nullptr;
362 }
363
364 if (saveCallback_ != nullptr) {
365 saveCallback_->OnSaveRequestFailed();
366 saveCallback_ = nullptr;
367 }
368 AutoFillManager::GetInstance().RemoveAutoFillExtensionCallback(callbackId_);
369 }
370
CloseUIExtension()371 void AutoFillExtensionCallback::CloseUIExtension()
372 {
373 Ace::UIContent* uiContent = nullptr;
374 {
375 std::lock_guard<std::mutex> lock(closeMutex_);
376 uiContent = GetUIContent();
377 if (uiContent == nullptr) {
378 TAG_LOGD(AAFwkTag::AUTOFILLMGR, "null uiContent");
379 return;
380 }
381 SetInstanceId(-1);
382 }
383
384 if (autoFillWindowType_ == AutoFill::AutoFillWindowType::POPUP_WINDOW) {
385 uiContent->DestroyCustomPopupUIExtension(sessionId_);
386 } else if (autoFillWindowType_ == AutoFill::AutoFillWindowType::MODAL_WINDOW) {
387 uiContent->CloseModalUIExtension(sessionId_);
388 }
389 SetModalUIExtensionProxy(nullptr);
390 }
391 #endif // SUPPORT_GRAPHICS
392 } // namespace AbilityRuntime
393 } // namespace OHOS
394