1 /*
2 * Copyright (c) 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 #include "session_incremental_backup_n_exporter.h"
16
17 #include <functional>
18 #include <memory>
19
20 #include "b_error/b_error.h"
21 #include "b_filesystem/b_file.h"
22 #include "b_incremental_backup_session.h"
23 #include "b_incremental_data.h"
24 #include "b_resources/b_constants.h"
25 #include "b_sa/b_sa_utils.h"
26 #include "backup_kit_inner.h"
27 #include "directory_ex.h"
28 #include "filemgmt_libhilog.h"
29 #include "general_callbacks.h"
30 #include "incremental_backup_data.h"
31 #include "service_proxy.h"
32
33 namespace OHOS::FileManagement::Backup {
34 using namespace std;
35 using namespace LibN;
36
37 struct BackupEntity {
38 unique_ptr<BIncrementalBackupSession> session;
39 shared_ptr<GeneralCallbacks> callbacks;
40 };
41
OnFileReady(weak_ptr<GeneralCallbacks> pCallbacks,const BFileInfo & fileInfo,UniqueFd fd,UniqueFd manifestFd,int sysErrno)42 static void OnFileReady(weak_ptr<GeneralCallbacks> pCallbacks, const BFileInfo &fileInfo, UniqueFd fd,
43 UniqueFd manifestFd, int sysErrno)
44 {
45 if (pCallbacks.expired()) {
46 HILOGI("callbacks is unbound");
47 return;
48 }
49 auto callbacks = pCallbacks.lock();
50 if (!callbacks) {
51 HILOGI("callback function onFileReady has already been released");
52 return;
53 }
54 if (!bool(callbacks->onFileReady)) {
55 HILOGI("callback function onFileReady is undefined");
56 return;
57 }
58 ErrCode errCode = BError::GetCodeByErrno(sysErrno);
59 std::string errMsg = "system errno: " + to_string(sysErrno);
60 std::tuple<uint32_t, std::string> errInfo = std::make_tuple(errCode, errMsg);
61
62 auto cbCompl = [bundleName {fileInfo.owner}, fileName {fileInfo.fileName},
63 fd {make_shared<UniqueFd>(fd.Release())},
64 manifestFd {make_shared<UniqueFd>(manifestFd.Release())},
65 errInfo](napi_env env, NError err) -> NVal {
66 if (err) {
67 return {env, err.GetNapiErr(env)};
68 }
69 HILOGI("callback function incremental backup onFileReady cbCompl errcode: %{public}d", std::get<0>(errInfo));
70 NVal obj;
71 ErrParam errorParam = [ errInfo ]() {
72 return errInfo;
73 };
74 if (std::get<0>(errInfo) != 0) {
75 obj = NVal {env, NError(errorParam).GetNapiErr(env)};
76 napi_status status = napi_set_named_property(env, obj.val_, FILEIO_TAG_ERR_DATA.c_str(),
77 NVal::CreateUTF8String(env, bundleName).val_);
78 if (status != napi_ok) {
79 HILOGE("Failed to set data, status %{public}d, bundleName %{public}s", status, bundleName.c_str());
80 }
81 } else {
82 obj = NVal::CreateObject(env);
83 obj.AddProp({
84 NVal::DeclareNapiProperty(BConstants::BUNDLE_NAME.c_str(),
85 NVal::CreateUTF8String(env, bundleName).val_),
86 NVal::DeclareNapiProperty(BConstants::URI.c_str(), NVal::CreateUTF8String(env, fileName).val_),
87 NVal::DeclareNapiProperty(BConstants::FD.c_str(), NVal::CreateInt32(env, fd->Release()).val_),
88 NVal::DeclareNapiProperty(BConstants::MANIFEST_FD.c_str(),
89 NVal::CreateInt32(env, manifestFd->Release()).val_)});
90 }
91 return {obj};
92 };
93
94 callbacks->onFileReady.ThreadSafeSchedule(cbCompl);
95 }
96
onBundleBegin(weak_ptr<GeneralCallbacks> pCallbacks,ErrCode err,const BundleName name)97 static void onBundleBegin(weak_ptr<GeneralCallbacks> pCallbacks, ErrCode err, const BundleName name)
98 {
99 HILOGI("Callback onBundleBegin, bundleName=%{public}s, errCode=%{public}d", name.c_str(), err);
100 if (pCallbacks.expired()) {
101 HILOGI("callbacks is unbound");
102 return;
103 }
104 auto callbacks = pCallbacks.lock();
105 if (!callbacks) {
106 HILOGI("callback function onBundleBegin has already been released");
107 return;
108 }
109 if (!bool(callbacks->onBundleBegin)) {
110 HILOGI("callback function onBundleBegin is undefined");
111 return;
112 }
113
114 ErrCode errCode = BError::GetBackupCodeByErrno(err);
115 std::string errMsg = BError::GetBackupMsgByErrno(errCode) + ", origin errno: " + to_string(err);
116 std::tuple<uint32_t, std::string> errInfo = std::make_tuple(errCode, errMsg);
117
118 auto cbCompl = [name {name}, errCode {err}, errInfo](napi_env env, NError err) -> NVal {
119 NVal bundleName = NVal::CreateUTF8String(env, name);
120 if (!err && errCode == 0) {
121 return bundleName;
122 }
123 ErrParam errorParam = [ errInfo ]() {
124 return errInfo;
125 };
126 NVal res;
127 if (err) {
128 res = NVal {env, err.GetNapiErr(env)};
129 } else {
130 res = NVal {env, NError(errorParam).GetNapiErr(env)};
131 }
132 napi_status status = napi_set_named_property(env, res.val_, FILEIO_TAG_ERR_DATA.c_str(), bundleName.val_);
133 if (status != napi_ok) {
134 HILOGE("Failed to set data property, status %{public}d, bundleName %{public}s", status, name.c_str());
135 }
136
137 return res;
138 };
139
140 callbacks->onBundleBegin.ThreadSafeSchedule(cbCompl);
141 }
142
onBundleEnd(weak_ptr<GeneralCallbacks> pCallbacks,ErrCode err,const BundleName name)143 static void onBundleEnd(weak_ptr<GeneralCallbacks> pCallbacks, ErrCode err, const BundleName name)
144 {
145 HILOGI("Callback onBundleEnd, bundleName=%{public}s, errCode=%{public}d", name.c_str(), err);
146 if (pCallbacks.expired()) {
147 HILOGI("callbacks is unbound");
148 return;
149 }
150 auto callbacks = pCallbacks.lock();
151 if (!callbacks) {
152 HILOGI("callback function onBundleEnd has already been released");
153 return;
154 }
155 if (!bool(callbacks->onBundleEnd)) {
156 HILOGI("callback function onBundleEnd is undefined");
157 return;
158 }
159
160 ErrCode errCode = BError::GetBackupCodeByErrno(err);
161 std::string errMsg = BError::GetBackupMsgByErrno(errCode) + ", origin errno: " + to_string(err);
162 std::tuple<uint32_t, std::string> errInfo = std::make_tuple(errCode, errMsg);
163
164 auto cbCompl = [name {name}, errCode {err}, errInfo](napi_env env, NError err) -> NVal {
165 NVal bundleName = NVal::CreateUTF8String(env, name);
166 if (!err && errCode == 0) {
167 return bundleName;
168 }
169 ErrParam errorParam = [ errInfo ]() {
170 return errInfo;
171 };
172 NVal res;
173 if (err) {
174 res = NVal {env, err.GetNapiErr(env)};
175 } else {
176 res = NVal {env, NError(errorParam).GetNapiErr(env)};
177 }
178 napi_status status = napi_set_named_property(env, res.val_, FILEIO_TAG_ERR_DATA.c_str(), bundleName.val_);
179 if (status != napi_ok) {
180 HILOGE("Failed to set data property, status %{public}d, bundleName %{public}s", status, name.c_str());
181 }
182
183 return res;
184 };
185
186 callbacks->onBundleEnd.ThreadSafeSchedule(cbCompl);
187 }
188
onAllBundlesEnd(weak_ptr<GeneralCallbacks> pCallbacks,ErrCode err)189 static void onAllBundlesEnd(weak_ptr<GeneralCallbacks> pCallbacks, ErrCode err)
190 {
191 if (pCallbacks.expired()) {
192 HILOGI("callbacks is unbound");
193 return;
194 }
195 auto callbacks = pCallbacks.lock();
196 if (!callbacks) {
197 HILOGI("callback function onAllBundlesEnd has already been released");
198 return;
199 }
200 if (!bool(callbacks->onAllBundlesEnd)) {
201 HILOGI("callback function onAllBundlesEnd is undefined");
202 return;
203 }
204
205 ErrCode errCode = BError::GetBackupCodeByErrno(err);
206 std::string errMsg = BError::GetBackupMsgByErrno(errCode) + ", origin errno: " + to_string(err);
207 std::tuple<uint32_t, std::string> errInfo = std::make_tuple(errCode, errMsg);
208
209 auto cbCompl = [errCode {err}, errInfo](napi_env env, NError err) -> NVal {
210 if (!err && errCode == 0) {
211 return NVal::CreateUndefined(env);
212 }
213 ErrParam errorParam = [ errInfo ]() {
214 return errInfo;
215 };
216 NVal res;
217 if (err) {
218 res = NVal {env, err.GetNapiErr(env)};
219 } else {
220 res = NVal {env, NError(errorParam).GetNapiErr(env)};
221 }
222
223 return res;
224 };
225
226 callbacks->onAllBundlesEnd.ThreadSafeSchedule(cbCompl);
227 }
228
OnResultReport(weak_ptr<GeneralCallbacks> pCallbacks,const std::string bundleName,const std::string result)229 static void OnResultReport(weak_ptr<GeneralCallbacks> pCallbacks, const std::string bundleName,
230 const std::string result)
231 {
232 HILOGI("Callback OnResultReport, bundleName=%{public}s", bundleName.c_str());
233 if (pCallbacks.expired()) {
234 HILOGI("callbacks is unbound");
235 return;
236 }
237 auto callbacks = pCallbacks.lock();
238 if (!callbacks) {
239 HILOGI("callback function onResultReport has already been released");
240 return;
241 }
242 if (!bool(callbacks->onResultReport)) {
243 HILOGI("callback function onResultReport is undefined");
244 return;
245 }
246 auto cbCompl = [bName {bundleName}, res {result}](napi_env env, vector<napi_value> &argv) -> bool {
247 napi_value napi_bName = nullptr;
248 napi_create_string_utf8(env, bName.c_str(), bName.size(), &napi_bName);
249 argv.push_back(napi_bName);
250 napi_value napi_res = nullptr;
251 napi_create_string_utf8(env, res.c_str(), res.size(), &napi_res);
252 argv.push_back(napi_res);
253 return true;
254 };
255 callbacks->onResultReport.CallJsMethod(cbCompl);
256 }
257
OnBackupServiceDied(weak_ptr<GeneralCallbacks> pCallbacks)258 static void OnBackupServiceDied(weak_ptr<GeneralCallbacks> pCallbacks)
259 {
260 HILOGI("Callback OnBackupServiceDied.");
261 if (pCallbacks.expired()) {
262 HILOGI("callbacks is unbound");
263 return;
264 }
265 auto callbacks = pCallbacks.lock();
266 if (!callbacks) {
267 HILOGI("js callback function onBackupServiceDied has already been released");
268 return;
269 }
270 if (!bool(callbacks->onBackupServiceDied)) {
271 HILOGI("callback function onBackupServiceDied is undefined");
272 return;
273 }
274
275 auto cbCompl = [](napi_env env, vector<napi_value> &argv) -> bool {
276 napi_value napi_res = nullptr;
277 napi_get_undefined(env, &napi_res);
278 argv.push_back(napi_res);
279 return true;
280 };
281 callbacks->onBackupServiceDied.CallJsMethod(cbCompl);
282 }
283
OnProcess(weak_ptr<GeneralCallbacks> pCallbacks,const BundleName name,const std::string processInfo)284 static void OnProcess(weak_ptr<GeneralCallbacks> pCallbacks, const BundleName name, const std::string processInfo)
285 {
286 HILOGI("Callback OnProcess, bundleName=%{public}s", name.c_str());
287 if (pCallbacks.expired()) {
288 HILOGI("callbacks is unbound");
289 return;
290 }
291 auto callbacks = pCallbacks.lock();
292 if (!callbacks) {
293 HILOGI("callback function OnProcess has already been released");
294 return;
295 }
296 if (!bool(callbacks->onProcess)) {
297 HILOGI("callback function OnProcess is undefined");
298 return;
299 }
300 auto cbCompl = [bundleName {name}, process {processInfo}](napi_env env, vector<napi_value> &argv) -> bool {
301 napi_value napi_bName = nullptr;
302 napi_create_string_utf8(env, bundleName.c_str(), bundleName.size(), &napi_bName);
303 argv.push_back(napi_bName);
304 napi_value napi_process = nullptr;
305 napi_create_string_utf8(env, process.c_str(), process.size(), &napi_process);
306 argv.push_back(napi_process);
307 return true;
308 };
309 callbacks->onProcess.CallJsMethod(cbCompl);
310 }
311
Constructor(napi_env env,napi_callback_info cbinfo)312 napi_value SessionIncrementalBackupNExporter::Constructor(napi_env env, napi_callback_info cbinfo)
313 {
314 HILOGD("called SessionIncrementalBackup::Constructor begin");
315 if (!SAUtils::CheckBackupPermission()) {
316 HILOGE("Has not permission!");
317 NError(E_PERMISSION).ThrowErr(env);
318 return nullptr;
319 }
320 if (!SAUtils::IsSystemApp()) {
321 HILOGE("System App check fail!");
322 NError(E_PERMISSION_SYS).ThrowErr(env);
323 return nullptr;
324 }
325 NFuncArg funcArg(env, cbinfo);
326 if (!funcArg.InitArgs(NARG_CNT::ONE)) {
327 HILOGE("Number of arguments unmatched");
328 NError(BError(BError::Codes::SDK_INVAL_ARG, "Number of arguments unmatched.").GetCode()).ThrowErr(env);
329 return nullptr;
330 }
331
332 NVal callbacks(env, funcArg[NARG_POS::FIRST]);
333 if (!callbacks.TypeIs(napi_object)) {
334 HILOGE("First argument is not an object.");
335 NError(BError(BError::Codes::SDK_INVAL_ARG, "First argument is not an object.").GetCode()).ThrowErr(env);
336 return nullptr;
337 }
338
339 NVal ptr(env, funcArg.GetThisVar());
340 auto backupEntity = std::make_unique<BackupEntity>();
341 backupEntity->callbacks = make_shared<GeneralCallbacks>(env, ptr, callbacks);
342 backupEntity->session = BIncrementalBackupSession::Init(BIncrementalBackupSession::Callbacks {
343 .onFileReady = bind(OnFileReady, backupEntity->callbacks, placeholders::_1, placeholders::_2, placeholders::_3,
344 placeholders::_4),
345 .onBundleStarted = bind(onBundleBegin, backupEntity->callbacks, placeholders::_1, placeholders::_2),
346 .onBundleFinished = bind(onBundleEnd, backupEntity->callbacks, placeholders::_1, placeholders::_2),
347 .onAllBundlesFinished = bind(onAllBundlesEnd, backupEntity->callbacks, placeholders::_1),
348 .onResultReport = bind(OnResultReport, backupEntity->callbacks, placeholders::_1, placeholders::_2),
349 .onBackupServiceDied = bind(OnBackupServiceDied, backupEntity->callbacks),
350 .onProcess = bind(OnProcess, backupEntity->callbacks, placeholders::_1, placeholders::_2)});
351 if (!backupEntity->session) {
352 NError(BError(BError::Codes::SDK_INVAL_ARG, "Failed to init backup").GetCode()).ThrowErr(env);
353 return nullptr;
354 }
355 if (!NClass::SetEntityFor<BackupEntity>(env, funcArg.GetThisVar(), move(backupEntity))) {
356 HILOGE("Failed to set BackupEntity entity.");
357 NError(BError(BError::Codes::SDK_INVAL_ARG, "Failed to set BackupEntity entity.").GetCode()).ThrowErr(env);
358 return nullptr;
359 }
360
361 HILOGD("called SessionIncrementalBackup::Constructor end");
362 return funcArg.GetThisVar();
363 }
364
CheckDataList(const LibN::NVal & data)365 static bool CheckDataList(const LibN::NVal &data)
366 {
367 LibN::NVal name = data.GetProp(BConstants::BUNDLE_NAME);
368 if (name.val_ == nullptr) {
369 return false;
370 }
371 auto [succ, str, ignore] = name.ToUTF8String();
372 if (!succ) {
373 return false;
374 }
375
376 LibN::NVal time = data.GetProp(BConstants::LAST_INCREMENTAL_TIME);
377 if (time.val_ == nullptr) {
378 return false;
379 }
380 tie(succ, ignore) = time.ToInt64();
381 if (!succ) {
382 return false;
383 }
384 return true;
385 }
386
ParseDataList(napi_env env,const napi_value & value)387 static std::tuple<bool, std::vector<BIncrementalData>> ParseDataList(napi_env env, const napi_value& value)
388 {
389 uint32_t size = 0;
390 napi_status status = napi_get_array_length(env, value, &size);
391 if (status != napi_ok) {
392 HILOGE("Get array length failed!");
393 return {false, {}};
394 }
395 if (size == 0) {
396 HILOGI("array length is zero!");
397 return {true, {}};
398 }
399
400 napi_value result;
401 std::vector<BIncrementalData> backupData;
402 for (uint32_t i = 0; i < size; i++) {
403 status = napi_get_element(env, value, i, &result);
404 if (status != napi_ok) {
405 HILOGE("Get element failed! index is :%{public}u", i);
406 return {false, {}};
407 } else {
408 NVal element(env, result);
409 if (!CheckDataList(element)) {
410 HILOGE("bundles are invalid!");
411 return {false, {}};
412 }
413 IncrementalBackupData data(element);
414 backupData.emplace_back(data.bundleName,
415 data.lastIncrementalTime,
416 data.manifestFd,
417 data.parameters,
418 data.priority);
419 }
420 }
421 return {true, backupData};
422 }
423
VerifyParamSuccess(NFuncArg & funcArg,std::vector<BIncrementalData> & backupBundles,std::vector<std::string> & bundleInfos,napi_env env)424 static bool VerifyParamSuccess(NFuncArg &funcArg, std::vector<BIncrementalData> &backupBundles,
425 std::vector<std::string> &bundleInfos, napi_env env)
426 {
427 if (!funcArg.InitArgs(NARG_CNT::ONE, NARG_CNT::TWO)) {
428 HILOGE("Number of arguments unmatched.");
429 NError(BError(BError::Codes::SDK_INVAL_ARG, "Number of arguments unmatched.").GetCode()).ThrowErr(env);
430 return false;
431 }
432 auto [succ, bundles] = ParseDataList(env, funcArg[NARG_POS::FIRST]);
433 if (!succ) {
434 HILOGE("bundles array invalid.");
435 NError(BError(BError::Codes::SDK_INVAL_ARG, "bundles array invalid.").GetCode()).ThrowErr(env);
436 return false;
437 }
438 backupBundles = bundles;
439 NVal jsInfos(env, funcArg[NARG_POS::SECOND]);
440 if (jsInfos.TypeIs(napi_undefined) || jsInfos.TypeIs(napi_null)) {
441 HILOGW("Third param is not exist");
442 return true;
443 }
444 auto [deSuc, jsBundleInfos, deIgnore] = jsInfos.ToStringArray();
445 if (deSuc) {
446 bundleInfos = jsBundleInfos;
447 if (backupBundles.size() != bundleInfos.size()) {
448 HILOGE("backupBundles count is not equals bundleInfos count");
449 return false;
450 }
451 return true;
452 }
453 HILOGI("Second param is callback");
454 return true;
455 }
456
AppendBundles(napi_env env,napi_callback_info cbinfo)457 napi_value SessionIncrementalBackupNExporter::AppendBundles(napi_env env, napi_callback_info cbinfo)
458 {
459 HILOGD("called SessionIncrementalBackup::AppendBundles begin");
460 if (!SAUtils::CheckBackupPermission()) {
461 HILOGE("Has not permission!");
462 NError(E_PERMISSION).ThrowErr(env);
463 return nullptr;
464 }
465 if (!SAUtils::IsSystemApp()) {
466 HILOGE("System App check fail!");
467 NError(E_PERMISSION_SYS).ThrowErr(env);
468 return nullptr;
469 }
470 std::vector<BIncrementalData> backupBundles;
471 std::vector<std::string> bundleInfos;
472 NFuncArg funcArg(env, cbinfo);
473 if (!VerifyParamSuccess(funcArg, backupBundles, bundleInfos, env)) {
474 HILOGE("VerifyParamSuccess fail");
475 return nullptr;
476 }
477 auto backupEntity = NClass::GetEntityOf<BackupEntity>(env, funcArg.GetThisVar());
478 if (!(backupEntity && backupEntity->session)) {
479 HILOGE("Failed to get backupSession entity.");
480 NError(BError(BError::Codes::SDK_INVAL_ARG, "Failed to get backupSession entity.").GetCode()).ThrowErr(env);
481 return nullptr;
482 }
483 auto cbExec = [session{ backupEntity->session.get() }, bundles{ backupBundles },
484 infos{ bundleInfos }]() -> NError {
485 if (!session) {
486 return NError(BError(BError::Codes::SDK_INVAL_ARG, "backup session is nullptr").GetCode());
487 }
488 if (!infos.empty()) {
489 return NError(session->AppendBundles(bundles, infos));
490 }
491 return NError(session->AppendBundles(bundles));
492 };
493 auto cbCompl = [](napi_env env, NError err) -> NVal {
494 return err ? NVal {env, err.GetNapiErr(env)} : NVal::CreateUndefined(env);
495 };
496 NVal thisVar(env, funcArg.GetThisVar());
497 if (funcArg.GetArgc() == NARG_CNT::ONE) {
498 return NAsyncWorkPromise(env, thisVar).Schedule(className, cbExec, cbCompl).val_;
499 } else if (!bundleInfos.empty()) {
500 return NAsyncWorkPromise(env, thisVar).Schedule(className, cbExec, cbCompl).val_;
501 } else {
502 NVal cb(env, funcArg[NARG_POS::SECOND]);
503 return NAsyncWorkCallback(env, thisVar, cb).Schedule(className, cbExec, cbCompl).val_;
504 }
505 }
506
Release(napi_env env,napi_callback_info cbinfo)507 napi_value SessionIncrementalBackupNExporter::Release(napi_env env, napi_callback_info cbinfo)
508 {
509 HILOGD("called SessionIncrementalBackup::Release begin");
510 if (!SAUtils::CheckBackupPermission()) {
511 HILOGE("Has not permission!");
512 NError(E_PERMISSION).ThrowErr(env);
513 return nullptr;
514 }
515 if (!SAUtils::IsSystemApp()) {
516 HILOGE("System App check fail!");
517 NError(E_PERMISSION_SYS).ThrowErr(env);
518 return nullptr;
519 }
520 NFuncArg funcArg(env, cbinfo);
521 if (!funcArg.InitArgs(NARG_CNT::ZERO)) {
522 HILOGE("Number of arguments unmatched.");
523 NError(BError(BError::Codes::SDK_INVAL_ARG, "Number of arguments unmatched.").GetCode()).ThrowErr(env);
524 return nullptr;
525 }
526
527 auto backupEntity = NClass::GetEntityOf<BackupEntity>(env, funcArg.GetThisVar());
528 if (!(backupEntity && backupEntity->session)) {
529 HILOGE("Failed to get backupSession entity.");
530 NError(BError(BError::Codes::SDK_INVAL_ARG, "Failed to get backupSession entity.").GetCode()).ThrowErr(env);
531 return nullptr;
532 }
533
534 auto cbExec = [session {backupEntity->session.get()}]() -> NError {
535 if (!session) {
536 return NError(BError(BError::Codes::SDK_INVAL_ARG, "backup session is nullptr").GetCode());
537 }
538 return NError(session->Release());
539 };
540 auto cbCompl = [](napi_env env, NError err) -> NVal {
541 return err ? NVal {env, err.GetNapiErr(env)} : NVal::CreateUndefined(env);
542 };
543
544 HILOGD("Called SessionIncrementalBackup::Release end.");
545
546 NVal thisVar(env, funcArg.GetThisVar());
547 return NAsyncWorkPromise(env, thisVar).Schedule(className, cbExec, cbCompl).val_;
548 }
549
Export()550 bool SessionIncrementalBackupNExporter::Export()
551 {
552 HILOGD("called SessionIncrementalBackupNExporter::Export begin");
553 vector<napi_property_descriptor> props = {
554 NVal::DeclareNapiFunction("appendBundles", AppendBundles),
555 NVal::DeclareNapiFunction("release", Release),
556 };
557
558 auto [succ, classValue] = NClass::DefineClass(exports_.env_, className, Constructor, std::move(props));
559 if (!succ) {
560 HILOGE("Failed to define class");
561 NError(EIO).ThrowErr(exports_.env_);
562 return false;
563 }
564 succ = NClass::SaveClass(exports_.env_, className, classValue);
565 if (!succ) {
566 HILOGE("Failed to save class");
567 NError(EIO).ThrowErr(exports_.env_);
568 return false;
569 }
570
571 HILOGD("called SessionIncrementalBackupNExporter::Export end");
572 return exports_.AddProp(className, classValue);
573 }
574
GetClassName()575 string SessionIncrementalBackupNExporter::GetClassName()
576 {
577 return SessionIncrementalBackupNExporter::className;
578 }
579
SessionIncrementalBackupNExporter(napi_env env,napi_value exports)580 SessionIncrementalBackupNExporter::SessionIncrementalBackupNExporter(napi_env env, napi_value exports)
581 : NExporter(env, exports) {}
582
~SessionIncrementalBackupNExporter()583 SessionIncrementalBackupNExporter::~SessionIncrementalBackupNExporter() {}
584 } // namespace OHOS::FileManagement::Backup