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 <deque> | 5 #include <deque> |
6 #include <vector> | 6 #include <vector> |
7 | 7 |
8 #include "base/bind.h" | 8 #include "base/bind.h" |
9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
10 #include "base/files/file_path.h" | 10 #include "base/files/file_path.h" |
(...skipping 28 matching lines...) Expand all Loading... |
39 #include "chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.
h" | 39 #include "chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.
h" |
40 #include "chrome/browser/safe_browsing/database_manager.h" | 40 #include "chrome/browser/safe_browsing/database_manager.h" |
41 #include "chrome/browser/safe_browsing/safe_browsing_service.h" | 41 #include "chrome/browser/safe_browsing/safe_browsing_service.h" |
42 #include "chrome/browser/safe_browsing/safe_browsing_util.h" | 42 #include "chrome/browser/safe_browsing/safe_browsing_util.h" |
43 #include "chrome/browser/task_manager/task_manager.h" | 43 #include "chrome/browser/task_manager/task_manager.h" |
44 #include "chrome/browser/task_manager/task_manager_browsertest_util.h" | 44 #include "chrome/browser/task_manager/task_manager_browsertest_util.h" |
45 #include "chrome/browser/ui/browser.h" | 45 #include "chrome/browser/ui/browser.h" |
46 #include "chrome/browser/ui/browser_commands.h" | 46 #include "chrome/browser/ui/browser_commands.h" |
47 #include "chrome/browser/ui/browser_finder.h" | 47 #include "chrome/browser/ui/browser_finder.h" |
48 #include "chrome/browser/ui/browser_navigator.h" | 48 #include "chrome/browser/ui/browser_navigator.h" |
| 49 #include "chrome/browser/ui/browser_tabstrip.h" |
49 #include "chrome/browser/ui/browser_window.h" | 50 #include "chrome/browser/ui/browser_window.h" |
50 #include "chrome/browser/ui/tabs/tab_strip_model.h" | 51 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
51 #include "chrome/browser/ui/tabs/tab_strip_model_observer.h" | 52 #include "chrome/browser/ui/tabs/tab_strip_model_observer.h" |
52 #include "chrome/common/chrome_paths.h" | 53 #include "chrome/common/chrome_paths.h" |
53 #include "chrome/common/chrome_switches.h" | 54 #include "chrome/common/chrome_switches.h" |
54 #include "chrome/common/extensions/extension_constants.h" | 55 #include "chrome/common/extensions/extension_constants.h" |
55 #include "chrome/common/extensions/mime_types_handler.h" | 56 #include "chrome/common/extensions/mime_types_handler.h" |
56 #include "chrome/common/pref_names.h" | 57 #include "chrome/common/pref_names.h" |
57 #include "chrome/test/base/in_process_browser_test.h" | 58 #include "chrome/test/base/in_process_browser_test.h" |
58 #include "chrome/test/base/test_switches.h" | 59 #include "chrome/test/base/test_switches.h" |
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
315 base::RunLoop loop_; | 316 base::RunLoop loop_; |
316 }; | 317 }; |
317 | 318 |
318 // Waits for a new tab to open and a navigation or swap in it. | 319 // Waits for a new tab to open and a navigation or swap in it. |
319 class NewTabNavigationOrSwapObserver { | 320 class NewTabNavigationOrSwapObserver { |
320 public: | 321 public: |
321 NewTabNavigationOrSwapObserver() | 322 NewTabNavigationOrSwapObserver() |
322 : new_tab_observer_( | 323 : new_tab_observer_( |
323 chrome::NOTIFICATION_TAB_ADDED, | 324 chrome::NOTIFICATION_TAB_ADDED, |
324 base::Bind(&NewTabNavigationOrSwapObserver::OnTabAdded, | 325 base::Bind(&NewTabNavigationOrSwapObserver::OnTabAdded, |
325 base::Unretained(this))) { | 326 base::Unretained(this))), |
| 327 new_tab_(NULL) { |
326 // Watch for NOTIFICATION_TAB_ADDED. Add a callback so that the | 328 // Watch for NOTIFICATION_TAB_ADDED. Add a callback so that the |
327 // NavigationOrSwapObserver can be attached synchronously and no events are | 329 // NavigationOrSwapObserver can be attached synchronously and no events are |
328 // missed. | 330 // missed. |
329 } | 331 } |
330 | 332 |
| 333 WebContents* new_tab() const { |
| 334 return new_tab_; |
| 335 } |
| 336 |
331 void Wait() { | 337 void Wait() { |
332 new_tab_observer_.Wait(); | 338 new_tab_observer_.Wait(); |
333 swap_observer_->Wait(); | 339 swap_observer_->Wait(); |
334 } | 340 } |
335 | 341 |
336 bool OnTabAdded(const content::NotificationSource& source, | 342 bool OnTabAdded(const content::NotificationSource& source, |
337 const content::NotificationDetails& details) { | 343 const content::NotificationDetails& details) { |
338 if (swap_observer_) | 344 if (swap_observer_) |
339 return true; | 345 return true; |
340 WebContents* new_tab = content::Details<WebContents>(details).ptr(); | 346 new_tab_ = content::Details<WebContents>(details).ptr(); |
341 // Get the TabStripModel. Assume this is attached to a Browser. | 347 // Get the TabStripModel. Assume this is attached to a Browser. |
342 TabStripModel* tab_strip_model = | 348 TabStripModel* tab_strip_model = |
343 static_cast<Browser*>(new_tab->GetDelegate())->tab_strip_model(); | 349 static_cast<Browser*>(new_tab_->GetDelegate())->tab_strip_model(); |
344 swap_observer_.reset(new NavigationOrSwapObserver(tab_strip_model, | 350 swap_observer_.reset(new NavigationOrSwapObserver(tab_strip_model, |
345 new_tab)); | 351 new_tab_)); |
346 return true; | 352 return true; |
347 } | 353 } |
348 | 354 |
349 private: | 355 private: |
350 content::WindowedNotificationObserver new_tab_observer_; | 356 content::WindowedNotificationObserver new_tab_observer_; |
| 357 WebContents* new_tab_; |
351 scoped_ptr<NavigationOrSwapObserver> swap_observer_; | 358 scoped_ptr<NavigationOrSwapObserver> swap_observer_; |
352 }; | 359 }; |
353 | 360 |
354 // PrerenderContents that stops the UI message loop on DidStopLoading(). | 361 // PrerenderContents that stops the UI message loop on DidStopLoading(). |
355 class TestPrerenderContents : public PrerenderContents { | 362 class TestPrerenderContents : public PrerenderContents { |
356 public: | 363 public: |
357 TestPrerenderContents( | 364 TestPrerenderContents( |
358 PrerenderManager* prerender_manager, | 365 PrerenderManager* prerender_manager, |
359 Profile* profile, | 366 Profile* profile, |
360 const GURL& url, | 367 const GURL& url, |
(...skipping 787 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1148 } | 1155 } |
1149 | 1156 |
1150 void OpenDestURLViaClick() const { | 1157 void OpenDestURLViaClick() const { |
1151 OpenURLViaClick(dest_url_); | 1158 OpenURLViaClick(dest_url_); |
1152 } | 1159 } |
1153 | 1160 |
1154 void OpenURLViaClick(const GURL& url) const { | 1161 void OpenURLViaClick(const GURL& url) const { |
1155 OpenURLWithJSImpl("Click", url, GURL(), false); | 1162 OpenURLWithJSImpl("Click", url, GURL(), false); |
1156 } | 1163 } |
1157 | 1164 |
1158 void OpenDestURLViaClickTarget() const { | 1165 WebContents* OpenDestURLViaClickTarget() const { |
1159 OpenURLWithJSImpl("ClickTarget", dest_url_, GURL(), true); | 1166 return OpenURLWithJSImpl("ClickTarget", dest_url_, GURL(), true); |
1160 } | 1167 } |
1161 | 1168 |
1162 void OpenDestURLViaClickPing(const GURL& ping_url) const { | 1169 void OpenDestURLViaClickPing(const GURL& ping_url) const { |
1163 OpenURLWithJSImpl("ClickPing", dest_url_, ping_url, false); | 1170 OpenURLWithJSImpl("ClickPing", dest_url_, ping_url, false); |
1164 } | 1171 } |
1165 | 1172 |
1166 void OpenDestURLViaClickNewWindow() const { | 1173 WebContents* OpenDestURLViaClickNewWindow() const { |
1167 OpenURLWithJSImpl("ShiftClick", dest_url_, GURL(), true); | 1174 return OpenURLWithJSImpl("ShiftClick", dest_url_, GURL(), true); |
1168 } | 1175 } |
1169 | 1176 |
1170 void OpenDestURLViaClickNewForegroundTab() const { | 1177 WebContents* OpenDestURLViaClickNewForegroundTab() const { |
1171 #if defined(OS_MACOSX) | 1178 #if defined(OS_MACOSX) |
1172 OpenURLWithJSImpl("MetaShiftClick", dest_url_, GURL(), true); | 1179 return OpenURLWithJSImpl("MetaShiftClick", dest_url_, GURL(), true); |
1173 #else | 1180 #else |
1174 OpenURLWithJSImpl("CtrlShiftClick", dest_url_, GURL(), true); | 1181 return OpenURLWithJSImpl("CtrlShiftClick", dest_url_, GURL(), true); |
1175 #endif | 1182 #endif |
1176 } | 1183 } |
1177 | 1184 |
1178 void OpenDestURLViaClickNewBackgroundTab() const { | 1185 WebContents* OpenDestURLViaClickNewBackgroundTab() const { |
1179 #if defined(OS_MACOSX) | 1186 #if defined(OS_MACOSX) |
1180 OpenURLWithJSImpl("MetaClick", dest_url_, GURL(), true); | 1187 return OpenURLWithJSImpl("MetaClick", dest_url_, GURL(), true); |
1181 #else | 1188 #else |
1182 OpenURLWithJSImpl("CtrlClick", dest_url_, GURL(), true); | 1189 return OpenURLWithJSImpl("CtrlClick", dest_url_, GURL(), true); |
1183 #endif | 1190 #endif |
1184 } | 1191 } |
1185 | 1192 |
1186 void OpenDestURLViaWindowOpen() const { | 1193 WebContents* OpenDestURLViaWindowOpen() const { |
1187 OpenURLWithJSImpl("WindowOpen", dest_url_, GURL(), true); | 1194 return OpenURLViaWindowOpen(dest_url_); |
| 1195 } |
| 1196 |
| 1197 WebContents* OpenURLViaWindowOpen(const GURL& url) const { |
| 1198 return OpenURLWithJSImpl("WindowOpen", url, GURL(), true); |
1188 } | 1199 } |
1189 | 1200 |
1190 void RemoveLinkElement(int i) const { | 1201 void RemoveLinkElement(int i) const { |
1191 GetActiveWebContents()->GetMainFrame()->ExecuteJavaScript( | 1202 GetActiveWebContents()->GetMainFrame()->ExecuteJavaScript( |
1192 base::ASCIIToUTF16(base::StringPrintf("RemoveLinkElement(%d)", i))); | 1203 base::ASCIIToUTF16(base::StringPrintf("RemoveLinkElement(%d)", i))); |
1193 } | 1204 } |
1194 | 1205 |
1195 void ClickToNextPageAfterPrerender() { | 1206 void ClickToNextPageAfterPrerender() { |
1196 TestNavigationObserver nav_observer(GetActiveWebContents()); | 1207 TestNavigationObserver nav_observer(GetActiveWebContents()); |
1197 RenderFrameHost* render_frame_host = GetActiveWebContents()->GetMainFrame(); | 1208 RenderFrameHost* render_frame_host = GetActiveWebContents()->GetMainFrame(); |
(...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1573 | 1584 |
1574 if (web_contents && expect_swap_to_succeed) { | 1585 if (web_contents && expect_swap_to_succeed) { |
1575 EXPECT_EQ(web_contents, target_web_contents); | 1586 EXPECT_EQ(web_contents, target_web_contents); |
1576 if (call_javascript_) | 1587 if (call_javascript_) |
1577 EXPECT_TRUE(DidDisplayPass(web_contents)); | 1588 EXPECT_TRUE(DidDisplayPass(web_contents)); |
1578 } | 1589 } |
1579 } | 1590 } |
1580 | 1591 |
1581 // Opens the prerendered page using javascript functions in the loader | 1592 // Opens the prerendered page using javascript functions in the loader |
1582 // page. |javascript_function_name| should be a 0 argument function which is | 1593 // page. |javascript_function_name| should be a 0 argument function which is |
1583 // invoked. |new_web_contents| is true if the navigation is expected to | 1594 // invoked. |new_web_contents| is true if the navigation is expected to happen |
1584 // happen in a new WebContents via OpenURL. | 1595 // in a new WebContents via OpenURL and the new WebContents is returned. |
1585 void OpenURLWithJSImpl(const std::string& javascript_function_name, | 1596 WebContents* OpenURLWithJSImpl(const std::string& javascript_function_name, |
1586 const GURL& url, | 1597 const GURL& url, |
1587 const GURL& ping_url, | 1598 const GURL& ping_url, |
1588 bool new_web_contents) const { | 1599 bool new_web_contents) const { |
1589 WebContents* web_contents = GetActiveWebContents(); | 1600 WebContents* web_contents = GetActiveWebContents(); |
1590 RenderFrameHost* render_frame_host = web_contents->GetMainFrame(); | 1601 RenderFrameHost* render_frame_host = web_contents->GetMainFrame(); |
1591 // Extra arguments in JS are ignored. | 1602 // Extra arguments in JS are ignored. |
1592 std::string javascript = base::StringPrintf( | 1603 std::string javascript = base::StringPrintf( |
1593 "%s('%s', '%s')", javascript_function_name.c_str(), | 1604 "%s('%s', '%s')", javascript_function_name.c_str(), |
1594 url.spec().c_str(), ping_url.spec().c_str()); | 1605 url.spec().c_str(), ping_url.spec().c_str()); |
1595 | 1606 |
1596 if (new_web_contents) { | 1607 if (new_web_contents) { |
1597 NewTabNavigationOrSwapObserver observer; | 1608 NewTabNavigationOrSwapObserver observer; |
1598 render_frame_host->ExecuteJavaScript(base::ASCIIToUTF16(javascript)); | 1609 render_frame_host->ExecuteJavaScript(base::ASCIIToUTF16(javascript)); |
1599 observer.Wait(); | 1610 observer.Wait(); |
| 1611 return observer.new_tab(); |
1600 } else { | 1612 } else { |
1601 NavigationOrSwapObserver observer(current_browser()->tab_strip_model(), | 1613 NavigationOrSwapObserver observer(current_browser()->tab_strip_model(), |
1602 web_contents); | 1614 web_contents); |
1603 render_frame_host->ExecuteJavaScript(base::ASCIIToUTF16(javascript)); | 1615 render_frame_host->ExecuteJavaScript(base::ASCIIToUTF16(javascript)); |
1604 observer.Wait(); | 1616 observer.Wait(); |
| 1617 return NULL; |
1605 } | 1618 } |
1606 } | 1619 } |
1607 | 1620 |
1608 TestPrerenderContentsFactory* prerender_contents_factory_; | 1621 TestPrerenderContentsFactory* prerender_contents_factory_; |
1609 #if defined(FULL_SAFE_BROWSING) | 1622 #if defined(FULL_SAFE_BROWSING) |
1610 scoped_ptr<TestSafeBrowsingServiceFactory> safe_browsing_factory_; | 1623 scoped_ptr<TestSafeBrowsingServiceFactory> safe_browsing_factory_; |
1611 #endif | 1624 #endif |
1612 NeverRunsExternalProtocolHandlerDelegate external_protocol_handler_delegate_; | 1625 NeverRunsExternalProtocolHandlerDelegate external_protocol_handler_delegate_; |
1613 GURL dest_url_; | 1626 GURL dest_url_; |
1614 scoped_ptr<net::SpawnedTestServer> https_src_server_; | 1627 scoped_ptr<net::SpawnedTestServer> https_src_server_; |
(...skipping 1247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2862 // and both pages are in the same domain the prerendered page is not used, due | 2875 // and both pages are in the same domain the prerendered page is not used, due |
2863 // to window.opener. | 2876 // to window.opener. |
2864 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, | 2877 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, |
2865 PrerenderSameDomainWindowOpenerClickTarget) { | 2878 PrerenderSameDomainWindowOpenerClickTarget) { |
2866 PrerenderTestURL("files/prerender/prerender_page.html", | 2879 PrerenderTestURL("files/prerender/prerender_page.html", |
2867 FINAL_STATUS_WINDOW_OPENER, | 2880 FINAL_STATUS_WINDOW_OPENER, |
2868 1); | 2881 1); |
2869 OpenDestURLViaClickTarget(); | 2882 OpenDestURLViaClickTarget(); |
2870 } | 2883 } |
2871 | 2884 |
| 2885 // Checks that, if a popup's opener is closed, it still will not accept |
| 2886 // prerender swaps. This is relevant in determining whether window.close() may |
| 2887 // be called. |
| 2888 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderOpenerClosed) { |
| 2889 // Bump the abandon timeout to ensure the prerender survives its referrer |
| 2890 // closing. |
| 2891 GetPrerenderManager()->mutable_config().abandon_time_to_live = |
| 2892 base::TimeDelta::FromMinutes(5); |
| 2893 |
| 2894 PrerenderTestURL("files/prerender/prerender_page.html", |
| 2895 FINAL_STATUS_WINDOW_OPENER, |
| 2896 1); |
| 2897 |
| 2898 // Open a popup with the referring page as opener. |
| 2899 WebContents* opener = GetActiveWebContents(); |
| 2900 WebContents* popup = OpenURLViaWindowOpen(GURL(content::kAboutBlankURL)); |
| 2901 |
| 2902 // Close the opener. The opener is gone, but WasOpenedByDOM() remains true. |
| 2903 EXPECT_TRUE(popup->HasOpener()); |
| 2904 EXPECT_TRUE(popup->CreatedWithOpener()); |
| 2905 chrome::CloseWebContents(browser(), opener, false); |
| 2906 EXPECT_FALSE(popup->HasOpener()); |
| 2907 EXPECT_TRUE(popup->CreatedWithOpener()); |
| 2908 |
| 2909 // Assume the popup is attached to a Browser. |
| 2910 set_browser(static_cast<Browser*>(popup->GetDelegate())); |
| 2911 |
| 2912 // The prerender should not swap. |
| 2913 NavigateToURLWithDisposition(dest_url(), CURRENT_TAB, false); |
| 2914 } |
| 2915 |
2872 class TestClientCertStore : public net::ClientCertStore { | 2916 class TestClientCertStore : public net::ClientCertStore { |
2873 public: | 2917 public: |
2874 TestClientCertStore() {} | 2918 TestClientCertStore() {} |
2875 virtual ~TestClientCertStore() {} | 2919 virtual ~TestClientCertStore() {} |
2876 | 2920 |
2877 // net::ClientCertStore: | 2921 // net::ClientCertStore: |
2878 virtual void GetClientCerts(const net::SSLCertRequestInfo& cert_request_info, | 2922 virtual void GetClientCerts(const net::SSLCertRequestInfo& cert_request_info, |
2879 net::CertificateList* selected_certs, | 2923 net::CertificateList* selected_certs, |
2880 const base::Closure& callback) OVERRIDE { | 2924 const base::Closure& callback) OVERRIDE { |
2881 *selected_certs = net::CertificateList( | 2925 *selected_certs = net::CertificateList( |
(...skipping 1291 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4173 } | 4217 } |
4174 }; | 4218 }; |
4175 | 4219 |
4176 // Checks that prerendering works in incognito mode. | 4220 // Checks that prerendering works in incognito mode. |
4177 IN_PROC_BROWSER_TEST_F(PrerenderIncognitoBrowserTest, PrerenderIncognito) { | 4221 IN_PROC_BROWSER_TEST_F(PrerenderIncognitoBrowserTest, PrerenderIncognito) { |
4178 PrerenderTestURL("files/prerender/prerender_page.html", FINAL_STATUS_USED, 1); | 4222 PrerenderTestURL("files/prerender/prerender_page.html", FINAL_STATUS_USED, 1); |
4179 NavigateToDestURL(); | 4223 NavigateToDestURL(); |
4180 } | 4224 } |
4181 | 4225 |
4182 } // namespace prerender | 4226 } // namespace prerender |
OLD | NEW |