1 /*
2 * Copyright (c) 2022-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_quick_fix_manager.h"
17
18 #include "hilog_tag_wrapper.h"
19 #include "js_application_quick_fix_info.h"
20 #include "js_runtime_utils.h"
21 #include "napi_common_util.h"
22 #include "quick_fix_error_utils.h"
23 #include "quick_fix_manager_client.h"
24 #include "js_error_utils.h"
25
26 namespace OHOS {
27 namespace AbilityRuntime {
28 namespace {
29 constexpr size_t ARGC_ZERO = 0;
30 constexpr size_t ARGC_ONE = 1;
31 constexpr size_t ARGC_TWO = 2;
32 const char *QUICK_FIX_MANAGER_NAME = "JsQuickFixMgr";
33 } // namespace
34
35 class JsQuickFixManager {
36 public:
37 JsQuickFixManager() = default;
38 ~JsQuickFixManager() = default;
39
Finalizer(napi_env env,void * data,void * hint)40 static void Finalizer(napi_env env, void *data, void *hint)
41 {
42 TAG_LOGD(AAFwkTag::QUICKFIX, "called");
43 std::unique_ptr<JsQuickFixManager>(static_cast<JsQuickFixManager*>(data));
44 }
45
ApplyQuickFix(napi_env env,napi_callback_info info)46 static napi_value ApplyQuickFix(napi_env env, napi_callback_info info)
47 {
48 GET_NAPI_INFO_AND_CALL(env, info, JsQuickFixManager, OnApplyQuickFix);
49 }
50
GetApplyedQuickFixInfo(napi_env env,napi_callback_info info)51 static napi_value GetApplyedQuickFixInfo(napi_env env, napi_callback_info info)
52 {
53 GET_NAPI_INFO_AND_CALL(env, info, JsQuickFixManager, OnGetApplyedQuickFixInfo);
54 }
55
RevokeQuickFix(napi_env env,napi_callback_info info)56 static napi_value RevokeQuickFix(napi_env env, napi_callback_info info)
57 {
58 GET_NAPI_INFO_AND_CALL(env, info, JsQuickFixManager, OnRevokeQuickFix);
59 }
60
Throw(napi_env env,int32_t errCode)61 static void Throw(napi_env env, int32_t errCode)
62 {
63 auto externalErrCode = AAFwk::QuickFixErrorUtil::GetErrorCode(errCode);
64 auto errMsg = AAFwk::QuickFixErrorUtil::GetErrorMessage(errCode);
65 napi_value error = CreateJsError(env, externalErrCode, errMsg);
66 napi_throw(env, error);
67 }
68
CreateJsErrorByErrorCode(napi_env env,int32_t errCode)69 static napi_value CreateJsErrorByErrorCode(napi_env env, int32_t errCode)
70 {
71 auto externalErrCode = AAFwk::QuickFixErrorUtil::GetErrorCode(errCode);
72 auto errMsg = AAFwk::QuickFixErrorUtil::GetErrorMessage(errCode);
73 return CreateJsError(env, externalErrCode, errMsg);
74 }
75
76 private:
OnGetApplyedQuickFixInfo(napi_env env,NapiCallbackInfo & info)77 napi_value OnGetApplyedQuickFixInfo(napi_env env, NapiCallbackInfo &info)
78 {
79 TAG_LOGD(AAFwkTag::QUICKFIX, "called");
80 if (info.argc != ARGC_ONE && info.argc != ARGC_TWO) {
81 TAG_LOGE(AAFwkTag::QUICKFIX, "The number of parameter is invalid");
82 ThrowInvalidParamError(env, "Parameter error: The number of parameter is invalid.");
83 return CreateJsUndefined(env);
84 }
85
86 std::string bundleName;
87 if (!OHOS::AppExecFwk::UnwrapStringFromJS2(env, info.argv[0], bundleName)) {
88 TAG_LOGE(AAFwkTag::QUICKFIX, "The bundleName is invalid");
89 ThrowInvalidParamError(env, "Parameter error: The bundleName is invalid, must be a string.");
90 return CreateJsUndefined(env);
91 }
92
93 auto complete = [bundleName](napi_env env, NapiAsyncTask &task, int32_t status) {
94 AppExecFwk::ApplicationQuickFixInfo quickFixInfo;
95 auto errCode = DelayedSingleton<AAFwk::QuickFixManagerClient>::GetInstance()->GetApplyedQuickFixInfo(
96 bundleName, quickFixInfo);
97 if (errCode == 0) {
98 task.ResolveWithNoError(env, CreateJsApplicationQuickFixInfo(env, quickFixInfo));
99 } else {
100 task.Reject(env, CreateJsErrorByErrorCode(env, errCode));
101 }
102 };
103
104 napi_value lastParam = (info.argc == ARGC_ONE) ? nullptr : info.argv[1];
105 napi_value result = nullptr;
106 NapiAsyncTask::Schedule("JsQuickFixManager::OnGetApplyedQuickFixInfo", env,
107 CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
108 return result;
109 }
110
OnApplyQuickFix(napi_env env,NapiCallbackInfo & info)111 napi_value OnApplyQuickFix(napi_env env, NapiCallbackInfo &info)
112 {
113 TAG_LOGD(AAFwkTag::QUICKFIX, "called");
114 if (info.argc != ARGC_ONE && info.argc != ARGC_TWO) {
115 TAG_LOGE(AAFwkTag::QUICKFIX, "The number of parameter is invalid");
116 ThrowInvalidParamError(env, "Parameter error: The number of parameter is invalid.");
117 return CreateJsUndefined(env);
118 }
119
120 std::vector<std::string> hapQuickFixFiles;
121 if (!OHOS::AppExecFwk::UnwrapArrayStringFromJS(env, info.argv[0], hapQuickFixFiles)) {
122 TAG_LOGE(AAFwkTag::QUICKFIX, "Hap quick fix files is invalid");
123 ThrowInvalidParamError(env, "Parameter error: Hap quick fix files is invalid, must be a Array<string>.");
124 return CreateJsUndefined(env);
125 }
126
127 auto complete = [hapQuickFixFiles](napi_env env, NapiAsyncTask &task, int32_t status) {
128 auto errcode = DelayedSingleton<AAFwk::QuickFixManagerClient>::GetInstance()->ApplyQuickFix(
129 hapQuickFixFiles);
130 if (errcode == 0) {
131 task.ResolveWithNoError(env, CreateJsUndefined(env));
132 } else {
133 task.Reject(env, CreateJsErrorByErrorCode(env, errcode));
134 }
135 };
136
137 napi_value lastParam = (info.argc == 1) ? nullptr : info.argv[1];
138 napi_value result = nullptr;
139 NapiAsyncTask::Schedule("JsQuickFixManager::OnApplyQuickFix", env,
140 CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
141 return result;
142 }
143
OnRevokeQuickFix(napi_env env,NapiCallbackInfo & info)144 napi_value OnRevokeQuickFix(napi_env env, NapiCallbackInfo &info)
145 {
146 TAG_LOGD(AAFwkTag::QUICKFIX, "called");
147 if (info.argc == ARGC_ZERO) {
148 TAG_LOGE(AAFwkTag::QUICKFIX, "The number of parameter is invalid");
149 ThrowInvalidParamError(env, "Parameter error: The number of parameter is invalid.");
150 return CreateJsUndefined(env);
151 }
152
153 std::string bundleName;
154 if (!ConvertFromJsValue(env, info.argv[ARGC_ZERO], bundleName)) {
155 TAG_LOGE(AAFwkTag::QUICKFIX, "The bundleName is invalid");
156 ThrowInvalidParamError(env, "Parameter error: The bundleName is invalid, must be a string.");
157 return CreateJsUndefined(env);
158 }
159
160 std::shared_ptr<int32_t> errCode = std::make_shared<int32_t>(AAFwk::ERR_OK);
161 auto execute = [retval = errCode, bundleName] () {
162 auto quickFixMgr = DelayedSingleton<AAFwk::QuickFixManagerClient>::GetInstance();
163 if (quickFixMgr == nullptr) {
164 *retval = AAFwk::ERR_QUICKFIX_INTERNAL_ERROR;
165 TAG_LOGE(AAFwkTag::QUICKFIX, "mgr is nullptr");
166 return;
167 }
168
169 *retval = quickFixMgr->RevokeQuickFix(bundleName);
170 TAG_LOGD(AAFwkTag::QUICKFIX, "Revoke quick fix execute retval is {%{public}d}", *retval);
171 };
172
173 auto complete = [retval = errCode](napi_env env, NapiAsyncTask &task, int32_t status) {
174 TAG_LOGD(AAFwkTag::QUICKFIX, "Revoke quick fix complete called");
175 if (*retval != AAFwk::ERR_OK) {
176 TAG_LOGE(AAFwkTag::QUICKFIX, "Revoke quick fix execution failed. retval is %{public}d", *retval);
177 task.Reject(env, CreateJsErrorByErrorCode(env, *retval));
178 return;
179 }
180 TAG_LOGD(AAFwkTag::QUICKFIX, "Revoke quick fix complete called ok");
181 task.ResolveWithNoError(env, CreateJsUndefined(env));
182 };
183
184 napi_value lastParam = (info.argc == ARGC_ONE) ? nullptr : info.argv[ARGC_ONE];
185 napi_value result = nullptr;
186 NapiAsyncTask::Schedule("JsQuickFixManager::OnRevokeQuickFix", env,
187 CreateAsyncTaskWithLastParam(env, lastParam, std::move(execute), std::move(complete), &result));
188 TAG_LOGD(AAFwkTag::QUICKFIX, "Function finished");
189 return result;
190 }
191 };
192
CreateJsQuickFixManager(napi_env env,napi_value exportObj)193 napi_value CreateJsQuickFixManager(napi_env env, napi_value exportObj)
194 {
195 TAG_LOGD(AAFwkTag::QUICKFIX, "called");
196 if (env == nullptr || exportObj == nullptr) {
197 TAG_LOGE(AAFwkTag::QUICKFIX, "Input parameter is invalid");
198 return nullptr;
199 }
200
201 std::unique_ptr<JsQuickFixManager> quickFixManager = std::make_unique<JsQuickFixManager>();
202 napi_wrap(env, exportObj, quickFixManager.release(), JsQuickFixManager::Finalizer, nullptr, nullptr);
203
204 BindNativeFunction(env, exportObj, "applyQuickFix", QUICK_FIX_MANAGER_NAME, JsQuickFixManager::ApplyQuickFix);
205 BindNativeFunction(env, exportObj, "getApplicationQuickFixInfo", QUICK_FIX_MANAGER_NAME,
206 JsQuickFixManager::GetApplyedQuickFixInfo);
207 BindNativeFunction(env, exportObj, "revokeQuickFix", QUICK_FIX_MANAGER_NAME, JsQuickFixManager::RevokeQuickFix);
208 return CreateJsUndefined(env);
209 }
210 } // namespace AbilityRuntime
211 } // namespace OHOS
212