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/memory/shared_memory.h"
      9 #include "base/message_loop/message_loop.h"
     10 #include "base/strings/utf_string_conversions.h"
     11 #include "cc/output/compositor_frame.h"
     12 #include "cc/output/compositor_frame_metadata.h"
     13 #include "cc/output/gl_frame_data.h"
     14 #include "content/browser/aura/resize_lock.h"
     15 #include "content/browser/browser_thread_impl.h"
     16 #include "content/browser/renderer_host/render_widget_host_delegate.h"
     17 #include "content/browser/renderer_host/render_widget_host_impl.h"
     18 #include "content/common/gpu/gpu_messages.h"
     19 #include "content/common/input_messages.h"
     20 #include "content/common/view_messages.h"
     21 #include "content/public/browser/render_widget_host_view.h"
     22 #include "content/public/test/mock_render_process_host.h"
     23 #include "content/public/test/test_browser_context.h"
     24 #include "ipc/ipc_test_sink.h"
     25 #include "testing/gmock/include/gmock/gmock.h"
     26 #include "testing/gtest/include/gtest/gtest.h"
     27 #include "ui/aura/client/aura_constants.h"
     28 #include "ui/aura/client/screen_position_client.h"
     29 #include "ui/aura/client/window_tree_client.h"
     30 #include "ui/aura/env.h"
     31 #include "ui/aura/layout_manager.h"
     32 #include "ui/aura/root_window.h"
     33 #include "ui/aura/test/aura_test_helper.h"
     34 #include "ui/aura/test/test_cursor_client.h"
     35 #include "ui/aura/test/test_screen.h"
     36 #include "ui/aura/test/test_window_delegate.h"
     37 #include "ui/aura/window.h"
     38 #include "ui/aura/window_observer.h"
     39 #include "ui/base/ui_base_types.h"
     40 #include "ui/compositor/compositor.h"
     41 #include "ui/compositor/test/test_context_factory.h"
     42 #include "ui/events/event.h"
     43 #include "ui/events/event_utils.h"
     44 
     45 using testing::_;
     46 
     47 namespace content {
     48 namespace {
     49 
     50 // Simple screen position client to test coordinate system conversion.
     51 class TestScreenPositionClient
     52     : public aura::client::ScreenPositionClient {
     53  public:
     54   TestScreenPositionClient() {}
     55   virtual ~TestScreenPositionClient() {}
     56 
     57   // aura::client::ScreenPositionClient overrides:
     58   virtual void ConvertPointToScreen(const aura::Window* window,
     59       gfx::Point* point) OVERRIDE {
     60     point->Offset(-1, -1);
     61   }
     62 
     63   virtual void ConvertPointFromScreen(const aura::Window* window,
     64       gfx::Point* point) OVERRIDE {
     65     point->Offset(1, 1);
     66   }
     67 
     68   virtual void ConvertHostPointToScreen(aura::Window* window,
     69       gfx::Point* point) OVERRIDE {
     70     ConvertPointToScreen(window, point);
     71   }
     72 
     73   virtual void SetBounds(aura::Window* window,
     74       const gfx::Rect& bounds,
     75       const gfx::Display& display) OVERRIDE {
     76   }
     77 };
     78 
     79 class MockRenderWidgetHostDelegate : public RenderWidgetHostDelegate {
     80  public:
     81   MockRenderWidgetHostDelegate() {}
     82   virtual ~MockRenderWidgetHostDelegate() {}
     83 };
     84 
     85 // Simple observer that keeps track of changes to a window for tests.
     86 class TestWindowObserver : public aura::WindowObserver {
     87  public:
     88   explicit TestWindowObserver(aura::Window* window_to_observe)
     89       : window_(window_to_observe) {
     90     window_->AddObserver(this);
     91   }
     92   virtual ~TestWindowObserver() {
     93     if (window_)
     94       window_->RemoveObserver(this);
     95   }
     96 
     97   bool destroyed() const { return destroyed_; }
     98 
     99   // aura::WindowObserver overrides:
    100   virtual void OnWindowDestroyed(aura::Window* window) OVERRIDE {
    101     CHECK_EQ(window, window_);
    102     destroyed_ = true;
    103     window_ = NULL;
    104   }
    105 
    106  private:
    107   // Window that we're observing, or NULL if it's been destroyed.
    108   aura::Window* window_;
    109 
    110   // Was |window_| destroyed?
    111   bool destroyed_;
    112 
    113   DISALLOW_COPY_AND_ASSIGN(TestWindowObserver);
    114 };
    115 
    116 class FakeRenderWidgetHostViewAura : public RenderWidgetHostViewAura {
    117  public:
    118   FakeRenderWidgetHostViewAura(RenderWidgetHost* widget)
    119       : RenderWidgetHostViewAura(widget), has_resize_lock_(false) {}
    120 
    121   virtual ~FakeRenderWidgetHostViewAura() {}
    122 
    123   virtual bool ShouldCreateResizeLock() OVERRIDE {
    124     gfx::Size desired_size = window()->bounds().size();
    125     return desired_size != current_frame_size();
    126   }
    127 
    128   virtual scoped_ptr<ResizeLock> CreateResizeLock(bool defer_compositor_lock)
    129       OVERRIDE {
    130     gfx::Size desired_size = window()->bounds().size();
    131     return scoped_ptr<ResizeLock>(
    132         new FakeResizeLock(desired_size, defer_compositor_lock));
    133   }
    134 
    135   void RunOnCompositingDidCommit() {
    136     OnCompositingDidCommit(window()->GetDispatcher()->compositor());
    137   }
    138 
    139   // A lock that doesn't actually do anything to the compositor, and does not
    140   // time out.
    141   class FakeResizeLock : public ResizeLock {
    142    public:
    143     FakeResizeLock(const gfx::Size new_size, bool defer_compositor_lock)
    144         : ResizeLock(new_size, defer_compositor_lock) {}
    145   };
    146 
    147   bool has_resize_lock_;
    148   gfx::Size last_frame_size_;
    149 };
    150 
    151 class RenderWidgetHostViewAuraTest : public testing::Test {
    152  public:
    153   RenderWidgetHostViewAuraTest()
    154       : browser_thread_for_ui_(BrowserThread::UI, &message_loop_) {}
    155 
    156   virtual void SetUp() {
    157     ImageTransportFactory::InitializeForUnitTests(
    158         scoped_ptr<ui::ContextFactory>(new ui::TestContextFactory));
    159     aura_test_helper_.reset(new aura::test::AuraTestHelper(&message_loop_));
    160     aura_test_helper_->SetUp();
    161 
    162     browser_context_.reset(new TestBrowserContext);
    163     process_host_ = new MockRenderProcessHost(browser_context_.get());
    164 
    165     sink_ = &process_host_->sink();
    166 
    167     parent_host_ = new RenderWidgetHostImpl(
    168         &delegate_, process_host_, MSG_ROUTING_NONE, false);
    169     parent_view_ = static_cast<RenderWidgetHostViewAura*>(
    170         RenderWidgetHostView::CreateViewForWidget(parent_host_));
    171     parent_view_->InitAsChild(NULL);
    172     aura::client::ParentWindowWithContext(parent_view_->GetNativeView(),
    173                                           aura_test_helper_->root_window(),
    174                                           gfx::Rect());
    175 
    176     widget_host_ = new RenderWidgetHostImpl(
    177         &delegate_, process_host_, MSG_ROUTING_NONE, false);
    178     widget_host_->Init();
    179     widget_host_->OnMessageReceived(
    180         ViewHostMsg_DidActivateAcceleratedCompositing(0, true));
    181     view_ = new FakeRenderWidgetHostViewAura(widget_host_);
    182   }
    183 
    184   virtual void TearDown() {
    185     sink_ = NULL;
    186     process_host_ = NULL;
    187     if (view_)
    188       view_->Destroy();
    189     delete widget_host_;
    190 
    191     parent_view_->Destroy();
    192     delete parent_host_;
    193 
    194     browser_context_.reset();
    195     aura_test_helper_->TearDown();
    196 
    197     message_loop_.DeleteSoon(FROM_HERE, browser_context_.release());
    198     message_loop_.RunUntilIdle();
    199     ImageTransportFactory::Terminate();
    200   }
    201 
    202  protected:
    203   base::MessageLoopForUI message_loop_;
    204   BrowserThreadImpl browser_thread_for_ui_;
    205   scoped_ptr<aura::test::AuraTestHelper> aura_test_helper_;
    206   scoped_ptr<BrowserContext> browser_context_;
    207   MockRenderWidgetHostDelegate delegate_;
    208   MockRenderProcessHost* process_host_;
    209 
    210   // Tests should set these to NULL if they've already triggered their
    211   // destruction.
    212   RenderWidgetHostImpl* parent_host_;
    213   RenderWidgetHostViewAura* parent_view_;
    214 
    215   // Tests should set these to NULL if they've already triggered their
    216   // destruction.
    217   RenderWidgetHostImpl* widget_host_;
    218   FakeRenderWidgetHostViewAura* view_;
    219 
    220   IPC::TestSink* sink_;
    221 
    222  private:
    223   DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostViewAuraTest);
    224 };
    225 
    226 // A layout manager that always resizes a child to the root window size.
    227 class FullscreenLayoutManager : public aura::LayoutManager {
    228  public:
    229   explicit FullscreenLayoutManager(aura::Window* owner)
    230       : owner_(owner) {}
    231   virtual ~FullscreenLayoutManager() {}
    232 
    233   // Overridden from aura::LayoutManager:
    234   virtual void OnWindowResized() OVERRIDE {
    235     aura::Window::Windows::const_iterator i;
    236     for (i = owner_->children().begin(); i != owner_->children().end(); ++i) {
    237       (*i)->SetBounds(gfx::Rect());
    238     }
    239   }
    240   virtual void OnWindowAddedToLayout(aura::Window* child) OVERRIDE {
    241     child->SetBounds(gfx::Rect());
    242   }
    243   virtual void OnWillRemoveWindowFromLayout(aura::Window* child) OVERRIDE {
    244   }
    245   virtual void OnWindowRemovedFromLayout(aura::Window* child) OVERRIDE {
    246   }
    247   virtual void OnChildWindowVisibilityChanged(aura::Window* child,
    248                                               bool visible) OVERRIDE {
    249   }
    250   virtual void SetChildBounds(aura::Window* child,
    251                               const gfx::Rect& requested_bounds) OVERRIDE {
    252     SetChildBoundsDirect(child, gfx::Rect(owner_->bounds().size()));
    253   }
    254 
    255  private:
    256   aura::Window* owner_;
    257   DISALLOW_COPY_AND_ASSIGN(FullscreenLayoutManager);
    258 };
    259 
    260 class MockWindowObserver : public aura::WindowObserver {
    261  public:
    262   MOCK_METHOD2(OnWindowPaintScheduled, void(aura::Window*, const gfx::Rect&));
    263 };
    264 
    265 }  // namespace
    266 
    267 // Checks that a fullscreen view has the correct show-state and receives the
    268 // focus.
    269 TEST_F(RenderWidgetHostViewAuraTest, FocusFullscreen) {
    270   view_->InitAsFullscreen(parent_view_);
    271   aura::Window* window = view_->GetNativeView();
    272   ASSERT_TRUE(window != NULL);
    273   EXPECT_EQ(ui::SHOW_STATE_FULLSCREEN,
    274             window->GetProperty(aura::client::kShowStateKey));
    275 
    276   // Check that we requested and received the focus.
    277   EXPECT_TRUE(window->HasFocus());
    278 
    279   // Check that we'll also say it's okay to activate the window when there's an
    280   // ActivationClient defined.
    281   EXPECT_TRUE(view_->ShouldActivate());
    282 }
    283 
    284 // Checks that a popup is positioned correctly relative to its parent using
    285 // screen coordinates.
    286 TEST_F(RenderWidgetHostViewAuraTest, PositionChildPopup) {
    287   TestScreenPositionClient screen_position_client;
    288 
    289   aura::Window* window = parent_view_->GetNativeView();
    290   aura::Window* root = window->GetRootWindow();
    291   aura::client::SetScreenPositionClient(root, &screen_position_client);
    292 
    293   parent_view_->SetBounds(gfx::Rect(10, 10, 800, 600));
    294   gfx::Rect bounds_in_screen = parent_view_->GetViewBounds();
    295   int horiz = bounds_in_screen.width() / 4;
    296   int vert = bounds_in_screen.height() / 4;
    297   bounds_in_screen.Inset(horiz, vert);
    298 
    299   // Verify that when the popup is initialized for the first time, it correctly
    300   // treats the input bounds as screen coordinates.
    301   view_->InitAsPopup(parent_view_, bounds_in_screen);
    302 
    303   gfx::Rect final_bounds_in_screen = view_->GetViewBounds();
    304   EXPECT_EQ(final_bounds_in_screen.ToString(), bounds_in_screen.ToString());
    305 
    306   // Verify that directly setting the bounds via SetBounds() treats the input
    307   // as screen coordinates.
    308   bounds_in_screen = gfx::Rect(60, 60, 100, 100);
    309   view_->SetBounds(bounds_in_screen);
    310   final_bounds_in_screen = view_->GetViewBounds();
    311   EXPECT_EQ(final_bounds_in_screen.ToString(), bounds_in_screen.ToString());
    312 
    313   // Verify that setting the size does not alter the origin.
    314   gfx::Point original_origin = window->bounds().origin();
    315   view_->SetSize(gfx::Size(120, 120));
    316   gfx::Point new_origin = window->bounds().origin();
    317   EXPECT_EQ(original_origin.ToString(), new_origin.ToString());
    318 
    319   aura::client::SetScreenPositionClient(root, NULL);
    320 }
    321 
    322 // Checks that a fullscreen view is destroyed when it loses the focus.
    323 TEST_F(RenderWidgetHostViewAuraTest, DestroyFullscreenOnBlur) {
    324   view_->InitAsFullscreen(parent_view_);
    325   aura::Window* window = view_->GetNativeView();
    326   ASSERT_TRUE(window != NULL);
    327   ASSERT_TRUE(window->HasFocus());
    328 
    329   // After we create and focus another window, the RWHVA's window should be
    330   // destroyed.
    331   TestWindowObserver observer(window);
    332   aura::test::TestWindowDelegate delegate;
    333   scoped_ptr<aura::Window> sibling(new aura::Window(&delegate));
    334   sibling->Init(ui::LAYER_TEXTURED);
    335   sibling->Show();
    336   window->parent()->AddChild(sibling.get());
    337   sibling->Focus();
    338   ASSERT_TRUE(sibling->HasFocus());
    339   ASSERT_TRUE(observer.destroyed());
    340 
    341   widget_host_ = NULL;
    342   view_ = NULL;
    343 }
    344 
    345 // Checks that IME-composition-event state is maintained correctly.
    346 TEST_F(RenderWidgetHostViewAuraTest, SetCompositionText) {
    347   view_->InitAsChild(NULL);
    348   view_->Show();
    349 
    350   ui::CompositionText composition_text;
    351   composition_text.text = ASCIIToUTF16("|a|b");
    352 
    353   // Focused segment
    354   composition_text.underlines.push_back(
    355       ui::CompositionUnderline(0, 3, 0xff000000, true));
    356 
    357   // Non-focused segment
    358   composition_text.underlines.push_back(
    359       ui::CompositionUnderline(3, 4, 0xff000000, false));
    360 
    361   const ui::CompositionUnderlines& underlines = composition_text.underlines;
    362 
    363   // Caret is at the end. (This emulates Japanese MSIME 2007 and later)
    364   composition_text.selection = gfx::Range(4);
    365 
    366   sink_->ClearMessages();
    367   view_->SetCompositionText(composition_text);
    368   EXPECT_TRUE(view_->has_composition_text_);
    369   {
    370     const IPC::Message* msg =
    371       sink_->GetFirstMessageMatching(ViewMsg_ImeSetComposition::ID);
    372     ASSERT_TRUE(msg != NULL);
    373 
    374     ViewMsg_ImeSetComposition::Param params;
    375     ViewMsg_ImeSetComposition::Read(msg, &params);
    376     // composition text
    377     EXPECT_EQ(composition_text.text, params.a);
    378     // underlines
    379     ASSERT_EQ(underlines.size(), params.b.size());
    380     for (size_t i = 0; i < underlines.size(); ++i) {
    381       EXPECT_EQ(underlines[i].start_offset, params.b[i].startOffset);
    382       EXPECT_EQ(underlines[i].end_offset, params.b[i].endOffset);
    383       EXPECT_EQ(underlines[i].color, params.b[i].color);
    384       EXPECT_EQ(underlines[i].thick, params.b[i].thick);
    385     }
    386     // highlighted range
    387     EXPECT_EQ(4, params.c) << "Should be the same to the caret pos";
    388     EXPECT_EQ(4, params.d) << "Should be the same to the caret pos";
    389   }
    390 
    391   view_->ImeCancelComposition();
    392   EXPECT_FALSE(view_->has_composition_text_);
    393 }
    394 
    395 // Checks that touch-event state is maintained correctly.
    396 TEST_F(RenderWidgetHostViewAuraTest, TouchEventState) {
    397   view_->InitAsChild(NULL);
    398   view_->Show();
    399 
    400   // Start with no touch-event handler in the renderer.
    401   widget_host_->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, false));
    402   EXPECT_FALSE(widget_host_->ShouldForwardTouchEvent());
    403 
    404   ui::TouchEvent press(ui::ET_TOUCH_PRESSED,
    405                        gfx::Point(30, 30),
    406                        0,
    407                        ui::EventTimeForNow());
    408   ui::TouchEvent move(ui::ET_TOUCH_MOVED,
    409                       gfx::Point(20, 20),
    410                       0,
    411                       ui::EventTimeForNow());
    412   ui::TouchEvent release(ui::ET_TOUCH_RELEASED,
    413                          gfx::Point(20, 20),
    414                          0,
    415                          ui::EventTimeForNow());
    416 
    417   view_->OnTouchEvent(&press);
    418   EXPECT_FALSE(press.handled());
    419   EXPECT_EQ(blink::WebInputEvent::TouchStart, view_->touch_event_.type);
    420   EXPECT_EQ(1U, view_->touch_event_.touchesLength);
    421   EXPECT_EQ(blink::WebTouchPoint::StatePressed,
    422             view_->touch_event_.touches[0].state);
    423 
    424   view_->OnTouchEvent(&move);
    425   EXPECT_FALSE(move.handled());
    426   EXPECT_EQ(blink::WebInputEvent::TouchMove, view_->touch_event_.type);
    427   EXPECT_EQ(1U, view_->touch_event_.touchesLength);
    428   EXPECT_EQ(blink::WebTouchPoint::StateMoved,
    429             view_->touch_event_.touches[0].state);
    430 
    431   view_->OnTouchEvent(&release);
    432   EXPECT_FALSE(release.handled());
    433   EXPECT_EQ(blink::WebInputEvent::TouchEnd, view_->touch_event_.type);
    434   EXPECT_EQ(0U, view_->touch_event_.touchesLength);
    435 
    436   // Now install some touch-event handlers and do the same steps. The touch
    437   // events should now be consumed. However, the touch-event state should be
    438   // updated as before.
    439   widget_host_->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, true));
    440   EXPECT_TRUE(widget_host_->ShouldForwardTouchEvent());
    441 
    442   view_->OnTouchEvent(&press);
    443   EXPECT_TRUE(press.stopped_propagation());
    444   EXPECT_EQ(blink::WebInputEvent::TouchStart, view_->touch_event_.type);
    445   EXPECT_EQ(1U, view_->touch_event_.touchesLength);
    446   EXPECT_EQ(blink::WebTouchPoint::StatePressed,
    447             view_->touch_event_.touches[0].state);
    448 
    449   view_->OnTouchEvent(&move);
    450   EXPECT_TRUE(move.stopped_propagation());
    451   EXPECT_EQ(blink::WebInputEvent::TouchMove, view_->touch_event_.type);
    452   EXPECT_EQ(1U, view_->touch_event_.touchesLength);
    453   EXPECT_EQ(blink::WebTouchPoint::StateMoved,
    454             view_->touch_event_.touches[0].state);
    455 
    456   view_->OnTouchEvent(&release);
    457   EXPECT_TRUE(release.stopped_propagation());
    458   EXPECT_EQ(blink::WebInputEvent::TouchEnd, view_->touch_event_.type);
    459   EXPECT_EQ(0U, view_->touch_event_.touchesLength);
    460 
    461   // Now start a touch event, and remove the event-handlers before the release.
    462   view_->OnTouchEvent(&press);
    463   EXPECT_TRUE(press.stopped_propagation());
    464   EXPECT_EQ(blink::WebInputEvent::TouchStart, view_->touch_event_.type);
    465   EXPECT_EQ(1U, view_->touch_event_.touchesLength);
    466   EXPECT_EQ(blink::WebTouchPoint::StatePressed,
    467             view_->touch_event_.touches[0].state);
    468 
    469   widget_host_->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, false));
    470   EXPECT_FALSE(widget_host_->ShouldForwardTouchEvent());
    471 
    472   ui::TouchEvent move2(ui::ET_TOUCH_MOVED, gfx::Point(20, 20), 0,
    473       base::Time::NowFromSystemTime() - base::Time());
    474   view_->OnTouchEvent(&move2);
    475   EXPECT_FALSE(move2.handled());
    476   EXPECT_EQ(blink::WebInputEvent::TouchMove, view_->touch_event_.type);
    477   EXPECT_EQ(1U, view_->touch_event_.touchesLength);
    478   EXPECT_EQ(blink::WebTouchPoint::StateMoved,
    479             view_->touch_event_.touches[0].state);
    480 
    481   ui::TouchEvent release2(ui::ET_TOUCH_RELEASED, gfx::Point(20, 20), 0,
    482       base::Time::NowFromSystemTime() - base::Time());
    483   view_->OnTouchEvent(&release2);
    484   EXPECT_FALSE(release2.handled());
    485   EXPECT_EQ(blink::WebInputEvent::TouchEnd, view_->touch_event_.type);
    486   EXPECT_EQ(0U, view_->touch_event_.touchesLength);
    487 }
    488 
    489 // Checks that touch-events are queued properly when there is a touch-event
    490 // handler on the page.
    491 TEST_F(RenderWidgetHostViewAuraTest, TouchEventSyncAsync) {
    492   view_->InitAsChild(NULL);
    493   view_->Show();
    494 
    495   widget_host_->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, true));
    496   EXPECT_TRUE(widget_host_->ShouldForwardTouchEvent());
    497 
    498   ui::TouchEvent press(ui::ET_TOUCH_PRESSED,
    499                        gfx::Point(30, 30),
    500                        0,
    501                        ui::EventTimeForNow());
    502   ui::TouchEvent move(ui::ET_TOUCH_MOVED,
    503                       gfx::Point(20, 20),
    504                       0,
    505                       ui::EventTimeForNow());
    506   ui::TouchEvent release(ui::ET_TOUCH_RELEASED,
    507                          gfx::Point(20, 20),
    508                          0,
    509                          ui::EventTimeForNow());
    510 
    511   view_->OnTouchEvent(&press);
    512   EXPECT_TRUE(press.stopped_propagation());
    513   EXPECT_EQ(blink::WebInputEvent::TouchStart, view_->touch_event_.type);
    514   EXPECT_EQ(1U, view_->touch_event_.touchesLength);
    515   EXPECT_EQ(blink::WebTouchPoint::StatePressed,
    516             view_->touch_event_.touches[0].state);
    517 
    518   view_->OnTouchEvent(&move);
    519   EXPECT_TRUE(move.stopped_propagation());
    520   EXPECT_EQ(blink::WebInputEvent::TouchMove, view_->touch_event_.type);
    521   EXPECT_EQ(1U, view_->touch_event_.touchesLength);
    522   EXPECT_EQ(blink::WebTouchPoint::StateMoved,
    523             view_->touch_event_.touches[0].state);
    524 
    525   // Send the same move event. Since the point hasn't moved, it won't affect the
    526   // queue. However, the view should consume the event.
    527   view_->OnTouchEvent(&move);
    528   EXPECT_TRUE(move.stopped_propagation());
    529   EXPECT_EQ(blink::WebInputEvent::TouchMove, view_->touch_event_.type);
    530   EXPECT_EQ(1U, view_->touch_event_.touchesLength);
    531   EXPECT_EQ(blink::WebTouchPoint::StateMoved,
    532             view_->touch_event_.touches[0].state);
    533 
    534   view_->OnTouchEvent(&release);
    535   EXPECT_TRUE(release.stopped_propagation());
    536   EXPECT_EQ(blink::WebInputEvent::TouchEnd, view_->touch_event_.type);
    537   EXPECT_EQ(0U, view_->touch_event_.touchesLength);
    538 }
    539 
    540 TEST_F(RenderWidgetHostViewAuraTest, PhysicalBackingSizeWithScale) {
    541   view_->InitAsChild(NULL);
    542   aura::client::ParentWindowWithContext(
    543       view_->GetNativeView(),
    544       parent_view_->GetNativeView()->GetRootWindow(),
    545       gfx::Rect());
    546   sink_->ClearMessages();
    547   view_->SetSize(gfx::Size(100, 100));
    548   EXPECT_EQ("100x100", view_->GetPhysicalBackingSize().ToString());
    549   EXPECT_EQ(1u, sink_->message_count());
    550   EXPECT_EQ(ViewMsg_Resize::ID, sink_->GetMessageAt(0)->type());
    551   {
    552     const IPC::Message* msg = sink_->GetMessageAt(0);
    553     EXPECT_EQ(ViewMsg_Resize::ID, msg->type());
    554     ViewMsg_Resize::Param params;
    555     ViewMsg_Resize::Read(msg, &params);
    556     EXPECT_EQ("100x100", params.a.new_size.ToString());  // dip size
    557     EXPECT_EQ("100x100",
    558         params.a.physical_backing_size.ToString());  // backing size
    559   }
    560 
    561   widget_host_->ResetSizeAndRepaintPendingFlags();
    562   sink_->ClearMessages();
    563 
    564   aura_test_helper_->test_screen()->SetDeviceScaleFactor(2.0f);
    565   EXPECT_EQ("200x200", view_->GetPhysicalBackingSize().ToString());
    566   // Extra ScreenInfoChanged message for |parent_view_|.
    567   EXPECT_EQ(1u, sink_->message_count());
    568   {
    569     const IPC::Message* msg = sink_->GetMessageAt(0);
    570     EXPECT_EQ(ViewMsg_Resize::ID, msg->type());
    571     ViewMsg_Resize::Param params;
    572     ViewMsg_Resize::Read(msg, &params);
    573     EXPECT_EQ(2.0f, params.a.screen_info.deviceScaleFactor);
    574     EXPECT_EQ("100x100", params.a.new_size.ToString());  // dip size
    575     EXPECT_EQ("200x200",
    576         params.a.physical_backing_size.ToString());  // backing size
    577   }
    578 
    579   widget_host_->ResetSizeAndRepaintPendingFlags();
    580   sink_->ClearMessages();
    581 
    582   aura_test_helper_->test_screen()->SetDeviceScaleFactor(1.0f);
    583   // Extra ScreenInfoChanged message for |parent_view_|.
    584   EXPECT_EQ(1u, sink_->message_count());
    585   EXPECT_EQ("100x100", view_->GetPhysicalBackingSize().ToString());
    586   {
    587     const IPC::Message* msg = sink_->GetMessageAt(0);
    588     EXPECT_EQ(ViewMsg_Resize::ID, msg->type());
    589     ViewMsg_Resize::Param params;
    590     ViewMsg_Resize::Read(msg, &params);
    591     EXPECT_EQ(1.0f, params.a.screen_info.deviceScaleFactor);
    592     EXPECT_EQ("100x100", params.a.new_size.ToString());  // dip size
    593     EXPECT_EQ("100x100",
    594         params.a.physical_backing_size.ToString());  // backing size
    595   }
    596 }
    597 
    598 // Checks that InputMsg_CursorVisibilityChange IPC messages are dispatched
    599 // to the renderer at the correct times.
    600 TEST_F(RenderWidgetHostViewAuraTest, CursorVisibilityChange) {
    601   view_->InitAsChild(NULL);
    602   aura::client::ParentWindowWithContext(
    603       view_->GetNativeView(),
    604       parent_view_->GetNativeView()->GetRootWindow(),
    605       gfx::Rect());
    606   view_->SetSize(gfx::Size(100, 100));
    607 
    608   aura::test::TestCursorClient cursor_client(
    609       parent_view_->GetNativeView()->GetRootWindow());
    610 
    611   cursor_client.AddObserver(view_);
    612 
    613   // Expect a message the first time the cursor is shown.
    614   view_->WasShown();
    615   sink_->ClearMessages();
    616   cursor_client.ShowCursor();
    617   EXPECT_EQ(1u, sink_->message_count());
    618   EXPECT_TRUE(sink_->GetUniqueMessageMatching(
    619       InputMsg_CursorVisibilityChange::ID));
    620 
    621   // No message expected if the renderer already knows the cursor is visible.
    622   sink_->ClearMessages();
    623   cursor_client.ShowCursor();
    624   EXPECT_EQ(0u, sink_->message_count());
    625 
    626   // Hiding the cursor should send a message.
    627   sink_->ClearMessages();
    628   cursor_client.HideCursor();
    629   EXPECT_EQ(1u, sink_->message_count());
    630   EXPECT_TRUE(sink_->GetUniqueMessageMatching(
    631       InputMsg_CursorVisibilityChange::ID));
    632 
    633   // No message expected if the renderer already knows the cursor is invisible.
    634   sink_->ClearMessages();
    635   cursor_client.HideCursor();
    636   EXPECT_EQ(0u, sink_->message_count());
    637 
    638   // No messages should be sent while the view is invisible.
    639   view_->WasHidden();
    640   sink_->ClearMessages();
    641   cursor_client.ShowCursor();
    642   EXPECT_EQ(0u, sink_->message_count());
    643   cursor_client.HideCursor();
    644   EXPECT_EQ(0u, sink_->message_count());
    645 
    646   // Show the view. Since the cursor was invisible when the view was hidden,
    647   // no message should be sent.
    648   sink_->ClearMessages();
    649   view_->WasShown();
    650   EXPECT_FALSE(sink_->GetUniqueMessageMatching(
    651       InputMsg_CursorVisibilityChange::ID));
    652 
    653   // No message expected if the renderer already knows the cursor is invisible.
    654   sink_->ClearMessages();
    655   cursor_client.HideCursor();
    656   EXPECT_EQ(0u, sink_->message_count());
    657 
    658   // Showing the cursor should send a message.
    659   sink_->ClearMessages();
    660   cursor_client.ShowCursor();
    661   EXPECT_EQ(1u, sink_->message_count());
    662   EXPECT_TRUE(sink_->GetUniqueMessageMatching(
    663       InputMsg_CursorVisibilityChange::ID));
    664 
    665   // No messages should be sent while the view is invisible.
    666   view_->WasHidden();
    667   sink_->ClearMessages();
    668   cursor_client.HideCursor();
    669   EXPECT_EQ(0u, sink_->message_count());
    670 
    671   // Show the view. Since the cursor was visible when the view was hidden,
    672   // a message is expected to be sent.
    673   sink_->ClearMessages();
    674   view_->WasShown();
    675   EXPECT_TRUE(sink_->GetUniqueMessageMatching(
    676       InputMsg_CursorVisibilityChange::ID));
    677 
    678   cursor_client.RemoveObserver(view_);
    679 }
    680 
    681 scoped_ptr<cc::CompositorFrame> MakeGLFrame(float scale_factor,
    682                                             gfx::Size size,
    683                                             gfx::Rect damage) {
    684   scoped_ptr<cc::CompositorFrame> frame(new cc::CompositorFrame);
    685   frame->metadata.device_scale_factor = scale_factor;
    686   frame->gl_frame_data.reset(new cc::GLFrameData);
    687   frame->gl_frame_data->sync_point = 1;
    688   memset(frame->gl_frame_data->mailbox.name, '1', 64);
    689   frame->gl_frame_data->size = size;
    690   frame->gl_frame_data->sub_buffer_rect = damage;
    691   return frame.Pass();
    692 }
    693 
    694 scoped_ptr<cc::CompositorFrame> MakeSoftwareFrame(float scale_factor,
    695                                                   gfx::Size size,
    696                                                   gfx::Rect damage) {
    697   scoped_ptr<cc::CompositorFrame> frame(new cc::CompositorFrame);
    698   frame->metadata.device_scale_factor = scale_factor;
    699   frame->software_frame_data.reset(new cc::SoftwareFrameData);
    700   frame->software_frame_data->id = 1;
    701   frame->software_frame_data->size = size;
    702   frame->software_frame_data->damage_rect = damage;
    703   base::SharedMemory shm;
    704   shm.CreateAndMapAnonymous(size.GetArea() * 4);
    705   shm.GiveToProcess(base::GetCurrentProcessHandle(),
    706                     &frame->software_frame_data->handle);
    707   return frame.Pass();
    708 }
    709 
    710 scoped_ptr<cc::CompositorFrame> MakeDelegatedFrame(float scale_factor,
    711                                                    gfx::Size size,
    712                                                    gfx::Rect damage) {
    713   scoped_ptr<cc::CompositorFrame> frame(new cc::CompositorFrame);
    714   frame->metadata.device_scale_factor = scale_factor;
    715   frame->delegated_frame_data.reset(new cc::DelegatedFrameData);
    716 
    717   scoped_ptr<cc::RenderPass> pass = cc::RenderPass::Create();
    718   pass->SetNew(cc::RenderPass::Id(1, 1),
    719                gfx::Rect(size),
    720                gfx::RectF(damage),
    721                gfx::Transform());
    722   frame->delegated_frame_data->render_pass_list.push_back(pass.Pass());
    723   return frame.Pass();
    724 }
    725 
    726 // Resizing in fullscreen mode should send the up-to-date screen info.
    727 TEST_F(RenderWidgetHostViewAuraTest, FullscreenResize) {
    728   aura::Window* root_window = aura_test_helper_->root_window();
    729   root_window->SetLayoutManager(new FullscreenLayoutManager(root_window));
    730   view_->InitAsFullscreen(parent_view_);
    731   view_->WasShown();
    732   widget_host_->ResetSizeAndRepaintPendingFlags();
    733   sink_->ClearMessages();
    734 
    735   // Call WasResized to flush the old screen info.
    736   view_->GetRenderWidgetHost()->WasResized();
    737   {
    738     // 0 is CreatingNew message.
    739     const IPC::Message* msg = sink_->GetMessageAt(0);
    740     EXPECT_EQ(ViewMsg_Resize::ID, msg->type());
    741     ViewMsg_Resize::Param params;
    742     ViewMsg_Resize::Read(msg, &params);
    743     EXPECT_EQ("0,0 800x600",
    744               gfx::Rect(params.a.screen_info.availableRect).ToString());
    745     EXPECT_EQ("800x600", params.a.new_size.ToString());
    746     // Resizes are blocked until we swapped a frame of the correct size, and
    747     // we've committed it.
    748     view_->OnSwapCompositorFrame(
    749         0, MakeGLFrame(1.f, params.a.new_size, gfx::Rect(params.a.new_size)));
    750     ui::DrawWaiterForTest::WaitForCommit(
    751         root_window->GetDispatcher()->compositor());
    752   }
    753 
    754   widget_host_->ResetSizeAndRepaintPendingFlags();
    755   sink_->ClearMessages();
    756 
    757   // Make sure the corrent screen size is set along in the resize
    758   // request when the screen size has changed.
    759   aura_test_helper_->test_screen()->SetUIScale(0.5);
    760   EXPECT_EQ(1u, sink_->message_count());
    761   {
    762     const IPC::Message* msg = sink_->GetMessageAt(0);
    763     EXPECT_EQ(ViewMsg_Resize::ID, msg->type());
    764     ViewMsg_Resize::Param params;
    765     ViewMsg_Resize::Read(msg, &params);
    766     EXPECT_EQ("0,0 1600x1200",
    767               gfx::Rect(params.a.screen_info.availableRect).ToString());
    768     EXPECT_EQ("1600x1200", params.a.new_size.ToString());
    769     view_->OnSwapCompositorFrame(
    770         0, MakeGLFrame(1.f, params.a.new_size, gfx::Rect(params.a.new_size)));
    771     ui::DrawWaiterForTest::WaitForCommit(
    772         root_window->GetDispatcher()->compositor());
    773   }
    774 }
    775 
    776 // Swapping a frame should notify the window.
    777 TEST_F(RenderWidgetHostViewAuraTest, SwapNotifiesWindow) {
    778   gfx::Size view_size(100, 100);
    779   gfx::Rect view_rect(view_size);
    780 
    781   view_->InitAsChild(NULL);
    782   aura::client::ParentWindowWithContext(
    783       view_->GetNativeView(),
    784       parent_view_->GetNativeView()->GetRootWindow(),
    785       gfx::Rect());
    786   view_->SetSize(view_size);
    787   view_->WasShown();
    788 
    789   MockWindowObserver observer;
    790   view_->window_->AddObserver(&observer);
    791 
    792   // Swap a frame through the GPU path.
    793   GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params params;
    794   params.surface_id = widget_host_->surface_id();
    795   params.route_id = widget_host_->GetRoutingID();
    796   params.mailbox_name = std::string(64, '1');
    797   params.size = view_size;
    798   params.scale_factor = 1.f;
    799 
    800   EXPECT_CALL(observer, OnWindowPaintScheduled(view_->window_, view_rect));
    801   view_->AcceleratedSurfaceBuffersSwapped(params, 0);
    802   testing::Mock::VerifyAndClearExpectations(&observer);
    803 
    804   // DSF = 2
    805   params.size = gfx::Size(200, 200);
    806   params.scale_factor = 2.f;
    807   EXPECT_CALL(observer, OnWindowPaintScheduled(view_->window_, view_rect));
    808   view_->AcceleratedSurfaceBuffersSwapped(params, 0);
    809   testing::Mock::VerifyAndClearExpectations(&observer);
    810 
    811   // Partial frames though GPU path
    812   GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params post_params;
    813   post_params.surface_id = widget_host_->surface_id();
    814   post_params.route_id = widget_host_->GetRoutingID();
    815   post_params.mailbox_name = std::string(64, '1');
    816   post_params.surface_size = gfx::Size(200, 200);
    817   post_params.surface_scale_factor = 2.f;
    818   post_params.x = 40;
    819   post_params.y = 40;
    820   post_params.width = 80;
    821   post_params.height = 80;
    822   // rect from params is upside down, and is inflated in RWHVA, just because.
    823   EXPECT_CALL(observer, OnWindowPaintScheduled(view_->window_,
    824                                                gfx::Rect(19, 39, 42, 42)));
    825   view_->AcceleratedSurfacePostSubBuffer(post_params, 0);
    826   testing::Mock::VerifyAndClearExpectations(&observer);
    827 
    828   // Composite-to-mailbox path
    829   EXPECT_CALL(observer, OnWindowPaintScheduled(view_->window_, view_rect));
    830   view_->OnSwapCompositorFrame(0, MakeGLFrame(1.f, view_size, view_rect));
    831   testing::Mock::VerifyAndClearExpectations(&observer);
    832 
    833   // rect from GL frame is upside down, and is inflated in RWHVA, just because.
    834   EXPECT_CALL(observer, OnWindowPaintScheduled(view_->window_,
    835                                                gfx::Rect(4, 89, 7, 7)));
    836   view_->OnSwapCompositorFrame(
    837       0, MakeGLFrame(1.f, view_size, gfx::Rect(5, 5, 5, 5)));
    838   testing::Mock::VerifyAndClearExpectations(&observer);
    839 
    840   // Software path
    841   EXPECT_CALL(observer, OnWindowPaintScheduled(view_->window_, view_rect));
    842   view_->OnSwapCompositorFrame(0, MakeSoftwareFrame(1.f, view_size, view_rect));
    843   testing::Mock::VerifyAndClearExpectations(&observer);
    844 
    845   EXPECT_CALL(observer, OnWindowPaintScheduled(view_->window_,
    846                                                gfx::Rect(5, 5, 5, 5)));
    847   view_->OnSwapCompositorFrame(
    848       0, MakeSoftwareFrame(1.f, view_size, gfx::Rect(5, 5, 5, 5)));
    849   testing::Mock::VerifyAndClearExpectations(&observer);
    850 
    851   // Delegated renderer path
    852   EXPECT_CALL(observer, OnWindowPaintScheduled(view_->window_, view_rect));
    853   view_->OnSwapCompositorFrame(
    854       0, MakeDelegatedFrame(1.f, view_size, view_rect));
    855   testing::Mock::VerifyAndClearExpectations(&observer);
    856 
    857   EXPECT_CALL(observer, OnWindowPaintScheduled(view_->window_,
    858                                                gfx::Rect(5, 5, 5, 5)));
    859   view_->OnSwapCompositorFrame(
    860       0, MakeDelegatedFrame(1.f, view_size, gfx::Rect(5, 5, 5, 5)));
    861   testing::Mock::VerifyAndClearExpectations(&observer);
    862 
    863   view_->window_->RemoveObserver(&observer);
    864 }
    865 
    866 // Skipped frames should not drop their damage.
    867 TEST_F(RenderWidgetHostViewAuraTest, SkippedDelegatedFrames) {
    868   gfx::Rect view_rect(100, 100);
    869   gfx::Size frame_size = view_rect.size();
    870 
    871   view_->InitAsChild(NULL);
    872   aura::client::ParentWindowWithContext(
    873       view_->GetNativeView(),
    874       parent_view_->GetNativeView()->GetRootWindow(),
    875       gfx::Rect());
    876   view_->SetSize(view_rect.size());
    877 
    878   MockWindowObserver observer;
    879   view_->window_->AddObserver(&observer);
    880 
    881   // A full frame of damage.
    882   EXPECT_CALL(observer, OnWindowPaintScheduled(view_->window_, view_rect));
    883   view_->OnSwapCompositorFrame(
    884       0, MakeDelegatedFrame(1.f, frame_size, view_rect));
    885   testing::Mock::VerifyAndClearExpectations(&observer);
    886   view_->RunOnCompositingDidCommit();
    887 
    888   // A partial damage frame.
    889   gfx::Rect partial_view_rect(30, 30, 20, 20);
    890   EXPECT_CALL(observer,
    891               OnWindowPaintScheduled(view_->window_, partial_view_rect));
    892   view_->OnSwapCompositorFrame(
    893       0, MakeDelegatedFrame(1.f, frame_size, partial_view_rect));
    894   testing::Mock::VerifyAndClearExpectations(&observer);
    895   view_->RunOnCompositingDidCommit();
    896 
    897   // Lock the compositor. Now we should drop frames.
    898   view_rect = gfx::Rect(150, 150);
    899   view_->SetSize(view_rect.size());
    900   view_->MaybeCreateResizeLock();
    901 
    902   // This frame is dropped.
    903   gfx::Rect dropped_damage_rect_1(10, 20, 30, 40);
    904   EXPECT_CALL(observer, OnWindowPaintScheduled(_, _)).Times(0);
    905   view_->OnSwapCompositorFrame(
    906       0, MakeDelegatedFrame(1.f, frame_size, dropped_damage_rect_1));
    907   testing::Mock::VerifyAndClearExpectations(&observer);
    908   view_->RunOnCompositingDidCommit();
    909 
    910   gfx::Rect dropped_damage_rect_2(40, 50, 10, 20);
    911   EXPECT_CALL(observer, OnWindowPaintScheduled(_, _)).Times(0);
    912   view_->OnSwapCompositorFrame(
    913       0, MakeDelegatedFrame(1.f, frame_size, dropped_damage_rect_2));
    914   testing::Mock::VerifyAndClearExpectations(&observer);
    915   view_->RunOnCompositingDidCommit();
    916 
    917   // Unlock the compositor. This frame should damage everything.
    918   frame_size = view_rect.size();
    919 
    920   gfx::Rect new_damage_rect(5, 6, 10, 10);
    921   EXPECT_CALL(observer,
    922               OnWindowPaintScheduled(view_->window_, view_rect));
    923   view_->OnSwapCompositorFrame(
    924       0, MakeDelegatedFrame(1.f, frame_size, new_damage_rect));
    925   testing::Mock::VerifyAndClearExpectations(&observer);
    926   view_->RunOnCompositingDidCommit();
    927 
    928   // A partial damage frame, this should not be dropped.
    929   EXPECT_CALL(observer,
    930               OnWindowPaintScheduled(view_->window_, partial_view_rect));
    931   view_->OnSwapCompositorFrame(
    932       0, MakeDelegatedFrame(1.f, frame_size, partial_view_rect));
    933   testing::Mock::VerifyAndClearExpectations(&observer);
    934   view_->RunOnCompositingDidCommit();
    935 
    936 
    937   view_->window_->RemoveObserver(&observer);
    938 }
    939 
    940 TEST_F(RenderWidgetHostViewAuraTest, OutputSurfaceIdChange) {
    941   gfx::Rect view_rect(100, 100);
    942   gfx::Size frame_size = view_rect.size();
    943 
    944   view_->InitAsChild(NULL);
    945   aura::client::ParentWindowWithContext(
    946       view_->GetNativeView(),
    947       parent_view_->GetNativeView()->GetRootWindow(),
    948       gfx::Rect());
    949   view_->SetSize(view_rect.size());
    950 
    951   MockWindowObserver observer;
    952   view_->window_->AddObserver(&observer);
    953 
    954   // Swap a frame.
    955   EXPECT_CALL(observer, OnWindowPaintScheduled(view_->window_, view_rect));
    956   view_->OnSwapCompositorFrame(
    957       0, MakeDelegatedFrame(1.f, frame_size, view_rect));
    958   testing::Mock::VerifyAndClearExpectations(&observer);
    959   view_->RunOnCompositingDidCommit();
    960 
    961   // Swap a frame with a different surface id.
    962   EXPECT_CALL(observer, OnWindowPaintScheduled(view_->window_, view_rect));
    963   view_->OnSwapCompositorFrame(
    964       1, MakeDelegatedFrame(1.f, frame_size, view_rect));
    965   testing::Mock::VerifyAndClearExpectations(&observer);
    966   view_->RunOnCompositingDidCommit();
    967 
    968   // Swap an empty frame, with a different surface id.
    969   view_->OnSwapCompositorFrame(
    970       2, MakeDelegatedFrame(1.f, gfx::Size(), gfx::Rect()));
    971   testing::Mock::VerifyAndClearExpectations(&observer);
    972   view_->RunOnCompositingDidCommit();
    973 
    974   // Swap another frame, with a different surface id.
    975   EXPECT_CALL(observer, OnWindowPaintScheduled(view_->window_, view_rect));
    976   view_->OnSwapCompositorFrame(3,
    977                                MakeDelegatedFrame(1.f, frame_size, view_rect));
    978   testing::Mock::VerifyAndClearExpectations(&observer);
    979   view_->RunOnCompositingDidCommit();
    980 
    981   view_->window_->RemoveObserver(&observer);
    982 }
    983 
    984 TEST_F(RenderWidgetHostViewAuraTest, DiscardDelegatedFrames) {
    985   size_t max_renderer_frames =
    986       RendererFrameManager::GetInstance()->max_number_of_saved_frames();
    987   ASSERT_LE(2u, max_renderer_frames);
    988   size_t renderer_count = max_renderer_frames + 1;
    989   gfx::Rect view_rect(100, 100);
    990   gfx::Size frame_size = view_rect.size();
    991 
    992   scoped_ptr<RenderWidgetHostImpl * []> hosts(
    993       new RenderWidgetHostImpl* [renderer_count]);
    994   scoped_ptr<FakeRenderWidgetHostViewAura * []> views(
    995       new FakeRenderWidgetHostViewAura* [renderer_count]);
    996 
    997   // Create a bunch of renderers.
    998   for (size_t i = 0; i < renderer_count; ++i) {
    999     hosts[i] = new RenderWidgetHostImpl(
   1000         &delegate_, process_host_, MSG_ROUTING_NONE, false);
   1001     hosts[i]->Init();
   1002     hosts[i]->OnMessageReceived(
   1003         ViewHostMsg_DidActivateAcceleratedCompositing(0, true));
   1004     views[i] = new FakeRenderWidgetHostViewAura(hosts[i]);
   1005     views[i]->InitAsChild(NULL);
   1006     aura::client::ParentWindowWithContext(
   1007         views[i]->GetNativeView(),
   1008         parent_view_->GetNativeView()->GetRootWindow(),
   1009         gfx::Rect());
   1010     views[i]->SetSize(view_rect.size());
   1011   }
   1012 
   1013   // Make each renderer visible, and swap a frame on it, then make it invisible.
   1014   for (size_t i = 0; i < renderer_count; ++i) {
   1015     views[i]->WasShown();
   1016     views[i]->OnSwapCompositorFrame(
   1017         1, MakeDelegatedFrame(1.f, frame_size, view_rect));
   1018     EXPECT_TRUE(views[i]->frame_provider_);
   1019     views[i]->WasHidden();
   1020   }
   1021 
   1022   // There should be max_renderer_frames with a frame in it, and one without it.
   1023   // Since the logic is LRU eviction, the first one should be without.
   1024   EXPECT_FALSE(views[0]->frame_provider_);
   1025   for (size_t i = 1; i < renderer_count; ++i)
   1026     EXPECT_TRUE(views[i]->frame_provider_);
   1027 
   1028   // LRU renderer is [0], make it visible, it shouldn't evict anything yet.
   1029   views[0]->WasShown();
   1030   EXPECT_FALSE(views[0]->frame_provider_);
   1031   EXPECT_TRUE(views[1]->frame_provider_);
   1032 
   1033   // Swap a frame on it, it should evict the next LRU [1].
   1034   views[0]->OnSwapCompositorFrame(
   1035       1, MakeDelegatedFrame(1.f, frame_size, view_rect));
   1036   EXPECT_TRUE(views[0]->frame_provider_);
   1037   EXPECT_FALSE(views[1]->frame_provider_);
   1038   views[0]->WasHidden();
   1039 
   1040   // LRU renderer is [1], still hidden. Swap a frame on it, it should evict
   1041   // the next LRU [2].
   1042   views[1]->OnSwapCompositorFrame(
   1043       1, MakeDelegatedFrame(1.f, frame_size, view_rect));
   1044   EXPECT_TRUE(views[0]->frame_provider_);
   1045   EXPECT_TRUE(views[1]->frame_provider_);
   1046   EXPECT_FALSE(views[2]->frame_provider_);
   1047   for (size_t i = 3; i < renderer_count; ++i)
   1048     EXPECT_TRUE(views[i]->frame_provider_);
   1049 
   1050   // Make all renderers but [0] visible and swap a frame on them, keep [0]
   1051   // hidden, it becomes the LRU.
   1052   for (size_t i = 1; i < renderer_count; ++i) {
   1053     views[i]->WasShown();
   1054     views[i]->OnSwapCompositorFrame(
   1055         1, MakeDelegatedFrame(1.f, frame_size, view_rect));
   1056     EXPECT_TRUE(views[i]->frame_provider_);
   1057   }
   1058   EXPECT_FALSE(views[0]->frame_provider_);
   1059 
   1060   // Swap a frame on [0], it should be evicted immediately.
   1061   views[0]->OnSwapCompositorFrame(
   1062       1, MakeDelegatedFrame(1.f, frame_size, view_rect));
   1063   EXPECT_FALSE(views[0]->frame_provider_);
   1064 
   1065   // Make [0] visible, and swap a frame on it. Nothing should be evicted
   1066   // although we're above the limit.
   1067   views[0]->WasShown();
   1068   views[0]->OnSwapCompositorFrame(
   1069       1, MakeDelegatedFrame(1.f, frame_size, view_rect));
   1070   for (size_t i = 0; i < renderer_count; ++i)
   1071     EXPECT_TRUE(views[i]->frame_provider_);
   1072 
   1073   // Make [0] hidden, it should evict its frame.
   1074   views[0]->WasHidden();
   1075   EXPECT_FALSE(views[0]->frame_provider_);
   1076 
   1077   for (size_t i = 0; i < renderer_count; ++i) {
   1078     views[i]->Destroy();
   1079     delete hosts[i];
   1080   }
   1081 }
   1082 
   1083 TEST_F(RenderWidgetHostViewAuraTest, SoftwareDPIChange) {
   1084   gfx::Rect view_rect(100, 100);
   1085   gfx::Size frame_size(100, 100);
   1086 
   1087   view_->InitAsChild(NULL);
   1088   aura::client::ParentWindowWithContext(
   1089       view_->GetNativeView(),
   1090       parent_view_->GetNativeView()->GetRootWindow(),
   1091       gfx::Rect());
   1092   view_->SetSize(view_rect.size());
   1093   view_->WasShown();
   1094 
   1095   // With a 1x DPI UI and 1x DPI Renderer.
   1096   view_->OnSwapCompositorFrame(
   1097       1, MakeDelegatedFrame(1.f, frame_size, gfx::Rect(frame_size)));
   1098 
   1099   // Save the frame provider.
   1100   scoped_refptr<cc::DelegatedFrameProvider> frame_provider =
   1101       view_->frame_provider_;
   1102 
   1103   // This frame will have the same number of physical pixels, but has a new
   1104   // scale on it.
   1105   view_->OnSwapCompositorFrame(
   1106       1, MakeDelegatedFrame(2.f, frame_size, gfx::Rect(frame_size)));
   1107 
   1108   // When we get a new frame with the same frame size in physical pixels, but a
   1109   // different scale, we should generate a new frame provider, as the final
   1110   // result will need to be scaled differently to the screen.
   1111   EXPECT_NE(frame_provider.get(), view_->frame_provider_.get());
   1112 }
   1113 
   1114 }  // namespace content
   1115