input_controller_unittest.cc 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685
  1. // Copyright (c) 2012 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 "services/audio/input_controller.h"
  5. #include <memory>
  6. #include <utility>
  7. #include "base/run_loop.h"
  8. #include "base/test/bind.h"
  9. #include "base/test/scoped_feature_list.h"
  10. #include "base/test/task_environment.h"
  11. #include "media/audio/audio_manager.h"
  12. #include "media/audio/fake_audio_input_stream.h"
  13. #include "media/audio/fake_audio_log_factory.h"
  14. #include "media/audio/fake_audio_manager.h"
  15. #include "media/audio/test_audio_thread.h"
  16. #include "media/base/audio_processing.h"
  17. #include "media/base/media_switches.h"
  18. #include "media/base/user_input_monitor.h"
  19. #include "mojo/public/cpp/bindings/remote.h"
  20. #include "services/audio/aecdump_recording_manager.h"
  21. #include "services/audio/concurrent_stream_metric_reporter.h"
  22. #include "services/audio/device_output_listener.h"
  23. #include "services/audio/processing_audio_fifo.h"
  24. #include "services/audio/reference_output.h"
  25. #include "testing/gmock/include/gmock/gmock.h"
  26. #include "testing/gtest/include/gtest/gtest.h"
  27. using ::testing::_;
  28. using ::testing::AtLeast;
  29. using ::testing::Exactly;
  30. using ::testing::InvokeWithoutArgs;
  31. using ::testing::NiceMock;
  32. using ::testing::NotNull;
  33. using ::testing::StrictMock;
  34. namespace audio {
  35. namespace {
  36. const int kSampleRate = media::AudioParameters::kAudioCDSampleRate;
  37. const media::ChannelLayout kChannelLayout = media::CHANNEL_LAYOUT_STEREO;
  38. const int kSamplesPerPacket = kSampleRate / 100;
  39. // InputController will poll once every second, so wait at most a bit
  40. // more than that for the callbacks.
  41. constexpr base::TimeDelta kOnMutePollInterval = base::Milliseconds(1000);
  42. enum class ProcessingFifoSetting {
  43. kEnabled,
  44. kEnabledWithSizeZero,
  45. kDisabled,
  46. };
  47. const std::string kFifoSizeParameter = "processing_fifo_size";
  48. const std::map<std::string, std::string> kDisabledFifoParam{
  49. {kFifoSizeParameter, "0"}};
  50. const std::map<std::string, std::string> kEnabledFifoParam{
  51. {kFifoSizeParameter, "110"}};
  52. } // namespace
  53. class MockInputControllerEventHandler : public InputController::EventHandler {
  54. public:
  55. MockInputControllerEventHandler() = default;
  56. MockInputControllerEventHandler(const MockInputControllerEventHandler&) =
  57. delete;
  58. MockInputControllerEventHandler& operator=(
  59. const MockInputControllerEventHandler&) = delete;
  60. void OnLog(base::StringPiece) override {}
  61. MOCK_METHOD1(OnCreated, void(bool initially_muted));
  62. MOCK_METHOD1(OnError, void(InputController::ErrorCode error_code));
  63. MOCK_METHOD1(OnMuted, void(bool is_muted));
  64. };
  65. class MockSyncWriter : public InputController::SyncWriter {
  66. public:
  67. MockSyncWriter() = default;
  68. MOCK_METHOD4(Write,
  69. void(const media::AudioBus* data,
  70. double volume,
  71. bool key_pressed,
  72. base::TimeTicks capture_time));
  73. MOCK_METHOD0(Close, void());
  74. };
  75. class MockUserInputMonitor : public media::UserInputMonitor {
  76. public:
  77. MockUserInputMonitor() = default;
  78. uint32_t GetKeyPressCount() const override { return 0; }
  79. MOCK_METHOD0(EnableKeyPressMonitoring, void());
  80. MOCK_METHOD0(DisableKeyPressMonitoring, void());
  81. };
  82. class MockInputStreamActivityMonitor : public InputStreamActivityMonitor {
  83. public:
  84. MockInputStreamActivityMonitor() = default;
  85. MOCK_METHOD0(OnInputStreamActive, void());
  86. MOCK_METHOD0(OnInputStreamInactive, void());
  87. };
  88. template <base::test::TaskEnvironment::TimeSource TimeSource =
  89. base::test::TaskEnvironment::TimeSource::MOCK_TIME>
  90. class TimeSourceInputControllerTest
  91. : public ::testing::TestWithParam<ProcessingFifoSetting> {
  92. public:
  93. TimeSourceInputControllerTest()
  94. : task_environment_(TimeSource),
  95. audio_manager_(std::make_unique<media::FakeAudioManager>(
  96. std::make_unique<media::TestAudioThread>(false),
  97. &log_factory_)),
  98. aecdump_recording_manager_(audio_manager_->GetTaskRunner()),
  99. params_(media::AudioParameters::AUDIO_FAKE,
  100. kChannelLayout,
  101. kSampleRate,
  102. kSamplesPerPacket) {
  103. #if BUILDFLAG(CHROME_WIDE_ECHO_CANCELLATION)
  104. switch (GetParam()) {
  105. case ProcessingFifoSetting::kEnabled:
  106. processing_fifo_feature_.InitAndEnableFeatureWithParameters(
  107. media::kChromeWideEchoCancellation, kEnabledFifoParam);
  108. break;
  109. case ProcessingFifoSetting::kEnabledWithSizeZero:
  110. processing_fifo_feature_.InitAndEnableFeatureWithParameters(
  111. media::kChromeWideEchoCancellation, kDisabledFifoParam);
  112. break;
  113. case ProcessingFifoSetting::kDisabled:
  114. processing_fifo_feature_.InitAndDisableFeature(
  115. media::kChromeWideEchoCancellation);
  116. break;
  117. };
  118. #endif
  119. }
  120. TimeSourceInputControllerTest(const TimeSourceInputControllerTest&) = delete;
  121. TimeSourceInputControllerTest& operator=(
  122. const TimeSourceInputControllerTest&) = delete;
  123. ~TimeSourceInputControllerTest() override {
  124. audio_manager_->Shutdown();
  125. task_environment_.RunUntilIdle();
  126. }
  127. protected:
  128. virtual void CreateAudioController() {
  129. controller_ = InputController::Create(
  130. audio_manager_.get(), &event_handler_, &sync_writer_,
  131. &user_input_monitor_, &mock_stream_activity_monitor_,
  132. /*device_output_listener =*/nullptr, &aecdump_recording_manager_,
  133. /*processing_config =*/nullptr, params_,
  134. media::AudioDeviceDescription::kDefaultDeviceId, false);
  135. }
  136. bool IsProcessingFifoEnabled() {
  137. return GetParam() == ProcessingFifoSetting::kEnabled;
  138. }
  139. base::test::TaskEnvironment task_environment_;
  140. #if BUILDFLAG(CHROME_WIDE_ECHO_CANCELLATION)
  141. base::test::ScopedFeatureList processing_fifo_feature_;
  142. #endif
  143. std::unique_ptr<media::AudioManager> audio_manager_;
  144. AecdumpRecordingManager aecdump_recording_manager_;
  145. std::unique_ptr<InputController> controller_;
  146. media::FakeAudioLogFactory log_factory_;
  147. MockInputControllerEventHandler event_handler_;
  148. MockSyncWriter sync_writer_;
  149. MockUserInputMonitor user_input_monitor_;
  150. StrictMock<MockInputStreamActivityMonitor> mock_stream_activity_monitor_;
  151. media::AudioParameters params_;
  152. };
  153. auto test_name_generator =
  154. [](const ::testing::TestParamInfo<
  155. TimeSourceInputControllerTest<>::ParamType>& info) {
  156. switch (info.param) {
  157. case ProcessingFifoSetting::kEnabled:
  158. return "FifoEnabled";
  159. case ProcessingFifoSetting::kEnabledWithSizeZero:
  160. return "FifoEnabledWithSizeZero";
  161. case ProcessingFifoSetting::kDisabled:
  162. return "FifoDisabled";
  163. }
  164. };
  165. using SystemTimeInputControllerTest = TimeSourceInputControllerTest<
  166. base::test::TaskEnvironment::TimeSource::SYSTEM_TIME>;
  167. using InputControllerTest = TimeSourceInputControllerTest<>;
  168. TEST_P(InputControllerTest, CreateAndCloseWithoutRecording) {
  169. EXPECT_CALL(event_handler_, OnCreated(_));
  170. CreateAudioController();
  171. task_environment_.RunUntilIdle();
  172. ASSERT_TRUE(controller_.get());
  173. EXPECT_CALL(sync_writer_, Close());
  174. controller_->Close();
  175. }
  176. // Test a normal call sequence of create, record and close.
  177. // Note: Must use system time as MOCK_TIME does not support the threads created
  178. // by the FakeAudioInputStream. The callbacks to sync_writer_.Write() are on
  179. // that thread, and thus we must use SYSTEM_TIME.
  180. TEST_P(SystemTimeInputControllerTest, CreateRecordAndClose) {
  181. EXPECT_CALL(event_handler_, OnCreated(_));
  182. EXPECT_CALL(mock_stream_activity_monitor_, OnInputStreamActive()).Times(1);
  183. EXPECT_CALL(mock_stream_activity_monitor_, OnInputStreamInactive()).Times(1);
  184. CreateAudioController();
  185. ASSERT_TRUE(controller_.get());
  186. base::RunLoop loop;
  187. {
  188. // Wait for Write() to be called ten times.
  189. testing::InSequence s;
  190. EXPECT_CALL(user_input_monitor_, EnableKeyPressMonitoring());
  191. EXPECT_CALL(sync_writer_, Write(NotNull(), _, _, _)).Times(Exactly(9));
  192. EXPECT_CALL(sync_writer_, Write(NotNull(), _, _, _))
  193. .Times(AtLeast(1))
  194. .WillOnce(InvokeWithoutArgs([&]() { loop.Quit(); }));
  195. }
  196. controller_->Record();
  197. loop.Run();
  198. testing::Mock::VerifyAndClearExpectations(&user_input_monitor_);
  199. testing::Mock::VerifyAndClearExpectations(&sync_writer_);
  200. EXPECT_CALL(sync_writer_, Close());
  201. EXPECT_CALL(user_input_monitor_, DisableKeyPressMonitoring());
  202. controller_->Close();
  203. task_environment_.RunUntilIdle();
  204. }
  205. TEST_P(InputControllerTest, RecordTwice) {
  206. EXPECT_CALL(event_handler_, OnCreated(_));
  207. EXPECT_CALL(mock_stream_activity_monitor_, OnInputStreamActive()).Times(1);
  208. EXPECT_CALL(mock_stream_activity_monitor_, OnInputStreamInactive()).Times(1);
  209. CreateAudioController();
  210. ASSERT_TRUE(controller_.get());
  211. EXPECT_CALL(user_input_monitor_, EnableKeyPressMonitoring());
  212. controller_->Record();
  213. controller_->Record();
  214. EXPECT_CALL(user_input_monitor_, DisableKeyPressMonitoring());
  215. EXPECT_CALL(sync_writer_, Close());
  216. controller_->Close();
  217. }
  218. TEST_P(InputControllerTest, CloseTwice) {
  219. EXPECT_CALL(event_handler_, OnCreated(_));
  220. EXPECT_CALL(mock_stream_activity_monitor_, OnInputStreamActive()).Times(1);
  221. EXPECT_CALL(mock_stream_activity_monitor_, OnInputStreamInactive()).Times(1);
  222. CreateAudioController();
  223. ASSERT_TRUE(controller_.get());
  224. EXPECT_CALL(user_input_monitor_, EnableKeyPressMonitoring());
  225. controller_->Record();
  226. EXPECT_CALL(user_input_monitor_, DisableKeyPressMonitoring());
  227. EXPECT_CALL(sync_writer_, Close());
  228. controller_->Close();
  229. controller_->Close();
  230. }
  231. // Test that InputController sends OnMute callbacks properly.
  232. TEST_P(InputControllerTest, TestOnmutedCallbackInitiallyUnmuted) {
  233. EXPECT_CALL(event_handler_, OnCreated(false));
  234. EXPECT_CALL(sync_writer_, Close());
  235. media::FakeAudioInputStream::SetGlobalMutedState(false);
  236. CreateAudioController();
  237. ASSERT_TRUE(controller_.get());
  238. task_environment_.FastForwardBy(kOnMutePollInterval);
  239. testing::Mock::VerifyAndClearExpectations(&event_handler_);
  240. EXPECT_CALL(event_handler_, OnMuted(true));
  241. media::FakeAudioInputStream::SetGlobalMutedState(true);
  242. task_environment_.FastForwardBy(kOnMutePollInterval);
  243. testing::Mock::VerifyAndClearExpectations(&event_handler_);
  244. EXPECT_CALL(event_handler_, OnMuted(false));
  245. media::FakeAudioInputStream::SetGlobalMutedState(false);
  246. task_environment_.FastForwardBy(kOnMutePollInterval);
  247. controller_->Close();
  248. }
  249. TEST_P(InputControllerTest, TestOnmutedCallbackInitiallyMuted) {
  250. EXPECT_CALL(event_handler_, OnCreated(true));
  251. EXPECT_CALL(sync_writer_, Close());
  252. media::FakeAudioInputStream::SetGlobalMutedState(true);
  253. CreateAudioController();
  254. ASSERT_TRUE(controller_.get());
  255. task_environment_.FastForwardBy(kOnMutePollInterval);
  256. testing::Mock::VerifyAndClearExpectations(&event_handler_);
  257. EXPECT_CALL(event_handler_, OnMuted(false));
  258. media::FakeAudioInputStream::SetGlobalMutedState(false);
  259. task_environment_.FastForwardBy(kOnMutePollInterval);
  260. controller_->Close();
  261. }
  262. INSTANTIATE_TEST_SUITE_P(
  263. InputControllerTest,
  264. InputControllerTest,
  265. testing::Values(ProcessingFifoSetting::kEnabled,
  266. ProcessingFifoSetting::kEnabledWithSizeZero,
  267. ProcessingFifoSetting::kDisabled),
  268. test_name_generator);
  269. INSTANTIATE_TEST_SUITE_P(
  270. SystemTimeInputControllerTest,
  271. SystemTimeInputControllerTest,
  272. testing::Values(ProcessingFifoSetting::kEnabled,
  273. ProcessingFifoSetting::kEnabledWithSizeZero,
  274. ProcessingFifoSetting::kDisabled),
  275. test_name_generator);
  276. #if BUILDFLAG(CHROME_WIDE_ECHO_CANCELLATION)
  277. class InputControllerTestHelper {
  278. public:
  279. explicit InputControllerTestHelper(InputController* controller)
  280. : controller_(controller) {}
  281. bool IsUsingProcessingThread() {
  282. return !!controller_->processing_fifo_.get();
  283. }
  284. // Adds a callback that will be run immediately after processing is done, in
  285. // the same sequence as the processing callback.
  286. // Should be called before starting the processing thread.
  287. void AttachOnProcessedCallback(base::RepeatingClosure on_processed_callback) {
  288. controller_->processing_fifo_->AttachOnProcessedCallbackForTesting(
  289. std::move(on_processed_callback));
  290. }
  291. private:
  292. raw_ptr<InputController> controller_;
  293. };
  294. class MockDeviceOutputListener : public DeviceOutputListener {
  295. public:
  296. MockDeviceOutputListener() = default;
  297. ~MockDeviceOutputListener() override = default;
  298. MOCK_METHOD2(StartListening,
  299. void(ReferenceOutput::Listener*, const std::string&));
  300. MOCK_METHOD1(StopListening, void(ReferenceOutput::Listener*));
  301. };
  302. template <base::test::TaskEnvironment::TimeSource TimeSource =
  303. base::test::TaskEnvironment::TimeSource::MOCK_TIME>
  304. class TimeSourceInputControllerTestWithDeviceListener
  305. : public TimeSourceInputControllerTest<TimeSource> {
  306. protected:
  307. void CreateAudioController() final {
  308. // Must use |this| to access template base class members:
  309. // https://stackoverflow.com/q/4643074
  310. this->controller_ = InputController::Create(
  311. this->audio_manager_.get(), &this->event_handler_, &this->sync_writer_,
  312. &this->user_input_monitor_, &this->mock_stream_activity_monitor_,
  313. &this->device_output_listener_, &this->aecdump_recording_manager_,
  314. std::move(processing_config_), this->params_,
  315. media::AudioDeviceDescription::kDefaultDeviceId, false);
  316. helper_ =
  317. std::make_unique<InputControllerTestHelper>(this->controller_.get());
  318. }
  319. enum class AudioProcessingType {
  320. // No effects, audio does not need to be modified.
  321. kNone,
  322. // Effects that modify audio but do not require a playout reference signal.
  323. kWithoutPlayoutReference,
  324. // Effects that require a playout reference signal.
  325. kWithPlayoutReference
  326. };
  327. void SetupProcessingConfig(AudioProcessingType audio_processing_type) {
  328. media::AudioProcessingSettings settings;
  329. settings.echo_cancellation = false;
  330. settings.noise_suppression = false;
  331. settings.transient_noise_suppression = false;
  332. settings.automatic_gain_control = false;
  333. settings.experimental_automatic_gain_control = false;
  334. settings.high_pass_filter = false;
  335. settings.multi_channel_capture_processing = false;
  336. settings.stereo_mirroring = false;
  337. settings.force_apm_creation = false;
  338. switch (audio_processing_type) {
  339. case AudioProcessingType::kNone:
  340. break;
  341. case AudioProcessingType::kWithoutPlayoutReference:
  342. settings.noise_suppression = true;
  343. break;
  344. case AudioProcessingType::kWithPlayoutReference:
  345. settings.echo_cancellation = true;
  346. break;
  347. }
  348. processing_config_ = media::mojom::AudioProcessingConfig::New(
  349. remote_controls_.BindNewPipeAndPassReceiver(), settings);
  350. }
  351. NiceMock<MockDeviceOutputListener> device_output_listener_;
  352. media::mojom::AudioProcessingConfigPtr processing_config_;
  353. mojo::Remote<media::mojom::AudioProcessorControls> remote_controls_;
  354. std::unique_ptr<InputControllerTestHelper> helper_;
  355. };
  356. using SystemTimeInputControllerTestWithDeviceListener =
  357. TimeSourceInputControllerTestWithDeviceListener<
  358. base::test::TaskEnvironment::TimeSource::SYSTEM_TIME>;
  359. using InputControllerTestWithDeviceListener =
  360. TimeSourceInputControllerTestWithDeviceListener<>;
  361. TEST_P(InputControllerTestWithDeviceListener,
  362. CreateWithAudioProcessingConfig_WithSomeEffectsEnabled) {
  363. SetupProcessingConfig(AudioProcessingType::kWithoutPlayoutReference);
  364. CreateAudioController();
  365. ASSERT_TRUE(controller_.get());
  366. base::RunLoop loop;
  367. base::SequencedTaskRunnerHandle::Get()->PostTask(FROM_HERE,
  368. loop.QuitClosure());
  369. loop.Run();
  370. // |controller_| should have bound the pending AudioProcessorControls
  371. // receiver it received through its ctor.
  372. EXPECT_TRUE(remote_controls_.is_connected());
  373. // InputController shouldn't offload processing work when there is no playout
  374. // reference.
  375. EXPECT_FALSE(helper_->IsUsingProcessingThread());
  376. // Test cleanup.
  377. controller_->Close();
  378. }
  379. TEST_P(InputControllerTestWithDeviceListener,
  380. CreateWithAudioProcessingConfig_WithoutEnablingEffects) {
  381. SetupProcessingConfig(AudioProcessingType::kNone);
  382. CreateAudioController();
  383. ASSERT_TRUE(controller_.get());
  384. base::RunLoop loop;
  385. base::SequencedTaskRunnerHandle::Get()->PostTask(FROM_HERE,
  386. loop.QuitClosure());
  387. loop.Run();
  388. // When all forms of audio processing are disabled, |controller_| should
  389. // ignore the pending AudioProcessorControls Receiver it received in its ctor.
  390. EXPECT_FALSE(remote_controls_.is_connected());
  391. // InputController shouldn't spin up a processing thread if it's not needed.
  392. EXPECT_FALSE(helper_->IsUsingProcessingThread());
  393. // Test cleanup.
  394. controller_->Close();
  395. }
  396. TEST_P(InputControllerTestWithDeviceListener,
  397. CreateWithAudioProcessingConfig_VerifyFifoUsage) {
  398. SetupProcessingConfig(AudioProcessingType::kWithPlayoutReference);
  399. CreateAudioController();
  400. ASSERT_TRUE(controller_.get());
  401. // The processing thread should only be enabled when the processing FIFO
  402. // is explicitly enabled.
  403. EXPECT_EQ(IsProcessingFifoEnabled(), helper_->IsUsingProcessingThread());
  404. // Test cleanup.
  405. controller_->Close();
  406. }
  407. TEST_P(
  408. InputControllerTestWithDeviceListener,
  409. CreateWithAudioProcessingConfig_DoesNotListenForPlayoutReferenceIfNotRequired) {
  410. base::test::ScopedFeatureList features;
  411. const std::string kOutputDeviceId = "0x123";
  412. EXPECT_CALL(mock_stream_activity_monitor_, OnInputStreamActive()).Times(1);
  413. EXPECT_CALL(mock_stream_activity_monitor_, OnInputStreamInactive()).Times(1);
  414. EXPECT_CALL(device_output_listener_, StartListening(_, _)).Times(0);
  415. EXPECT_CALL(device_output_listener_, StopListening(_)).Times(0);
  416. SetupProcessingConfig(AudioProcessingType::kWithoutPlayoutReference);
  417. CreateAudioController();
  418. ASSERT_TRUE(controller_.get());
  419. controller_->Record();
  420. controller_->SetOutputDeviceForAec(kOutputDeviceId);
  421. // InputController spin up a processing thread if it's not needed.
  422. EXPECT_FALSE(helper_->IsUsingProcessingThread());
  423. controller_->Close();
  424. EXPECT_FALSE(helper_->IsUsingProcessingThread());
  425. }
  426. TEST_P(InputControllerTestWithDeviceListener, RecordBeforeSetOutputForAec) {
  427. const std::string kOutputDeviceId = "0x123";
  428. EXPECT_CALL(mock_stream_activity_monitor_, OnInputStreamActive()).Times(1);
  429. EXPECT_CALL(mock_stream_activity_monitor_, OnInputStreamInactive()).Times(1);
  430. // Calling Record() will start listening to the "" device by default.
  431. EXPECT_CALL(device_output_listener_, StartListening(_, "")).Times(1);
  432. EXPECT_CALL(device_output_listener_, StartListening(_, kOutputDeviceId))
  433. .Times(1);
  434. EXPECT_CALL(device_output_listener_, StopListening(_)).Times(1);
  435. SetupProcessingConfig(AudioProcessingType::kWithPlayoutReference);
  436. CreateAudioController();
  437. ASSERT_TRUE(controller_.get());
  438. controller_->Record();
  439. controller_->SetOutputDeviceForAec(kOutputDeviceId);
  440. // InputController should offload processing to its own thread, if enabled.
  441. EXPECT_EQ(IsProcessingFifoEnabled(), helper_->IsUsingProcessingThread());
  442. controller_->Close();
  443. // The processing thread should be stopped after controller has closed.
  444. EXPECT_FALSE(helper_->IsUsingProcessingThread());
  445. }
  446. TEST_P(InputControllerTestWithDeviceListener, RecordAfterSetOutputForAec) {
  447. const std::string kOutputDeviceId = "0x123";
  448. EXPECT_CALL(mock_stream_activity_monitor_, OnInputStreamActive()).Times(1);
  449. EXPECT_CALL(mock_stream_activity_monitor_, OnInputStreamInactive()).Times(1);
  450. EXPECT_CALL(device_output_listener_, StartListening(_, kOutputDeviceId))
  451. .Times(1);
  452. EXPECT_CALL(device_output_listener_, StopListening(_)).Times(1);
  453. SetupProcessingConfig(AudioProcessingType::kWithPlayoutReference);
  454. CreateAudioController();
  455. ASSERT_TRUE(controller_.get());
  456. controller_->SetOutputDeviceForAec(kOutputDeviceId);
  457. controller_->Record();
  458. // InputController should offload processing to its own thread, if enabled.
  459. EXPECT_EQ(IsProcessingFifoEnabled(), helper_->IsUsingProcessingThread());
  460. controller_->Close();
  461. // The processing thread should be stopped after controller has closed.
  462. EXPECT_FALSE(helper_->IsUsingProcessingThread());
  463. }
  464. TEST_P(InputControllerTestWithDeviceListener, ChangeOutputForAec) {
  465. const std::string kOutputDeviceId = "0x123";
  466. const std::string kOtherOutputDeviceId = "0x987";
  467. EXPECT_CALL(mock_stream_activity_monitor_, OnInputStreamActive()).Times(1);
  468. EXPECT_CALL(mock_stream_activity_monitor_, OnInputStreamInactive()).Times(1);
  469. // Each output ID should receive one call to StartListening().
  470. EXPECT_CALL(device_output_listener_, StartListening(_, kOutputDeviceId))
  471. .Times(1);
  472. EXPECT_CALL(device_output_listener_, StartListening(_, kOtherOutputDeviceId))
  473. .Times(1);
  474. // StopListening() should be called once, regardless of how many ID changes.
  475. EXPECT_CALL(device_output_listener_, StopListening(_)).Times(1);
  476. SetupProcessingConfig(AudioProcessingType::kWithPlayoutReference);
  477. CreateAudioController();
  478. ASSERT_TRUE(controller_.get());
  479. controller_->SetOutputDeviceForAec(kOutputDeviceId);
  480. controller_->Record();
  481. controller_->SetOutputDeviceForAec(kOtherOutputDeviceId);
  482. controller_->Close();
  483. }
  484. // Test a normal call sequence of create, record and close when audio processing
  485. // is enabled.
  486. // Note: Must use system time as MOCK_TIME does not support the threads created
  487. // by the FakeAudioInputStream. The callbacks to sync_writer_.Write() are on
  488. // that thread, and thus we must use SYSTEM_TIME.
  489. TEST_P(SystemTimeInputControllerTestWithDeviceListener, CreateRecordAndClose) {
  490. EXPECT_CALL(event_handler_, OnCreated(_));
  491. EXPECT_CALL(mock_stream_activity_monitor_, OnInputStreamActive()).Times(1);
  492. EXPECT_CALL(mock_stream_activity_monitor_, OnInputStreamInactive()).Times(1);
  493. SetupProcessingConfig(AudioProcessingType::kWithPlayoutReference);
  494. CreateAudioController();
  495. bool data_processed_by_fifo = false;
  496. if (IsProcessingFifoEnabled()) {
  497. auto main_sequence = base::SequencedTaskRunnerHandle::Get();
  498. auto verify_data_processed = [&data_processed_by_fifo, main_sequence]() {
  499. // Data should be processed on its own thread.
  500. EXPECT_FALSE(main_sequence->RunsTasksInCurrentSequence());
  501. data_processed_by_fifo = true;
  502. };
  503. helper_->AttachOnProcessedCallback(
  504. base::BindLambdaForTesting(verify_data_processed));
  505. }
  506. ASSERT_TRUE(controller_.get());
  507. base::RunLoop loop;
  508. {
  509. // Wait for Write() to be called ten times.
  510. testing::InSequence s;
  511. EXPECT_CALL(user_input_monitor_, EnableKeyPressMonitoring());
  512. EXPECT_CALL(sync_writer_, Write(NotNull(), _, _, _)).Times(Exactly(9));
  513. EXPECT_CALL(sync_writer_, Write(NotNull(), _, _, _))
  514. .Times(AtLeast(1))
  515. .WillOnce(InvokeWithoutArgs([&]() { loop.Quit(); }));
  516. }
  517. controller_->Record();
  518. // InputController should offload processing to its own thread if the
  519. // processing FIFO is enabled.
  520. EXPECT_EQ(IsProcessingFifoEnabled(), helper_->IsUsingProcessingThread());
  521. loop.Run();
  522. testing::Mock::VerifyAndClearExpectations(&user_input_monitor_);
  523. testing::Mock::VerifyAndClearExpectations(&sync_writer_);
  524. EXPECT_CALL(sync_writer_, Close());
  525. EXPECT_CALL(user_input_monitor_, DisableKeyPressMonitoring());
  526. controller_->Close();
  527. // The processing thread should be stopped after controller has closed.
  528. EXPECT_FALSE(helper_->IsUsingProcessingThread());
  529. task_environment_.RunUntilIdle();
  530. EXPECT_EQ(data_processed_by_fifo, IsProcessingFifoEnabled());
  531. }
  532. INSTANTIATE_TEST_SUITE_P(
  533. InputControllerTestWithDeviceListener,
  534. InputControllerTestWithDeviceListener,
  535. testing::Values(ProcessingFifoSetting::kEnabled,
  536. ProcessingFifoSetting::kEnabledWithSizeZero,
  537. ProcessingFifoSetting::kDisabled),
  538. test_name_generator);
  539. INSTANTIATE_TEST_SUITE_P(
  540. SystemTimeInputControllerTestWithDeviceListener,
  541. SystemTimeInputControllerTestWithDeviceListener,
  542. testing::Values(ProcessingFifoSetting::kEnabled,
  543. ProcessingFifoSetting::kEnabledWithSizeZero,
  544. ProcessingFifoSetting::kDisabled),
  545. test_name_generator);
  546. #endif // BUILDFLAG(CHROME_WIDE_ECHO_CANCELLATION)
  547. } // namespace audio