Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 <stddef.h> | 5 #include <stddef.h> |
| 6 #include <stdint.h> | 6 #include <stdint.h> |
| 7 | 7 |
| 8 #include <set> | 8 #include <set> |
| 9 | 9 |
| 10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 27 #include "content/browser/webui/web_ui_impl.h" | 27 #include "content/browser/webui/web_ui_impl.h" |
| 28 #include "content/common/content_constants_internal.h" | 28 #include "content/common/content_constants_internal.h" |
| 29 #include "content/common/input_messages.h" | 29 #include "content/common/input_messages.h" |
| 30 #include "content/common/site_isolation_policy.h" | 30 #include "content/common/site_isolation_policy.h" |
| 31 #include "content/public/browser/navigation_controller.h" | 31 #include "content/public/browser/navigation_controller.h" |
| 32 #include "content/public/browser/navigation_entry.h" | 32 #include "content/public/browser/navigation_entry.h" |
| 33 #include "content/public/browser/render_process_host.h" | 33 #include "content/public/browser/render_process_host.h" |
| 34 #include "content/public/browser/resource_dispatcher_host.h" | 34 #include "content/public/browser/resource_dispatcher_host.h" |
| 35 #include "content/public/browser/web_contents.h" | 35 #include "content/public/browser/web_contents.h" |
| 36 #include "content/public/browser/web_contents_observer.h" | 36 #include "content/public/browser/web_contents_observer.h" |
| 37 #include "content/public/browser/web_ui_message_handler.h" | |
| 37 #include "content/public/common/bindings_policy.h" | 38 #include "content/public/common/bindings_policy.h" |
| 38 #include "content/public/common/browser_side_navigation_policy.h" | 39 #include "content/public/common/browser_side_navigation_policy.h" |
| 39 #include "content/public/common/content_switches.h" | 40 #include "content/public/common/content_switches.h" |
| 40 #include "content/public/common/file_chooser_file_info.h" | 41 #include "content/public/common/file_chooser_file_info.h" |
| 41 #include "content/public/common/file_chooser_params.h" | 42 #include "content/public/common/file_chooser_params.h" |
| 42 #include "content/public/common/page_state.h" | 43 #include "content/public/common/page_state.h" |
| 43 #include "content/public/common/url_constants.h" | 44 #include "content/public/common/url_constants.h" |
| 44 #include "content/public/test/browser_test_utils.h" | 45 #include "content/public/test/browser_test_utils.h" |
| 45 #include "content/public/test/content_browser_test.h" | 46 #include "content/public/test/content_browser_test.h" |
| 46 #include "content/public/test/content_browser_test_utils.h" | 47 #include "content/public/test/content_browser_test_utils.h" |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 68 " document.body.appendChild(lnk);\n" | 69 " document.body.appendChild(lnk);\n" |
| 69 " lnk.click();\n" | 70 " lnk.click();\n" |
| 70 "})"; | 71 "})"; |
| 71 | 72 |
| 72 // Adds a link with given url and target=_blank, and clicks on it. | 73 // Adds a link with given url and target=_blank, and clicks on it. |
| 73 void OpenUrlViaClickTarget(const ToRenderFrameHost& adapter, const GURL& url) { | 74 void OpenUrlViaClickTarget(const ToRenderFrameHost& adapter, const GURL& url) { |
| 74 EXPECT_TRUE(ExecuteScript(adapter, | 75 EXPECT_TRUE(ExecuteScript(adapter, |
| 75 std::string(kOpenUrlViaClickTargetFunc) + "(\"" + url.spec() + "\");")); | 76 std::string(kOpenUrlViaClickTargetFunc) + "(\"" + url.spec() + "\");")); |
| 76 } | 77 } |
| 77 | 78 |
| 79 class TestWebUIMessageHandler : public WebUIMessageHandler { | |
| 80 public: | |
| 81 using WebUIMessageHandler::AllowJavascript; | |
| 82 using WebUIMessageHandler::IsJavascriptAllowed; | |
| 83 | |
| 84 protected: | |
| 85 void RegisterMessages() override {} | |
| 86 }; | |
| 87 | |
| 88 // This class implements waiting for RenderFrameHost destruction. It relies on | |
| 89 // the fact that RenderFrameDeleted event is fired when RenderFrameHost is | |
| 90 // destroyed. | |
| 91 // Note: RenderFrameDeleted is also fired when the process associated with the | |
| 92 // RenderFrameHost crashes, so this cannot be used in cases where process dying | |
| 93 // is expected. | |
| 94 class RenderFrameHostDestructionObserver : public WebContentsObserver { | |
| 95 public: | |
| 96 explicit RenderFrameHostDestructionObserver(RenderFrameHost* rfh) | |
| 97 : WebContentsObserver(WebContents::FromRenderFrameHost(rfh)), | |
| 98 message_loop_runner_(new MessageLoopRunner), | |
| 99 deleted_(false), | |
| 100 render_frame_host_(rfh) {} | |
| 101 ~RenderFrameHostDestructionObserver() override {} | |
| 102 | |
| 103 bool deleted() const { return deleted_; } | |
| 104 | |
| 105 void Wait() { | |
| 106 if (deleted_) | |
| 107 return; | |
| 108 | |
| 109 message_loop_runner_->Run(); | |
| 110 } | |
| 111 | |
| 112 // WebContentsObserver implementation: | |
| 113 void RenderFrameDeleted(RenderFrameHost* rfh) override { | |
| 114 if (rfh == render_frame_host_) { | |
| 115 CHECK(!deleted_); | |
| 116 deleted_ = true; | |
| 117 } | |
| 118 | |
| 119 if (deleted_ && message_loop_runner_->loop_running()) { | |
| 120 base::ThreadTaskRunnerHandle::Get()->PostTask( | |
| 121 FROM_HERE, message_loop_runner_->QuitClosure()); | |
| 122 } | |
| 123 } | |
| 124 | |
| 125 private: | |
| 126 scoped_refptr<MessageLoopRunner> message_loop_runner_; | |
| 127 bool deleted_; | |
| 128 RenderFrameHost* render_frame_host_; | |
| 129 }; | |
| 130 | |
| 78 } // anonymous namespace | 131 } // anonymous namespace |
| 79 | 132 |
| 80 class RenderFrameHostManagerTest : public ContentBrowserTest { | 133 class RenderFrameHostManagerTest : public ContentBrowserTest { |
| 81 public: | 134 public: |
| 82 RenderFrameHostManagerTest() : foo_com_("foo.com") { | 135 RenderFrameHostManagerTest() : foo_com_("foo.com") { |
| 83 replace_host_.SetHostStr(foo_com_); | 136 replace_host_.SetHostStr(foo_com_); |
| 84 } | 137 } |
| 85 | 138 |
| 86 static void GetFilePathWithHostAndPortReplacement( | 139 static void GetFilePathWithHostAndPortReplacement( |
| 87 const std::string& original_file_path, | 140 const std::string& original_file_path, |
| (...skipping 1722 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1810 | 1863 |
| 1811 EXPECT_TRUE(NavigateToURL(shell(), GURL(url::kAboutBlankURL))); | 1864 EXPECT_TRUE(NavigateToURL(shell(), GURL(url::kAboutBlankURL))); |
| 1812 EXPECT_NE(orig_site_instance, shell()->web_contents()->GetSiteInstance()); | 1865 EXPECT_NE(orig_site_instance, shell()->web_contents()->GetSiteInstance()); |
| 1813 | 1866 |
| 1814 GURL regular_page_url(embedded_test_server()->GetURL("/title2.html")); | 1867 GURL regular_page_url(embedded_test_server()->GetURL("/title2.html")); |
| 1815 EXPECT_TRUE(NavigateToURL(shell(), regular_page_url)); | 1868 EXPECT_TRUE(NavigateToURL(shell(), regular_page_url)); |
| 1816 EXPECT_FALSE(ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings( | 1869 EXPECT_FALSE(ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings( |
| 1817 shell()->web_contents()->GetRenderProcessHost()->GetID())); | 1870 shell()->web_contents()->GetRenderProcessHost()->GetID())); |
| 1818 } | 1871 } |
| 1819 | 1872 |
| 1873 // crbug.com/615274 | |
| 1874 // This test ensures that after an RVH is swapped out, the associated WebUI | |
|
Charlie Reis
2016/06/08 20:57:11
nit: RFH
tommycli
2016/06/08 22:52:34
Done.
| |
| 1875 // instance is no longer allowed to send JavaScript messages. This is necessary | |
| 1876 // because WebUI currently (and unusually) always sends JavaScript messages to | |
| 1877 // the current main frame, rather than the RVH that owns the WebUI. | |
|
Charlie Reis
2016/06/08 20:57:11
nit: RFH
tommycli
2016/06/08 22:52:34
Done.
| |
| 1878 IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest, | |
| 1879 WebUIJavascriptDisallowedAfterSwapOut) { | |
| 1880 StartEmbeddedServer(); | |
| 1881 | |
| 1882 const GURL web_ui_url(std::string(kChromeUIScheme) + "://" + | |
| 1883 std::string(kChromeUIGpuHost)); | |
| 1884 EXPECT_TRUE(NavigateToURL(shell(), web_ui_url)); | |
| 1885 | |
| 1886 RenderFrameHostImpl* rfh = | |
| 1887 static_cast<WebContentsImpl*>(shell()->web_contents())->GetMainFrame(); | |
| 1888 WebUIImpl* web_ui = rfh->web_ui(); | |
| 1889 | |
| 1890 EXPECT_TRUE(web_ui->CanCallJavascript()); | |
| 1891 TestWebUIMessageHandler* handler = new TestWebUIMessageHandler(); | |
| 1892 | |
| 1893 web_ui->AddMessageHandler(handler); | |
| 1894 EXPECT_FALSE(handler->IsJavascriptAllowed()); | |
| 1895 | |
| 1896 handler->AllowJavascript(); | |
| 1897 EXPECT_TRUE(handler->IsJavascriptAllowed()); | |
| 1898 | |
| 1899 rfh->DisableSwapOutTimerForTesting(); | |
| 1900 RenderFrameHostDestructionObserver rfh_observer(rfh); | |
| 1901 | |
| 1902 // Navigate, but wait for commit, not the actual load to finish. | |
| 1903 SiteInstanceImpl* web_ui_site_instance = rfh->GetSiteInstance(); | |
| 1904 FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) | |
| 1905 ->GetFrameTree() | |
| 1906 ->root(); | |
| 1907 TestFrameNavigationObserver commit_observer(root); | |
| 1908 shell()->LoadURL(GURL(url::kAboutBlankURL)); | |
| 1909 commit_observer.WaitForCommit(); | |
| 1910 EXPECT_NE(web_ui_site_instance, shell()->web_contents()->GetSiteInstance()); | |
| 1911 EXPECT_TRUE( | |
| 1912 root->render_manager()->GetRenderFrameProxyHost(web_ui_site_instance)); | |
| 1913 | |
| 1914 // The previous RFH should still be pending deletion, as we wait for either | |
| 1915 // the SwapOut ACK or a timeout. | |
| 1916 ASSERT_TRUE(rfh->IsRenderFrameLive()); | |
|
Charlie Reis
2016/06/08 20:57:11
I think this part will be flaky unless we guarante
tommycli
2016/06/08 22:52:34
Done.
| |
| 1917 ASSERT_FALSE(rfh->is_active()); | |
| 1918 | |
| 1919 // We specifically want verify behavior between swap-out and RFH destruction. | |
| 1920 ASSERT_FALSE(rfh_observer.deleted()); | |
| 1921 | |
| 1922 EXPECT_FALSE(handler->IsJavascriptAllowed()); | |
| 1923 } | |
| 1924 | |
| 1820 class FileChooserDelegate : public WebContentsDelegate { | 1925 class FileChooserDelegate : public WebContentsDelegate { |
| 1821 public: | 1926 public: |
| 1822 FileChooserDelegate(const base::FilePath& file) | 1927 FileChooserDelegate(const base::FilePath& file) |
| 1823 : file_(file), file_chosen_(false) {} | 1928 : file_(file), file_chosen_(false) {} |
| 1824 | 1929 |
| 1825 void RunFileChooser(WebContents* web_contents, | 1930 void RunFileChooser(WebContents* web_contents, |
| 1826 const FileChooserParams& params) override { | 1931 const FileChooserParams& params) override { |
| 1827 // Send the selected file to the renderer process. | 1932 // Send the selected file to the renderer process. |
| 1828 FileChooserFileInfo file_info; | 1933 FileChooserFileInfo file_info; |
| 1829 file_info.file_path = file_; | 1934 file_info.file_path = file_; |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1952 shell()->web_contents()->GetController().GoBack(); | 2057 shell()->web_contents()->GetController().GoBack(); |
| 1953 back_nav_load_observer.Wait(); | 2058 back_nav_load_observer.Wait(); |
| 1954 EXPECT_NE(process_id, | 2059 EXPECT_NE(process_id, |
| 1955 shell()->web_contents()->GetRenderProcessHost()->GetID()); | 2060 shell()->web_contents()->GetRenderProcessHost()->GetID()); |
| 1956 | 2061 |
| 1957 // Ensure that the file access still exists in the new process ID. | 2062 // Ensure that the file access still exists in the new process ID. |
| 1958 EXPECT_TRUE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile( | 2063 EXPECT_TRUE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile( |
| 1959 shell()->web_contents()->GetRenderProcessHost()->GetID(), file)); | 2064 shell()->web_contents()->GetRenderProcessHost()->GetID(), file)); |
| 1960 } | 2065 } |
| 1961 | 2066 |
| 1962 // This class implements waiting for RenderFrameHost destruction. It relies on | |
| 1963 // the fact that RenderFrameDeleted event is fired when RenderFrameHost is | |
| 1964 // destroyed. | |
| 1965 // Note: RenderFrameDeleted is also fired when the process associated with the | |
| 1966 // RenderFrameHost crashes, so this cannot be used in cases where process dying | |
| 1967 // is expected. | |
| 1968 class RenderFrameHostDestructionObserver : public WebContentsObserver { | |
| 1969 public: | |
| 1970 explicit RenderFrameHostDestructionObserver(RenderFrameHost* rfh) | |
| 1971 : WebContentsObserver(WebContents::FromRenderFrameHost(rfh)), | |
| 1972 message_loop_runner_(new MessageLoopRunner), | |
| 1973 deleted_(false), | |
| 1974 render_frame_host_(rfh) {} | |
| 1975 ~RenderFrameHostDestructionObserver() override {} | |
| 1976 | |
| 1977 void Wait() { | |
| 1978 if (deleted_) | |
| 1979 return; | |
| 1980 | |
| 1981 message_loop_runner_->Run(); | |
| 1982 } | |
| 1983 | |
| 1984 // WebContentsObserver implementation: | |
| 1985 void RenderFrameDeleted(RenderFrameHost* rfh) override { | |
| 1986 if (rfh == render_frame_host_) { | |
| 1987 CHECK(!deleted_); | |
| 1988 deleted_ = true; | |
| 1989 } | |
| 1990 | |
| 1991 if (deleted_ && message_loop_runner_->loop_running()) { | |
| 1992 base::ThreadTaskRunnerHandle::Get()->PostTask( | |
| 1993 FROM_HERE, message_loop_runner_->QuitClosure()); | |
| 1994 } | |
| 1995 } | |
| 1996 | |
| 1997 private: | |
| 1998 scoped_refptr<MessageLoopRunner> message_loop_runner_; | |
| 1999 bool deleted_; | |
| 2000 RenderFrameHost* render_frame_host_; | |
| 2001 }; | |
| 2002 | |
| 2003 // Ensures that no RenderFrameHost/RenderViewHost objects are leaked when | 2067 // Ensures that no RenderFrameHost/RenderViewHost objects are leaked when |
| 2004 // doing a simple cross-process navigation. | 2068 // doing a simple cross-process navigation. |
| 2005 IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest, | 2069 IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest, |
| 2006 CleanupOnCrossProcessNavigation) { | 2070 CleanupOnCrossProcessNavigation) { |
| 2007 StartEmbeddedServer(); | 2071 StartEmbeddedServer(); |
| 2008 | 2072 |
| 2009 // Do an initial navigation and capture objects we expect to be cleaned up | 2073 // Do an initial navigation and capture objects we expect to be cleaned up |
| 2010 // on cross-process navigation. | 2074 // on cross-process navigation. |
| 2011 GURL start_url = embedded_test_server()->GetURL("/title1.html"); | 2075 GURL start_url = embedded_test_server()->GetURL("/title1.html"); |
| 2012 NavigateToURL(shell(), start_url); | 2076 NavigateToURL(shell(), start_url); |
| (...skipping 737 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2750 TestNavigationObserver commit_observer(web_contents); | 2814 TestNavigationObserver commit_observer(web_contents); |
| 2751 shell()->LoadURL(embedded_test_server()->GetURL("b.com", "/title1.html")); | 2815 shell()->LoadURL(embedded_test_server()->GetURL("b.com", "/title1.html")); |
| 2752 commit_observer.Wait(); | 2816 commit_observer.Wait(); |
| 2753 exit_observer.Wait(); | 2817 exit_observer.Wait(); |
| 2754 | 2818 |
| 2755 // Ensure the entry's title hasn't changed after the ignored commit. | 2819 // Ensure the entry's title hasn't changed after the ignored commit. |
| 2756 EXPECT_EQ(title, entry->GetTitle()); | 2820 EXPECT_EQ(title, entry->GetTitle()); |
| 2757 } | 2821 } |
| 2758 | 2822 |
| 2759 } // namespace content | 2823 } // namespace content |
| OLD | NEW |