1 /*
2 * Copyright (c) 2023-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 "session_restore_n_exporter.h"
16
17 #include <functional>
18 #include <memory>
19 #include <fcntl.h>
20
21 #include "b_error/b_error.h"
22 #include "b_filesystem/b_dir.h"
23 #include "b_filesystem/b_file.h"
24 #include "b_incremental_restore_session.h"
25 #include "b_ohos/startup/backup_para.h"
26 #include "b_resources/b_constants.h"
27 #include "b_sa/b_sa_utils.h"
28 #include "b_session_restore.h"
29 #include "backup_kit_inner.h"
30 #include "filemgmt_libhilog.h"
31 #include "general_callbacks.h"
32 #include "service_proxy.h"
33
34 namespace OHOS::FileManagement::Backup {
35 using namespace std;
36 using namespace LibN;
37
38 struct RestoreEntity {
39 unique_ptr<BSessionRestore> sessionWhole;
40 unique_ptr<BIncrementalRestoreSession> sessionSheet;
41 shared_ptr<GeneralCallbacks> callbacks;
42 };
43
OnFileReadySheet(weak_ptr<GeneralCallbacks> pCallbacks,const BFileInfo & fileInfo,UniqueFd fd,UniqueFd manifestFd,int32_t sysErrno)44 static void OnFileReadySheet(weak_ptr<GeneralCallbacks> pCallbacks, const BFileInfo &fileInfo,
45 UniqueFd fd, UniqueFd manifestFd, int32_t sysErrno)
46 {
47 auto callbacks = pCallbacks.lock();
48 if (!callbacks) {
49 HILOGI("callback function onFileReady has already been released");
50 return;
51 }
52 if (!bool(callbacks->onFileReady)) {
53 HILOGI("callback function onFileReady is undefined");
54 return;
55 }
56 ErrCode errCode = BError::GetCodeByErrno(sysErrno);
57 std::tuple<uint32_t, std::string> errInfo = std::make_tuple(errCode, "system errno: " + to_string(sysErrno));
58 HILOGI("callback function restore onFileReadySheet begin errCode: %{public}d, bundle: %{public}s, file: %{public}s",
59 std::get<0>(errInfo), fileInfo.owner.c_str(), GetAnonyPath(fileInfo.fileName).c_str());
60 auto cbCompl = [bundleName {fileInfo.owner}, fileName {fileInfo.fileName},
61 fd {make_shared<UniqueFd>(fd.Release())}, manifestFd {make_shared<UniqueFd>(manifestFd.Release())},
62 errInfo](napi_env env, NError err) -> NVal {
63 if (err) {
64 return {env, err.GetNapiErr(env)};
65 }
66 HILOGI("callback function restore OnFileReadySheet errCode: %{public}d, bundle: %{public}s, file: %{public}s",
67 std::get<0>(errInfo), bundleName.c_str(), GetAnonyPath(fileName).c_str());
68 NVal obj;
69 ErrParam errorParam = [ errInfo ]() {
70 return errInfo;
71 };
72 if (std::get<0>(errInfo) != 0) {
73 obj = NVal {env, NError(errorParam).GetNapiErr(env)};
74 napi_status status = napi_set_named_property(env, obj.val_, FILEIO_TAG_ERR_DATA.c_str(),
75 NVal::CreateUTF8String(env, bundleName).val_);
76 if (status != napi_ok) {
77 HILOGE("Failed to set data, status %{public}d, bundleName %{public}s", status, bundleName.c_str());
78 }
79 } else {
80 obj = NVal::CreateObject(env);
81 obj.AddProp({
82 NVal::DeclareNapiProperty(BConstants::BUNDLE_NAME.c_str(),
83 NVal::CreateUTF8String(env, bundleName).val_),
84 NVal::DeclareNapiProperty(BConstants::URI.c_str(), NVal::CreateUTF8String(env, fileName).val_),
85 NVal::DeclareNapiProperty(BConstants::FD.c_str(), NVal::CreateInt32(env, fd->Release()).val_),
86 NVal::DeclareNapiProperty(BConstants::MANIFEST_FD.c_str(),
87 NVal::CreateInt32(env, manifestFd->Release()).val_)});
88 }
89 HILOGI("callback function restore onFileReadySheet end errCode:%{public}d, bundle:%{public}s, file:%{public}s",
90 std::get<0>(errInfo), bundleName.c_str(), GetAnonyPath(fileName).c_str());
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 auto callbacks = pCallbacks.lock();
101 if (!callbacks) {
102 HILOGI("callback function onBundleBegin has already been released");
103 return;
104 }
105 if (!bool(callbacks->onBundleBegin)) {
106 HILOGI("callback function onBundleBegin is undefined");
107 return;
108 }
109
110 ErrCode errCode = BError::GetBackupCodeByErrno(err);
111 std::string errMsg = BError::GetBackupMsgByErrno(errCode) + ", origin errno: " + to_string(err);
112 std::tuple<uint32_t, std::string> errInfo = std::make_tuple(errCode, errMsg);
113 HILOGI("callback function restore onBundleBegin start errCode: %{public}d", std::get<0>(errInfo));
114 auto cbCompl = [name {name}, errCode {err}, errInfo](napi_env env, NError err) -> NVal {
115 NVal bundleName = NVal::CreateUTF8String(env, name);
116 if (!err && errCode == 0) {
117 return bundleName;
118 }
119 ErrParam errorParam = [ errInfo ]() {
120 return errInfo;
121 };
122 NVal res;
123 if (err) {
124 res = NVal {env, err.GetNapiErr(env)};
125 } else {
126 res = NVal {env, NError(errorParam).GetNapiErr(env)};
127 }
128 napi_status status = napi_set_named_property(env, res.val_, FILEIO_TAG_ERR_DATA.c_str(), bundleName.val_);
129 if (status != napi_ok) {
130 HILOGE("Failed to set data property, status %{public}d, bundleName %{public}s", status, name.c_str());
131 }
132 HILOGI("callback function restore onBundleBegin end errCode: %{public}d", std::get<0>(errInfo));
133 return res;
134 };
135
136 callbacks->onBundleBegin.ThreadSafeSchedule(cbCompl);
137 }
138
onBundleEnd(weak_ptr<GeneralCallbacks> pCallbacks,ErrCode err,const BundleName name)139 static void onBundleEnd(weak_ptr<GeneralCallbacks> pCallbacks, ErrCode err, const BundleName name)
140 {
141 HILOGI("Callback onBundleEnd, bundleName=%{public}s, errCode=%{public}d", name.c_str(), err);
142 auto callbacks = pCallbacks.lock();
143 if (!callbacks) {
144 HILOGI("callback function onBundleEnd has already been released");
145 return;
146 }
147 if (!bool(callbacks->onBundleEnd)) {
148 HILOGI("callback function onBundleEnd is undefined");
149 return;
150 }
151
152 ErrCode errCode = BError::GetBackupCodeByErrno(err);
153 std::string errMsg = BError::GetBackupMsgByErrno(errCode) + ", origin errno: " + to_string(err);
154 std::tuple<uint32_t, std::string> errInfo = std::make_tuple(errCode, errMsg);
155 HILOGI("callback function restore onBundleEnd start errCode: %{public}d", std::get<0>(errInfo));
156 auto cbCompl = [name {name}, errCode {err}, errInfo](napi_env env, NError err) -> NVal {
157 NVal bundleName = NVal::CreateUTF8String(env, name);
158 if (!err && errCode == 0) {
159 return bundleName;
160 }
161 ErrParam errorParam = [ errInfo ]() {
162 return errInfo;
163 };
164 NVal res;
165 if (err) {
166 res = NVal {env, err.GetNapiErr(env)};
167 } else {
168 res = NVal {env, NError(errorParam).GetNapiErr(env)};
169 }
170 napi_status status = napi_set_named_property(env, res.val_, FILEIO_TAG_ERR_DATA.c_str(), bundleName.val_);
171 if (status != napi_ok) {
172 HILOGE("Failed to set data property, status %{public}d, bundleName %{public}s", status, name.c_str());
173 }
174 HILOGI("callback function restore onBundleEnd end errCode: %{public}d", std::get<0>(errInfo));
175 return res;
176 };
177
178 callbacks->onBundleEnd.ThreadSafeSchedule(cbCompl);
179 }
180
onAllBundlesEnd(weak_ptr<GeneralCallbacks> pCallbacks,ErrCode err)181 static void onAllBundlesEnd(weak_ptr<GeneralCallbacks> pCallbacks, ErrCode err)
182 {
183 auto callbacks = pCallbacks.lock();
184 if (!callbacks) {
185 HILOGI("callback function onAllBundlesEnd has already been released");
186 return;
187 }
188 if (!bool(callbacks->onAllBundlesEnd)) {
189 HILOGI("callback function onAllBundlesEnd is undefined");
190 return;
191 }
192
193 ErrCode errCode = BError::GetBackupCodeByErrno(err);
194 std::string errMsg = BError::GetBackupMsgByErrno(errCode) + ", origin errno: " + to_string(err);
195 std::tuple<uint32_t, std::string> errInfo = std::make_tuple(errCode, errMsg);
196 HILOGI("callback function restore onAllBundlesEnd begin errCode: %{public}d", std::get<0>(errInfo));
197 auto cbCompl = [errCode {err}, errInfo](napi_env env, NError err) -> NVal {
198 if (!err && errCode == 0) {
199 return NVal::CreateUndefined(env);
200 }
201 ErrParam errorParam = [ errInfo ]() {
202 return errInfo;
203 };
204 NVal res;
205 if (err) {
206 res = NVal {env, err.GetNapiErr(env)};
207 } else {
208 res = NVal {env, NError(errorParam).GetNapiErr(env)};
209 }
210 HILOGI("callback function backup onAllBundlesEnd end errCode: %{public}d", std::get<0>(errInfo));
211 return res;
212 };
213
214 callbacks->onAllBundlesEnd.ThreadSafeSchedule(cbCompl);
215 }
216
OnBackupServiceDied(weak_ptr<GeneralCallbacks> pCallbacks)217 static void OnBackupServiceDied(weak_ptr<GeneralCallbacks> pCallbacks)
218 {
219 HILOGI("Callback OnBackupServiceDied.");
220 auto callbacks = pCallbacks.lock();
221 if (!callbacks) {
222 HILOGI("js callback function onBackupServiceDied has already been released");
223 return;
224 }
225 if (!bool(callbacks->onBackupServiceDied)) {
226 HILOGI("callback function onBackupServiceDied is undefined");
227 return;
228 }
229
230 auto cbCompl = [](napi_env env, vector<napi_value> &argv) -> bool {
231 argv.emplace_back(nullptr);
232 napi_value napi_res = nullptr;
233 if (napi_get_undefined(env, &napi_res) != napi_ok) {
234 HILOGE("create undefined napi object failed");
235 return false;
236 }
237 argv.emplace_back(napi_res);
238 return true;
239 };
240 callbacks->onBackupServiceDied.CallJsMethod(cbCompl);
241 }
242
OnResultReport(weak_ptr<GeneralCallbacks> pCallbacks,const std::string bundleName,const std::string result)243 static void OnResultReport(weak_ptr<GeneralCallbacks> pCallbacks, const std::string bundleName,
244 const std::string result)
245 {
246 HILOGI("Callback OnResultReport, bundleName=%{public}s", bundleName.c_str());
247 auto callbacks = pCallbacks.lock();
248 if (!callbacks) {
249 HILOGI("callback function onResultReport has already been released");
250 return;
251 }
252 if (!bool(callbacks->onResultReport)) {
253 HILOGI("callback function onResultReport is undefined");
254 return;
255 }
256 auto cbCompl = [bName {bundleName}, res {result}](napi_env env, vector<napi_value> &argv) -> bool {
257 napi_value napi_bName = nullptr;
258 if (napi_create_string_utf8(env, bName.c_str(), bName.size(), &napi_bName) != napi_ok) {
259 HILOGE("create napi string failed");
260 return false;
261 }
262 argv.emplace_back(napi_bName);
263 napi_value napi_res = nullptr;
264 if (napi_create_string_utf8(env, res.c_str(), res.size(), &napi_res) != napi_ok) {
265 HILOGE("create napi string failed");
266 return false;
267 }
268 argv.emplace_back(napi_res);
269 return true;
270 };
271 callbacks->onResultReport.CallJsMethod(cbCompl);
272 }
273
OnProcess(weak_ptr<GeneralCallbacks> pCallbacks,const BundleName name,const std::string processInfo)274 static void OnProcess(weak_ptr<GeneralCallbacks> pCallbacks, const BundleName name, const std::string processInfo)
275 {
276 HILOGI("Callback OnProcess, bundleName=%{public}s", name.c_str());
277 auto callbacks = pCallbacks.lock();
278 if (!callbacks) {
279 HILOGI("callback function OnProcess has already been released");
280 return;
281 }
282 if (!bool(callbacks->onProcess)) {
283 HILOGI("callback function OnProcess is undefined");
284 return;
285 }
286 auto cbCompl = [bundleName {name}, process {processInfo}](napi_env env, vector<napi_value> &argv) -> bool {
287 napi_value napi_bName = nullptr;
288 if (napi_create_string_utf8(env, bundleName.c_str(), bundleName.size(), &napi_bName) != napi_ok) {
289 HILOGE("create napi string failed");
290 return false;
291 }
292 argv.emplace_back(napi_bName);
293 napi_value napi_process = nullptr;
294 if (napi_create_string_utf8(env, process.c_str(), process.size(), &napi_process) != napi_ok) {
295 HILOGE("create napi string failed");
296 return false;
297 }
298 argv.emplace_back(napi_process);
299 return true;
300 };
301 callbacks->onProcess.CallJsMethod(cbCompl);
302 }
303
VerifyAppendBundlesParam(NFuncArg & funcArg,int32_t & fd,std::vector<std::string> & bundleNames,std::vector<std::string> & bundleInfos,napi_env env)304 static bool VerifyAppendBundlesParam(NFuncArg &funcArg, int32_t &fd, std::vector<std::string> &bundleNames,
305 std::vector<std::string> &bundleInfos, napi_env env)
306 {
307 if (!funcArg.InitArgs(NARG_CNT::TWO, NARG_CNT::THREE)) {
308 HILOGE("Number of arguments unmatched.");
309 NError(BError(BError::Codes::SDK_INVAL_ARG, "Number of arguments unmatched.").GetCode()).ThrowErr(env);
310 return false;
311 }
312 NVal remoteCap(env, funcArg[NARG_POS::FIRST]);
313 auto [err, jsFd] = remoteCap.ToInt32();
314 if (!err) {
315 HILOGE("First argument is not remote capabilitily file number.");
316 NError(BError(BError::Codes::SDK_INVAL_ARG, "First argument is not remote capabilitily file number.").GetCode())
317 .ThrowErr(env);
318 return false;
319 }
320 fd = jsFd;
321 NVal jsBundles(env, funcArg[NARG_POS::SECOND]);
322 auto [succ, jsBundleNames, ignore] = jsBundles.ToStringArray();
323 if (!succ) {
324 HILOGE("First argument is not bundles array.");
325 NError(BError(BError::Codes::SDK_INVAL_ARG, "First argument is not bundles array.").GetCode()).ThrowErr(env);
326 return false;
327 }
328 bundleNames = jsBundleNames;
329 NVal jsInfos(env, funcArg[NARG_POS::THIRD]);
330 if (jsInfos.TypeIs(napi_undefined) || jsInfos.TypeIs(napi_null)) {
331 HILOGW("Third param is not exist");
332 return true;
333 }
334 auto [deSuc, jsBundleInfos, deIgnore] = jsInfos.ToStringArray();
335 if (deSuc) {
336 bundleInfos = jsBundleInfos;
337 if (bundleNames.size() != bundleInfos.size()) {
338 HILOGE("bundleNames count is not equals bundleInfos count");
339 return false;
340 }
341 return true;
342 }
343 HILOGI("Third param is callback");
344 return true;
345 }
346
ParseFileMeta(napi_env env,const NVal & fileMeta)347 static std::tuple<bool, std::unique_ptr<char[]>, std::unique_ptr<char[]>> ParseFileMeta(napi_env env,
348 const NVal &fileMeta)
349 {
350 bool succ = false;
351 std::unique_ptr<char[]> bundleName = nullptr;
352 tie(succ, bundleName, ignore) = fileMeta.GetProp(BConstants::BUNDLE_NAME).ToUTF8String();
353 if (!succ) {
354 HILOGE("First argument is not have property bundle name.");
355 return { false, nullptr, nullptr };
356 }
357
358 std::unique_ptr<char[]> fileName = nullptr;
359 tie(succ, fileName, ignore) = fileMeta.GetProp(BConstants::URI).ToUTF8String();
360 if (!succ) {
361 HILOGE("First argument is not have property file name.");
362 return { false, nullptr, nullptr };
363 }
364
365 return { true, move(bundleName), move(fileName) };
366 }
367
VerifyPublishFileParam(NFuncArg & funcArg,std::string & bundleName,std::string & fileName,napi_env env)368 static bool VerifyPublishFileParam(NFuncArg &funcArg, std::string &bundleName, std::string &fileName, napi_env env)
369 {
370 if (!funcArg.InitArgs(NARG_CNT::ONE, NARG_CNT::TWO)) {
371 HILOGE("Number of arguments unmatched.");
372 NError(BError(BError::Codes::SDK_INVAL_ARG, "Number of arguments unmatched.").GetCode()).ThrowErr(env);
373 return false;
374 }
375
376 NVal fileMeta(env, funcArg[NARG_POS::FIRST]);
377 if (!fileMeta.TypeIs(napi_object)) {
378 HILOGE("First arguments is not an object.");
379 NError(BError(BError::Codes::SDK_INVAL_ARG, "First arguments is not an object.").GetCode()).ThrowErr(env);
380 return false;
381 }
382 auto [succ, bundle, file] = ParseFileMeta(env, fileMeta);
383 if (!succ) {
384 HILOGE("ParseFileMeta failed.");
385 NError(BError(BError::Codes::SDK_INVAL_ARG, "ParseFileMeta failed.").GetCode()).ThrowErr(env);
386 return false;
387 }
388 bundleName = string(bundle.get());
389 fileName = string(file.get());
390 return true;
391 }
392
VerifyNapiObject(napi_env env,NFuncArg & funcArg)393 static bool VerifyNapiObject(napi_env env, NFuncArg &funcArg)
394 {
395 if (!funcArg.InitArgs(NARG_CNT::ONE)) {
396 HILOGE("Number of arguments unmatched.");
397 NError(BError(BError::Codes::SDK_INVAL_ARG, "Number of arguments unmatched.").GetCode()).ThrowErr(env);
398 return true;
399 }
400 return false;
401 }
402
VerifyNarg(napi_env env,NVal & callbacks)403 static bool VerifyNarg(napi_env env, NVal &callbacks)
404 {
405 if (!callbacks.TypeIs(napi_object)) {
406 HILOGE("First argument is not an object.");
407 NError(BError(BError::Codes::SDK_INVAL_ARG, "First argument is not an object.").GetCode()).ThrowErr(env);
408 return true;
409 }
410 return false;
411 }
412
SetSessionRestoreEntity(napi_env env,NFuncArg & funcArg,std::unique_ptr<RestoreEntity> restoreEntity)413 static bool SetSessionRestoreEntity(napi_env env, NFuncArg &funcArg, std::unique_ptr<RestoreEntity> restoreEntity)
414 {
415 auto finalize = [](napi_env env, void *data, void *hint) {
416 std::unique_ptr<RestoreEntity> entity = std::unique_ptr<RestoreEntity>(static_cast<RestoreEntity *>(data));
417 if (entity == nullptr) {
418 HILOGE("Entity is nullptr");
419 return;
420 }
421 if (entity->callbacks == nullptr) {
422 HILOGE("Callbacks is nullptr");
423 return;
424 }
425 entity->callbacks->RemoveCallbackRef();
426 };
427 if (napi_wrap(env, funcArg.GetThisVar(), restoreEntity.release(), finalize, nullptr, nullptr) != napi_ok) {
428 HILOGE("Failed to set restoreEntity entity.");
429 return false;
430 }
431 return true;
432 }
433
Constructor(napi_env env,napi_callback_info cbinfo)434 napi_value SessionRestoreNExporter::Constructor(napi_env env, napi_callback_info cbinfo)
435 {
436 HILOGI("called SessionRestore::Constructor begin");
437 if (!SAUtils::CheckBackupPermission()) {
438 HILOGE("Has not permission!");
439 NError(E_PERMISSION).ThrowErr(env);
440 return nullptr;
441 }
442 if (!SAUtils::IsSystemApp()) {
443 HILOGE("System App check fail!");
444 NError(E_PERMISSION_SYS).ThrowErr(env);
445 return nullptr;
446 }
447 NFuncArg funcArg(env, cbinfo);
448 if (VerifyNapiObject(env, funcArg)) {
449 return nullptr;
450 }
451 NVal callbacks(env, funcArg[NARG_POS::FIRST]);
452 if (VerifyNarg(env, callbacks)) {
453 return nullptr;
454 }
455
456 NVal ptr(env, funcArg.GetThisVar());
457 auto restoreEntity = std::make_unique<RestoreEntity>();
458 restoreEntity->callbacks = make_shared<GeneralCallbacks>(env, ptr, callbacks);
459 restoreEntity->sessionWhole = nullptr;
460 ErrCode errCode;
461 std::string errMsg;
462 restoreEntity->sessionSheet = BIncrementalRestoreSession::Init(BIncrementalRestoreSession::Callbacks {
463 .onFileReady = bind(OnFileReadySheet, restoreEntity->callbacks, placeholders::_1, placeholders::_2,
464 placeholders::_3, placeholders::_4),
465 .onBundleStarted = bind(onBundleBegin, restoreEntity->callbacks, placeholders::_1, placeholders::_2),
466 .onBundleFinished = bind(onBundleEnd, restoreEntity->callbacks, placeholders::_1, placeholders::_2),
467 .onAllBundlesFinished = bind(onAllBundlesEnd, restoreEntity->callbacks, placeholders::_1),
468 .onResultReport = bind(OnResultReport, restoreEntity->callbacks, placeholders::_1, placeholders::_2),
469 .onBackupServiceDied = bind(OnBackupServiceDied, restoreEntity->callbacks),
470 .onProcess = bind(OnProcess, restoreEntity->callbacks, placeholders::_1, placeholders::_2)}, errMsg, errCode);
471 if (!restoreEntity->sessionSheet) {
472 std::tuple<uint32_t, std::string> errInfo = (errCode == BError(BError::Codes::SA_SESSION_CONFLICT)) ?
473 std::make_tuple(errCode, errMsg) : std::make_tuple(errCode, BError::GetBackupMsgByErrno(errCode));
474 ErrParam errorParam = [ errInfo ]() { return errInfo;};
475 NError(errorParam).ThrowErr(env);
476 return nullptr;
477 }
478 if (!SetSessionRestoreEntity(env, funcArg, std::move(restoreEntity))) {
479 NError(BError(BError::Codes::SDK_INVAL_ARG, "Failed to set SessionRestore entity.").GetCode()).ThrowErr(env);
480 return nullptr;
481 }
482 HILOGI("called SessionRestore::Constructor end");
483 return funcArg.GetThisVar();
484 }
485
GetLocalCapabilities(napi_env env,napi_callback_info cbinfo)486 napi_value SessionRestoreNExporter::GetLocalCapabilities(napi_env env, napi_callback_info cbinfo)
487 {
488 HILOGI("called SessionBackup, GetLocalCapabilities Begin");
489 if (!SAUtils::CheckBackupPermission()) {
490 HILOGE("Has not permission!");
491 NError(E_PERMISSION).ThrowErr(env);
492 return nullptr;
493 }
494 if (!SAUtils::IsSystemApp()) {
495 HILOGE("System App check fail!");
496 NError(E_PERMISSION_SYS).ThrowErr(env);
497 return nullptr;
498 }
499 NFuncArg funcArg(env, cbinfo);
500 if (!funcArg.InitArgs(NARG_CNT::ZERO)) {
501 HILOGE("Number of arguments unmatched.");
502 NError(BError(BError::Codes::SDK_INVAL_ARG, "Number of arguments unmatched.").GetCode()).ThrowErr(env);
503 return nullptr;
504 }
505 auto restoreEntity = NClass::GetEntityOf<RestoreEntity>(env, funcArg.GetThisVar());
506 if (!(restoreEntity && (restoreEntity->sessionWhole || restoreEntity->sessionSheet))) {
507 HILOGE("Failed to get restoreSession entity.");
508 NError(BError(BError::Codes::SDK_INVAL_ARG, "Failed to get restoreSession entity.").GetCode()).ThrowErr(env);
509 return nullptr;
510 }
511 auto fd = make_shared<UniqueFd>();
512 auto cbExec = [session {restoreEntity}, fd]() -> NError {
513 if (!session && (session->sessionWhole || session->sessionSheet)) {
514 return NError(BError(BError::Codes::SDK_INVAL_ARG, "backup session is nullptr").GetCode());
515 }
516 if (session->sessionWhole) {
517 *fd = session->sessionWhole->GetLocalCapabilities();
518 } else if (session->sessionSheet) {
519 *fd = session->sessionSheet->GetLocalCapabilities();
520 }
521 return NError(ERRNO_NOERR);
522 };
523 auto cbCompl = [fd](napi_env env, NError err) -> NVal {
524 NVal obj = NVal::CreateObject(env);
525 obj.AddProp({NVal::DeclareNapiProperty(BConstants::FD.c_str(), NVal::CreateInt32(env, fd->Release()).val_)});
526 return {obj};
527 };
528 NVal thisVar(env, funcArg.GetThisVar());
529 return NAsyncWorkPromise(env, thisVar).Schedule(className, cbExec, cbCompl).val_;
530 }
531
GetAppendBundlesCBExec(napi_env env,NFuncArg & funcArg,const int32_t fdRestore,const std::vector<std::string> & bundleNames,const std::vector<std::string> & bundleInfos)532 static NContextCBExec GetAppendBundlesCBExec(napi_env env, NFuncArg &funcArg, const int32_t fdRestore,
533 const std::vector<std::string> &bundleNames, const std::vector<std::string> &bundleInfos)
534 {
535 auto restoreEntity = NClass::GetEntityOf<RestoreEntity>(env, funcArg.GetThisVar());
536 if (!(restoreEntity && (restoreEntity->sessionWhole || restoreEntity->sessionSheet))) {
537 HILOGE("Failed to get RestoreSession entity.");
538 NError(BError(BError::Codes::SDK_INVAL_ARG, "Failed to get RestoreSession entity.").GetCode()).ThrowErr(env);
539 return nullptr;
540 }
541 return [entity {restoreEntity}, fd {fdRestore}, bundles {bundleNames}, infos {bundleInfos}]() -> NError {
542 if (!(entity && (entity->sessionWhole || entity->sessionSheet))) {
543 return NError(BError(BError::Codes::SDK_INVAL_ARG, "restore session is nullptr").GetCode());
544 }
545 if (fcntl(fd, F_GETFD) == -1) {
546 HILOGE("AppendBundles fd is invalid.");
547 return NError(BError(BError::Codes::SDK_INVAL_ARG, "AppendBundles fd is invalid.").GetCode());
548 }
549 if (entity->sessionWhole) {
550 if (!infos.empty()) {
551 return NError(entity->sessionWhole->AppendBundles(UniqueFd(fd), bundles, infos));
552 }
553 return NError(entity->sessionWhole->AppendBundles(UniqueFd(fd), bundles));
554 }
555 if (!infos.empty()) {
556 return NError(entity->sessionSheet->AppendBundles(UniqueFd(fd), bundles, infos));
557 }
558 return NError(entity->sessionSheet->AppendBundles(UniqueFd(fd), bundles));
559 };
560 }
561
AppendBundles(napi_env env,napi_callback_info cbinfo)562 napi_value SessionRestoreNExporter::AppendBundles(napi_env env, napi_callback_info cbinfo)
563 {
564 HILOGI("called SessionRestore::AppendBundles begin");
565 if (!SAUtils::CheckBackupPermission()) {
566 HILOGE("Has not permission!");
567 NError(E_PERMISSION).ThrowErr(env);
568 return nullptr;
569 }
570 if (!SAUtils::IsSystemApp()) {
571 HILOGE("System App check fail!");
572 NError(E_PERMISSION_SYS).ThrowErr(env);
573 return nullptr;
574 }
575 int32_t fdRestore = BConstants::INVALID_FD_NUM;
576 std::vector<std::string> bundleNames;
577 std::vector<std::string> bundleInfos;
578 NFuncArg funcArg(env, cbinfo);
579 if (!VerifyAppendBundlesParam(funcArg, fdRestore, bundleNames, bundleInfos, env)) {
580 return nullptr;
581 }
582 auto cbExec = GetAppendBundlesCBExec(env, funcArg, fdRestore, bundleNames, bundleInfos);
583 if (cbExec == nullptr) {
584 HILOGE("GetAppendBundlesCBExec fail!");
585 return nullptr;
586 }
587 auto cbCompl = [](napi_env env, NError err) -> NVal {
588 return err ? NVal {env, err.GetNapiErr(env)} : NVal::CreateUndefined(env);
589 };
590 HILOGD("Called SessionRestore::AppendBundles end.");
591
592 NVal thisVar(env, funcArg.GetThisVar());
593 if (funcArg.GetArgc() == NARG_CNT::TWO) {
594 return NAsyncWorkPromise(env, thisVar).Schedule(className, cbExec, cbCompl).val_;
595 } else if (!bundleInfos.empty()) {
596 HILOGI("The third param is string array");
597 return NAsyncWorkPromise(env, thisVar).Schedule(className, cbExec, cbCompl).val_;
598 } else {
599 HILOGI("The third param is call back");
600 NVal cb(env, funcArg[NARG_POS::THIRD]);
601 return NAsyncWorkCallback(env, thisVar, cb).Schedule(className, cbExec, cbCompl).val_;
602 }
603 }
604
GetPublishFileCBExec(napi_env env,NFuncArg & funcArg,const std::string & bundleName,const std::string & fileName)605 static NContextCBExec GetPublishFileCBExec(napi_env env, NFuncArg &funcArg, const std::string &bundleName,
606 const std::string &fileName)
607 {
608 auto restoreEntity = NClass::GetEntityOf<RestoreEntity>(env, funcArg.GetThisVar());
609 if (!(restoreEntity && (restoreEntity->sessionWhole || restoreEntity->sessionSheet))) {
610 HILOGE("Failed to get RestoreSession entity.");
611 NError(BError(BError::Codes::SDK_INVAL_ARG, "Failed to get RestoreSession entity.").GetCode()).ThrowErr(env);
612 return nullptr;
613 }
614 return [entity {restoreEntity}, bundleName {bundleName}, fileName {fileName}]() -> NError {
615 if (!(entity && (entity->sessionWhole || entity->sessionSheet))) {
616 return NError(BError(BError::Codes::SDK_INVAL_ARG, "restore session is nullptr").GetCode());
617 }
618 BFileInfo fileInfo(bundleName, fileName, 0);
619 if (entity->sessionWhole) {
620 return NError(entity->sessionWhole->PublishFile(fileInfo));
621 }
622 if (SAUtils::IsSABundleName(bundleName)) {
623 if (SAUtils::IsSABundleName(fileName)) {
624 HILOGI("SA %{public}s pushlish file", bundleName.c_str());
625 if (fcntl(std::atoi(fileName.c_str()), F_GETFD) == -1) {
626 HILOGE("PublishFile fd is invalid.");
627 return NError(BError(BError::Codes::SDK_INVAL_ARG, "PublishFile fd is invalid.").GetCode());
628 }
629 return NError(entity->sessionSheet->PublishSAFile(fileInfo, UniqueFd(std::atoi(fileName.c_str()))));
630 }
631 HILOGE("SA:%{public}s, fileName:%{private}s is invalid", bundleName.c_str(), fileName.c_str());
632 return NError(BError(BError::Codes::SDK_INVAL_ARG, "PublishFile fd is invalid.").GetCode());
633 }
634 return NError(entity->sessionSheet->PublishFile(fileInfo));
635 };
636 }
637
PublishFile(napi_env env,napi_callback_info cbinfo)638 napi_value SessionRestoreNExporter::PublishFile(napi_env env, napi_callback_info cbinfo)
639 {
640 HILOGD("called SessionRestore::PublishFile begin");
641 if (!SAUtils::CheckBackupPermission()) {
642 HILOGE("Has not permission!");
643 NError(E_PERMISSION).ThrowErr(env);
644 return nullptr;
645 }
646 if (!SAUtils::IsSystemApp()) {
647 HILOGE("System App check fail!");
648 NError(E_PERMISSION_SYS).ThrowErr(env);
649 return nullptr;
650 }
651 std::string bundleName;
652 std::string fileName;
653 NFuncArg funcArg(env, cbinfo);
654 if (!VerifyPublishFileParam(funcArg, bundleName, fileName, env)) {
655 return nullptr;
656 }
657 auto cbExec = GetPublishFileCBExec(env, funcArg, bundleName, fileName);
658 if (cbExec == nullptr) {
659 HILOGE("GetPublishFileCBExec fail!");
660 return nullptr;
661 }
662 auto cbCompl = [](napi_env env, NError err) -> NVal {
663 return err ? NVal {env, err.GetNapiErr(env)} : NVal::CreateUndefined(env);
664 };
665 HILOGD("Called SessionRestore::PublishFile end.");
666
667 NVal thisVar(env, funcArg.GetThisVar());
668 if (funcArg.GetArgc() == NARG_CNT::ONE) {
669 return NAsyncWorkPromise(env, thisVar).Schedule(className, cbExec, cbCompl).val_;
670 } else {
671 NVal cb(env, funcArg[NARG_POS::SECOND]);
672 return NAsyncWorkCallback(env, thisVar, cb).Schedule(className, cbExec, cbCompl).val_;
673 }
674 }
675
GetFileHandleCBExec(napi_env env,NFuncArg & funcArg,std::unique_ptr<char[]> bundleName,std::unique_ptr<char[]> fileName)676 static NContextCBExec GetFileHandleCBExec(napi_env env, NFuncArg &funcArg, std::unique_ptr<char[]> bundleName,
677 std::unique_ptr<char[]> fileName)
678 {
679 auto restoreEntity = NClass::GetEntityOf<RestoreEntity>(env, funcArg.GetThisVar());
680 if (!(restoreEntity && (restoreEntity->sessionWhole || restoreEntity->sessionSheet))) {
681 HILOGE("Failed to get RestoreSession entity.");
682 NError(BError(BError::Codes::SDK_INVAL_ARG, "Failed to get RestoreSession entity.").GetCode()).ThrowErr(env);
683 return nullptr;
684 }
685 return [entity {restoreEntity}, bundleName {string(bundleName.get())},
686 fileName {string(fileName.get())}]() -> NError {
687 if (!(entity && (entity->sessionWhole || entity->sessionSheet))) {
688 return NError(BError(BError::Codes::SDK_INVAL_ARG, "restore session is nullptr").GetCode());
689 }
690 string bundle = bundleName;
691 string file = fileName;
692 if (entity->sessionWhole) {
693 return NError(entity->sessionWhole->GetFileHandle(bundle, file));
694 }
695 return NError(entity->sessionSheet->GetFileHandle(bundle, file));
696 };
697 }
698
GetFileHandle(napi_env env,napi_callback_info cbinfo)699 napi_value SessionRestoreNExporter::GetFileHandle(napi_env env, napi_callback_info cbinfo)
700 {
701 HILOGD("called SessionRestore::GetFileHandle begin");
702 if (!SAUtils::CheckBackupPermission()) {
703 HILOGE("Has not permission!");
704 NError(E_PERMISSION).ThrowErr(env);
705 return nullptr;
706 }
707 if (!SAUtils::IsSystemApp()) {
708 HILOGE("System App check fail!");
709 NError(E_PERMISSION_SYS).ThrowErr(env);
710 return nullptr;
711 }
712 NFuncArg funcArg(env, cbinfo);
713 if (!funcArg.InitArgs(NARG_CNT::ONE, NARG_CNT::TWO)) {
714 HILOGE("Number of arguments unmatched.");
715 NError(BError(BError::Codes::SDK_INVAL_ARG, "Number of arguments unmatched.").GetCode()).ThrowErr(env);
716 return nullptr;
717 }
718
719 NVal fileMeta(env, funcArg[NARG_POS::FIRST]);
720 if (!fileMeta.TypeIs(napi_object)) {
721 HILOGE("First arguments is not an object.");
722 NError(BError(BError::Codes::SDK_INVAL_ARG, "First arguments is not an object.").GetCode()).ThrowErr(env);
723 return nullptr;
724 }
725
726 auto [succ, bundleName, fileName] = ParseFileMeta(env, fileMeta);
727 if (!succ) {
728 HILOGE("ParseFileMeta failed.");
729 NError(BError(BError::Codes::SDK_INVAL_ARG, "ParseFileMeta failed.").GetCode()).ThrowErr(env);
730 return nullptr;
731 }
732
733 auto cbExec = GetFileHandleCBExec(env, funcArg, move(bundleName), move(fileName));
734 if (cbExec == nullptr) {
735 HILOGE("GetFileHandleCBExec fail!");
736 return nullptr;
737 }
738 auto cbCompl = [](napi_env env, NError err) -> NVal {
739 return err ? NVal {env, err.GetNapiErr(env)} : NVal::CreateUndefined(env);
740 };
741 HILOGD("Called SessionRestore::GetFileHandle end.");
742
743 NVal thisVar(env, funcArg.GetThisVar());
744 if (funcArg.GetArgc() == NARG_CNT::ONE) {
745 return NAsyncWorkPromise(env, thisVar).Schedule(className, cbExec, cbCompl).val_;
746 } else {
747 NVal cb(env, funcArg[NARG_POS::SECOND]);
748 return NAsyncWorkCallback(env, thisVar, cb).Schedule(className, cbExec, cbCompl).val_;
749 }
750 }
751
Release(napi_env env,napi_callback_info cbinfo)752 napi_value SessionRestoreNExporter::Release(napi_env env, napi_callback_info cbinfo)
753 {
754 HILOGI("called SessionRestore::Release begin");
755 if (!SAUtils::CheckBackupPermission()) {
756 HILOGE("Has not permission!");
757 NError(E_PERMISSION).ThrowErr(env);
758 return nullptr;
759 }
760 if (!SAUtils::IsSystemApp()) {
761 HILOGE("System App check fail!");
762 NError(E_PERMISSION_SYS).ThrowErr(env);
763 return nullptr;
764 }
765 NFuncArg funcArg(env, cbinfo);
766 if (!funcArg.InitArgs(NARG_CNT::ZERO)) {
767 HILOGE("Number of arguments unmatched.");
768 NError(BError(BError::Codes::SDK_INVAL_ARG, "Number of arguments unmatched.").GetCode()).ThrowErr(env);
769 return nullptr;
770 }
771
772 auto restoreEntity = NClass::GetEntityOf<RestoreEntity>(env, funcArg.GetThisVar());
773 if (!(restoreEntity && (restoreEntity->sessionWhole || restoreEntity->sessionSheet))) {
774 HILOGE("Failed to get RestoreSession entity.");
775 NError(BError(BError::Codes::SDK_INVAL_ARG, "Failed to get RestoreSession entity.").GetCode()).ThrowErr(env);
776 return nullptr;
777 }
778
779 auto cbExec = [entity {restoreEntity}]() -> NError {
780 if (!(entity && (entity->sessionWhole || entity->sessionSheet))) {
781 return NError(BError(BError::Codes::SDK_INVAL_ARG, "restore session is nullptr").GetCode());
782 }
783 if (entity->sessionWhole) {
784 return NError(entity->sessionWhole->Release());
785 }
786 return NError(entity->sessionSheet->Release());
787 };
788 auto cbCompl = [](napi_env env, NError err) -> NVal {
789 return err ? NVal {env, err.GetNapiErr(env)} : NVal::CreateUndefined(env);
790 };
791 HILOGI("Called SessionRestore::Release end.");
792
793 NVal thisVar(env, funcArg.GetThisVar());
794 return NAsyncWorkPromise(env, thisVar).Schedule(className, cbExec, cbCompl).val_;
795 }
796
Cancel(napi_env env,napi_callback_info info)797 napi_value SessionRestoreNExporter::Cancel(napi_env env, napi_callback_info info)
798 {
799 HILOGD("Called SessionRestore::Cancel begin");
800 if (!SAUtils::CheckBackupPermission()) {
801 HILOGE("Has not permission!");
802 NError(E_PERMISSION).ThrowErr(env);
803 return nullptr;
804 }
805 if (!SAUtils::IsSystemApp()) {
806 HILOGE("System App check fail!");
807 NError(E_PERMISSION_SYS).ThrowErr(env);
808 return nullptr;
809 }
810 NFuncArg funcArg(env, info);
811 if (!funcArg.InitArgs(NARG_CNT::ONE, NARG_CNT::TWO)) {
812 HILOGE("Number of arguments unmatched.");
813 NError(E_PARAMS).ThrowErr(env);
814 return nullptr;
815 }
816 NVal jsBundleStr(env, funcArg[NARG_POS::FIRST]);
817 auto [succStr, bundle, sizeStr] = jsBundleStr.ToUTF8String();
818 if (!succStr) {
819 HILOGE("First argument is not bundleName.");
820 NError(E_PARAMS).ThrowErr(env);
821 return nullptr;
822 }
823 std::string bundleName = bundle.get();
824
825 auto restoreEntity = NClass::GetEntityOf<RestoreEntity>(env, funcArg.GetThisVar());
826 if (!(restoreEntity && (restoreEntity->sessionWhole || restoreEntity->sessionSheet))) {
827 HILOGE("Failed to get restoreSession entity.");
828 return nullptr;
829 }
830
831 int result = BError(BError::Codes::OK);
832 if (restoreEntity->sessionWhole) {
833 result = restoreEntity->sessionWhole->Cancel(bundleName);
834 } else {
835 result = restoreEntity->sessionSheet->Cancel(bundleName);
836 }
837
838 napi_value nResult;
839 napi_status status = napi_create_int32(env, result, &nResult);
840 if (status != napi_ok) {
841 HILOGE("napi_create_int32 faild.");
842 return nullptr;
843 }
844 HILOGI("Cancel success with result: %{public}d", result);
845 return nResult;
846 }
847
CleanBundleTempDirCBExec(napi_env env,const NFuncArg & funcArg,std::unique_ptr<char[]> bundleName)848 static NContextCBExec CleanBundleTempDirCBExec(napi_env env, const NFuncArg &funcArg,
849 std::unique_ptr<char[]> bundleName)
850 {
851 auto restoreEntity = NClass::GetEntityOf<RestoreEntity>(env, funcArg.GetThisVar());
852 if (!(restoreEntity && (restoreEntity->sessionWhole || restoreEntity->sessionSheet))) {
853 HILOGE("Failed to get RestoreSession entity.");
854 NError(BError(BError::Codes::SDK_INVAL_ARG, "Failed to get RestoreSession entity.").GetCode()).ThrowErr(env);
855 return nullptr;
856 }
857 return [entity {restoreEntity}, bundleName {string(bundleName.get())}]() -> NError {
858 if (!(entity && (entity->sessionWhole || entity->sessionSheet))) {
859 return NError(BError(BError::Codes::SDK_INVAL_ARG, "restore session is nullptr").GetCode());
860 }
861 if (entity->sessionWhole) {
862 return NError(entity->sessionWhole->CleanBundleTempDir(bundleName));
863 }
864 return NError(entity->sessionSheet->CleanBundleTempDir(bundleName));
865 };
866 }
867
CleanBundleTempDir(napi_env env,napi_callback_info cbinfo)868 napi_value SessionRestoreNExporter::CleanBundleTempDir(napi_env env, napi_callback_info cbinfo)
869 {
870 HILOGI("Called SessionRestore::CleanBundleTempDir begin.");
871 if (!SAUtils::CheckBackupPermission()) {
872 HILOGE("Has not permission!");
873 NError(E_PERMISSION).ThrowErr(env);
874 return nullptr;
875 }
876 if (!SAUtils::IsSystemApp()) {
877 HILOGE("System App check fail!");
878 NError(E_PERMISSION_SYS).ThrowErr(env);
879 return nullptr;
880 }
881 NFuncArg funcArg(env, cbinfo);
882 if (!funcArg.InitArgs(NARG_CNT::ONE)) {
883 HILOGE("Number of arguments unmatched");
884 NError(E_PARAMS).ThrowErr(env);
885 return nullptr;
886 }
887 NVal jsBundleStr(env, funcArg[NARG_POS::FIRST]);
888 auto [succ, bundleName, sizeStr] = jsBundleStr.ToUTF8String();
889 if (!succ) {
890 HILOGE("First arguments is not string.");
891 NError(E_PARAMS).ThrowErr(env);
892 return nullptr;
893 }
894
895 auto cbExec = CleanBundleTempDirCBExec(env, funcArg, std::move(bundleName));
896 if (cbExec == nullptr) {
897 HILOGE("CleanBundleTempDirCBExec fail!");
898 return nullptr;
899 }
900 auto cbCompl = [](napi_env env, NError err) -> NVal {
901 return err ? NVal::CreateBool(env, false) : NVal::CreateBool(env, true);
902 };
903
904 NVal thisVar(env, funcArg.GetThisVar());
905 return NAsyncWorkPromise(env, thisVar).Schedule(className, cbExec, cbCompl).val_;
906 }
907
GetCompatibilityInfoCBExec(napi_env env,const NFuncArg & funcArg,string bundleName,string extInfo,shared_ptr<string> compatInfo)908 static NContextCBExec GetCompatibilityInfoCBExec(napi_env env, const NFuncArg &funcArg, string bundleName,
909 string extInfo, shared_ptr<string> compatInfo)
910 {
911 auto restoreEntity = NClass::GetEntityOf<RestoreEntity>(env, funcArg.GetThisVar());
912 if (!(restoreEntity && (restoreEntity->sessionWhole || restoreEntity->sessionSheet))) {
913 HILOGE("Failed to get RestoreSession entity.");
914 return nullptr;
915 }
916 return [entity {restoreEntity}, bundleName, extInfo, compatInfo]() -> NError {
917 if (!(entity && (entity->sessionWhole || entity->sessionSheet))) {
918 return NError(BError(BError::Codes::SDK_INVAL_ARG, "restore session is nullptr").GetCode());
919 }
920 if (entity->sessionWhole) {
921 return NError(entity->sessionWhole->GetCompatibilityInfo(bundleName, extInfo, *compatInfo));
922 }
923 return NError(entity->sessionSheet->GetCompatibilityInfo(bundleName, extInfo, *compatInfo));
924 };
925 }
926
ParseCompatInfoParam(napi_env env,NFuncArg & funcArg,string & bundleName,string & extInfo)927 static bool ParseCompatInfoParam(napi_env env, NFuncArg &funcArg, string &bundleName, string &extInfo)
928 {
929 if (!funcArg.InitArgs(NARG_CNT::TWO)) {
930 HILOGE("Number of arguments unmatched");
931 return false;
932 }
933 NVal jsBundleName(env, funcArg[NARG_POS::FIRST]);
934 auto [succ, bundleNamePtr, sizeStr] = jsBundleName.ToUTF8String();
935 if (!succ) {
936 HILOGE("First arguments is not string.");
937 return false;
938 }
939 NVal jsExtInfo(env, funcArg[NARG_POS::SECOND]);
940 auto [succ1, extInfoPtr, sizeStr1] = jsExtInfo.ToUTF8String();
941 if (!succ1) {
942 HILOGE("Second arguments is not string.");
943 return false;
944 }
945 bundleName = string(bundleNamePtr.get());
946 extInfo = string(extInfoPtr.get());
947 return true;
948 }
949
GetCompatibilityInfo(napi_env env,napi_callback_info cbinfo)950 napi_value SessionRestoreNExporter::GetCompatibilityInfo(napi_env env, napi_callback_info cbinfo)
951 {
952 HILOGI("Called SessionRestore::GetCompatibilityInfo begin.");
953 if (!SAUtils::CheckBackupPermission()) {
954 HILOGE("Has not permission!");
955 NError(E_PERMISSION).ThrowErr(env);
956 return nullptr;
957 }
958 if (!SAUtils::IsSystemApp()) {
959 HILOGE("System App check fail!");
960 NError(E_PERMISSION_SYS).ThrowErr(env);
961 return nullptr;
962 }
963
964 NFuncArg funcArg(env, cbinfo);
965 string bundleName;
966 string extInfo;
967 if (!ParseCompatInfoParam(env, funcArg, bundleName, extInfo)) {
968 NError(E_PARAMS).ThrowErr(env);
969 return nullptr;
970 }
971
972 auto compatInfo = std::make_shared<string>();
973 auto cbExec = GetCompatibilityInfoCBExec(env, funcArg, bundleName, extInfo, compatInfo);
974 if (cbExec == nullptr) {
975 NError(BError(BError::Codes::SDK_INVAL_ARG, "Failed to get RestoreSession entity.").GetCode()).ThrowErr(env);
976 return nullptr;
977 }
978 auto cbCompl = [compatInfo](napi_env env, NError err) -> NVal {
979 return err ? NVal {env, err.GetNapiErr(env)} : NVal::CreateUTF8String(env, *compatInfo);
980 };
981
982 NVal thisVar(env, funcArg.GetThisVar());
983 return NAsyncWorkPromise(env, thisVar).Schedule(className, cbExec, cbCompl).val_;
984 }
985
Export()986 bool SessionRestoreNExporter::Export()
987 {
988 HILOGD("called SessionRestoreNExporter::Export begin");
989 vector<napi_property_descriptor> props = {
990 NVal::DeclareNapiFunction("getLocalCapabilities", GetLocalCapabilities),
991 NVal::DeclareNapiFunction("appendBundles", AppendBundles),
992 NVal::DeclareNapiFunction("publishFile", PublishFile),
993 NVal::DeclareNapiFunction("getFileHandle", GetFileHandle),
994 NVal::DeclareNapiFunction("release", Release),
995 NVal::DeclareNapiFunction("cancel", Cancel),
996 NVal::DeclareNapiFunction("cleanBundleTempDir", CleanBundleTempDir),
997 NVal::DeclareNapiFunction("getCompatibilityInfo", GetCompatibilityInfo),
998 };
999
1000 auto [succ, classValue] = NClass::DefineClass(exports_.env_, className, Constructor, std::move(props));
1001 if (!succ) {
1002 HILOGE("Failed to define class");
1003 NError(EIO).ThrowErr(exports_.env_);
1004 return false;
1005 }
1006 succ = NClass::SaveClass(exports_.env_, className, classValue);
1007 if (!succ) {
1008 HILOGE("Failed to save class");
1009 NError(EIO).ThrowErr(exports_.env_);
1010 return false;
1011 }
1012
1013 HILOGD("called SessionRestoreNExporter::Export end");
1014 return exports_.AddProp(className, classValue);
1015 }
1016
GetClassName()1017 string SessionRestoreNExporter::GetClassName()
1018 {
1019 return SessionRestoreNExporter::className;
1020 }
1021
SessionRestoreNExporter(napi_env env,napi_value exports)1022 SessionRestoreNExporter::SessionRestoreNExporter(napi_env env, napi_value exports) : NExporter(env, exports) {}
1023
~SessionRestoreNExporter()1024 SessionRestoreNExporter::~SessionRestoreNExporter() {}
1025 } // namespace OHOS::FileManagement::Backup