1 /*
2 * Copyright (c) 2025 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 "prop_n_operation.h"
16
17 #include "b_error/b_error.h"
18 #include "b_resources/b_constants.h"
19 #include "b_sa/b_sa_utils.h"
20 #include "filemgmt_libhilog.h"
21 #include "filemgmt_libn.h"
22 #include "incremental_backup_data.h"
23 #include "parse_inc_info_from_js.h"
24 #include "service_client.h"
25 #include "access_token.h"
26 #include "accesstoken_kit.h"
27 #include "ipc_skeleton.h"
28 #include "tokenid_kit.h"
29
30 namespace OHOS::FileManagement::Backup {
31 using namespace std;
32 using namespace LibN;
33
AsyncCallback(napi_env env,const NFuncArg & funcArg)34 static napi_value AsyncCallback(napi_env env, const NFuncArg& funcArg)
35 {
36 HILOGD("called LocalCapabilities::AsyncCallback begin");
37
38 auto fd = make_shared<UniqueFd>();
39 auto cbExec = [fd]() -> NError {
40 HILOGI("called LocalCapabilities::AsyncCallback cbExec");
41 ServiceClient::InvaildInstance();
42 auto proxy = ServiceClient::GetInstance();
43 if (!proxy) {
44 HILOGI("called LocalCapabilities::AsyncCallback cbExec, failed to get proxy");
45 return NError(errno);
46 }
47 int fdNum = INVALID_FD;
48 proxy->GetLocalCapabilities(fdNum);
49 UniqueFd fdData(fdNum);
50 *fd = std::move(fdData);
51 HILOGI("called LocalCapabilities::AsyncCallback cbExec success");
52 return NError(ERRNO_NOERR);
53 };
54 auto cbCompl = [fd](napi_env env, NError err) -> NVal {
55 HILOGI("called LocalCapabilities::AsyncCallback cbCompl");
56 if (err) {
57 return {env, err.GetNapiErr(env)};
58 }
59 NVal obj = NVal::CreateObject(env);
60 obj.AddProp({NVal::DeclareNapiProperty(BConstants::FD.c_str(), NVal::CreateInt32(env, fd->Release()).val_)});
61 return {obj};
62 };
63
64 NVal thisVar(env, funcArg.GetThisVar());
65 if (funcArg.GetArgc() == NARG_CNT::ZERO) {
66 HILOGI("called LocalCapabilities::Async::promise");
67 return NAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_LOCALCAPABILITIES_NAME, cbExec, cbCompl).val_;
68 } else {
69 HILOGI("called LocalCapabilities::Async::callback");
70 NVal cb(env, funcArg[NARG_POS::FIRST]);
71 return NAsyncWorkCallback(env, thisVar, cb).Schedule(PROCEDURE_LOCALCAPABILITIES_NAME, cbExec, cbCompl).val_;
72 }
73 }
74
AsyncDataList(napi_env env,const NFuncArg & funcArg)75 static napi_value AsyncDataList(napi_env env, const NFuncArg& funcArg)
76 {
77 HILOGD("called LocalCapabilities::AsyncDataList begin");
78 auto [succ, bundles] = Parse::ParseDataList(env, funcArg[NARG_POS::FIRST]);
79 if (!succ) {
80 HILOGE("bundles array invalid.");
81 NError(BError(BError::Codes::SDK_INVAL_ARG, "bundles array invalid.").GetCode()).ThrowErr(env);
82 return nullptr;
83 }
84
85 auto fd = make_shared<UniqueFd>();
86 auto cbExec = [fd, bundles {move(bundles)}]() -> NError {
87 HILOGI("called LocalCapabilities::AsyncDataList cbExec");
88 ServiceClient::InvaildInstance();
89 auto proxy = ServiceClient::GetInstance();
90 if (!proxy) {
91 HILOGI("called LocalCapabilities::AsyncDataList cbExec, failed to get proxy");
92 return NError(errno);
93 }
94 int fdValue = INVALID_FD;
95 proxy->GetLocalCapabilitiesIncremental(bundles, fdValue);
96 UniqueFd fdData(fdValue);
97 *fd = std::move(fdData);
98 return NError(ERRNO_NOERR);
99 };
100 auto cbCompl = [fd](napi_env env, NError err) -> NVal {
101 if (err) {
102 return {env, err.GetNapiErr(env)};
103 }
104 NVal obj = NVal::CreateObject(env);
105 obj.AddProp({NVal::DeclareNapiProperty(BConstants::FD.c_str(), NVal::CreateInt32(env, fd->Release()).val_)});
106 return {obj};
107 };
108
109 HILOGI("called LocalCapabilities::Async::promise");
110 NVal thisVar(env, funcArg.GetThisVar());
111 return NAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_LOCALCAPABILITIES_NAME, cbExec, cbCompl).val_;
112 }
113
Async(napi_env env,napi_callback_info info)114 napi_value PropNOperation::Async(napi_env env, napi_callback_info info)
115 {
116 HILOGD("called LocalCapabilities::Async begin");
117 if (!SAUtils::CheckBackupPermission()) {
118 HILOGE("Has not permission!");
119 NError(E_PERMISSION).ThrowErr(env);
120 return nullptr;
121 }
122 if (!SAUtils::IsSystemApp()) {
123 HILOGE("System App check fail!");
124 NError(E_PERMISSION_SYS).ThrowErr(env);
125 return nullptr;
126 }
127 NFuncArg funcArg(env, info);
128 if (!funcArg.InitArgs(NARG_CNT::ZERO, NARG_CNT::ONE)) {
129 HILOGE("Number of arguments unmatched.");
130 NError(BError(BError::Codes::SDK_INVAL_ARG, "Number of arguments unmatched.").GetCode()).ThrowErr(env);
131 return nullptr;
132 }
133
134 if (funcArg.GetArgc() == 1) {
135 bool result = 0;
136 napi_status status = napi_is_array(env, funcArg[NARG_POS::FIRST], &result);
137 if (status == napi_ok && result) {
138 return AsyncDataList(env, funcArg);
139 }
140 }
141
142 return AsyncCallback(env, funcArg);
143 }
144
DoGetBackupInfo(napi_env env,napi_callback_info info)145 napi_value PropNOperation::DoGetBackupInfo(napi_env env, napi_callback_info info)
146 {
147 HILOGD("called DoGetBackupInfo begin");
148 if (!SAUtils::CheckBackupPermission()) {
149 HILOGE("Has not permission!");
150 NError(E_PERMISSION).ThrowErr(env);
151 return nullptr;
152 }
153 if (!SAUtils::IsSystemApp()) {
154 HILOGE("System App check fail!");
155 NError(E_PERMISSION_SYS).ThrowErr(env);
156 return nullptr;
157 }
158 std::string result;
159 NFuncArg funcArg(env, info);
160 if (!funcArg.InitArgs(NARG_CNT::ONE, NARG_CNT::TWO)) {
161 HILOGE("Number of arguments unmatched.");
162 NError(BError(BError::Codes::SDK_INVAL_ARG, "Number of arguments unmatched.").GetCode()).ThrowErr(env);
163 return nullptr;
164 }
165 NVal jsBundle(env, funcArg[NARG_POS::FIRST]);
166 auto [succ, bundle, size] = jsBundle.ToUTF8String();
167 if (!succ) {
168 HILOGE("First argument is not string.");
169 NError(EINVAL).ThrowErr(env);
170 return nullptr;
171 }
172
173 ServiceClient::InvaildInstance();
174 auto proxy = ServiceClient::GetInstance();
175 if (!proxy) {
176 HILOGE("called DoGetBackupInfo,failed to get proxy");
177 return nullptr;
178 }
179 std::string bundleName = bundle.get();
180 ErrCode errcode = proxy->GetBackupInfo(bundleName, result);
181 if (errcode != 0) {
182 HILOGE("proxy->GetBackupInfo faild.");
183 return nullptr;
184 }
185
186 napi_value nResult;
187 napi_status status = napi_create_string_utf8(env, result.c_str(), result.size(), &nResult);
188 if (status != napi_ok) {
189 HILOGE("napi_create_string_utf8 faild.");
190 return nullptr;
191 }
192 HILOGI("DoGetBackupInfo success with result: %{public}s", result.c_str());
193 return nResult;
194 }
195
UpdateSendRate(std::string & bundleName,int32_t sendRate)196 bool PropNOperation::UpdateSendRate(std::string &bundleName, int32_t sendRate)
197 {
198 bool result = false;
199 ServiceClient::InvaildInstance();
200 auto proxy = ServiceClient::GetInstance();
201 if (!proxy) {
202 HILOGE("called UpdateSendRate,failed to get proxy");
203 return result;
204 }
205 ErrCode errCode = proxy->UpdateSendRate(bundleName, sendRate, result);
206 if (errCode != 0) {
207 HILOGE("Proxy execute UpdateSendRate failed. errCode:%{public}d", errCode);
208 return result;
209 }
210 return result;
211 }
212
UpdateTimer(std::string & bundleName,uint32_t timeout)213 bool PropNOperation::UpdateTimer(std::string &bundleName, uint32_t timeout)
214 {
215 bool result = false;
216 ServiceClient::InvaildInstance();
217 auto proxy = ServiceClient::GetInstance();
218 if (!proxy) {
219 HILOGE("called DoUpdateTimer,failed to get proxy");
220 return result;
221 }
222 ErrCode errcode = proxy->UpdateTimer(bundleName, timeout, result);
223 if (errcode != 0) {
224 HILOGE("proxy->UpdateTimer faild.");
225 return result;
226 }
227 return result;
228 }
229
DoUpdateTimer(napi_env env,napi_callback_info info)230 napi_value PropNOperation::DoUpdateTimer(napi_env env, napi_callback_info info)
231 {
232 HILOGD("called DoUpdateTimer begin");
233 if (!SAUtils::CheckBackupPermission()) {
234 HILOGE("Has not permission!");
235 NError(E_PERMISSION).ThrowErr(env);
236 return nullptr;
237 }
238 if (!SAUtils::IsSystemApp()) {
239 HILOGE("System App check fail!");
240 NError(E_PERMISSION_SYS).ThrowErr(env);
241 return nullptr;
242 }
243 NFuncArg funcArg(env, info);
244 if (!funcArg.InitArgs(NARG_CNT::ONE, NARG_CNT::TWO)) {
245 HILOGE("Number of arguments unmatched.");
246 NError(E_PARAMS).ThrowErr(env);
247 return nullptr;
248 }
249 NVal jsBundleStr(env, funcArg[NARG_POS::FIRST]);
250 auto [succStr, bundle, sizeStr] = jsBundleStr.ToUTF8String();
251 if (!succStr) {
252 HILOGE("First argument is not string.");
253 NError(E_PARAMS).ThrowErr(env);
254 return nullptr;
255 }
256 NVal jsBundleInt(env, funcArg[NARG_POS::SECOND]);
257 auto [succInt, time] = jsBundleInt.ToInt32();
258 if (!succInt || time < 0 || time > static_cast<int32_t>(BConstants::MAX_UPDATE_TIMER)) {
259 HILOGE("Second argument is not number.");
260 NError(E_PARAMS).ThrowErr(env);
261 return nullptr;
262 }
263
264 std::string bundleName = bundle.get();
265 uint32_t timeout = static_cast<uint32_t>(time);
266 bool result = UpdateTimer(bundleName, timeout);
267
268 napi_value nResult;
269 napi_status status = napi_get_boolean(env, result, &nResult);
270 if (status != napi_ok) {
271 HILOGE("napi_get_boolean faild.");
272 return nullptr;
273 }
274 HILOGI("DoUpdateTimer success with result: %{public}d", result);
275 return nResult;
276 }
277
DoUpdateSendRate(napi_env env,napi_callback_info info)278 napi_value PropNOperation::DoUpdateSendRate(napi_env env, napi_callback_info info)
279 {
280 HILOGD("called DoUpdateSendRate begin");
281 if (!SAUtils::CheckBackupPermission()) {
282 HILOGE("Has not permission!");
283 NError(E_PERMISSION).ThrowErr(env);
284 return nullptr;
285 }
286 if (!SAUtils::IsSystemApp()) {
287 HILOGE("System App check fail!");
288 NError(E_PERMISSION_SYS).ThrowErr(env);
289 return nullptr;
290 }
291 NFuncArg funcArg(env, info);
292 if (!funcArg.InitArgs(NARG_CNT::ONE, NARG_CNT::TWO)) {
293 HILOGE("Number of arguments unmatched.");
294 NError(E_PARAMS).ThrowErr(env);
295 return nullptr;
296 }
297 NVal jsBundleStr(env, funcArg[NARG_POS::FIRST]);
298 auto [succStr, bundle, sizeStr] = jsBundleStr.ToUTF8String();
299 if (!succStr) {
300 HILOGE("First argument is not string.");
301 NError(E_PARAMS).ThrowErr(env);
302 return nullptr;
303 }
304 std::string bundleName = bundle.get();
305 NVal jsBundleInt(env, funcArg[NARG_POS::SECOND]);
306 auto [succInt, jsRate] = jsBundleInt.ToInt32();
307 if (!succInt || jsRate < 0) {
308 HILOGE("Second argument is invalid. bundleName:%{public}s", bundleName.c_str());
309 NError(E_PARAMS).ThrowErr(env);
310 return nullptr;
311 }
312 int32_t sendFdRate = static_cast<int32_t>(jsRate);
313 if (sendFdRate > BConstants::MAX_FD_SEND_RATE) {
314 HILOGI("sendFdRate is too large, %{public}d", sendFdRate);
315 sendFdRate = BConstants::MAX_FD_SEND_RATE;
316 }
317 bool result = UpdateSendRate(bundleName, sendFdRate);
318 napi_value nResult;
319 napi_status status = napi_get_boolean(env, result, &nResult);
320 if (status != napi_ok) {
321 HILOGE("napi_get_boolean failed.");
322 return nullptr;
323 }
324 HILOGI("DoUpdateSendRate success with result: %{public}d", result);
325 return nResult;
326 }
327
DoGetBackupVersion(napi_env env,napi_callback_info info)328 napi_value PropNOperation::DoGetBackupVersion(napi_env env, napi_callback_info info)
329 {
330 HILOGD("called DoGetBackupVersion begin");
331 if (!SAUtils::CheckBackupPermission()) {
332 HILOGE("Has not permission!");
333 NError(E_PERMISSION).ThrowErr(env);
334 return nullptr;
335 }
336 if (!SAUtils::IsSystemApp()) {
337 HILOGE("System App check fail!");
338 NError(E_PERMISSION_SYS).ThrowErr(env);
339 return nullptr;
340 }
341 std::string result = BConstants::BACKUP_VERSION;
342 napi_value nResult;
343 napi_status status = napi_create_string_utf8(env, result.c_str(), result.size(), &nResult);
344 if (status != napi_ok) {
345 HILOGE("napi_create_string_utf8 faild.");
346 return nullptr;
347 }
348 HILOGI("DoGetBackupVersion success with result: %{public}s", result.c_str());
349 return nResult;
350 }
351 } // namespace OHOS::FileManagement::Backup