Index: chrome/browser/renderer_host/render_process_host_chrome_browsertest.cc |
diff --git a/chrome/browser/renderer_host/render_process_host_chrome_browsertest.cc b/chrome/browser/renderer_host/render_process_host_chrome_browsertest.cc |
index 24c58ef9a6acd950d566e73f5f62e0f5225ad8ed..43d6d93381f00b106992fd159fb3226a2d123576 100644 |
--- a/chrome/browser/renderer_host/render_process_host_chrome_browsertest.cc |
+++ b/chrome/browser/renderer_host/render_process_host_chrome_browsertest.cc |
@@ -3,7 +3,9 @@ |
// found in the LICENSE file. |
#include "base/command_line.h" |
+#include "base/path_service.h" |
#include "base/process/process.h" |
+#include "base/test/test_timeouts.h" |
#include "chrome/browser/chrome_notification_types.h" |
#include "chrome/browser/devtools/devtools_window.h" |
#include "chrome/browser/search/search.h" |
@@ -23,6 +25,8 @@ |
#include "content/public/browser/web_contents.h" |
#include "content/public/browser/web_contents_observer.h" |
#include "content/public/test/browser_test_utils.h" |
+#include "net/base/filename_util.h" |
+#include "net/test/embedded_test_server/embedded_test_server.h" |
using content::RenderViewHost; |
using content::RenderWidgetHost; |
@@ -531,3 +535,165 @@ IN_PROC_BROWSER_TEST_F(ChromeRenderProcessHostTest, |
observer.Wait(); |
} |
+ |
+// Sets up the browser in order to start the tests with two tabs open: one |
+// called "no audio" in foreground and another called "audio" in background with |
+// audio in playing state. Also sets up the variables containing the process |
+// associated with each tab, the urls of the two pages and the WebContents of |
+// the "audio" page. |
+class ChromeRenderProcessHostBackgroundingTest |
+ : public ChromeRenderProcessHostTest { |
+ public: |
+ ChromeRenderProcessHostBackgroundingTest() {} |
+ |
+ void SetUpCommandLine(base::CommandLine* command_line) override { |
+ command_line->AppendSwitch(switches::kProcessPerTab); |
+ } |
+ |
+ void SetUpOnMainThread() override { |
+ ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); |
+ |
+ // Set up the server and get the test pages. |
+ base::FilePath test_data_dir; |
+ ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &test_data_dir)); |
+ embedded_test_server()->ServeFilesFromDirectory( |
+ test_data_dir.AppendASCII("chrome/test/data/")); |
+ audio_url_ = embedded_test_server()->GetURL("/extensions/loop_audio.html"); |
+ no_audio_url_ = embedded_test_server()->GetURL("/title1.html"); |
+ |
+ // Open a browser, navigate to the audio page and get its WebContents. |
+ ui_test_utils::NavigateToURL(browser(), audio_url_); |
+ audio_tab_web_contents_ = |
+ browser()->tab_strip_model()->GetActiveWebContents(); |
+ |
+ // Create a new tab for the no audio page and get the processes |
+ // corresponding to each page. |
gab
2015/08/24 20:59:22
// Create a new tab for the no audio page and conf
sebsg
2015/08/25 01:35:59
Done.
|
+ base::Process no_audio_process_ = ShowSingletonTab(no_audio_url_); |
gab
2015/08/24 20:59:22
|no_audio_process| (no longer a member variable, s
sebsg
2015/08/25 01:35:59
Done.
|
+ no_audio_tab_web_contents_ = |
gab
2015/08/24 20:59:22
Perhaps move this after the ASSERTs as it's now no
sebsg
2015/08/25 01:35:59
Done.
|
+ browser()->tab_strip_model()->GetActiveWebContents(); |
+ base::Process audio_process_ = ProcessFromHandle( |
+ audio_tab_web_contents_->GetRenderProcessHost()->GetHandle()); |
+ |
+ ASSERT_TRUE(no_audio_process_.IsValid()); |
+ ASSERT_TRUE(audio_process_.IsValid()); |
+ ASSERT_NE(audio_process_.Pid(), no_audio_process_.Pid()); |
+ } |
+ |
+ protected: |
+ bool IsProcessBackgroundedHelper(const content::WebContents& web_contents) { |
gab
2015/08/24 20:59:22
I'd say const* is arguably better here so that you
sebsg
2015/08/25 01:35:59
Done.
|
+#if defined(OS_MACOSX) |
+ content::RenderProcessHost* rph = web_contents.GetRenderProcessHost(); |
gab
2015/08/24 20:59:22
const
sebsg
2015/08/25 01:35:59
Done.
|
+ base::Process process = ProcessFromHandle(rph->GetHandle()); |
gab
2015/08/24 20:59:22
const
sebsg
2015/08/25 01:35:59
Done.
|
+ return process.IsProcessBackgrounded(rph->GetMachTaskPortForTesting()); |
+#else |
+ base::Process process = |
gab
2015/08/24 20:59:22
const
sebsg
2015/08/25 01:35:59
Done.
|
+ ProcessFromHandle(web_contents.GetRenderProcessHost()->GetHandle()); |
+ return process.IsProcessBackgrounded(); |
+#endif // defined(OS_MACOSX) |
+ } |
+ |
+ GURL audio_url_; |
+ GURL no_audio_url_; |
+ |
+ content::WebContents* audio_tab_web_contents_; |
+ content::WebContents* no_audio_tab_web_contents_; |
+ |
+ private: |
+ DISALLOW_COPY_AND_ASSIGN(ChromeRenderProcessHostBackgroundingTest); |
+}; |
+ |
+// Test to make sure that a process is backgrounded when the audio stops playing |
+// from the active tab and there is an immediate tab switch. |
+IN_PROC_BROWSER_TEST_F(ChromeRenderProcessHostBackgroundingTest, |
+ ProcessPriorityAfterStoppedAudio) { |
+ // This test is invalid on platforms that can't background. |
+ if (!base::Process::CanBackgroundProcesses()) |
+ return; |
+ |
+ ShowSingletonTab(audio_url_); |
+ |
+ // Wait until the no audio page is backgrounded and the audio page is not |
+ // backgrounded. |
+ while (!IsProcessBackgroundedHelper(*no_audio_tab_web_contents_) || |
+ IsProcessBackgroundedHelper(*audio_tab_web_contents_)) { |
+ base::RunLoop().RunUntilIdle(); |
+ base::PlatformThread::Sleep(TestTimeouts::tiny_timeout()); |
+ } |
+ |
+ // Pause the audio and immediately switch to the no audio tab. |
+ ASSERT_TRUE(content::ExecuteScript( |
+ audio_tab_web_contents_, |
+ "document.getElementById('audioPlayer').pause();")); |
+ ShowSingletonTab(no_audio_url_); |
+ |
+ // Wait until the no audio page is not backgrounded and the audio page is |
+ // backgrounded. |
+ while (IsProcessBackgroundedHelper(*no_audio_tab_web_contents_) || |
+ !IsProcessBackgroundedHelper(*audio_tab_web_contents_)) { |
+ base::RunLoop().RunUntilIdle(); |
+ base::PlatformThread::Sleep(TestTimeouts::tiny_timeout()); |
+ } |
+} |
+ |
+// Test to make sure that a process is backgrounded automatically when audio |
+// stops playing from a hidden tab. |
+IN_PROC_BROWSER_TEST_F(ChromeRenderProcessHostBackgroundingTest, |
+ ProcessPriorityAfterAudioStopsOnNotVisibleTab) { |
+ // This test is invalid on platforms that can't background. |
+ if (!base::Process::CanBackgroundProcesses()) |
+ return; |
+ |
+ // Wait until the two pages are not backgrounded. |
+ while (IsProcessBackgroundedHelper(*no_audio_tab_web_contents_) || |
+ IsProcessBackgroundedHelper(*audio_tab_web_contents_)) { |
+ base::RunLoop().RunUntilIdle(); |
+ base::PlatformThread::Sleep(TestTimeouts::tiny_timeout()); |
+ } |
+ |
+ // Stop the audio. |
+ ASSERT_TRUE(content::ExecuteScript( |
+ audio_tab_web_contents_, |
+ "document.getElementById('audioPlayer').pause();")); |
+ |
+ // Wait until the no audio page is not backgrounded and the audio page is |
+ // backgrounded. |
+ while (IsProcessBackgroundedHelper(*no_audio_tab_web_contents_) || |
+ !IsProcessBackgroundedHelper(*audio_tab_web_contents_)) { |
+ base::RunLoop().RunUntilIdle(); |
+ base::PlatformThread::Sleep(TestTimeouts::tiny_timeout()); |
+ } |
+} |
+ |
+// Test to make sure that a process is un-backgrounded automatically when audio |
+// starts playing from a backgrounded tab. |
+IN_PROC_BROWSER_TEST_F(ChromeRenderProcessHostBackgroundingTest, |
+ ProcessPriorityAfterAudioStartsFromBackgroundTab) { |
+ // This test is invalid on platforms that can't background. |
+ if (!base::Process::CanBackgroundProcesses()) |
+ return; |
+ |
+ // Stop the audio. |
+ ASSERT_TRUE(content::ExecuteScript( |
+ audio_tab_web_contents_, |
+ "document.getElementById('audioPlayer').pause();")); |
+ |
+ // Wait until the no audio page is not backgrounded and the audio page is |
+ // backgrounded. |
+ while (IsProcessBackgroundedHelper(*no_audio_tab_web_contents_) || |
+ !IsProcessBackgroundedHelper(*audio_tab_web_contents_)) { |
+ base::RunLoop().RunUntilIdle(); |
+ base::PlatformThread::Sleep(TestTimeouts::tiny_timeout()); |
+ } |
+ |
+ // Start the audio from the backgrounded tab. |
+ ASSERT_TRUE( |
+ content::ExecuteScript(audio_tab_web_contents_, |
+ "document.getElementById('audioPlayer').play();")); |
+ |
+ // Wait until the two pages are not backgrounded. |
+ while (IsProcessBackgroundedHelper(*no_audio_tab_web_contents_) || |
+ IsProcessBackgroundedHelper(*audio_tab_web_contents_)) { |
+ base::RunLoop().RunUntilIdle(); |
+ base::PlatformThread::Sleep(TestTimeouts::tiny_timeout()); |
+ } |
+} |