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

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

Issue 2424163004: Factor out authorization from AudioRendererHost. (Closed)
Patch Set: Minor fixes. 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/browser/media_device_id.h"
21 #include "content/public/common/content_switches.h" 22 #include "content/public/common/content_switches.h"
23 #include "content/public/test/mock_render_process_host.h"
24 #include "content/public/test/test_browser_context.h"
22 #include "content/public/test/test_browser_thread_bundle.h" 25 #include "content/public/test/test_browser_thread_bundle.h"
23 #include "ipc/ipc_message_utils.h" 26 #include "ipc/ipc_message_utils.h"
24 #include "media/audio/audio_manager.h" 27 #include "media/audio/fake_audio_log_factory.h"
28 #include "media/audio/fake_audio_manager.h"
25 #include "media/base/bind_to_current_loop.h" 29 #include "media/base/bind_to_current_loop.h"
26 #include "media/base/media_switches.h" 30 #include "media/base/media_switches.h"
27 #include "testing/gmock/include/gmock/gmock.h" 31 #include "testing/gmock/include/gmock/gmock.h"
28 #include "testing/gtest/include/gtest/gtest.h" 32 #include "testing/gtest/include/gtest/gtest.h"
29 33
30 using ::testing::_; 34 using ::testing::_;
31 using ::testing::Assign; 35 using ::testing::Assign;
32 using ::testing::AtLeast; 36 using ::testing::AtLeast;
33 using ::testing::DoAll; 37 using ::testing::DoAll;
34 using ::testing::NotNull; 38 using ::testing::NotNull;
35 39
36 namespace content { 40 namespace content {
37 41
38 namespace { 42 namespace {
39 const int kRenderProcessId = 1;
40 const int kRenderFrameId = 5; 43 const int kRenderFrameId = 5;
41 const int kStreamId = 50; 44 const int kStreamId = 50;
42 const char kSecurityOrigin[] = "http://localhost"; 45 const char kSecurityOrigin[] = "http://localhost";
43 const char kBadSecurityOrigin[] = "about:about"; 46 const char kBadSecurityOrigin[] = "about:about";
44 const char kDefaultDeviceId[] = ""; 47 const char kDefaultDeviceId[] = "";
48 const char kSalt[] = "salt";
45 const char kNondefaultDeviceId[] = 49 const char kNondefaultDeviceId[] =
46 "deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef"; 50 "deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef";
47 const char kBadDeviceId[] = 51 const char kBadDeviceId[] =
48 "badbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbad1"; 52 "badbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbad1";
49 const char kInvalidDeviceId[] = "invalid-device-id"; 53 const char kInvalidDeviceId[] = "invalid-device-id";
50 54
51 void ValidateRenderFrameId(int render_process_id, 55 void ValidateRenderFrameId(int render_process_id,
52 int render_frame_id, 56 int render_frame_id,
53 const base::Callback<void(bool)>& callback) { 57 const base::Callback<void(bool)>& callback) {
54 DCHECK_CURRENTLY_ON(BrowserThread::UI); 58 DCHECK_CURRENTLY_ON(BrowserThread::UI);
55 const bool frame_exists = (render_process_id == kRenderProcessId && 59 const bool frame_exists = (render_frame_id == kRenderFrameId);
56 render_frame_id == kRenderFrameId);
57 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, 60 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
58 base::Bind(callback, frame_exists)); 61 base::Bind(callback, frame_exists));
59 } 62 }
60 63
61 } // namespace
62 64
63 class MockAudioMirroringManager : public AudioMirroringManager { 65 class MockAudioMirroringManager : public AudioMirroringManager {
64 public: 66 public:
65 MockAudioMirroringManager() {} 67 MockAudioMirroringManager() {}
66 virtual ~MockAudioMirroringManager() {} 68 virtual ~MockAudioMirroringManager() {}
67 69
68 MOCK_METHOD3(AddDiverter, 70 MOCK_METHOD3(AddDiverter,
69 void(int render_process_id, 71 void(int render_process_id,
70 int render_frame_id, 72 int render_frame_id,
71 Diverter* diverter)); 73 Diverter* diverter));
72 MOCK_METHOD1(RemoveDiverter, void(Diverter* diverter)); 74 MOCK_METHOD1(RemoveDiverter, void(Diverter* diverter));
73 75
74 private: 76 private:
75 DISALLOW_COPY_AND_ASSIGN(MockAudioMirroringManager); 77 DISALLOW_COPY_AND_ASSIGN(MockAudioMirroringManager);
76 }; 78 };
77 79
80 class MockRenderProcessHostWithSignaling : public MockRenderProcessHost {
81 public:
82 MockRenderProcessHostWithSignaling(BrowserContext* context,
83 base::RunLoop* auth_run_loop)
84 : MockRenderProcessHost(context), auth_run_loop_(auth_run_loop) {}
85
86 void ShutdownForBadMessage(CrashReportMode crash_report_mode) override {
87 MockRenderProcessHost::ShutdownForBadMessage(crash_report_mode);
88 auth_run_loop_->Quit();
89 }
90
91 private:
92 base::RunLoop* auth_run_loop_;
93 };
94
95 class FakeAudioManagerWithAssociations : public media::FakeAudioManager {
96 public:
97 FakeAudioManagerWithAssociations(
98 scoped_refptr<base::SingleThreadTaskRunner> task_runner,
99 media::AudioLogFactory* factory)
100 : FakeAudioManager(task_runner, task_runner, factory) {}
101
102 void CreateDeviceAssociation(const std::string& input_device_id,
103 const std::string& output_device_id) {
104 // We shouldn't accidentally add hashed ids, since the audio manager
105 // works with raw ids.
Guido Urdaneta 2016/11/10 15:26:05 Does the audio manager not work with default and c
106 EXPECT_FALSE(IsValidDeviceId(input_device_id));
107 EXPECT_FALSE(IsValidDeviceId(output_device_id));
108
109 associations_[input_device_id] = output_device_id;
110 }
111
112 std::string GetAssociatedOutputDeviceID(
113 const std::string& input_id) override {
114 auto it = associations_.find(input_id);
115 return it == associations_.end() ? "" : it->second;
116 }
117
118 private:
119 std::map<std::string, std::string> associations_;
120 };
121
122 } // namespace
123
78 class MockAudioRendererHost : public AudioRendererHost { 124 class MockAudioRendererHost : public AudioRendererHost {
79 public: 125 public:
80 MockAudioRendererHost(base::RunLoop* auth_run_loop, 126 MockAudioRendererHost(base::RunLoop* auth_run_loop,
127 int render_process_id,
81 media::AudioManager* audio_manager, 128 media::AudioManager* audio_manager,
82 AudioMirroringManager* mirroring_manager, 129 AudioMirroringManager* mirroring_manager,
83 MediaInternals* media_internals, 130 MediaInternals* media_internals,
84 MediaStreamManager* media_stream_manager, 131 MediaStreamManager* media_stream_manager,
85 const std::string& salt) 132 const std::string& salt)
86 : AudioRendererHost(kRenderProcessId, 133 : AudioRendererHost(render_process_id,
87 audio_manager, 134 audio_manager,
88 mirroring_manager, 135 mirroring_manager,
89 media_internals, 136 media_internals,
90 media_stream_manager, 137 media_stream_manager,
91 salt), 138 salt),
92 shared_memory_length_(0), 139 shared_memory_length_(0),
93 auth_run_loop_(auth_run_loop) { 140 auth_run_loop_(auth_run_loop) {
94 set_render_frame_id_validate_function_for_testing(&ValidateRenderFrameId); 141 set_render_frame_id_validate_function_for_testing(&ValidateRenderFrameId);
95 } 142 }
96 143
97 // A list of mock methods. 144 // A list of mock methods.
98 MOCK_METHOD0(ShutdownForBadMessage, void());
99 MOCK_METHOD4(OnDeviceAuthorized, 145 MOCK_METHOD4(OnDeviceAuthorized,
100 void(int stream_id, 146 void(int stream_id,
101 media::OutputDeviceStatus device_status, 147 media::OutputDeviceStatus device_status,
102 const media::AudioParameters& output_params, 148 const media::AudioParameters& output_params,
103 const std::string& matched_device_id)); 149 const std::string& matched_device_id));
104 MOCK_METHOD2(OnStreamCreated, void(int stream_id, int length)); 150 MOCK_METHOD2(OnStreamCreated, void(int stream_id, int length));
105 MOCK_METHOD1(OnStreamError, void(int stream_id)); 151 MOCK_METHOD1(OnStreamError, void(int stream_id));
106 152
153 void ShutdownForBadMessage() override { bad_msg_count++; }
154
155 int bad_msg_count = 0;
156
107 private: 157 private:
108 virtual ~MockAudioRendererHost() { 158 virtual ~MockAudioRendererHost() {
109 // Make sure all audio streams have been deleted. 159 // Make sure all audio streams have been deleted.
110 EXPECT_TRUE(audio_entries_.empty()); 160 EXPECT_TRUE(audio_entries_.empty());
111 } 161 }
112 162
113 // This method is used to dispatch IPC messages to the renderer. We intercept 163 // 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 164 // these messages here and dispatch to our mock methods to verify the
115 // conversation between this object and the renderer. 165 // conversation between this object and the renderer.
116 // Note: this means that file descriptors won't be duplicated, 166 // Note: this means that file descriptors won't be duplicated,
117 // leading to double-close errors from SyncSocket. 167 // leading to double-close errors from SyncSocket.
118 // See crbug.com/647659. 168 // See crbug.com/647659.
119 virtual bool Send(IPC::Message* message) { 169 bool Send(IPC::Message* message) override {
120 CHECK(message); 170 CHECK(message);
121 171
122 // In this method we dispatch the messages to the according handlers as if 172 // In this method we dispatch the messages to the according handlers as if
123 // we are the renderer. 173 // we are the renderer.
124 bool handled = true; 174 bool handled = true;
125 IPC_BEGIN_MESSAGE_MAP(MockAudioRendererHost, *message) 175 IPC_BEGIN_MESSAGE_MAP(MockAudioRendererHost, *message)
126 IPC_MESSAGE_HANDLER(AudioMsg_NotifyDeviceAuthorized, 176 IPC_MESSAGE_HANDLER(AudioMsg_NotifyDeviceAuthorized,
127 OnNotifyDeviceAuthorized) 177 OnNotifyDeviceAuthorized)
128 IPC_MESSAGE_HANDLER(AudioMsg_NotifyStreamCreated, 178 IPC_MESSAGE_HANDLER(AudioMsg_NotifyStreamCreated,
129 OnNotifyStreamCreated) 179 OnNotifyStreamCreated)
130 IPC_MESSAGE_HANDLER(AudioMsg_NotifyStreamError, OnNotifyStreamError) 180 IPC_MESSAGE_HANDLER(AudioMsg_NotifyStreamError, OnNotifyStreamError)
131 IPC_MESSAGE_UNHANDLED(handled = false) 181 IPC_MESSAGE_UNHANDLED(handled = false)
132 IPC_END_MESSAGE_MAP() 182 IPC_END_MESSAGE_MAP()
133 EXPECT_TRUE(handled); 183 EXPECT_TRUE(handled);
134 184
135 delete message; 185 delete message;
136 return true; 186 return true;
137 } 187 }
138 188
139 void OnNotifyDeviceAuthorized(int stream_id, 189 void OnNotifyDeviceAuthorized(int stream_id,
140 media::OutputDeviceStatus device_status, 190 media::OutputDeviceStatus device_status,
141 const media::AudioParameters& output_params, 191 const media::AudioParameters& output_params,
142 const std::string& matched_device_id) { 192 const std::string& matched_device_id) {
193 // Make sure we didn't leak a raw device id.
194 EXPECT_TRUE(IsValidDeviceId(matched_device_id));
195
143 OnDeviceAuthorized(stream_id, device_status, output_params, 196 OnDeviceAuthorized(stream_id, device_status, output_params,
144 matched_device_id); 197 matched_device_id);
145 auth_run_loop_->Quit(); 198 auth_run_loop_->Quit();
146 } 199 }
147 200
148 void OnNotifyStreamCreated( 201 void OnNotifyStreamCreated(
149 int stream_id, 202 int stream_id,
150 base::SharedMemoryHandle handle, 203 base::SharedMemoryHandle handle,
151 base::SyncSocket::TransitDescriptor socket_descriptor, 204 base::SyncSocket::TransitDescriptor socket_descriptor,
152 uint32_t length) { 205 uint32_t length) {
(...skipping 17 matching lines...) Expand all
170 std::unique_ptr<base::SharedMemory> shared_memory_; 223 std::unique_ptr<base::SharedMemory> shared_memory_;
171 std::unique_ptr<base::SyncSocket> sync_socket_; 224 std::unique_ptr<base::SyncSocket> sync_socket_;
172 uint32_t shared_memory_length_; 225 uint32_t shared_memory_length_;
173 base::RunLoop* auth_run_loop_; // Used to wait for authorization. 226 base::RunLoop* auth_run_loop_; // Used to wait for authorization.
174 227
175 DISALLOW_COPY_AND_ASSIGN(MockAudioRendererHost); 228 DISALLOW_COPY_AND_ASSIGN(MockAudioRendererHost);
176 }; 229 };
177 230
178 class AudioRendererHostTest : public testing::Test { 231 class AudioRendererHostTest : public testing::Test {
179 public: 232 public:
180 AudioRendererHostTest() { 233 AudioRendererHostTest()
181 audio_manager_ = media::AudioManager::CreateForTesting( 234 : render_process_host_(&browser_context_, &auth_run_loop_),
182 base::ThreadTaskRunnerHandle::Get()); 235 log_factory(base::MakeUnique<media::FakeAudioLogFactory>()),
236 audio_manager_(base::MakeUnique<FakeAudioManagerWithAssociations>(
237 base::ThreadTaskRunnerHandle::Get(),
238 log_factory.get())) {
183 base::CommandLine::ForCurrentProcess()->AppendSwitch( 239 base::CommandLine::ForCurrentProcess()->AppendSwitch(
184 switches::kUseFakeDeviceForMediaStream); 240 switches::kUseFakeDeviceForMediaStream);
185 media_stream_manager_.reset(new MediaStreamManager(audio_manager_.get())); 241 media_stream_manager_.reset(new MediaStreamManager(audio_manager_.get()));
186 host_ = new MockAudioRendererHost( 242 host_ = new MockAudioRendererHost(
187 &auth_run_loop_, audio_manager_.get(), &mirroring_manager_, 243 &auth_run_loop_, render_process_host_.GetID(), audio_manager_.get(),
188 MediaInternals::GetInstance(), media_stream_manager_.get(), 244 &mirroring_manager_, MediaInternals::GetInstance(),
189 std::string()); 245 media_stream_manager_.get(), kSalt);
190
191 EXPECT_CALL(*host_, ShutdownForBadMessage()).Times(0);
192 246
193 // Simulate IPC channel connected. 247 // Simulate IPC channel connected.
194 host_->set_peer_process_for_testing(base::Process::Current()); 248 host_->set_peer_process_for_testing(base::Process::Current());
195 } 249 }
196 250
197 ~AudioRendererHostTest() override { 251 ~AudioRendererHostTest() override {
198 // Simulate closing the IPC channel and give the audio thread time to close 252 // Simulate closing the IPC channel and give the audio thread time to close
199 // the underlying streams. 253 // the underlying streams.
200 host_->OnChannelClosing(); 254 host_->OnChannelClosing();
201 SyncWithAudioThread(); 255 SyncWithAudioThread();
202 256
203 // Release the reference to the mock object. The object will be destructed 257 // Release the reference to the mock object. The object will be destructed
204 // on message_loop_. 258 // on message_loop_.
205 host_ = NULL; 259 host_ = NULL;
206 } 260 }
207 261
208 protected: 262 protected:
209 void Create() { 263 void OverrideDevicePermissions(bool has_permissions) {
210 Create(false, kDefaultDeviceId, url::Origin(GURL(kSecurityOrigin)), true); 264 host_->OverrideDevicePermissionsForTesting(has_permissions);
211 } 265 }
212 266
213 void Create(bool unified_stream, 267 std::string GetNondefaultIdExpectedToPassPermissionsCheck() {
214 const std::string& device_id, 268 std::string nondefault_id;
269
270 MediaDevicesManager::BoolDeviceTypes devices_to_enumerate;
271 devices_to_enumerate[MEDIA_DEVICE_TYPE_AUDIO_OUTPUT] = true;
272 media_stream_manager_->media_devices_manager()->EnumerateDevices(
273 devices_to_enumerate,
274 base::Bind(
275 [](std::string* out, const MediaDeviceEnumeration& result) {
276 // Index 0 is default, so use 1.
Guido Urdaneta 2016/11/10 15:26:05 Shouldn't you have a check or expectation that the
Max Morin 2016/11/11 09:26:55 Done (size > 1).
277 *out = result[MediaDeviceType::MEDIA_DEVICE_TYPE_AUDIO_OUTPUT][1]
278 .device_id;
279 },
280 base::Unretained(&nondefault_id)));
281
282 // Make sure nondefault_id is set before returning.
283 base::RunLoop().RunUntilIdle();
284
285 return nondefault_id;
286 }
287
288 std::string GetNondefaultInputId() {
289 std::string nondefault_id;
290
291 MediaDevicesManager::BoolDeviceTypes devices_to_enumerate;
292 devices_to_enumerate[MEDIA_DEVICE_TYPE_AUDIO_INPUT] = true;
293 media_stream_manager_->media_devices_manager()->EnumerateDevices(
294 devices_to_enumerate,
295 base::Bind(
296 [](std::string* out, const MediaDeviceEnumeration& result) {
297 *out = result[MediaDeviceType::MEDIA_DEVICE_TYPE_AUDIO_INPUT][1]
298 .device_id;
299 },
300 base::Unretained(&nondefault_id)));
301
302 base::RunLoop().RunUntilIdle();
303
304 return nondefault_id;
305 }
306
307 void Create() {
308 Create(kDefaultDeviceId, url::Origin(GURL(kSecurityOrigin)), true, true);
309 }
310
311 void Create(const std::string& device_id,
215 const url::Origin& security_origin, 312 const url::Origin& security_origin,
216 bool wait_for_auth) { 313 bool wait_for_auth,
314 bool expect_onauthorized) {
217 media::OutputDeviceStatus expected_device_status = 315 media::OutputDeviceStatus expected_device_status =
218 device_id == kDefaultDeviceId 316 device_id == kDefaultDeviceId ||
317 device_id ==
318 MediaStreamManager::GetHMACForMediaDeviceID(
319 kSalt, url::Origin(GURL(kSecurityOrigin)),
320 GetNondefaultIdExpectedToPassPermissionsCheck())
219 ? media::OUTPUT_DEVICE_STATUS_OK 321 ? media::OUTPUT_DEVICE_STATUS_OK
220 : device_id == kBadDeviceId 322 : device_id == kBadDeviceId
221 ? media::OUTPUT_DEVICE_STATUS_ERROR_NOT_AUTHORIZED 323 ? media::OUTPUT_DEVICE_STATUS_ERROR_NOT_AUTHORIZED
222 : media::OUTPUT_DEVICE_STATUS_ERROR_NOT_FOUND; 324 : media::OUTPUT_DEVICE_STATUS_ERROR_NOT_FOUND;
223 325
224 EXPECT_CALL(*host_.get(), 326 if (expect_onauthorized)
225 OnDeviceAuthorized(kStreamId, expected_device_status, _, _)); 327 EXPECT_CALL(*host_.get(),
328 OnDeviceAuthorized(kStreamId, expected_device_status, _, _));
226 329
227 if (expected_device_status == media::OUTPUT_DEVICE_STATUS_OK) { 330 if (expected_device_status == media::OUTPUT_DEVICE_STATUS_OK) {
228 EXPECT_CALL(*host_.get(), OnStreamCreated(kStreamId, _)); 331 EXPECT_CALL(*host_.get(), OnStreamCreated(kStreamId, _));
229 EXPECT_CALL(mirroring_manager_, 332 EXPECT_CALL(mirroring_manager_, AddDiverter(render_process_host_.GetID(),
230 AddDiverter(kRenderProcessId, kRenderFrameId, NotNull())) 333 kRenderFrameId, NotNull()))
231 .RetiresOnSaturation(); 334 .RetiresOnSaturation();
232 } 335 }
233 336
234 // Send a create stream message to the audio output stream and wait until 337 // Send a create stream message to the audio output stream and wait until
235 // we receive the created message. 338 // we receive the created message.
236 media::AudioParameters params( 339 media::AudioParameters params(
237 media::AudioParameters::AUDIO_FAKE, media::CHANNEL_LAYOUT_STEREO, 340 media::AudioParameters::AUDIO_FAKE, media::CHANNEL_LAYOUT_STEREO,
238 media::AudioParameters::kAudioCDSampleRate, 16, 341 media::AudioParameters::kAudioCDSampleRate, 16,
239 media::AudioParameters::kAudioCDSampleRate / 10); 342 media::AudioParameters::kAudioCDSampleRate / 10);
240 int session_id = 0; 343 int session_id = 0;
241 if (unified_stream) { 344
242 // Use AudioInputDeviceManager::kFakeOpenSessionId as the session id to
243 // pass the permission check.
244 session_id = AudioInputDeviceManager::kFakeOpenSessionId;
245 }
246 host_->OnRequestDeviceAuthorization(kStreamId, kRenderFrameId, session_id, 345 host_->OnRequestDeviceAuthorization(kStreamId, kRenderFrameId, session_id,
247 device_id, security_origin); 346 device_id, security_origin);
248 if (wait_for_auth) 347 if (wait_for_auth)
249 auth_run_loop_.Run(); 348 auth_run_loop_.Run();
250 349
251 if (!wait_for_auth || 350 if (!wait_for_auth ||
252 expected_device_status == media::OUTPUT_DEVICE_STATUS_OK) 351 expected_device_status == media::OUTPUT_DEVICE_STATUS_OK)
253 host_->OnCreateStream(kStreamId, kRenderFrameId, params); 352 host_->OnCreateStream(kStreamId, kRenderFrameId, params);
254 353
255 if (expected_device_status == media::OUTPUT_DEVICE_STATUS_OK) 354 if (expected_device_status == media::OUTPUT_DEVICE_STATUS_OK)
256 // At some point in the future, a corresponding RemoveDiverter() call must 355 // At some point in the future, a corresponding RemoveDiverter() call must
257 // be made. 356 // be made.
258 EXPECT_CALL(mirroring_manager_, RemoveDiverter(NotNull())) 357 EXPECT_CALL(mirroring_manager_, RemoveDiverter(NotNull()))
259 .RetiresOnSaturation(); 358 .RetiresOnSaturation();
260 SyncWithAudioThread(); 359 SyncWithAudioThread();
261 } 360 }
262 361
263 void RequestDeviceAuthorizationWithBadOrigin(const std::string& device_id) { 362 void RequestDeviceAuthorizationWithBadOrigin(const std::string& device_id) {
264 int session_id = 0; 363 int session_id = 0;
265 host_->OnRequestDeviceAuthorization(kStreamId, kRenderFrameId, session_id, 364 host_->OnRequestDeviceAuthorization(kStreamId, kRenderFrameId, session_id,
266 device_id, 365 device_id,
267 url::Origin(GURL(kBadSecurityOrigin))); 366 url::Origin(GURL(kBadSecurityOrigin)));
268 SyncWithAudioThread(); 367 SyncWithAudioThread();
269 } 368 }
270 369
271 void CreateWithoutWaitingForAuth(const std::string& device_id) { 370 void CreateWithoutWaitingForAuth(const std::string& device_id) {
272 Create(false, device_id, url::Origin(GURL(kSecurityOrigin)), false); 371 Create(device_id, url::Origin(GURL(kSecurityOrigin)), false, false);
273 } 372 }
274 373
275 void CreateWithInvalidRenderFrameId() { 374 void CreateWithInvalidRenderFrameId() {
276 // When creating a stream with an invalid render frame ID, the host will 375 // When creating a stream with an invalid render frame ID, the host will
277 // reply with a stream error message. 376 // reply with a stream error message.
278 EXPECT_CALL(*host_, OnStreamError(kStreamId)); 377 EXPECT_CALL(*host_, OnStreamError(kStreamId));
279 378
280 // However, validation does not block stream creation, so these method calls 379 // However, validation does not block stream creation, so these method calls
281 // might be made: 380 // might be made:
282 EXPECT_CALL(*host_, OnStreamCreated(kStreamId, _)).Times(AtLeast(0)); 381 EXPECT_CALL(*host_, OnStreamCreated(kStreamId, _)).Times(AtLeast(0));
283 EXPECT_CALL(mirroring_manager_, AddDiverter(_, _, _)).Times(AtLeast(0)); 382 EXPECT_CALL(mirroring_manager_, AddDiverter(_, _, _)).Times(AtLeast(0));
284 EXPECT_CALL(mirroring_manager_, RemoveDiverter(_)).Times(AtLeast(0)); 383 EXPECT_CALL(mirroring_manager_, RemoveDiverter(_)).Times(AtLeast(0));
285 384
286 // Provide a seemingly-valid render frame ID; and it should be rejected when 385 // Provide a seemingly-valid render frame ID; and it should be rejected when
287 // AudioRendererHost calls ValidateRenderFrameId(). 386 // AudioRendererHost calls ValidateRenderFrameId().
288 const int kInvalidRenderFrameId = kRenderFrameId + 1; 387 const int kInvalidRenderFrameId = kRenderFrameId + 1;
289 const media::AudioParameters params( 388 const media::AudioParameters params(
290 media::AudioParameters::AUDIO_FAKE, media::CHANNEL_LAYOUT_STEREO, 389 media::AudioParameters::AUDIO_FAKE, media::CHANNEL_LAYOUT_STEREO,
291 media::AudioParameters::kAudioCDSampleRate, 16, 390 media::AudioParameters::kAudioCDSampleRate, 16,
292 media::AudioParameters::kAudioCDSampleRate / 10); 391 media::AudioParameters::kAudioCDSampleRate / 10);
293 host_->OnCreateStream(kStreamId, kInvalidRenderFrameId, params); 392 host_->OnCreateStream(kStreamId, kInvalidRenderFrameId, params);
294 base::RunLoop().RunUntilIdle(); 393 base::RunLoop().RunUntilIdle();
295 } 394 }
296 395
396 void CreateUnifiedStream(const url::Origin& security_origin) {
397 std::string output_id = GetNondefaultIdExpectedToPassPermissionsCheck();
398 std::string input_id = GetNondefaultInputId();
399 std::string hashed_output_id = MediaStreamManager::GetHMACForMediaDeviceID(
400 kSalt, url::Origin(GURL(kSecurityOrigin)), output_id);
401 // Set up association between input and output so that the output
402 // device gets selected when using session id:
403 audio_manager_->CreateDeviceAssociation(input_id, output_id);
404 int session_id = media_stream_manager_->audio_input_device_manager()->Open(
405 StreamDeviceInfo(MEDIA_DEVICE_AUDIO_CAPTURE, "Fake input device",
406 input_id));
407 base::RunLoop().RunUntilIdle();
408
409 // Send a create stream message to the audio output stream and wait until
410 // we receive the created message.
411 media::AudioParameters params(
412 media::AudioParameters::AUDIO_FAKE, media::CHANNEL_LAYOUT_STEREO,
413 media::AudioParameters::kAudioCDSampleRate, 16,
414 media::AudioParameters::kAudioCDSampleRate / 10);
415
416 EXPECT_CALL(*host_.get(),
417 OnDeviceAuthorized(kStreamId, media::OUTPUT_DEVICE_STATUS_OK, _,
418 hashed_output_id))
419 .Times(1);
420 EXPECT_CALL(*host_.get(), OnStreamCreated(kStreamId, _));
421 EXPECT_CALL(mirroring_manager_, AddDiverter(render_process_host_.GetID(),
422 kRenderFrameId, NotNull()))
423 .RetiresOnSaturation();
424 EXPECT_CALL(mirroring_manager_, RemoveDiverter(NotNull()))
425 .RetiresOnSaturation();
426
427 host_->OnRequestDeviceAuthorization(kStreamId, kRenderFrameId, session_id,
428 /*device id*/ std::string(),
429 security_origin);
430
431 auth_run_loop_.Run();
432
433 host_->OnCreateStream(kStreamId, kRenderFrameId, params);
434
435 SyncWithAudioThread();
436 }
437
297 void Close() { 438 void Close() {
298 // Send a message to AudioRendererHost to tell it we want to close the 439 // Send a message to AudioRendererHost to tell it we want to close the
299 // stream. 440 // stream.
300 host_->OnCloseStream(kStreamId); 441 host_->OnCloseStream(kStreamId);
301 SyncWithAudioThread(); 442 SyncWithAudioThread();
302 } 443 }
303 444
304 void Play() { 445 void Play() {
305 host_->OnPlayStream(kStreamId); 446 host_->OnPlayStream(kStreamId);
306 SyncWithAudioThread(); 447 SyncWithAudioThread();
(...skipping 30 matching lines...) Expand all
337 // closing an audio stream. 478 // closing an audio stream.
338 void SyncWithAudioThread() { 479 void SyncWithAudioThread() {
339 base::RunLoop().RunUntilIdle(); 480 base::RunLoop().RunUntilIdle();
340 481
341 base::RunLoop run_loop; 482 base::RunLoop run_loop;
342 audio_manager_->GetTaskRunner()->PostTask( 483 audio_manager_->GetTaskRunner()->PostTask(
343 FROM_HERE, media::BindToCurrentLoop(run_loop.QuitClosure())); 484 FROM_HERE, media::BindToCurrentLoop(run_loop.QuitClosure()));
344 run_loop.Run(); 485 run_loop.Run();
345 } 486 }
346 487
347 void ExpectShutdown() { 488 void AssertBadMsgReported() {
348 EXPECT_CALL(*host_, ShutdownForBadMessage()).Times(1); 489 // Bad messages can be reported either directly to the RPH or through the
490 // ARH, so we check both of them.
491 EXPECT_EQ(render_process_host_.bad_msg_count() + host_->bad_msg_count, 1);
349 } 492 }
350 493
351 private: 494 private:
352 // MediaStreamManager uses a DestructionObserver, so it must outlive the 495 // MediaStreamManager uses a DestructionObserver, so it must outlive the
353 // TestBrowserThreadBundle. 496 // TestBrowserThreadBundle.
354 std::unique_ptr<MediaStreamManager> media_stream_manager_; 497 std::unique_ptr<MediaStreamManager> media_stream_manager_;
355 TestBrowserThreadBundle thread_bundle_; 498 TestBrowserThreadBundle thread_bundle_;
356 media::ScopedAudioManagerPtr audio_manager_; 499 TestBrowserContext browser_context_;
500 MockRenderProcessHostWithSignaling render_process_host_;
501 std::unique_ptr<media::FakeAudioLogFactory> log_factory;
502 std::unique_ptr<FakeAudioManagerWithAssociations> audio_manager_;
357 MockAudioMirroringManager mirroring_manager_; 503 MockAudioMirroringManager mirroring_manager_;
504 base::RunLoop auth_run_loop_;
358 scoped_refptr<MockAudioRendererHost> host_; 505 scoped_refptr<MockAudioRendererHost> host_;
359 base::RunLoop auth_run_loop_;
360 506
361 DISALLOW_COPY_AND_ASSIGN(AudioRendererHostTest); 507 DISALLOW_COPY_AND_ASSIGN(AudioRendererHostTest);
362 }; 508 };
363 509
364 TEST_F(AudioRendererHostTest, CreateAndClose) { 510 TEST_F(AudioRendererHostTest, CreateAndClose) {
365 Create(); 511 Create();
366 Close(); 512 Close();
367 } 513 }
368 514
369 // Simulate the case where a stream is not properly closed. 515 // Simulate the case where a stream is not properly closed.
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
415 // the audio device is closed but the render process try to close the 561 // the audio device is closed but the render process try to close the
416 // audio stream again. 562 // audio stream again.
417 TEST_F(AudioRendererHostTest, SimulateErrorAndClose) { 563 TEST_F(AudioRendererHostTest, SimulateErrorAndClose) {
418 Create(); 564 Create();
419 Play(); 565 Play();
420 SimulateError(); 566 SimulateError();
421 Close(); 567 Close();
422 } 568 }
423 569
424 TEST_F(AudioRendererHostTest, CreateUnifiedStreamAndClose) { 570 TEST_F(AudioRendererHostTest, CreateUnifiedStreamAndClose) {
425 Create(true, kDefaultDeviceId, url::Origin(GURL(kSecurityOrigin)), true); 571 CreateUnifiedStream(url::Origin(GURL(kSecurityOrigin)));
426 Close(); 572 Close();
427 } 573 }
428 574
429 TEST_F(AudioRendererHostTest, CreateUnauthorizedDevice) { 575 TEST_F(AudioRendererHostTest, CreateUnauthorizedDevice) {
430 Create(false, kBadDeviceId, url::Origin(GURL(kSecurityOrigin)), true); 576 Create(kBadDeviceId, url::Origin(GURL(kSecurityOrigin)), true, true);
577 // Close();
578 }
579
580 TEST_F(AudioRendererHostTest, CreateAuthorizedDevice) {
581 OverrideDevicePermissions(true);
582 std::string id = GetNondefaultIdExpectedToPassPermissionsCheck();
583 std::string hashed_id = MediaStreamManager::GetHMACForMediaDeviceID(
584 kSalt, url::Origin(GURL(kSecurityOrigin)), id);
585 Create(hashed_id, url::Origin(GURL(kSecurityOrigin)), true, true);
431 Close(); 586 Close();
432 } 587 }
433 588
434 TEST_F(AudioRendererHostTest, CreateDeviceWithAuthorizationPendingIsError) { 589 TEST_F(AudioRendererHostTest, CreateDeviceWithAuthorizationPendingIsError) {
435 ExpectShutdown();
436 CreateWithoutWaitingForAuth(kBadDeviceId); 590 CreateWithoutWaitingForAuth(kBadDeviceId);
437 Close(); 591 Close();
592 AssertBadMsgReported();
438 } 593 }
439 594
440 TEST_F(AudioRendererHostTest, CreateDeviceWithBadSecurityOrigin) { 595 TEST_F(AudioRendererHostTest, CreateDeviceWithBadSecurityOrigin) {
441 ExpectShutdown();
442 RequestDeviceAuthorizationWithBadOrigin(kNondefaultDeviceId); 596 RequestDeviceAuthorizationWithBadOrigin(kNondefaultDeviceId);
443 Close(); 597 Close();
598 AssertBadMsgReported();
444 } 599 }
445 600
446 TEST_F(AudioRendererHostTest, CreateInvalidDevice) { 601 TEST_F(AudioRendererHostTest, CreateInvalidDevice) {
447 Create(false, kInvalidDeviceId, url::Origin(GURL(kSecurityOrigin)), true); 602 Create(kInvalidDeviceId, url::Origin(GURL(kSecurityOrigin)), true, false);
448 Close(); 603 Close();
604 AssertBadMsgReported();
449 } 605 }
450 606
451 TEST_F(AudioRendererHostTest, CreateFailsForInvalidRenderFrame) { 607 TEST_F(AudioRendererHostTest, CreateFailsForInvalidRenderFrame) {
452 CreateWithInvalidRenderFrameId(); 608 CreateWithInvalidRenderFrameId();
453 Close(); 609 Close();
454 } 610 }
455 611
456 // TODO(hclam): Add tests for data conversation in low latency mode. 612 // TODO(hclam): Add tests for data conversation in low latency mode.
457 613
458 } // namespace content 614 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698