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 380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 Loading... |
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(¤t_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 |
OLD | NEW |