Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(172)

Side by Side Diff: media/audio/audio_system_impl_unittest.cc

Issue 2784433002: Ensures that audio tasks cannot run after AudioManager is deleted. (Closed)
Patch Set: cleanup Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2017 The Chromium Authors. All rights reserved. 1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "media/audio/audio_system_impl.h" 5 #include "media/audio/audio_system_impl.h"
6 #include "base/memory/ptr_util.h" 6 #include "base/memory/ptr_util.h"
7 #include "base/run_loop.h" 7 #include "base/run_loop.h"
8 #include "base/single_thread_task_runner.h" 8 #include "base/single_thread_task_runner.h"
9 #include "base/task_runner_util.h" 9 #include "base/task_runner_util.h"
10 #include "base/threading/thread.h" 10 #include "base/threading/thread.h"
11 #include "base/threading/thread_checker.h" 11 #include "base/threading/thread_checker.h"
12 #include "base/threading/thread_task_runner_handle.h" 12 #include "base/threading/thread_task_runner_handle.h"
13 #include "media/audio/audio_device_description.h" 13 #include "media/audio/audio_device_description.h"
14 #include "media/audio/audio_thread_impl.h"
14 #include "media/audio/mock_audio_manager.h" 15 #include "media/audio/mock_audio_manager.h"
16 #include "media/audio/test_audio_thread.h"
15 #include "media/base/test_helpers.h" 17 #include "media/base/test_helpers.h"
16 #include "testing/gmock/include/gmock/gmock.h" 18 #include "testing/gmock/include/gmock/gmock.h"
17 #include "testing/gtest/include/gtest/gtest.h" 19 #include "testing/gtest/include/gtest/gtest.h"
18 20
19 namespace { 21 namespace {
20 const char* kNonDefaultDeviceId = "non-default-device-id"; 22 const char* kNonDefaultDeviceId = "non-default-device-id";
21 } 23 }
22 24
23 namespace media { 25 namespace media {
24 26
25 bool operator==(const media::AudioDeviceDescription& lhs, 27 bool operator==(const media::AudioDeviceDescription& lhs,
26 const media::AudioDeviceDescription& rhs) { 28 const media::AudioDeviceDescription& rhs) {
27 return lhs.device_name == rhs.device_name && lhs.unique_id == rhs.unique_id && 29 return lhs.device_name == rhs.device_name && lhs.unique_id == rhs.unique_id &&
28 lhs.group_id == rhs.group_id; 30 lhs.group_id == rhs.group_id;
29 } 31 }
30 32
31 class AudioSystemImplTest : public testing::TestWithParam<bool> { 33 class AudioSystemImplTest : public testing::TestWithParam<bool> {
32 public: 34 public:
33 AudioSystemImplTest() 35 AudioSystemImplTest()
34 : use_audio_thread_(GetParam()), 36 : use_audio_thread_(GetParam()),
35 audio_thread_("AudioSystemThread"),
36 input_params_(AudioParameters::AUDIO_PCM_LINEAR, 37 input_params_(AudioParameters::AUDIO_PCM_LINEAR,
37 CHANNEL_LAYOUT_MONO, 38 CHANNEL_LAYOUT_MONO,
38 AudioParameters::kTelephoneSampleRate, 39 AudioParameters::kTelephoneSampleRate,
39 16, 40 16,
40 AudioParameters::kTelephoneSampleRate / 10), 41 AudioParameters::kTelephoneSampleRate / 10),
41 output_params_(AudioParameters::AUDIO_PCM_LINEAR, 42 output_params_(AudioParameters::AUDIO_PCM_LINEAR,
42 CHANNEL_LAYOUT_MONO, 43 CHANNEL_LAYOUT_MONO,
43 AudioParameters::kTelephoneSampleRate, 44 AudioParameters::kTelephoneSampleRate,
44 16, 45 16,
45 AudioParameters::kTelephoneSampleRate / 20), 46 AudioParameters::kTelephoneSampleRate / 20),
46 default_output_params_(AudioParameters::AUDIO_PCM_LINEAR, 47 default_output_params_(AudioParameters::AUDIO_PCM_LINEAR,
47 CHANNEL_LAYOUT_MONO, 48 CHANNEL_LAYOUT_MONO,
48 AudioParameters::kTelephoneSampleRate, 49 AudioParameters::kTelephoneSampleRate,
49 16, 50 16,
50 AudioParameters::kTelephoneSampleRate / 30) { 51 AudioParameters::kTelephoneSampleRate / 30) {
51 if (use_audio_thread_) { 52 if (use_audio_thread_) {
52 audio_thread_.StartAndWaitForTesting(); 53 audio_manager_ = base::MakeUnique<MockAudioManager>(
53 audio_manager_.reset( 54 base::MakeUnique<AudioThreadImpl>());
54 new media::MockAudioManager(audio_thread_.task_runner()));
55 } else { 55 } else {
56 audio_manager_.reset(new media::MockAudioManager( 56 audio_manager_ = base::MakeUnique<MockAudioManager>(
57 base::ThreadTaskRunnerHandle::Get().get())); 57 base::MakeUnique<TestAudioThread>());
o1ka 2017/04/28 13:24:20 Can we have a bool parameter for AudioThreadImpl c
alokp 2017/04/28 17:31:12 I think this is cleaner. Did you have any specific
o1ka 2017/05/02 16:16:00 The problem with this particular test is that |use
alokp 2017/05/02 17:11:28 You are right, but what is the use for testing a c
o1ka 2017/05/02 21:42:23 AudioSystem can be accessed from any thread. In pr
alokp 2017/05/09 19:06:15 I added a bool to TestAudioThread constructor and
58 } 58 }
59
60 audio_manager_->SetInputStreamParameters(input_params_); 59 audio_manager_->SetInputStreamParameters(input_params_);
61 audio_manager_->SetOutputStreamParameters(output_params_); 60 audio_manager_->SetOutputStreamParameters(output_params_);
62 audio_manager_->SetDefaultOutputStreamParameters(default_output_params_); 61 audio_manager_->SetDefaultOutputStreamParameters(default_output_params_);
63 62
64 auto get_device_descriptions = [](const AudioDeviceDescriptions* source, 63 auto get_device_descriptions = [](const AudioDeviceDescriptions* source,
65 AudioDeviceDescriptions* destination) { 64 AudioDeviceDescriptions* destination) {
66 destination->insert(destination->end(), source->begin(), source->end()); 65 destination->insert(destination->end(), source->begin(), source->end());
67 }; 66 };
68 67
69 audio_manager_->SetInputDeviceDescriptionsCallback( 68 audio_manager_->SetInputDeviceDescriptionsCallback(
70 base::Bind(get_device_descriptions, 69 base::Bind(get_device_descriptions,
71 base::Unretained(&input_device_descriptions_))); 70 base::Unretained(&input_device_descriptions_)));
72 audio_manager_->SetOutputDeviceDescriptionsCallback( 71 audio_manager_->SetOutputDeviceDescriptionsCallback(
73 base::Bind(get_device_descriptions, 72 base::Bind(get_device_descriptions,
74 base::Unretained(&output_device_descriptions_))); 73 base::Unretained(&output_device_descriptions_)));
75 74
76 audio_system_ = media::AudioSystemImpl::Create(audio_manager_.get()); 75 audio_system_ = media::AudioSystemImpl::Create(audio_manager_.get());
77 EXPECT_EQ(AudioSystem::Get(), audio_system_.get()); 76 EXPECT_EQ(AudioSystem::Get(), audio_system_.get());
78 } 77 }
79 78
80 ~AudioSystemImplTest() override { 79 ~AudioSystemImplTest() override { audio_manager_->Shutdown(); }
o1ka 2017/04/28 13:24:20 Note that in this test the destruction sequence is
alokp 2017/04/28 17:31:12 This one is correct :) We need to fix BML as noted
o1ka 2017/05/02 16:16:00 Right, that's what I thought :)
81 // Deleting |audio_manager_| on its thread.
82 audio_system_.reset();
83 EXPECT_EQ(AudioSystem::Get(), nullptr);
84 audio_manager_.reset();
85 audio_thread_.Stop();
86 }
87 80
88 void OnAudioParams(const AudioParameters& expected, 81 void OnAudioParams(const AudioParameters& expected,
89 const AudioParameters& received) { 82 const AudioParameters& received) {
90 EXPECT_TRUE(thread_checker_.CalledOnValidThread()); 83 EXPECT_TRUE(thread_checker_.CalledOnValidThread());
91 EXPECT_EQ(expected.AsHumanReadableString(), 84 EXPECT_EQ(expected.AsHumanReadableString(),
92 received.AsHumanReadableString()); 85 received.AsHumanReadableString());
93 AudioParametersReceived(); 86 AudioParametersReceived();
94 } 87 }
95 88
96 void OnHasInputDevices(bool result) { 89 void OnHasInputDevices(bool result) {
(...skipping 28 matching lines...) Expand all
125 EXPECT_EQ(expected_associated_device_id, associated_device_id); 118 EXPECT_EQ(expected_associated_device_id, associated_device_id);
126 InputDeviceInfoReceived(); 119 InputDeviceInfoReceived();
127 } 120 }
128 121
129 void WaitForCallback() { 122 void WaitForCallback() {
130 if (!use_audio_thread_) { 123 if (!use_audio_thread_) {
131 base::RunLoop().RunUntilIdle(); 124 base::RunLoop().RunUntilIdle();
132 return; 125 return;
133 } 126 }
134 WaitableMessageLoopEvent event; 127 WaitableMessageLoopEvent event;
135 audio_thread_.task_runner()->PostTaskAndReply( 128 audio_manager_->GetTaskRunner()->PostTaskAndReply(
136 FROM_HERE, base::Bind(&base::DoNothing), event.GetClosure()); 129 FROM_HERE, base::Bind(&base::DoNothing), event.GetClosure());
137 // Runs the loop and waits for the |audio_thread_| to call event's closure, 130 // Runs the loop and waits for the |audio_thread_| to call event's closure,
138 // which means AudioSystem reply containing device parameters is already 131 // which means AudioSystem reply containing device parameters is already
139 // queued on the main thread. 132 // queued on the main thread.
140 event.RunAndWait(); 133 event.RunAndWait();
141 base::RunLoop().RunUntilIdle(); 134 base::RunLoop().RunUntilIdle();
142 } 135 }
143 136
144 // Mocks to verify that AudioSystem replied with an expected callback. 137 // Mocks to verify that AudioSystem replied with an expected callback.
145 MOCK_METHOD0(AudioParametersReceived, void(void)); 138 MOCK_METHOD0(AudioParametersReceived, void(void));
146 MOCK_METHOD1(HasInputDevicesCallback, void(bool)); 139 MOCK_METHOD1(HasInputDevicesCallback, void(bool));
147 MOCK_METHOD1(HasOutputDevicesCallback, void(bool)); 140 MOCK_METHOD1(HasOutputDevicesCallback, void(bool));
148 MOCK_METHOD0(DeviceDescriptionsReceived, void(void)); 141 MOCK_METHOD0(DeviceDescriptionsReceived, void(void));
149 MOCK_METHOD1(AssociatedOutputDeviceIDReceived, void(const std::string&)); 142 MOCK_METHOD1(AssociatedOutputDeviceIDReceived, void(const std::string&));
150 MOCK_METHOD0(InputDeviceInfoReceived, void(void)); 143 MOCK_METHOD0(InputDeviceInfoReceived, void(void));
151 144
152 protected: 145 protected:
153 base::MessageLoop message_loop_; 146 base::MessageLoop message_loop_;
154 base::ThreadChecker thread_checker_; 147 base::ThreadChecker thread_checker_;
155 bool use_audio_thread_; 148 bool use_audio_thread_;
156 base::Thread audio_thread_; 149 std::unique_ptr<media::MockAudioManager> audio_manager_;
157 MockAudioManager::UniquePtr audio_manager_;
158 std::unique_ptr<media::AudioSystem> audio_system_; 150 std::unique_ptr<media::AudioSystem> audio_system_;
159 AudioParameters input_params_; 151 AudioParameters input_params_;
160 AudioParameters output_params_; 152 AudioParameters output_params_;
161 AudioParameters default_output_params_; 153 AudioParameters default_output_params_;
162 AudioDeviceDescriptions input_device_descriptions_; 154 AudioDeviceDescriptions input_device_descriptions_;
163 AudioDeviceDescriptions output_device_descriptions_; 155 AudioDeviceDescriptions output_device_descriptions_;
164 }; 156 };
165 157
166 TEST_P(AudioSystemImplTest, GetInputStreamParameters) { 158 TEST_P(AudioSystemImplTest, GetInputStreamParameters) {
167 EXPECT_CALL(*this, AudioParametersReceived()); 159 EXPECT_CALL(*this, AudioParametersReceived());
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
344 audio_system_->GetInputDeviceInfo( 336 audio_system_->GetInputDeviceInfo(
345 kNonDefaultDeviceId, base::Bind(&AudioSystemImplTest::OnInputDeviceInfo, 337 kNonDefaultDeviceId, base::Bind(&AudioSystemImplTest::OnInputDeviceInfo,
346 base::Unretained(this), input_params_, 338 base::Unretained(this), input_params_,
347 output_params_, associated_id)); 339 output_params_, associated_id));
348 WaitForCallback(); 340 WaitForCallback();
349 } 341 }
350 342
351 INSTANTIATE_TEST_CASE_P(, AudioSystemImplTest, testing::Values(false, true)); 343 INSTANTIATE_TEST_CASE_P(, AudioSystemImplTest, testing::Values(false, true));
352 344
353 } // namespace media 345 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698