| 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/process/process.h" |
| 6 #include "chrome/browser/chrome_notification_types.h" | 7 #include "chrome/browser/chrome_notification_types.h" |
| 7 #include "chrome/browser/devtools/devtools_window.h" | 8 #include "chrome/browser/devtools/devtools_window.h" |
| 8 #include "chrome/browser/search/search.h" | 9 #include "chrome/browser/search/search.h" |
| 9 #include "chrome/browser/ui/browser.h" | 10 #include "chrome/browser/ui/browser.h" |
| 10 #include "chrome/browser/ui/browser_commands.h" | 11 #include "chrome/browser/ui/browser_commands.h" |
| 11 #include "chrome/browser/ui/singleton_tabs.h" | 12 #include "chrome/browser/ui/singleton_tabs.h" |
| 12 #include "chrome/browser/ui/tabs/tab_strip_model.h" | 13 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
| 13 #include "chrome/common/chrome_switches.h" | 14 #include "chrome/common/chrome_switches.h" |
| 14 #include "chrome/common/url_constants.h" | 15 #include "chrome/common/url_constants.h" |
| 15 #include "chrome/test/base/in_process_browser_test.h" | 16 #include "chrome/test/base/in_process_browser_test.h" |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 51 continue; | 52 continue; |
| 52 RenderViewHost* host = RenderViewHost::From(widget); | 53 RenderViewHost* host = RenderViewHost::From(widget); |
| 53 WebContents* contents = WebContents::FromRenderViewHost(host); | 54 WebContents* contents = WebContents::FromRenderViewHost(host); |
| 54 GURL url = contents->GetURL(); | 55 GURL url = contents->GetURL(); |
| 55 if (url.SchemeIs(content::kChromeDevToolsScheme)) | 56 if (url.SchemeIs(content::kChromeDevToolsScheme)) |
| 56 return contents; | 57 return contents; |
| 57 } | 58 } |
| 58 return NULL; | 59 return NULL; |
| 59 } | 60 } |
| 60 | 61 |
| 62 // TODO(rvargas) crbug.com/417532: Remove this code. |
| 63 base::Process ProcessFromHandle(base::ProcessHandle handle) { |
| 64 #if defined(OS_WIN) |
| 65 if (handle == GetCurrentProcess()) |
| 66 return base::Process::Current(); |
| 67 |
| 68 base::ProcessHandle out_handle; |
| 69 if (!::DuplicateHandle(GetCurrentProcess(), handle, GetCurrentProcess(), |
| 70 &out_handle, 0, FALSE, DUPLICATE_SAME_ACCESS)) { |
| 71 return base::Process(); |
| 72 } |
| 73 handle = out_handle; |
| 74 #endif // defined(OS_WIN) |
| 75 return base::Process(handle); |
| 76 } |
| 77 |
| 61 } // namespace | 78 } // namespace |
| 62 | 79 |
| 63 class ChromeRenderProcessHostTest : public InProcessBrowserTest { | 80 class ChromeRenderProcessHostTest : public InProcessBrowserTest { |
| 64 public: | 81 public: |
| 65 ChromeRenderProcessHostTest() {} | 82 ChromeRenderProcessHostTest() {} |
| 66 | 83 |
| 67 // Show a tab, activating the current one if there is one, and wait for | 84 // Show a tab, activating the current one if there is one, and wait for |
| 68 // the renderer process to be created or foregrounded, returning the process | 85 // the renderer process to be created or foregrounded, returning the process |
| 69 // handle. | 86 // handle. |
| 70 base::ProcessHandle ShowSingletonTab(const GURL& page) { | 87 base::Process ShowSingletonTab(const GURL& page) { |
| 71 chrome::ShowSingletonTab(browser(), page); | 88 chrome::ShowSingletonTab(browser(), page); |
| 72 WebContents* wc = browser()->tab_strip_model()->GetActiveWebContents(); | 89 WebContents* wc = browser()->tab_strip_model()->GetActiveWebContents(); |
| 73 CHECK(wc->GetURL() == page); | 90 CHECK(wc->GetURL() == page); |
| 74 | 91 |
| 75 WaitForLauncherThread(); | 92 WaitForLauncherThread(); |
| 76 WaitForMessageProcessing(wc); | 93 WaitForMessageProcessing(wc); |
| 77 return wc->GetRenderProcessHost()->GetHandle(); | 94 return ProcessFromHandle(wc->GetRenderProcessHost()->GetHandle()); |
| 78 } | 95 } |
| 79 | 96 |
| 80 // Loads the given url in a new background tab and returns the handle of its | 97 // Loads the given url in a new background tab and returns the handle of its |
| 81 // renderer. | 98 // renderer. |
| 82 base::ProcessHandle OpenBackgroundTab(const GURL& page) { | 99 base::Process OpenBackgroundTab(const GURL& page) { |
| 83 ui_test_utils::NavigateToURLWithDisposition(browser(), page, | 100 ui_test_utils::NavigateToURLWithDisposition(browser(), page, |
| 84 NEW_BACKGROUND_TAB, ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); | 101 NEW_BACKGROUND_TAB, ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); |
| 85 | 102 |
| 86 TabStripModel* tab_strip = browser()->tab_strip_model(); | 103 TabStripModel* tab_strip = browser()->tab_strip_model(); |
| 87 WebContents* wc = tab_strip->GetWebContentsAt( | 104 WebContents* wc = tab_strip->GetWebContentsAt( |
| 88 tab_strip->active_index() + 1); | 105 tab_strip->active_index() + 1); |
| 89 CHECK(wc->GetVisibleURL() == page); | 106 CHECK(wc->GetVisibleURL() == page); |
| 90 | 107 |
| 91 WaitForLauncherThread(); | 108 WaitForLauncherThread(); |
| 92 WaitForMessageProcessing(wc); | 109 WaitForMessageProcessing(wc); |
| 93 return wc->GetRenderProcessHost()->GetHandle(); | 110 return ProcessFromHandle(wc->GetRenderProcessHost()->GetHandle()); |
| 94 } | 111 } |
| 95 | 112 |
| 96 // Ensures that the backgrounding / foregrounding gets a chance to run. | 113 // Ensures that the backgrounding / foregrounding gets a chance to run. |
| 97 void WaitForLauncherThread() { | 114 void WaitForLauncherThread() { |
| 98 content::BrowserThread::PostTaskAndReply( | 115 content::BrowserThread::PostTaskAndReply( |
| 99 content::BrowserThread::PROCESS_LAUNCHER, FROM_HERE, | 116 content::BrowserThread::PROCESS_LAUNCHER, FROM_HERE, |
| 100 base::Bind(&base::DoNothing), base::MessageLoop::QuitClosure()); | 117 base::Bind(&base::DoNothing), base::MessageLoop::QuitClosure()); |
| 101 base::MessageLoop::current()->Run(); | 118 base::MessageLoop::current()->Run(); |
| 102 } | 119 } |
| 103 | 120 |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 279 } | 296 } |
| 280 CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess(); | 297 CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess(); |
| 281 parsed_command_line.AppendSwitch(switches::kProcessPerTab); | 298 parsed_command_line.AppendSwitch(switches::kProcessPerTab); |
| 282 | 299 |
| 283 // Change the first tab to be the omnibox page (TYPE_WEBUI). | 300 // Change the first tab to be the omnibox page (TYPE_WEBUI). |
| 284 GURL omnibox(chrome::kChromeUIOmniboxURL); | 301 GURL omnibox(chrome::kChromeUIOmniboxURL); |
| 285 ui_test_utils::NavigateToURL(browser(), omnibox); | 302 ui_test_utils::NavigateToURL(browser(), omnibox); |
| 286 | 303 |
| 287 // Create a new tab. It should be foreground. | 304 // Create a new tab. It should be foreground. |
| 288 GURL page1("data:text/html,hello world1"); | 305 GURL page1("data:text/html,hello world1"); |
| 289 base::ProcessHandle pid1 = ShowSingletonTab(page1); | 306 base::Process process1 = ShowSingletonTab(page1); |
| 290 EXPECT_FALSE(base::Process(pid1).IsProcessBackgrounded()); | 307 ASSERT_TRUE(process1.IsValid()); |
| 308 EXPECT_FALSE(process1.IsProcessBackgrounded()); |
| 291 | 309 |
| 292 // Create another tab. It should be foreground, and the first tab should | 310 // Create another tab. It should be foreground, and the first tab should |
| 293 // now be background. | 311 // now be background. |
| 294 GURL page2("data:text/html,hello world2"); | 312 GURL page2("data:text/html,hello world2"); |
| 295 base::ProcessHandle pid2 = ShowSingletonTab(page2); | 313 base::Process process2 = ShowSingletonTab(page2); |
| 296 EXPECT_NE(pid1, pid2); | 314 ASSERT_TRUE(process2.IsValid()); |
| 297 EXPECT_TRUE(base::Process(pid1).IsProcessBackgrounded()); | 315 EXPECT_NE(process1.pid(), process2.pid()); |
| 298 EXPECT_FALSE(base::Process(pid2).IsProcessBackgrounded()); | 316 EXPECT_TRUE(process1.IsProcessBackgrounded()); |
| 317 EXPECT_FALSE(process2.IsProcessBackgrounded()); |
| 299 | 318 |
| 300 // Load another tab in background. The renderer of the new tab should be | 319 // Load another tab in background. The renderer of the new tab should be |
| 301 // backgrounded, while visibility of the other renderers should not change. | 320 // backgrounded, while visibility of the other renderers should not change. |
| 302 GURL page3("data:text/html,hello world3"); | 321 GURL page3("data:text/html,hello world3"); |
| 303 base::ProcessHandle pid3 = OpenBackgroundTab(page3); | 322 base::Process process3 = OpenBackgroundTab(page3); |
| 304 EXPECT_NE(pid3, pid1); | 323 ASSERT_TRUE(process3.IsValid()); |
| 305 EXPECT_NE(pid3, pid2); | 324 EXPECT_NE(process3.pid(), process1.pid()); |
| 306 EXPECT_TRUE(base::Process(pid1).IsProcessBackgrounded()); | 325 EXPECT_NE(process3.pid(), process2.pid()); |
| 307 EXPECT_FALSE(base::Process(pid2).IsProcessBackgrounded()); | 326 EXPECT_TRUE(process1.IsProcessBackgrounded()); |
| 308 EXPECT_TRUE(base::Process(pid3).IsProcessBackgrounded()); | 327 EXPECT_FALSE(process2.IsProcessBackgrounded()); |
| 328 EXPECT_TRUE(process3.IsProcessBackgrounded()); |
| 309 | 329 |
| 310 // Navigate back to the first page. Its renderer should be in foreground | 330 // Navigate back to the first page. Its renderer should be in foreground |
| 311 // again while the other renderers should be backgrounded. | 331 // again while the other renderers should be backgrounded. |
| 312 EXPECT_EQ(pid1, ShowSingletonTab(page1)); | 332 EXPECT_EQ(process1.pid(), ShowSingletonTab(page1).pid()); |
| 313 EXPECT_FALSE(base::Process(pid1).IsProcessBackgrounded()); | 333 EXPECT_FALSE(process1.IsProcessBackgrounded()); |
| 314 EXPECT_TRUE(base::Process(pid2).IsProcessBackgrounded()); | 334 EXPECT_TRUE(process2.IsProcessBackgrounded()); |
| 315 EXPECT_TRUE(base::Process(pid3).IsProcessBackgrounded()); | 335 EXPECT_TRUE(process3.IsProcessBackgrounded()); |
| 316 } | 336 } |
| 317 #endif | 337 #endif |
| 318 | 338 |
| 319 // TODO(nasko): crbug.com/173137 | 339 // TODO(nasko): crbug.com/173137 |
| 320 #if defined(OS_WIN) | 340 #if defined(OS_WIN) |
| 321 #define MAYBE_ProcessOverflow DISABLED_ProcessOverflow | 341 #define MAYBE_ProcessOverflow DISABLED_ProcessOverflow |
| 322 #else | 342 #else |
| 323 #define MAYBE_ProcessOverflow ProcessOverflow | 343 #define MAYBE_ProcessOverflow ProcessOverflow |
| 324 #endif | 344 #endif |
| 325 | 345 |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 487 chrome::NOTIFICATION_BROWSER_CLOSED, | 507 chrome::NOTIFICATION_BROWSER_CLOSED, |
| 488 content::NotificationService::AllSources()); | 508 content::NotificationService::AllSources()); |
| 489 | 509 |
| 490 // Kill the renderer process, simulating a crash. This should the ProcessDied | 510 // Kill the renderer process, simulating a crash. This should the ProcessDied |
| 491 // method to be called. Alternatively, RenderProcessHost::OnChannelError can | 511 // method to be called. Alternatively, RenderProcessHost::OnChannelError can |
| 492 // be called to directly force a call to ProcessDied. | 512 // be called to directly force a call to ProcessDied. |
| 493 base::KillProcess(wc1->GetRenderProcessHost()->GetHandle(), -1, true); | 513 base::KillProcess(wc1->GetRenderProcessHost()->GetHandle(), -1, true); |
| 494 | 514 |
| 495 observer.Wait(); | 515 observer.Wait(); |
| 496 } | 516 } |
| OLD | NEW |