Home | History | Annotate | Download | only in frame
      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 "ash/frame/custom_frame_view_ash.h"
      6 
      7 #include "ash/frame/caption_buttons/frame_caption_button.h"
      8 #include "ash/frame/caption_buttons/frame_caption_button_container_view.h"
      9 #include "ash/shell.h"
     10 #include "ash/test/ash_test_base.h"
     11 #include "ash/test/test_session_state_delegate.h"
     12 #include "ash/wm/maximize_mode/maximize_mode_controller.h"
     13 #include "base/memory/scoped_ptr.h"
     14 #include "grit/ash_resources.h"
     15 #include "ui/base/resource/resource_bundle.h"
     16 #include "ui/gfx/image/image_skia.h"
     17 #include "ui/gfx/rect.h"
     18 #include "ui/views/widget/widget.h"
     19 #include "ui/views/widget/widget_delegate.h"
     20 
     21 namespace ash {
     22 
     23 // A views::WidgetDelegate which uses a CustomFrameViewAsh.
     24 class TestWidgetDelegate : public views::WidgetDelegateView {
     25  public:
     26   TestWidgetDelegate() {}
     27   virtual ~TestWidgetDelegate() {}
     28 
     29   virtual views::NonClientFrameView* CreateNonClientFrameView(
     30       views::Widget* widget) OVERRIDE {
     31     custom_frame_view_ = new CustomFrameViewAsh(widget);
     32     return custom_frame_view_;
     33   }
     34 
     35   CustomFrameViewAsh* custom_frame_view() const {
     36     return custom_frame_view_;
     37   }
     38 
     39  private:
     40   // Not owned.
     41   CustomFrameViewAsh* custom_frame_view_;
     42 
     43   DISALLOW_COPY_AND_ASSIGN(TestWidgetDelegate);
     44 };
     45 
     46 class TestWidgetConstraintsDelegate : public TestWidgetDelegate {
     47  public:
     48   TestWidgetConstraintsDelegate() {}
     49   virtual ~TestWidgetConstraintsDelegate() {}
     50 
     51   // views::View:
     52   virtual gfx::Size GetMinimumSize() const OVERRIDE {
     53     return minimum_size_;
     54   }
     55 
     56   virtual gfx::Size GetMaximumSize() const OVERRIDE {
     57     return maximum_size_;
     58   }
     59 
     60   virtual views::View* GetContentsView() OVERRIDE {
     61     // Set this instance as the contents view so that the maximum and minimum
     62     // size constraints will be used.
     63     return this;
     64   }
     65 
     66   // views::WidgetDelegate:
     67   virtual bool CanMaximize() const OVERRIDE {
     68     return true;
     69   }
     70 
     71   virtual bool CanMinimize() const OVERRIDE {
     72     return true;
     73   }
     74 
     75   void set_minimum_size(const gfx::Size& min_size) {
     76     minimum_size_ = min_size;
     77   }
     78 
     79   void set_maximum_size(const gfx::Size& max_size) {
     80     maximum_size_ = max_size;
     81   }
     82 
     83   const gfx::Rect& GetFrameCaptionButtonContainerViewBounds() {
     84     return custom_frame_view()->GetFrameCaptionButtonContainerViewForTest()->
     85         bounds();
     86   }
     87 
     88   void EndFrameCaptionButtonContainerViewAnimations() {
     89     FrameCaptionButtonContainerView::TestApi test(custom_frame_view()->
     90         GetFrameCaptionButtonContainerViewForTest());
     91     test.EndAnimations();
     92   }
     93 
     94   int GetTitleBarHeight() const {
     95     return custom_frame_view()->NonClientTopBorderHeight();
     96   }
     97 
     98  private:
     99   gfx::Size minimum_size_;
    100   gfx::Size maximum_size_;
    101 
    102   DISALLOW_COPY_AND_ASSIGN(TestWidgetConstraintsDelegate);
    103 };
    104 
    105 class CustomFrameViewAshTest : public test::AshTestBase {
    106  public:
    107   CustomFrameViewAshTest() {}
    108   virtual ~CustomFrameViewAshTest() {}
    109 
    110  protected:
    111   scoped_ptr<views::Widget> CreateWidget(TestWidgetDelegate* delegate) {
    112     scoped_ptr<views::Widget> widget(new views::Widget);
    113     views::Widget::InitParams params;
    114     params.delegate = delegate;
    115     params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
    116     params.bounds = gfx::Rect(0, 0, 100, 100);
    117     params.context = CurrentContext();
    118     widget->Init(params);
    119     return widget.Pass();
    120   }
    121 
    122   test::TestSessionStateDelegate* GetTestSessionStateDelegate() {
    123     return static_cast<ash::test::TestSessionStateDelegate*>(
    124         Shell::GetInstance()->session_state_delegate());
    125   }
    126 
    127  private:
    128   DISALLOW_COPY_AND_ASSIGN(CustomFrameViewAshTest);
    129 };
    130 
    131 // Test that the height of the header is correct upon initially displaying
    132 // the widget.
    133 TEST_F(CustomFrameViewAshTest, HeaderHeight) {
    134   TestWidgetDelegate* delegate = new TestWidgetDelegate;
    135 
    136   scoped_ptr<views::Widget> widget(CreateWidget(delegate));
    137   widget->Show();
    138 
    139   ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
    140   gfx::ImageSkia* close_button =
    141       rb.GetImageSkiaNamed(IDR_AURA_WINDOW_CONTROL_BACKGROUND_H);
    142 
    143   // The header should have enough room for the window controls. The
    144   // header/content separator line overlays the window controls.
    145   EXPECT_EQ(close_button->height(),
    146             delegate->custom_frame_view()->GetHeaderView()->height());
    147 }
    148 
    149 // Verify that CustomFrameViewAsh returns the correct minimum and maximum frame
    150 // sizes when the client view does not specify any size constraints.
    151 TEST_F(CustomFrameViewAshTest, NoSizeConstraints) {
    152   TestWidgetConstraintsDelegate* delegate = new TestWidgetConstraintsDelegate;
    153   scoped_ptr<views::Widget> widget(CreateWidget(delegate));
    154 
    155   CustomFrameViewAsh* custom_frame_view = delegate->custom_frame_view();
    156   gfx::Size min_frame_size = custom_frame_view->GetMinimumSize();
    157   gfx::Size max_frame_size = custom_frame_view->GetMaximumSize();
    158 
    159   EXPECT_EQ(delegate->GetTitleBarHeight(), min_frame_size.height());
    160 
    161   // A width and height constraint of 0 denotes unbounded.
    162   EXPECT_EQ(0, max_frame_size.width());
    163   EXPECT_EQ(0, max_frame_size.height());
    164 }
    165 
    166 // Verify that CustomFrameViewAsh returns the correct minimum and maximum frame
    167 // sizes when the client view specifies size constraints.
    168 TEST_F(CustomFrameViewAshTest, MinimumAndMaximumSize) {
    169   gfx::Size min_client_size(500, 500);
    170   gfx::Size max_client_size(800, 800);
    171   TestWidgetConstraintsDelegate* delegate = new TestWidgetConstraintsDelegate;
    172   delegate->set_minimum_size(min_client_size);
    173   delegate->set_maximum_size(max_client_size);
    174   scoped_ptr<views::Widget> widget(CreateWidget(delegate));
    175 
    176   CustomFrameViewAsh* custom_frame_view = delegate->custom_frame_view();
    177   gfx::Size min_frame_size = custom_frame_view->GetMinimumSize();
    178   gfx::Size max_frame_size = custom_frame_view->GetMaximumSize();
    179 
    180   EXPECT_EQ(min_client_size.width(), min_frame_size.width());
    181   EXPECT_EQ(max_client_size.width(), max_frame_size.width());
    182   EXPECT_EQ(min_client_size.height() + delegate->GetTitleBarHeight(),
    183             min_frame_size.height());
    184   EXPECT_EQ(max_client_size.height() + delegate->GetTitleBarHeight(),
    185             max_frame_size.height());
    186 }
    187 
    188 // Verify that CustomFrameViewAsh updates the avatar icon based on the
    189 // state of the SessionStateDelegate after visibility change.
    190 TEST_F(CustomFrameViewAshTest, AvatarIcon) {
    191   TestWidgetConstraintsDelegate* delegate = new TestWidgetConstraintsDelegate;
    192   scoped_ptr<views::Widget> widget(CreateWidget(delegate));
    193 
    194   CustomFrameViewAsh* custom_frame_view = delegate->custom_frame_view();
    195   EXPECT_FALSE(custom_frame_view->GetAvatarIconViewForTest());
    196 
    197   // Avatar image becomes available.
    198   const gfx::ImageSkia user_image =
    199       *ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
    200           IDR_AURA_UBER_TRAY_GUEST_ICON);
    201   GetTestSessionStateDelegate()->SetUserImage(user_image);
    202   widget->Hide();
    203   widget->Show();
    204   EXPECT_TRUE(custom_frame_view->GetAvatarIconViewForTest());
    205 
    206   // Avatar image is gone; the ImageView for the avatar icon should be
    207   // removed.
    208   GetTestSessionStateDelegate()->SetUserImage(gfx::ImageSkia());
    209   widget->Hide();
    210   widget->Show();
    211   EXPECT_FALSE(custom_frame_view->GetAvatarIconViewForTest());
    212 }
    213 
    214 // The visibility of the size button is updated when maximize mode is toggled.
    215 // Verify that the layout of the HeaderView is updated for the size button's
    216 // new visibility.
    217 TEST_F(CustomFrameViewAshTest, HeaderViewNotifiedOfChildSizeChange) {
    218   TestWidgetConstraintsDelegate* delegate = new TestWidgetConstraintsDelegate;
    219   scoped_ptr<views::Widget> widget(CreateWidget(delegate));
    220 
    221   const gfx::Rect initial = delegate->
    222       GetFrameCaptionButtonContainerViewBounds();
    223   Shell::GetInstance()->maximize_mode_controller()->
    224       EnableMaximizeModeWindowManager(true);
    225   delegate->EndFrameCaptionButtonContainerViewAnimations();
    226   const gfx::Rect maximize_mode_bounds = delegate->
    227       GetFrameCaptionButtonContainerViewBounds();
    228   EXPECT_GT(initial.width(), maximize_mode_bounds.width());
    229   Shell::GetInstance()->maximize_mode_controller()->
    230       EnableMaximizeModeWindowManager(false);
    231   delegate->EndFrameCaptionButtonContainerViewAnimations();
    232   const gfx::Rect after_restore = delegate->
    233       GetFrameCaptionButtonContainerViewBounds();
    234   EXPECT_EQ(initial, after_restore);
    235 }
    236 
    237 }  // namespace ash
    238