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

Side by Side Diff: content/browser/site_per_process_browsertest.cc

Issue 2883033003: Propagate inert state to OOPIFs when a modal dialog is active (Closed)
Patch Set: nit addressed Created 3 years, 6 months 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 "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 10179 matching lines...) Expand 10 before | Expand all | Expand 10 after
10190 10190
10191 // Go back again. This should go to foo.com. 10191 // Go back again. This should go to foo.com.
10192 { 10192 {
10193 TestNavigationObserver back_observer(web_contents()); 10193 TestNavigationObserver back_observer(web_contents());
10194 web_contents()->GetController().GoBack(); 10194 web_contents()->GetController().GoBack();
10195 back_observer.Wait(); 10195 back_observer.Wait();
10196 } 10196 }
10197 EXPECT_EQ(foo_url, web_contents()->GetMainFrame()->GetLastCommittedURL()); 10197 EXPECT_EQ(foo_url, web_contents()->GetMainFrame()->GetLastCommittedURL());
10198 } 10198 }
10199 10199
10200 // Class to sniff incoming IPCs for FrameHostMsg_SetIsInert messages.
10201 class SetIsInertMessageFilter : public content::BrowserMessageFilter {
10202 public:
10203 SetIsInertMessageFilter()
10204 : content::BrowserMessageFilter(FrameMsgStart),
10205 message_loop_runner_(new content::MessageLoopRunner),
10206 msg_received_(false) {}
10207
10208 bool OnMessageReceived(const IPC::Message& message) override {
10209 IPC_BEGIN_MESSAGE_MAP(SetIsInertMessageFilter, message)
10210 IPC_MESSAGE_HANDLER(FrameHostMsg_SetIsInert, OnSetIsInert)
10211 IPC_END_MESSAGE_MAP()
10212 return false;
10213 }
10214
10215 bool is_inert() const { return is_inert_; }
10216
10217 void Wait() { message_loop_runner_->Run(); }
10218
10219 private:
10220 ~SetIsInertMessageFilter() override {}
10221
10222 void OnSetIsInert(bool is_inert) {
10223 content::BrowserThread::PostTask(
10224 content::BrowserThread::UI, FROM_HERE,
10225 base::Bind(&SetIsInertMessageFilter::OnSetIsInertOnUI, this, is_inert));
10226 }
10227 void OnSetIsInertOnUI(bool is_inert) {
10228 is_inert_ = is_inert;
10229 if (!msg_received_) {
10230 msg_received_ = true;
10231 message_loop_runner_->Quit();
10232 }
10233 }
10234 scoped_refptr<content::MessageLoopRunner> message_loop_runner_;
10235 bool msg_received_;
10236 bool is_inert_;
10237 DISALLOW_COPY_AND_ASSIGN(SetIsInertMessageFilter);
10238 };
10239
10240 // Tests that when a frame contains a modal <dialog> element, out-of-process
10241 // iframe children cannot take focus, because they are inert.
10242 IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, CrossProcessInertSubframe) {
10243 // This uses a(b,b) instead of a(b) to preserve the b.com process even when
10244 // the first subframe is navigated away from it.
10245 GURL main_url(embedded_test_server()->GetURL(
10246 "a.com", "/cross_site_iframe_factory.html?a(b,b)"));
10247 EXPECT_TRUE(NavigateToURL(shell(), main_url));
10248
10249 FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
10250 ->GetFrameTree()
10251 ->root();
10252 ASSERT_EQ(2U, root->child_count());
10253
10254 FrameTreeNode* iframe_node = root->child_at(0);
10255
10256 EXPECT_TRUE(ExecuteScript(
10257 iframe_node,
10258 "document.head.innerHTML = '';"
10259 "document.body.innerHTML = '<input id=\"text1\"> <input id=\"text2\">';"
10260 "text1.focus();"));
10261
10262 // Add a filter to the parent frame's process to monitor for inert bit
10263 // updates. These are sent through the proxy for b.com child frame.
10264 scoped_refptr<SetIsInertMessageFilter> filter = new SetIsInertMessageFilter();
10265 root->current_frame_host()->GetProcess()->AddFilter(filter.get());
10266
10267 // Add a <dialog> to the root frame and call showModal on it.
10268 EXPECT_TRUE(ExecuteScript(root,
10269 "let dialog = "
10270 "document.body.appendChild(document.createElement('"
10271 "dialog'));"
10272 "dialog.innerHTML = 'Modal dialog <input>';"
10273 "dialog.showModal();"));
10274 filter->Wait();
10275 EXPECT_TRUE(filter->is_inert());
10276
10277 // This yields the UI thread to ensure that the real SetIsInert message
10278 // handler runs, in order to guarantee that the update arrives at the
10279 // renderer process before the script below.
10280 {
10281 base::RunLoop loop;
10282 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
10283 loop.QuitClosure());
10284 loop.Run();
10285 }
10286
10287 std::string focused_element;
10288
10289 // Attempt to change focus in the inert subframe. This should fail.
10290 // The setTimeout ensures that the inert bit can propagate before the
10291 // test JS code runs.
10292 EXPECT_TRUE(ExecuteScriptAndExtractString(
10293 iframe_node,
10294 "window.setTimeout(() => {text2.focus();"
10295 "domAutomationController.send(document.activeElement.id);}, 0)",
10296 &focused_element));
10297 EXPECT_EQ("", focused_element);
10298
10299 // Navigate the child frame to another site, so that it moves into a new
10300 // process.
10301 GURL site_url(embedded_test_server()->GetURL("c.com", "/title1.html"));
10302 NavigateFrameToURL(iframe_node, site_url);
10303
10304 EXPECT_TRUE(ExecuteScript(
10305 iframe_node,
10306 "document.head.innerHTML = '';"
10307 "document.body.innerHTML = '<input id=\"text1\"> <input id=\"text2\">';"
10308 "text1.focus();"));
10309
10310 // Verify that inertness was preserved across the navigation.
10311 EXPECT_TRUE(ExecuteScriptAndExtractString(
10312 iframe_node,
10313 "text2.focus();"
10314 "domAutomationController.send(document.activeElement.id);",
10315 &focused_element));
10316 EXPECT_EQ("", focused_element);
10317
10318 // Navigate the subframe back into its parent process to verify that the
10319 // new local frame remains inert.
10320 GURL same_site_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
10321 NavigateFrameToURL(iframe_node, same_site_url);
10322
10323 EXPECT_TRUE(ExecuteScript(
10324 iframe_node,
10325 "document.head.innerHTML = '';"
10326 "document.body.innerHTML = '<input id=\"text1\"> <input id=\"text2\">';"
10327 "text1.focus();"));
10328
10329 // Verify that inertness was preserved across the navigation.
10330 EXPECT_TRUE(ExecuteScriptAndExtractString(
10331 iframe_node,
10332 "text2.focus();"
10333 "domAutomationController.send(document.activeElement.id);",
10334 &focused_element));
10335 EXPECT_EQ("", focused_element);
10336 }
10337
10200 } // namespace content 10338 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/frame_host/render_widget_host_view_child_frame.cc ('k') | content/common/frame_messages.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698