OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/json/json_writer.h" | 5 #include "base/json/json_writer.h" |
6 #include "base/message_loop/message_loop.h" | 6 #include "base/message_loop/message_loop.h" |
7 #include "base/strings/string_util.h" | |
7 #include "base/strings/stringprintf.h" | 8 #include "base/strings/stringprintf.h" |
9 #include "base/strings/utf_string_conversions.h" | |
8 #include "base/synchronization/waitable_event.h" | 10 #include "base/synchronization/waitable_event.h" |
9 #include "base/threading/platform_thread.h" | 11 #include "base/threading/platform_thread.h" |
10 #include "base/time/time.h" | 12 #include "base/time/time.h" |
11 #include "chrome/browser/extensions/api/webrtc_audio_private/webrtc_audio_privat e_api.h" | 13 #include "chrome/browser/extensions/api/webrtc_audio_private/webrtc_audio_privat e_api.h" |
14 #include "chrome/browser/extensions/component_loader.h" | |
12 #include "chrome/browser/extensions/extension_apitest.h" | 15 #include "chrome/browser/extensions/extension_apitest.h" |
13 #include "chrome/browser/extensions/extension_function_test_utils.h" | 16 #include "chrome/browser/extensions/extension_function_test_utils.h" |
14 #include "chrome/browser/extensions/extension_tab_util.h" | 17 #include "chrome/browser/extensions/extension_tab_util.h" |
15 #include "chrome/browser/ui/browser.h" | 18 #include "chrome/browser/ui/browser.h" |
16 #include "chrome/browser/ui/tabs/tab_strip_model.h" | 19 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
17 #include "chrome/common/extensions/permissions/permissions_data.h" | 20 #include "chrome/common/extensions/permissions/permissions_data.h" |
18 #include "chrome/test/base/in_process_browser_test.h" | 21 #include "chrome/test/base/in_process_browser_test.h" |
19 #include "chrome/test/base/ui_test_utils.h" | 22 #include "chrome/test/base/ui_test_utils.h" |
20 #include "content/public/browser/media_device_id.h" | 23 #include "content/public/browser/media_device_id.h" |
21 #include "content/public/browser/web_contents.h" | 24 #include "content/public/browser/web_contents.h" |
25 #include "content/public/test/browser_test_utils.h" | |
22 #include "extensions/common/permissions/permission_set.h" | 26 #include "extensions/common/permissions/permission_set.h" |
23 #include "media/audio/audio_manager.h" | 27 #include "media/audio/audio_manager.h" |
24 #include "net/test/embedded_test_server/embedded_test_server.h" | 28 #include "net/test/embedded_test_server/embedded_test_server.h" |
25 #include "testing/gtest/include/gtest/gtest.h" | 29 #include "testing/gtest/include/gtest/gtest.h" |
26 | 30 |
27 using base::JSONWriter; | 31 using base::JSONWriter; |
28 using content::RenderViewHost; | 32 using content::RenderViewHost; |
29 using content::WebContents; | 33 using content::WebContents; |
30 using media::AudioDeviceNames; | 34 using media::AudioDeviceNames; |
31 using media::AudioManager; | 35 using media::AudioManager; |
32 | 36 |
33 namespace extensions { | 37 namespace extensions { |
34 | 38 |
35 using extension_function_test_utils::RunFunctionAndReturnError; | 39 using extension_function_test_utils::RunFunctionAndReturnError; |
36 using extension_function_test_utils::RunFunctionAndReturnSingleResult; | 40 using extension_function_test_utils::RunFunctionAndReturnSingleResult; |
37 | 41 |
38 class WebrtcAudioPrivateTest : public ExtensionApiTest { | 42 class AudioWaitingExtensionTest : public ExtensionApiTest { |
43 protected: | |
44 void WaitUntilAudioIsPlaying(WebContents* tab) { | |
45 // Wait for audio to start playing. We gate this on there being one | |
46 // or more AudioOutputController objects for our tab. | |
47 bool audio_playing = false; | |
48 for (size_t remaining_tries = 50; remaining_tries > 0; --remaining_tries) { | |
49 tab->GetRenderViewHost()->GetAudioOutputControllers( | |
50 base::Bind(OnAudioControllers, &audio_playing)); | |
51 base::MessageLoop::current()->RunUntilIdle(); | |
52 if (audio_playing) | |
53 break; | |
54 | |
55 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(100)); | |
56 } | |
57 | |
58 if (!audio_playing) | |
59 FAIL() << "Audio did not start playing within ~5 seconds."; | |
60 } | |
61 | |
62 // Used by the test above to wait until audio is playing. | |
63 static void OnAudioControllers( | |
64 bool* audio_playing, | |
65 const RenderViewHost::AudioOutputControllerList& list) { | |
66 if (!list.empty()) | |
67 *audio_playing = true; | |
68 } | |
69 }; | |
70 | |
71 class WebrtcAudioPrivateTest : public AudioWaitingExtensionTest { | |
39 public: | 72 public: |
40 WebrtcAudioPrivateTest() : enumeration_event_(false, false) { | 73 WebrtcAudioPrivateTest() : enumeration_event_(false, false) { |
41 } | 74 } |
42 | 75 |
43 protected: | 76 protected: |
44 std::string InvokeGetActiveSink(int tab_id) { | 77 std::string InvokeGetActiveSink(int tab_id) { |
45 ListValue parameters; | 78 ListValue parameters; |
46 parameters.AppendInteger(tab_id); | 79 parameters.AppendInteger(tab_id); |
47 std::string parameter_string; | 80 std::string parameter_string; |
48 JSONWriter::Write(¶meters, ¶meter_string); | 81 JSONWriter::Write(¶meters, ¶meter_string); |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
158 | 191 |
159 scoped_refptr<WebrtcAudioPrivateSetActiveSinkFunction> function = | 192 scoped_refptr<WebrtcAudioPrivateSetActiveSinkFunction> function = |
160 new WebrtcAudioPrivateSetActiveSinkFunction(); | 193 new WebrtcAudioPrivateSetActiveSinkFunction(); |
161 std::string error(RunFunctionAndReturnError(function.get(), | 194 std::string error(RunFunctionAndReturnError(function.get(), |
162 parameter_string, | 195 parameter_string, |
163 browser())); | 196 browser())); |
164 EXPECT_EQ(base::StringPrintf("No active stream for tab with id: %d.", tab_id), | 197 EXPECT_EQ(base::StringPrintf("No active stream for tab with id: %d.", tab_id), |
165 error); | 198 error); |
166 } | 199 } |
167 | 200 |
168 // Used by the test below to wait until audio is playing. | |
169 static void OnAudioControllers( | |
170 bool* audio_playing, | |
171 const RenderViewHost::AudioOutputControllerList& list) { | |
172 if (!list.empty()) | |
173 *audio_playing = true; | |
174 } | |
175 | |
176 IN_PROC_BROWSER_TEST_F(WebrtcAudioPrivateTest, GetAndSetWithMediaStream) { | 201 IN_PROC_BROWSER_TEST_F(WebrtcAudioPrivateTest, GetAndSetWithMediaStream) { |
177 // First get the list of output devices, so that we can (if | 202 // First get the list of output devices, so that we can (if |
178 // available) set the active device to a device other than the one | 203 // available) set the active device to a device other than the one |
179 // it starts as. This function is not threadsafe and is normally | 204 // it starts as. This function is not threadsafe and is normally |
180 // called only from the audio IO thread, but we know no other code | 205 // called only from the audio IO thread, but we know no other code |
181 // is currently running so we call it directly. | 206 // is currently running so we call it directly. |
182 AudioDeviceNames devices; | 207 AudioDeviceNames devices; |
183 GetAudioDeviceNames(&AudioManager::GetAudioOutputDeviceNames, &devices); | 208 GetAudioDeviceNames(&AudioManager::GetAudioOutputDeviceNames, &devices); |
184 | 209 |
185 ASSERT_TRUE(StartEmbeddedTestServer()); | 210 ASSERT_TRUE(StartEmbeddedTestServer()); |
186 | 211 |
187 // Open a normal page that uses an audio sink. | 212 // Open a normal page that uses an audio sink. |
188 ui_test_utils::NavigateToURL( | 213 ui_test_utils::NavigateToURL( |
189 browser(), | 214 browser(), |
190 GURL(embedded_test_server()->GetURL("/extensions/loop_audio.html"))); | 215 GURL(embedded_test_server()->GetURL("/extensions/loop_audio.html"))); |
191 | 216 |
192 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); | 217 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); |
193 int tab_id = ExtensionTabUtil::GetTabId(tab); | 218 int tab_id = ExtensionTabUtil::GetTabId(tab); |
194 | 219 |
195 // Wait for audio to start playing. We gate this on there being one | 220 WaitUntilAudioIsPlaying(tab); |
196 // or more AudioOutputController objects for our tab. | |
197 bool audio_playing = false; | |
198 for (size_t remaining_tries = 50; remaining_tries > 0; --remaining_tries) { | |
199 tab->GetRenderViewHost()->GetAudioOutputControllers( | |
200 base::Bind(OnAudioControllers, &audio_playing)); | |
201 base::MessageLoop::current()->RunUntilIdle(); | |
202 if (audio_playing) | |
203 break; | |
204 | |
205 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(100)); | |
206 } | |
207 | |
208 if (!audio_playing) | |
209 FAIL() << "Audio did not start playing within ~5 seconds."; | |
210 | 221 |
211 std::string current_device = InvokeGetActiveSink(tab_id); | 222 std::string current_device = InvokeGetActiveSink(tab_id); |
212 VLOG(2) << "Before setting, current device: " << current_device; | 223 VLOG(2) << "Before setting, current device: " << current_device; |
213 EXPECT_NE("", current_device); | 224 EXPECT_NE("", current_device); |
214 | 225 |
215 // Set to each of the other devices in turn. | 226 // Set to each of the other devices in turn. |
216 for (AudioDeviceNames::const_iterator it = devices.begin(); | 227 for (AudioDeviceNames::const_iterator it = devices.begin(); |
217 it != devices.end(); | 228 it != devices.end(); |
218 ++it) { | 229 ++it) { |
219 std::string target_device(it->unique_id); | 230 std::string target_device(it->unique_id); |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
286 const extensions::Extension* extension = LoadExtension( | 297 const extensions::Extension* extension = LoadExtension( |
287 test_data_dir_.AppendASCII("webrtc_audio_private_event_listener")); | 298 test_data_dir_.AppendASCII("webrtc_audio_private_event_listener")); |
288 service->OnDevicesChanged(base::SystemMonitor::DEVTYPE_AUDIO_CAPTURE); | 299 service->OnDevicesChanged(base::SystemMonitor::DEVTYPE_AUDIO_CAPTURE); |
289 | 300 |
290 // Check that the extension got the notification. | 301 // Check that the extension got the notification. |
291 std::string result = ExecuteScriptInBackgroundPage(extension->id(), | 302 std::string result = ExecuteScriptInBackgroundPage(extension->id(), |
292 "reportIfGot()"); | 303 "reportIfGot()"); |
293 EXPECT_EQ("true", result); | 304 EXPECT_EQ("true", result); |
294 } | 305 } |
295 | 306 |
307 class HangoutServicesBrowserTest : public AudioWaitingExtensionTest { | |
308 public: | |
309 virtual void SetUp() OVERRIDE { | |
310 // Make sure the Hangout Services component extension gets loaded. | |
311 ComponentLoader::EnableBackgroundExtensionsForTesting(); | |
312 ExtensionBrowserTest::SetUp(); | |
Henrik Grunell
2013/11/06 08:49:01
Just checking: should it be ExtensionApiTest::SetU
Jói
2013/11/06 11:19:29
Good catch, it should be <superclass>::SetUp(), so
| |
313 } | |
314 }; | |
315 | |
316 IN_PROC_BROWSER_TEST_F(HangoutServicesBrowserTest, | |
Henrik Grunell
2013/11/06 08:49:01
If the services test runs other than audio tests,
Jói
2013/11/06 11:19:29
I thought about that, but it doesn't really belong
Henrik Grunell
2013/11/06 11:43:30
I'm fine with that.
| |
317 RunComponentExtensionTest) { | |
318 // This runs the end-to-end JavaScript test for the Hangout Services | |
319 // component extension, which uses the webrtcAudioPrivate API among | |
320 // others. | |
321 ASSERT_TRUE(StartEmbeddedTestServer()); | |
322 GURL url(embedded_test_server()->GetURL( | |
323 "/extensions/hangout_services_test.html")); | |
324 // The "externally connectable" extension permission doesn't seem to | |
325 // like when we use 127.0.0.1 as the host, but using localhost works. | |
326 std::string url_spec = url.spec(); | |
327 ReplaceFirstSubstringAfterOffset(&url_spec, 0, "127.0.0.1", "localhost"); | |
328 GURL localhost_url(url_spec); | |
329 ui_test_utils::NavigateToURL(browser(), localhost_url); | |
330 | |
331 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); | |
332 WaitUntilAudioIsPlaying(tab); | |
333 | |
334 ASSERT_TRUE(content::ExecuteScript(tab, "browsertestRunAllTests();")); | |
335 | |
336 content::TitleWatcher title_watcher(tab, ASCIIToUTF16("success")); | |
337 title_watcher.AlsoWaitForTitle(ASCIIToUTF16("failure")); | |
338 string16 result = title_watcher.WaitAndGetTitle(); | |
339 EXPECT_EQ(ASCIIToUTF16("success"), result); | |
340 } | |
341 | |
296 } // namespace extensions | 342 } // namespace extensions |
OLD | NEW |