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