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 "js_auto_fill_manager.h"
17
18 #include "ability_business_error.h"
19 #include "auto_fill_manager.h"
20 #include "hilog_wrapper.h"
21 #include "ipc_skeleton.h"
22 #include "js_error_utils.h"
23
24 namespace OHOS {
25 namespace AbilityRuntime {
26 namespace {
27 constexpr int32_t INDEX_ZERO = 0;
28 constexpr int32_t INDEX_ONE = 1;
29 constexpr size_t ARGC_ONE = 1;
30 } // namespace
31
Finalizer(napi_env env,void * data,void * hint)32 void JsAutoFillManager::Finalizer(napi_env env, void *data, void *hint)
33 {
34 HILOG_DEBUG("Called.");
35 std::unique_ptr<JsAutoFillManager>(static_cast<JsAutoFillManager *>(data));
36 }
37
RequestAutoSave(napi_env env,napi_callback_info info)38 napi_value JsAutoFillManager::RequestAutoSave(napi_env env, napi_callback_info info)
39 {
40 GET_NAPI_INFO_AND_CALL(env, info, JsAutoFillManager, OnRequestAutoSave);
41 }
42
OnRequestAutoSave(napi_env env,NapiCallbackInfo & info)43 napi_value JsAutoFillManager::OnRequestAutoSave(napi_env env, NapiCallbackInfo &info)
44 {
45 HILOG_DEBUG("Called.");
46 if (info.argc < ARGC_ONE) {
47 HILOG_ERROR("The param is invalid.");
48 ThrowTooFewParametersError(env);
49 return CreateJsUndefined(env);
50 }
51
52 napi_value instanceIdValue = nullptr;
53 if (napi_get_named_property(env, info.argv[INDEX_ZERO], "instanceId_", &instanceIdValue) != napi_ok) {
54 HILOG_ERROR("Get function by name failed.");
55 ThrowError(env, AbilityErrorCode::ERROR_CODE_INVALID_PARAM);
56 return CreateJsUndefined(env);
57 }
58 int32_t instanceId = -1;
59 if (!ConvertFromJsValue(env, instanceIdValue, instanceId)) {
60 HILOG_ERROR("Failed to parse type.");
61 ThrowError(env, AbilityErrorCode::ERROR_CODE_INVALID_PARAM);
62 return CreateJsUndefined(env);
63 }
64
65 auto saveCallback = GetCallbackByInstanceId(instanceId);
66 if (saveCallback != nullptr) {
67 HILOG_ERROR("There are other requests in progress.");
68 ThrowError(env, AbilityErrorCode::ERROR_CODE_INNER);
69 return CreateJsUndefined(env);
70 }
71
72 auto autoSaveMangerFunc = std::bind(&JsAutoFillManager::OnRequestAutoSaveDone, this, std::placeholders::_1);
73 saveCallback = std::make_shared<JsAutoSaveRequestCallback>(env, instanceId, autoSaveMangerFunc);
74 if (saveCallback == nullptr) {
75 HILOG_ERROR("saveCallback is nullptr.");
76 ThrowError(env, AbilityErrorCode::ERROR_CODE_INNER);
77 return CreateJsUndefined(env);
78 }
79
80 if (info.argc != ARGC_ONE) {
81 if (!CheckTypeForNapiValue(env, info.argv[INDEX_ONE], napi_object)) {
82 HILOG_ERROR("Second input parameter error.");
83 ThrowError(env, AbilityErrorCode::ERROR_CODE_INVALID_PARAM);
84 return CreateJsUndefined(env);
85 }
86 saveCallback->Register(info.argv[INDEX_ONE]);
87 }
88 OnRequestAutoSaveInner(env, instanceId, saveCallback);
89 return CreateJsUndefined(env);
90 }
91
OnRequestAutoSaveInner(napi_env env,int32_t instanceId,const std::shared_ptr<JsAutoSaveRequestCallback> & saveRequestCallback)92 void JsAutoFillManager::OnRequestAutoSaveInner(napi_env env, int32_t instanceId,
93 const std::shared_ptr<JsAutoSaveRequestCallback> &saveRequestCallback)
94 {
95 auto uiContent = Ace::UIContent::GetUIContent(instanceId);
96 if (uiContent == nullptr) {
97 HILOG_ERROR("UIContent is nullptr.");
98 ThrowError(env, AbilityErrorCode::ERROR_CODE_INNER);
99 return;
100 }
101 if (uiContent->CheckNeedAutoSave()) {
102 AbilityBase::ViewData viewData;
103 uiContent->DumpViewData(viewData);
104 auto ret = AutoFillManager::GetInstance().RequestAutoSave(uiContent, viewData, saveRequestCallback);
105 if (ret != ERR_OK) {
106 HILOG_ERROR("Request auto save error[%{public}d].", ret);
107 ThrowError(env, GetJsErrorCodeByNativeError(ret));
108 return;
109 }
110 std::lock_guard<std::mutex> lock(mutexLock_);
111 saveRequestObject_.emplace(instanceId, saveRequestCallback);
112 }
113 }
114
GetCallbackByInstanceId(int32_t instanceId)115 std::shared_ptr<JsAutoSaveRequestCallback> JsAutoFillManager::GetCallbackByInstanceId(int32_t instanceId)
116 {
117 std::lock_guard<std::mutex> lock(mutexLock_);
118 auto iter = saveRequestObject_.find(instanceId);
119 if (iter != saveRequestObject_.end()) {
120 return iter->second.lock();
121 }
122 return nullptr;
123 }
124
OnRequestAutoSaveDone(int32_t instanceId)125 void JsAutoFillManager::OnRequestAutoSaveDone(int32_t instanceId)
126 {
127 std::lock_guard<std::mutex> lock(mutexLock_);
128 auto iter = saveRequestObject_.find(instanceId);
129 if (iter != saveRequestObject_.end()) {
130 saveRequestObject_.erase(iter);
131 }
132 }
133
CreateJsAutoFillType(napi_env env)134 napi_value CreateJsAutoFillType(napi_env env)
135 {
136 HILOG_DEBUG("Called.");
137 napi_value objValue = nullptr;
138 napi_create_object(env, &objValue);
139
140 napi_set_named_property(env, objValue, "UNSPECIFIED", CreateJsValue(env, AbilityBase::AutoFillType::UNSPECIFIED));
141 napi_set_named_property(env, objValue, "PASSWORD", CreateJsValue(env, AbilityBase::AutoFillType::PASSWORD));
142 napi_set_named_property(env, objValue, "USER_NAME", CreateJsValue(env, AbilityBase::AutoFillType::USER_NAME));
143 napi_set_named_property(env, objValue, "NEW_PASSWORD", CreateJsValue(env, AbilityBase::AutoFillType::NEW_PASSWORD));
144 return objValue;
145 }
146
JsAutoFillManagerInit(napi_env env,napi_value exportObj)147 napi_value JsAutoFillManagerInit(napi_env env, napi_value exportObj)
148 {
149 HILOG_DEBUG("Called.");
150 if (env == nullptr || exportObj == nullptr) {
151 HILOG_ERROR("Env or exportObj nullptr.");
152 return nullptr;
153 }
154
155 auto jsAbilityAutoFillManager = std::make_unique<JsAutoFillManager>();
156 napi_wrap(env, exportObj, jsAbilityAutoFillManager.release(), JsAutoFillManager::Finalizer, nullptr, nullptr);
157
158 napi_set_named_property(env, exportObj, "AutoFillType", CreateJsAutoFillType(env));
159
160 const char *moduleName = "JsAutoFillManager";
161 BindNativeFunction(env, exportObj, "requestAutoSave", moduleName, JsAutoFillManager::RequestAutoSave);
162
163 return CreateJsUndefined(env);
164 }
165 } // namespace AbilityRuntime
166 } // namespace OHOS