Home | History | Annotate | Download | only in renderer_host
      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, &params);
    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, &params);
    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, &params);
    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, &params);
    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, &params);
    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, &params);
    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