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