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 "content/browser/site_per_process_browsertest.h" | 5 #include "content/browser/site_per_process_browsertest.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 #include <stdint.h> | 8 #include <stdint.h> |
9 | 9 |
10 #include <algorithm> | 10 #include <algorithm> |
(...skipping 10182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
10193 | 10193 |
10194 // Go back again. This should go to foo.com. | 10194 // Go back again. This should go to foo.com. |
10195 { | 10195 { |
10196 TestNavigationObserver back_observer(web_contents()); | 10196 TestNavigationObserver back_observer(web_contents()); |
10197 web_contents()->GetController().GoBack(); | 10197 web_contents()->GetController().GoBack(); |
10198 back_observer.Wait(); | 10198 back_observer.Wait(); |
10199 } | 10199 } |
10200 EXPECT_EQ(foo_url, web_contents()->GetMainFrame()->GetLastCommittedURL()); | 10200 EXPECT_EQ(foo_url, web_contents()->GetMainFrame()->GetLastCommittedURL()); |
10201 } | 10201 } |
10202 | 10202 |
10203 // Class to sniff incoming IPCs for FrameHostMsg_SetIsInert messages. | |
10204 class SetIsInertMessageFilter : public content::BrowserMessageFilter { | |
10205 public: | |
10206 SetIsInertMessageFilter() | |
10207 : content::BrowserMessageFilter(FrameMsgStart), | |
10208 message_loop_runner_(new content::MessageLoopRunner), | |
10209 msg_received_(false) {} | |
10210 | |
10211 bool OnMessageReceived(const IPC::Message& message) override { | |
10212 IPC_BEGIN_MESSAGE_MAP(SetIsInertMessageFilter, message) | |
10213 IPC_MESSAGE_HANDLER(FrameHostMsg_SetIsInert, OnSetIsInert) | |
10214 IPC_END_MESSAGE_MAP() | |
10215 return false; | |
10216 } | |
10217 | |
10218 bool is_inert() const { return is_inert_; } | |
10219 | |
10220 void Wait() { message_loop_runner_->Run(); } | |
10221 | |
10222 private: | |
10223 ~SetIsInertMessageFilter() override {} | |
10224 | |
10225 void OnSetIsInert(bool is_inert) { | |
10226 content::BrowserThread::PostTask( | |
10227 content::BrowserThread::UI, FROM_HERE, | |
10228 base::Bind(&SetIsInertMessageFilter::OnSetIsInertOnUI, this, is_inert)); | |
10229 } | |
10230 void OnSetIsInertOnUI(bool is_inert) { | |
10231 is_inert_ = is_inert; | |
10232 if (!msg_received_) { | |
10233 msg_received_ = true; | |
10234 message_loop_runner_->Quit(); | |
10235 } | |
10236 } | |
10237 scoped_refptr<content::MessageLoopRunner> message_loop_runner_; | |
10238 bool msg_received_; | |
10239 bool is_inert_; | |
10240 DISALLOW_COPY_AND_ASSIGN(SetIsInertMessageFilter); | |
10241 }; | |
10242 | |
10243 // Tests that when a frame contains a modal <dialog> element, out-of-process | |
10244 // iframe children cannot take focus, because they are inert. | |
10245 IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, CrossProcessInertSubframe) { | |
10246 GURL main_url(embedded_test_server()->GetURL( | |
10247 "a.com", "/cross_site_iframe_factory.html?a(b)")); | |
10248 EXPECT_TRUE(NavigateToURL(shell(), main_url)); | |
10249 | |
10250 FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) | |
10251 ->GetFrameTree() | |
10252 ->root(); | |
10253 ASSERT_EQ(1U, root->child_count()); | |
10254 | |
10255 FrameTreeNode* iframe_node = root->child_at(0); | |
10256 | |
10257 EXPECT_TRUE(ExecuteScript( | |
10258 iframe_node, | |
10259 "document.head.innerHTML = '';" | |
10260 "document.body.innerHTML = '<input id=\"text1\"> <input id=\"text2\">';" | |
10261 "text1.focus();")); | |
10262 | |
10263 // Add a filter to the parent frame's process to monitor for inert bit | |
10264 // updates. These are sent through the proxy for b.com child frame. | |
10265 scoped_refptr<SetIsInertMessageFilter> filter = new SetIsInertMessageFilter(); | |
10266 root->current_frame_host()->GetProcess()->AddFilter(filter.get()); | |
10267 | |
10268 // Add a <dialog> to the root frame and call showModal on it. | |
10269 EXPECT_TRUE(ExecuteScript(root, | |
10270 "let dialog = " | |
10271 "document.body.appendChild(document.createElement('" | |
10272 "dialog'));" | |
10273 "dialog.innerHTML = 'Modal dialog <input>';" | |
10274 "dialog.showModal();")); | |
10275 filter->Wait(); | |
10276 EXPECT_TRUE(filter->is_inert()); | |
10277 | |
10278 // This yields the UI thread to ensure that the real SetIsInert message | |
10279 // handler runs, in order to guarantee that the update arrives at the | |
10280 // renderer process before the script below. | |
10281 { | |
10282 base::RunLoop loop; | |
10283 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, | |
10284 loop.QuitClosure()); | |
10285 loop.Run(); | |
10286 } | |
10287 | |
10288 std::string focused_element; | |
10289 | |
10290 // Attempt to change focus in the inert subframe. This should fail. | |
10291 // The setTimeout ensures that the inert bit can propagate before the | |
10292 // test JS code runs. | |
10293 EXPECT_TRUE(ExecuteScriptAndExtractString( | |
10294 iframe_node, | |
10295 "window.setTimeout(() => {text2.focus();" | |
10296 "domAutomationController.send(document.activeElement.id);}, 0)", | |
10297 &focused_element)); | |
10298 EXPECT_EQ("", focused_element); | |
10299 | |
10300 // Navigate the child frame to another site, so that it moves into a new | |
10301 // process. | |
10302 GURL site_url(embedded_test_server()->GetURL("c.com", "/title1.html")); | |
10303 NavigateFrameToURL(iframe_node, site_url); | |
10304 | |
10305 EXPECT_TRUE(ExecuteScript( | |
10306 iframe_node, | |
10307 "document.head.innerHTML = '';" | |
10308 "document.body.innerHTML = '<input id=\"text1\"> <input id=\"text2\">';" | |
10309 "text1.focus();")); | |
10310 | |
10311 // Verify that inertness was preserved across the navigation. | |
10312 EXPECT_TRUE(ExecuteScriptAndExtractString( | |
10313 iframe_node, | |
10314 "text2.focus();" | |
10315 "domAutomationController.send(document.activeElement.id);", | |
10316 &focused_element)); | |
10317 EXPECT_EQ("", focused_element); | |
alexmos
2017/06/20 18:46:10
For completeness, and since it should be easy, cou
kenrb
2017/06/22 15:33:35
Done.
| |
10318 } | |
10319 | |
10203 } // namespace content | 10320 } // namespace content |
OLD | NEW |