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 3 // found in the LICENSE file. 4 5 #include "content/browser/renderer_host/render_widget_host_view_aura.h" 6 7 #include "base/basictypes.h" 8 #include "base/message_loop/message_loop.h" 9 #include "base/strings/utf_string_conversions.h" 10 #include "content/browser/renderer_host/render_widget_host_delegate.h" 11 #include "content/browser/renderer_host/render_widget_host_impl.h" 12 #include "content/common/input_messages.h" 13 #include "content/common/view_messages.h" 14 #include "content/public/browser/render_widget_host_view.h" 15 #include "content/public/test/mock_render_process_host.h" 16 #include "content/public/test/test_browser_context.h" 17 #include "ipc/ipc_test_sink.h" 18 #include "testing/gtest/include/gtest/gtest.h" 19 #include "ui/aura/client/aura_constants.h" 20 #include "ui/aura/env.h" 21 #include "ui/aura/layout_manager.h" 22 #include "ui/aura/root_window.h" 23 #include "ui/aura/test/aura_test_helper.h" 24 #include "ui/aura/test/test_cursor_client.h" 25 #include "ui/aura/test/test_screen.h" 26 #include "ui/aura/test/test_window_delegate.h" 27 #include "ui/aura/window.h" 28 #include "ui/aura/window_observer.h" 29 #include "ui/base/events/event.h" 30 #include "ui/base/events/event_utils.h" 31 #include "ui/base/ui_base_types.h" 32 33 namespace content { 34 namespace { 35 class MockRenderWidgetHostDelegate : public RenderWidgetHostDelegate { 36 public: 37 MockRenderWidgetHostDelegate() {} 38 virtual ~MockRenderWidgetHostDelegate() {} 39 }; 40 41 // Simple observer that keeps track of changes to a window for tests. 42 class TestWindowObserver : public aura::WindowObserver { 43 public: 44 explicit TestWindowObserver(aura::Window* window_to_observe) 45 : window_(window_to_observe) { 46 window_->AddObserver(this); 47 } 48 virtual ~TestWindowObserver() { 49 if (window_) 50 window_->RemoveObserver(this); 51 } 52 53 bool destroyed() const { return destroyed_; } 54 55 // aura::WindowObserver overrides: 56 virtual void OnWindowDestroyed(aura::Window* window) OVERRIDE { 57 CHECK_EQ(window, window_); 58 destroyed_ = true; 59 window_ = NULL; 60 } 61 62 private: 63 // Window that we're observing, or NULL if it's been destroyed. 64 aura::Window* window_; 65 66 // Was |window_| destroyed? 67 bool destroyed_; 68 69 DISALLOW_COPY_AND_ASSIGN(TestWindowObserver); 70 }; 71 72 class RenderWidgetHostViewAuraTest : public testing::Test { 73 public: 74 RenderWidgetHostViewAuraTest() {} 75 76 virtual void SetUp() { 77 aura_test_helper_.reset(new aura::test::AuraTestHelper(&message_loop_)); 78 aura_test_helper_->SetUp(); 79 80 browser_context_.reset(new TestBrowserContext); 81 MockRenderProcessHost* process_host = 82 new MockRenderProcessHost(browser_context_.get()); 83 84 sink_ = &process_host->sink(); 85 86 parent_host_ = new RenderWidgetHostImpl( 87 &delegate_, process_host, MSG_ROUTING_NONE); 88 parent_view_ = static_cast<RenderWidgetHostViewAura*>( 89 RenderWidgetHostView::CreateViewForWidget(parent_host_)); 90 parent_view_->InitAsChild(NULL); 91 parent_view_->GetNativeView()->SetDefaultParentByRootWindow( 92 aura_test_helper_->root_window(), gfx::Rect()); 93 94 widget_host_ = new RenderWidgetHostImpl( 95 &delegate_, process_host, MSG_ROUTING_NONE); 96 widget_host_->Init(); 97 view_ = static_cast<RenderWidgetHostViewAura*>( 98 RenderWidgetHostView::CreateViewForWidget(widget_host_)); 99 } 100 101 virtual void TearDown() { 102 sink_ = NULL; 103 if (view_) 104 view_->Destroy(); 105 delete widget_host_; 106 107 parent_view_->Destroy(); 108 delete parent_host_; 109 110 browser_context_.reset(); 111 aura_test_helper_->TearDown(); 112 113 message_loop_.DeleteSoon(FROM_HERE, browser_context_.release()); 114 message_loop_.RunUntilIdle(); 115 } 116 117 protected: 118 base::MessageLoopForUI message_loop_; 119 scoped_ptr<aura::test::AuraTestHelper> aura_test_helper_; 120 scoped_ptr<BrowserContext> browser_context_; 121 MockRenderWidgetHostDelegate delegate_; 122 123 // Tests should set these to NULL if they've already triggered their 124 // destruction. 125 RenderWidgetHostImpl* parent_host_; 126 RenderWidgetHostViewAura* parent_view_; 127 128 // Tests should set these to NULL if they've already triggered their 129 // destruction. 130 RenderWidgetHostImpl* widget_host_; 131 RenderWidgetHostViewAura* view_; 132 133 IPC::TestSink* sink_; 134 135 private: 136 DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostViewAuraTest); 137 }; 138 139 // A layout manager that always resizes a child to the root window size. 140 class FullscreenLayoutManager : public aura::LayoutManager { 141 public: 142 explicit FullscreenLayoutManager(aura::RootWindow* owner) 143 : owner_(owner) {} 144 virtual ~FullscreenLayoutManager() {} 145 146 // Overridden from aura::LayoutManager: 147 virtual void OnWindowResized() OVERRIDE { 148 aura::Window::Windows::const_iterator i; 149 for (i = owner_->children().begin(); i != owner_->children().end(); ++i) { 150 (*i)->SetBounds(gfx::Rect()); 151 } 152 } 153 virtual void OnWindowAddedToLayout(aura::Window* child) OVERRIDE { 154 child->SetBounds(gfx::Rect()); 155 } 156 virtual void OnWillRemoveWindowFromLayout(aura::Window* child) OVERRIDE { 157 } 158 virtual void OnWindowRemovedFromLayout(aura::Window* child) OVERRIDE { 159 } 160 virtual void OnChildWindowVisibilityChanged(aura::Window* child, 161 bool visible) OVERRIDE { 162 } 163 virtual void SetChildBounds(aura::Window* child, 164 const gfx::Rect& requested_bounds) OVERRIDE { 165 SetChildBoundsDirect(child, gfx::Rect(owner_->bounds().size())); 166 } 167 168 private: 169 aura::RootWindow* owner_; 170 DISALLOW_COPY_AND_ASSIGN(FullscreenLayoutManager); 171 }; 172 173 } // namespace 174 175 // Checks that a fullscreen view has the correct show-state and receives the 176 // focus. 177 TEST_F(RenderWidgetHostViewAuraTest, FocusFullscreen) { 178 view_->InitAsFullscreen(parent_view_); 179 aura::Window* window = view_->GetNativeView(); 180 ASSERT_TRUE(window != NULL); 181 EXPECT_EQ(ui::SHOW_STATE_FULLSCREEN, 182 window->GetProperty(aura::client::kShowStateKey)); 183 184 // Check that we requested and received the focus. 185 EXPECT_TRUE(window->HasFocus()); 186 187 // Check that we'll also say it's okay to activate the window when there's an 188 // ActivationClient defined. 189 EXPECT_TRUE(view_->ShouldActivate()); 190 } 191 192 // Checks that a fullscreen view is destroyed when it loses the focus. 193 TEST_F(RenderWidgetHostViewAuraTest, DestroyFullscreenOnBlur) { 194 view_->InitAsFullscreen(parent_view_); 195 aura::Window* window = view_->GetNativeView(); 196 ASSERT_TRUE(window != NULL); 197 ASSERT_TRUE(window->HasFocus()); 198 199 // After we create and focus another window, the RWHVA's window should be 200 // destroyed. 201 TestWindowObserver observer(window); 202 aura::test::TestWindowDelegate delegate; 203 scoped_ptr<aura::Window> sibling(new aura::Window(&delegate)); 204 sibling->Init(ui::LAYER_TEXTURED); 205 sibling->Show(); 206 window->parent()->AddChild(sibling.get()); 207 sibling->Focus(); 208 ASSERT_TRUE(sibling->HasFocus()); 209 ASSERT_TRUE(observer.destroyed()); 210 211 widget_host_ = NULL; 212 view_ = NULL; 213 } 214 215 // Checks that IME-composition-event state is maintained correctly. 216 TEST_F(RenderWidgetHostViewAuraTest, SetCompositionText) { 217 view_->InitAsChild(NULL); 218 view_->Show(); 219 220 ui::CompositionText composition_text; 221 composition_text.text = ASCIIToUTF16("|a|b"); 222 223 // Focused segment 224 composition_text.underlines.push_back( 225 ui::CompositionUnderline(0, 3, 0xff000000, true)); 226 227 // Non-focused segment 228 composition_text.underlines.push_back( 229 ui::CompositionUnderline(3, 4, 0xff000000, false)); 230 231 const ui::CompositionUnderlines& underlines = composition_text.underlines; 232 233 // Caret is at the end. (This emulates Japanese MSIME 2007 and later) 234 composition_text.selection = ui::Range(4); 235 236 sink_->ClearMessages(); 237 view_->SetCompositionText(composition_text); 238 EXPECT_TRUE(view_->has_composition_text_); 239 { 240 const IPC::Message* msg = 241 sink_->GetFirstMessageMatching(ViewMsg_ImeSetComposition::ID); 242 ASSERT_TRUE(msg != NULL); 243 244 ViewMsg_ImeSetComposition::Param params; 245 ViewMsg_ImeSetComposition::Read(msg, ¶ms); 246 // composition text 247 EXPECT_EQ(composition_text.text, params.a); 248 // underlines 249 ASSERT_EQ(underlines.size(), params.b.size()); 250 for (size_t i = 0; i < underlines.size(); ++i) { 251 EXPECT_EQ(underlines[i].start_offset, params.b[i].startOffset); 252 EXPECT_EQ(underlines[i].end_offset, params.b[i].endOffset); 253 EXPECT_EQ(underlines[i].color, params.b[i].color); 254 EXPECT_EQ(underlines[i].thick, params.b[i].thick); 255 } 256 // highlighted range 257 EXPECT_EQ(4, params.c) << "Should be the same to the caret pos"; 258 EXPECT_EQ(4, params.d) << "Should be the same to the caret pos"; 259 } 260 261 view_->ImeCancelComposition(); 262 EXPECT_FALSE(view_->has_composition_text_); 263 } 264 265 // Checks that touch-event state is maintained correctly. 266 TEST_F(RenderWidgetHostViewAuraTest, TouchEventState) { 267 view_->InitAsChild(NULL); 268 view_->Show(); 269 270 // Start with no touch-event handler in the renderer. 271 widget_host_->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, false)); 272 EXPECT_FALSE(widget_host_->ShouldForwardTouchEvent()); 273 274 ui::TouchEvent press(ui::ET_TOUCH_PRESSED, 275 gfx::Point(30, 30), 276 0, 277 ui::EventTimeForNow()); 278 ui::TouchEvent move(ui::ET_TOUCH_MOVED, 279 gfx::Point(20, 20), 280 0, 281 ui::EventTimeForNow()); 282 ui::TouchEvent release(ui::ET_TOUCH_RELEASED, 283 gfx::Point(20, 20), 284 0, 285 ui::EventTimeForNow()); 286 287 view_->OnTouchEvent(&press); 288 EXPECT_FALSE(press.handled()); 289 EXPECT_EQ(WebKit::WebInputEvent::TouchStart, view_->touch_event_.type); 290 EXPECT_EQ(1U, view_->touch_event_.touchesLength); 291 EXPECT_EQ(WebKit::WebTouchPoint::StatePressed, 292 view_->touch_event_.touches[0].state); 293 294 view_->OnTouchEvent(&move); 295 EXPECT_FALSE(move.handled()); 296 EXPECT_EQ(WebKit::WebInputEvent::TouchMove, view_->touch_event_.type); 297 EXPECT_EQ(1U, view_->touch_event_.touchesLength); 298 EXPECT_EQ(WebKit::WebTouchPoint::StateMoved, 299 view_->touch_event_.touches[0].state); 300 301 view_->OnTouchEvent(&release); 302 EXPECT_FALSE(release.handled()); 303 EXPECT_EQ(WebKit::WebInputEvent::TouchEnd, view_->touch_event_.type); 304 EXPECT_EQ(0U, view_->touch_event_.touchesLength); 305 306 // Now install some touch-event handlers and do the same steps. The touch 307 // events should now be consumed. However, the touch-event state should be 308 // updated as before. 309 widget_host_->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, true)); 310 EXPECT_TRUE(widget_host_->ShouldForwardTouchEvent()); 311 312 view_->OnTouchEvent(&press); 313 EXPECT_TRUE(press.stopped_propagation()); 314 EXPECT_EQ(WebKit::WebInputEvent::TouchStart, view_->touch_event_.type); 315 EXPECT_EQ(1U, view_->touch_event_.touchesLength); 316 EXPECT_EQ(WebKit::WebTouchPoint::StatePressed, 317 view_->touch_event_.touches[0].state); 318 319 view_->OnTouchEvent(&move); 320 EXPECT_TRUE(move.stopped_propagation()); 321 EXPECT_EQ(WebKit::WebInputEvent::TouchMove, view_->touch_event_.type); 322 EXPECT_EQ(1U, view_->touch_event_.touchesLength); 323 EXPECT_EQ(WebKit::WebTouchPoint::StateMoved, 324 view_->touch_event_.touches[0].state); 325 326 view_->OnTouchEvent(&release); 327 EXPECT_TRUE(release.stopped_propagation()); 328 EXPECT_EQ(WebKit::WebInputEvent::TouchEnd, view_->touch_event_.type); 329 EXPECT_EQ(0U, view_->touch_event_.touchesLength); 330 331 // Now start a touch event, and remove the event-handlers before the release. 332 view_->OnTouchEvent(&press); 333 EXPECT_TRUE(press.stopped_propagation()); 334 EXPECT_EQ(WebKit::WebInputEvent::TouchStart, view_->touch_event_.type); 335 EXPECT_EQ(1U, view_->touch_event_.touchesLength); 336 EXPECT_EQ(WebKit::WebTouchPoint::StatePressed, 337 view_->touch_event_.touches[0].state); 338 339 widget_host_->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, false)); 340 EXPECT_FALSE(widget_host_->ShouldForwardTouchEvent()); 341 342 ui::TouchEvent move2(ui::ET_TOUCH_MOVED, gfx::Point(20, 20), 0, 343 base::Time::NowFromSystemTime() - base::Time()); 344 view_->OnTouchEvent(&move2); 345 EXPECT_FALSE(move2.handled()); 346 EXPECT_EQ(WebKit::WebInputEvent::TouchMove, view_->touch_event_.type); 347 EXPECT_EQ(1U, view_->touch_event_.touchesLength); 348 EXPECT_EQ(WebKit::WebTouchPoint::StateMoved, 349 view_->touch_event_.touches[0].state); 350 351 ui::TouchEvent release2(ui::ET_TOUCH_RELEASED, gfx::Point(20, 20), 0, 352 base::Time::NowFromSystemTime() - base::Time()); 353 view_->OnTouchEvent(&release2); 354 EXPECT_FALSE(release2.handled()); 355 EXPECT_EQ(WebKit::WebInputEvent::TouchEnd, view_->touch_event_.type); 356 EXPECT_EQ(0U, view_->touch_event_.touchesLength); 357 } 358 359 // Checks that touch-events are queued properly when there is a touch-event 360 // handler on the page. 361 TEST_F(RenderWidgetHostViewAuraTest, TouchEventSyncAsync) { 362 view_->InitAsChild(NULL); 363 view_->Show(); 364 365 widget_host_->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, true)); 366 EXPECT_TRUE(widget_host_->ShouldForwardTouchEvent()); 367 368 ui::TouchEvent press(ui::ET_TOUCH_PRESSED, 369 gfx::Point(30, 30), 370 0, 371 ui::EventTimeForNow()); 372 ui::TouchEvent move(ui::ET_TOUCH_MOVED, 373 gfx::Point(20, 20), 374 0, 375 ui::EventTimeForNow()); 376 ui::TouchEvent release(ui::ET_TOUCH_RELEASED, 377 gfx::Point(20, 20), 378 0, 379 ui::EventTimeForNow()); 380 381 view_->OnTouchEvent(&press); 382 EXPECT_TRUE(press.stopped_propagation()); 383 EXPECT_EQ(WebKit::WebInputEvent::TouchStart, view_->touch_event_.type); 384 EXPECT_EQ(1U, view_->touch_event_.touchesLength); 385 EXPECT_EQ(WebKit::WebTouchPoint::StatePressed, 386 view_->touch_event_.touches[0].state); 387 388 view_->OnTouchEvent(&move); 389 EXPECT_TRUE(move.stopped_propagation()); 390 EXPECT_EQ(WebKit::WebInputEvent::TouchMove, view_->touch_event_.type); 391 EXPECT_EQ(1U, view_->touch_event_.touchesLength); 392 EXPECT_EQ(WebKit::WebTouchPoint::StateMoved, 393 view_->touch_event_.touches[0].state); 394 395 // Send the same move event. Since the point hasn't moved, it won't affect the 396 // queue. However, the view should consume the event. 397 view_->OnTouchEvent(&move); 398 EXPECT_TRUE(move.stopped_propagation()); 399 EXPECT_EQ(WebKit::WebInputEvent::TouchMove, view_->touch_event_.type); 400 EXPECT_EQ(1U, view_->touch_event_.touchesLength); 401 EXPECT_EQ(WebKit::WebTouchPoint::StateMoved, 402 view_->touch_event_.touches[0].state); 403 404 view_->OnTouchEvent(&release); 405 EXPECT_TRUE(release.stopped_propagation()); 406 EXPECT_EQ(WebKit::WebInputEvent::TouchEnd, view_->touch_event_.type); 407 EXPECT_EQ(0U, view_->touch_event_.touchesLength); 408 } 409 410 TEST_F(RenderWidgetHostViewAuraTest, PhysicalBackingSizeWithScale) { 411 view_->InitAsChild(NULL); 412 view_->GetNativeView()->SetDefaultParentByRootWindow( 413 parent_view_->GetNativeView()->GetRootWindow(), gfx::Rect()); 414 sink_->ClearMessages(); 415 view_->SetSize(gfx::Size(100, 100)); 416 EXPECT_EQ("100x100", view_->GetPhysicalBackingSize().ToString()); 417 EXPECT_EQ(1u, sink_->message_count()); 418 EXPECT_EQ(ViewMsg_Resize::ID, sink_->GetMessageAt(0)->type()); 419 { 420 const IPC::Message* msg = sink_->GetMessageAt(0); 421 EXPECT_EQ(ViewMsg_Resize::ID, msg->type()); 422 ViewMsg_Resize::Param params; 423 ViewMsg_Resize::Read(msg, ¶ms); 424 EXPECT_EQ("100x100", params.a.new_size.ToString()); // dip size 425 EXPECT_EQ("100x100", 426 params.a.physical_backing_size.ToString()); // backing size 427 } 428 429 widget_host_->ResetSizeAndRepaintPendingFlags(); 430 sink_->ClearMessages(); 431 432 aura_test_helper_->test_screen()->SetDeviceScaleFactor(2.0f); 433 EXPECT_EQ("200x200", view_->GetPhysicalBackingSize().ToString()); 434 // Extra ScreenInfoChanged message for |parent_view_|. 435 EXPECT_EQ(1u, sink_->message_count()); 436 { 437 const IPC::Message* msg = sink_->GetMessageAt(0); 438 EXPECT_EQ(ViewMsg_Resize::ID, msg->type()); 439 ViewMsg_Resize::Param params; 440 ViewMsg_Resize::Read(msg, ¶ms); 441 EXPECT_EQ(2.0f, params.a.screen_info.deviceScaleFactor); 442 EXPECT_EQ("100x100", params.a.new_size.ToString()); // dip size 443 EXPECT_EQ("200x200", 444 params.a.physical_backing_size.ToString()); // backing size 445 } 446 447 widget_host_->ResetSizeAndRepaintPendingFlags(); 448 sink_->ClearMessages(); 449 450 aura_test_helper_->test_screen()->SetDeviceScaleFactor(1.0f); 451 // Extra ScreenInfoChanged message for |parent_view_|. 452 EXPECT_EQ(1u, sink_->message_count()); 453 EXPECT_EQ("100x100", view_->GetPhysicalBackingSize().ToString()); 454 { 455 const IPC::Message* msg = sink_->GetMessageAt(0); 456 EXPECT_EQ(ViewMsg_Resize::ID, msg->type()); 457 ViewMsg_Resize::Param params; 458 ViewMsg_Resize::Read(msg, ¶ms); 459 EXPECT_EQ(1.0f, params.a.screen_info.deviceScaleFactor); 460 EXPECT_EQ("100x100", params.a.new_size.ToString()); // dip size 461 EXPECT_EQ("100x100", 462 params.a.physical_backing_size.ToString()); // backing size 463 } 464 } 465 466 // Checks that InputMsg_CursorVisibilityChange IPC messages are dispatched 467 // to the renderer at the correct times. 468 TEST_F(RenderWidgetHostViewAuraTest, CursorVisibilityChange) { 469 view_->InitAsChild(NULL); 470 view_->GetNativeView()->SetDefaultParentByRootWindow( 471 parent_view_->GetNativeView()->GetRootWindow(), gfx::Rect()); 472 view_->SetSize(gfx::Size(100, 100)); 473 474 aura::test::TestCursorClient cursor_client( 475 parent_view_->GetNativeView()->GetRootWindow()); 476 477 cursor_client.AddObserver(view_); 478 479 // Expect a message the first time the cursor is shown. 480 view_->WasShown(); 481 sink_->ClearMessages(); 482 cursor_client.ShowCursor(); 483 EXPECT_EQ(1u, sink_->message_count()); 484 EXPECT_TRUE(sink_->GetUniqueMessageMatching( 485 InputMsg_CursorVisibilityChange::ID)); 486 487 // No message expected if the renderer already knows the cursor is visible. 488 sink_->ClearMessages(); 489 cursor_client.ShowCursor(); 490 EXPECT_EQ(0u, sink_->message_count()); 491 492 // Hiding the cursor should send a message. 493 sink_->ClearMessages(); 494 cursor_client.HideCursor(); 495 EXPECT_EQ(1u, sink_->message_count()); 496 EXPECT_TRUE(sink_->GetUniqueMessageMatching( 497 InputMsg_CursorVisibilityChange::ID)); 498 499 // No message expected if the renderer already knows the cursor is invisible. 500 sink_->ClearMessages(); 501 cursor_client.HideCursor(); 502 EXPECT_EQ(0u, sink_->message_count()); 503 504 // No messages should be sent while the view is invisible. 505 view_->WasHidden(); 506 sink_->ClearMessages(); 507 cursor_client.ShowCursor(); 508 EXPECT_EQ(0u, sink_->message_count()); 509 cursor_client.HideCursor(); 510 EXPECT_EQ(0u, sink_->message_count()); 511 512 // Show the view. Since the cursor was invisible when the view was hidden, 513 // no message should be sent. 514 sink_->ClearMessages(); 515 view_->WasShown(); 516 EXPECT_FALSE(sink_->GetUniqueMessageMatching( 517 InputMsg_CursorVisibilityChange::ID)); 518 519 // No message expected if the renderer already knows the cursor is invisible. 520 sink_->ClearMessages(); 521 cursor_client.HideCursor(); 522 EXPECT_EQ(0u, sink_->message_count()); 523 524 // Showing the cursor should send a message. 525 sink_->ClearMessages(); 526 cursor_client.ShowCursor(); 527 EXPECT_EQ(1u, sink_->message_count()); 528 EXPECT_TRUE(sink_->GetUniqueMessageMatching( 529 InputMsg_CursorVisibilityChange::ID)); 530 531 // No messages should be sent while the view is invisible. 532 view_->WasHidden(); 533 sink_->ClearMessages(); 534 cursor_client.HideCursor(); 535 EXPECT_EQ(0u, sink_->message_count()); 536 537 // Show the view. Since the cursor was visible when the view was hidden, 538 // a message is expected to be sent. 539 sink_->ClearMessages(); 540 view_->WasShown(); 541 EXPECT_TRUE(sink_->GetUniqueMessageMatching( 542 InputMsg_CursorVisibilityChange::ID)); 543 544 cursor_client.RemoveObserver(view_); 545 } 546 547 // Resizing in fullscreen mode should send the up-to-date screen info. 548 TEST_F(RenderWidgetHostViewAuraTest, FullscreenResize) { 549 aura::RootWindow* root_window = aura_test_helper_->root_window(); 550 root_window->SetLayoutManager(new FullscreenLayoutManager(root_window)); 551 view_->InitAsFullscreen(parent_view_); 552 view_->WasShown(); 553 widget_host_->ResetSizeAndRepaintPendingFlags(); 554 sink_->ClearMessages(); 555 556 // Call WasResized to flush the old screen info. 557 view_->GetRenderWidgetHost()->WasResized(); 558 { 559 // 0 is CreatingNew message. 560 const IPC::Message* msg = sink_->GetMessageAt(0); 561 EXPECT_EQ(ViewMsg_Resize::ID, msg->type()); 562 ViewMsg_Resize::Param params; 563 ViewMsg_Resize::Read(msg, ¶ms); 564 EXPECT_EQ("0,0 800x600", 565 gfx::Rect(params.a.screen_info.availableRect).ToString()); 566 EXPECT_EQ("800x600", params.a.new_size.ToString()); 567 } 568 569 widget_host_->ResetSizeAndRepaintPendingFlags(); 570 sink_->ClearMessages(); 571 572 // Make sure the corrent screen size is set along in the resize 573 // request when the screen size has changed. 574 aura_test_helper_->test_screen()->SetUIScale(0.5); 575 EXPECT_EQ(1u, sink_->message_count()); 576 { 577 const IPC::Message* msg = sink_->GetMessageAt(0); 578 EXPECT_EQ(ViewMsg_Resize::ID, msg->type()); 579 ViewMsg_Resize::Param params; 580 ViewMsg_Resize::Read(msg, ¶ms); 581 EXPECT_EQ("0,0 1600x1200", 582 gfx::Rect(params.a.screen_info.availableRect).ToString()); 583 EXPECT_EQ("1600x1200", params.a.new_size.ToString()); 584 } 585 } 586 587 } // namespace content 588