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

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

Issue 2424163004: Factor out authorization from AudioRendererHost. (Closed)
Patch Set: Guidos comments. Created 4 years, 1 month 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 "content/browser/renderer_host/media/audio_renderer_host.h" 5 #include "content/browser/renderer_host/media/audio_renderer_host.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 8
9 #include <memory> 9 #include <memory>
10 10
11 #include "base/bind.h" 11 #include "base/bind.h"
12 #include "base/command_line.h" 12 #include "base/command_line.h"
13 #include "base/macros.h" 13 #include "base/macros.h"
14 #include "base/run_loop.h" 14 #include "base/run_loop.h"
15 #include "base/sync_socket.h" 15 #include "base/sync_socket.h"
16 #include "content/browser/media/capture/audio_mirroring_manager.h" 16 #include "content/browser/media/capture/audio_mirroring_manager.h"
17 #include "content/browser/media/media_internals.h" 17 #include "content/browser/media/media_internals.h"
18 #include "content/browser/renderer_host/media/audio_input_device_manager.h" 18 #include "content/browser/renderer_host/media/audio_input_device_manager.h"
19 #include "content/browser/renderer_host/media/media_stream_manager.h" 19 #include "content/browser/renderer_host/media/media_stream_manager.h"
20 #include "content/common/media/audio_messages.h" 20 #include "content/common/media/audio_messages.h"
21 #include "content/public/common/content_switches.h" 21 #include "content/public/common/content_switches.h"
22 #include "content/public/test/mock_render_process_host.h"
23 #include "content/public/test/test_browser_context.h"
22 #include "content/public/test/test_browser_thread_bundle.h" 24 #include "content/public/test/test_browser_thread_bundle.h"
23 #include "ipc/ipc_message_utils.h" 25 #include "ipc/ipc_message_utils.h"
24 #include "media/audio/audio_manager.h" 26 #include "media/audio/audio_manager.h"
25 #include "media/base/bind_to_current_loop.h" 27 #include "media/base/bind_to_current_loop.h"
26 #include "media/base/media_switches.h" 28 #include "media/base/media_switches.h"
27 #include "testing/gmock/include/gmock/gmock.h" 29 #include "testing/gmock/include/gmock/gmock.h"
28 #include "testing/gtest/include/gtest/gtest.h" 30 #include "testing/gtest/include/gtest/gtest.h"
29 31
30 using ::testing::_; 32 using ::testing::_;
31 using ::testing::Assign; 33 using ::testing::Assign;
32 using ::testing::AtLeast; 34 using ::testing::AtLeast;
33 using ::testing::DoAll; 35 using ::testing::DoAll;
34 using ::testing::NotNull; 36 using ::testing::NotNull;
35 37
36 namespace content { 38 namespace content {
37 39
38 namespace { 40 namespace {
39 const int kRenderProcessId = 1;
40 const int kRenderFrameId = 5; 41 const int kRenderFrameId = 5;
41 const int kStreamId = 50; 42 const int kStreamId = 50;
42 const char kSecurityOrigin[] = "http://localhost"; 43 const char kSecurityOrigin[] = "http://localhost";
43 const char kBadSecurityOrigin[] = "about:about"; 44 const char kBadSecurityOrigin[] = "about:about";
44 const char kDefaultDeviceId[] = ""; 45 const char kDefaultDeviceId[] = "";
45 const char kNondefaultDeviceId[] = 46 const char kNondefaultDeviceId[] =
46 "deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef"; 47 "deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef";
47 const char kBadDeviceId[] = 48 const char kBadDeviceId[] =
48 "badbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbad1"; 49 "badbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbad1";
49 const char kInvalidDeviceId[] = "invalid-device-id"; 50 const char kInvalidDeviceId[] = "invalid-device-id";
50 51
51 void ValidateRenderFrameId(int render_process_id, 52 void ValidateRenderFrameId(int render_process_id,
52 int render_frame_id, 53 int render_frame_id,
53 const base::Callback<void(bool)>& callback) { 54 const base::Callback<void(bool)>& callback) {
54 DCHECK_CURRENTLY_ON(BrowserThread::UI); 55 DCHECK_CURRENTLY_ON(BrowserThread::UI);
55 const bool frame_exists = (render_process_id == kRenderProcessId && 56 const bool frame_exists = (render_frame_id == kRenderFrameId);
56 render_frame_id == kRenderFrameId);
57 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, 57 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
58 base::Bind(callback, frame_exists)); 58 base::Bind(callback, frame_exists));
59 } 59 }
60 60
61 } // namespace 61 } // namespace
62 62
63 class MockAudioMirroringManager : public AudioMirroringManager { 63 class MockAudioMirroringManager : public AudioMirroringManager {
64 public: 64 public:
65 MockAudioMirroringManager() {} 65 MockAudioMirroringManager() {}
66 virtual ~MockAudioMirroringManager() {} 66 virtual ~MockAudioMirroringManager() {}
67 67
68 MOCK_METHOD3(AddDiverter, 68 MOCK_METHOD3(AddDiverter,
69 void(int render_process_id, 69 void(int render_process_id,
70 int render_frame_id, 70 int render_frame_id,
71 Diverter* diverter)); 71 Diverter* diverter));
72 MOCK_METHOD1(RemoveDiverter, void(Diverter* diverter)); 72 MOCK_METHOD1(RemoveDiverter, void(Diverter* diverter));
73 73
74 private: 74 private:
75 DISALLOW_COPY_AND_ASSIGN(MockAudioMirroringManager); 75 DISALLOW_COPY_AND_ASSIGN(MockAudioMirroringManager);
76 }; 76 };
77 77
78 class MockAudioRendererHost : public AudioRendererHost { 78 class MockAudioRendererHost : public AudioRendererHost {
79 public: 79 public:
80 MockAudioRendererHost(base::RunLoop* auth_run_loop, 80 MockAudioRendererHost(base::RunLoop* auth_run_loop,
81 int render_process_id,
81 media::AudioManager* audio_manager, 82 media::AudioManager* audio_manager,
82 AudioMirroringManager* mirroring_manager, 83 AudioMirroringManager* mirroring_manager,
83 MediaInternals* media_internals, 84 MediaInternals* media_internals,
84 MediaStreamManager* media_stream_manager, 85 MediaStreamManager* media_stream_manager,
85 const std::string& salt) 86 const std::string& salt)
86 : AudioRendererHost(kRenderProcessId, 87 : AudioRendererHost(render_process_id,
87 audio_manager, 88 audio_manager,
88 mirroring_manager, 89 mirroring_manager,
89 media_internals, 90 media_internals,
90 media_stream_manager, 91 media_stream_manager,
91 salt), 92 salt),
92 shared_memory_length_(0), 93 shared_memory_length_(0),
93 auth_run_loop_(auth_run_loop) { 94 auth_run_loop_(auth_run_loop) {
94 set_render_frame_id_validate_function_for_testing(&ValidateRenderFrameId); 95 set_render_frame_id_validate_function_for_testing(&ValidateRenderFrameId);
95 } 96 }
96 97
97 // A list of mock methods. 98 // A list of mock methods.
98 MOCK_METHOD0(ShutdownForBadMessage, void());
99 MOCK_METHOD4(OnDeviceAuthorized, 99 MOCK_METHOD4(OnDeviceAuthorized,
100 void(int stream_id, 100 void(int stream_id,
101 media::OutputDeviceStatus device_status, 101 media::OutputDeviceStatus device_status,
102 const media::AudioParameters& output_params, 102 const media::AudioParameters& output_params,
103 const std::string& matched_device_id)); 103 const std::string& matched_device_id));
104 MOCK_METHOD2(OnStreamCreated, void(int stream_id, int length)); 104 MOCK_METHOD2(OnStreamCreated, void(int stream_id, int length));
105 MOCK_METHOD1(OnStreamError, void(int stream_id)); 105 MOCK_METHOD1(OnStreamError, void(int stream_id));
106 106
107 void ShutdownForBadMessage() override { bad_msg_count++; }
108
109 int bad_msg_count = 0;
110
107 private: 111 private:
108 virtual ~MockAudioRendererHost() { 112 virtual ~MockAudioRendererHost() {
109 // Make sure all audio streams have been deleted. 113 // Make sure all audio streams have been deleted.
110 EXPECT_TRUE(audio_entries_.empty()); 114 EXPECT_TRUE(audio_entries_.empty());
111 } 115 }
112 116
113 // This method is used to dispatch IPC messages to the renderer. We intercept 117 // This method is used to dispatch IPC messages to the renderer. We intercept
114 // these messages here and dispatch to our mock methods to verify the 118 // these messages here and dispatch to our mock methods to verify the
115 // conversation between this object and the renderer. 119 // conversation between this object and the renderer.
116 // Note: this means that file descriptors won't be duplicated, 120 // Note: this means that file descriptors won't be duplicated,
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
170 std::unique_ptr<base::SharedMemory> shared_memory_; 174 std::unique_ptr<base::SharedMemory> shared_memory_;
171 std::unique_ptr<base::SyncSocket> sync_socket_; 175 std::unique_ptr<base::SyncSocket> sync_socket_;
172 uint32_t shared_memory_length_; 176 uint32_t shared_memory_length_;
173 base::RunLoop* auth_run_loop_; // Used to wait for authorization. 177 base::RunLoop* auth_run_loop_; // Used to wait for authorization.
174 178
175 DISALLOW_COPY_AND_ASSIGN(MockAudioRendererHost); 179 DISALLOW_COPY_AND_ASSIGN(MockAudioRendererHost);
176 }; 180 };
177 181
178 class AudioRendererHostTest : public testing::Test { 182 class AudioRendererHostTest : public testing::Test {
179 public: 183 public:
180 AudioRendererHostTest() { 184 AudioRendererHostTest() : render_process_host_(&browser_context_) {
181 audio_manager_ = media::AudioManager::CreateForTesting( 185 audio_manager_ = media::AudioManager::CreateForTesting(
182 base::ThreadTaskRunnerHandle::Get()); 186 base::ThreadTaskRunnerHandle::Get());
183 base::CommandLine::ForCurrentProcess()->AppendSwitch( 187 base::CommandLine::ForCurrentProcess()->AppendSwitch(
184 switches::kUseFakeDeviceForMediaStream); 188 switches::kUseFakeDeviceForMediaStream);
185 media_stream_manager_.reset(new MediaStreamManager(audio_manager_.get())); 189 media_stream_manager_.reset(new MediaStreamManager(audio_manager_.get()));
186 host_ = new MockAudioRendererHost( 190 host_ = new MockAudioRendererHost(
187 &auth_run_loop_, audio_manager_.get(), &mirroring_manager_, 191 &auth_run_loop_, render_process_host_.GetID(), audio_manager_.get(),
188 MediaInternals::GetInstance(), media_stream_manager_.get(), 192 &mirroring_manager_, MediaInternals::GetInstance(),
189 std::string()); 193 media_stream_manager_.get(), std::string());
190
191 EXPECT_CALL(*host_, ShutdownForBadMessage()).Times(0);
192 194
193 // Simulate IPC channel connected. 195 // Simulate IPC channel connected.
194 host_->set_peer_process_for_testing(base::Process::Current()); 196 host_->set_peer_process_for_testing(base::Process::Current());
195 } 197 }
196 198
197 ~AudioRendererHostTest() override { 199 ~AudioRendererHostTest() override {
198 // 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
199 // the underlying streams. 201 // the underlying streams.
200 host_->OnChannelClosing(); 202 host_->OnChannelClosing();
201 SyncWithAudioThread(); 203 SyncWithAudioThread();
(...skipping 17 matching lines...) Expand all
219 ? media::OUTPUT_DEVICE_STATUS_OK 221 ? media::OUTPUT_DEVICE_STATUS_OK
220 : device_id == kBadDeviceId 222 : device_id == kBadDeviceId
221 ? media::OUTPUT_DEVICE_STATUS_ERROR_NOT_AUTHORIZED 223 ? media::OUTPUT_DEVICE_STATUS_ERROR_NOT_AUTHORIZED
222 : media::OUTPUT_DEVICE_STATUS_ERROR_NOT_FOUND; 224 : media::OUTPUT_DEVICE_STATUS_ERROR_NOT_FOUND;
223 225
224 EXPECT_CALL(*host_.get(), 226 EXPECT_CALL(*host_.get(),
225 OnDeviceAuthorized(kStreamId, expected_device_status, _, _)); 227 OnDeviceAuthorized(kStreamId, expected_device_status, _, _));
226 228
227 if (expected_device_status == media::OUTPUT_DEVICE_STATUS_OK) { 229 if (expected_device_status == media::OUTPUT_DEVICE_STATUS_OK) {
228 EXPECT_CALL(*host_.get(), OnStreamCreated(kStreamId, _)); 230 EXPECT_CALL(*host_.get(), OnStreamCreated(kStreamId, _));
229 EXPECT_CALL(mirroring_manager_, 231 EXPECT_CALL(mirroring_manager_, AddDiverter(render_process_host_.GetID(),
230 AddDiverter(kRenderProcessId, kRenderFrameId, NotNull())) 232 kRenderFrameId, NotNull()))
231 .RetiresOnSaturation(); 233 .RetiresOnSaturation();
232 } 234 }
233 235
234 // Send a create stream message to the audio output stream and wait until 236 // Send a create stream message to the audio output stream and wait until
235 // we receive the created message. 237 // we receive the created message.
236 media::AudioParameters params( 238 media::AudioParameters params(
237 media::AudioParameters::AUDIO_FAKE, media::CHANNEL_LAYOUT_STEREO, 239 media::AudioParameters::AUDIO_FAKE, media::CHANNEL_LAYOUT_STEREO,
238 media::AudioParameters::kAudioCDSampleRate, 16, 240 media::AudioParameters::kAudioCDSampleRate, 16,
239 media::AudioParameters::kAudioCDSampleRate / 10); 241 media::AudioParameters::kAudioCDSampleRate / 10);
240 int session_id = 0; 242 int session_id = 0;
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
337 // closing an audio stream. 339 // closing an audio stream.
338 void SyncWithAudioThread() { 340 void SyncWithAudioThread() {
339 base::RunLoop().RunUntilIdle(); 341 base::RunLoop().RunUntilIdle();
340 342
341 base::RunLoop run_loop; 343 base::RunLoop run_loop;
342 audio_manager_->GetTaskRunner()->PostTask( 344 audio_manager_->GetTaskRunner()->PostTask(
343 FROM_HERE, media::BindToCurrentLoop(run_loop.QuitClosure())); 345 FROM_HERE, media::BindToCurrentLoop(run_loop.QuitClosure()));
344 run_loop.Run(); 346 run_loop.Run();
345 } 347 }
346 348
347 void ExpectShutdown() { 349 void AssertBadMsgReported() {
348 EXPECT_CALL(*host_, ShutdownForBadMessage()).Times(1); 350 // Bad messages can be reported either directly to the RPH or through the
351 // ARH, so we check both of them.
352 EXPECT_EQ(render_process_host_.bad_msg_count() + host_->bad_msg_count, 1);
349 } 353 }
350 354
351 private: 355 private:
352 // MediaStreamManager uses a DestructionObserver, so it must outlive the 356 // MediaStreamManager uses a DestructionObserver, so it must outlive the
353 // TestBrowserThreadBundle. 357 // TestBrowserThreadBundle.
354 std::unique_ptr<MediaStreamManager> media_stream_manager_; 358 std::unique_ptr<MediaStreamManager> media_stream_manager_;
355 TestBrowserThreadBundle thread_bundle_; 359 TestBrowserThreadBundle thread_bundle_;
356 media::ScopedAudioManagerPtr audio_manager_; 360 media::ScopedAudioManagerPtr audio_manager_;
357 MockAudioMirroringManager mirroring_manager_; 361 MockAudioMirroringManager mirroring_manager_;
362 TestBrowserContext browser_context_;
363 MockRenderProcessHost render_process_host_;
358 scoped_refptr<MockAudioRendererHost> host_; 364 scoped_refptr<MockAudioRendererHost> host_;
359 base::RunLoop auth_run_loop_; 365 base::RunLoop auth_run_loop_;
360 366
361 DISALLOW_COPY_AND_ASSIGN(AudioRendererHostTest); 367 DISALLOW_COPY_AND_ASSIGN(AudioRendererHostTest);
362 }; 368 };
363 369
364 TEST_F(AudioRendererHostTest, CreateAndClose) { 370 TEST_F(AudioRendererHostTest, CreateAndClose) {
365 Create(); 371 Create();
366 Close(); 372 Close();
367 } 373 }
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
425 Create(true, kDefaultDeviceId, url::Origin(GURL(kSecurityOrigin)), true); 431 Create(true, kDefaultDeviceId, url::Origin(GURL(kSecurityOrigin)), true);
426 Close(); 432 Close();
427 } 433 }
428 434
429 TEST_F(AudioRendererHostTest, CreateUnauthorizedDevice) { 435 TEST_F(AudioRendererHostTest, CreateUnauthorizedDevice) {
430 Create(false, kBadDeviceId, url::Origin(GURL(kSecurityOrigin)), true); 436 Create(false, kBadDeviceId, url::Origin(GURL(kSecurityOrigin)), true);
431 Close(); 437 Close();
432 } 438 }
433 439
434 TEST_F(AudioRendererHostTest, CreateDeviceWithAuthorizationPendingIsError) { 440 TEST_F(AudioRendererHostTest, CreateDeviceWithAuthorizationPendingIsError) {
435 ExpectShutdown();
436 CreateWithoutWaitingForAuth(kBadDeviceId); 441 CreateWithoutWaitingForAuth(kBadDeviceId);
437 Close(); 442 Close();
443 AssertBadMsgReported();
438 } 444 }
439 445
440 TEST_F(AudioRendererHostTest, CreateDeviceWithBadSecurityOrigin) { 446 TEST_F(AudioRendererHostTest, CreateDeviceWithBadSecurityOrigin) {
441 ExpectShutdown();
442 RequestDeviceAuthorizationWithBadOrigin(kNondefaultDeviceId); 447 RequestDeviceAuthorizationWithBadOrigin(kNondefaultDeviceId);
443 Close(); 448 Close();
449 AssertBadMsgReported();
444 } 450 }
445 451
446 TEST_F(AudioRendererHostTest, CreateInvalidDevice) { 452 TEST_F(AudioRendererHostTest, CreateInvalidDevice) {
447 Create(false, kInvalidDeviceId, url::Origin(GURL(kSecurityOrigin)), true); 453 Create(false, kInvalidDeviceId, url::Origin(GURL(kSecurityOrigin)), true);
448 Close(); 454 Close();
449 } 455 }
450 456
451 TEST_F(AudioRendererHostTest, CreateFailsForInvalidRenderFrame) { 457 TEST_F(AudioRendererHostTest, CreateFailsForInvalidRenderFrame) {
452 CreateWithInvalidRenderFrameId(); 458 CreateWithInvalidRenderFrameId();
453 Close(); 459 Close();
454 } 460 }
455 461
456 // TODO(hclam): Add tests for data conversation in low latency mode. 462 // TODO(hclam): Add tests for data conversation in low latency mode.
457 463
458 } // namespace content 464 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698