diff --git a/bundle.json b/bundle.json index 4e053079943df38a3960c495baebc94cefbd9d9a..8608ce2cae9be7f07f60992ccdee90ac759f0e3b 100644 --- a/bundle.json +++ b/bundle.json @@ -71,7 +71,8 @@ "//foundation/filemanagement/app_file_service/interfaces/kits/ani/file_share:fileshare_ani_package", "//foundation/filemanagement/app_file_service/interfaces/kits/ani/file_uri:fileuri_ani_package", "//foundation/filemanagement/app_file_service/interfaces/kits/ndk/fileuri/src:ohfileuri", - "//foundation/filemanagement/app_file_service/interfaces/kits/ndk/fileshare/src:ohfileshare" + "//foundation/filemanagement/app_file_service/interfaces/kits/ndk/fileshare/src:ohfileshare", + "//foundation/filemanagement/app_file_service/frameworks/native/backup_ext/ani:backup_ext_ani_package" ], "service_group": [ "//foundation/filemanagement/app_file_service:tgt_backup_extension", diff --git a/frameworks/native/backup_ext/ani/BUILD.gn b/frameworks/native/backup_ext/ani/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..098ebf899e4b0d25c12757f3c9deb067b8e99361 --- /dev/null +++ b/frameworks/native/backup_ext/ani/BUILD.gn @@ -0,0 +1,62 @@ +# 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. + +import("//build/config/components/ets_frontend/ets2abc_config.gni") +import("//build/ohos.gni") +import("//foundation/filemanagement/app_file_service/backup.gni") + +group("backup_ext_ani_package") { + deps = [ ":backup_ext_ani" ] +} + +ohos_shared_library("backup_ext_ani") { + sanitize = { + integer_overflow = true + ubsan = true + boundary_sanitize = true + cfi = true + cfi_cross_dso = true + debug = false + } + + sources = [ "src/ext_backup_ani.cpp" ] + + include_dirs = [ + "include", + "../include", + ] + + deps = [ "${path_backup}/utils:backup_utils" ] + + external_deps = [ + "ability_base:want", + "ability_runtime:ability_context_native", + "ability_runtime:abilitykit_native", + "ability_runtime:app_context", + "ability_runtime:appkit_native", + "ability_runtime:extensionkit_native", + "ability_runtime:runtime", + "access_token:libaccesstoken_sdk", + "bundle_framework:appexecfwk_core", + "c_utils:utils", + "hilog:libhilog", + "hitrace:hitrace_meter", + "ipc:ipc_core", + "runtime_core:ani", + "samgr:samgr_proxy", + ] + + subsystem_name = "filemanagement" + part_name = "app_file_service" + output_extension = "so" +} diff --git a/frameworks/native/backup_ext/ani/ets/@ohos.application.BackupExtensionAbility.ets b/frameworks/native/backup_ext/ani/ets/@ohos.application.BackupExtensionAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..aeafebc7304d2d63b823f835ba3c4e8400a298ac --- /dev/null +++ b/frameworks/native/backup_ext/ani/ets/@ohos.application.BackupExtensionAbility.ets @@ -0,0 +1,30 @@ +/* + * 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. + */ + + +export interface BundleVersion { + public code: number; + public name: string; +} + +class BundleVersionInner extends BundleVersion { + public code: number; + public name: string; +} + +export default class BackupExtensionAbility { + onBackup(): void; + onRestore(bundleVersion: BundleVersion): void; +} \ No newline at end of file diff --git a/frameworks/native/backup_ext/ani/include/ani_utils.h b/frameworks/native/backup_ext/ani/include/ani_utils.h new file mode 100644 index 0000000000000000000000000000000000000000..6ce270f0c81e39a03338154d07245afb2ef25ed5 --- /dev/null +++ b/frameworks/native/backup_ext/ani/include/ani_utils.h @@ -0,0 +1,445 @@ +/* + * 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 ANI_UTILS_H +#define ANI_UTILS_H + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +class AniObjectUtils { +public: + static ani_object Create(ani_env *env, const char *nsName, const char *clsName, ...) + { + ani_object nullobj {}; + + ani_namespace ns; + if (ANI_OK != env->FindNamespace(nsName, &ns)) { + std::cerr << "[ANI] Not found namespace " << nsName << std::endl; + return nullobj; + } + + ani_class cls; + if (ANI_OK != env->Namespace_FindClass(ns, clsName, &cls)) { + std::cerr << "[ANI] Not found class " << clsName << std::endl; + return nullobj; + } + + ani_method ctor; + if (ANI_OK != env->Class_FindMethod(cls, "", nullptr, &ctor)) { + std::cerr << "[ANI] Not found for class " << clsName << std::endl; + return nullobj; + } + + std::cerr << "[ANI] AniObjectUtils Object_New_V " << clsName << std::endl; + ani_object obj; + va_list args; + va_start(args, clsName); + ani_status status = env->Object_New_V(cls, ctor, &obj, args); + va_end(args); + if (ANI_OK != status) { + std::cerr << "[ANI] Failed to Object_New for class " << cls << std::endl; + return nullobj; + } + return obj; + } + + static ani_object Create(ani_env *env, const char *clsName, ...) + { + ani_object nullobj {}; + + ani_class cls; + if (ANI_OK != env->FindClass(clsName, &cls)) { + std::cerr << "[ANI] Not found class " << clsName << std::endl; + return nullobj; + } + + ani_method ctor; + if (ANI_OK != env->Class_FindMethod(cls, "", nullptr, &ctor)) { + std::cerr << "[ANI] Not found for class " << clsName << std::endl; + return nullobj; + } + + ani_object obj; + va_list args; + va_start(args, clsName); + ani_status status = env->Object_New_V(cls, ctor, &obj, args); + va_end(args); + if (ANI_OK != status) { + std::cerr << "[ANI] Failed to Object_New for class " << cls << std::endl; + return nullobj; + } + return obj; + } + + static ani_object Create(ani_env *env, ani_class cls, ...) + { + ani_object nullobj {}; + + ani_method ctor; + if (ANI_OK != env->Class_FindMethod(cls, "", nullptr, &ctor)) { + std::cerr << "[ANI] Not found for class" << std::endl; + return nullobj; + } + + ani_object obj; + va_list args; + va_start(args, cls); + ani_status status = env->Object_New_V(cls, ctor, &obj, args); + va_end(args); + if (ANI_OK != status) { + std::cerr << "[ANI] Failed to Object_New for class " << cls << std::endl; + return nullobj; + } + return obj; + } + + template + static ani_status Wrap(ani_env *env, ani_object object, T *nativePtr, const char *propName = "nativePtr") + { + return env->Object_SetFieldByName_Long(object, propName, reinterpret_cast(nativePtr)); + } + + template + static T *Unwrap(ani_env *env, ani_object object, const char *propName = "nativePtr") + { + ani_long nativePtr; + if (ANI_OK != env->Object_GetFieldByName_Long(object, propName, &nativePtr)) { + return nullptr; + } + return reinterpret_cast(nativePtr); + } +}; + +class AniStringUtils { +public: + static std::string ToStd(ani_env *env, ani_string ani_str) + { + ani_size strSize; + env->String_GetUTF8Size(ani_str, &strSize); + + std::vector buffer(strSize + 1); // +1 for null terminator + char *utf8_buffer = buffer.data(); + + // String_GetUTF8 Supportted by https://gitee.com/openharmony/arkcompiler_runtime_core/pulls/3416 + ani_size bytes_written = 0; + env->String_GetUTF8(ani_str, utf8_buffer, strSize + 1, &bytes_written); + + utf8_buffer[bytes_written] = '\0'; + std::string content = std::string(utf8_buffer); + return content; + } + + static ani_string ToAni(ani_env *env, const std::string &str) + { + ani_string aniStr = nullptr; + if (ANI_OK != env->String_NewUTF8(str.data(), str.size(), &aniStr)) { + std::cerr << "[ANI] Unsupported ANI_VERSION_1" << std::endl; + return nullptr; + } + return aniStr; + } +}; + +class UnionAccessor { +public: + UnionAccessor(ani_env *env, ani_object &obj) : env_(env), obj_(obj) {} + + bool IsInstanceOf(const std::string &cls_name) + { + ani_class cls; + env_->FindClass(cls_name.c_str(), &cls); + + ani_boolean ret; + env_->Object_InstanceOf(obj_, cls, &ret); + return ret; + } + + template + bool IsInstanceOfType(); + + template + bool TryConvert(T &value); + + template + bool TryConvertArray(std::vector &value); + +private: + ani_env *env_; + ani_object obj_; +}; + +template <> +bool UnionAccessor::IsInstanceOfType() +{ + return IsInstanceOf("Lstd/core/Boolean;"); +} + +template <> +bool UnionAccessor::IsInstanceOfType() +{ + return IsInstanceOf("Lstd/core/Int;"); +} + +template <> +bool UnionAccessor::IsInstanceOfType() +{ + return IsInstanceOf("Lstd/core/Double;"); +} + +template <> +bool UnionAccessor::IsInstanceOfType() +{ + return IsInstanceOf("Lstd/core/String;"); +} + +template <> +bool UnionAccessor::TryConvert(bool &value) +{ + if (!IsInstanceOfType()) { + return false; + } + + ani_boolean aniValue; + auto ret = env_->Object_CallMethodByName_Boolean(obj_, "unboxed", nullptr, &aniValue); + if (ret != ANI_OK) { + return false; + } + value = static_cast(aniValue); + return true; +} + +template <> +bool UnionAccessor::TryConvert(int &value) +{ + if (!IsInstanceOfType()) { + return false; + } + + ani_int aniValue; + auto ret = env_->Object_CallMethodByName_Int(obj_, "unboxed", nullptr, &aniValue); + if (ret != ANI_OK) { + return false; + } + value = static_cast(aniValue); + return true; +} + +template <> +bool UnionAccessor::TryConvert(double &value) +{ + if (!IsInstanceOfType()) { + return false; + } + + ani_double aniValue; + auto ret = env_->Object_CallMethodByName_Double(obj_, "unboxed", nullptr, &aniValue); + if (ret != ANI_OK) { + return false; + } + value = static_cast(aniValue); + return true; +} + +template <> +bool UnionAccessor::TryConvert(std::string &value) +{ + if (!IsInstanceOfType()) { + return false; + } + + value = AniStringUtils::ToStd(env_, static_cast(obj_)); + return true; +} + +template <> +bool UnionAccessor::TryConvertArray(std::vector &value) +{ + ani_double length; + if (ANI_OK != env_->Object_GetPropertyByName_Double(obj_, "length", &length)) { + std::cerr << "Object_GetPropertyByName_Double length failed" << std::endl; + return false; + } + for (int i = 0; i < int(length); i++) { + ani_ref ref; + if (ANI_OK != env_->Object_CallMethodByName_Ref(obj_, "$_get", "I:Lstd/core/Object;", &ref, (ani_int)i)) { + std::cerr << "Object_GetPropertyByName_Ref failed" << std::endl; + return false; + } + ani_boolean val; + if (ANI_OK != env_->Object_CallMethodByName_Boolean(static_cast(ref), "unboxed", nullptr, &val)) { + std::cerr << "Object_CallMethodByName_Double unbox failed" << std::endl; + return false; + } + value.push_back(static_cast(val)); + } + return true; +} + +template <> +bool UnionAccessor::TryConvertArray(std::vector &value) +{ + ani_double length; + if (ANI_OK != env_->Object_GetPropertyByName_Double(obj_, "length", &length)) { + std::cerr << "Object_GetPropertyByName_Double length failed" << std::endl; + return false; + } + for (int i = 0; i < int(length); i++) { + ani_ref ref; + if (ANI_OK != env_->Object_CallMethodByName_Ref(obj_, "$_get", "I:Lstd/core/Object;", &ref, (ani_int)i)) { + std::cerr << "Object_GetPropertyByName_Ref failed" << std::endl; + return false; + } + ani_int intValue; + if (ANI_OK != env_->Object_CallMethodByName_Int(static_cast(ref), "unboxed", nullptr, &intValue)) { + std::cerr << "Object_CallMethodByName_Double unbox failed" << std::endl; + return false; + } + value.push_back(static_cast(intValue)); + } + return true; +} + +template <> +bool UnionAccessor::TryConvertArray(std::vector &value) +{ + ani_double length; + if (ANI_OK != env_->Object_GetPropertyByName_Double(obj_, "length", &length)) { + std::cerr << "Object_GetPropertyByName_Double length failed" << std::endl; + return false; + } + for (int i = 0; i < int(length); i++) { + ani_ref ref; + if (ANI_OK != env_->Object_CallMethodByName_Ref(obj_, "$_get", "I:Lstd/core/Object;", &ref, (ani_int)i)) { + std::cerr << "Object_GetPropertyByName_Ref failed" << std::endl; + return false; + } + ani_double val; + if (ANI_OK != env_->Object_CallMethodByName_Double(static_cast(ref), "unboxed", nullptr, &val)) { + std::cerr << "Object_CallMethodByName_Double unbox failed" << std::endl; + return false; + } + value.push_back(static_cast(val)); + } + return true; +} + +template <> +bool UnionAccessor::TryConvertArray(std::vector &value) +{ + std::cout << "TryConvertArray std::vector" << std::endl; + ani_ref buffer; + if (ANI_OK != env_->Object_GetFieldByName_Ref(obj_, "buffer", &buffer)) { + std::cout << "Object_GetFieldByName_Ref failed" << std::endl; + return false; + } + void *data; + size_t length; + if (ANI_OK != env_->ArrayBuffer_GetInfo(static_cast(buffer), &data, &length)) { + std::cerr << "ArrayBuffer_GetInfo failed" << std::endl; + return false; + } + std::cout << "Length of buffer is " << length << std::endl; + for (size_t i = 0; i < length; i++) { + value.push_back(static_cast(data)[i]); + } + return true; +} + +template <> +bool UnionAccessor::TryConvertArray(std::vector &value) +{ + ani_double length; + if (ANI_OK != env_->Object_GetPropertyByName_Double(obj_, "length", &length)) { + std::cerr << "Object_GetPropertyByName_Double length failed" << std::endl; + return false; + } + + for (int i = 0; i < int(length); i++) { + ani_ref ref; + if (ANI_OK != env_->Object_CallMethodByName_Ref(obj_, "$_get", "I:Lstd/core/Object;", &ref, (ani_int)i)) { + std::cerr << "Object_GetPropertyByName_Double length failed" << std::endl; + return false; + } + value.push_back(AniStringUtils::ToStd(env_, static_cast(ref))); + } + return true; +} + +class OptionalAccessor { +public: + OptionalAccessor(ani_env *env, ani_object &obj) : env_(env), obj_(obj) {} + + bool IsUndefined() + { + ani_boolean isUndefined; + env_->Reference_IsUndefined(obj_, &isUndefined); + return isUndefined; + } + + template + std::optional Convert(); + +private: + ani_env *env_; + ani_object obj_; +}; + +template <> +std::optional OptionalAccessor::Convert() +{ + if (IsUndefined()) { + return std::nullopt; + } + + ani_double aniValue; + auto ret = env_->Object_CallMethodByName_Double(obj_, "doubleValue", nullptr, &aniValue); + if (ret != ANI_OK) { + return std::nullopt; + } + auto value = static_cast(aniValue); + return value; +} + +template <> +std::optional OptionalAccessor::Convert() +{ + if (IsUndefined()) { + return std::nullopt; + } + + ani_size strSize; + env_->String_GetUTF8Size(static_cast(obj_), &strSize); + + std::vector buffer(strSize + 1); + char *utf8_buffer = buffer.data(); + + ani_size bytes_written = 0; + env_->String_GetUTF8(static_cast(obj_), utf8_buffer, strSize + 1, &bytes_written); + + utf8_buffer[bytes_written] = '\0'; + std::string content = std::string(utf8_buffer); + return content; +} + +#endif diff --git a/frameworks/native/backup_ext/ani/include/ext_backup_ani.h b/frameworks/native/backup_ext/ani/include/ext_backup_ani.h new file mode 100644 index 0000000000000000000000000000000000000000..4a19383c4afccd1d6e3ed156fb70f42ba47fe69c --- /dev/null +++ b/frameworks/native/backup_ext/ani/include/ext_backup_ani.h @@ -0,0 +1,59 @@ +/* + * 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 EXT_BACKUP_ANI_H +#define EXT_BACKUP_ANI_H + +#include "ani_utils.h" +#include "ext_backup_context.h" +#include "extension_base.h" +#include "runtime.h" +#include "sts_runtime.h" + +namespace OHOS::FileManagement::Backup { + +class ExtBackupAni : public AbilityRuntime::ExtensionBase { +public: + void Init(const std::shared_ptr &record, + const std::shared_ptr &application, + std::shared_ptr &handler, + const sptr &token) override; + +public: + static ExtBackupAni *Create(const std::unique_ptr &runtime); + + ErrCode OnBackup(std::function callback, + std::function callbackEx); + + ErrCode OnRestore(std::function callback, + std::function callbackEx); + +public: + explicit ExtBackupAni(AbilityRuntime::Runtime &runtime); + virtual ~ExtBackupAni() override; + +private: + ErrCode CallEtsOnBackup(); + ErrCode CallEtsOnRestore(); + +private: + AbilityRuntime::STSRuntime &stsRuntime_; + ani_env *env_; + std::unique_ptr etsObj_; +}; + +} // namespace OHOS::FileManagement::Backup + +#endif // EXT_BACKUP_ANI_H \ No newline at end of file diff --git a/frameworks/native/backup_ext/ani/include/ext_backup_loader.h b/frameworks/native/backup_ext/ani/include/ext_backup_loader.h new file mode 100644 index 0000000000000000000000000000000000000000..cb1951b6b2ce9d77a232543d5e0220c63602de4f --- /dev/null +++ b/frameworks/native/backup_ext/ani/include/ext_backup_loader.h @@ -0,0 +1,38 @@ +/* + * 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 OHOS_FILEMGMT_BACKUP_EXT_BACKUP_LOADER_H +#define OHOS_FILEMGMT_BACKUP_EXT_BACKUP_LOADER_H + +#include "extension_module_loader.h" + +namespace OHOS::FileManagement::Backup { +class ExtBackupLoader : public AbilityRuntime::ExtensionModuleLoader, public Singleton { + DECLARE_SINGLETON(ExtBackupLoader); + +public: + /** + * @brief Create Extension. + * + * @param runtime The runtime. + * @return The Extension instance. + */ + AbilityRuntime::Extension *Create(const std::unique_ptr &runtime) const override; + + virtual std::map GetParams() override; +}; +} // namespace OHOS::FileManagement::Backup + +#endif // OHOS_FILEMGMT_BACKUP_EXT_BACKUP_LOADER_H \ No newline at end of file diff --git a/frameworks/native/backup_ext/ani/src/ext_backup_ani.cpp b/frameworks/native/backup_ext/ani/src/ext_backup_ani.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d5ac5d1ab66a145c47a8d78bf9e3130bf0b4077b --- /dev/null +++ b/frameworks/native/backup_ext/ani/src/ext_backup_ani.cpp @@ -0,0 +1,122 @@ +/* + * 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 "ext_backup_ani.h" +#include "b_error/b_error.h" +#include "b_error/b_excep_utils.h" +#include "filemgmt_libhilog.h" + +namespace OHOS::FileManagement::Backup { +using namespace std; + +ExtBackupAni::ExtBackupAni(AbilityRuntime::Runtime &runtime) + : stsRuntime_(static_cast(runtime)) +{ + HILOGI("Create as an BackupExtensionAbility"); + env_ = stsRuntime_.GetAniEnv(); +} + +ExtBackupAni::~ExtBackupAni() +{ + HILOGI("ExtBackupAni::~ExtBackupAni."); +} + +void ExtBackupAni::Init(const std::shared_ptr &record, + const std::shared_ptr &application, + std::shared_ptr &handler, + const sptr &token) +{ + HILOGI("Init the BackupExtensionAbility"); + try { + if (record == nullptr) { + HILOGE("record null"); + return; + } + Extension::Init(record, application, handler, token); + if (Extension::abilityInfo_ == nullptr || Extension::abilityInfo_->srcEntrance.empty()) { + HILOGE("BackupExtensionAbility Init abilityInfo error"); + return; + } + std::string srcPath(Extension::abilityInfo_->moduleName + "/"); + srcPath.append(Extension::abilityInfo_->srcEntrance); + auto pos = srcPath.rfind("."); + if (pos != std::string::npos) { + srcPath.erase(pos); + srcPath.append(".abc"); + } + std::string moduleName(Extension::abilityInfo_->moduleName); + moduleName.append("::").append(abilityInfo_->name); + etsObj_ = stsRuntime_.LoadModule(moduleName, srcPath, abilityInfo_->hapPath, + abilityInfo_->compileMode == AppExecFwk::CompileMode::ES_MODULE, false, + abilityInfo_->srcEntrance); + if (etsObj_ == nullptr) { + HILOGE("Failed to get etsObj"); + return; + } + } catch (const BError &e) { + HILOGE("%{public}s", e.what()); + } catch (const exception &e) { + HILOGE("%{public}s", e.what()); + } +} + +ErrCode ExtBackupAni::CallEtsOnBackup() +{ + if (ANI_OK != env_->Object_CallMethodByName_Void(etsObj_->aniObj, "onBackup", nullptr)) { + HILOGE("Failed to call the method: onBackup"); + return EINVAL; + } + return ERR_OK; +} + +ErrCode ExtBackupAni::CallEtsOnRestore() +{ + ani_object bundleVersionObj = AniObjectUtils::Create(env_, "LBundleVersionInner;"); + if (nullptr == bundleVersionObj) { + HILOGE("Failed to Create the BundleVersionInner"); + return EINVAL; + } + if (ANI_OK != env_->Object_CallMethodByName_Void(etsObj_->aniObj, "onRestore", nullptr, bundleVersionObj)) { + HILOGE("Failed to call the method: onRestore"); + return EINVAL; + } + return ERR_OK; +} + +ExtBackupAni *ExtBackupAni::Create(const std::unique_ptr &runtime) +{ + HILOGI("Create as an BackupExtensionAbility"); + return new ExtBackupAni(*runtime); +} + +ErrCode ExtBackupAni::OnBackup(function callback, + std::function callbackEx) +{ + HILOGI("ExtBackupAni OnBackup"); + BExcepUltils::BAssert(etsObj_, BError::Codes::EXT_BROKEN_FRAMEWORK, + "The app does not provide the onBackup interface."); + return CallEtsOnBackup(); +} + +ErrCode ExtBackupAni::OnRestore(std::function callback, + std::function callbackEx) +{ + HILOGI("ExtBackupAni OnRestore"); + BExcepUltils::BAssert(etsObj_, BError::Codes::EXT_BROKEN_FRAMEWORK, + "The app does not provide the OnRestore interface."); + return CallEtsOnRestore(); +} + +} // namespace OHOS::FileManagement::Backup \ No newline at end of file diff --git a/frameworks/native/backup_ext/ani/src/ext_backup_loader.cpp b/frameworks/native/backup_ext/ani/src/ext_backup_loader.cpp new file mode 100644 index 0000000000000000000000000000000000000000..82b465d25992ec1bb1576fda4de9d60a752af3be --- /dev/null +++ b/frameworks/native/backup_ext/ani/src/ext_backup_loader.cpp @@ -0,0 +1,48 @@ +/* + * 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 "ext_backup_loader.h" + +#include "ext_backup_ani.h" +#include "filemgmt_libhilog.h" + +namespace OHOS::FileManagement::Backup { +using namespace std; + +ExtBackupLoader::ExtBackupLoader() = default; +ExtBackupLoader::~ExtBackupLoader() = default; + +AbilityRuntime::Extension *ExtBackupLoader::Create(const unique_ptr &runtime) const +{ + HILOGI("Create as an BackupExtensionAbility(Loader)"); + return ExtBackupAni::Create(runtime); +} + +map ExtBackupLoader::GetParams() +{ + HILOGI("Register as an extension ability"); + return { + // Type 即为 Extension 类型,定义在 ExtensionAbilityType 这一枚举类中。具体位置见 extension_ability_info.h + {"type", "9"}, + {"name", "BackupExtensionAbility"}, + }; +} + +extern "C" __attribute__((visibility("default"))) void *OHOS_EXTENSION_GetExtensionModule() +{ + HILOGI("Load as a library"); + return &ExtBackupLoader::GetInstance(); +} +} // namespace OHOS::FileManagement::Backup \ No newline at end of file