123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685 |
- // Copyright (c) 2012 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "services/audio/input_controller.h"
- #include <memory>
- #include <utility>
- #include "base/run_loop.h"
- #include "base/test/bind.h"
- #include "base/test/scoped_feature_list.h"
- #include "base/test/task_environment.h"
- #include "media/audio/audio_manager.h"
- #include "media/audio/fake_audio_input_stream.h"
- #include "media/audio/fake_audio_log_factory.h"
- #include "media/audio/fake_audio_manager.h"
- #include "media/audio/test_audio_thread.h"
- #include "media/base/audio_processing.h"
- #include "media/base/media_switches.h"
- #include "media/base/user_input_monitor.h"
- #include "mojo/public/cpp/bindings/remote.h"
- #include "services/audio/aecdump_recording_manager.h"
- #include "services/audio/concurrent_stream_metric_reporter.h"
- #include "services/audio/device_output_listener.h"
- #include "services/audio/processing_audio_fifo.h"
- #include "services/audio/reference_output.h"
- #include "testing/gmock/include/gmock/gmock.h"
- #include "testing/gtest/include/gtest/gtest.h"
- using ::testing::_;
- using ::testing::AtLeast;
- using ::testing::Exactly;
- using ::testing::InvokeWithoutArgs;
- using ::testing::NiceMock;
- using ::testing::NotNull;
- using ::testing::StrictMock;
- namespace audio {
- namespace {
- const int kSampleRate = media::AudioParameters::kAudioCDSampleRate;
- const media::ChannelLayout kChannelLayout = media::CHANNEL_LAYOUT_STEREO;
- const int kSamplesPerPacket = kSampleRate / 100;
- // InputController will poll once every second, so wait at most a bit
- // more than that for the callbacks.
- constexpr base::TimeDelta kOnMutePollInterval = base::Milliseconds(1000);
- enum class ProcessingFifoSetting {
- kEnabled,
- kEnabledWithSizeZero,
- kDisabled,
- };
- const std::string kFifoSizeParameter = "processing_fifo_size";
- const std::map<std::string, std::string> kDisabledFifoParam{
- {kFifoSizeParameter, "0"}};
- const std::map<std::string, std::string> kEnabledFifoParam{
- {kFifoSizeParameter, "110"}};
- } // namespace
- class MockInputControllerEventHandler : public InputController::EventHandler {
- public:
- MockInputControllerEventHandler() = default;
- MockInputControllerEventHandler(const MockInputControllerEventHandler&) =
- delete;
- MockInputControllerEventHandler& operator=(
- const MockInputControllerEventHandler&) = delete;
- void OnLog(base::StringPiece) override {}
- MOCK_METHOD1(OnCreated, void(bool initially_muted));
- MOCK_METHOD1(OnError, void(InputController::ErrorCode error_code));
- MOCK_METHOD1(OnMuted, void(bool is_muted));
- };
- class MockSyncWriter : public InputController::SyncWriter {
- public:
- MockSyncWriter() = default;
- MOCK_METHOD4(Write,
- void(const media::AudioBus* data,
- double volume,
- bool key_pressed,
- base::TimeTicks capture_time));
- MOCK_METHOD0(Close, void());
- };
- class MockUserInputMonitor : public media::UserInputMonitor {
- public:
- MockUserInputMonitor() = default;
- uint32_t GetKeyPressCount() const override { return 0; }
- MOCK_METHOD0(EnableKeyPressMonitoring, void());
- MOCK_METHOD0(DisableKeyPressMonitoring, void());
- };
- class MockInputStreamActivityMonitor : public InputStreamActivityMonitor {
- public:
- MockInputStreamActivityMonitor() = default;
- MOCK_METHOD0(OnInputStreamActive, void());
- MOCK_METHOD0(OnInputStreamInactive, void());
- };
- template <base::test::TaskEnvironment::TimeSource TimeSource =
- base::test::TaskEnvironment::TimeSource::MOCK_TIME>
- class TimeSourceInputControllerTest
- : public ::testing::TestWithParam<ProcessingFifoSetting> {
- public:
- TimeSourceInputControllerTest()
- : task_environment_(TimeSource),
- audio_manager_(std::make_unique<media::FakeAudioManager>(
- std::make_unique<media::TestAudioThread>(false),
- &log_factory_)),
- aecdump_recording_manager_(audio_manager_->GetTaskRunner()),
- params_(media::AudioParameters::AUDIO_FAKE,
- kChannelLayout,
- kSampleRate,
- kSamplesPerPacket) {
- #if BUILDFLAG(CHROME_WIDE_ECHO_CANCELLATION)
- switch (GetParam()) {
- case ProcessingFifoSetting::kEnabled:
- processing_fifo_feature_.InitAndEnableFeatureWithParameters(
- media::kChromeWideEchoCancellation, kEnabledFifoParam);
- break;
- case ProcessingFifoSetting::kEnabledWithSizeZero:
- processing_fifo_feature_.InitAndEnableFeatureWithParameters(
- media::kChromeWideEchoCancellation, kDisabledFifoParam);
- break;
- case ProcessingFifoSetting::kDisabled:
- processing_fifo_feature_.InitAndDisableFeature(
- media::kChromeWideEchoCancellation);
- break;
- };
- #endif
- }
- TimeSourceInputControllerTest(const TimeSourceInputControllerTest&) = delete;
- TimeSourceInputControllerTest& operator=(
- const TimeSourceInputControllerTest&) = delete;
- ~TimeSourceInputControllerTest() override {
- audio_manager_->Shutdown();
- task_environment_.RunUntilIdle();
- }
- protected:
- virtual void CreateAudioController() {
- controller_ = InputController::Create(
- audio_manager_.get(), &event_handler_, &sync_writer_,
- &user_input_monitor_, &mock_stream_activity_monitor_,
- /*device_output_listener =*/nullptr, &aecdump_recording_manager_,
- /*processing_config =*/nullptr, params_,
- media::AudioDeviceDescription::kDefaultDeviceId, false);
- }
- bool IsProcessingFifoEnabled() {
- return GetParam() == ProcessingFifoSetting::kEnabled;
- }
- base::test::TaskEnvironment task_environment_;
- #if BUILDFLAG(CHROME_WIDE_ECHO_CANCELLATION)
- base::test::ScopedFeatureList processing_fifo_feature_;
- #endif
- std::unique_ptr<media::AudioManager> audio_manager_;
- AecdumpRecordingManager aecdump_recording_manager_;
- std::unique_ptr<InputController> controller_;
- media::FakeAudioLogFactory log_factory_;
- MockInputControllerEventHandler event_handler_;
- MockSyncWriter sync_writer_;
- MockUserInputMonitor user_input_monitor_;
- StrictMock<MockInputStreamActivityMonitor> mock_stream_activity_monitor_;
- media::AudioParameters params_;
- };
- auto test_name_generator =
- [](const ::testing::TestParamInfo<
- TimeSourceInputControllerTest<>::ParamType>& info) {
- switch (info.param) {
- case ProcessingFifoSetting::kEnabled:
- return "FifoEnabled";
- case ProcessingFifoSetting::kEnabledWithSizeZero:
- return "FifoEnabledWithSizeZero";
- case ProcessingFifoSetting::kDisabled:
- return "FifoDisabled";
- }
- };
- using SystemTimeInputControllerTest = TimeSourceInputControllerTest<
- base::test::TaskEnvironment::TimeSource::SYSTEM_TIME>;
- using InputControllerTest = TimeSourceInputControllerTest<>;
- TEST_P(InputControllerTest, CreateAndCloseWithoutRecording) {
- EXPECT_CALL(event_handler_, OnCreated(_));
- CreateAudioController();
- task_environment_.RunUntilIdle();
- ASSERT_TRUE(controller_.get());
- EXPECT_CALL(sync_writer_, Close());
- controller_->Close();
- }
- // Test a normal call sequence of create, record and close.
- // Note: Must use system time as MOCK_TIME does not support the threads created
- // by the FakeAudioInputStream. The callbacks to sync_writer_.Write() are on
- // that thread, and thus we must use SYSTEM_TIME.
- TEST_P(SystemTimeInputControllerTest, CreateRecordAndClose) {
- EXPECT_CALL(event_handler_, OnCreated(_));
- EXPECT_CALL(mock_stream_activity_monitor_, OnInputStreamActive()).Times(1);
- EXPECT_CALL(mock_stream_activity_monitor_, OnInputStreamInactive()).Times(1);
- CreateAudioController();
- ASSERT_TRUE(controller_.get());
- base::RunLoop loop;
- {
- // Wait for Write() to be called ten times.
- testing::InSequence s;
- EXPECT_CALL(user_input_monitor_, EnableKeyPressMonitoring());
- EXPECT_CALL(sync_writer_, Write(NotNull(), _, _, _)).Times(Exactly(9));
- EXPECT_CALL(sync_writer_, Write(NotNull(), _, _, _))
- .Times(AtLeast(1))
- .WillOnce(InvokeWithoutArgs([&]() { loop.Quit(); }));
- }
- controller_->Record();
- loop.Run();
- testing::Mock::VerifyAndClearExpectations(&user_input_monitor_);
- testing::Mock::VerifyAndClearExpectations(&sync_writer_);
- EXPECT_CALL(sync_writer_, Close());
- EXPECT_CALL(user_input_monitor_, DisableKeyPressMonitoring());
- controller_->Close();
- task_environment_.RunUntilIdle();
- }
- TEST_P(InputControllerTest, RecordTwice) {
- EXPECT_CALL(event_handler_, OnCreated(_));
- EXPECT_CALL(mock_stream_activity_monitor_, OnInputStreamActive()).Times(1);
- EXPECT_CALL(mock_stream_activity_monitor_, OnInputStreamInactive()).Times(1);
- CreateAudioController();
- ASSERT_TRUE(controller_.get());
- EXPECT_CALL(user_input_monitor_, EnableKeyPressMonitoring());
- controller_->Record();
- controller_->Record();
- EXPECT_CALL(user_input_monitor_, DisableKeyPressMonitoring());
- EXPECT_CALL(sync_writer_, Close());
- controller_->Close();
- }
- TEST_P(InputControllerTest, CloseTwice) {
- EXPECT_CALL(event_handler_, OnCreated(_));
- EXPECT_CALL(mock_stream_activity_monitor_, OnInputStreamActive()).Times(1);
- EXPECT_CALL(mock_stream_activity_monitor_, OnInputStreamInactive()).Times(1);
- CreateAudioController();
- ASSERT_TRUE(controller_.get());
- EXPECT_CALL(user_input_monitor_, EnableKeyPressMonitoring());
- controller_->Record();
- EXPECT_CALL(user_input_monitor_, DisableKeyPressMonitoring());
- EXPECT_CALL(sync_writer_, Close());
- controller_->Close();
- controller_->Close();
- }
- // Test that InputController sends OnMute callbacks properly.
- TEST_P(InputControllerTest, TestOnmutedCallbackInitiallyUnmuted) {
- EXPECT_CALL(event_handler_, OnCreated(false));
- EXPECT_CALL(sync_writer_, Close());
- media::FakeAudioInputStream::SetGlobalMutedState(false);
- CreateAudioController();
- ASSERT_TRUE(controller_.get());
- task_environment_.FastForwardBy(kOnMutePollInterval);
- testing::Mock::VerifyAndClearExpectations(&event_handler_);
- EXPECT_CALL(event_handler_, OnMuted(true));
- media::FakeAudioInputStream::SetGlobalMutedState(true);
- task_environment_.FastForwardBy(kOnMutePollInterval);
- testing::Mock::VerifyAndClearExpectations(&event_handler_);
- EXPECT_CALL(event_handler_, OnMuted(false));
- media::FakeAudioInputStream::SetGlobalMutedState(false);
- task_environment_.FastForwardBy(kOnMutePollInterval);
- controller_->Close();
- }
- TEST_P(InputControllerTest, TestOnmutedCallbackInitiallyMuted) {
- EXPECT_CALL(event_handler_, OnCreated(true));
- EXPECT_CALL(sync_writer_, Close());
- media::FakeAudioInputStream::SetGlobalMutedState(true);
- CreateAudioController();
- ASSERT_TRUE(controller_.get());
- task_environment_.FastForwardBy(kOnMutePollInterval);
- testing::Mock::VerifyAndClearExpectations(&event_handler_);
- EXPECT_CALL(event_handler_, OnMuted(false));
- media::FakeAudioInputStream::SetGlobalMutedState(false);
- task_environment_.FastForwardBy(kOnMutePollInterval);
- controller_->Close();
- }
- INSTANTIATE_TEST_SUITE_P(
- InputControllerTest,
- InputControllerTest,
- testing::Values(ProcessingFifoSetting::kEnabled,
- ProcessingFifoSetting::kEnabledWithSizeZero,
- ProcessingFifoSetting::kDisabled),
- test_name_generator);
- INSTANTIATE_TEST_SUITE_P(
- SystemTimeInputControllerTest,
- SystemTimeInputControllerTest,
- testing::Values(ProcessingFifoSetting::kEnabled,
- ProcessingFifoSetting::kEnabledWithSizeZero,
- ProcessingFifoSetting::kDisabled),
- test_name_generator);
- #if BUILDFLAG(CHROME_WIDE_ECHO_CANCELLATION)
- class InputControllerTestHelper {
- public:
- explicit InputControllerTestHelper(InputController* controller)
- : controller_(controller) {}
- bool IsUsingProcessingThread() {
- return !!controller_->processing_fifo_.get();
- }
- // Adds a callback that will be run immediately after processing is done, in
- // the same sequence as the processing callback.
- // Should be called before starting the processing thread.
- void AttachOnProcessedCallback(base::RepeatingClosure on_processed_callback) {
- controller_->processing_fifo_->AttachOnProcessedCallbackForTesting(
- std::move(on_processed_callback));
- }
- private:
- raw_ptr<InputController> controller_;
- };
- class MockDeviceOutputListener : public DeviceOutputListener {
- public:
- MockDeviceOutputListener() = default;
- ~MockDeviceOutputListener() override = default;
- MOCK_METHOD2(StartListening,
- void(ReferenceOutput::Listener*, const std::string&));
- MOCK_METHOD1(StopListening, void(ReferenceOutput::Listener*));
- };
- template <base::test::TaskEnvironment::TimeSource TimeSource =
- base::test::TaskEnvironment::TimeSource::MOCK_TIME>
- class TimeSourceInputControllerTestWithDeviceListener
- : public TimeSourceInputControllerTest<TimeSource> {
- protected:
- void CreateAudioController() final {
- // Must use |this| to access template base class members:
- // https://stackoverflow.com/q/4643074
- this->controller_ = InputController::Create(
- this->audio_manager_.get(), &this->event_handler_, &this->sync_writer_,
- &this->user_input_monitor_, &this->mock_stream_activity_monitor_,
- &this->device_output_listener_, &this->aecdump_recording_manager_,
- std::move(processing_config_), this->params_,
- media::AudioDeviceDescription::kDefaultDeviceId, false);
- helper_ =
- std::make_unique<InputControllerTestHelper>(this->controller_.get());
- }
- enum class AudioProcessingType {
- // No effects, audio does not need to be modified.
- kNone,
- // Effects that modify audio but do not require a playout reference signal.
- kWithoutPlayoutReference,
- // Effects that require a playout reference signal.
- kWithPlayoutReference
- };
- void SetupProcessingConfig(AudioProcessingType audio_processing_type) {
- media::AudioProcessingSettings settings;
- settings.echo_cancellation = false;
- settings.noise_suppression = false;
- settings.transient_noise_suppression = false;
- settings.automatic_gain_control = false;
- settings.experimental_automatic_gain_control = false;
- settings.high_pass_filter = false;
- settings.multi_channel_capture_processing = false;
- settings.stereo_mirroring = false;
- settings.force_apm_creation = false;
- switch (audio_processing_type) {
- case AudioProcessingType::kNone:
- break;
- case AudioProcessingType::kWithoutPlayoutReference:
- settings.noise_suppression = true;
- break;
- case AudioProcessingType::kWithPlayoutReference:
- settings.echo_cancellation = true;
- break;
- }
- processing_config_ = media::mojom::AudioProcessingConfig::New(
- remote_controls_.BindNewPipeAndPassReceiver(), settings);
- }
- NiceMock<MockDeviceOutputListener> device_output_listener_;
- media::mojom::AudioProcessingConfigPtr processing_config_;
- mojo::Remote<media::mojom::AudioProcessorControls> remote_controls_;
- std::unique_ptr<InputControllerTestHelper> helper_;
- };
- using SystemTimeInputControllerTestWithDeviceListener =
- TimeSourceInputControllerTestWithDeviceListener<
- base::test::TaskEnvironment::TimeSource::SYSTEM_TIME>;
- using InputControllerTestWithDeviceListener =
- TimeSourceInputControllerTestWithDeviceListener<>;
- TEST_P(InputControllerTestWithDeviceListener,
- CreateWithAudioProcessingConfig_WithSomeEffectsEnabled) {
- SetupProcessingConfig(AudioProcessingType::kWithoutPlayoutReference);
- CreateAudioController();
- ASSERT_TRUE(controller_.get());
- base::RunLoop loop;
- base::SequencedTaskRunnerHandle::Get()->PostTask(FROM_HERE,
- loop.QuitClosure());
- loop.Run();
- // |controller_| should have bound the pending AudioProcessorControls
- // receiver it received through its ctor.
- EXPECT_TRUE(remote_controls_.is_connected());
- // InputController shouldn't offload processing work when there is no playout
- // reference.
- EXPECT_FALSE(helper_->IsUsingProcessingThread());
- // Test cleanup.
- controller_->Close();
- }
- TEST_P(InputControllerTestWithDeviceListener,
- CreateWithAudioProcessingConfig_WithoutEnablingEffects) {
- SetupProcessingConfig(AudioProcessingType::kNone);
- CreateAudioController();
- ASSERT_TRUE(controller_.get());
- base::RunLoop loop;
- base::SequencedTaskRunnerHandle::Get()->PostTask(FROM_HERE,
- loop.QuitClosure());
- loop.Run();
- // When all forms of audio processing are disabled, |controller_| should
- // ignore the pending AudioProcessorControls Receiver it received in its ctor.
- EXPECT_FALSE(remote_controls_.is_connected());
- // InputController shouldn't spin up a processing thread if it's not needed.
- EXPECT_FALSE(helper_->IsUsingProcessingThread());
- // Test cleanup.
- controller_->Close();
- }
- TEST_P(InputControllerTestWithDeviceListener,
- CreateWithAudioProcessingConfig_VerifyFifoUsage) {
- SetupProcessingConfig(AudioProcessingType::kWithPlayoutReference);
- CreateAudioController();
- ASSERT_TRUE(controller_.get());
- // The processing thread should only be enabled when the processing FIFO
- // is explicitly enabled.
- EXPECT_EQ(IsProcessingFifoEnabled(), helper_->IsUsingProcessingThread());
- // Test cleanup.
- controller_->Close();
- }
- TEST_P(
- InputControllerTestWithDeviceListener,
- CreateWithAudioProcessingConfig_DoesNotListenForPlayoutReferenceIfNotRequired) {
- base::test::ScopedFeatureList features;
- const std::string kOutputDeviceId = "0x123";
- EXPECT_CALL(mock_stream_activity_monitor_, OnInputStreamActive()).Times(1);
- EXPECT_CALL(mock_stream_activity_monitor_, OnInputStreamInactive()).Times(1);
- EXPECT_CALL(device_output_listener_, StartListening(_, _)).Times(0);
- EXPECT_CALL(device_output_listener_, StopListening(_)).Times(0);
- SetupProcessingConfig(AudioProcessingType::kWithoutPlayoutReference);
- CreateAudioController();
- ASSERT_TRUE(controller_.get());
- controller_->Record();
- controller_->SetOutputDeviceForAec(kOutputDeviceId);
- // InputController spin up a processing thread if it's not needed.
- EXPECT_FALSE(helper_->IsUsingProcessingThread());
- controller_->Close();
- EXPECT_FALSE(helper_->IsUsingProcessingThread());
- }
- TEST_P(InputControllerTestWithDeviceListener, RecordBeforeSetOutputForAec) {
- const std::string kOutputDeviceId = "0x123";
- EXPECT_CALL(mock_stream_activity_monitor_, OnInputStreamActive()).Times(1);
- EXPECT_CALL(mock_stream_activity_monitor_, OnInputStreamInactive()).Times(1);
- // Calling Record() will start listening to the "" device by default.
- EXPECT_CALL(device_output_listener_, StartListening(_, "")).Times(1);
- EXPECT_CALL(device_output_listener_, StartListening(_, kOutputDeviceId))
- .Times(1);
- EXPECT_CALL(device_output_listener_, StopListening(_)).Times(1);
- SetupProcessingConfig(AudioProcessingType::kWithPlayoutReference);
- CreateAudioController();
- ASSERT_TRUE(controller_.get());
- controller_->Record();
- controller_->SetOutputDeviceForAec(kOutputDeviceId);
- // InputController should offload processing to its own thread, if enabled.
- EXPECT_EQ(IsProcessingFifoEnabled(), helper_->IsUsingProcessingThread());
- controller_->Close();
- // The processing thread should be stopped after controller has closed.
- EXPECT_FALSE(helper_->IsUsingProcessingThread());
- }
- TEST_P(InputControllerTestWithDeviceListener, RecordAfterSetOutputForAec) {
- const std::string kOutputDeviceId = "0x123";
- EXPECT_CALL(mock_stream_activity_monitor_, OnInputStreamActive()).Times(1);
- EXPECT_CALL(mock_stream_activity_monitor_, OnInputStreamInactive()).Times(1);
- EXPECT_CALL(device_output_listener_, StartListening(_, kOutputDeviceId))
- .Times(1);
- EXPECT_CALL(device_output_listener_, StopListening(_)).Times(1);
- SetupProcessingConfig(AudioProcessingType::kWithPlayoutReference);
- CreateAudioController();
- ASSERT_TRUE(controller_.get());
- controller_->SetOutputDeviceForAec(kOutputDeviceId);
- controller_->Record();
- // InputController should offload processing to its own thread, if enabled.
- EXPECT_EQ(IsProcessingFifoEnabled(), helper_->IsUsingProcessingThread());
- controller_->Close();
- // The processing thread should be stopped after controller has closed.
- EXPECT_FALSE(helper_->IsUsingProcessingThread());
- }
- TEST_P(InputControllerTestWithDeviceListener, ChangeOutputForAec) {
- const std::string kOutputDeviceId = "0x123";
- const std::string kOtherOutputDeviceId = "0x987";
- EXPECT_CALL(mock_stream_activity_monitor_, OnInputStreamActive()).Times(1);
- EXPECT_CALL(mock_stream_activity_monitor_, OnInputStreamInactive()).Times(1);
- // Each output ID should receive one call to StartListening().
- EXPECT_CALL(device_output_listener_, StartListening(_, kOutputDeviceId))
- .Times(1);
- EXPECT_CALL(device_output_listener_, StartListening(_, kOtherOutputDeviceId))
- .Times(1);
- // StopListening() should be called once, regardless of how many ID changes.
- EXPECT_CALL(device_output_listener_, StopListening(_)).Times(1);
- SetupProcessingConfig(AudioProcessingType::kWithPlayoutReference);
- CreateAudioController();
- ASSERT_TRUE(controller_.get());
- controller_->SetOutputDeviceForAec(kOutputDeviceId);
- controller_->Record();
- controller_->SetOutputDeviceForAec(kOtherOutputDeviceId);
- controller_->Close();
- }
- // Test a normal call sequence of create, record and close when audio processing
- // is enabled.
- // Note: Must use system time as MOCK_TIME does not support the threads created
- // by the FakeAudioInputStream. The callbacks to sync_writer_.Write() are on
- // that thread, and thus we must use SYSTEM_TIME.
- TEST_P(SystemTimeInputControllerTestWithDeviceListener, CreateRecordAndClose) {
- EXPECT_CALL(event_handler_, OnCreated(_));
- EXPECT_CALL(mock_stream_activity_monitor_, OnInputStreamActive()).Times(1);
- EXPECT_CALL(mock_stream_activity_monitor_, OnInputStreamInactive()).Times(1);
- SetupProcessingConfig(AudioProcessingType::kWithPlayoutReference);
- CreateAudioController();
- bool data_processed_by_fifo = false;
- if (IsProcessingFifoEnabled()) {
- auto main_sequence = base::SequencedTaskRunnerHandle::Get();
- auto verify_data_processed = [&data_processed_by_fifo, main_sequence]() {
- // Data should be processed on its own thread.
- EXPECT_FALSE(main_sequence->RunsTasksInCurrentSequence());
- data_processed_by_fifo = true;
- };
- helper_->AttachOnProcessedCallback(
- base::BindLambdaForTesting(verify_data_processed));
- }
- ASSERT_TRUE(controller_.get());
- base::RunLoop loop;
- {
- // Wait for Write() to be called ten times.
- testing::InSequence s;
- EXPECT_CALL(user_input_monitor_, EnableKeyPressMonitoring());
- EXPECT_CALL(sync_writer_, Write(NotNull(), _, _, _)).Times(Exactly(9));
- EXPECT_CALL(sync_writer_, Write(NotNull(), _, _, _))
- .Times(AtLeast(1))
- .WillOnce(InvokeWithoutArgs([&]() { loop.Quit(); }));
- }
- controller_->Record();
- // InputController should offload processing to its own thread if the
- // processing FIFO is enabled.
- EXPECT_EQ(IsProcessingFifoEnabled(), helper_->IsUsingProcessingThread());
- loop.Run();
- testing::Mock::VerifyAndClearExpectations(&user_input_monitor_);
- testing::Mock::VerifyAndClearExpectations(&sync_writer_);
- EXPECT_CALL(sync_writer_, Close());
- EXPECT_CALL(user_input_monitor_, DisableKeyPressMonitoring());
- controller_->Close();
- // The processing thread should be stopped after controller has closed.
- EXPECT_FALSE(helper_->IsUsingProcessingThread());
- task_environment_.RunUntilIdle();
- EXPECT_EQ(data_processed_by_fifo, IsProcessingFifoEnabled());
- }
- INSTANTIATE_TEST_SUITE_P(
- InputControllerTestWithDeviceListener,
- InputControllerTestWithDeviceListener,
- testing::Values(ProcessingFifoSetting::kEnabled,
- ProcessingFifoSetting::kEnabledWithSizeZero,
- ProcessingFifoSetting::kDisabled),
- test_name_generator);
- INSTANTIATE_TEST_SUITE_P(
- SystemTimeInputControllerTestWithDeviceListener,
- SystemTimeInputControllerTestWithDeviceListener,
- testing::Values(ProcessingFifoSetting::kEnabled,
- ProcessingFifoSetting::kEnabledWithSizeZero,
- ProcessingFifoSetting::kDisabled),
- test_name_generator);
- #endif // BUILDFLAG(CHROME_WIDE_ECHO_CANCELLATION)
- } // namespace audio
|