Home | History | Annotate | Download | only in aura
      1 // Copyright 2014 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/web_contents/aura/overscroll_navigation_overlay.h"
      6 
      7 #include "content/browser/frame_host/navigation_entry_impl.h"
      8 #include "content/browser/web_contents/aura/image_window_delegate.h"
      9 #include "content/browser/web_contents/web_contents_view.h"
     10 #include "content/common/view_messages.h"
     11 #include "content/public/test/mock_render_process_host.h"
     12 #include "content/test/test_render_view_host.h"
     13 #include "content/test/test_web_contents.h"
     14 #include "ui/aura/test/test_windows.h"
     15 #include "ui/aura/window.h"
     16 #include "ui/gfx/codec/png_codec.h"
     17 
     18 namespace content {
     19 
     20 class OverscrollNavigationOverlayTest : public RenderViewHostImplTestHarness {
     21  public:
     22   OverscrollNavigationOverlayTest() {}
     23   virtual ~OverscrollNavigationOverlayTest() {}
     24 
     25   gfx::Image CreateDummyScreenshot() {
     26     SkBitmap bitmap;
     27     bitmap.setConfig(SkBitmap::kARGB_8888_Config, 1, 1);
     28     bitmap.allocPixels();
     29     bitmap.eraseColor(SK_ColorWHITE);
     30     return gfx::Image::CreateFrom1xBitmap(bitmap);
     31   }
     32 
     33   void SetDummyScreenshotOnNavEntry(NavigationEntry* entry) {
     34     SkBitmap bitmap;
     35     bitmap.setConfig(SkBitmap::kARGB_8888_Config, 1, 1);
     36     bitmap.allocPixels();
     37     bitmap.eraseColor(SK_ColorWHITE);
     38     std::vector<unsigned char> png_data;
     39     gfx::PNGCodec::EncodeBGRASkBitmap(bitmap, true, &png_data);
     40     scoped_refptr<base::RefCountedBytes> png_bytes =
     41         base::RefCountedBytes::TakeVector(&png_data);
     42     NavigationEntryImpl* entry_impl =
     43         NavigationEntryImpl::FromNavigationEntry(entry);
     44     entry_impl->SetScreenshotPNGData(png_bytes);
     45   }
     46 
     47   void ReceivePaintUpdate() {
     48     ViewHostMsg_DidFirstVisuallyNonEmptyPaint msg(test_rvh()->GetRoutingID());
     49     RenderViewHostTester::TestOnMessageReceived(test_rvh(), msg);
     50   }
     51 
     52   void PerformBackNavigationViaSliderCallbacks() {
     53     // Sets slide direction to SLIDE_BACK, sets screenshot from NavEntry at
     54     // offset -1  on layer_delegate_.
     55     delete GetOverlay()->CreateBackLayer();
     56     // Performs BACK navigation, sets image from layer_delegate_ on
     57     // image_delegate_.
     58     GetOverlay()->OnWindowSlideCompleting();
     59     GetOverlay()->OnWindowSlideCompleted(scoped_ptr<ui::Layer>());
     60   }
     61 
     62  protected:
     63   // RenderViewHostImplTestHarness:
     64   virtual void SetUp() OVERRIDE {
     65     RenderViewHostImplTestHarness::SetUp();
     66 
     67     const GURL first("https://www.google.com");
     68     contents()->NavigateAndCommit(first);
     69     EXPECT_TRUE(controller().GetVisibleEntry());
     70     EXPECT_FALSE(controller().CanGoBack());
     71 
     72     const GURL second("http://www.chromium.org");
     73     contents()->NavigateAndCommit(second);
     74     EXPECT_TRUE(controller().CanGoBack());
     75 
     76     // Receive a paint update. This is necessary to make sure the size is set
     77     // correctly in RenderWidgetHostImpl.
     78     ViewHostMsg_UpdateRect_Params params;
     79     memset(&params, 0, sizeof(params));
     80     params.view_size = gfx::Size(10, 10);
     81     ViewHostMsg_UpdateRect rect(test_rvh()->GetRoutingID(), params);
     82     RenderViewHostTester::TestOnMessageReceived(test_rvh(), rect);
     83 
     84     // Reset pending flags for size/paint.
     85     test_rvh()->ResetSizeAndRepaintPendingFlags();
     86 
     87     // Create the overlay, and set the contents of the overlay window.
     88     overlay_.reset(new OverscrollNavigationOverlay(contents()));
     89     ImageWindowDelegate* image_delegate = new ImageWindowDelegate();
     90     scoped_ptr<aura::Window> overlay_window(
     91       aura::test::CreateTestWindowWithDelegate(
     92           image_delegate,
     93           0,
     94           gfx::Rect(root_window()->bounds().size()),
     95           root_window()));
     96 
     97     overlay_->SetOverlayWindow(overlay_window.Pass(), image_delegate);
     98     overlay_->StartObserving();
     99 
    100     EXPECT_TRUE(overlay_->web_contents());
    101     EXPECT_FALSE(overlay_->loading_complete_);
    102     EXPECT_FALSE(overlay_->received_paint_update_);
    103   }
    104 
    105   virtual void TearDown() OVERRIDE {
    106     overlay_.reset();
    107     RenderViewHostImplTestHarness::TearDown();
    108   }
    109 
    110   OverscrollNavigationOverlay* GetOverlay() {
    111     return overlay_.get();
    112   }
    113 
    114  private:
    115   scoped_ptr<OverscrollNavigationOverlay> overlay_;
    116 
    117   DISALLOW_COPY_AND_ASSIGN(OverscrollNavigationOverlayTest);
    118 };
    119 
    120 TEST_F(OverscrollNavigationOverlayTest, FirstVisuallyNonEmptyPaint_NoImage) {
    121   ReceivePaintUpdate();
    122   EXPECT_TRUE(GetOverlay()->received_paint_update_);
    123   EXPECT_FALSE(GetOverlay()->loading_complete_);
    124   // The paint update will hide the overlay.
    125   EXPECT_FALSE(GetOverlay()->web_contents());
    126 }
    127 
    128 TEST_F(OverscrollNavigationOverlayTest, FirstVisuallyNonEmptyPaint_WithImage) {
    129   GetOverlay()->image_delegate_->SetImage(CreateDummyScreenshot());
    130 
    131   ReceivePaintUpdate();
    132   EXPECT_TRUE(GetOverlay()->received_paint_update_);
    133   EXPECT_FALSE(GetOverlay()->loading_complete_);
    134   // The paint update will hide the overlay.
    135   EXPECT_FALSE(GetOverlay()->web_contents());
    136 }
    137 
    138 TEST_F(OverscrollNavigationOverlayTest, LoadUpdateWithoutNonEmptyPaint) {
    139   GetOverlay()->image_delegate_->SetImage(CreateDummyScreenshot());
    140   process()->sink().ClearMessages();
    141 
    142   contents()->TestSetIsLoading(false);
    143   EXPECT_TRUE(GetOverlay()->loading_complete_);
    144   EXPECT_FALSE(GetOverlay()->received_paint_update_);
    145   // The page load should hide the overlay.
    146   EXPECT_FALSE(GetOverlay()->web_contents());
    147 }
    148 
    149 TEST_F(OverscrollNavigationOverlayTest, MultiNavigation_PaintUpdate) {
    150   GetOverlay()->image_delegate_->SetImage(CreateDummyScreenshot());
    151   SetDummyScreenshotOnNavEntry(controller().GetEntryAtOffset(-1));
    152 
    153   PerformBackNavigationViaSliderCallbacks();
    154   // Screenshot was set on NavEntry at offset -1.
    155   EXPECT_TRUE(GetOverlay()->image_delegate_->has_image());
    156   EXPECT_FALSE(GetOverlay()->received_paint_update_);
    157 
    158   ReceivePaintUpdate();
    159   // Paint updates until the navigation is committed represent updates
    160   // for the previous page, so they shouldn't affect the flag.
    161   EXPECT_FALSE(GetOverlay()->received_paint_update_);
    162 
    163   contents()->CommitPendingNavigation();
    164   ReceivePaintUpdate();
    165   // Navigation was committed and the paint update was received - the flag
    166   // should now be updated.
    167   EXPECT_TRUE(GetOverlay()->received_paint_update_);
    168 
    169   EXPECT_FALSE(GetOverlay()->web_contents());
    170 }
    171 
    172 TEST_F(OverscrollNavigationOverlayTest, MultiNavigation_LoadingUpdate) {
    173   GetOverlay()->image_delegate_->SetImage(CreateDummyScreenshot());
    174 
    175   PerformBackNavigationViaSliderCallbacks();
    176   // No screenshot was set on NavEntry at offset -1.
    177   EXPECT_FALSE(GetOverlay()->image_delegate_->has_image());
    178   // Navigation was started, so the loading status flag should be reset.
    179   EXPECT_FALSE(GetOverlay()->loading_complete_);
    180 
    181   // Load updates until the navigation is committed represent updates for the
    182   // previous page, so they shouldn't affect the flag.
    183   contents()->TestSetIsLoading(true);
    184   contents()->TestSetIsLoading(false);
    185   EXPECT_FALSE(GetOverlay()->loading_complete_);
    186 
    187   contents()->CommitPendingNavigation();
    188   contents()->TestSetIsLoading(true);
    189   contents()->TestSetIsLoading(false);
    190   // Navigation was committed and the load update was received - the flag
    191   // should now be updated.
    192   EXPECT_TRUE(GetOverlay()->loading_complete_);
    193 
    194   EXPECT_FALSE(GetOverlay()->web_contents());
    195 }
    196 
    197 }  // namespace content
    198