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 488 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
524 chrome::NOTIFICATION_BROWSER_CLOSED, | 528 chrome::NOTIFICATION_BROWSER_CLOSED, |
525 content::NotificationService::AllSources()); | 529 content::NotificationService::AllSources()); |
526 | 530 |
527 // Kill the renderer process, simulating a crash. This should the ProcessDied | 531 // Kill the renderer process, simulating a crash. This should the ProcessDied |
528 // method to be called. Alternatively, RenderProcessHost::OnChannelError can | 532 // method to be called. Alternatively, RenderProcessHost::OnChannelError can |
529 // be called to directly force a call to ProcessDied. | 533 // be called to directly force a call to ProcessDied. |
530 wc1->GetRenderProcessHost()->Shutdown(-1, true); | 534 wc1->GetRenderProcessHost()->Shutdown(-1, true); |
531 | 535 |
532 observer.Wait(); | 536 observer.Wait(); |
533 } | 537 } |
538 | |
539 // Sets up the browser in order to start the tests with two tabs open: one | |
540 // called "no audio" in foreground and another called "audio" in background with | |
541 // audio in playing state. Also sets up the variables containing the process | |
542 // associated with each tab, the urls of the two pages and the WebContents of | |
543 // the "audio" page. | |
544 class ChromeRenderProcessHostBackgroundingTest | |
545 : public ChromeRenderProcessHostTest { | |
546 public: | |
547 ChromeRenderProcessHostBackgroundingTest() {} | |
548 | |
549 void SetUpCommandLine(base::CommandLine* command_line) override { | |
550 command_line->AppendSwitch(switches::kProcessPerTab); | |
551 } | |
552 | |
553 void SetUpOnMainThread() override { | |
554 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); | |
555 | |
556 // Set up the server and get the test pages. | |
557 base::FilePath test_data_dir; | |
558 ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &test_data_dir)); | |
559 embedded_test_server()->ServeFilesFromDirectory( | |
560 test_data_dir.AppendASCII("chrome/test/data/")); | |
561 audio_url_ = embedded_test_server()->GetURL("/extensions/loop_audio.html"); | |
562 no_audio_url_ = embedded_test_server()->GetURL("/title1.html"); | |
563 | |
564 // Open a browser, navigate to the audio page and get its WebContents. | |
565 ui_test_utils::NavigateToURL(browser(), audio_url_); | |
566 audio_tab_web_contents_ = | |
567 browser()->tab_strip_model()->GetActiveWebContents(); | |
568 | |
569 // Create a new tab for the no audio page and get the processes | |
570 // 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.
| |
571 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.
| |
572 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.
| |
573 browser()->tab_strip_model()->GetActiveWebContents(); | |
574 base::Process audio_process_ = ProcessFromHandle( | |
575 audio_tab_web_contents_->GetRenderProcessHost()->GetHandle()); | |
576 | |
577 ASSERT_TRUE(no_audio_process_.IsValid()); | |
578 ASSERT_TRUE(audio_process_.IsValid()); | |
579 ASSERT_NE(audio_process_.Pid(), no_audio_process_.Pid()); | |
580 } | |
581 | |
582 protected: | |
583 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.
| |
584 #if defined(OS_MACOSX) | |
585 content::RenderProcessHost* rph = web_contents.GetRenderProcessHost(); | |
gab
2015/08/24 20:59:22
const
sebsg
2015/08/25 01:35:59
Done.
| |
586 base::Process process = ProcessFromHandle(rph->GetHandle()); | |
gab
2015/08/24 20:59:22
const
sebsg
2015/08/25 01:35:59
Done.
| |
587 return process.IsProcessBackgrounded(rph->GetMachTaskPortForTesting()); | |
588 #else | |
589 base::Process process = | |
gab
2015/08/24 20:59:22
const
sebsg
2015/08/25 01:35:59
Done.
| |
590 ProcessFromHandle(web_contents.GetRenderProcessHost()->GetHandle()); | |
591 return process.IsProcessBackgrounded(); | |
592 #endif // defined(OS_MACOSX) | |
593 } | |
594 | |
595 GURL audio_url_; | |
596 GURL no_audio_url_; | |
597 | |
598 content::WebContents* audio_tab_web_contents_; | |
599 content::WebContents* no_audio_tab_web_contents_; | |
600 | |
601 private: | |
602 DISALLOW_COPY_AND_ASSIGN(ChromeRenderProcessHostBackgroundingTest); | |
603 }; | |
604 | |
605 // Test to make sure that a process is backgrounded when the audio stops playing | |
606 // from the active tab and there is an immediate tab switch. | |
607 IN_PROC_BROWSER_TEST_F(ChromeRenderProcessHostBackgroundingTest, | |
608 ProcessPriorityAfterStoppedAudio) { | |
609 // This test is invalid on platforms that can't background. | |
610 if (!base::Process::CanBackgroundProcesses()) | |
611 return; | |
612 | |
613 ShowSingletonTab(audio_url_); | |
614 | |
615 // Wait until the no audio page is backgrounded and the audio page is not | |
616 // backgrounded. | |
617 while (!IsProcessBackgroundedHelper(*no_audio_tab_web_contents_) || | |
618 IsProcessBackgroundedHelper(*audio_tab_web_contents_)) { | |
619 base::RunLoop().RunUntilIdle(); | |
620 base::PlatformThread::Sleep(TestTimeouts::tiny_timeout()); | |
621 } | |
622 | |
623 // Pause the audio and immediately switch to the no audio tab. | |
624 ASSERT_TRUE(content::ExecuteScript( | |
625 audio_tab_web_contents_, | |
626 "document.getElementById('audioPlayer').pause();")); | |
627 ShowSingletonTab(no_audio_url_); | |
628 | |
629 // Wait until the no audio page is not backgrounded and the audio page is | |
630 // backgrounded. | |
631 while (IsProcessBackgroundedHelper(*no_audio_tab_web_contents_) || | |
632 !IsProcessBackgroundedHelper(*audio_tab_web_contents_)) { | |
633 base::RunLoop().RunUntilIdle(); | |
634 base::PlatformThread::Sleep(TestTimeouts::tiny_timeout()); | |
635 } | |
636 } | |
637 | |
638 // Test to make sure that a process is backgrounded automatically when audio | |
639 // stops playing from a hidden tab. | |
640 IN_PROC_BROWSER_TEST_F(ChromeRenderProcessHostBackgroundingTest, | |
641 ProcessPriorityAfterAudioStopsOnNotVisibleTab) { | |
642 // This test is invalid on platforms that can't background. | |
643 if (!base::Process::CanBackgroundProcesses()) | |
644 return; | |
645 | |
646 // Wait until the two pages are not backgrounded. | |
647 while (IsProcessBackgroundedHelper(*no_audio_tab_web_contents_) || | |
648 IsProcessBackgroundedHelper(*audio_tab_web_contents_)) { | |
649 base::RunLoop().RunUntilIdle(); | |
650 base::PlatformThread::Sleep(TestTimeouts::tiny_timeout()); | |
651 } | |
652 | |
653 // Stop the audio. | |
654 ASSERT_TRUE(content::ExecuteScript( | |
655 audio_tab_web_contents_, | |
656 "document.getElementById('audioPlayer').pause();")); | |
657 | |
658 // Wait until the no audio page is not backgrounded and the audio page is | |
659 // backgrounded. | |
660 while (IsProcessBackgroundedHelper(*no_audio_tab_web_contents_) || | |
661 !IsProcessBackgroundedHelper(*audio_tab_web_contents_)) { | |
662 base::RunLoop().RunUntilIdle(); | |
663 base::PlatformThread::Sleep(TestTimeouts::tiny_timeout()); | |
664 } | |
665 } | |
666 | |
667 // Test to make sure that a process is un-backgrounded automatically when audio | |
668 // starts playing from a backgrounded tab. | |
669 IN_PROC_BROWSER_TEST_F(ChromeRenderProcessHostBackgroundingTest, | |
670 ProcessPriorityAfterAudioStartsFromBackgroundTab) { | |
671 // This test is invalid on platforms that can't background. | |
672 if (!base::Process::CanBackgroundProcesses()) | |
673 return; | |
674 | |
675 // Stop the audio. | |
676 ASSERT_TRUE(content::ExecuteScript( | |
677 audio_tab_web_contents_, | |
678 "document.getElementById('audioPlayer').pause();")); | |
679 | |
680 // Wait until the no audio page is not backgrounded and the audio page is | |
681 // backgrounded. | |
682 while (IsProcessBackgroundedHelper(*no_audio_tab_web_contents_) || | |
683 !IsProcessBackgroundedHelper(*audio_tab_web_contents_)) { | |
684 base::RunLoop().RunUntilIdle(); | |
685 base::PlatformThread::Sleep(TestTimeouts::tiny_timeout()); | |
686 } | |
687 | |
688 // Start the audio from the backgrounded tab. | |
689 ASSERT_TRUE( | |
690 content::ExecuteScript(audio_tab_web_contents_, | |
691 "document.getElementById('audioPlayer').play();")); | |
692 | |
693 // Wait until the two pages are not backgrounded. | |
694 while (IsProcessBackgroundedHelper(*no_audio_tab_web_contents_) || | |
695 IsProcessBackgroundedHelper(*audio_tab_web_contents_)) { | |
696 base::RunLoop().RunUntilIdle(); | |
697 base::PlatformThread::Sleep(TestTimeouts::tiny_timeout()); | |
698 } | |
699 } | |
OLD | NEW |