diff --git a/BUILD.gn b/BUILD.gn index 77cfe271..b8caba01 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -15,6 +15,12 @@ import("//build/ohos.gni") +group("vulkan_loader_test") { + testonly = true + + public_deps = [ "openharmony/test:test" ] +} + # Vulkan loader build options ## Build libvulkan.so {{{ @@ -30,6 +36,7 @@ config("vulkan_internal_config") { "-Wno-unused-variable", "-fPIC", ] + cflags_cc = [ "-std=c++17" ] ldflags = [ "-Wl,-Bsymbolic" ] defines += [ @@ -86,13 +93,21 @@ ohos_shared_library("vulkan_loader") { "loader/vk_loader_platform.h", "loader/wsi.c", "loader/wsi.h", + "openharmony/bundle_mgr_helper/vk_bundle_mgr_helper.cpp", + "openharmony/bundle_mgr_helper/vk_bundle_mgr_helper.h", + "openharmony/loader_hilog.h", ] configs = [ ":vulkan_internal_config" ] public_configs = [ ":vulkan_loader_config" ] external_deps = [ + "bundle_framework:appexecfwk_base", + "bundle_framework:appexecfwk_core", + "c_utils:utils", "hilog:libhilog", "init:libbegetutil", + "ipc:ipc_core", + "samgr:samgr_proxy", ] public_external_deps = [ "vulkan-headers:vulkan_headers" ] diff --git a/README_OpenHarmony.md b/README_OpenHarmony.md index ecbe0bb4..5e077d29 100644 --- a/README_OpenHarmony.md +++ b/README_OpenHarmony.md @@ -61,6 +61,71 @@ Vulkan Layer属于增强Vulkan开发环境的扩展功能,可以由开发人 在OpenHarmony上,Vulkan-Loader通过读取指定路径下的Layer的**json清单文件**加载Vulkan Layer。 +### user mode下加载自定义layer使用指南 +1. layer对应json文件和so文件放置 + 1. json文件放置位置: entry\src\main\resources\rawfile\layerName.json + 2. so文件放置位置: entry\libs\arm64-v8a\libLayerName.so + +2. json文件指定so文件位置 + 引入包管理后,json文件中的library_path支持使用相对路径,即将library_path修改为 libLayerName.so + 同时,兼容现有的library_path写绝对路径的方式,即library_path为 /data/storage/el1/bundle/lib/arm64/libLayerName.so + +3. 拷贝json文件至沙箱路径 + 由于当前loader无法直接从hap包中获取rawfile路径下文件,因此需要hap工程手动复制json文件到沙箱中 + 在entry\src\main\ets\pages\Index.ets文件中引入@ohos.file.fs, 并在aboutToAppear() 中写入复制方法,如下: + + ``` Java + // 在Index.ets文件中 + import fs from '@ohos.file.fs'; + // ...... + aboutToAppear(): void { // Copy layerName.json to hap sandbox + let path = getContext(this).filesDir; + if (!fs.accessSync(path)) { + fs.mkdirSync(path); + } + + buffer = getContext(this).resourceManager.getRawFileContentSync('layerName.json'); + file = fs.openSync(path + '/layerName.json', fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE); + fs.writeSync(file.fd, buffer.buffer); + } + ``` +4. 设置环境变量 + 开启时设置环境变量 + hdc shell param set debug.graphic.debug_layer layerName (应与json的名字保持一致:xxxxx.json) + hdc shell param set debug.graphic.debug_hap hapName (应于hap包名保持一致) + + 关闭时清空两个环境变量 + hdc shell param set debug.graphic.debug_layer '' (设置成空字符) + hdc shell param set debug.graphic.debug_hap '' (设置成空字符) +5. 异常排查方法 + 1. 检查json文件位置是否正常 + hap工程路径: \entry\src\main\resources\rawfile\layerName.json + hdc shell路径: /data/app/el2/100/base/{your_pakage_name}/file/layerName.json + 应用视角下json文件的路径: /data/storage/el2/base/haps/entry/files/layerName.json + + 2. 检查so文件位置是否正常 + hap工程路径: \entry\libs\arm64-v8a\libLayerName.so + hdc shell路径: /data/app/el1/bundle/public/{your_pakage_name}/libs/arm64/libLayerName.so + 应用视角下json文件的路径: /data/storage/el1/bundle/libs/arm64/libLayerName.so + 3. 抓取异常日志 + ``` + hdc shell + hilog -b X + hilog -b D -D D001405 + hilog |grep -i VulkanLoader + ``` +6. 进入应用视角 + 在调试过程中,如果权限不对或文件不存在,开发者需要从调试进程视角切换为应用视角,以便直观分析权限及文件目录问题。视角切换命令如下: + ``` + hdc shell // 进入shell + ps -ef|grep [hapName] // 通过ps命令找到对应应用的pid + nsenter -t [hapPid] -m /bin/sh // 通过上一步找到的应用pid进入对应应用的沙箱环境中 + hdc shell // 进入shell + ps -ef|grep [hapName] // 通过ps命令找到对应应用的pid + nsenter -t [hapPid] -m /bin/sh // 通过上一步找到的应用pid进入对应应用的沙箱环境中 + ``` + 执行完成后,即切换到了应用视角,该视角下的目录路径为应用沙箱路径,可以去排查沙箱路径相关问题。 + ### 指定的扫描路径 ``` diff --git a/bundle.json b/bundle.json index 667df8bc..6126c053 100644 --- a/bundle.json +++ b/bundle.json @@ -17,6 +17,10 @@ "ram": "10000KB", "deps": { "components": [ + "bundle_framework", + "c_utils", + "samgr", + "ipc", "hilog", "init" ], diff --git a/loader/loader.c b/loader/loader.c index d95076fa..83911cbb 100644 --- a/loader/loader.c +++ b/loader/loader.c @@ -3023,7 +3023,7 @@ VkResult read_data_files_in_search_paths(const struct loader_instance *inst, enu char *debug_layer_json_path = NULL; bool currentProcessEnableDebugLayer = false; - if(NULL != debug_hap_name && '\0' != debug_hap_name[0] && NULL != debug_layer_name && '\0' != debug_layer_name[0]){ + if (NULL != debug_layer_name && '\0' != debug_layer_name[0] && InitBundleInfo(debug_hap_name)) { currentProcessEnableDebugLayer = true; debug_layer_json_path = loader_secure_getenv("debug.graphic.vklayer_json_path",inst); if (NULL == debug_layer_json_path || '\0' == debug_layer_json_path[0]){ @@ -3039,6 +3039,7 @@ VkResult read_data_files_in_search_paths(const struct loader_instance *inst, enu strncat(debug_layer_json_path,debug_layer_name,debug_layer_json_path_len); strncat(debug_layer_json_path,json_suffix,debug_layer_json_path_len); } + loader_log(inst, VULKAN_LOADER_DEBUG_BIT, 0, "OHOS:: debug_layer_json_path: %s", debug_layer_json_path); } #endif @@ -4151,13 +4152,67 @@ struct loader_instance *loader_get_instance(const VkInstance instance) { } loader_platform_dl_handle loader_open_layer_file(const struct loader_instance *inst, struct loader_layer_properties *prop) { - if ((prop->lib_handle = loader_platform_open_library(prop->lib_name)) == NULL) { + char* libPath = prop->lib_name; +#if defined(__OHOS__) + char *debug_layer_name = loader_secure_getenv("debug.graphic.debug_layer", inst); + char *debug_hap_name = loader_secure_getenv("debug.graphic.debug_hap", inst); + bool isDebugLayer = false; + char* debugLayerLibPath = NULL; + if (NULL != debug_layer_name && '\0' != debug_layer_name[0] && InitBundleInfo(debug_hap_name)) { + const char lib_prefix[] = "lib"; + const char so_suffix[] = ".so"; + size_t totalLen = strlen(debug_layer_name) + strlen(lib_prefix) + strlen(so_suffix) + 1; + char* layerSoName = loader_instance_heap_calloc(inst, totalLen, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND); + if (layerSoName == NULL) { + loader_log(inst, VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_LAYER_BIT, 0, "malloc layerSoName fail"); + goto mallocErr; + } + strncpy(layerSoName, lib_prefix, totalLen); + strncat(layerSoName, debug_layer_name, totalLen); + strncat(layerSoName, so_suffix, totalLen); + if (strcmp(layerSoName, libPath) == 0) { + isDebugLayer = true; + debugLayerLibPath = GetDebugLayerLibPath(inst, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND); + if(debugLayerLibPath == NULL) { + loader_instance_heap_free(inst, layerSoName); + isDebugLayer = false; + goto mallocErr; + } + size_t totalLength = strlen(libPath) + strlen(debugLayerLibPath) + 1; + libPath = loader_instance_heap_calloc(inst, totalLength, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND); + if (libPath == NULL) { + loader_log(inst, VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_LAYER_BIT, 0, "malloc libPath fail"); + loader_instance_heap_free(inst, layerSoName); + loader_instance_heap_free(inst, debugLayerLibPath); + libPath = prop->lib_name; + isDebugLayer = false; + goto mallocErr; + } + strncpy(libPath, debugLayerLibPath, totalLength); + strncat(libPath, prop->lib_name, totalLength); + } else { + loader_log(inst, VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_LAYER_BIT, 0, "layerSoName != libPath : %s != %s", + layerSoName, libPath); + } + loader_instance_heap_free(inst, layerSoName); + } +mallocErr: + loader_free_getenv(debug_layer_name, inst); + loader_free_getenv(debug_hap_name, inst); +#endif + loader_log(inst, VULKAN_LOADER_DEBUG_BIT | VULKAN_LOADER_LAYER_BIT, 0, "try to open libPath: %s", libPath); + if ((prop->lib_handle = loader_platform_open_library(libPath)) == NULL) { loader_handle_load_library_error(inst, prop->lib_name, &prop->lib_status); } else { prop->lib_status = LOADER_LAYER_LIB_SUCCESS_LOADED; loader_log(inst, VULKAN_LOADER_DEBUG_BIT | VULKAN_LOADER_LAYER_BIT, 0, "Loading layer library %s", prop->lib_name); } - +#if defined(__OHOS__) + if (isDebugLayer) { + loader_instance_heap_free(inst, debugLayerLibPath); + loader_instance_heap_free(inst, libPath); + } +#endif return prop->lib_handle; } diff --git a/loader/loader.h b/loader/loader.h index 93346a9d..405d159a 100644 --- a/loader/loader.h +++ b/loader/loader.h @@ -31,6 +31,7 @@ #include "loader_common.h" #include "cJSON.h" +#include "bundle_mgr_helper/vk_bundle_mgr_helper.h" // Declare the once_init variable LOADER_PLATFORM_THREAD_ONCE_EXTERN_DEFINITION(once_init) diff --git a/openharmony/bundle_mgr_helper/vk_bundle_mgr_helper.cpp b/openharmony/bundle_mgr_helper/vk_bundle_mgr_helper.cpp new file mode 100644 index 00000000..ef4fbcc0 --- /dev/null +++ b/openharmony/bundle_mgr_helper/vk_bundle_mgr_helper.cpp @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd.. All rights reserved. + * 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 "vk_bundle_mgr_helper.h" + +#include "iservice_registry.h" +#include "system_ability_definition.h" +#include "../loader_hilog.h" +#include +#define EOK 0 + +extern "C" { + void *loader_instance_heap_calloc(const struct loader_instance *instance, size_t size, VkSystemAllocationScope allocation_scope); +} +constexpr const char *DEBUG_SANDBOX_DIR = "/data/storage/el1/bundle/"; + +bool InitBundleInfo(char* debugHapName) +{ + if (NULL == debugHapName || '\0' == debugHapName[0]) { + VKHILOGE("debug_hap_name is NULL!"); + return false; + } + std::string debugHap(debugHapName); + auto vkBundleMgrHelper = OHOS::DelayedSingleton::GetInstance(); + if (vkBundleMgrHelper == nullptr) { + VKHILOGE("vkBundleMgrHelper is null!"); + return false; + } + + if (vkBundleMgrHelper->GetBundleInfoForSelf( + OHOS::AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_APPLICATION, vkBundleMgrHelper->g_bundleInfo) == + OHOS::ERR_OK) { + if (vkBundleMgrHelper->g_bundleInfo.name == debugHap) { + return true; + } else { + VKHILOGE("this hap is %{public}s, the debug hap is %{public}s", + vkBundleMgrHelper->g_bundleInfo.name.c_str(), debugHap.c_str()); + } + } else { + VKHILOGE("Call GetBundleInfoForSelf func failed!"); + } + return false; +} + +char* GetDebugLayerLibPath(const struct loader_instance *inst, VkSystemAllocationScope allocation_sacope) +{ + auto vkBundleMgrHelper = OHOS::DelayedSingleton::GetInstance(); + std::string pathStr(DEBUG_SANDBOX_DIR); + std::string appLibPath = pathStr + vkBundleMgrHelper->g_bundleInfo.applicationInfo.nativeLibraryPath + "/"; + const char* fullPath = appLibPath.c_str(); + size_t len = strlen(fullPath) + 1; + char* libPath = static_cast(loader_instance_heap_calloc(inst, len, allocation_sacope)); + if (libPath == NULL) { + VKHILOGE("malloc libPath fail"); + return NULL; + } + if (memcpy_s(libPath, len, fullPath, len) != EOK) { + VKHILOGE("memcpy_s libPath fail, fullPath: %{public}s", fullPath); + return NULL; + } + VKHILOGD("GetDebugLayerLibPath(): the libPath is %{public}s", libPath); + return libPath; +} + +namespace OHOS { +namespace AppExecFwk { +VKBundleMgrHelper::VKBundleMgrHelper() {} + +VKBundleMgrHelper::~VKBundleMgrHelper() +{ + if (bundleMgr_ != nullptr && bundleMgr_->AsObject() != nullptr && deathRecipient_ != nullptr) { + bundleMgr_->AsObject()->RemoveDeathRecipient(deathRecipient_); + } +} + +sptr VKBundleMgrHelper::Connect() +{ + VKHILOGD("Call VKBundleMgrHelper::Connect"); + std::lock_guard lock(mutex_); + if (bundleMgr_ == nullptr) { + sptr systemAbilityManager = + SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + if (systemAbilityManager == nullptr) { + VKHILOGE("Failed to get system ability manager."); + return nullptr; + } + sptr remoteObject_ = systemAbilityManager->GetSystemAbility( + BUNDLE_MGR_SERVICE_SYS_ABILITY_ID); + if (remoteObject_ == nullptr || (bundleMgr_ = iface_cast(remoteObject_)) == nullptr) { + VKHILOGE("Failed to get bundle mgr service remote object"); + return nullptr; + } + std::weak_ptr weakPtr = shared_from_this(); + auto deathCallback = [weakPtr](const wptr &object) { + auto sharedPtr = weakPtr.lock(); + if (sharedPtr == nullptr) { + VKHILOGE("Bundle helper instance is nullptr"); + return; + } + sharedPtr->OnDeath(); + }; + deathRecipient_ = new(std::nothrow) VKBundleMgrServiceDeathRecipient(deathCallback); + if (deathRecipient_ == nullptr) { + VKHILOGE("Failed to create death recipient ptr deathRecipient_!"); + return nullptr; + } + if (bundleMgr_->AsObject() != nullptr) { + bundleMgr_->AsObject()->AddDeathRecipient(deathRecipient_); + } + } + return bundleMgr_; +} + +void VKBundleMgrHelper::OnDeath() +{ + VKHILOGD("Call VKBundleMgrHelper::OnDeath"); + std::lock_guard lock(mutex_); + if (bundleMgr_ == nullptr || bundleMgr_->AsObject() == nullptr) { + VKHILOGE("bundleMgr_ is nullptr!"); + return; + } + bundleMgr_->AsObject()->RemoveDeathRecipient(deathRecipient_); + bundleMgr_ = nullptr; +} + +ErrCode VKBundleMgrHelper::GetBundleInfoForSelf(AppExecFwk::GetBundleInfoFlag flags, BundleInfo &bundleInfo) +{ + VKHILOGD("Call VKBundleMgrHealper::GetBundleInfoForSelf."); + auto bundleMgr_ = Connect(); + if (bundleMgr_ == nullptr) { + VKHILOGE("Failed to connect."); + return -1; + } + return bundleMgr_->GetBundleInfoForSelf(static_cast(flags), bundleInfo); +} + +VKBundleMgrServiceDeathRecipient::VKBundleMgrServiceDeathRecipient( + const std::function& object)>& deathCallback) + : deathCallback_(deathCallback) {} + +void VKBundleMgrServiceDeathRecipient::OnRemoteDied(const wptr& object) +{ + if (deathCallback_ != nullptr) { + deathCallback_(object); + } +} +} +} \ No newline at end of file diff --git a/openharmony/bundle_mgr_helper/vk_bundle_mgr_helper.h b/openharmony/bundle_mgr_helper/vk_bundle_mgr_helper.h new file mode 100644 index 00000000..15f551b0 --- /dev/null +++ b/openharmony/bundle_mgr_helper/vk_bundle_mgr_helper.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd.. All rights reserved. + * 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 "vulkan/vulkan_core.h" +#ifdef __cplusplus +#include +#include "bundle_mgr_interface.h" + +extern "C" { +#endif // __cplusplus + +bool InitBundleInfo(char* debugHapName); +char* GetDebugLayerLibPath(const struct loader_instance *inst, VkSystemAllocationScope allocation_sacope); + +#ifdef __cplusplus +} +namespace OHOS { +namespace AppExecFwk { +class VKBundleMgrHelper : public std::enable_shared_from_this { +public: + DISALLOW_COPY_AND_MOVE(VKBundleMgrHelper); + + BundleInfo g_bundleInfo; + ErrCode GetBundleInfoForSelf(AppExecFwk::GetBundleInfoFlag flags, BundleInfo& bundleInfo); + +private: + sptr Connect(); + + void OnDeath(); + +private: + DECLARE_DELAYED_SINGLETON(VKBundleMgrHelper); + + std::mutex mutex_; + sptr bundleMgr_; + sptr deathRecipient_ = nullptr; +}; + +class VKBundleMgrServiceDeathRecipient : public IRemoteObject::DeathRecipient { +public: + explicit VKBundleMgrServiceDeathRecipient( + const std::function& object)>& deathCallback); + DISALLOW_COPY_AND_MOVE(VKBundleMgrServiceDeathRecipient); + virtual ~VKBundleMgrServiceDeathRecipient() = default; + void OnRemoteDied(const wptr& object) override; + +private: + std::function& object)> deathCallback_; +}; +} +} +#endif // __cplusplus \ No newline at end of file diff --git a/openharmony/test/BUILD.gn b/openharmony/test/BUILD.gn new file mode 100644 index 00000000..3a0bfd33 --- /dev/null +++ b/openharmony/test/BUILD.gn @@ -0,0 +1,18 @@ +# Copyright (c) 2023 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. + +group("test") { + testonly = true + + deps = [ "unittest:unittest" ] +} diff --git a/openharmony/test/unittest/BUILD.gn b/openharmony/test/unittest/BUILD.gn new file mode 100644 index 00000000..af9dc4a8 --- /dev/null +++ b/openharmony/test/unittest/BUILD.gn @@ -0,0 +1,66 @@ +# Copyright (c) 2023 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/test.gni") +module_out_path = "thirdparty/vulkan-loader" + +group("unittest") { + testonly = true + + deps = [ ":vk_bundle_mgr_helper_test" ] +} + +ohos_unittest("vk_bundle_mgr_helper_test") { + module_out_path = module_out_path + sources = [ "vk_bundle_mgr_helper_tests.cpp" ] + deps = [ ":vk_bundle_mgr_helper_test_common" ] + + external_deps = [ + "bundle_framework:appexecfwk_base", + "bundle_framework:appexecfwk_core", + "c_utils:utils", + "ipc:ipc_core", + "samgr:samgr_proxy", + ] +} + +ohos_static_library("vk_bundle_mgr_helper_test_common") { + visibility = [ ":*" ] + testonly = true + + public_configs = [ ":vk_bundle_mgr_helper_test_common_public_config" ] + + public_deps = [ + "//third_party/googletest:gtest_main", + "//third_party/vulkan-loader:vulkan_loader", + ] + + external_deps = [ + "c_utils:utils", + "hilog:libhilog", + ] + subsystem_name = "bundle_info" + part_name = "vulkan-loader-bundle" +} + +config("vk_bundle_mgr_helper_test_common_public_config") { + include_dirs = [ "vk_bundle_mgr_helper_tests.cpp" ] + + cflags = [ + "-Wall", + "-Werror", + "-g3", + "-Dprivate=public", + "-Dprotected=public", + ] +} diff --git a/openharmony/test/unittest/vk_bundle_mgr_helper_tests.cpp b/openharmony/test/unittest/vk_bundle_mgr_helper_tests.cpp new file mode 100644 index 00000000..0aedbeef --- /dev/null +++ b/openharmony/test/unittest/vk_bundle_mgr_helper_tests.cpp @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2024 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, Hardware + * 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 +#include "bundle_mgr_helper/vk_bundle_mgr_helper.h" + +using namespace testing; +using namespace testing::ext; + +namespace OHOS::Rosen { +class VkBundleMgrHelperTest : public testing::Test { +public: + static void SetUpTestCase() {} + static void TearDownTestCase() {} + void SetUp() {} + void TearDown() {} +}; +/** + * @tc.name: Init001 + * @tc.desc: + * @tc.type: FUNC + */ +HWTEST_F(VkBundleMgrHelperTest, VkBundleMgrHelperTest, Level1) +{ + AppExecFwk::BundleInfo bundleInfo; + auto vkBundleMgrHelper = DelayedSingleton::GetInstance(); + auto result = vkBundleMgrHelper->GetBundleInfoForSelf( + AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_APPLICATION, bundleInfo); + EXPECT_NE(result, ERR_OK); + + bool ret = InitBundleInfo(NULL); + EXPECT_EQ(ret, false); + + string name = "\0"; + ret = InitBundleInfo(const_cast(name.c_str())); + EXPECT_EQ(ret, false); + + string fatalName = "randomFatalName"; + ret = InitBundleInfo(const_cast(fatalName.c_str())); + EXPECT_EQ(ret, false); + + ret = InitBundleInfo((const_cast(bundleInfo.name.c_str()))); + EXPECT_EQ(ret, false); + + char* path = GetDebugLayerLibPath(); + EXPECT_NE(path, nullptr); + free(path); +} +} \ No newline at end of file