From 4409e6d68a41609a4e6d188aff5ae32dfba25453 Mon Sep 17 00:00:00 2001 From: lanhaoyu Date: Thu, 1 May 2025 10:11:20 +0800 Subject: [PATCH] add code Signed-off-by: lanhaoyu --- .../bundle/include/native_interface_bundle.h | 103 +++++++++ .../kits/native/bundle/libbundle.ndk.json | 8 + .../bundle/src/native_interface_bundle.cpp | 208 ++++++++++++++++++ 3 files changed, 319 insertions(+) diff --git a/interfaces/kits/native/bundle/include/native_interface_bundle.h b/interfaces/kits/native/bundle/include/native_interface_bundle.h index cdabbaa09a..2d1944414d 100644 --- a/interfaces/kits/native/bundle/include/native_interface_bundle.h +++ b/interfaces/kits/native/bundle/include/native_interface_bundle.h @@ -36,6 +36,9 @@ #ifndef FOUNDATION_APPEXECFWK_STANDARD_KITS_APPKIT_NATIVE_BUNDLE_INCLUDE_NATIVE_INTERFACE_BUNDLE_H #define FOUNDATION_APPEXECFWK_STANDARD_KITS_APPKIT_NATIVE_BUNDLE_INCLUDE_NATIVE_INTERFACE_BUNDLE_H +#include +#include + #ifdef __cplusplus extern "C" { #endif @@ -76,6 +79,74 @@ struct OH_NativeBundle_ElementName { char* abilityName; }; +/** + * @brief Indicates information of metadata + * + * @atomicservice + * @since 20 + */ +struct OH_NativeBundle_Metadata { + /** + * @brief Indicates the metadata name + * + * @atomicservice + * @since 20 + */ + char* name; + /** + * @brief Indicates the metadata value + * + * @atomicservice + * @since 20 + */ + char* value; + /** + * @brief Indicates the metadata resource + * + * @atomicservice + * @since 20 + */ + char* resource; +}; + +/** + * @brief Indicates information of metadata + * + * @atomicservice + * @since 20 + */ +typedef struct OH_NativeBundle_Metadata OH_NativeBundle_Metadata; + +/** + * @brief Indicates information of module metadata + * + * @atomicservice + * @since 20 + */ +struct OH_NativeBundle_ModuleMetadata { + /** + * @brief Indicates the moduleName of module + * + * @atomicservice + * @since 20 + */ + char* moduleName; + /** + * @brief Indicates the metadata array of module + * + * @atomicservice + * @since 20 + */ + OH_NativeBundle_Metadata* metadataArray; + /** + * @brief Indicates the metadata array size of module + * + * @atomicservice + * @since 20 + */ + size_t metadataArraySize; +}; + /** * @brief Indicates information of application * @@ -92,6 +163,14 @@ typedef struct OH_NativeBundle_ApplicationInfo OH_NativeBundle_ApplicationInfo; */ typedef struct OH_NativeBundle_ElementName OH_NativeBundle_ElementName; +/** + * @brief Indicates information of module metadata + * + * @atomicservice + * @since 20 + */ +typedef struct OH_NativeBundle_ModuleMetadata OH_NativeBundle_ModuleMetadata; + /** * @brief Obtains the application info based on the The current bundle. * @@ -160,6 +239,30 @@ OH_NativeBundle_ElementName OH_NativeBundle_GetMainElementName(); * @version 1.0 */ char* OH_NativeBundle_GetCompatibleDeviceType(); + +/** + * @brief Obtains the application debug mode. + * + * @param isDebugMode Indicates whether the application is in debug mode. + * @return Returns true if call successful, false otherwise. + * @atomicservice + * @since 20 + */ +bool OH_NativeBundle_IsDebugMode(bool* isDebugMode); + +/** + * @brief Obtains the module metadata array of the current application. + * After utilizing this interface, to prevent memory leaks, + * it is necessary to manually release the pointer returned by the interface. + * + * @param size Indicates the module metadata array size. + * @return Returns the newly created module metadata array, if the returned object is NULL, + * it indicates creation failure. The possible cause of failure could be that the application address space is full, + * leading to space allocation failure. + * @atomicservice + * @since 20 + */ +OH_NativeBundle_ModuleMetadata* OH_NativeBundle_GetModuleMetadata(size_t* size); #ifdef __cplusplus }; #endif diff --git a/interfaces/kits/native/bundle/libbundle.ndk.json b/interfaces/kits/native/bundle/libbundle.ndk.json index f61863508c..7c05eef7bb 100644 --- a/interfaces/kits/native/bundle/libbundle.ndk.json +++ b/interfaces/kits/native/bundle/libbundle.ndk.json @@ -18,5 +18,13 @@ { "first_introduced": "14", "name": "OH_NativeBundle_GetCompatibleDeviceType" + }, + { + "first_introduced": "20", + "name": "OH_NativeBundle_IsDebugMode" + }, + { + "first_introduced": "20", + "name": "OH_NativeBundle_GetModuleMetadata" } ] diff --git a/interfaces/kits/native/bundle/src/native_interface_bundle.cpp b/interfaces/kits/native/bundle/src/native_interface_bundle.cpp index 66ef681e5e..647eef95af 100644 --- a/interfaces/kits/native/bundle/src/native_interface_bundle.cpp +++ b/interfaces/kits/native/bundle/src/native_interface_bundle.cpp @@ -15,8 +15,11 @@ #include "native_interface_bundle.h" +#include +#include #include #include +#include #include "application_info.h" #include "bundle_info.h" @@ -25,6 +28,7 @@ #include "ipc_skeleton.h" #include "securec.h" namespace { +const size_t CHAR_MIN_LENGTH = 1; const size_t CHAR_MAX_LENGTH = 10240; } @@ -274,3 +278,207 @@ char* OH_NativeBundle_GetCompatibleDeviceType() APP_LOGI("OH_NativeBundle_GetCompatibleDeviceType success"); return deviceTypeC; } + +bool OH_NativeBundle_IsDebugMode(bool* isDebugMode) +{ + if (isDebugMode == nullptr) { + APP_LOGE("invalid param isDebugMode"); + return false; + } + OHOS::AppExecFwk::BundleMgrProxyNative bundleMgrProxyNative; + OHOS::AppExecFwk::BundleInfo bundleInfo; + + auto bundleInfoFlag = + static_cast(OHOS::AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_APPLICATION); + + if (!bundleMgrProxyNative.GetBundleInfoForSelf(bundleInfoFlag, bundleInfo)) { + APP_LOGE("can not get bundleInfo for self"); + return false; + } + + *isDebugMode = bundleInfo.applicationInfo.debug; + APP_LOGI("OH_NativeBundle_IsDebugMode success"); + return true; +} + +void FreeMetadataArray(OH_NativeBundle_Metadata* &metadata, size_t metadataSize) +{ + if (metadata == nullptr || metadataSize == 0) { + APP_LOGE("invalid param"); + return; + } + for (size_t i = 0; i < metadataSize; ++i) { + free(metadata[i].resource); + free(metadata[i].value); + free(metadata[i].name); + } + free(metadata); +} + +void FreeModuleMetadataArray(OH_NativeBundle_ModuleMetadata* &moduleMetadata, size_t moduleMetadataSize) +{ + if (moduleMetadata == nullptr || moduleMetadataSize == 0) { + APP_LOGE("invalid param"); + return; + } + + for (size_t i = 0; i < moduleMetadataSize; ++i) { + free(moduleMetadata[i].moduleName); + FreeMetadataArray(moduleMetadata[i].metadataArray, moduleMetadata[i].metadataArraySize); + } + free(moduleMetadata); +} + +bool CopyMetadataStringToChar(char* &name, const std::string &value) +{ + size_t length = value.size(); + if ((length == 0) || (length + 1) > CHAR_MAX_LENGTH || (length + 1) == 0) { + APP_LOGW("failed due to the length of value is empty or too long"); + name = static_cast(malloc(CHAR_MIN_LENGTH)); + if (name == nullptr) { + APP_LOGE("failed due to malloc error"); + return false; + } + name[0] = '\0'; + return true; + } + name = static_cast(malloc(length + 1)); + if (name == nullptr) { + APP_LOGE("failed due to malloc error"); + return false; + } + (void)memset_s(name, length + 1, 0x00, length + 1); + if (strcpy_s(name, length + 1, value.c_str()) != EOK) { + APP_LOGE("failed due to strcpy_s error"); + return false; + } + return true; +} + +OH_NativeBundle_ModuleMetadata* AllocateModuleMetadata(size_t moduleMetadataSize) +{ + if (moduleMetadataSize == 0) { + APP_LOGE("failed due to the length of value is empty"); + return nullptr; + } + size_t length = sizeof(OH_NativeBundle_ModuleMetadata) * moduleMetadataSize; + OH_NativeBundle_ModuleMetadata *moduleMetadata = static_cast(malloc(length)); + if (moduleMetadata == nullptr) { + APP_LOGE("failed to allocate memory for OH_NativeBundle_ModuleMetadata"); + } + (void)memset_s(moduleMetadata, length, 0x00, length); + return moduleMetadata; +} + +bool FillModuleMetadata(OH_NativeBundle_ModuleMetadata &moduleMetadata, const std::string &moduleName, + const std::vector &metadataArray) +{ + if (!CopyMetadataStringToChar(moduleMetadata.moduleName, moduleName.c_str())) { + APP_LOGE("failed to allocate memory for OH_NativeBundle_ModuleMetadata moduleName"); + return false; + } + + auto metadataArraySize = metadataArray.size(); + if (metadataArraySize == 0) { + moduleMetadata.metadataArray = nullptr; + moduleMetadata.metadataArraySize = metadataArraySize; + APP_LOGI("metadataArray is empty"); + return true; + } + + size_t length = sizeof(OH_NativeBundle_Metadata) * metadataArraySize; + moduleMetadata.metadataArray = static_cast(malloc(length)); + if (moduleMetadata.metadataArray == nullptr) { + APP_LOGE("failed to allocate memory for metadataArray"); + return false; + } + (void)memset_s(moduleMetadata.metadataArray, length, 0x00, length); + moduleMetadata.metadataArraySize = metadataArraySize; + + for (size_t j = 0; j < metadataArraySize; ++j) { + if (!CopyMetadataStringToChar(moduleMetadata.metadataArray[j].name, metadataArray[j].name.c_str())) { + APP_LOGE("failed to allocate memory for OH_NativeBundle_ModuleMetadata name"); + return false; + } + if (!CopyMetadataStringToChar(moduleMetadata.metadataArray[j].value, metadataArray[j].value.c_str())) { + APP_LOGE("failed to allocate memory for OH_NativeBundle_ModuleMetadata value"); + return false; + } + if (!CopyMetadataStringToChar(moduleMetadata.metadataArray[j].resource, metadataArray[j].resource.c_str())) { + APP_LOGE("failed to allocate memory for OH_NativeBundle_ModuleMetadata resource"); + return false; + } + } + return true; +} + +OH_NativeBundle_ModuleMetadata* CreateModuleMetadata(const std::map> &metadata) +{ + auto moduleMetadataSize = metadata.size(); + OH_NativeBundle_ModuleMetadata *moduleMetadata = AllocateModuleMetadata(moduleMetadataSize); + if (moduleMetadata == nullptr) { + APP_LOGE("allocate module metadata failed"); + return nullptr; + } + + size_t i = 0; + for (const auto &[moduleName, metadataArray] : metadata) { + if (!FillModuleMetadata(moduleMetadata[i], moduleName, metadataArray)) { + FreeModuleMetadataArray(moduleMetadata, i + 1); + APP_LOGE("fill module metadata failed"); + return nullptr; + } + ++i; + } + + return moduleMetadata; +} + +OH_NativeBundle_ModuleMetadata* OH_NativeBundle_GetModuleMetadata(size_t* size) +{ + if (size == nullptr) { + APP_LOGE("invalid param size"); + return nullptr; + } + *size = 0; + OHOS::AppExecFwk::BundleMgrProxyNative bundleMgrProxyNative; + OHOS::AppExecFwk::BundleInfo bundleInfo; + auto bundleInfoFlag = + static_cast(OHOS::AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_METADATA) | + static_cast(OHOS::AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_APPLICATION); + + if (!bundleMgrProxyNative.GetBundleInfoForSelf(bundleInfoFlag, bundleInfo)) { + APP_LOGE("failed to get bundleInfo for self, flags: %{public}d", bundleInfoFlag); + return nullptr; + } + + OH_NativeBundle_ModuleMetadata *moduleMetadata = nullptr; + + if (bundleInfo.applicationInfo.metadata.empty()) { + moduleMetadata = (OH_NativeBundle_ModuleMetadata *)malloc(sizeof(OH_NativeBundle_ModuleMetadata)); + if (moduleMetadata == nullptr) { + APP_LOGE("failed to malloc moduleMetadata"); + return nullptr; + } + std::string moduleName = bundleInfo.moduleNames.empty() ? "" : bundleInfo.moduleNames[0]; + if (!CopyMetadataStringToChar(moduleMetadata->moduleName, moduleName.c_str())) { + free(moduleMetadata); + APP_LOGE("failed to allocate memory for OH_NativeBundle_ModuleMetadata moduleName"); + return nullptr; + } + moduleMetadata->metadataArray = nullptr; + moduleMetadata->metadataArraySize = 0; + *size = 1; + APP_LOGI("bundleInfo applicationInfo metadata is empty"); + return moduleMetadata; + } + moduleMetadata = CreateModuleMetadata(bundleInfo.applicationInfo.metadata); + if (moduleMetadata == nullptr) { + APP_LOGE("failed to create moduleMetadata"); + return nullptr; + } + *size = bundleInfo.applicationInfo.metadata.size(); + APP_LOGI("OH_NativeBundle_GetModuleMetadata success"); + return moduleMetadata; +} \ No newline at end of file -- Gitee