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

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

Issue 1652483002: Browser Side Text Input State Tracking for OOPIF. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 10 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 380 matching lines...) Expand 10 before | Expand all | Expand 10 after
391 frames_created_++; 391 frames_created_++;
392 if (frames_created_ == expected_frame_count_) { 392 if (frames_created_ == expected_frame_count_) {
393 message_loop_runner_->Quit(); 393 message_loop_runner_->Quit();
394 } 394 }
395 } 395 }
396 396
397 // This observer is used to wait for its owner FrameTreeNode to become focused. 397 // This observer is used to wait for its owner FrameTreeNode to become focused.
398 class FrameFocusedObserver : public FrameTreeNode::Observer { 398 class FrameFocusedObserver : public FrameTreeNode::Observer {
399 public: 399 public:
400 FrameFocusedObserver(FrameTreeNode* owner) 400 FrameFocusedObserver(FrameTreeNode* owner)
401 : owner_(owner), message_loop_runner_(new MessageLoopRunner) { 401 : focused_(false),
402 owner_(owner),
403 message_loop_runner_(new MessageLoopRunner) {
402 owner->AddObserver(this); 404 owner->AddObserver(this);
403 } 405 }
404 406
405 ~FrameFocusedObserver() override { owner_->RemoveObserver(this); } 407 ~FrameFocusedObserver() override { owner_->RemoveObserver(this); }
406 408
407 void Wait() { message_loop_runner_->Run(); } 409 void Wait() {
410 if (focused_)
411 return;
412 message_loop_runner_->Run();
413 }
408 414
409 private: 415 private:
410 // FrameTreeNode::Observer 416 // FrameTreeNode::Observer
411 void OnFrameTreeNodeFocused(FrameTreeNode* node) override { 417 void OnFrameTreeNodeFocused(FrameTreeNode* node) override {
412 if (node == owner_) 418 if (node == owner_) {
419 focused_ = true;
413 message_loop_runner_->Quit(); 420 message_loop_runner_->Quit();
421 }
414 } 422 }
415 423
424 bool focused_;
416 FrameTreeNode* owner_; 425 FrameTreeNode* owner_;
417 scoped_refptr<MessageLoopRunner> message_loop_runner_; 426 scoped_refptr<MessageLoopRunner> message_loop_runner_;
418 427
419 DISALLOW_COPY_AND_ASSIGN(FrameFocusedObserver); 428 DISALLOW_COPY_AND_ASSIGN(FrameFocusedObserver);
420 }; 429 };
421 430
422 // This observer is used to wait for its owner FrameTreeNode to become deleted. 431 // This observer is used to wait for its owner FrameTreeNode to become deleted.
423 class FrameDeletedObserver : public FrameTreeNode::Observer { 432 class FrameDeletedObserver : public FrameTreeNode::Observer {
424 public: 433 public:
425 FrameDeletedObserver(FrameTreeNode* owner) 434 FrameDeletedObserver(FrameTreeNode* owner)
(...skipping 4782 matching lines...) Expand 10 before | Expand all | Expand 10 after
5208 ->root(); 5217 ->root();
5209 ASSERT_EQ(1U, root->child_count()); 5218 ASSERT_EQ(1U, root->child_count());
5210 FrameTreeNode* mixed_child = root->child_at(0)->child_at(0); 5219 FrameTreeNode* mixed_child = root->child_at(0)->child_at(0);
5211 ASSERT_TRUE(mixed_child); 5220 ASSERT_TRUE(mixed_child);
5212 // The child iframe attempted to create a mixed iframe; this should 5221 // The child iframe attempted to create a mixed iframe; this should
5213 // have been blocked, so the mixed iframe should not have committed a 5222 // have been blocked, so the mixed iframe should not have committed a
5214 // load. 5223 // load.
5215 EXPECT_FALSE(mixed_child->has_committed_real_load()); 5224 EXPECT_FALSE(mixed_child->has_committed_real_load());
5216 } 5225 }
5217 5226
5227 // This class observes the first change in the text input state
5228 // for a given RenderWidgetHostViewBase.
5229 class TextInputStateObserver {
5230 public:
5231 TextInputStateObserver(RenderWidgetHostViewBase* view)
5232 : view_(view),
5233 state_(*view->current_text_input_state()),
5234 message_loop_runner_(nullptr) {}
5235
5236 // Hold and keep polling the |view_| until its text input state changes.
5237 TextInputState WaitUntilStateChanges() {
5238 while (!DidChangeState()) {
5239 message_loop_runner_ = new MessageLoopRunner;
5240 BrowserThread::ID current_thread_id;
5241 EXPECT_TRUE(
5242 BrowserThread::GetCurrentThreadIdentifier(&current_thread_id));
5243 BrowserThread::PostDelayedTask(current_thread_id, FROM_HERE,
5244 message_loop_runner_->QuitClosure(),
5245 base::TimeDelta::FromMicroseconds(500));
5246 message_loop_runner_->Run();
5247 }
5248 return *view_->current_text_input_state();
5249 }
5250
5251 private:
5252 bool DidChangeState() {
5253 TextInputState current = *view_->current_text_input_state();
5254 return state_.type != current.type || state_.mode != current.mode ||
5255 state_.value != current.value;
5256 }
5257 RenderWidgetHostViewBase* view_;
5258 TextInputState state_;
5259 scoped_refptr<MessageLoopRunner> message_loop_runner_;
5260
5261 DISALLOW_COPY_AND_ASSIGN(TextInputStateObserver);
5262 };
5263
5264 // Verify that by moving the focus between different frames the top-level
5265 // RenderWidgetHostViewBase tracks the input state properly.
5266 IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, TextInputStateChanged) {
5267 GURL main_page_url(embedded_test_server()->GetURL(
5268 "a.com", "/textinput/page_with_input_field_and_iframe.html"));
5269 NavigateToURL(shell(), main_page_url);
5270 GURL cross_origin_url(embedded_test_server()->GetURL(
5271 "b.com", "/textinput/page_with_input_field_and_iframe.html"));
5272 FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
5273 ->GetFrameTree()
5274 ->root();
5275 // Wait for the main frame to finish loading.
5276 EXPECT_TRUE(WaitForRenderFrameReady(root->current_frame_host()));
5277
5278 // Navigate the child frame.
5279 FrameTreeNode* child_frame_node = root->child_at(0);
5280 NavigateFrameToURL(child_frame_node, cross_origin_url);
5281
5282 // Wait for the child frame to finish loading.
5283 EXPECT_TRUE(WaitForRenderFrameReady(child_frame_node->current_frame_host()));
5284
5285 RenderWidgetHostImpl* root_rwh =
5286 root->current_frame_host()->GetRenderWidgetHost();
5287 RenderWidgetHostViewBase* root_rwhv = root_rwh->GetView();
5288
5289 EXPECT_EQ(root_rwhv->current_text_input_state()->type,
5290 ui::TEXT_INPUT_TYPE_NONE);
5291 // Focus the root (main-frame). This would focus the text input field.
5292 LOG(INFO) << "Sending a mouse click to top level page's <input>.";
5293 TextInputStateObserver root_observer(root_rwhv);
5294 SimulateMouseClick(root_rwh, 1, 1);
5295 TextInputState new_state = root_observer.WaitUntilStateChanges();
5296 EXPECT_EQ(new_state.type, ui::TEXT_INPUT_TYPE_TEXT);
5297
5298 // Now focus the child frame and read the text input state.
5299 RenderWidgetHostImpl* child_rwh =
5300 child_frame_node->current_frame_host()->GetRenderWidgetHost();
5301 RenderWidgetHostViewBase* child_rwhv = child_rwh->GetView();
5302 TextInputStateObserver child_observer(child_rwhv);
5303 SimulateMouseClick(child_rwh, 1, 1);
5304 new_state = child_observer.WaitUntilStateChanges();
5305
5306 EXPECT_EQ(new_state.type, ui::TEXT_INPUT_TYPE_TEXT);
5307
5308 // Finally, the top level view should see the child's view.
5309 new_state = *root_rwhv->current_text_input_state();
5310 EXPECT_EQ(new_state.type, ui::TEXT_INPUT_TYPE_TEXT);
5311 EXPECT_EQ(new_state.value, cross_origin_url.spec());
5312 }
5313
5218 } // namespace content 5314 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698