Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(478)

Side by Side Diff: chrome/browser/renderer_host/render_process_host_chrome_browsertest.cc

Issue 2454073003: Allow backgrounding processes on Mac (Closed)
Patch Set: Forgot ifdef Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/macros.h" 6 #include "base/macros.h"
7 #include "base/path_service.h" 7 #include "base/path_service.h"
8 #include "base/process/process.h" 8 #include "base/process/process.h"
9 #include "base/run_loop.h" 9 #include "base/run_loop.h"
10 #include "base/test/test_timeouts.h" 10 #include "base/test/test_timeouts.h"
(...skipping 14 matching lines...) Expand all
25 #include "content/public/browser/render_view_host.h" 25 #include "content/public/browser/render_view_host.h"
26 #include "content/public/browser/render_widget_host.h" 26 #include "content/public/browser/render_widget_host.h"
27 #include "content/public/browser/render_widget_host_iterator.h" 27 #include "content/public/browser/render_widget_host_iterator.h"
28 #include "content/public/browser/web_contents.h" 28 #include "content/public/browser/web_contents.h"
29 #include "content/public/browser/web_contents_observer.h" 29 #include "content/public/browser/web_contents_observer.h"
30 #include "content/public/common/content_switches.h" 30 #include "content/public/common/content_switches.h"
31 #include "content/public/test/browser_test_utils.h" 31 #include "content/public/test/browser_test_utils.h"
32 #include "net/base/filename_util.h" 32 #include "net/base/filename_util.h"
33 #include "net/test/embedded_test_server/embedded_test_server.h" 33 #include "net/test/embedded_test_server/embedded_test_server.h"
34 34
35 #if defined(OS_MACOSX)
36 #include "content/public/browser/browser_child_process_host.h"
37 #endif // defined(OS_MACOSX)
38
35 using content::RenderViewHost; 39 using content::RenderViewHost;
36 using content::RenderWidgetHost; 40 using content::RenderWidgetHost;
37 using content::WebContents; 41 using content::WebContents;
38 42
39 namespace { 43 namespace {
40 44
41 int RenderProcessHostCount() { 45 int RenderProcessHostCount() {
42 content::RenderProcessHost::iterator hosts = 46 content::RenderProcessHost::iterator hosts =
43 content::RenderProcessHost::AllHostsIterator(); 47 content::RenderProcessHost::AllHostsIterator();
44 int count = 0; 48 int count = 0;
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after
289 // Create another omnibox tab. It should share the process with the other 293 // Create another omnibox tab. It should share the process with the other
290 // WebUI. 294 // WebUI.
291 ui_test_utils::NavigateToURLWithDisposition( 295 ui_test_utils::NavigateToURLWithDisposition(
292 browser(), omnibox, WindowOpenDisposition::NEW_FOREGROUND_TAB, 296 browser(), omnibox, WindowOpenDisposition::NEW_FOREGROUND_TAB,
293 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); 297 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
294 tab_count++; 298 tab_count++;
295 EXPECT_EQ(tab_count, browser()->tab_strip_model()->count()); 299 EXPECT_EQ(tab_count, browser()->tab_strip_model()->count());
296 EXPECT_EQ(host_count, RenderProcessHostCount()); 300 EXPECT_EQ(host_count, RenderProcessHostCount());
297 } 301 }
298 302
299 // We don't change process priorities on Mac or Posix because the user lacks the 303 // We don't change process priorities on Posix because the user lacks the
300 // permission to raise a process' priority even after lowering it. 304 // permission to raise a process' priority even after lowering it.
301 #if defined(OS_WIN) || defined(OS_LINUX) 305 #if defined(OS_WIN) || defined(OS_LINUX) || defined(OS_MACOSX)
302 IN_PROC_BROWSER_TEST_F(ChromeRenderProcessHostTest, Backgrounding) { 306 IN_PROC_BROWSER_TEST_F(ChromeRenderProcessHostTest, Backgrounding) {
303 if (!base::Process::CanBackgroundProcesses()) { 307 if (!base::Process::CanBackgroundProcesses()) {
304 LOG(ERROR) << "Can't background processes"; 308 LOG(ERROR) << "Can't background processes";
305 return; 309 return;
306 } 310 }
311 #if defined(OS_MACOSX)
312 base::PortProvider* port_provider =
313 content::BrowserChildProcessHost::GetPortProvider();
314 #endif // defined(OS_MACOSX)
315
307 base::CommandLine& parsed_command_line = 316 base::CommandLine& parsed_command_line =
308 *base::CommandLine::ForCurrentProcess(); 317 *base::CommandLine::ForCurrentProcess();
309 parsed_command_line.AppendSwitch(switches::kProcessPerTab); 318 parsed_command_line.AppendSwitch(switches::kProcessPerTab);
310 319
311 // Change the first tab to be the omnibox page (TYPE_WEBUI). 320 // Change the first tab to be the omnibox page (TYPE_WEBUI).
312 GURL omnibox(chrome::kChromeUIOmniboxURL); 321 GURL omnibox(chrome::kChromeUIOmniboxURL);
313 ui_test_utils::NavigateToURL(browser(), omnibox); 322 ui_test_utils::NavigateToURL(browser(), omnibox);
314 323
315 // Create a new tab. It should be foreground. 324 // Create a new tab. It should be foreground.
316 GURL page1("data:text/html,hello world1"); 325 GURL page1("data:text/html,hello world1");
317 base::Process process1 = ShowSingletonTab(page1); 326 base::Process process1 = ShowSingletonTab(page1);
318 ASSERT_TRUE(process1.IsValid()); 327 ASSERT_TRUE(process1.IsValid());
328 #if defined(OS_MACOSX)
329 EXPECT_FALSE(process1.IsProcessBackgrounded(port_provider));
330 #else
319 EXPECT_FALSE(process1.IsProcessBackgrounded()); 331 EXPECT_FALSE(process1.IsProcessBackgrounded());
332 #endif
320 333
321 // Create another tab. It should be foreground, and the first tab should 334 // Create another tab. It should be foreground, and the first tab should
322 // now be background. 335 // now be background.
323 GURL page2("data:text/html,hello world2"); 336 GURL page2("data:text/html,hello world2");
324 base::Process process2 = ShowSingletonTab(page2); 337 base::Process process2 = ShowSingletonTab(page2);
325 ASSERT_TRUE(process2.IsValid()); 338 ASSERT_TRUE(process2.IsValid());
326 EXPECT_NE(process1.Pid(), process2.Pid()); 339 EXPECT_NE(process1.Pid(), process2.Pid());
340 #if defined(OS_MACOSX)
341 EXPECT_TRUE(process1.IsProcessBackgrounded(port_provider));
342 EXPECT_FALSE(process2.IsProcessBackgrounded(port_provider));
343 #else
327 EXPECT_TRUE(process1.IsProcessBackgrounded()); 344 EXPECT_TRUE(process1.IsProcessBackgrounded());
328 EXPECT_FALSE(process2.IsProcessBackgrounded()); 345 EXPECT_FALSE(process2.IsProcessBackgrounded());
346 #endif // defined(OS_MACOSX)
329 347
330 // Load another tab in background. The renderer of the new tab should be 348 // Load another tab in background. The renderer of the new tab should be
331 // backgrounded, while visibility of the other renderers should not change. 349 // backgrounded, while visibility of the other renderers should not change.
332 GURL page3("data:text/html,hello world3"); 350 GURL page3("data:text/html,hello world3");
333 base::Process process3 = OpenBackgroundTab(page3); 351 base::Process process3 = OpenBackgroundTab(page3);
334 ASSERT_TRUE(process3.IsValid()); 352 ASSERT_TRUE(process3.IsValid());
335 EXPECT_NE(process3.Pid(), process1.Pid()); 353 EXPECT_NE(process3.Pid(), process1.Pid());
336 EXPECT_NE(process3.Pid(), process2.Pid()); 354 EXPECT_NE(process3.Pid(), process2.Pid());
355 #if defined(OS_MACOSX)
356 EXPECT_TRUE(process1.IsProcessBackgrounded(port_provider));
357 EXPECT_FALSE(process2.IsProcessBackgrounded(port_provider));
358 // TODO(gab): The new background tab should be backgrounded but it currently
359 // intentionally isn't per a workaround to https://crbug.com/560446 in
360 // RenderProcessHostImpl::OnProcessLaunched().
361 EXPECT_FALSE(process3.IsProcessBackgrounded(port_provider));
362
363 // Navigate back to the first page. Its renderer should be in foreground
364 // again while the other renderers should be backgrounded.
365
366 EXPECT_EQ(process1.Pid(), ShowSingletonTab(page1).Pid());
367 EXPECT_FALSE(process1.IsProcessBackgrounded(port_provider));
368 EXPECT_TRUE(process2.IsProcessBackgrounded(port_provider));
369 // TODO(gab): Same as above.
370 EXPECT_FALSE(process3.IsProcessBackgrounded(port_provider));
371
372 // TODO(gab): Remove this when https://crbug.com/560446 is fixed, but for now
373 // confirm that the correct state is at least achieved when tab #3 is
374 // explicitly foregrounded and re-backgrounded.
375 EXPECT_EQ(process3.Pid(), ShowSingletonTab(page3).Pid());
376 EXPECT_EQ(process1.Pid(), ShowSingletonTab(page1).Pid());
377 EXPECT_FALSE(process1.IsProcessBackgrounded(port_provider));
378 EXPECT_TRUE(process2.IsProcessBackgrounded(port_provider));
379 EXPECT_TRUE(process3.IsProcessBackgrounded(port_provider));
380 #else
337 EXPECT_TRUE(process1.IsProcessBackgrounded()); 381 EXPECT_TRUE(process1.IsProcessBackgrounded());
338 EXPECT_FALSE(process2.IsProcessBackgrounded()); 382 EXPECT_FALSE(process2.IsProcessBackgrounded());
339 // TODO(gab): The new background tab should be backgrounded but it currently 383 // TODO(gab): The new background tab should be backgrounded but it currently
340 // intentionally isn't per a workaround to https://crbug.com/560446 in 384 // intentionally isn't per a workaround to https://crbug.com/560446 in
341 // RenderProcessHostImpl::OnProcessLaunched(). 385 // RenderProcessHostImpl::OnProcessLaunched().
342 EXPECT_FALSE(process3.IsProcessBackgrounded()); 386 EXPECT_FALSE(process3.IsProcessBackgrounded());
343 387
344 // Navigate back to the first page. Its renderer should be in foreground 388 // Navigate back to the first page. Its renderer should be in foreground
345 // again while the other renderers should be backgrounded. 389 // again while the other renderers should be backgrounded.
390
346 EXPECT_EQ(process1.Pid(), ShowSingletonTab(page1).Pid()); 391 EXPECT_EQ(process1.Pid(), ShowSingletonTab(page1).Pid());
347 EXPECT_FALSE(process1.IsProcessBackgrounded()); 392 EXPECT_FALSE(process1.IsProcessBackgrounded());
348 EXPECT_TRUE(process2.IsProcessBackgrounded()); 393 EXPECT_TRUE(process2.IsProcessBackgrounded());
349 // TODO(gab): Same as above. 394 // TODO(gab): Same as above.
350 EXPECT_FALSE(process3.IsProcessBackgrounded()); 395 EXPECT_FALSE(process3.IsProcessBackgrounded());
351 396
352 // TODO(gab): Remove this when https://crbug.com/560446 is fixed, but for now 397 // TODO(gab): Remove this when https://crbug.com/560446 is fixed, but for now
353 // confirm that the correct state is at least achieved when tab #3 is 398 // confirm that the correct state is at least achieved when tab #3 is
354 // explicitly foregrounded and re-backgrounded. 399 // explicitly foregrounded and re-backgrounded.
355 EXPECT_EQ(process3.Pid(), ShowSingletonTab(page3).Pid()); 400 EXPECT_EQ(process3.Pid(), ShowSingletonTab(page3).Pid());
356 EXPECT_EQ(process1.Pid(), ShowSingletonTab(page1).Pid()); 401 EXPECT_EQ(process1.Pid(), ShowSingletonTab(page1).Pid());
357 EXPECT_FALSE(process1.IsProcessBackgrounded()); 402 EXPECT_FALSE(process1.IsProcessBackgrounded());
358 EXPECT_TRUE(process2.IsProcessBackgrounded()); 403 EXPECT_TRUE(process2.IsProcessBackgrounded());
359 EXPECT_TRUE(process3.IsProcessBackgrounded()); 404 EXPECT_TRUE(process3.IsProcessBackgrounded());
405 #endif
360 } 406 }
361 #endif 407 #endif
362 408
363 // TODO(nasko): crbug.com/173137 409 // TODO(nasko): crbug.com/173137
364 // Disable on Windows and Mac due to ongoing flakiness. (crbug.com/442785) 410 // Disable on Windows and Mac due to ongoing flakiness. (crbug.com/442785)
365 #if defined(OS_WIN) || defined(OS_MACOSX) 411 #if defined(OS_WIN) || defined(OS_MACOSX)
366 #define MAYBE_ProcessOverflow DISABLED_ProcessOverflow 412 #define MAYBE_ProcessOverflow DISABLED_ProcessOverflow
367 #else 413 #else
368 #define MAYBE_ProcessOverflow ProcessOverflow 414 #define MAYBE_ProcessOverflow ProcessOverflow
369 #endif 415 #endif
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
569 browser()->tab_strip_model()->GetActiveWebContents(); 615 browser()->tab_strip_model()->GetActiveWebContents();
570 616
571 // Create a new tab for the no audio page and confirm that the process of 617 // Create a new tab for the no audio page and confirm that the process of
572 // each tab is different and that both are valid. 618 // each tab is different and that both are valid.
573 audio_process_ = ProcessFromHandle( 619 audio_process_ = ProcessFromHandle(
574 audio_tab_web_contents_->GetRenderProcessHost()->GetHandle()); 620 audio_tab_web_contents_->GetRenderProcessHost()->GetHandle());
575 no_audio_process_ = ShowSingletonTab(no_audio_url_); 621 no_audio_process_ = ShowSingletonTab(no_audio_url_);
576 ASSERT_NE(audio_process_.Pid(), no_audio_process_.Pid()); 622 ASSERT_NE(audio_process_.Pid(), no_audio_process_.Pid());
577 ASSERT_TRUE(no_audio_process_.IsValid()); 623 ASSERT_TRUE(no_audio_process_.IsValid());
578 ASSERT_TRUE(audio_process_.IsValid()); 624 ASSERT_TRUE(audio_process_.IsValid());
625 #if defined(OS_MACOSX)
626 port_provider_ = content::BrowserChildProcessHost::GetPortProvider();
627 #endif // defined(OS_MACOSX)
579 } 628 }
580 629
581 protected: 630 protected:
631 void WaitUntilBackgrounded(const base::Process& lhs,
632 bool lhs_backgrounded,
633 const base::Process& rhs,
634 bool rhs_backgrounded) {
635 while (IsProcessBackgrounded(lhs) != lhs_backgrounded ||
636 IsProcessBackgrounded(rhs) != rhs_backgrounded) {
637 base::RunLoop().RunUntilIdle();
638 base::PlatformThread::Sleep(TestTimeouts::tiny_timeout());
639 }
640 }
641
582 GURL audio_url_; 642 GURL audio_url_;
583 GURL no_audio_url_; 643 GURL no_audio_url_;
584 644
585 base::Process audio_process_; 645 base::Process audio_process_;
586 base::Process no_audio_process_; 646 base::Process no_audio_process_;
587 647
588 content::WebContents* audio_tab_web_contents_; 648 content::WebContents* audio_tab_web_contents_;
589 649
590 private: 650 private:
651 bool IsProcessBackgrounded(const base::Process& process) {
652 #if defined(OS_MACOSX)
653 return process.IsProcessBackgrounded(port_provider_);
654 #else
655 return process.IsProcessBackgrounded();
656 #endif
657 }
658
659 #if defined(OS_MACOSX)
660 base::PortProvider* port_provider_;
661 #endif
662
591 DISALLOW_COPY_AND_ASSIGN(ChromeRenderProcessHostBackgroundingTest); 663 DISALLOW_COPY_AND_ASSIGN(ChromeRenderProcessHostBackgroundingTest);
592 }; 664 };
593 665
594 // Test to make sure that a process is backgrounded when the audio stops playing 666 // Test to make sure that a process is backgrounded when the audio stops playing
595 // from the active tab and there is an immediate tab switch. 667 // from the active tab and there is an immediate tab switch.
596 IN_PROC_BROWSER_TEST_F(ChromeRenderProcessHostBackgroundingTest, 668 IN_PROC_BROWSER_TEST_F(ChromeRenderProcessHostBackgroundingTest,
597 ProcessPriorityAfterStoppedAudio) { 669 ProcessPriorityAfterStoppedAudio) {
598 // This test is invalid on platforms that can't background. 670 // This test is invalid on platforms that can't background.
599 if (!base::Process::CanBackgroundProcesses()) 671 if (!base::Process::CanBackgroundProcesses())
600 return; 672 return;
601 673
602 ShowSingletonTab(audio_url_); 674 ShowSingletonTab(audio_url_);
603 675
604 // Wait until the no audio page is backgrounded and the audio page is not 676 // Wait until the no audio page is backgrounded and the audio page is not
605 // backgrounded. 677 // backgrounded.
606 while (!no_audio_process_.IsProcessBackgrounded() || 678 WaitUntilBackgrounded(no_audio_process_, true, audio_process_, false);
607 audio_process_.IsProcessBackgrounded()) {
608 base::RunLoop().RunUntilIdle();
609 base::PlatformThread::Sleep(TestTimeouts::tiny_timeout());
610 }
611
612 // Pause the audio and immediately switch to the no audio tab. 679 // Pause the audio and immediately switch to the no audio tab.
613 ASSERT_TRUE(content::ExecuteScript( 680 ASSERT_TRUE(content::ExecuteScript(
614 audio_tab_web_contents_, 681 audio_tab_web_contents_,
615 "document.getElementById('audioPlayer').pause();")); 682 "document.getElementById('audioPlayer').pause();"));
616 ShowSingletonTab(no_audio_url_); 683 ShowSingletonTab(no_audio_url_);
617 684
618 // Wait until the no audio page is not backgrounded and the audio page is 685 // Wait until the no audio page is not backgrounded and the audio page is
619 // backgrounded. 686 // backgrounded.
620 while (no_audio_process_.IsProcessBackgrounded() || 687 WaitUntilBackgrounded(no_audio_process_, false, audio_process_, true);
621 !audio_process_.IsProcessBackgrounded()) {
622 base::RunLoop().RunUntilIdle();
623 base::PlatformThread::Sleep(TestTimeouts::tiny_timeout());
624 }
625 } 688 }
626 689
627 // Test to make sure that a process is backgrounded automatically when audio 690 // Test to make sure that a process is backgrounded automatically when audio
628 // stops playing from a hidden tab. 691 // stops playing from a hidden tab.
629 IN_PROC_BROWSER_TEST_F(ChromeRenderProcessHostBackgroundingTest, 692 IN_PROC_BROWSER_TEST_F(ChromeRenderProcessHostBackgroundingTest,
630 ProcessPriorityAfterAudioStopsOnNotVisibleTab) { 693 ProcessPriorityAfterAudioStopsOnNotVisibleTab) {
631 // This test is invalid on platforms that can't background. 694 // This test is invalid on platforms that can't background.
632 if (!base::Process::CanBackgroundProcesses()) 695 if (!base::Process::CanBackgroundProcesses())
633 return; 696 return;
634 697
635 // Wait until the two pages are not backgrounded. 698 // Wait until the two pages are not backgrounded.
636 while (no_audio_process_.IsProcessBackgrounded() || 699 WaitUntilBackgrounded(audio_process_, false, no_audio_process_, false);
637 audio_process_.IsProcessBackgrounded()) {
638 base::RunLoop().RunUntilIdle();
639 base::PlatformThread::Sleep(TestTimeouts::tiny_timeout());
640 }
641
642 // Stop the audio. 700 // Stop the audio.
643 ASSERT_TRUE(content::ExecuteScript( 701 ASSERT_TRUE(content::ExecuteScript(
644 audio_tab_web_contents_, 702 audio_tab_web_contents_,
645 "document.getElementById('audioPlayer').pause();")); 703 "document.getElementById('audioPlayer').pause();"));
646 704
647 // Wait until the no audio page is not backgrounded and the audio page is 705 // Wait until the no audio page is not backgrounded and the audio page is
648 // backgrounded. 706 // backgrounded.
649 while (no_audio_process_.IsProcessBackgrounded() || 707 WaitUntilBackgrounded(no_audio_process_, false, audio_process_, true);
650 !audio_process_.IsProcessBackgrounded()) {
651 base::RunLoop().RunUntilIdle();
652 base::PlatformThread::Sleep(TestTimeouts::tiny_timeout());
653 }
654 } 708 }
655 709
656 // Test to make sure that a process is un-backgrounded automatically when audio 710 // Test to make sure that a process is un-backgrounded automatically when
711 // audio
657 // starts playing from a backgrounded tab. 712 // starts playing from a backgrounded tab.
658 IN_PROC_BROWSER_TEST_F(ChromeRenderProcessHostBackgroundingTest, 713 IN_PROC_BROWSER_TEST_F(ChromeRenderProcessHostBackgroundingTest,
659 ProcessPriorityAfterAudioStartsFromBackgroundTab) { 714 ProcessPriorityAfterAudioStartsFromBackgroundTab) {
660 // This test is invalid on platforms that can't background. 715 // This test is invalid on platforms that can't background.
661 if (!base::Process::CanBackgroundProcesses()) 716 if (!base::Process::CanBackgroundProcesses())
662 return; 717 return;
663 718
664 // Stop the audio. 719 // Stop the audio.
665 ASSERT_TRUE(content::ExecuteScript( 720 ASSERT_TRUE(content::ExecuteScript(
666 audio_tab_web_contents_, 721 audio_tab_web_contents_,
667 "document.getElementById('audioPlayer').pause();")); 722 "document.getElementById('audioPlayer').pause();"));
668 723
669 // Wait until the no audio page is not backgrounded and the audio page is 724 WaitUntilBackgrounded(no_audio_process_, false, audio_process_, true);
670 // backgrounded.
671 while (no_audio_process_.IsProcessBackgrounded() ||
672 !audio_process_.IsProcessBackgrounded()) {
673 base::RunLoop().RunUntilIdle();
674 base::PlatformThread::Sleep(TestTimeouts::tiny_timeout());
675 }
676 725
677 // Start the audio from the backgrounded tab. 726 // Start the audio from the backgrounded tab.
678 ASSERT_TRUE( 727 ASSERT_TRUE(
679 content::ExecuteScript(audio_tab_web_contents_, 728 content::ExecuteScript(audio_tab_web_contents_,
680 "document.getElementById('audioPlayer').play();")); 729 "document.getElementById('audioPlayer').play();"));
681 730
682 // Wait until the two pages are not backgrounded. 731 // Wait until the two pages are not backgrounded.
683 while (no_audio_process_.IsProcessBackgrounded() || 732 WaitUntilBackgrounded(no_audio_process_, false, audio_process_, false);
684 audio_process_.IsProcessBackgrounded()) {
685 base::RunLoop().RunUntilIdle();
686 base::PlatformThread::Sleep(TestTimeouts::tiny_timeout());
687 }
688 } 733 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698