Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 "base/command_line.h" | 5 #include "base/command_line.h" |
| 6 #include "base/path_service.h" | |
| 6 #include "base/process/process.h" | 7 #include "base/process/process.h" |
| 8 #include "base/test/test_timeouts.h" | |
| 7 #include "chrome/browser/chrome_notification_types.h" | 9 #include "chrome/browser/chrome_notification_types.h" |
| 8 #include "chrome/browser/devtools/devtools_window.h" | 10 #include "chrome/browser/devtools/devtools_window.h" |
| 9 #include "chrome/browser/search/search.h" | 11 #include "chrome/browser/search/search.h" |
| 10 #include "chrome/browser/ui/browser.h" | 12 #include "chrome/browser/ui/browser.h" |
| 11 #include "chrome/browser/ui/browser_commands.h" | 13 #include "chrome/browser/ui/browser_commands.h" |
| 12 #include "chrome/browser/ui/singleton_tabs.h" | 14 #include "chrome/browser/ui/singleton_tabs.h" |
| 13 #include "chrome/browser/ui/tabs/tab_strip_model.h" | 15 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
| 14 #include "chrome/common/chrome_switches.h" | 16 #include "chrome/common/chrome_switches.h" |
| 15 #include "chrome/common/url_constants.h" | 17 #include "chrome/common/url_constants.h" |
| 16 #include "chrome/test/base/in_process_browser_test.h" | 18 #include "chrome/test/base/in_process_browser_test.h" |
| 17 #include "chrome/test/base/test_switches.h" | 19 #include "chrome/test/base/test_switches.h" |
| 18 #include "chrome/test/base/ui_test_utils.h" | 20 #include "chrome/test/base/ui_test_utils.h" |
| 19 #include "content/public/browser/notification_service.h" | 21 #include "content/public/browser/notification_service.h" |
| 20 #include "content/public/browser/render_process_host.h" | 22 #include "content/public/browser/render_process_host.h" |
| 21 #include "content/public/browser/render_view_host.h" | 23 #include "content/public/browser/render_view_host.h" |
| 22 #include "content/public/browser/render_widget_host_iterator.h" | 24 #include "content/public/browser/render_widget_host_iterator.h" |
| 23 #include "content/public/browser/web_contents.h" | 25 #include "content/public/browser/web_contents.h" |
| 24 #include "content/public/browser/web_contents_observer.h" | 26 #include "content/public/browser/web_contents_observer.h" |
| 25 #include "content/public/test/browser_test_utils.h" | 27 #include "content/public/test/browser_test_utils.h" |
| 28 #include "net/base/filename_util.h" | |
| 29 #include "net/test/embedded_test_server/embedded_test_server.h" | |
| 26 | 30 |
| 27 using content::RenderViewHost; | 31 using content::RenderViewHost; |
| 28 using content::RenderWidgetHost; | 32 using content::RenderWidgetHost; |
| 29 using content::WebContents; | 33 using content::WebContents; |
| 30 | 34 |
| 31 namespace { | 35 namespace { |
| 32 | 36 |
| 33 int RenderProcessHostCount() { | 37 int RenderProcessHostCount() { |
| 34 content::RenderProcessHost::iterator hosts = | 38 content::RenderProcessHost::iterator hosts = |
| 35 content::RenderProcessHost::AllHostsIterator(); | 39 content::RenderProcessHost::AllHostsIterator(); |
| (...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 217 | 221 |
| 218 | 222 |
| 219 class ChromeRenderProcessHostTestWithCommandLine | 223 class ChromeRenderProcessHostTestWithCommandLine |
| 220 : public ChromeRenderProcessHostTest { | 224 : public ChromeRenderProcessHostTest { |
| 221 protected: | 225 protected: |
| 222 void SetUpCommandLine(base::CommandLine* command_line) override { | 226 void SetUpCommandLine(base::CommandLine* command_line) override { |
| 223 command_line->AppendSwitchASCII(switches::kRendererProcessLimit, "1"); | 227 command_line->AppendSwitchASCII(switches::kRendererProcessLimit, "1"); |
| 224 } | 228 } |
| 225 }; | 229 }; |
| 226 | 230 |
| 231 class ChromeRenderProcessHostBackgroundingTest | |
| 232 : public ChromeRenderProcessHostTest { | |
| 233 public: | |
| 234 ChromeRenderProcessHostBackgroundingTest() {} | |
| 235 | |
| 236 void SetUpCommandLine(base::CommandLine* command_line) override { | |
| 237 command_line->AppendSwitch(switches::kProcessPerTab); | |
| 238 } | |
| 239 | |
| 240 void SetUpOnMainThread() override { | |
| 241 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); | |
| 242 | |
| 243 // Set up the server and get the test pages. | |
| 244 base::FilePath test_data_dir; | |
| 245 ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &test_data_dir)); | |
| 246 embedded_test_server()->ServeFilesFromDirectory( | |
| 247 test_data_dir.AppendASCII("chrome/test/data/")); | |
| 248 audio_url_ = embedded_test_server()->GetURL("/extensions/loop_audio.html"); | |
| 249 no_audio_url_ = embedded_test_server()->GetURL("/title1.html"); | |
| 250 | |
| 251 // Open a browser, navigate to the audio page and get its WebContent. | |
| 252 ui_test_utils::NavigateToURL(browser(), audio_url_); | |
| 253 audio_tab_web_content_ = | |
| 254 browser()->tab_strip_model()->GetActiveWebContents(); | |
| 255 | |
| 256 // Get the process corresponding to the pages and create a new tab for the | |
| 257 // no audio page. | |
| 258 audio_process_ = ProcessFromHandle( | |
| 259 audio_tab_web_content_->GetRenderProcessHost()->GetHandle()); | |
| 260 no_audio_process_ = ShowSingletonTab(no_audio_url_); | |
| 261 | |
| 262 ASSERT_TRUE(no_audio_process_.IsValid()); | |
| 263 ASSERT_TRUE(audio_process_.IsValid()); | |
| 264 ASSERT_NE(audio_process_.Pid(), no_audio_process_.Pid()); | |
| 265 } | |
| 266 | |
| 267 protected: | |
| 268 bool IsProcessBackgroundedHelper(const base::Process& process) { | |
| 269 #if defined(OS_MACOSX) | |
| 270 MachBroker* broker = MachBroker::GetInstance(); | |
| 271 mach_port_t task_port = broker->TaskForPid(process.Pid()); | |
| 272 return process.IsProcessBackgrounded(task_port); | |
| 273 #else | |
| 274 return process.IsProcessBackgrounded(); | |
| 275 #endif // defined(OS_MACOSX) | |
| 276 } | |
| 277 | |
| 278 base::Process audio_process_; | |
| 279 base::Process no_audio_process_; | |
| 280 | |
| 281 GURL audio_url_; | |
| 282 GURL no_audio_url_; | |
| 283 | |
| 284 content::WebContents* audio_tab_web_content_; | |
| 285 }; | |
| 286 | |
| 227 // Disable on Mac and Windows due to ongoing flakiness. (crbug.com/442785) | 287 // Disable on Mac and Windows due to ongoing flakiness. (crbug.com/442785) |
| 228 #if defined(OS_MACOSX) || defined(OS_WIN) | 288 #if defined(OS_MACOSX) || defined(OS_WIN) |
| 229 #define MAYBE_ProcessPerTab DISABLED_ProcessPerTab | 289 #define MAYBE_ProcessPerTab DISABLED_ProcessPerTab |
| 230 #else | 290 #else |
| 231 #define MAYBE_ProcessPerTab ProcessPerTab | 291 #define MAYBE_ProcessPerTab ProcessPerTab |
| 232 #endif | 292 #endif |
| 233 | 293 |
| 234 IN_PROC_BROWSER_TEST_F(ChromeRenderProcessHostTest, MAYBE_ProcessPerTab) { | 294 IN_PROC_BROWSER_TEST_F(ChromeRenderProcessHostTest, MAYBE_ProcessPerTab) { |
| 235 // Set max renderers to 1 to force running out of processes. | 295 // Set max renderers to 1 to force running out of processes. |
| 236 content::RenderProcessHost::SetMaxRendererProcessCount(1); | 296 content::RenderProcessHost::SetMaxRendererProcessCount(1); |
| (...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 524 chrome::NOTIFICATION_BROWSER_CLOSED, | 584 chrome::NOTIFICATION_BROWSER_CLOSED, |
| 525 content::NotificationService::AllSources()); | 585 content::NotificationService::AllSources()); |
| 526 | 586 |
| 527 // Kill the renderer process, simulating a crash. This should the ProcessDied | 587 // Kill the renderer process, simulating a crash. This should the ProcessDied |
| 528 // method to be called. Alternatively, RenderProcessHost::OnChannelError can | 588 // method to be called. Alternatively, RenderProcessHost::OnChannelError can |
| 529 // be called to directly force a call to ProcessDied. | 589 // be called to directly force a call to ProcessDied. |
| 530 wc1->GetRenderProcessHost()->Shutdown(-1, true); | 590 wc1->GetRenderProcessHost()->Shutdown(-1, true); |
| 531 | 591 |
| 532 observer.Wait(); | 592 observer.Wait(); |
| 533 } | 593 } |
| 594 | |
| 595 // Test to make sure that a process is backgrounded when the audio stops playing | |
| 596 // from the active tab and there is an immediate tab switch. | |
| 597 IN_PROC_BROWSER_TEST_F(ChromeRenderProcessHostBackgroundingTest, | |
| 598 ProcessPriorityAfterStoppedAudio) { | |
| 599 // This test is invalid on platforms that can't background. | |
| 600 if (!base::Process::CanBackgroundProcesses()) | |
| 601 return; | |
| 602 | |
| 603 ShowSingletonTab(audio_url_); | |
| 604 | |
| 605 // Wait until the no audio page is backgrounded and the audio page is not | |
| 606 // backgrounded. | |
| 607 while (!IsProcessBackgroundedHelper(no_audio_process_) || | |
| 608 IsProcessBackgroundedHelper(audio_process_)) { | |
| 609 base::RunLoop().RunUntilIdle(); | |
| 610 base::PlatformThread::Sleep(TestTimeouts::tiny_timeout()); | |
| 611 } | |
| 612 | |
| 613 // Pause the audio and immediately switch to the no audio tab. | |
| 614 content::ExecuteScript(audio_tab_web_content_, | |
| 615 "document.getElementById('audioPlayer').pause();"); | |
| 616 ShowSingletonTab(no_audio_url_); | |
| 617 | |
| 618 // Wait until the no audio page is not backgrounded and the audio page is | |
| 619 // backgrounded. | |
| 620 while (IsProcessBackgroundedHelper(no_audio_process_) || | |
| 621 !IsProcessBackgroundedHelper(audio_process_)) { | |
| 622 base::RunLoop().RunUntilIdle(); | |
| 623 base::PlatformThread::Sleep(TestTimeouts::tiny_timeout()); | |
| 624 } | |
| 625 } | |
| 626 | |
| 627 // Test to make sure that a process is backgrounded automatically when audio | |
| 628 // stops playing from a not visible tab. | |
| 629 IN_PROC_BROWSER_TEST_F(ChromeRenderProcessHostBackgroundingTest, | |
| 630 ProcessPriorityAfterAudioStopsOnNotVisibleTab) { | |
| 631 // This test is invalid on platforms that can't background. | |
| 632 if (!base::Process::CanBackgroundProcesses()) | |
| 633 return; | |
| 634 | |
| 635 // Wait until the two pages are not backgrounded. | |
| 636 while (IsProcessBackgroundedHelper(no_audio_process_) || | |
| 637 IsProcessBackgroundedHelper(audio_process_)) { | |
| 638 base::RunLoop().RunUntilIdle(); | |
| 639 base::PlatformThread::Sleep(TestTimeouts::tiny_timeout()); | |
| 640 } | |
| 641 | |
| 642 // Stop the audio. | |
| 643 content::ExecuteScript(audio_tab_web_content_, | |
|
gab
2015/08/18 01:48:05
Need to ASSERT_TRUE on content::ExecuteScript.
Th
sebsg
2015/08/18 20:20:15
Done.
| |
| 644 "document.getElementById('audioPlayer').pause();"); | |
| 645 | |
| 646 // Wait until the no audio page is not backgrounded and the audio page is | |
| 647 // backgrounded. | |
| 648 while (IsProcessBackgroundedHelper(no_audio_process_) || | |
| 649 !IsProcessBackgroundedHelper(audio_process_)) { | |
| 650 base::RunLoop().RunUntilIdle(); | |
| 651 base::PlatformThread::Sleep(TestTimeouts::tiny_timeout()); | |
| 652 } | |
| 653 } | |
| 654 | |
| 655 // Test to make sure that a process is un-backgrounded automatically when audio | |
| 656 // starts playing from a backgrounded tab. | |
| 657 IN_PROC_BROWSER_TEST_F(ChromeRenderProcessHostBackgroundingTest, | |
| 658 ProcessPriorityAfterAudioStartsFromBackgroundTab) { | |
| 659 // This test is invalid on platforms that can't background. | |
| 660 if (!base::Process::CanBackgroundProcesses()) | |
| 661 return; | |
| 662 | |
| 663 // Stop the audio. | |
| 664 content::ExecuteScript(audio_tab_web_content_, | |
| 665 "document.getElementById('audioPlayer').pause();"); | |
| 666 | |
| 667 // Wait until the no audio page is not backgrounded and the audio page is | |
| 668 // backgrounded. | |
| 669 while (IsProcessBackgroundedHelper(no_audio_process_) || | |
| 670 !IsProcessBackgroundedHelper(audio_process_)) { | |
| 671 base::RunLoop().RunUntilIdle(); | |
| 672 base::PlatformThread::Sleep(TestTimeouts::tiny_timeout()); | |
| 673 } | |
| 674 | |
| 675 // Start the audio from the backgrounded tab. | |
| 676 content::ExecuteScript(audio_tab_web_content_, | |
| 677 "document.getElementById('audioPlayer').play();"); | |
| 678 | |
| 679 // Wait until the two pages are not backgrounded. | |
| 680 while (IsProcessBackgroundedHelper(no_audio_process_) || | |
| 681 IsProcessBackgroundedHelper(audio_process_)) { | |
| 682 base::RunLoop().RunUntilIdle(); | |
| 683 base::PlatformThread::Sleep(TestTimeouts::tiny_timeout()); | |
| 684 } | |
| 685 } | |
| OLD | NEW |