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
16 #include "auto_fill_manager.h"
17
18 #include "auto_fill_error.h"
19 #include "auto_fill_manager_util.h"
20 #include "extension_ability_info.h"
21 #include "hilog_tag_wrapper.h"
22 #include "parameters.h"
23
24 namespace OHOS {
25 namespace AbilityRuntime {
26 namespace {
27 const std::string WANT_PARAMS_EXTENSION_TYPE = "autoFill/password";
28 const std::string WANT_PARAMS_SMART_EXTENSION_TYPE = "autoFill/smart";
29 const std::string AUTO_FILL_START_POPUP_WINDOW = "persist.sys.abilityms.autofill.is_passwd_popup_window";
30 constexpr static char WANT_PARAMS_VIEW_DATA_KEY[] = "ohos.ability.params.viewData";
31 constexpr static char WANT_PARAMS_AUTO_FILL_CMD_KEY[] = "ohos.ability.params.autoFillCmd";
32 constexpr static char WANT_PARAMS_AUTO_FILL_POPUP_WINDOW_KEY[] = "ohos.ability.params.popupWindow";
33 constexpr static char WANT_PARAMS_EXTENSION_TYPE_KEY[] = "ability.want.params.uiExtensionType";
34 constexpr static char WANT_PARAMS_AUTO_FILL_TYPE_KEY[] = "ability.want.params.AutoFillType";
35 constexpr static char AUTO_FILL_MANAGER_THREAD[] = "AutoFillManager";
36 constexpr static uint32_t AUTO_FILL_REQUEST_TIME_OUT_VALUE = 1000;
37 constexpr static uint32_t AUTO_FILL_UI_EXTENSION_SESSION_ID_INVALID = 0;
38 } // namespace
GetInstance()39 AutoFillManager &AutoFillManager::GetInstance()
40 {
41 static AutoFillManager instance;
42 return instance;
43 }
44
AutoFillManager()45 AutoFillManager::AutoFillManager()
46 {
47 auto runner = AppExecFwk::EventRunner::Create(AUTO_FILL_MANAGER_THREAD);
48 eventHandler_ = std::make_shared<AutoFillEventHandler>(runner);
49 }
50
~AutoFillManager()51 AutoFillManager::~AutoFillManager()
52 {
53 TAG_LOGD(AAFwkTag::AUTOFILLMGR, "called");
54 }
55
RequestAutoFill(Ace::UIContent * uiContent,const AutoFill::AutoFillRequest & request,const std::shared_ptr<IFillRequestCallback> & fillCallback,AutoFill::AutoFillResult & result)56 int32_t AutoFillManager::RequestAutoFill(Ace::UIContent *uiContent, const AutoFill::AutoFillRequest &request,
57 const std::shared_ptr<IFillRequestCallback> &fillCallback, AutoFill::AutoFillResult &result)
58 {
59 TAG_LOGD(AAFwkTag::AUTOFILLMGR, "called");
60 if (uiContent == nullptr || fillCallback == nullptr) {
61 TAG_LOGE(AAFwkTag::AUTOFILLMGR, "null uiContent or fillCallback");
62 return AutoFill::AUTO_FILL_OBJECT_IS_NULL;
63 }
64
65 if (request.autoFillType == AbilityBase::AutoFillType::UNSPECIFIED) {
66 TAG_LOGE(AAFwkTag::AUTOFILLMGR, "autoFillType invalid");
67 return AutoFill::AUTO_FILL_TYPE_INVALID;
68 }
69 return HandleRequestExecuteInner(uiContent, request, fillCallback, nullptr, result);
70 }
71
RequestAutoSave(Ace::UIContent * uiContent,const AutoFill::AutoFillRequest & request,const std::shared_ptr<ISaveRequestCallback> & saveCallback,AutoFill::AutoFillResult & result)72 int32_t AutoFillManager::RequestAutoSave(Ace::UIContent *uiContent, const AutoFill::AutoFillRequest &request,
73 const std::shared_ptr<ISaveRequestCallback> &saveCallback, AutoFill::AutoFillResult &result)
74 {
75 TAG_LOGD(AAFwkTag::AUTOFILLMGR, "called");
76 if (uiContent == nullptr || saveCallback == nullptr) {
77 TAG_LOGE(AAFwkTag::AUTOFILLMGR, "null UIContent or saveCallback");
78 return AutoFill::AUTO_FILL_OBJECT_IS_NULL;
79 }
80 return HandleRequestExecuteInner(uiContent, request, nullptr, saveCallback, result);
81 }
82
HandleRequestExecuteInner(Ace::UIContent * uiContent,const AutoFill::AutoFillRequest & request,const std::shared_ptr<IFillRequestCallback> & fillCallback,const std::shared_ptr<ISaveRequestCallback> & saveCallback,AutoFill::AutoFillResult & result)83 int32_t AutoFillManager::HandleRequestExecuteInner(Ace::UIContent *uiContent, const AutoFill::AutoFillRequest &request,
84 const std::shared_ptr<IFillRequestCallback> &fillCallback,
85 const std::shared_ptr<ISaveRequestCallback> &saveCallback,
86 AutoFill::AutoFillResult &result)
87 {
88 if (uiContent == nullptr || (fillCallback == nullptr && saveCallback == nullptr)) {
89 TAG_LOGE(AAFwkTag::AUTOFILLMGR, "null uiContent or fillCallback&saveCallback");
90 return AutoFill::AUTO_FILL_OBJECT_IS_NULL;
91 }
92 if (!IsPreviousRequestFinished(uiContent)) {
93 TAG_LOGE(AAFwkTag::AUTOFILLMGR, "Previous request not finished");
94 return AutoFill::AUTO_FILL_PREVIOUS_REQUEST_NOT_FINISHED;
95 }
96
97 auto extensionCallback = std::make_shared<AutoFillExtensionCallback>();
98 if (fillCallback != nullptr) {
99 extensionCallback->SetFillRequestCallback(fillCallback);
100 } else {
101 extensionCallback->SetSaveRequestCallback(saveCallback);
102 }
103 Ace::ModalUIExtensionCallbacks callback;
104 BindModalUIExtensionCallback(extensionCallback, callback);
105
106 bool isSmartAutoFill = false;
107 AutoFill::AutoFillWindowType autoFillWindowType = AutoFill::AutoFillWindowType::MODAL_WINDOW;
108 if (!ConvertAutoFillWindowType(request, isSmartAutoFill, autoFillWindowType)) {
109 TAG_LOGE(AAFwkTag::AUTOFILLMGR, "Convert auto fill type failed");
110 return AutoFill::AUTO_FILL_CREATE_MODULE_UI_EXTENSION_FAILED;
111 }
112
113 auto callbackId = extensionCallback->GetCallbackId();
114 SetTimeOutEvent(callbackId);
115 result.isPopup = autoFillWindowType == AutoFill::AutoFillWindowType::POPUP_WINDOW ? true : false;
116 auto sessionId = CreateAutoFillExtension(uiContent, request, callback, autoFillWindowType, isSmartAutoFill);
117 if (sessionId == AUTO_FILL_UI_EXTENSION_SESSION_ID_INVALID) {
118 TAG_LOGE(AAFwkTag::AUTOFILLMGR, "Create ui extension failed");
119 RemoveEvent(callbackId);
120 return AutoFill::AUTO_FILL_CREATE_MODULE_UI_EXTENSION_FAILED;
121 }
122 result.autoFillSessionId = callbackId;
123 extensionCallback->SetInstanceId(uiContent->GetInstanceId());
124 extensionCallback->SetSessionId(sessionId);
125 extensionCallback->SetWindowType(autoFillWindowType);
126 extensionCallback->SetExtensionType(isSmartAutoFill);
127 extensionCallback->SetAutoFillRequest(request);
128 TAG_LOGI(AAFwkTag::AUTOFILLMGR, "callbackId: %{public}u", callbackId);
129 std::lock_guard<std::mutex> lock(extensionCallbacksMutex_);
130 extensionCallbacks_.emplace(callbackId, extensionCallback);
131 return AutoFill::AUTO_FILL_SUCCESS;
132 }
133
UpdateCustomPopupUIExtension(uint32_t autoFillSessionId,const AbilityBase::ViewData & viewData)134 void AutoFillManager::UpdateCustomPopupUIExtension(uint32_t autoFillSessionId, const AbilityBase::ViewData &viewData)
135 {
136 TAG_LOGD(AAFwkTag::AUTOFILLMGR, "called");
137 auto extensionCallback = GetAutoFillExtensionCallback(autoFillSessionId);
138 if (extensionCallback == nullptr) {
139 TAG_LOGE(AAFwkTag::AUTOFILLMGR, "null extensionCallback");
140 return;
141 }
142 extensionCallback->UpdateCustomPopupUIExtension(viewData);
143 }
144
CloseUIExtension(uint32_t autoFillSessionId)145 void AutoFillManager::CloseUIExtension(uint32_t autoFillSessionId)
146 {
147 TAG_LOGD(AAFwkTag::AUTOFILLMGR, "called");
148 auto extensionCallback = GetAutoFillExtensionCallback(autoFillSessionId);
149 if (extensionCallback == nullptr) {
150 TAG_LOGE(AAFwkTag::AUTOFILLMGR, "null extensionCallback");
151 return;
152 }
153 extensionCallback->CloseUIExtension();
154 }
155
BindModalUIExtensionCallback(const std::shared_ptr<AutoFillExtensionCallback> & extensionCallback,Ace::ModalUIExtensionCallbacks & callback)156 void AutoFillManager::BindModalUIExtensionCallback(
157 const std::shared_ptr<AutoFillExtensionCallback> &extensionCallback, Ace::ModalUIExtensionCallbacks &callback)
158 {
159 TAG_LOGD(AAFwkTag::AUTOFILLMGR, "called");
160 callback.onResult = [extensionCallback](int32_t errCode, const AAFwk::Want& want) {
161 extensionCallback->OnResult(errCode, want);
162 };
163
164 callback.onRelease = [extensionCallback](int arg1) {
165 extensionCallback->OnRelease(arg1);
166 };
167
168 callback.onError = [extensionCallback](int32_t errCode, const std::string& name, const std::string& message) {
169 extensionCallback->OnError(errCode, name, message);
170 };
171
172 callback.onReceive = [extensionCallback](const AAFwk::WantParams &arg1) {
173 extensionCallback->OnReceive(arg1);
174 };
175
176 callback.onRemoteReady = [extensionCallback](const std::shared_ptr<Ace::ModalUIExtensionProxy> &arg1) {
177 extensionCallback->onRemoteReady(arg1);
178 };
179
180 callback.onDestroy = [extensionCallback]() { extensionCallback->onDestroy(); };
181 }
182
CreateAutoFillExtension(Ace::UIContent * uiContent,const AutoFill::AutoFillRequest & request,const Ace::ModalUIExtensionCallbacks & callback,const AutoFill::AutoFillWindowType & autoFillWindowType,bool isSmartAutoFill)183 int32_t AutoFillManager::CreateAutoFillExtension(Ace::UIContent *uiContent,
184 const AutoFill::AutoFillRequest &request,
185 const Ace::ModalUIExtensionCallbacks &callback,
186 const AutoFill::AutoFillWindowType &autoFillWindowType,
187 bool isSmartAutoFill)
188 {
189 int32_t sessionId = AUTO_FILL_UI_EXTENSION_SESSION_ID_INVALID;
190 if (uiContent == nullptr) {
191 TAG_LOGE(AAFwkTag::AUTOFILLMGR, "null uiContent");
192 return sessionId;
193 }
194
195 AAFwk::Want want;
196 want.SetParam(WANT_PARAMS_AUTO_FILL_CMD_KEY, static_cast<int32_t>(request.autoFillCommand));
197 want.SetParam(WANT_PARAMS_AUTO_FILL_TYPE_KEY, static_cast<int32_t>(request.autoFillType));
198 want.SetParam(WANT_PARAMS_VIEW_DATA_KEY, request.viewData.ToJsonString());
199 isSmartAutoFill ? want.SetParam(WANT_PARAMS_EXTENSION_TYPE_KEY, WANT_PARAMS_SMART_EXTENSION_TYPE) :
200 want.SetParam(WANT_PARAMS_EXTENSION_TYPE_KEY, WANT_PARAMS_EXTENSION_TYPE);
201
202 if (autoFillWindowType == AutoFill::AutoFillWindowType::POPUP_WINDOW) {
203 want.SetParam(WANT_PARAMS_AUTO_FILL_POPUP_WINDOW_KEY, true);
204 Ace::CustomPopupUIExtensionConfig popupConfig;
205 AutoFillManagerUtil::ConvertToPopupUIExtensionConfig(request.config, popupConfig);
206 sessionId = uiContent->CreateCustomPopupUIExtension(want, callback, popupConfig);
207 } else if (autoFillWindowType == AutoFill::AutoFillWindowType::MODAL_WINDOW) {
208 want.SetParam(WANT_PARAMS_AUTO_FILL_POPUP_WINDOW_KEY, false);
209 Ace::ModalUIExtensionConfig config;
210 config.isAsyncModalBinding = true;
211 config.doAfterAsyncModalBinding = std::move(request.doAfterAsyncModalBinding);
212 sessionId = uiContent->CreateModalUIExtension(want, callback, config);
213 }
214 return sessionId;
215 }
216
IsNeed2SaveRequest(const AbilityBase::ViewData & viewData,bool & isSmartAutoFill)217 bool AutoFillManager::IsNeed2SaveRequest(const AbilityBase::ViewData& viewData, bool& isSmartAutoFill)
218 {
219 bool ret = false;
220 for (auto it = viewData.nodes.begin(); it != viewData.nodes.end(); ++it) {
221 if ((it->autoFillType == AbilityBase::AutoFillType::PASSWORD ||
222 it->autoFillType == AbilityBase::AutoFillType::USER_NAME ||
223 it->autoFillType == AbilityBase::AutoFillType::NEW_PASSWORD) &&
224 it->enableAutoFill && !it->value.empty()) {
225 isSmartAutoFill = false;
226 return true;
227 }
228 if (AbilityBase::AutoFillType::FULL_STREET_ADDRESS <= it->autoFillType &&
229 it->autoFillType <= AbilityBase::AutoFillType::FORMAT_ADDRESS &&
230 it->enableAutoFill && !it->value.empty()) {
231 isSmartAutoFill = true;
232 ret = true;
233 }
234 }
235 return ret;
236 }
237
ConvertAutoFillWindowType(const AutoFill::AutoFillRequest & request,bool & isSmartAutoFill,AutoFill::AutoFillWindowType & autoFillWindowType)238 bool AutoFillManager::ConvertAutoFillWindowType(const AutoFill::AutoFillRequest &request,
239 bool &isSmartAutoFill, AutoFill::AutoFillWindowType &autoFillWindowType)
240 {
241 bool ret = true;
242 autoFillWindowType = AutoFill::AutoFillWindowType::MODAL_WINDOW;
243 AbilityBase::AutoFillType autoFillType = request.autoFillType;
244 if (autoFillType >= AbilityBase::AutoFillType::FULL_STREET_ADDRESS &&
245 autoFillType <= AbilityBase::AutoFillType::FORMAT_ADDRESS) {
246 autoFillWindowType = AutoFill::AutoFillWindowType::POPUP_WINDOW;
247 isSmartAutoFill = true;
248 } else if (autoFillType == AbilityBase::AutoFillType::PASSWORD ||
249 autoFillType == AbilityBase::AutoFillType::USER_NAME ||
250 autoFillType == AbilityBase::AutoFillType::NEW_PASSWORD) {
251 if (system::GetBoolParameter(AUTO_FILL_START_POPUP_WINDOW, false)) {
252 autoFillWindowType = AutoFill::AutoFillWindowType::POPUP_WINDOW;
253 } else {
254 autoFillWindowType = AutoFill::AutoFillWindowType::MODAL_WINDOW;
255 }
256 isSmartAutoFill = false;
257 }
258
259 if (request.autoFillCommand == AutoFill::AutoFillCommand::SAVE) {
260 ret = IsNeed2SaveRequest(request.viewData, isSmartAutoFill);
261 autoFillWindowType = AutoFill::AutoFillWindowType::MODAL_WINDOW;
262 }
263 return ret;
264 }
265
SetTimeOutEvent(uint32_t eventId)266 void AutoFillManager::SetTimeOutEvent(uint32_t eventId)
267 {
268 TAG_LOGD(AAFwkTag::AUTOFILLMGR, "called");
269 if (eventHandler_ == nullptr) {
270 TAG_LOGE(AAFwkTag::AUTOFILLMGR, "null eventHandler");
271 return;
272 }
273 eventHandler_->SendEvent(eventId, AUTO_FILL_REQUEST_TIME_OUT_VALUE);
274 }
275
RemoveEvent(uint32_t eventId)276 void AutoFillManager::RemoveEvent(uint32_t eventId)
277 {
278 TAG_LOGD(AAFwkTag::AUTOFILLMGR, "called");
279 if (eventHandler_ == nullptr) {
280 TAG_LOGE(AAFwkTag::AUTOFILLMGR, "null eventhandler");
281 return;
282 }
283 eventHandler_->RemoveEvent(eventId);
284 }
285
HandleTimeOut(uint32_t eventId)286 void AutoFillManager::HandleTimeOut(uint32_t eventId)
287 {
288 TAG_LOGI(AAFwkTag::AUTOFILLMGR, "called");
289 auto extensionCallback = GetAutoFillExtensionCallback(eventId);
290 if (extensionCallback == nullptr) {
291 TAG_LOGE(AAFwkTag::AUTOFILLMGR, "null extensionCallback");
292 return;
293 }
294 extensionCallback->HandleTimeOut();
295 }
296
IsNeedToCreatePopupWindow(const AbilityBase::AutoFillType & autoFillType)297 bool AutoFillManager::IsNeedToCreatePopupWindow(const AbilityBase::AutoFillType &autoFillType)
298 {
299 TAG_LOGD(AAFwkTag::AUTOFILLMGR, "Called.");
300 if (autoFillType == AbilityBase::AutoFillType::PASSWORD ||
301 autoFillType == AbilityBase::AutoFillType::USER_NAME ||
302 autoFillType == AbilityBase::AutoFillType::NEW_PASSWORD) {
303 if (system::GetBoolParameter(AUTO_FILL_START_POPUP_WINDOW, false)) {
304 return true;
305 } else {
306 return false;
307 }
308 }
309 return true;
310 }
311
GetAutoFillExtensionCallback(uint32_t callbackId)312 std::shared_ptr<AutoFillExtensionCallback> AutoFillManager::GetAutoFillExtensionCallback(uint32_t callbackId)
313 {
314 std::lock_guard<std::mutex> lock(extensionCallbacksMutex_);
315 auto iter = extensionCallbacks_.find(callbackId);
316 if (iter == extensionCallbacks_.end()) {
317 TAG_LOGE(AAFwkTag::AUTOFILLMGR, "not find, callbackId: %{public}u", callbackId);
318 return nullptr;
319 }
320 return iter->second;
321 }
322
RemoveAutoFillExtensionCallback(uint32_t callbackId)323 void AutoFillManager::RemoveAutoFillExtensionCallback(uint32_t callbackId)
324 {
325 TAG_LOGI(AAFwkTag::AUTOFILLMGR, "callbackId: %{public}u", callbackId);
326 std::lock_guard<std::mutex> lock(extensionCallbacksMutex_);
327 extensionCallbacks_.erase(callbackId);
328 }
329
IsPreviousRequestFinished(Ace::UIContent * uiContent)330 bool AutoFillManager::IsPreviousRequestFinished(Ace::UIContent *uiContent)
331 {
332 if (uiContent == nullptr) {
333 return false;
334 }
335 std::lock_guard<std::mutex> lock(extensionCallbacksMutex_);
336 for (const auto& item: extensionCallbacks_) {
337 auto extensionCallback = item.second;
338 if (extensionCallback == nullptr) {
339 continue;
340 }
341 if (extensionCallback->GetWindowType() == AutoFill::AutoFillWindowType::MODAL_WINDOW &&
342 extensionCallback->GetInstanceId() == uiContent->GetInstanceId()) {
343 return false;
344 }
345 if (extensionCallback->GetWindowType() == AutoFill::AutoFillWindowType::POPUP_WINDOW &&
346 extensionCallback->GetInstanceId() == uiContent->GetInstanceId()) {
347 TAG_LOGI(AAFwkTag::AUTOFILLMGR, "autofill popup window exist!");
348 extensionCallback->CloseUIExtension();
349 return true;
350 }
351 }
352 return true;
353 }
354 } // namespace AbilityRuntime
355 } // namespace OHOS
356