| @@ -33,6 +33,7 @@ | |||
| 33 | "accessibility", | 33 | "accessibility", |
| 34 | "audio_framework", | 34 | "audio_framework", |
| 35 | "av_codec", | 35 | "av_codec", |
| 36 | + "config_policy", | ||
| 36 | "cJSON", | 37 | "cJSON", |
| 37 | "c_utils", | 38 | "c_utils", |
| 38 | "device_security_level", | 39 | "device_security_level", |
| @@ -0,0 +1,46 @@ | |||
| 1 | +/* | ||
| 2 | + * Copyright (c) 2024-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 | + | ||
| 16 | +#ifndef OHOS_DAUDIO_SINK_CONFIG_LOADER_H | ||
| 17 | +#define OHOS_DAUDIO_SINK_CONFIG_LOADER_H | ||
| 18 | + | ||
| 19 | +#include <string> | ||
| 20 | + | ||
| 21 | +#include "cJSON.h" | ||
| 22 | +#include "dhfwk_single_instance.h" | ||
| 23 | + | ||
| 24 | +namespace OHOS { | ||
| 25 | +namespace DistributedHardware { | ||
| 26 | +class DAudioSinkConfigLoader { | ||
| 27 | + FWK_DECLARE_SINGLE_INSTANCE_BASE(DAudioSinkConfigLoader); | ||
| 28 | +public: | ||
| 29 | + int32_t Init(); | ||
| 30 | + bool IsMicSinkEnabled() const; | ||
| 31 | + bool IsSpeakerSinkEnabled() const; | ||
| 32 | + | ||
| 33 | +private: | ||
| 34 | + DAudioSinkConfigLoader() = default; | ||
| 35 | + ~DAudioSinkConfigLoader() = default; | ||
| 36 | + std::string ReadConfigFile(); | ||
| 37 | + void ParseAudioEnableConfig(const cJSON *root); | ||
| 38 | + | ||
| 39 | +private: | ||
| 40 | + bool micSinkEnabled_ = true; | ||
| 41 | + bool speakerSinkEnabled_ = true; | ||
| 42 | + bool isInitialized_ = false; | ||
| 43 | +}; | ||
| 44 | +} // namespace DistributedHardware | ||
| 45 | +} // namespace OHOS | ||
| 46 | +#endif // OHOS_DAUDIO_SINK_CONFIG_LOADER_H | ||
| @@ -0,0 +1,143 @@ | |||
| 1 | +/* | ||
| 2 | + * Copyright (c) 2024-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 | + | ||
| 16 | +#include "daudio_sink_config_loader.h" | ||
| 17 | + | ||
| 18 | +#include <climits> | ||
| 19 | +#include <fstream> | ||
| 20 | + | ||
| 21 | +#include "config_policy_utils.h" | ||
| 22 | + | ||
| 23 | +#include "daudio_constants.h" | ||
| 24 | +#include "daudio_errorcode.h" | ||
| 25 | +#include "daudio_log.h" | ||
| 26 | + | ||
| 27 | +#undef DH_LOG_TAG | ||
| 28 | +#define DH_LOG_TAG "DAudioSinkCfgLoader" | ||
| 29 | + | ||
| 30 | +namespace OHOS { | ||
| 31 | +namespace DistributedHardware { | ||
| 32 | +namespace { | ||
| 33 | +constexpr const char *COMPONENTSLOAD_PROFILE_PATH = | ||
| 34 | + "etc/distributedhardware/distributed_hardware_components_cfg.json"; | ||
| 35 | +constexpr const char *COMPONENT_ENABLE_CONFIG = "component_enable_config"; | ||
| 36 | +constexpr const char *AUDIO_TYPE_NAME = "AUDIO"; | ||
| 37 | +constexpr const char *ROLE_SINK = "sink"; | ||
| 38 | +} | ||
| 39 | + | ||
| 40 | +FWK_IMPLEMENT_SINGLE_INSTANCE(DAudioSinkConfigLoader); | ||
| 41 | + | ||
| 42 | +std::string DAudioSinkConfigLoader::ReadConfigFile() | ||
| 43 | +{ | ||
| 44 | + char buf[MAX_PATH_LEN] = {0}; | ||
| 45 | + char *profilePath = GetOneCfgFile(COMPONENTSLOAD_PROFILE_PATH, buf, MAX_PATH_LEN); | ||
| 46 | + if (profilePath == nullptr || strlen(profilePath) == 0 || strlen(profilePath) > PATH_MAX) { | ||
| 47 | + DHLOGE("Get config file path failed."); | ||
| 48 | + return ""; | ||
| 49 | + } | ||
| 50 | + char path[PATH_MAX] = {0x00}; | ||
| 51 | + if (realpath(profilePath, path) == nullptr) { | ||
| 52 | + DHLOGE("Get config file path failed."); | ||
| 53 | + return ""; | ||
| 54 | + } | ||
| 55 | + std::ifstream infile(path); | ||
| 56 | + if (!infile.is_open()) { | ||
| 57 | + DHLOGE("Open config file failed."); | ||
| 58 | + return ""; | ||
| 59 | + } | ||
| 60 | + std::string sLine; | ||
| 61 | + std::string sAll; | ||
| 62 | + while (getline(infile, sLine)) { | ||
| 63 | + sAll.append(sLine); | ||
| 64 | + } | ||
| 65 | + infile.close(); | ||
| 66 | + return sAll; | ||
| 67 | +} | ||
B | |||
| 68 | + | ||
| 69 | +void DAudioSinkConfigLoader::ParseAudioEnableConfig(const cJSON *root) | ||
| 70 | +{ | ||
| 71 | + if (root == nullptr) { | ||
| 72 | + return; | ||
| 73 | + } | ||
| 74 | + cJSON *enableConfig = cJSON_GetObjectItem(root, COMPONENT_ENABLE_CONFIG); | ||
| 75 | + if (enableConfig == nullptr || !cJSON_IsObject(enableConfig)) { | ||
| 76 | + DHLOGI("component_enable_config not found, use default (all enabled)."); | ||
| 77 | + return; | ||
| 78 | + } | ||
| 79 | + cJSON *audioEntry = cJSON_GetObjectItem(enableConfig, AUDIO_TYPE_NAME); | ||
| 80 | + if (audioEntry == nullptr || !cJSON_IsObject(audioEntry)) { | ||
| 81 | + DHLOGI("AUDIO entry not found in component_enable_config, use default (all enabled)."); | ||
| 82 | + return; | ||
| 83 | + } | ||
| 84 | + cJSON *micEntry = cJSON_GetObjectItem(audioEntry, MIC.c_str()); | ||
| 85 | + if (micEntry != nullptr) { | ||
| 86 | + if (cJSON_IsBool(micEntry)) { | ||
| 87 | + micSinkEnabled_ = cJSON_IsTrue(micEntry); | ||
| 88 | + } else if (cJSON_IsObject(micEntry)) { | ||
| 89 | + cJSON *sinkItem = cJSON_GetObjectItem(micEntry, ROLE_SINK); | ||
| 90 | + if (sinkItem != nullptr && cJSON_IsBool(sinkItem)) { | ||
| 91 | + micSinkEnabled_ = cJSON_IsTrue(sinkItem); | ||
| 92 | + } | ||
| 93 | + } | ||
| 94 | + } | ||
| 95 | + cJSON *spkEntry = cJSON_GetObjectItem(audioEntry, SPEAKER.c_str()); | ||
| 96 | + if (spkEntry != nullptr) { | ||
| 97 | + if (cJSON_IsBool(spkEntry)) { | ||
| 98 | + speakerSinkEnabled_ = cJSON_IsTrue(spkEntry); | ||
| 99 | + } else if (cJSON_IsObject(spkEntry)) { | ||
| 100 | + cJSON *sinkItem = cJSON_GetObjectItem(spkEntry, ROLE_SINK); | ||
| 101 | + if (sinkItem != nullptr && cJSON_IsBool(sinkItem)) { | ||
| 102 | + speakerSinkEnabled_ = cJSON_IsTrue(sinkItem); | ||
| 103 | + } | ||
| 104 | + } | ||
| 105 | + } | ||
| 106 | + DHLOGI("Parse audio enable config: micSink=%{public}d, speakerSink=%{public}d.", | ||
| 107 | + micSinkEnabled_, speakerSinkEnabled_); | ||
| 108 | +} | ||
| 109 | + | ||
| 110 | +int32_t DAudioSinkConfigLoader::Init() | ||
| 111 | +{ | ||
| 112 | + if (isInitialized_) { | ||
| 113 | + return DH_SUCCESS; | ||
| 114 | + } | ||
| 115 | + std::string jsonStr = ReadConfigFile(); | ||
| 116 | + if (jsonStr.empty()) { | ||
| 117 | + DHLOGW("Config file is empty, use default (all enabled)."); | ||
| 118 | + isInitialized_ = true; | ||
| 119 | + return DH_SUCCESS; | ||
| 120 | + } | ||
| 121 | + cJSON *root = cJSON_Parse(jsonStr.c_str()); | ||
| 122 | + if (root == nullptr) { | ||
| 123 | + DHLOGE("Parse config json failed, use default (all enabled)."); | ||
| 124 | + isInitialized_ = true; | ||
| 125 | + return DH_SUCCESS; | ||
| 126 | + } | ||
| 127 | + ParseAudioEnableConfig(root); | ||
| 128 | + cJSON_Delete(root); | ||
| 129 | + isInitialized_ = true; | ||
| 130 | + return DH_SUCCESS; | ||
B 🤖 AI 代码检视意见 | 🛡️ Reliability | ⚠️ High | 行号区间: L109-L130 问题描述: DAudioSinkConfigLoader::Init() 方法检查 isInitialized_ 标志并进行写操作,但整个过程没有加锁。如果该方法在多线程环境下被并发调用,可能会导致重复初始化、数据竞争以及读取到未完全更新的配置状态。 💡 查看修复建议(点击展开)修改建议:为单例的 Init 方法增加互斥锁保护(需在头文件中声明 std::mutex),避免多线程并发调用时产生数据竞争或重复初始化。
![]() ![]() | |||
| 131 | +} | ||
| 132 | + | ||
| 133 | +bool DAudioSinkConfigLoader::IsMicSinkEnabled() const | ||
| 134 | +{ | ||
| 135 | + return micSinkEnabled_; | ||
| 136 | +} | ||
| 137 | + | ||
| 138 | +bool DAudioSinkConfigLoader::IsSpeakerSinkEnabled() const | ||
| 139 | +{ | ||
| 140 | + return speakerSinkEnabled_; | ||
| 141 | +} | ||
| 142 | +} // namespace DistributedHardware | ||
| 143 | +} // namespace OHOS | ||
| @@ -20,6 +20,7 @@ | |||
| 20 | #include "daudio_constants.h" | 20 | #include "daudio_constants.h" |
| 21 | #include "daudio_errorcode.h" | 21 | #include "daudio_errorcode.h" |
| 22 | #include "daudio_log.h" | 22 | #include "daudio_log.h" |
| 23 | +#include "daudio_sink_config_loader.h" | ||
| 23 | #include "daudio_sink_manager.h" | 24 | #include "daudio_sink_manager.h" |
| 24 | #include "daudio_util.h" | 25 | #include "daudio_util.h" |
| 25 | 26 | ||
| @@ -131,6 +132,10 @@ int32_t DAudioSinkDev::TaskDisableDevice(const std::string &args) | |||
| 131 | int32_t DAudioSinkDev::TaskOpenDSpeaker(const std::string &args) | 132 | int32_t DAudioSinkDev::TaskOpenDSpeaker(const std::string &args) |
| 132 | { | 133 | { |
| 133 | DHLOGI("Open speaker device"); | 134 | DHLOGI("Open speaker device"); |
| 135 | + if (!DAudioSinkConfigLoader::GetInstance().IsSpeakerSinkEnabled()) { | ||
| 136 | + DHLOGE("Speaker sink is disabled by config."); | ||
| 137 | + return ERR_DH_AUDIO_FAILED; | ||
| 138 | + } | ||
B 🤖 AI 代码检视意见 | 🏗️ Architecture | ℹ️ Medium | 行号区间: L135-L138 问题描述: 当 Speaker/Mic Sink 被配置项禁用时,返回了通用的 ERR_DH_AUDIO_FAILED 错误码。配置禁用属于正常业务拦截,而非系统内部故障。返回通用的 FAILED 错误码可能导致上层调用方无法准确区分是“系统异常”还是“功能被配置关闭”,从而影响重试逻辑或错误上报。 💡 查看修复建议(点击展开)修改建议:建议新增或使用现有的“不支持”或“未使能”特定错误码替代 ERR_DH_AUDIO_FAILED,以便于上层业务精准区分失败原因。若无合适错误码,可保持现状但需在接口文档中说明。
![]() ![]() | |||
| 134 | if (args.length() > DAUDIO_MAX_JSON_LEN || args.empty()) { | 139 | if (args.length() > DAUDIO_MAX_JSON_LEN || args.empty()) { |
| 135 | return ERR_DH_AUDIO_SA_PARAM_INVALID; | 140 | return ERR_DH_AUDIO_SA_PARAM_INVALID; |
| 136 | } | 141 | } |
| @@ -288,6 +293,10 @@ int32_t DAudioSinkDev::TaskStartRender(const std::string &args) | |||
| 288 | int32_t DAudioSinkDev::TaskOpenDMic(const std::string &args) | 293 | int32_t DAudioSinkDev::TaskOpenDMic(const std::string &args) |
| 289 | { | 294 | { |
| 290 | DHLOGI("Open mic device."); | 295 | DHLOGI("Open mic device."); |
| 296 | + if (!DAudioSinkConfigLoader::GetInstance().IsMicSinkEnabled()) { | ||
| 297 | + DHLOGE("Mic sink is disabled by config."); | ||
| 298 | + return ERR_DH_AUDIO_FAILED; | ||
| 299 | + } | ||
| 291 | if (!isDevLevelStatus_) { | 300 | if (!isDevLevelStatus_) { |
| 292 | DHLOGI("Dev security level status is false."); | 301 | DHLOGI("Dev security level status is false."); |
| 293 | return ERR_DH_AUDIO_FAILED; | 302 | return ERR_DH_AUDIO_FAILED; |
| @@ -305,8 +314,7 @@ int32_t DAudioSinkDev::TaskOpenDMic(const std::string &args) | |||
| 305 | CHECK_AND_FREE_RETURN_RET_LOG(ret != DH_SUCCESS, ret, jParam, | 314 | CHECK_AND_FREE_RETURN_RET_LOG(ret != DH_SUCCESS, ret, jParam, |
| 306 | "Get audio param from cjson failed, error code %{public}d.", ret); | 315 | "Get audio param from cjson failed, error code %{public}d.", ret); |
| 307 | int32_t dhId = ParseDhidFromEvent(args); | 316 | int32_t dhId = ParseDhidFromEvent(args); |
| 308 | - CHECK_AND_FREE_RETURN_RET_LOG(dhId == -1, ERR_DH_AUDIO_NULLPTR, jParam, | 317 | + CHECK_AND_FREE_RETURN_RET_LOG(dhId == -1, ERR_DH_AUDIO_NULLPTR, jParam, "%{public}s", "Parse dhId error."); |
| 309 | - "%{public}s", "Parse dhId error."); | ||
| 310 | cJSON_Delete(jParam); | 318 | cJSON_Delete(jParam); |
| 311 | micDhId_ = std::to_string(dhId); | 319 | micDhId_ = std::to_string(dhId); |
| 312 | std::shared_ptr<DMicClient> micClient = nullptr; | 320 | std::shared_ptr<DMicClient> micClient = nullptr; |
| @@ -23,6 +23,7 @@ | |||
| 23 | #include "daudio_constants.h" | 23 | #include "daudio_constants.h" |
| 24 | #include "daudio_errorcode.h" | 24 | #include "daudio_errorcode.h" |
| 25 | #include "daudio_log.h" | 25 | #include "daudio_log.h" |
| 26 | +#include "daudio_sink_config_loader.h" | ||
| 26 | #include "daudio_util.h" | 27 | #include "daudio_util.h" |
| 27 | #include "device_manager.h" | 28 | #include "device_manager.h" |
| 28 | 29 | ||
| @@ -69,6 +70,7 @@ int32_t DAudioSinkManager::Init(const sptr<IDAudioSinkIpcCallback> &sinkCallback | |||
| 69 | return DH_SUCCESS; | 70 | return DH_SUCCESS; |
| 70 | } | 71 | } |
| 71 | DHLOGI("Init audio sink manager."); | 72 | DHLOGI("Init audio sink manager."); |
| 73 | + DAudioSinkConfigLoader::GetInstance().Init(); | ||
| 72 | { | 74 | { |
| 73 | std::lock_guard<std::mutex> ipcLock(ipcCallbackMutex_); | 75 | std::lock_guard<std::mutex> ipcLock(ipcCallbackMutex_); |
| 74 | initCallback_ = std::make_shared<DeviceInitCallback>(); | 76 | initCallback_ = std::make_shared<DeviceInitCallback>(); |
| @@ -58,6 +58,7 @@ ohos_shared_library("distributed_audio_sink") { | |||
| 58 | "${innerkits_path}/native_cpp/audio_sink/src/daudio_sink_load_callback.cpp", | 58 | "${innerkits_path}/native_cpp/audio_sink/src/daudio_sink_load_callback.cpp", |
| 59 | "${innerkits_path}/native_cpp/audio_sink/src/daudio_sink_proxy.cpp", | 59 | "${innerkits_path}/native_cpp/audio_sink/src/daudio_sink_proxy.cpp", |
| 60 | "${innerkits_path}/native_cpp/audio_source/src/daudio_source_proxy.cpp", | 60 | "${innerkits_path}/native_cpp/audio_source/src/daudio_source_proxy.cpp", |
| 61 | + "${services_path}/audiomanager/managersink/src/daudio_sink_config_loader.cpp", | ||
| 61 | "${services_path}/audiomanager/managersink/src/daudio_sink_dev.cpp", | 62 | "${services_path}/audiomanager/managersink/src/daudio_sink_dev.cpp", |
| 62 | "${services_path}/audiomanager/managersink/src/daudio_sink_manager.cpp", | 63 | "${services_path}/audiomanager/managersink/src/daudio_sink_manager.cpp", |
| 63 | "src/daudio_sink_hidumper.cpp", | 64 | "src/daudio_sink_hidumper.cpp", |
| @@ -92,6 +93,7 @@ ohos_shared_library("distributed_audio_sink") { | |||
| 92 | "audio_framework:audio_renderer", | 93 | "audio_framework:audio_renderer", |
| 93 | "cJSON:cjson", | 94 | "cJSON:cjson", |
| 94 | "c_utils:utils", | 95 | "c_utils:utils", |
| 96 | + "config_policy:configpolicy_util", | ||
| 95 | "device_manager:devicemanagersdk", | 97 | "device_manager:devicemanagersdk", |
| 96 | "distributed_hardware_fwk:distributed_av_receiver", | 98 | "distributed_hardware_fwk:distributed_av_receiver", |
| 97 | "distributed_hardware_fwk:distributed_av_sender", | 99 | "distributed_hardware_fwk:distributed_av_sender", |
| @@ -131,9 +131,41 @@ ohos_unittest("DAudioSinkManagerTest") { | |||
| 131 | } | 131 | } |
| 132 | } | 132 | } |
| 133 | 133 | ||
| 134 | +## UnitTest daudio_sink_config_loader_test | ||
| 135 | +ohos_unittest("DAudioSinkConfigLoaderTest") { | ||
| 136 | + module_out_path = module_out_path | ||
| 137 | + | ||
| 138 | + sources = [ "${services_path}/audiomanager/test/unittest/managersink/src/daudio_sink_config_loader_test.cpp" ] | ||
| 139 | + | ||
| 140 | + configs = [ ":module_private_config" ] | ||
| 141 | + | ||
| 142 | + deps = [ | ||
| 143 | + "${innerkits_path}/native_cpp/audio_sink:distributed_audio_sink_sdk", | ||
| 144 | + "${services_path}/audiomanager/servicesink:distributed_audio_sink", | ||
| 145 | + "${services_path}/common:distributed_audio_utils", | ||
| 146 | + ] | ||
| 147 | + | ||
| 148 | + external_deps = [ | ||
| 149 | + "cJSON:cjson", | ||
| 150 | + "c_utils:utils", | ||
| 151 | + "config_policy:configpolicy_util", | ||
| 152 | + "device_manager:devicemanagersdk", | ||
| 153 | + "distributed_hardware_fwk:distributedhardwareutils", | ||
| 154 | + "dsoftbus:softbus_client", | ||
| 155 | + "eventhandler:libeventhandler", | ||
| 156 | + "googletest:gmock", | ||
| 157 | + "hilog:libhilog", | ||
| 158 | + "hitrace:hitrace_meter", | ||
| 159 | + "ipc:ipc_core", | ||
| 160 | + "safwk:system_ability_fwk", | ||
| 161 | + "samgr:samgr_proxy", | ||
| 162 | + ] | ||
| 163 | +} | ||
| 164 | + | ||
| 134 | group("manager_sink_test") { | 165 | group("manager_sink_test") { |
| 135 | testonly = true | 166 | testonly = true |
| 136 | deps = [ | 167 | deps = [ |
| 168 | + ":DAudioSinkConfigLoaderTest", | ||
| 137 | ":DAudioSinkManagerTest", | 169 | ":DAudioSinkManagerTest", |
| 138 | ":DaudioSinkDevTest", | 170 | ":DaudioSinkDevTest", |
| 139 | ] | 171 | ] |
| @@ -0,0 +1,36 @@ | |||
| 1 | +/* | ||
| 2 | + * Copyright (c) 2024-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 | + | ||
| 16 | +#ifndef OHOS_DAUDIO_SINK_CONFIG_LOADER_TEST_H | ||
| 17 | +#define OHOS_DAUDIO_SINK_CONFIG_LOADER_TEST_H | ||
| 18 | + | ||
把UT报告测试结果发一下 ![]() ![]() | |||
| 19 | +#include <gtest/gtest.h> | ||
| 20 | + | ||
| 21 | +#define private public | ||
| 22 | +#include "daudio_sink_config_loader.h" | ||
| 23 | +#undef private | ||
| 24 | + | ||
| 25 | +namespace OHOS { | ||
| 26 | +namespace DistributedHardware { | ||
| 27 | +class DAudioSinkConfigLoaderTest : public testing::Test { | ||
| 28 | +public: | ||
| 29 | + static void SetUpTestCase(void); | ||
| 30 | + static void TearDownTestCase(void); | ||
| 31 | + void SetUp(); | ||
| 32 | + void TearDown(); | ||
| 33 | +}; | ||
| 34 | +} // namespace DistributedHardware | ||
| 35 | +} // namespace OHOS | ||
| 36 | +#endif // OHOS_DAUDIO_SINK_CONFIG_LOADER_TEST_H | ||
| @@ -21,6 +21,7 @@ | |||
| 21 | #include "if_system_ability_manager.h" | 21 | #include "if_system_ability_manager.h" |
| 22 | 22 | ||
| 23 | #define private public | 23 | #define private public |
| 24 | +#include "daudio_sink_config_loader.h" | ||
| 24 | #include "daudio_sink_dev.h" | 25 | #include "daudio_sink_dev.h" |
| 25 | #undef private | 26 | #undef private |
| 26 | 27 | ||
| @@ -0,0 +1,370 @@ | |||
| 1 | +/* | ||
| 2 | + * Copyright (c) 2024-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 | + | ||
| 16 | +#include "daudio_sink_config_loader_test.h" | ||
| 17 | + | ||
| 18 | +#include "cJSON.h" | ||
| 19 | +#include "daudio_constants.h" | ||
| 20 | +#include "daudio_errorcode.h" | ||
| 21 | +#include "daudio_log.h" | ||
| 22 | + | ||
| 23 | +#undef DH_LOG_TAG | ||
| 24 | +#define DH_LOG_TAG "DAudioSinkCfgLoaderTest" | ||
| 25 | + | ||
| 26 | +using namespace testing::ext; | ||
| 27 | + | ||
| 28 | +namespace OHOS { | ||
| 29 | +namespace DistributedHardware { | ||
| 30 | +namespace { | ||
| 31 | +constexpr const char *COMPONENT_ENABLE_CONFIG = "component_enable_config"; | ||
| 32 | +constexpr const char *AUDIO_TYPE_NAME = "AUDIO"; | ||
| 33 | +} | ||
| 34 | + | ||
| 35 | +void DAudioSinkConfigLoaderTest::SetUpTestCase(void) {} | ||
| 36 | +void DAudioSinkConfigLoaderTest::TearDownTestCase(void) {} | ||
| 37 | +void DAudioSinkConfigLoaderTest::SetUp() | ||
| 38 | +{ | ||
| 39 | + auto &loader = DAudioSinkConfigLoader::GetInstance(); | ||
| 40 | + loader.micSinkEnabled_ = true; | ||
| 41 | + loader.speakerSinkEnabled_ = true; | ||
| 42 | + loader.isInitialized_ = false; | ||
| 43 | +} | ||
| 44 | +void DAudioSinkConfigLoaderTest::TearDown() | ||
| 45 | +{ | ||
| 46 | + auto &loader = DAudioSinkConfigLoader::GetInstance(); | ||
| 47 | + loader.micSinkEnabled_ = true; | ||
| 48 | + loader.speakerSinkEnabled_ = true; | ||
| 49 | + loader.isInitialized_ = false; | ||
| 50 | +} | ||
| 51 | + | ||
| 52 | +struct SubtypeConfig { | ||
| 53 | + bool present = false; | ||
| 54 | + bool isBool = false; | ||
| 55 | + bool sinkVal = false; | ||
| 56 | +}; | ||
| 57 | + | ||
| 58 | +static cJSON *BuildEnableConfigJson(const SubtypeConfig &micCfg, const SubtypeConfig &spkCfg) | ||
| 59 | +{ | ||
| 60 | + cJSON *root = cJSON_CreateObject(); | ||
| 61 | + cJSON *enableConfig = cJSON_CreateObject(); | ||
| 62 | + cJSON *audioEntry = cJSON_CreateObject(); | ||
| 63 | + if (micCfg.present) { | ||
| 64 | + if (micCfg.isBool) { | ||
| 65 | + cJSON_AddBoolToObject(audioEntry, MIC.c_str(), micCfg.sinkVal); | ||
| 66 | + } else { | ||
| 67 | + cJSON *micObj = cJSON_CreateObject(); | ||
| 68 | + cJSON_AddBoolToObject(micObj, "sink", micCfg.sinkVal); | ||
| 69 | + cJSON_AddBoolToObject(micObj, "source", true); | ||
| 70 | + cJSON_AddItemToObject(audioEntry, MIC.c_str(), micObj); | ||
| 71 | + } | ||
| 72 | + } | ||
| 73 | + if (spkCfg.present) { | ||
| 74 | + if (spkCfg.isBool) { | ||
| 75 | + cJSON_AddBoolToObject(audioEntry, SPEAKER.c_str(), spkCfg.sinkVal); | ||
| 76 | + } else { | ||
| 77 | + cJSON *spkObj = cJSON_CreateObject(); | ||
| 78 | + cJSON_AddBoolToObject(spkObj, "sink", spkCfg.sinkVal); | ||
| 79 | + cJSON_AddBoolToObject(spkObj, "source", true); | ||
| 80 | + cJSON_AddItemToObject(audioEntry, SPEAKER.c_str(), spkObj); | ||
| 81 | + } | ||
| 82 | + } | ||
| 83 | + cJSON_AddItemToObject(enableConfig, AUDIO_TYPE_NAME, audioEntry); | ||
| 84 | + cJSON_AddItemToObject(root, COMPONENT_ENABLE_CONFIG, enableConfig); | ||
| 85 | + return root; | ||
| 86 | +} | ||
| 87 | + | ||
| 88 | +HWTEST_F(DAudioSinkConfigLoaderTest, ParseAudioEnableConfig_001, TestSize.Level1) | ||
| 89 | +{ | ||
| 90 | + auto &loader = DAudioSinkConfigLoader::GetInstance(); | ||
| 91 | + loader.micSinkEnabled_ = true; | ||
| 92 | + loader.speakerSinkEnabled_ = true; | ||
| 93 | + cJSON *root = BuildEnableConfigJson({true, false, false}, {true, false, false}); | ||
| 94 | + ASSERT_NE(root, nullptr); | ||
| 95 | + loader.ParseAudioEnableConfig(root); | ||
| 96 | + EXPECT_FALSE(loader.micSinkEnabled_); | ||
| 97 | + EXPECT_FALSE(loader.speakerSinkEnabled_); | ||
| 98 | + cJSON_Delete(root); | ||
| 99 | +} | ||
| 100 | + | ||
| 101 | +HWTEST_F(DAudioSinkConfigLoaderTest, ParseAudioEnableConfig_002, TestSize.Level1) | ||
| 102 | +{ | ||
| 103 | + auto &loader = DAudioSinkConfigLoader::GetInstance(); | ||
| 104 | + loader.micSinkEnabled_ = true; | ||
| 105 | + loader.speakerSinkEnabled_ = true; | ||
| 106 | + cJSON *root = BuildEnableConfigJson({true, true, false}, {true, true, true}); | ||
| 107 | + ASSERT_NE(root, nullptr); | ||
| 108 | + loader.ParseAudioEnableConfig(root); | ||
| 109 | + EXPECT_FALSE(loader.micSinkEnabled_); | ||
| 110 | + EXPECT_TRUE(loader.speakerSinkEnabled_); | ||
| 111 | + cJSON_Delete(root); | ||
| 112 | +} | ||
| 113 | + | ||
| 114 | +HWTEST_F(DAudioSinkConfigLoaderTest, ParseAudioEnableConfig_003, TestSize.Level1) | ||
| 115 | +{ | ||
| 116 | + auto &loader = DAudioSinkConfigLoader::GetInstance(); | ||
| 117 | + loader.micSinkEnabled_ = true; | ||
| 118 | + loader.speakerSinkEnabled_ = true; | ||
| 119 | + cJSON *root = BuildEnableConfigJson({true, false, true}, {true, false, true}); | ||
| 120 | + ASSERT_NE(root, nullptr); | ||
| 121 | + loader.ParseAudioEnableConfig(root); | ||
| 122 | + EXPECT_TRUE(loader.micSinkEnabled_); | ||
| 123 | + EXPECT_TRUE(loader.speakerSinkEnabled_); | ||
| 124 | + cJSON_Delete(root); | ||
| 125 | +} | ||
| 126 | + | ||
| 127 | +HWTEST_F(DAudioSinkConfigLoaderTest, ParseAudioEnableConfig_004, TestSize.Level1) | ||
| 128 | +{ | ||
| 129 | + auto &loader = DAudioSinkConfigLoader::GetInstance(); | ||
| 130 | + loader.micSinkEnabled_ = false; | ||
| 131 | + loader.speakerSinkEnabled_ = false; | ||
| 132 | + cJSON *root = BuildEnableConfigJson({false, false, false}, {false, false, false}); | ||
| 133 | + ASSERT_NE(root, nullptr); | ||
| 134 | + loader.ParseAudioEnableConfig(root); | ||
| 135 | + EXPECT_FALSE(loader.micSinkEnabled_); | ||
| 136 | + EXPECT_FALSE(loader.speakerSinkEnabled_); | ||
| 137 | + cJSON_Delete(root); | ||
| 138 | +} | ||
| 139 | + | ||
| 140 | +HWTEST_F(DAudioSinkConfigLoaderTest, ParseAudioEnableConfig_005, TestSize.Level1) | ||
| 141 | +{ | ||
| 142 | + auto &loader = DAudioSinkConfigLoader::GetInstance(); | ||
| 143 | + loader.micSinkEnabled_ = false; | ||
| 144 | + loader.speakerSinkEnabled_ = false; | ||
| 145 | + cJSON *root = cJSON_CreateObject(); | ||
| 146 | + ASSERT_NE(root, nullptr); | ||
| 147 | + loader.ParseAudioEnableConfig(root); | ||
| 148 | + EXPECT_FALSE(loader.micSinkEnabled_); | ||
| 149 | + EXPECT_FALSE(loader.speakerSinkEnabled_); | ||
| 150 | + cJSON_Delete(root); | ||
| 151 | +} | ||
| 152 | + | ||
| 153 | +HWTEST_F(DAudioSinkConfigLoaderTest, ParseAudioEnableConfig_006, TestSize.Level1) | ||
| 154 | +{ | ||
| 155 | + auto &loader = DAudioSinkConfigLoader::GetInstance(); | ||
| 156 | + loader.micSinkEnabled_ = false; | ||
| 157 | + loader.speakerSinkEnabled_ = false; | ||
| 158 | + cJSON *root = cJSON_CreateObject(); | ||
| 159 | + cJSON *enableConfig = cJSON_CreateObject(); | ||
| 160 | + cJSON_AddItemToObject(root, COMPONENT_ENABLE_CONFIG, enableConfig); | ||
| 161 | + loader.ParseAudioEnableConfig(root); | ||
| 162 | + EXPECT_FALSE(loader.micSinkEnabled_); | ||
| 163 | + EXPECT_FALSE(loader.speakerSinkEnabled_); | ||
| 164 | + cJSON_Delete(root); | ||
| 165 | +} | ||
| 166 | + | ||
| 167 | +HWTEST_F(DAudioSinkConfigLoaderTest, ParseAudioEnableConfig_007, TestSize.Level1) | ||
| 168 | +{ | ||
| 169 | + auto &loader = DAudioSinkConfigLoader::GetInstance(); | ||
| 170 | + loader.micSinkEnabled_ = false; | ||
| 171 | + loader.speakerSinkEnabled_ = false; | ||
| 172 | + cJSON *root = cJSON_CreateObject(); | ||
| 173 | + cJSON *enableConfig = cJSON_CreateObject(); | ||
| 174 | + cJSON *audioEntry = cJSON_CreateObject(); | ||
| 175 | + cJSON_AddItemToObject(enableConfig, AUDIO_TYPE_NAME, audioEntry); | ||
| 176 | + cJSON_AddItemToObject(root, COMPONENT_ENABLE_CONFIG, enableConfig); | ||
| 177 | + loader.ParseAudioEnableConfig(root); | ||
| 178 | + EXPECT_FALSE(loader.micSinkEnabled_); | ||
| 179 | + EXPECT_FALSE(loader.speakerSinkEnabled_); | ||
| 180 | + cJSON_Delete(root); | ||
| 181 | +} | ||
| 182 | + | ||
| 183 | +HWTEST_F(DAudioSinkConfigLoaderTest, ParseAudioEnableConfig_008, TestSize.Level1) | ||
| 184 | +{ | ||
| 185 | + auto &loader = DAudioSinkConfigLoader::GetInstance(); | ||
| 186 | + loader.micSinkEnabled_ = true; | ||
| 187 | + loader.speakerSinkEnabled_ = true; | ||
| 188 | + cJSON *root = BuildEnableConfigJson({true, false, false}, {false, false, false}); | ||
| 189 | + ASSERT_NE(root, nullptr); | ||
| 190 | + loader.ParseAudioEnableConfig(root); | ||
| 191 | + EXPECT_FALSE(loader.micSinkEnabled_); | ||
| 192 | + EXPECT_TRUE(loader.speakerSinkEnabled_); | ||
| 193 | + cJSON_Delete(root); | ||
| 194 | +} | ||
| 195 | + | ||
| 196 | +HWTEST_F(DAudioSinkConfigLoaderTest, ParseAudioEnableConfig_009, TestSize.Level1) | ||
| 197 | +{ | ||
| 198 | + auto &loader = DAudioSinkConfigLoader::GetInstance(); | ||
| 199 | + loader.micSinkEnabled_ = true; | ||
| 200 | + loader.speakerSinkEnabled_ = true; | ||
| 201 | + cJSON *root = BuildEnableConfigJson({false, false, false}, {true, false, false}); | ||
| 202 | + ASSERT_NE(root, nullptr); | ||
| 203 | + loader.ParseAudioEnableConfig(root); | ||
| 204 | + EXPECT_TRUE(loader.micSinkEnabled_); | ||
| 205 | + EXPECT_FALSE(loader.speakerSinkEnabled_); | ||
| 206 | + cJSON_Delete(root); | ||
| 207 | +} | ||
| 208 | + | ||
| 209 | +HWTEST_F(DAudioSinkConfigLoaderTest, ParseAudioEnableConfig_nullptr, TestSize.Level1) | ||
| 210 | +{ | ||
| 211 | + auto &loader = DAudioSinkConfigLoader::GetInstance(); | ||
| 212 | + loader.micSinkEnabled_ = false; | ||
| 213 | + loader.speakerSinkEnabled_ = false; | ||
| 214 | + loader.ParseAudioEnableConfig(nullptr); | ||
| 215 | + EXPECT_FALSE(loader.micSinkEnabled_); | ||
| 216 | + EXPECT_FALSE(loader.speakerSinkEnabled_); | ||
| 217 | +} | ||
| 218 | + | ||
| 219 | +HWTEST_F(DAudioSinkConfigLoaderTest, Init_already_initialized, TestSize.Level1) | ||
| 220 | +{ | ||
| 221 | + auto &loader = DAudioSinkConfigLoader::GetInstance(); | ||
| 222 | + loader.isInitialized_ = true; | ||
| 223 | + loader.micSinkEnabled_ = false; | ||
| 224 | + loader.speakerSinkEnabled_ = false; | ||
| 225 | + EXPECT_EQ(DH_SUCCESS, loader.Init()); | ||
| 226 | + EXPECT_FALSE(loader.micSinkEnabled_); | ||
| 227 | + EXPECT_FALSE(loader.speakerSinkEnabled_); | ||
| 228 | +} | ||
| 229 | + | ||
| 230 | +HWTEST_F(DAudioSinkConfigLoaderTest, Init_not_initialized, TestSize.Level1) | ||
| 231 | +{ | ||
| 232 | + auto &loader = DAudioSinkConfigLoader::GetInstance(); | ||
| 233 | + loader.isInitialized_ = false; | ||
| 234 | + EXPECT_EQ(DH_SUCCESS, loader.Init()); | ||
| 235 | + EXPECT_TRUE(loader.isInitialized_); | ||
| 236 | +} | ||
| 237 | + | ||
| 238 | +HWTEST_F(DAudioSinkConfigLoaderTest, IsMicSinkEnabled_default, TestSize.Level1) | ||
| 239 | +{ | ||
| 240 | + auto &loader = DAudioSinkConfigLoader::GetInstance(); | ||
| 241 | + loader.micSinkEnabled_ = true; | ||
| 242 | + EXPECT_TRUE(loader.IsMicSinkEnabled()); | ||
| 243 | +} | ||
| 244 | + | ||
| 245 | +HWTEST_F(DAudioSinkConfigLoaderTest, IsMicSinkEnabled_disabled, TestSize.Level1) | ||
| 246 | +{ | ||
| 247 | + auto &loader = DAudioSinkConfigLoader::GetInstance(); | ||
| 248 | + loader.micSinkEnabled_ = false; | ||
| 249 | + EXPECT_FALSE(loader.IsMicSinkEnabled()); | ||
| 250 | +} | ||
| 251 | + | ||
| 252 | +HWTEST_F(DAudioSinkConfigLoaderTest, IsSpeakerSinkEnabled_default, TestSize.Level1) | ||
| 253 | +{ | ||
| 254 | + auto &loader = DAudioSinkConfigLoader::GetInstance(); | ||
| 255 | + loader.speakerSinkEnabled_ = true; | ||
| 256 | + EXPECT_TRUE(loader.IsSpeakerSinkEnabled()); | ||
| 257 | +} | ||
| 258 | + | ||
| 259 | +HWTEST_F(DAudioSinkConfigLoaderTest, IsSpeakerSinkEnabled_disabled, TestSize.Level1) | ||
| 260 | +{ | ||
| 261 | + auto &loader = DAudioSinkConfigLoader::GetInstance(); | ||
| 262 | + loader.speakerSinkEnabled_ = false; | ||
| 263 | + EXPECT_FALSE(loader.IsSpeakerSinkEnabled()); | ||
| 264 | +} | ||
| 265 | + | ||
| 266 | +HWTEST_F(DAudioSinkConfigLoaderTest, ParseAudioEnableConfig_mic_not_bool_not_object, TestSize.Level1) | ||
| 267 | +{ | ||
| 268 | + auto &loader = DAudioSinkConfigLoader::GetInstance(); | ||
| 269 | + loader.micSinkEnabled_ = false; | ||
| 270 | + loader.speakerSinkEnabled_ = false; | ||
| 271 | + cJSON *root = cJSON_CreateObject(); | ||
| 272 | + cJSON *enableConfig = cJSON_CreateObject(); | ||
| 273 | + cJSON *audioEntry = cJSON_CreateObject(); | ||
| 274 | + cJSON_AddNumberToObject(audioEntry, MIC.c_str(), 123); | ||
| 275 | + cJSON_AddItemToObject(enableConfig, AUDIO_TYPE_NAME, audioEntry); | ||
| 276 | + cJSON_AddItemToObject(root, COMPONENT_ENABLE_CONFIG, enableConfig); | ||
| 277 | + loader.ParseAudioEnableConfig(root); | ||
| 278 | + EXPECT_FALSE(loader.micSinkEnabled_); | ||
| 279 | + cJSON_Delete(root); | ||
| 280 | +} | ||
| 281 | + | ||
| 282 | +HWTEST_F(DAudioSinkConfigLoaderTest, ParseAudioEnableConfig_mic_object_no_sink, TestSize.Level1) | ||
| 283 | +{ | ||
| 284 | + auto &loader = DAudioSinkConfigLoader::GetInstance(); | ||
| 285 | + loader.micSinkEnabled_ = false; | ||
| 286 | + loader.speakerSinkEnabled_ = false; | ||
| 287 | + cJSON *root = cJSON_CreateObject(); | ||
| 288 | + cJSON *enableConfig = cJSON_CreateObject(); | ||
| 289 | + cJSON *audioEntry = cJSON_CreateObject(); | ||
| 290 | + cJSON *micObj = cJSON_CreateObject(); | ||
| 291 | + cJSON_AddBoolToObject(micObj, "source", true); | ||
| 292 | + cJSON_AddItemToObject(audioEntry, MIC.c_str(), micObj); | ||
| 293 | + cJSON_AddItemToObject(enableConfig, AUDIO_TYPE_NAME, audioEntry); | ||
| 294 | + cJSON_AddItemToObject(root, COMPONENT_ENABLE_CONFIG, enableConfig); | ||
| 295 | + loader.ParseAudioEnableConfig(root); | ||
| 296 | + EXPECT_FALSE(loader.micSinkEnabled_); | ||
| 297 | + cJSON_Delete(root); | ||
| 298 | +} | ||
| 299 | + | ||
| 300 | +HWTEST_F(DAudioSinkConfigLoaderTest, ParseAudioEnableConfig_mic_object_sink_not_bool, TestSize.Level1) | ||
| 301 | +{ | ||
| 302 | + auto &loader = DAudioSinkConfigLoader::GetInstance(); | ||
| 303 | + loader.micSinkEnabled_ = false; | ||
| 304 | + loader.speakerSinkEnabled_ = false; | ||
| 305 | + cJSON *root = cJSON_CreateObject(); | ||
| 306 | + cJSON *enableConfig = cJSON_CreateObject(); | ||
| 307 | + cJSON *audioEntry = cJSON_CreateObject(); | ||
| 308 | + cJSON *micObj = cJSON_CreateObject(); | ||
| 309 | + cJSON_AddNumberToObject(micObj, "sink", 123); | ||
| 310 | + cJSON_AddItemToObject(audioEntry, MIC.c_str(), micObj); | ||
| 311 | + cJSON_AddItemToObject(enableConfig, AUDIO_TYPE_NAME, audioEntry); | ||
| 312 | + cJSON_AddItemToObject(root, COMPONENT_ENABLE_CONFIG, enableConfig); | ||
| 313 | + loader.ParseAudioEnableConfig(root); | ||
| 314 | + EXPECT_FALSE(loader.micSinkEnabled_); | ||
| 315 | + cJSON_Delete(root); | ||
| 316 | +} | ||
| 317 | + | ||
| 318 | +HWTEST_F(DAudioSinkConfigLoaderTest, ParseAudioEnableConfig_spk_not_bool_not_object, TestSize.Level1) | ||
| 319 | +{ | ||
| 320 | + auto &loader = DAudioSinkConfigLoader::GetInstance(); | ||
| 321 | + loader.micSinkEnabled_ = false; | ||
| 322 | + loader.speakerSinkEnabled_ = false; | ||
| 323 | + cJSON *root = cJSON_CreateObject(); | ||
| 324 | + cJSON *enableConfig = cJSON_CreateObject(); | ||
| 325 | + cJSON *audioEntry = cJSON_CreateObject(); | ||
| 326 | + cJSON_AddNumberToObject(audioEntry, SPEAKER.c_str(), 123); | ||
| 327 | + cJSON_AddItemToObject(enableConfig, AUDIO_TYPE_NAME, audioEntry); | ||
| 328 | + cJSON_AddItemToObject(root, COMPONENT_ENABLE_CONFIG, enableConfig); | ||
| 329 | + loader.ParseAudioEnableConfig(root); | ||
| 330 | + EXPECT_FALSE(loader.speakerSinkEnabled_); | ||
| 331 | + cJSON_Delete(root); | ||
| 332 | +} | ||
| 333 | + | ||
| 334 | +HWTEST_F(DAudioSinkConfigLoaderTest, ParseAudioEnableConfig_spk_object_no_sink, TestSize.Level1) | ||
| 335 | +{ | ||
| 336 | + auto &loader = DAudioSinkConfigLoader::GetInstance(); | ||
| 337 | + loader.micSinkEnabled_ = false; | ||
| 338 | + loader.speakerSinkEnabled_ = false; | ||
| 339 | + cJSON *root = cJSON_CreateObject(); | ||
| 340 | + cJSON *enableConfig = cJSON_CreateObject(); | ||
| 341 | + cJSON *audioEntry = cJSON_CreateObject(); | ||
| 342 | + cJSON *spkObj = cJSON_CreateObject(); | ||
| 343 | + cJSON_AddBoolToObject(spkObj, "source", true); | ||
| 344 | + cJSON_AddItemToObject(audioEntry, SPEAKER.c_str(), spkObj); | ||
| 345 | + cJSON_AddItemToObject(enableConfig, AUDIO_TYPE_NAME, audioEntry); | ||
| 346 | + cJSON_AddItemToObject(root, COMPONENT_ENABLE_CONFIG, enableConfig); | ||
| 347 | + loader.ParseAudioEnableConfig(root); | ||
| 348 | + EXPECT_FALSE(loader.speakerSinkEnabled_); | ||
| 349 | + cJSON_Delete(root); | ||
| 350 | +} | ||
| 351 | + | ||
| 352 | +HWTEST_F(DAudioSinkConfigLoaderTest, ParseAudioEnableConfig_spk_object_sink_not_bool, TestSize.Level1) | ||
| 353 | +{ | ||
| 354 | + auto &loader = DAudioSinkConfigLoader::GetInstance(); | ||
| 355 | + loader.micSinkEnabled_ = false; | ||
| 356 | + loader.speakerSinkEnabled_ = false; | ||
| 357 | + cJSON *root = cJSON_CreateObject(); | ||
| 358 | + cJSON *enableConfig = cJSON_CreateObject(); | ||
| 359 | + cJSON *audioEntry = cJSON_CreateObject(); | ||
| 360 | + cJSON *spkObj = cJSON_CreateObject(); | ||
| 361 | + cJSON_AddNumberToObject(spkObj, "sink", 123); | ||
| 362 | + cJSON_AddItemToObject(audioEntry, SPEAKER.c_str(), spkObj); | ||
| 363 | + cJSON_AddItemToObject(enableConfig, AUDIO_TYPE_NAME, audioEntry); | ||
| 364 | + cJSON_AddItemToObject(root, COMPONENT_ENABLE_CONFIG, enableConfig); | ||
| 365 | + loader.ParseAudioEnableConfig(root); | ||
| 366 | + EXPECT_FALSE(loader.speakerSinkEnabled_); | ||
| 367 | + cJSON_Delete(root); | ||
| 368 | +} | ||
| 369 | +} // namespace DistributedHardware | ||
| 370 | +} // namespace OHOS | ||
| @@ -1229,79 +1229,6 @@ HWTEST_F(DAudioSinkDevTest, NotifyEnhanceParamChange_002, TestSize.Level1) | |||
| 1229 | sinkDev_->handler_->NotifyEnhanceParamChange(msgEvent); | 1229 | sinkDev_->handler_->NotifyEnhanceParamChange(msgEvent); |
| 1230 | } | 1230 | } |
| 1231 | 1231 | ||
| 1232 | -/** | ||
| 1233 | - * @tc.name: IsHardwareAccessGranted_001 | ||
| 1234 | - * @tc.desc: Verify the IsHardwareAccessGranted function without authorization decision. | ||
| 1235 | - * @tc.type: FUNC | ||
| 1236 | - * @tc.require: AR000H0E5F | ||
| 1237 | - */ | ||
| 1238 | -HWTEST_F(DAudioSinkDevTest, IsHardwareAccessGranted_001, TestSize.Level1) | ||
| 1239 | -{ | ||
| 1240 | - ASSERT_NE(sinkDev_, nullptr); | ||
| 1241 | - bool result = sinkDev_->IsHardwareAccessGranted(); | ||
| 1242 | - EXPECT_EQ(false, result); | ||
| 1243 | -} | ||
| 1244 | - | ||
| 1245 | -/** | ||
| 1246 | - * @tc.name: IsEventAllowedByHardwareAccess_001 | ||
| 1247 | - * @tc.desc: Verify IsEventAllowedByHardwareAccess with OPEN_SPEAKER event. | ||
| 1248 | - * @tc.type: FUNC | ||
| 1249 | - * @tc.require: AR000H0E5F | ||
| 1250 | - */ | ||
| 1251 | -HWTEST_F(DAudioSinkDevTest, IsEventAllowedByHardwareAccess_001, TestSize.Level1) | ||
| 1252 | -{ | ||
| 1253 | - int32_t eventType = OPEN_SPEAKER; | ||
| 1254 | - std::string eventContent = "{\"dhId\":\"1\"}"; | ||
| 1255 | - AudioEvent audioEvent(eventType, eventContent); | ||
| 1256 | - auto eventParam = std::make_shared<AudioEvent>(audioEvent); | ||
| 1257 | - auto msgEvent = AppExecFwk::InnerEvent::Get(static_cast<uint32_t>(audioEvent.type), eventParam, 0); | ||
| 1258 | - ASSERT_NE(sinkDev_, nullptr); | ||
| 1259 | - EXPECT_EQ(DH_SUCCESS, sinkDev_->AwakeAudioDev()); | ||
| 1260 | - ASSERT_NE(sinkDev_->handler_, nullptr); | ||
| 1261 | - sinkDev_->handler_->ProcessEvent(msgEvent); | ||
| 1262 | - ASSERT_NE(sinkDev_->handler_, nullptr); | ||
| 1263 | -} | ||
| 1264 | - | ||
| 1265 | -/** | ||
| 1266 | - * @tc.name: IsEventAllowedByHardwareAccess_002 | ||
| 1267 | - * @tc.desc: Verify IsEventAllowedByHardwareAccess with OPEN_MIC event. | ||
| 1268 | - * @tc.type: FUNC | ||
| 1269 | - * @tc.require: AR000H0E5F | ||
| 1270 | - */ | ||
| 1271 | -HWTEST_F(DAudioSinkDevTest, IsEventAllowedByHardwareAccess_002, TestSize.Level1) | ||
| 1272 | -{ | ||
| 1273 | - int32_t eventType = OPEN_MIC; | ||
| 1274 | - std::string eventContent = "{\"dhId\":\"1\"}"; | ||
| 1275 | - AudioEvent audioEvent(eventType, eventContent); | ||
| 1276 | - auto eventParam = std::make_shared<AudioEvent>(audioEvent); | ||
| 1277 | - auto msgEvent = AppExecFwk::InnerEvent::Get(static_cast<uint32_t>(audioEvent.type), eventParam, 0); | ||
| 1278 | - ASSERT_NE(sinkDev_, nullptr); | ||
| 1279 | - EXPECT_EQ(DH_SUCCESS, sinkDev_->AwakeAudioDev()); | ||
| 1280 | - ASSERT_NE(sinkDev_->handler_, nullptr); | ||
| 1281 | - sinkDev_->handler_->ProcessEvent(msgEvent); | ||
| 1282 | - ASSERT_NE(sinkDev_->handler_, nullptr); | ||
| 1283 | -} | ||
| 1284 | - | ||
| 1285 | -/** | ||
| 1286 | - * @tc.name: IsEventAllowedByHardwareAccess_003 | ||
| 1287 | - * @tc.desc: Verify IsEventAllowedByHardwareAccess with other event type. | ||
| 1288 | - * @tc.type: FUNC | ||
| 1289 | - * @tc.require: AR000H0E5F | ||
| 1290 | - */ | ||
| 1291 | -HWTEST_F(DAudioSinkDevTest, IsEventAllowedByHardwareAccess_003, TestSize.Level1) | ||
| 1292 | -{ | ||
| 1293 | - int32_t eventType = VOLUME_SET; | ||
| 1294 | - std::string eventContent = "{\"dhId\":\"1\"}"; | ||
| 1295 | - AudioEvent audioEvent(eventType, eventContent); | ||
| 1296 | - auto eventParam = std::make_shared<AudioEvent>(audioEvent); | ||
| 1297 | - auto msgEvent = AppExecFwk::InnerEvent::Get(static_cast<uint32_t>(audioEvent.type), eventParam, 0); | ||
| 1298 | - ASSERT_NE(sinkDev_, nullptr); | ||
| 1299 | - EXPECT_EQ(DH_SUCCESS, sinkDev_->AwakeAudioDev()); | ||
| 1300 | - ASSERT_NE(sinkDev_->handler_, nullptr); | ||
| 1301 | - sinkDev_->handler_->ProcessEvent(msgEvent); | ||
| 1302 | - ASSERT_NE(sinkDev_->handler_, nullptr); | ||
| 1303 | -} | ||
| 1304 | - | ||
| 1305 | HWTEST_F(DAudioSinkDevTest, ResolveEnableUser_001, TestSize.Level1) | 1232 | HWTEST_F(DAudioSinkDevTest, ResolveEnableUser_001, TestSize.Level1) |
B 🤖 AI 代码检视意见 | ✨ Quality | ℹ️ Medium | 行号区间: L1232 问题描述: 此 PR 删除了 IsHardwareAccessGranted 和 IsEventAllowedByHardwareAccess 系列测试用例,但在源文件 daudio_sink_dev.cpp 的 diff 中未见删除对应的函数实现。如果源码中这些函数仍然存在,删除测试用例将导致代码覆盖率下降,违反测试完整性原则。 💡 查看修复建议(点击展开)修改建议:检查 IsHardwareAccessGranted 和 IsEventAllowedByHardwareAccess 方法在 daudio_sink_dev.cpp 中是否仍存在。若仍存在,请恢复对应的测试用例以维持代码覆盖率;若已删除,请忽略此建议。
![]() ![]() | |||
| 1306 | { | 1233 | { |
| 1307 | ASSERT_NE(sinkDev_, nullptr); | 1234 | ASSERT_NE(sinkDev_, nullptr); |
| @@ -1377,5 +1304,49 @@ HWTEST_F(DAudioSinkDevTest, CheckAclRight_ResolveEnableUser_002, TestSize.Level1 | |||
| 1377 | DAudioSinkManager::GetInstance().SetEnableFirstTokenId(0); | 1304 | DAudioSinkManager::GetInstance().SetEnableFirstTokenId(0); |
| 1378 | } | 1305 | } |
| 1379 | 1306 | ||
| 1307 | +HWTEST_F(DAudioSinkDevTest, TaskOpenDSpeaker_config_disabled, TestSize.Level1) | ||
| 1308 | +{ | ||
| 1309 | + ASSERT_NE(sinkDev_, nullptr); | ||
| 1310 | + auto &loader = DAudioSinkConfigLoader::GetInstance(); | ||
| 1311 | + bool saved = loader.speakerSinkEnabled_; | ||
| 1312 | + loader.speakerSinkEnabled_ = false; | ||
| 1313 | + std::string args = "{\"dhId\":\"1\"}"; | ||
| 1314 | + EXPECT_EQ(ERR_DH_AUDIO_FAILED, sinkDev_->TaskOpenDSpeaker(args)); | ||
| 1315 | + loader.speakerSinkEnabled_ = saved; | ||
| 1316 | +} | ||
| 1317 | + | ||
| 1318 | +HWTEST_F(DAudioSinkDevTest, TaskOpenDSpeaker_config_enabled, TestSize.Level1) | ||
| 1319 | +{ | ||
| 1320 | + ASSERT_NE(sinkDev_, nullptr); | ||
| 1321 | + auto &loader = DAudioSinkConfigLoader::GetInstance(); | ||
| 1322 | + bool saved = loader.speakerSinkEnabled_; | ||
| 1323 | + loader.speakerSinkEnabled_ = true; | ||
| 1324 | + std::string args; | ||
| 1325 | + EXPECT_NE(DH_SUCCESS, sinkDev_->TaskOpenDSpeaker(args)); | ||
| 1326 | + loader.speakerSinkEnabled_ = saved; | ||
| 1327 | +} | ||
| 1328 | + | ||
| 1329 | +HWTEST_F(DAudioSinkDevTest, TaskOpenDMic_config_disabled, TestSize.Level1) | ||
| 1330 | +{ | ||
| 1331 | + ASSERT_NE(sinkDev_, nullptr); | ||
| 1332 | + auto &loader = DAudioSinkConfigLoader::GetInstance(); | ||
| 1333 | + bool saved = loader.micSinkEnabled_; | ||
| 1334 | + loader.micSinkEnabled_ = false; | ||
| 1335 | + std::string args = "{\"dhId\":\"1\"}"; | ||
| 1336 | + EXPECT_EQ(ERR_DH_AUDIO_FAILED, sinkDev_->TaskOpenDMic(args)); | ||
| 1337 | + loader.micSinkEnabled_ = saved; | ||
| 1338 | +} | ||
| 1339 | + | ||
| 1340 | +HWTEST_F(DAudioSinkDevTest, TaskOpenDMic_config_enabled, TestSize.Level1) | ||
| 1341 | +{ | ||
| 1342 | + ASSERT_NE(sinkDev_, nullptr); | ||
| 1343 | + auto &loader = DAudioSinkConfigLoader::GetInstance(); | ||
| 1344 | + bool saved = loader.micSinkEnabled_; | ||
| 1345 | + loader.micSinkEnabled_ = true; | ||
| 1346 | + std::string args; | ||
| 1347 | + EXPECT_NE(DH_SUCCESS, sinkDev_->TaskOpenDMic(args)); | ||
| 1348 | + loader.micSinkEnabled_ = saved; | ||
| 1349 | +} | ||
| 1350 | + | ||
| 1380 | } // DistributedHardware | 1351 | } // DistributedHardware |
| 1381 | } // OHOS | 1352 | } // OHOS |


🤖 AI 代码检视意见 | ✨ Quality | ✅ Low | 行号区间: L56-L67
问题描述: 使用 while(getline) 逐行读取并 append 字符串效率较低,且显式调用 infile.close() 在 RAII 机制下是多余的。虽然功能正确,但在处理大文件或频繁读取时会有不必要的性能开销和代码冗余。
💡 查看修复建议(点击展开)
修改建议:使用流迭代器一次性读取文件内容,提升读取效率,并依赖 RAII 自动管理文件句柄,移除显式的 close 调用。