diff --git a/interfaces/kits/ani/backup/BUILD.gn b/interfaces/kits/ani/backup/BUILD.gn index d554f928ea99ced17beeb467d1167f3f02f3cb75..1d90f61d734291790e772144a6d1598f332584a6 100644 --- a/interfaces/kits/ani/backup/BUILD.gn +++ b/interfaces/kits/ani/backup/BUILD.gn @@ -38,6 +38,8 @@ ohos_shared_library("ani_session_transfer") { "../../../common/src/json_utils.cpp", "src/backup_session_transfer.cpp", "src/backup_session.cpp", + "src/restore_session_transfer.cpp", + "src/restore_session.cpp", "src/incr_backup_session_transfer.cpp", "src/incremental_backup_session.cpp", "src/ani_constructor.cpp", diff --git a/interfaces/kits/ani/backup/ets/@ohos.backup.transfer.ets b/interfaces/kits/ani/backup/ets/@ohos.backup.transfer.ets index 0ff303f23f5667f6b94324af806d93758f66362f..05588d009e716ed83dbb7938e56329f3257365bc 100644 --- a/interfaces/kits/ani/backup/ets/@ohos.backup.transfer.ets +++ b/interfaces/kits/ani/backup/ets/@ohos.backup.transfer.ets @@ -43,6 +43,21 @@ export namespace backup { native clean(): void } + class RestoreSessionCleaner implements Cleaner { + static { + loadLibrary("ani_session_transfer"); + } + private session: long = 0 + private incrSession: long = 0 + private callbacks: long = 0 + constructor(session: long, incrSession: long, callbacks: long) { + this.session = session; + this.incrSession = incrSession; + this.callbacks = callbacks; + } + native clean(): void + } + export function callback(cleaner: Cleaner): void { cleaner.clean(); } @@ -57,6 +72,37 @@ export namespace backup { public backupPriority: int = 0; } + class RestoreSession { + public session: long = 0; + public incrSession: long = 0; + public callbacks: long = 0; + private cleaner: RestoreSessionCleaner | null = null; + constructor(session: long, incrSession: long, callbacks: long) { + this.session = session; + this.incrSession = incrSession; + this.callbacks = callbacks; + this.registerCleaner(); + } + registerCleaner(): void { + this.cleaner = new RestoreSessionCleaner(this.session, this.incrSession, this.callbacks); + destroyRegister.register(this, this.cleaner!, unregisterToken); + } + } + + class RestoreSessionTransfer { + static { + loadLibrary("ani_session_transfer"); + } + private static native transferStaticSession(input: ESValue): Object; + private static native transferDynamicSession(input: Object): ESValue; + static transferStatic(input: Any): Object { // 1.1(dynamic) => 1.2(static) + return RestoreSessionTransfer.transferStaticSession(ESValue.wrap(input)); + } + static transferDynamic(input: Object): Any { // 1.2 => 1.1 + return RestoreSessionTransfer.transferDynamicSession(input); + } + } + class BackupSession { public session: long = 0; public callbacks: long = 0; diff --git a/interfaces/kits/ani/backup/include/restore_session.h b/interfaces/kits/ani/backup/include/restore_session.h new file mode 100644 index 0000000000000000000000000000000000000000..a207d61c3b43235c0287a337539b93c5aa7a6b47 --- /dev/null +++ b/interfaces/kits/ani/backup/include/restore_session.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef RESTORE_SESSION_H +#define RESTORE_SESSION_H + +#include +#include +#include "b_incremental_restore_session.h" +#include "b_session_restore.h" +#include "general_callbacks.h" +#include "native_engine/native_engine.h" + +namespace OHOS::FileManagement::Backup { +class RestoreSession { +public: + ~RestoreSession() = default; + RestoreSession(const RestoreSession&) = delete; + RestoreSession(RestoreSession&&) = delete; + RestoreSession& operator=(const RestoreSession&) = delete; + RestoreSession& operator=(RestoreSession&&) = delete; + static void Init(ani_env *aniEnv); + + std::unique_ptr session; + std::unique_ptr incrSession; + std::shared_ptr callbacks; +}; + +class RestoreSessionCleaner { +public: + static void Clean(ani_env *aniEnv, ani_object object); +}; +} // namespace OHOS::FileManagement::Backup +#endif // RESTORE_SESSION_H \ No newline at end of file diff --git a/interfaces/kits/ani/backup/include/restore_session_transfer.h b/interfaces/kits/ani/backup/include/restore_session_transfer.h new file mode 100644 index 0000000000000000000000000000000000000000..d796db928f88660e3149f3327882767de87d36bd --- /dev/null +++ b/interfaces/kits/ani/backup/include/restore_session_transfer.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef RESTORE_SESSION_TRANSFER_H +#define RESTORE_SESSION_TRANSFER_H + +#include +#include +#include "native_engine/native_engine.h" + +namespace OHOS::FileManagement::Backup { +class RestoreSessionTransfer { +public: + RestoreSessionTransfer() = default; + ~RestoreSessionTransfer() = default; + + RestoreSessionTransfer(const RestoreSessionTransfer&) = delete; + RestoreSessionTransfer(RestoreSessionTransfer&&) = delete; + RestoreSessionTransfer& operator=(const RestoreSessionTransfer&) = delete; + RestoreSessionTransfer& operator=(RestoreSessionTransfer&&) = delete; + + static void Init(ani_env *aniEnv); + static ani_object TransferStaticSession(ani_env *aniEnv, ani_class aniCls, ani_object input); + static ani_ref TransferDynamicSession(ani_env *aniEnv, ani_class aniCls, ani_object input); +}; +} // namespace OHOS::FileManagement::Backup +#endif // RESTORE_SESSION_TRANSFER_H \ No newline at end of file diff --git a/interfaces/kits/ani/backup/src/ani_constructor.cpp b/interfaces/kits/ani/backup/src/ani_constructor.cpp index 1648bcf004c40768387f479584784b5edbd81eb2..c100ed4957da8ea1c805ac104ebc40983adf9092 100644 --- a/interfaces/kits/ani/backup/src/ani_constructor.cpp +++ b/interfaces/kits/ani/backup/src/ani_constructor.cpp @@ -18,6 +18,8 @@ #include "backup_session_transfer.h" #include "incremental_backup_session.h" #include "incr_backup_session_transfer.h" +#include "restore_session.h" +#include "restore_session_transfer.h" namespace OHOS::FileManagement::Backup { extern "C" { @@ -31,6 +33,8 @@ extern "C" { IncrementalBackupSession::Init(env); BackupSession::Init(env); BackupSessionTransfer::Init(env); + RestoreSession::Init(env); + RestoreSessionTransfer::Init(env); *result = ANI_VERSION_1; return ANI_OK; } diff --git a/interfaces/kits/ani/backup/src/backup_session.cpp b/interfaces/kits/ani/backup/src/backup_session.cpp index 7ef5ab86abe837247aba4d5f908a200eee59888f..bd52ac811b9978550251130a5a9bc6648688a1a4 100644 --- a/interfaces/kits/ani/backup/src/backup_session.cpp +++ b/interfaces/kits/ani/backup/src/backup_session.cpp @@ -29,7 +29,7 @@ namespace OHOS::FileManagement::Backup { using namespace LibN; namespace { -const char *BACKUP_SESSION_CLEANER_CLASS_NAME = "L@ohos/backup/transfer/backup/BackupSessionCleaner;"; +const char *RESTORE_SESSION_CLEANER_CLASS_NAME = "L@ohos/backup/transfer/backup/BackupSessionCleaner;"; } void BackupSession::Init(ani_env *aniEnv) @@ -39,7 +39,7 @@ void BackupSession::Init(ani_env *aniEnv) HILOGE("aniEnv is null"); return; } - ani_class clsCleaner = AniUtils::GetAniClsByName(aniEnv, BACKUP_SESSION_CLEANER_CLASS_NAME); + ani_class clsCleaner = AniUtils::GetAniClsByName(aniEnv, RESTORE_SESSION_CLEANER_CLASS_NAME); if (clsCleaner == nullptr) { return; } diff --git a/interfaces/kits/ani/backup/src/incr_backup_session_transfer.cpp b/interfaces/kits/ani/backup/src/incr_backup_session_transfer.cpp index 5112f269d67a01a59bd7baf0fe808b98438faafb..5b55e724aa9cb46e6840fa2dfb1111b1e29274b5 100644 --- a/interfaces/kits/ani/backup/src/incr_backup_session_transfer.cpp +++ b/interfaces/kits/ani/backup/src/incr_backup_session_transfer.cpp @@ -124,7 +124,7 @@ ani_ref IncreBackupSessionTransfer::TransferDynamicSession(ani_env *aniEnv, ani_ HILOGE("get field callbacks failed, ret:%{public}d", ret); return nullptr; } - IncrBackupEntity* entity = new IncrBackupEntity(); + std::unique_ptr entity = std::make_unique(); std::unique_ptr sessionPtr(reinterpret_cast(session)); entity->session = move(sessionPtr); std::shared_ptr callbackPtr(reinterpret_cast(callbacks)); @@ -132,23 +132,19 @@ ani_ref IncreBackupSessionTransfer::TransferDynamicSession(ani_env *aniEnv, ani_ napi_env jsEnv; if (!arkts_napi_scope_open(aniEnv, &jsEnv)) { HILOGE("Failed to arkts_napi_scope_open"); - delete entity; return nullptr; } - napi_value napiEntity = SessionIncrementalBackupNExporter::CreateByEntity(jsEnv, entity); + napi_value napiEntity = SessionIncrementalBackupNExporter::CreateByEntity(jsEnv, move(entity)); if (napiEntity == nullptr) { HILOGE("Failed to create napi obj"); - delete entity; return nullptr; } ani_ref outObj; if (!arkts_napi_scope_close_n(jsEnv, 1, &napiEntity, &outObj)) { HILOGE("Failed to arkts_napi_scope_close_n"); - delete entity; return nullptr; } HILOGD("TransferDynamicSession end"); - delete entity; return outObj; } } diff --git a/interfaces/kits/ani/backup/src/restore_session.cpp b/interfaces/kits/ani/backup/src/restore_session.cpp new file mode 100644 index 0000000000000000000000000000000000000000..239f48633f486d2e3c6d26670895f7a7be21c2a2 --- /dev/null +++ b/interfaces/kits/ani/backup/src/restore_session.cpp @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "restore_session.h" +#include +#include +#include +#include +#include "ani_utils.h" +#include "b_sa/b_sa_utils.h" +#include "filemgmt_libhilog.h" +#include "napi/native_api.h" +#include "napi/native_node_api.h" +#include "native_engine/native_engine.h" + +namespace OHOS::FileManagement::Backup { +using namespace LibN; + +namespace { +const char *RESTORE_SESSION_CLEANER_CLASS_NAME = "L@ohos/backup/transfer/backup/RestoreSessionCleaner;"; +} + +void RestoreSession::Init(ani_env *aniEnv) +{ + HILOGD("Init RestoreSession begin"); + if (aniEnv == nullptr) { + HILOGE("aniEnv is null"); + return; + } + ani_class clsCleaner = AniUtils::GetAniClsByName(aniEnv, RESTORE_SESSION_CLEANER_CLASS_NAME); + if (clsCleaner == nullptr) { + return; + } + std::array cleanNativeFuncs = { + ani_native_function {"clean", ":V", reinterpret_cast(RestoreSessionCleaner::Clean)}, + }; + auto status = aniEnv->Class_BindNativeMethods(clsCleaner, cleanNativeFuncs.data(), cleanNativeFuncs.size()); + if (status != ANI_OK) { + HILOGE("Class_BindNativeMethods failed status: %{public}d", status); + return; + } + HILOGD("Init RestoreSession end"); +} + +void RestoreSessionCleaner::Clean(ani_env *aniEnv, ani_object object) +{ + if (aniEnv == nullptr) { + HILOGE("aniEnv is null"); + return; + } + ani_status ret = ANI_ERROR; + ani_long session {}; + if ((ret = aniEnv->Object_GetPropertyByName_Long(object, "session", &session)) != ANI_OK) { + HILOGE("get field session failed, ret:%{public}d", ret); + } else { + BSessionRestore* sessionPtr = reinterpret_cast(session); + if (sessionPtr != nullptr) { + delete sessionPtr; + } + } + ani_long incrSession {}; + if ((ret = aniEnv->Object_GetPropertyByName_Long(object, "incrSession", &incrSession)) != ANI_OK) { + HILOGE("get field incrSession failed, ret:%{public}d", ret); + } else { + BIncrementalRestoreSession* incrSessionPtr = reinterpret_cast(incrSession); + if (incrSessionPtr != nullptr) { + delete incrSessionPtr; + } + } + ani_long callbacks {}; + if ((ret = aniEnv->Object_GetPropertyByName_Long(object, "callbacks", &callbacks)) != ANI_OK) { + HILOGE("get field callbacks failed, ret:%{public}d", ret); + } else { + GeneralCallbacks* callbackPtr = reinterpret_cast(callbacks); + if (callbackPtr != nullptr) { + delete callbackPtr; + } + } +} +} \ No newline at end of file diff --git a/interfaces/kits/ani/backup/src/restore_session_transfer.cpp b/interfaces/kits/ani/backup/src/restore_session_transfer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ea07875fbf2886c8491a744b2f0cfb333461b4fd --- /dev/null +++ b/interfaces/kits/ani/backup/src/restore_session_transfer.cpp @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "restore_session_transfer.h" + +#include +#include +#include +#include +#include +#include "interop_js/arkts_interop_js_api.h" +#include "interop_js/arkts_esvalue.h" +#include "filemgmt_libhilog.h" +#include "ani_utils.h" +#include "restore_session.h" +#include "napi/native_api.h" +#include "napi/native_node_api.h" +#include "native_engine/native_engine.h" +#include "session_restore_n_exporter.h" + +namespace OHOS::FileManagement::Backup { +namespace { +const char *RESTORE_SESSION_TRANSFER_CLASS_NAME = "L@ohos/backup/transfer/backup/RestoreSessionTransfer;"; +const char *RESTORE_SESSION_CLASS_NAME = "L@ohos/backup/transfer/backup/RestoreSession;"; +} + +void RestoreSessionTransfer::Init(ani_env *aniEnv) +{ + HILOGD("Init transfer native method begin"); + if (aniEnv == nullptr) { + HILOGE("aniEnv is null"); + return; + } + ani_class cls = AniUtils::GetAniClsByName(aniEnv, RESTORE_SESSION_TRANSFER_CLASS_NAME); + if (cls == nullptr) { + return; + } + std::array nativeFuncs = { + ani_native_function { "transferStaticSession", nullptr, + reinterpret_cast(RestoreSessionTransfer::TransferStaticSession)}, + ani_native_function { "transferDynamicSession", nullptr, + reinterpret_cast(RestoreSessionTransfer::TransferDynamicSession)}, + }; + int32_t status = aniEnv->Class_BindStaticNativeMethods(cls, nativeFuncs.data(), nativeFuncs.size()); + if (status != ANI_OK) { + HILOGE("Class_BindNativeMethods failed status: %{public}d", status); + return; + } + HILOGD("Init transfer native method end"); +} + +ani_object RestoreSessionTransfer::TransferStaticSession(ani_env *aniEnv, ani_class aniCls, ani_object input) +{ + HILOGD("Transfer RestoreSession Static begin"); + if (aniEnv == nullptr) { + HILOGE("aniEnv is null"); + return nullptr; + } + + void *unwrapResult = nullptr; + bool unwrapRet = arkts_esvalue_unwrap(aniEnv, input, &unwrapResult); + if (!unwrapRet) { + HILOGE("Failed to unwrap"); + return nullptr; + } + if (unwrapResult == nullptr) { + HILOGE("UnwrapResult is nullptr"); + return nullptr; + } + RestoreSession* entity = reinterpret_cast(unwrapResult); + ani_class cls = AniUtils::GetAniClsByName(aniEnv, RESTORE_SESSION_CLASS_NAME); + if (cls == nullptr) { + HILOGE("Call FindClass failed"); + return nullptr; + } + ani_method constructFunc; + ani_status ret = ANI_ERROR; + if ((ret = aniEnv->Class_FindMethod(cls, "", nullptr, &constructFunc)) != ANI_OK) { + HILOGE("Call Class_FindMethod failed, ret = %{public}d", ret); + return nullptr; + } + ani_object outObj; + ret = aniEnv->Object_New(cls, constructFunc, &outObj, entity->session.release(), + entity->incrSession.release(), entity->callbacks.get()); + if (ret != ANI_OK) { + HILOGE("Call Object_New failed, ret = %{public}d", ret); + return nullptr; + } + HILOGD("Transfer RestoreSession Static end"); + return outObj; +} + +ani_ref RestoreSessionTransfer::TransferDynamicSession(ani_env *aniEnv, ani_class aniCls, ani_object input) +{ + HILOGD("TransferDynamicSession start"); + if (aniEnv == nullptr) { + HILOGE("aniEnv is null"); + return nullptr; + } + // 1.2->1.1 + ani_status ret = ANI_ERROR; + ani_long session {}; + if ((ret = aniEnv->Object_GetPropertyByName_Long(input, "session", &session)) != ANI_OK) { + HILOGE("get field session failed, ret:%{public}d", ret); + return nullptr; + } + ani_long incrSession {}; + if ((ret = aniEnv->Object_GetPropertyByName_Long(input, "incrSession", &incrSession)) != ANI_OK) { + HILOGE("get field incrSession failed, ret:%{public}d", ret); + return nullptr; + } + ani_long callbacks {}; + if ((ret = aniEnv->Object_GetPropertyByName_Long(input, "callbacks", &callbacks)) != ANI_OK) { + HILOGE("get field callbacks failed, ret:%{public}d", ret); + return nullptr; + } + std::unique_ptr entity = std::make_unique(); + std::unique_ptr sessionPtr(reinterpret_cast(session)); + entity->sessionWhole = move(sessionPtr); + std::unique_ptr + incrSessionPtr(reinterpret_cast(incrSession)); + entity->sessionSheet = move(incrSessionPtr); + std::shared_ptr callbackPtr(reinterpret_cast(callbacks)); + entity->callbacks = callbackPtr; + napi_env jsEnv; + if (!arkts_napi_scope_open(aniEnv, &jsEnv)) { + HILOGE("Failed to arkts_napi_scope_open"); + return nullptr; + } + napi_value napiEntity = SessionRestoreNExporter::CreateByEntity(jsEnv, move(entity)); + if (napiEntity == nullptr) { + HILOGE("Failed to create napi obj"); + return nullptr; + } + ani_ref outObj; + if (!arkts_napi_scope_close_n(jsEnv, 1, &napiEntity, &outObj)) { + HILOGE("Failed to arkts_napi_scope_close_n"); + return nullptr; + } + HILOGD("TransferDynamicSession end"); + return outObj; +} +} \ No newline at end of file diff --git a/interfaces/kits/js/backup/session_backup_n_exporter.cpp b/interfaces/kits/js/backup/session_backup_n_exporter.cpp index c1de836aa50874add91fd60c416c8b9feb23defb..6d4989971219ee65ced63af3d9022cb036434f49 100644 --- a/interfaces/kits/js/backup/session_backup_n_exporter.cpp +++ b/interfaces/kits/js/backup/session_backup_n_exporter.cpp @@ -807,8 +807,10 @@ napi_value SessionBackupNExporter::CreateByEntity(napi_env env, std::unique_ptr< } entity->callbacks->RemoveCallbackRef(); }; - if (napi_ok != napi_create_external(env, (void *)entity.release(), finalize, nullptr, &napiEntity)) { + BackupEntity* entityPtr = entity.release(); + if (napi_ok != napi_create_external(env, (void *)entityPtr, finalize, nullptr, &napiEntity)) { HILOGE("wrap entity prt fail"); + delete entityPtr; return nullptr; } size_t argc = 1; diff --git a/interfaces/kits/js/backup/session_incremental_backup_n_exporter.cpp b/interfaces/kits/js/backup/session_incremental_backup_n_exporter.cpp index a0c496810ddf62d5f7e4f7d5bcd7a674cadb988f..e6606f8d0497e45fe6a0270a0f7ef16dfab7c02f 100644 --- a/interfaces/kits/js/backup/session_incremental_backup_n_exporter.cpp +++ b/interfaces/kits/js/backup/session_incremental_backup_n_exporter.cpp @@ -775,7 +775,7 @@ napi_value SessionIncrementalBackupNExporter::ConstructorFromEntity(napi_env env return funcArg.GetThisVar(); } -napi_value SessionIncrementalBackupNExporter::CreateByEntity(napi_env env, IncrBackupEntity* entity) +napi_value SessionIncrementalBackupNExporter::CreateByEntity(napi_env env, std::unique_ptr entity) { HILOGD("CreateByEntity begin"); if (entity == nullptr) { @@ -790,8 +790,7 @@ napi_value SessionIncrementalBackupNExporter::CreateByEntity(napi_env env, IncrB NVal::DeclareNapiFunction("cancel", Cancel), NVal::DeclareNapiFunction("cleanBundleTempDir", CleanBundleTempDir), }; - auto [defRet, constroctor] = NClass::DefineClass(env, NAPI_CLASS_NAME, ConstructorFromEntity, - std::move(props)); + auto [defRet, constroctor] = NClass::DefineClass(env, NAPI_CLASS_NAME, ConstructorFromEntity, std::move(props)); if (!defRet) { HILOGE("Failed to define class"); return nullptr; @@ -811,8 +810,10 @@ napi_value SessionIncrementalBackupNExporter::CreateByEntity(napi_env env, IncrB } entity->callbacks->RemoveCallbackRef(); }; - if (napi_ok != napi_create_external(env, (void *)entity, finalize, nullptr, &napiEntity)) { + IncrBackupEntity* entityPtr = entity.release(); + if (napi_ok != napi_create_external(env, (void *)entityPtr, finalize, nullptr, &napiEntity)) { HILOGE("wrap entity prt fail"); + delete entityPtr; return nullptr; } size_t argc = 1; diff --git a/interfaces/kits/js/backup/session_incremental_backup_n_exporter.h b/interfaces/kits/js/backup/session_incremental_backup_n_exporter.h index a75655e8f5bdd9ccbf5fbcdf7981a08ecffd98b5..e87010ac81c6764f013732f3ecf65c6709c4774f 100644 --- a/interfaces/kits/js/backup/session_incremental_backup_n_exporter.h +++ b/interfaces/kits/js/backup/session_incremental_backup_n_exporter.h @@ -41,7 +41,7 @@ public: static napi_value CleanBundleTempDir(napi_env env, napi_callback_info cbinfo); static napi_value ConstructorFromEntity(napi_env env, napi_callback_info cbinfo); - static napi_value CreateByEntity(napi_env env, IncrBackupEntity* entity); + static napi_value CreateByEntity(napi_env env, std::unique_ptr entity); SessionIncrementalBackupNExporter(napi_env env, napi_value exports); ~SessionIncrementalBackupNExporter() override; diff --git a/interfaces/kits/js/backup/session_restore_n_exporter.cpp b/interfaces/kits/js/backup/session_restore_n_exporter.cpp index b57a9b27107490108e9e05971b4ecbb489e7000d..134e35321a23c698e5452ae995ce034c19c6f967 100644 --- a/interfaces/kits/js/backup/session_restore_n_exporter.cpp +++ b/interfaces/kits/js/backup/session_restore_n_exporter.cpp @@ -15,31 +15,23 @@ #include "session_restore_n_exporter.h" #include -#include #include #include "b_error/b_error.h" #include "b_filesystem/b_dir.h" #include "b_filesystem/b_file.h" -#include "b_incremental_restore_session.h" #include "b_ohos/startup/backup_para.h" #include "b_resources/b_constants.h" #include "b_sa/b_sa_utils.h" -#include "b_session_restore.h" #include "backup_kit_inner.h" #include "filemgmt_libhilog.h" -#include "general_callbacks.h" #include "service_proxy.h" namespace OHOS::FileManagement::Backup { using namespace std; using namespace LibN; -struct RestoreEntity { - unique_ptr sessionWhole; - unique_ptr sessionSheet; - shared_ptr callbacks; -}; +static const std::string NAPI_CLASS_NAME = "NapiSessionRestore"; static void OnFileReadySheet(weak_ptr pCallbacks, const BFileInfo &fileInfo, UniqueFd fd, UniqueFd manifestFd, int32_t sysErrno) @@ -935,6 +927,100 @@ bool SessionRestoreNExporter::Export() return exports_.AddProp(className, classValue); } + +napi_value SessionRestoreNExporter::ConstructorFromEntity(napi_env env, napi_callback_info cbinfo) +{ + HILOGD("called ConstructorFromEntity begin"); + if (!SAUtils::CheckBackupPermission()) { + NError(E_PERMISSION).ThrowErr(env); + return nullptr; + } + if (!SAUtils::IsSystemApp()) { + NError(E_PERMISSION_SYS).ThrowErr(env); + return nullptr; + } + NFuncArg funcArg(env, cbinfo); + if (!funcArg.InitArgs(NARG_CNT::ONE)) { + NError(BError(BError::Codes::SDK_INVAL_ARG, "Number of arguments unmatched.").GetCode()).ThrowErr(env); + return nullptr; + } + void* entityRawPtr = nullptr; + if (napi_ok != napi_get_value_external(env, funcArg[NARG_POS::FIRST], &entityRawPtr)) { + NError(BError(BError::Codes::SDK_INVAL_ARG, "parse entity raw ptr fail.").GetCode()).ThrowErr(env); + return nullptr; + } + RestoreEntity* entity = reinterpret_cast(entityRawPtr); + if (entity == nullptr) { + NError(BError(BError::Codes::SDK_INVAL_ARG, "First argument is not session pointer.").GetCode()).ThrowErr(env); + return nullptr; + } + std::unique_ptr restoreEntity(entity); + if ((restoreEntity->sessionWhole == nullptr && restoreEntity->sessionSheet == nullptr) || + restoreEntity->callbacks == nullptr) { + NError(BError(BError::Codes::SDK_INVAL_ARG, "session or callback is null.").GetCode()).ThrowErr(env); + return nullptr; + } + if (!SetSessionRestoreEntity(env, funcArg, std::move(restoreEntity))) { + NError(BError(BError::Codes::SDK_INVAL_ARG, "Failed to set RestoreEntity entity.").GetCode()).ThrowErr(env); + return nullptr; + } + HILOGD("called ConstructorFromEntity end"); + return funcArg.GetThisVar(); +} + +napi_value SessionRestoreNExporter::CreateByEntity(napi_env env, std::unique_ptr entity) +{ + HILOGD("CreateByEntity begin"); + if (entity == nullptr) { + HILOGE("entity is null"); + return nullptr; + } + vector props = { + NVal::DeclareNapiFunction("getLocalCapabilities", GetLocalCapabilities), + NVal::DeclareNapiFunction("getFileHandle", GetFileHandle), + NVal::DeclareNapiFunction("appendBundles", AppendBundles), + NVal::DeclareNapiFunction("publishFile", PublishFile), + NVal::DeclareNapiFunction("release", Release), + NVal::DeclareNapiFunction("cancel", Cancel), + NVal::DeclareNapiFunction("cleanBundleTempDir", CleanBundleTempDir), + }; + auto [defRet, constroctor] = NClass::DefineClass(env, NAPI_CLASS_NAME, ConstructorFromEntity, std::move(props)); + if (!defRet) { + HILOGE("Failed to define class"); + return nullptr; + } + napi_value instance; + napi_value napiEntity; + auto finalize = [](napi_env env, void *data, void *hint) { + std::unique_ptr entity(static_cast(data)); + if (entity == nullptr) { + HILOGE("Entity is nullptr"); + return; + } + if (entity->callbacks == nullptr) { + HILOGE("Callbacks is nullptr"); + return; + } + entity->callbacks->RemoveCallbackRef(); + }; + RestoreEntity* entityPtr = entity.release(); + if (napi_ok != napi_create_external(env, (void *)entityPtr, finalize, nullptr, &napiEntity)) { + HILOGE("wrap entity prt fail"); + delete entityPtr; + return nullptr; + } + size_t argc = 1; + napi_value args[1] = { napiEntity }; + + napi_status napiStatus = napi_new_instance(env, constroctor, argc, args, &instance); + if (napi_status::napi_ok != napiStatus) { + HILOGE("Failed to napi_new_instance, status=%{public}d", napiStatus); + return nullptr; + } + HILOGD("CreateByEntity end"); + return instance; +} + string SessionRestoreNExporter::GetClassName() { return SessionRestoreNExporter::className; diff --git a/interfaces/kits/js/backup/session_restore_n_exporter.h b/interfaces/kits/js/backup/session_restore_n_exporter.h index 12a40fca8a98920d8b466a79b9331e036dbec53b..70c62f43e765d403794617e53af01822dbd0ddf1 100644 --- a/interfaces/kits/js/backup/session_restore_n_exporter.h +++ b/interfaces/kits/js/backup/session_restore_n_exporter.h @@ -16,11 +16,22 @@ #define INTERFACES_KITS_JS_SRC_MOD_BACKUP_PROPERTIES_SESSION_RESTORE_N_EXPORTER_H #include +#include #include +#include "b_incremental_restore_session.h" +#include "b_session_restore.h" #include "filemgmt_libn.h" +#include "general_callbacks.h" + namespace OHOS::FileManagement::Backup { +struct RestoreEntity { + std::unique_ptr sessionWhole; + std::unique_ptr sessionSheet; + std::shared_ptr callbacks; +}; + class SessionRestoreNExporter final : public LibN::NExporter { public: inline static const std::string className = "SessionRestore"; @@ -37,6 +48,9 @@ public: static napi_value Cancel(napi_env env, napi_callback_info cbinfo); static napi_value CleanBundleTempDir(napi_env env, napi_callback_info cbinfo); + static napi_value ConstructorFromEntity(napi_env env, napi_callback_info cbinfo); + static napi_value CreateByEntity(napi_env env, std::unique_ptr entity); + SessionRestoreNExporter(napi_env env, napi_value exports); ~SessionRestoreNExporter() override; };