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

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

Issue 2301353007: Fix race in AudioRendererHost around render frame ID validation. (Closed)
Patch Set: Created 4 years, 3 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 "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
(...skipping 11 matching lines...) Expand all
22 #include "content/public/test/test_browser_thread_bundle.h" 22 #include "content/public/test/test_browser_thread_bundle.h"
23 #include "ipc/ipc_message_utils.h" 23 #include "ipc/ipc_message_utils.h"
24 #include "media/audio/audio_manager.h" 24 #include "media/audio/audio_manager.h"
25 #include "media/base/bind_to_current_loop.h" 25 #include "media/base/bind_to_current_loop.h"
26 #include "media/base/media_switches.h" 26 #include "media/base/media_switches.h"
27 #include "testing/gmock/include/gmock/gmock.h" 27 #include "testing/gmock/include/gmock/gmock.h"
28 #include "testing/gtest/include/gtest/gtest.h" 28 #include "testing/gtest/include/gtest/gtest.h"
29 29
30 using ::testing::_; 30 using ::testing::_;
31 using ::testing::Assign; 31 using ::testing::Assign;
32 using ::testing::AtLeast;
32 using ::testing::DoAll; 33 using ::testing::DoAll;
33 using ::testing::NotNull; 34 using ::testing::NotNull;
34 35
35 namespace content { 36 namespace content {
36 37
37 namespace { 38 namespace {
38 const int kRenderProcessId = 1; 39 const int kRenderProcessId = 1;
39 const int kRenderFrameId = 5; 40 const int kRenderFrameId = 5;
40 const int kStreamId = 50; 41 const int kStreamId = 50;
41 const char kSecurityOrigin[] = "http://localhost"; 42 const char kSecurityOrigin[] = "http://localhost";
42 const char kDefaultDeviceId[] = ""; 43 const char kDefaultDeviceId[] = "";
43 const char kBadDeviceId[] = 44 const char kBadDeviceId[] =
44 "badbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbad1"; 45 "badbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbad1";
45 const char kInvalidDeviceId[] = "invalid-device-id"; 46 const char kInvalidDeviceId[] = "invalid-device-id";
46 47
47 #if DCHECK_IS_ON()
48 void ValidateRenderFrameId(int render_process_id, 48 void ValidateRenderFrameId(int render_process_id,
49 int render_frame_id, 49 int render_frame_id,
50 const base::Callback<void(bool)>& callback) { 50 const base::Callback<void(bool)>& callback) {
51 DCHECK_CURRENTLY_ON(BrowserThread::UI); 51 DCHECK_CURRENTLY_ON(BrowserThread::UI);
52 const bool frame_exists = (render_process_id == kRenderProcessId && 52 const bool frame_exists = (render_process_id == kRenderProcessId &&
53 render_frame_id == kRenderFrameId); 53 render_frame_id == kRenderFrameId);
54 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, 54 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
55 base::Bind(callback, frame_exists)); 55 base::Bind(callback, frame_exists));
56 } 56 }
57 #endif // DCHECK_IS_ON()
58 57
59 } // namespace 58 } // namespace
60 59
61 class MockAudioMirroringManager : public AudioMirroringManager { 60 class MockAudioMirroringManager : public AudioMirroringManager {
62 public: 61 public:
63 MockAudioMirroringManager() {} 62 MockAudioMirroringManager() {}
64 virtual ~MockAudioMirroringManager() {} 63 virtual ~MockAudioMirroringManager() {}
65 64
66 MOCK_METHOD3(AddDiverter, 65 MOCK_METHOD3(AddDiverter,
67 void(int render_process_id, 66 void(int render_process_id,
(...skipping 12 matching lines...) Expand all
80 MediaInternals* media_internals, 79 MediaInternals* media_internals,
81 MediaStreamManager* media_stream_manager, 80 MediaStreamManager* media_stream_manager,
82 const std::string& salt) 81 const std::string& salt)
83 : AudioRendererHost(kRenderProcessId, 82 : AudioRendererHost(kRenderProcessId,
84 audio_manager, 83 audio_manager,
85 mirroring_manager, 84 mirroring_manager,
86 media_internals, 85 media_internals,
87 media_stream_manager, 86 media_stream_manager,
88 salt), 87 salt),
89 shared_memory_length_(0) { 88 shared_memory_length_(0) {
90 #if DCHECK_IS_ON()
91 set_render_frame_id_validate_function_for_testing(&ValidateRenderFrameId); 89 set_render_frame_id_validate_function_for_testing(&ValidateRenderFrameId);
92 #endif // DCHECK_IS_ON()
93 } 90 }
94 91
95 // A list of mock methods. 92 // A list of mock methods.
96 MOCK_METHOD4(OnDeviceAuthorized, 93 MOCK_METHOD4(OnDeviceAuthorized,
97 void(int stream_id, 94 void(int stream_id,
98 media::OutputDeviceStatus device_status, 95 media::OutputDeviceStatus device_status,
99 const media::AudioParameters& output_params, 96 const media::AudioParameters& output_params,
100 const std::string& matched_device_id)); 97 const std::string& matched_device_id));
101 MOCK_METHOD2(OnStreamCreated, void(int stream_id, int length)); 98 MOCK_METHOD2(OnStreamCreated, void(int stream_id, int length));
102 MOCK_METHOD1(OnStreamPlaying, void(int stream_id)); 99 MOCK_METHOD1(OnStreamPlaying, void(int stream_id));
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
277 274
278 // At some point in the future, a corresponding RemoveDiverter() call must 275 // At some point in the future, a corresponding RemoveDiverter() call must
279 // be made. 276 // be made.
280 EXPECT_CALL(mirroring_manager_, RemoveDiverter(NotNull())) 277 EXPECT_CALL(mirroring_manager_, RemoveDiverter(NotNull()))
281 .RetiresOnSaturation(); 278 .RetiresOnSaturation();
282 } 279 }
283 SyncWithAudioThread(); 280 SyncWithAudioThread();
284 } 281 }
285 282
286 void CreateWithInvalidRenderFrameId() { 283 void CreateWithInvalidRenderFrameId() {
287 // Because the render frame is invalid, the host should only reply with a 284 // When creating a stream with an invalid render frame ID, the host will
288 // stream error message. 285 // reply with a stream error message.
289 EXPECT_CALL(*host_, OnStreamError(kStreamId)); 286 EXPECT_CALL(*host_, OnStreamError(kStreamId));
290 287
291 // When DCHECKs are on, provide a seemingly-valid render frame ID; and it 288 // However, validation does not block stream creation, so these method calls
292 // should be rejected when AudioRendererHost calls 289 // might be made:
293 // ValidateRenderFrameId(). When DCHECKs are off, AudioRendererHost won't 290 EXPECT_CALL(*host_, OnStreamCreated(kStreamId, _)).Times(AtLeast(0));
294 // call the validation function, but can still reject a render frame ID when 291 EXPECT_CALL(mirroring_manager_, AddDiverter(_, _, _)).Times(AtLeast(0));
295 // it is obviously bogus. 292 EXPECT_CALL(mirroring_manager_, RemoveDiverter(_)).Times(AtLeast(0));
296 #if DCHECK_IS_ON() 293
294 // Provide a seemingly-valid render frame ID; and it should be rejected when
295 // AudioRendererHost calls ValidateRenderFrameId().
297 const int kInvalidRenderFrameId = kRenderFrameId + 1; 296 const int kInvalidRenderFrameId = kRenderFrameId + 1;
298 #else
299 const int kInvalidRenderFrameId = MSG_ROUTING_NONE;
300 #endif // DCHECK_IS_ON()
301
302 const media::AudioParameters params( 297 const media::AudioParameters params(
303 media::AudioParameters::AUDIO_FAKE, media::CHANNEL_LAYOUT_STEREO, 298 media::AudioParameters::AUDIO_FAKE, media::CHANNEL_LAYOUT_STEREO,
304 media::AudioParameters::kAudioCDSampleRate, 16, 299 media::AudioParameters::kAudioCDSampleRate, 16,
305 media::AudioParameters::kAudioCDSampleRate / 10); 300 media::AudioParameters::kAudioCDSampleRate / 10);
306 host_->OnCreateStream(kStreamId, kInvalidRenderFrameId, params); 301 host_->OnCreateStream(kStreamId, kInvalidRenderFrameId, params);
302 base::RunLoop().RunUntilIdle();
307 } 303 }
308 304
309 void Close() { 305 void Close() {
310 // Send a message to AudioRendererHost to tell it we want to close the 306 // Send a message to AudioRendererHost to tell it we want to close the
311 // stream. 307 // stream.
312 host_->OnCloseStream(kStreamId); 308 host_->OnCloseStream(kStreamId);
313 SyncWithAudioThread(); 309 SyncWithAudioThread();
314 } 310 }
315 311
316 void Play() { 312 void Play() {
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
446 } 442 }
447 443
448 TEST_F(AudioRendererHostTest, CreateFailsForInvalidRenderFrame) { 444 TEST_F(AudioRendererHostTest, CreateFailsForInvalidRenderFrame) {
449 CreateWithInvalidRenderFrameId(); 445 CreateWithInvalidRenderFrameId();
450 Close(); 446 Close();
451 } 447 }
452 448
453 // TODO(hclam): Add tests for data conversation in low latency mode. 449 // TODO(hclam): Add tests for data conversation in low latency mode.
454 450
455 } // namespace content 451 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698