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

Side by Side Diff: content/browser/renderer_host/media/audio_renderer_host_unittest.cc

Issue 1171953002: Add IPC interface for switching the audio output device for a given audio stream in the browser. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix style Created 5 years, 6 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 (c) 2012 The Chromium Authors. All rights reserved. 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 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 "base/bind.h" 5 #include "base/bind.h"
6 #include "base/command_line.h" 6 #include "base/command_line.h"
7 #include "base/memory/scoped_ptr.h" 7 #include "base/memory/scoped_ptr.h"
8 #include "base/run_loop.h" 8 #include "base/run_loop.h"
9 #include "base/sync_socket.h" 9 #include "base/sync_socket.h"
10 #include "content/browser/media/capture/audio_mirroring_manager.h" 10 #include "content/browser/media/capture/audio_mirroring_manager.h"
(...skipping 13 matching lines...) Expand all
24 24
25 using ::testing::_; 25 using ::testing::_;
26 using ::testing::Assign; 26 using ::testing::Assign;
27 using ::testing::DoAll; 27 using ::testing::DoAll;
28 using ::testing::NotNull; 28 using ::testing::NotNull;
29 29
30 namespace { 30 namespace {
31 const int kRenderProcessId = 1; 31 const int kRenderProcessId = 1;
32 const int kRenderFrameId = 5; 32 const int kRenderFrameId = 5;
33 const int kStreamId = 50; 33 const int kStreamId = 50;
34 const int kBadStreamId = 99;
35 const int kSwitchOutputDeviceRequestId = 1;
36 const GURL kSecurityOrigin("http://localhost");
37 const std::string kDefaultDeviceID = "";
38 const std::string kBadDeviceID = "bad-device-id";
34 } // namespace 39 } // namespace
35 40
36 namespace content { 41 namespace content {
37 42
38 class MockAudioMirroringManager : public AudioMirroringManager { 43 class MockAudioMirroringManager : public AudioMirroringManager {
39 public: 44 public:
40 MockAudioMirroringManager() {} 45 MockAudioMirroringManager() {}
41 virtual ~MockAudioMirroringManager() {} 46 virtual ~MockAudioMirroringManager() {}
42 47
43 MOCK_METHOD3(AddDiverter, 48 MOCK_METHOD3(AddDiverter,
44 void(int render_process_id, 49 void(int render_process_id,
45 int render_frame_id, 50 int render_frame_id,
46 Diverter* diverter)); 51 Diverter* diverter));
47 MOCK_METHOD1(RemoveDiverter, void(Diverter* diverter)); 52 MOCK_METHOD1(RemoveDiverter, void(Diverter* diverter));
48 53
49 private: 54 private:
50 DISALLOW_COPY_AND_ASSIGN(MockAudioMirroringManager); 55 DISALLOW_COPY_AND_ASSIGN(MockAudioMirroringManager);
51 }; 56 };
52 57
53 class MockAudioRendererHost : public AudioRendererHost { 58 class MockAudioRendererHost : public AudioRendererHost {
54 public: 59 public:
55 MockAudioRendererHost(media::AudioManager* audio_manager, 60 MockAudioRendererHost(media::AudioManager* audio_manager,
56 AudioMirroringManager* mirroring_manager, 61 AudioMirroringManager* mirroring_manager,
57 MediaInternals* media_internals, 62 MediaInternals* media_internals,
58 MediaStreamManager* media_stream_manager) 63 MediaStreamManager* media_stream_manager,
64 const ResourceContext::SaltCallback& salt_callback)
59 : AudioRendererHost(kRenderProcessId, 65 : AudioRendererHost(kRenderProcessId,
60 audio_manager, 66 audio_manager,
61 mirroring_manager, 67 mirroring_manager,
62 media_internals, 68 media_internals,
63 media_stream_manager), 69 media_stream_manager,
70 salt_callback),
64 shared_memory_length_(0) {} 71 shared_memory_length_(0) {}
65 72
66 // A list of mock methods. 73 // A list of mock methods.
67 MOCK_METHOD2(OnStreamCreated, void(int stream_id, int length)); 74 MOCK_METHOD2(OnStreamCreated, void(int stream_id, int length));
68 MOCK_METHOD1(OnStreamPlaying, void(int stream_id)); 75 MOCK_METHOD1(OnStreamPlaying, void(int stream_id));
69 MOCK_METHOD1(OnStreamPaused, void(int stream_id)); 76 MOCK_METHOD1(OnStreamPaused, void(int stream_id));
70 MOCK_METHOD1(OnStreamError, void(int stream_id)); 77 MOCK_METHOD1(OnStreamError, void(int stream_id));
78 MOCK_METHOD3(OnOutputDeviceSwitched,
79 void(int stream_id,
80 int request_id,
81 media::SwitchOutputDeviceResult result));
71 82
72 private: 83 private:
73 virtual ~MockAudioRendererHost() { 84 virtual ~MockAudioRendererHost() {
74 // Make sure all audio streams have been deleted. 85 // Make sure all audio streams have been deleted.
75 EXPECT_TRUE(audio_entries_.empty()); 86 EXPECT_TRUE(audio_entries_.empty());
76 } 87 }
77 88
78 // This method is used to dispatch IPC messages to the renderer. We intercept 89 // This method is used to dispatch IPC messages to the renderer. We intercept
79 // these messages here and dispatch to our mock methods to verify the 90 // these messages here and dispatch to our mock methods to verify the
80 // conversation between this object and the renderer. 91 // conversation between this object and the renderer.
81 virtual bool Send(IPC::Message* message) { 92 virtual bool Send(IPC::Message* message) {
82 CHECK(message); 93 CHECK(message);
83 94
84 // In this method we dispatch the messages to the according handlers as if 95 // In this method we dispatch the messages to the according handlers as if
85 // we are the renderer. 96 // we are the renderer.
86 bool handled = true; 97 bool handled = true;
87 IPC_BEGIN_MESSAGE_MAP(MockAudioRendererHost, *message) 98 IPC_BEGIN_MESSAGE_MAP(MockAudioRendererHost, *message)
88 IPC_MESSAGE_HANDLER(AudioMsg_NotifyStreamCreated, 99 IPC_MESSAGE_HANDLER(AudioMsg_NotifyStreamCreated,
89 OnNotifyStreamCreated) 100 OnNotifyStreamCreated)
90 IPC_MESSAGE_HANDLER(AudioMsg_NotifyStreamStateChanged, 101 IPC_MESSAGE_HANDLER(AudioMsg_NotifyStreamStateChanged,
91 OnNotifyStreamStateChanged) 102 OnNotifyStreamStateChanged)
103 IPC_MESSAGE_HANDLER(AudioMsg_NotifyOutputDeviceSwitched,
104 OnNotifyOutputDeviceSwitched)
92 IPC_MESSAGE_UNHANDLED(handled = false) 105 IPC_MESSAGE_UNHANDLED(handled = false)
93 IPC_END_MESSAGE_MAP() 106 IPC_END_MESSAGE_MAP()
94 EXPECT_TRUE(handled); 107 EXPECT_TRUE(handled);
95 108
96 delete message; 109 delete message;
97 return true; 110 return true;
98 } 111 }
99 112
100 void OnNotifyStreamCreated( 113 void OnNotifyStreamCreated(
101 int stream_id, base::SharedMemoryHandle handle, 114 int stream_id, base::SharedMemoryHandle handle,
(...skipping 24 matching lines...) Expand all
126 break; 139 break;
127 case media::AudioOutputIPCDelegate::kError: 140 case media::AudioOutputIPCDelegate::kError:
128 OnStreamError(stream_id); 141 OnStreamError(stream_id);
129 break; 142 break;
130 default: 143 default:
131 FAIL() << "Unknown stream state"; 144 FAIL() << "Unknown stream state";
132 break; 145 break;
133 } 146 }
134 } 147 }
135 148
149 void OnNotifyOutputDeviceSwitched(int stream_id,
150 int request_id,
151 media::SwitchOutputDeviceResult result) {
152 switch (result) {
153 case media::SWITCH_OUTPUT_DEVICE_RESULT_SUCCESS:
154 case media::SWITCH_OUTPUT_DEVICE_RESULT_ERROR_NOT_FOUND:
155 case media::SWITCH_OUTPUT_DEVICE_RESULT_ERROR_NOT_AUTHORIZED:
156 case media::SWITCH_OUTPUT_DEVICE_RESULT_ERROR_OBSOLETE:
157 case media::SWITCH_OUTPUT_DEVICE_RESULT_ERROR_NOT_SUPPORTED:
158 OnOutputDeviceSwitched(stream_id, request_id, result);
159 break;
160 default:
161 FAIL() << "Unknown SwitchOutputDevice result";
162 break;
163 }
164 }
165
136 scoped_ptr<base::SharedMemory> shared_memory_; 166 scoped_ptr<base::SharedMemory> shared_memory_;
137 scoped_ptr<base::SyncSocket> sync_socket_; 167 scoped_ptr<base::SyncSocket> sync_socket_;
138 uint32 shared_memory_length_; 168 uint32 shared_memory_length_;
139 169
140 DISALLOW_COPY_AND_ASSIGN(MockAudioRendererHost); 170 DISALLOW_COPY_AND_ASSIGN(MockAudioRendererHost);
141 }; 171 };
142 172
173 namespace {
174 std::string ReturnMockSalt() {
175 return std::string();
176 }
177
178 ResourceContext::SaltCallback GetMockSaltCallback() {
179 return base::Bind(&ReturnMockSalt);
180 }
181 }
182
143 class AudioRendererHostTest : public testing::Test { 183 class AudioRendererHostTest : public testing::Test {
144 public: 184 public:
145 AudioRendererHostTest() { 185 AudioRendererHostTest() {
146 audio_manager_.reset(media::AudioManager::CreateForTesting()); 186 audio_manager_.reset(media::AudioManager::CreateForTesting());
147 base::CommandLine::ForCurrentProcess()->AppendSwitch( 187 base::CommandLine::ForCurrentProcess()->AppendSwitch(
148 switches::kUseFakeDeviceForMediaStream); 188 switches::kUseFakeDeviceForMediaStream);
149 media_stream_manager_.reset(new MediaStreamManager(audio_manager_.get())); 189 media_stream_manager_.reset(new MediaStreamManager(audio_manager_.get()));
150 host_ = new MockAudioRendererHost(audio_manager_.get(), 190 host_ = new MockAudioRendererHost(audio_manager_.get(), &mirroring_manager_,
151 &mirroring_manager_,
152 MediaInternals::GetInstance(), 191 MediaInternals::GetInstance(),
153 media_stream_manager_.get()); 192 media_stream_manager_.get(),
193 GetMockSaltCallback());
154 194
155 // Simulate IPC channel connected. 195 // Simulate IPC channel connected.
156 host_->set_peer_process_for_testing(base::Process::Current()); 196 host_->set_peer_process_for_testing(base::Process::Current());
157 } 197 }
158 198
159 ~AudioRendererHostTest() override { 199 ~AudioRendererHostTest() override {
160 // Simulate closing the IPC channel and give the audio thread time to close 200 // Simulate closing the IPC channel and give the audio thread time to close
161 // the underlying streams. 201 // the underlying streams.
162 host_->OnChannelClosing(); 202 host_->OnChannelClosing();
163 SyncWithAudioThread(); 203 SyncWithAudioThread();
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
223 EXPECT_CALL(*host_.get(), OnStreamPaused(kStreamId)); 263 EXPECT_CALL(*host_.get(), OnStreamPaused(kStreamId));
224 host_->OnPauseStream(kStreamId); 264 host_->OnPauseStream(kStreamId);
225 SyncWithAudioThread(); 265 SyncWithAudioThread();
226 } 266 }
227 267
228 void SetVolume(double volume) { 268 void SetVolume(double volume) {
229 host_->OnSetVolume(kStreamId, volume); 269 host_->OnSetVolume(kStreamId, volume);
230 SyncWithAudioThread(); 270 SyncWithAudioThread();
231 } 271 }
232 272
273 void SwitchOutputDevice(int stream_id,
274 std::string device_id,
275 media::SwitchOutputDeviceResult expected_result) {
276 EXPECT_CALL(*host_.get(),
277 OnOutputDeviceSwitched(stream_id, kSwitchOutputDeviceRequestId,
278 expected_result));
279 host_->OnSwitchOutputDevice(stream_id, kRenderFrameId, device_id,
280 kSecurityOrigin, kSwitchOutputDeviceRequestId);
281 SyncWithAudioThread();
282 }
283
233 void SimulateError() { 284 void SimulateError() {
234 EXPECT_EQ(1u, host_->audio_entries_.size()) 285 EXPECT_EQ(1u, host_->audio_entries_.size())
235 << "Calls Create() before calling this method"; 286 << "Calls Create() before calling this method";
236 287
237 // Expect an error signal sent through IPC. 288 // Expect an error signal sent through IPC.
238 EXPECT_CALL(*host_.get(), OnStreamError(kStreamId)); 289 EXPECT_CALL(*host_.get(), OnStreamError(kStreamId));
239 290
240 // Simulate an error sent from the audio device. 291 // Simulate an error sent from the audio device.
241 host_->ReportErrorAndClose(kStreamId); 292 host_->ReportErrorAndClose(kStreamId);
242 SyncWithAudioThread(); 293 SyncWithAudioThread();
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
294 } 345 }
295 346
296 TEST_F(AudioRendererHostTest, SetVolume) { 347 TEST_F(AudioRendererHostTest, SetVolume) {
297 Create(false); 348 Create(false);
298 SetVolume(0.5); 349 SetVolume(0.5);
299 Play(); 350 Play();
300 Pause(); 351 Pause();
301 Close(); 352 Close();
302 } 353 }
303 354
355 TEST_F(AudioRendererHostTest, SwitchOutputDevice) {
356 Create(false);
357 SwitchOutputDevice(kStreamId, kDefaultDeviceID,
358 media::SWITCH_OUTPUT_DEVICE_RESULT_SUCCESS);
359 Close();
360 }
361
362 TEST_F(AudioRendererHostTest, SwitchOutputDeviceNotAuthorized) {
363 Create(false);
364 SwitchOutputDevice(kStreamId, kBadDeviceID,
365 media::SWITCH_OUTPUT_DEVICE_RESULT_ERROR_NOT_AUTHORIZED);
366 Close();
367 }
368
369 TEST_F(AudioRendererHostTest, SwitchOutputDeviceNoStream) {
370 Create(false);
371 SwitchOutputDevice(kBadStreamId, kDefaultDeviceID,
372 media::SWITCH_OUTPUT_DEVICE_RESULT_ERROR_OBSOLETE);
373 Close();
374 }
375
304 // Simulate the case where a stream is not properly closed. 376 // Simulate the case where a stream is not properly closed.
305 TEST_F(AudioRendererHostTest, CreatePlayAndShutdown) { 377 TEST_F(AudioRendererHostTest, CreatePlayAndShutdown) {
306 Create(false); 378 Create(false);
307 Play(); 379 Play();
308 } 380 }
309 381
310 // Simulate the case where a stream is not properly closed. 382 // Simulate the case where a stream is not properly closed.
311 TEST_F(AudioRendererHostTest, CreatePlayPauseAndShutdown) { 383 TEST_F(AudioRendererHostTest, CreatePlayPauseAndShutdown) {
312 Create(false); 384 Create(false);
313 Play(); 385 Play();
(...skipping 17 matching lines...) Expand all
331 } 403 }
332 404
333 TEST_F(AudioRendererHostTest, CreateUnifiedStreamAndClose) { 405 TEST_F(AudioRendererHostTest, CreateUnifiedStreamAndClose) {
334 Create(true); 406 Create(true);
335 Close(); 407 Close();
336 } 408 }
337 409
338 // TODO(hclam): Add tests for data conversation in low latency mode. 410 // TODO(hclam): Add tests for data conversation in low latency mode.
339 411
340 } // namespace content 412 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/renderer_host/media/audio_renderer_host.cc ('k') | content/browser/renderer_host/render_process_host_impl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698