audio_manager_chromeos_unittest.cc 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367
  1. // Copyright (c) 2021 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "media/audio/cras/audio_manager_chromeos.h"
  5. #include "base/test/scoped_feature_list.h"
  6. #include "build/chromeos_buildflags.h"
  7. #include "media/audio/audio_features.h"
  8. #include "testing/gtest/include/gtest/gtest.h"
  9. namespace media {
  10. namespace {
  11. constexpr int kAecTestGroupId = 9;
  12. constexpr int kNoAecFlaggedGroupId = 0;
  13. // Chosen to be the same as in `audio_manager_chromeos.cc`, but any size should
  14. // work since this should not affect the testing done herein.
  15. constexpr int kDefaultInputBufferSize = 1024;
  16. bool ExperimentalAecActive(const AudioParameters& params) {
  17. return params.effects() & AudioParameters::EXPERIMENTAL_ECHO_CANCELLER;
  18. }
  19. bool AecActive(const AudioParameters& params) {
  20. return params.effects() & AudioParameters::ECHO_CANCELLER;
  21. }
  22. bool NsActive(const AudioParameters& params) {
  23. return params.effects() & AudioParameters::NOISE_SUPPRESSION;
  24. }
  25. bool AgcActive(const AudioParameters& params) {
  26. return params.effects() & AudioParameters::AUTOMATIC_GAIN_CONTROL;
  27. }
  28. bool DspAecAllowed(const AudioParameters& params) {
  29. return params.effects() & AudioParameters::ALLOW_DSP_ECHO_CANCELLER &&
  30. params.effects() & AudioParameters::ECHO_CANCELLER;
  31. }
  32. bool DspNsAllowed(const AudioParameters& params) {
  33. return params.effects() & AudioParameters::ALLOW_DSP_NOISE_SUPPRESSION &&
  34. params.effects() & AudioParameters::NOISE_SUPPRESSION;
  35. }
  36. bool DspAgcAllowed(const AudioParameters& params) {
  37. return params.effects() & AudioParameters::ALLOW_DSP_AUTOMATIC_GAIN_CONTROL &&
  38. params.effects() & AudioParameters::AUTOMATIC_GAIN_CONTROL;
  39. }
  40. } // namespace
  41. class GetStreamParametersForSystem
  42. : public ::testing::Test,
  43. public ::testing::WithParamInterface<
  44. std::tuple<int, bool, int32_t, bool, bool>> {
  45. protected:
  46. // Retrieve test parameter values.
  47. void GetTestParameters() {
  48. user_buffer_size_ = std::get<0>(GetParam());
  49. system_apm_info_.aec_supported = std::get<1>(GetParam());
  50. system_apm_info_.aec_group_id = std::get<2>(GetParam());
  51. system_apm_info_.ns_supported = std::get<3>(GetParam());
  52. system_apm_info_.agc_supported = std::get<4>(GetParam());
  53. }
  54. AudioManagerChromeOS::SystemAudioProcessingInfo system_apm_info_;
  55. size_t user_buffer_size_;
  56. };
  57. INSTANTIATE_TEST_SUITE_P(
  58. AllInputParameters,
  59. GetStreamParametersForSystem,
  60. ::testing::Combine(::testing::Values(512, kDefaultInputBufferSize),
  61. ::testing::Values(false, true),
  62. ::testing::Values(kNoAecFlaggedGroupId, kAecTestGroupId),
  63. ::testing::Values(false, true),
  64. ::testing::Values(false, true)));
  65. TEST_P(GetStreamParametersForSystem, DefaultBehavior) {
  66. GetTestParameters();
  67. AudioParameters params = AudioManagerChromeOS::GetStreamParametersForSystem(
  68. user_buffer_size_, system_apm_info_);
  69. EXPECT_TRUE(ExperimentalAecActive(params));
  70. EXPECT_EQ(AecActive(params), system_apm_info_.aec_supported);
  71. if (system_apm_info_.aec_supported) {
  72. EXPECT_FALSE(NsActive(params));
  73. EXPECT_FALSE(AgcActive(params));
  74. } else {
  75. EXPECT_FALSE(NsActive(params));
  76. EXPECT_FALSE(AgcActive(params));
  77. }
  78. }
  79. TEST_P(GetStreamParametersForSystem,
  80. BehaviorWithCrOSEnforceSystemAecDisallowed) {
  81. base::test::ScopedFeatureList feature_list;
  82. feature_list.InitAndDisableFeature(features::kCrOSSystemAEC);
  83. GetTestParameters();
  84. AudioParameters params = AudioManagerChromeOS::GetStreamParametersForSystem(
  85. user_buffer_size_, system_apm_info_);
  86. EXPECT_TRUE(ExperimentalAecActive(params));
  87. EXPECT_FALSE(AecActive(params));
  88. EXPECT_FALSE(NsActive(params));
  89. EXPECT_FALSE(AgcActive(params));
  90. }
  91. TEST_P(GetStreamParametersForSystem, BehaviorWithCrOSEnforceSystemAecNsAgc) {
  92. base::test::ScopedFeatureList feature_list;
  93. feature_list.InitAndEnableFeature(features::kCrOSEnforceSystemAecNsAgc);
  94. GetTestParameters();
  95. AudioParameters params = AudioManagerChromeOS::GetStreamParametersForSystem(
  96. user_buffer_size_, system_apm_info_);
  97. EXPECT_TRUE(ExperimentalAecActive(params));
  98. EXPECT_TRUE(AecActive(params));
  99. if (system_apm_info_.aec_supported) {
  100. EXPECT_FALSE(NsActive(params));
  101. EXPECT_FALSE(AgcActive(params));
  102. } else {
  103. EXPECT_TRUE(NsActive(params));
  104. EXPECT_TRUE(AgcActive(params));
  105. }
  106. }
  107. // TODO(crbug.com/1216273): DCHECKs are disabled during automated testing on
  108. // CrOS and this test failed when tested on an experimental builder with
  109. // DCHECKs. Revert https://crrev.com/c/2959990 to re-enable it.
  110. // See go/chrome-dcheck-on-cros or http://crbug.com/1113456 for more details.
  111. #if !BUILDFLAG(IS_CHROMEOS_ASH)
  112. TEST_P(GetStreamParametersForSystem,
  113. BehaviorWithCrOSEnforceSystemAecNsAndAecAgc) {
  114. base::test::ScopedFeatureList feature_list;
  115. feature_list.InitAndEnableFeature(features::kCrOSEnforceSystemAecNs);
  116. feature_list.InitAndEnableFeature(features::kCrOSEnforceSystemAecAgc);
  117. GetTestParameters();
  118. AudioParameters params = AudioManagerChromeOS::GetStreamParametersForSystem(
  119. user_buffer_size_, system_apm_info_);
  120. EXPECT_TRUE(ExperimentalAecActive(params));
  121. EXPECT_TRUE(AecActive(params));
  122. if (system_apm_info_.aec_supported) {
  123. EXPECT_FALSE(NsActive(params));
  124. EXPECT_FALSE(AgcActive(params));
  125. } else {
  126. EXPECT_TRUE(NsActive(params));
  127. EXPECT_TRUE(AgcActive(params));
  128. }
  129. }
  130. #endif
  131. // TODO(crbug.com/1216273): DCHECKs are disabled during automated testing on
  132. // CrOS and this test failed when tested on an experimental builder with
  133. // DCHECKs. Revert https://crrev.com/c/2959990 to re-enable it.
  134. // See go/chrome-dcheck-on-cros or http://crbug.com/1113456 for more details.
  135. #if !BUILDFLAG(IS_CHROMEOS_ASH)
  136. TEST_P(GetStreamParametersForSystem,
  137. BehaviorWithCrOSEnforceSystemAecNsAgcAndDisallowedSystemAec) {
  138. base::test::ScopedFeatureList feature_list;
  139. feature_list.InitAndEnableFeature(features::kCrOSEnforceSystemAecNsAgc);
  140. feature_list.InitAndDisableFeature(features::kCrOSSystemAEC);
  141. GetTestParameters();
  142. AudioParameters params = AudioManagerChromeOS::GetStreamParametersForSystem(
  143. user_buffer_size_, system_apm_info_);
  144. EXPECT_TRUE(ExperimentalAecActive(params));
  145. EXPECT_TRUE(AecActive(params));
  146. if (system_apm_info_.aec_supported) {
  147. EXPECT_FALSE(NsActive(params));
  148. EXPECT_FALSE(AgcActive(params));
  149. } else {
  150. EXPECT_TRUE(NsActive(params));
  151. EXPECT_TRUE(AgcActive(params));
  152. }
  153. }
  154. #endif
  155. TEST_P(GetStreamParametersForSystem, BehaviorWithCrOSEnforceSystemAecNs) {
  156. base::test::ScopedFeatureList feature_list;
  157. feature_list.InitAndEnableFeature(features::kCrOSEnforceSystemAecNs);
  158. GetTestParameters();
  159. AudioParameters params = AudioManagerChromeOS::GetStreamParametersForSystem(
  160. user_buffer_size_, system_apm_info_);
  161. EXPECT_TRUE(ExperimentalAecActive(params));
  162. EXPECT_TRUE(AecActive(params));
  163. if (system_apm_info_.aec_supported) {
  164. EXPECT_FALSE(NsActive(params));
  165. EXPECT_FALSE(AgcActive(params));
  166. } else {
  167. EXPECT_TRUE(NsActive(params));
  168. EXPECT_EQ(AgcActive(params), system_apm_info_.agc_supported);
  169. }
  170. }
  171. TEST_P(GetStreamParametersForSystem, BehaviorWithCrOSEnforceSystemAecAgc) {
  172. base::test::ScopedFeatureList feature_list;
  173. feature_list.InitAndEnableFeature(features::kCrOSEnforceSystemAecAgc);
  174. GetTestParameters();
  175. AudioParameters params = AudioManagerChromeOS::GetStreamParametersForSystem(
  176. user_buffer_size_, system_apm_info_);
  177. EXPECT_TRUE(ExperimentalAecActive(params));
  178. EXPECT_TRUE(AecActive(params));
  179. if (system_apm_info_.aec_supported) {
  180. EXPECT_FALSE(NsActive(params));
  181. EXPECT_FALSE(AgcActive(params));
  182. } else {
  183. EXPECT_EQ(NsActive(params), system_apm_info_.ns_supported);
  184. EXPECT_TRUE(AgcActive(params));
  185. }
  186. }
  187. TEST_P(GetStreamParametersForSystem, BehaviorWithCrOSEnforceSystemAec) {
  188. base::test::ScopedFeatureList feature_list;
  189. feature_list.InitAndEnableFeature(features::kCrOSEnforceSystemAec);
  190. GetTestParameters();
  191. AudioParameters params = AudioManagerChromeOS::GetStreamParametersForSystem(
  192. user_buffer_size_, system_apm_info_);
  193. EXPECT_TRUE(ExperimentalAecActive(params));
  194. EXPECT_TRUE(AecActive(params));
  195. if (system_apm_info_.aec_supported) {
  196. EXPECT_FALSE(NsActive(params));
  197. EXPECT_FALSE(AgcActive(params));
  198. } else {
  199. EXPECT_EQ(NsActive(params), system_apm_info_.ns_supported);
  200. EXPECT_EQ(AgcActive(params), system_apm_info_.agc_supported);
  201. }
  202. }
  203. class AllowedDspParameters
  204. : public ::testing::Test,
  205. public ::testing::WithParamInterface<std::tuple<bool, bool, bool>> {
  206. protected:
  207. // Retrieve test parameter values.
  208. void GetTestParameters() {
  209. system_apm_info_.aec_group_id = 0;
  210. system_apm_info_.aec_supported = false;
  211. system_apm_info_.ns_supported = false;
  212. system_apm_info_.agc_supported = false;
  213. aec_on_dsp_allowed_ = std::get<0>(GetParam());
  214. ns_on_dsp_allowed_ = std::get<1>(GetParam());
  215. agc_on_dsp_allowed_ = std::get<2>(GetParam());
  216. if (aec_on_dsp_allowed_) {
  217. enabled_features_.emplace_back(features::kCrOSDspBasedAecAllowed);
  218. } else {
  219. disabled_features_.emplace_back(features::kCrOSDspBasedAecAllowed);
  220. }
  221. if (ns_on_dsp_allowed_) {
  222. enabled_features_.emplace_back(features::kCrOSDspBasedNsAllowed);
  223. } else {
  224. disabled_features_.emplace_back(features::kCrOSDspBasedNsAllowed);
  225. }
  226. if (agc_on_dsp_allowed_) {
  227. enabled_features_.emplace_back(features::kCrOSDspBasedAgcAllowed);
  228. } else {
  229. disabled_features_.emplace_back(features::kCrOSDspBasedAgcAllowed);
  230. }
  231. }
  232. AudioManagerChromeOS::SystemAudioProcessingInfo system_apm_info_;
  233. size_t user_buffer_size_ = kDefaultInputBufferSize;
  234. std::vector<base::Feature> enabled_features_;
  235. std::vector<base::Feature> disabled_features_;
  236. bool aec_on_dsp_allowed_;
  237. bool ns_on_dsp_allowed_;
  238. bool agc_on_dsp_allowed_;
  239. };
  240. INSTANTIATE_TEST_SUITE_P(AllAllowedDspInputParameters,
  241. AllowedDspParameters,
  242. ::testing::Combine(::testing::Values(false, true),
  243. ::testing::Values(false, true),
  244. ::testing::Values(false, true)));
  245. TEST_P(AllowedDspParameters, BehaviorWithoutAnyEnforcedEffects) {
  246. GetTestParameters();
  247. base::test::ScopedFeatureList feature_list;
  248. feature_list.InitWithFeatures(enabled_features_, disabled_features_);
  249. AudioParameters params = AudioManagerChromeOS::GetStreamParametersForSystem(
  250. user_buffer_size_, system_apm_info_);
  251. EXPECT_FALSE(DspAecAllowed(params));
  252. EXPECT_FALSE(DspNsAllowed(params));
  253. EXPECT_FALSE(DspAgcAllowed(params));
  254. }
  255. TEST_P(AllowedDspParameters, BehaviorWithCrOSEnforceSystemAec) {
  256. GetTestParameters();
  257. base::test::ScopedFeatureList feature_list;
  258. enabled_features_.emplace_back(features::kCrOSEnforceSystemAec);
  259. feature_list.InitWithFeatures(enabled_features_, disabled_features_);
  260. AudioParameters params = AudioManagerChromeOS::GetStreamParametersForSystem(
  261. user_buffer_size_, system_apm_info_);
  262. EXPECT_TRUE(DspAecAllowed(params) && aec_on_dsp_allowed_ ||
  263. !DspAecAllowed(params) && !aec_on_dsp_allowed_);
  264. EXPECT_FALSE(DspNsAllowed(params));
  265. EXPECT_FALSE(DspAgcAllowed(params));
  266. }
  267. TEST_P(AllowedDspParameters, BehaviorWithCrOSEnforceSystemAecNs) {
  268. GetTestParameters();
  269. base::test::ScopedFeatureList feature_list;
  270. enabled_features_.emplace_back(features::kCrOSEnforceSystemAecNs);
  271. feature_list.InitWithFeatures(enabled_features_, disabled_features_);
  272. AudioParameters params = AudioManagerChromeOS::GetStreamParametersForSystem(
  273. user_buffer_size_, system_apm_info_);
  274. EXPECT_TRUE(DspAecAllowed(params) && aec_on_dsp_allowed_ ||
  275. !DspAecAllowed(params) && !aec_on_dsp_allowed_);
  276. EXPECT_TRUE(DspNsAllowed(params) && ns_on_dsp_allowed_ ||
  277. !DspNsAllowed(params) && !ns_on_dsp_allowed_);
  278. EXPECT_FALSE(DspAgcAllowed(params));
  279. }
  280. TEST_P(AllowedDspParameters, BehaviorWithCrOSEnforceSystemAecAgc) {
  281. GetTestParameters();
  282. base::test::ScopedFeatureList feature_list;
  283. enabled_features_.emplace_back(features::kCrOSEnforceSystemAecAgc);
  284. feature_list.InitWithFeatures(enabled_features_, disabled_features_);
  285. AudioParameters params = AudioManagerChromeOS::GetStreamParametersForSystem(
  286. user_buffer_size_, system_apm_info_);
  287. EXPECT_TRUE(DspAecAllowed(params) && aec_on_dsp_allowed_ ||
  288. !DspAecAllowed(params) && !aec_on_dsp_allowed_);
  289. EXPECT_FALSE(DspNsAllowed(params));
  290. EXPECT_TRUE(DspAgcAllowed(params) && agc_on_dsp_allowed_ ||
  291. !DspAgcAllowed(params) && !agc_on_dsp_allowed_);
  292. }
  293. TEST_P(AllowedDspParameters, BehaviorWithCrOSEnforceSystemAecNsAgc) {
  294. GetTestParameters();
  295. base::test::ScopedFeatureList feature_list;
  296. enabled_features_.emplace_back(features::kCrOSEnforceSystemAecNsAgc);
  297. feature_list.InitWithFeatures(enabled_features_, disabled_features_);
  298. AudioParameters params = AudioManagerChromeOS::GetStreamParametersForSystem(
  299. user_buffer_size_, system_apm_info_);
  300. EXPECT_TRUE(DspAecAllowed(params) && aec_on_dsp_allowed_ ||
  301. !DspAecAllowed(params) && !aec_on_dsp_allowed_);
  302. EXPECT_TRUE(DspNsAllowed(params) && ns_on_dsp_allowed_ ||
  303. !DspNsAllowed(params) && !ns_on_dsp_allowed_);
  304. EXPECT_TRUE(DspAgcAllowed(params) && agc_on_dsp_allowed_ ||
  305. !DspAgcAllowed(params) && !agc_on_dsp_allowed_);
  306. }
  307. } // namespace media