Home | History | Annotate | Download | only in frame
      1 // Copyright 2013 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 "chrome/browser/ui/views/frame/opaque_browser_frame_view_layout.h"
      6 
      7 #include "base/basictypes.h"
      8 #include "base/command_line.h"
      9 #include "base/strings/utf_string_conversions.h"
     10 #include "chrome/browser/ui/views/profiles/avatar_label.h"
     11 #include "chrome/browser/ui/views/profiles/avatar_menu_button.h"
     12 #include "chrome/browser/ui/views/tab_icon_view.h"
     13 #include "chrome/browser/ui/views/tabs/tab.h"
     14 #include "chrome/common/chrome_switches.h"
     15 #include "components/signin/core/common/profile_management_switches.h"
     16 #include "ui/gfx/image/image_skia.h"
     17 #include "ui/gfx/image/image_skia_rep.h"
     18 #include "ui/gfx/text_constants.h"
     19 #include "ui/views/controls/button/image_button.h"
     20 #include "ui/views/controls/button/menu_button.h"
     21 #include "ui/views/controls/label.h"
     22 #include "ui/views/test/views_test_base.h"
     23 
     24 using views::Widget;
     25 
     26 namespace {
     27 
     28 const int kWidth = 500;
     29 
     30 class TestLayoutDelegate : public OpaqueBrowserFrameViewLayoutDelegate {
     31  public:
     32   enum WindowState {
     33     STATE_NORMAL,
     34     STATE_MAXIMIZED,
     35     STATE_MINIMIZED,
     36     STATE_FULLSCREEN
     37   };
     38 
     39   TestLayoutDelegate()
     40       : show_avatar_(false),
     41         show_caption_buttons_(true),
     42         window_state_(STATE_NORMAL) {
     43   }
     44 
     45   virtual ~TestLayoutDelegate() {}
     46 
     47   void SetWindowTitle(const base::string16& title) {
     48     window_title_ = title;
     49   }
     50 
     51   void SetShouldShowAvatar(bool show_avatar) {
     52     show_avatar_ = show_avatar;
     53   }
     54 
     55   void SetShouldShowCaptionButtons(bool show_caption_buttons) {
     56     show_caption_buttons_ = show_caption_buttons;
     57   }
     58 
     59   void SetWindowState(WindowState state) {
     60     window_state_ = state;
     61   }
     62 
     63   // OpaqueBrowserFrameViewLayoutDelegate overrides:
     64 
     65   virtual bool ShouldShowWindowIcon() const OVERRIDE {
     66     return !window_title_.empty();
     67   }
     68 
     69   virtual bool ShouldShowWindowTitle() const OVERRIDE {
     70     return !window_title_.empty();
     71   }
     72 
     73   virtual base::string16 GetWindowTitle() const OVERRIDE {
     74     return window_title_;
     75   }
     76 
     77   virtual int GetIconSize() const OVERRIDE {
     78     // The value on linux_aura and non-aura windows.
     79     return 17;
     80   }
     81 
     82   virtual bool ShouldLeaveOffsetNearTopBorder() const OVERRIDE {
     83     return !IsMaximized();
     84   }
     85 
     86   virtual gfx::Size GetBrowserViewMinimumSize() const OVERRIDE {
     87     // Taken from a calculation in BrowserViewLayout.
     88     return gfx::Size(168, 64);
     89   }
     90 
     91   virtual bool ShouldShowCaptionButtons() const OVERRIDE {
     92     return show_caption_buttons_;
     93   }
     94 
     95   virtual bool ShouldShowAvatar() const OVERRIDE {
     96     return show_avatar_;
     97   }
     98 
     99   virtual bool IsRegularOrGuestSession() const OVERRIDE {
    100     return true;
    101   }
    102 
    103   virtual gfx::ImageSkia GetOTRAvatarIcon() const OVERRIDE {
    104     // The calculations depend on the size of the OTR resource, and chromeos
    105     // uses a different sized image, so hard code the size of the current
    106     // windows/linux one.
    107     gfx::ImageSkiaRep rep(gfx::Size(40, 29), 1.0f);
    108     gfx::ImageSkia image(rep);
    109     return image;
    110   }
    111 
    112   virtual bool IsMaximized() const OVERRIDE {
    113     return window_state_ == STATE_MAXIMIZED;
    114   }
    115 
    116   virtual bool IsMinimized() const OVERRIDE {
    117     return window_state_ == STATE_MINIMIZED;
    118   }
    119 
    120   virtual bool IsFullscreen() const OVERRIDE {
    121     return window_state_ == STATE_FULLSCREEN;
    122   }
    123 
    124   virtual bool IsTabStripVisible() const OVERRIDE {
    125     return window_title_.empty();
    126   }
    127 
    128   virtual int GetTabStripHeight() const OVERRIDE {
    129     return IsTabStripVisible() ? Tab::GetMinimumUnselectedSize().height() : 0;
    130   }
    131 
    132   virtual gfx::Size GetTabstripPreferredSize() const OVERRIDE {
    133     // Measured from Tabstrip::GetPreferredSize().
    134     return IsTabStripVisible() ? gfx::Size(78, 29) : gfx::Size(0, 0);
    135   }
    136 
    137  private:
    138   base::string16 window_title_;
    139   bool show_avatar_;
    140   bool show_caption_buttons_;
    141   WindowState window_state_;
    142 
    143   DISALLOW_COPY_AND_ASSIGN(TestLayoutDelegate);
    144 };
    145 
    146 }  // namespace
    147 
    148 class OpaqueBrowserFrameViewLayoutTest : public views::ViewsTestBase {
    149  public:
    150   OpaqueBrowserFrameViewLayoutTest() {}
    151   virtual ~OpaqueBrowserFrameViewLayoutTest() {}
    152 
    153   virtual void SetUp() OVERRIDE {
    154     views::ViewsTestBase::SetUp();
    155 
    156     delegate_.reset(new TestLayoutDelegate);
    157     layout_manager_ = new OpaqueBrowserFrameViewLayout(delegate_.get());
    158     layout_manager_->set_extra_caption_y(0);
    159     layout_manager_->set_window_caption_spacing(0);
    160     widget_ = new Widget;
    161     widget_->Init(CreateParams(Widget::InitParams::TYPE_POPUP));
    162     root_view_ = widget_->GetRootView();
    163     root_view_->SetSize(gfx::Size(kWidth, kWidth));
    164     root_view_->SetLayoutManager(layout_manager_);
    165 
    166     // Add the caption buttons. We use fake images because we're modeling the
    167     // Windows assets here, while the linux version uses differently sized
    168     // assets.
    169     //
    170     // TODO(erg): In a follow up patch, separate these sizes out into virtual
    171     // accessors so we can test both the windows and linux behaviours once we
    172     // start modifying the code.
    173     minimize_button_ = InitWindowCaptionButton(
    174         VIEW_ID_MINIMIZE_BUTTON, gfx::Size(26, 18));
    175     maximize_button_ = InitWindowCaptionButton(
    176         VIEW_ID_MAXIMIZE_BUTTON, gfx::Size(25, 18));
    177     restore_button_ = InitWindowCaptionButton(
    178         VIEW_ID_RESTORE_BUTTON, gfx::Size(25, 18));
    179     close_button_ = InitWindowCaptionButton(
    180         VIEW_ID_CLOSE_BUTTON, gfx::Size(43, 18));
    181   }
    182 
    183   virtual void TearDown() OVERRIDE {
    184     widget_->CloseNow();
    185 
    186     views::ViewsTestBase::TearDown();
    187   }
    188 
    189  protected:
    190   views::ImageButton* InitWindowCaptionButton(ViewID view_id,
    191                                               const gfx::Size& size) {
    192     views::ImageButton* button = new views::ImageButton(NULL);
    193     gfx::ImageSkiaRep rep(size, 1.0f);
    194     gfx::ImageSkia image(rep);
    195     button->SetImage(views::CustomButton::STATE_NORMAL, &image);
    196     button->set_id(view_id);
    197     root_view_->AddChildView(button);
    198     return button;
    199   }
    200 
    201   void AddWindowTitleIcons() {
    202     tab_icon_view_ = new TabIconView(NULL, NULL);
    203     tab_icon_view_->set_is_light(true);
    204     tab_icon_view_->set_id(VIEW_ID_WINDOW_ICON);
    205     root_view_->AddChildView(tab_icon_view_);
    206 
    207     window_title_ = new views::Label(delegate_->GetWindowTitle());
    208     window_title_->SetVisible(delegate_->ShouldShowWindowTitle());
    209     window_title_->SetEnabledColor(SK_ColorWHITE);
    210     window_title_->SetSubpixelRenderingEnabled(false);
    211     window_title_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
    212     window_title_->set_id(VIEW_ID_WINDOW_TITLE);
    213     root_view_->AddChildView(window_title_);
    214   }
    215 
    216   void AddAvatarButton() {
    217     // Disable the New Avatar Menu.
    218     switches::DisableNewAvatarMenuForTesting(CommandLine::ForCurrentProcess());
    219 
    220     menu_button_ = new AvatarMenuButton(NULL, false);
    221     menu_button_->set_id(VIEW_ID_AVATAR_BUTTON);
    222     delegate_->SetShouldShowAvatar(true);
    223     root_view_->AddChildView(menu_button_);
    224   }
    225 
    226   void AddAvatarLabel() {
    227     avatar_label_ = new AvatarLabel(NULL);
    228     avatar_label_->set_id(VIEW_ID_AVATAR_LABEL);
    229     root_view_->AddChildView(avatar_label_);
    230 
    231     // The avatar label should only be used together with the avatar button.
    232     AddAvatarButton();
    233   }
    234 
    235   void AddNewAvatarButton() {
    236     // Enable the New Avatar Menu.
    237     switches::EnableNewAvatarMenuForTesting(CommandLine::ForCurrentProcess());
    238 
    239     new_avatar_button_ =
    240         new views::MenuButton(NULL, base::string16(), NULL, false);
    241     new_avatar_button_->set_id(VIEW_ID_NEW_AVATAR_BUTTON);
    242     root_view_->AddChildView(new_avatar_button_);
    243   }
    244 
    245   void ExpectBasicWindowBounds() {
    246     EXPECT_EQ("428,1 25x18", maximize_button_->bounds().ToString());
    247     EXPECT_EQ("402,1 26x18", minimize_button_->bounds().ToString());
    248     EXPECT_EQ("0,0 0x0", restore_button_->bounds().ToString());
    249     EXPECT_EQ("453,1 43x18", close_button_->bounds().ToString());
    250   }
    251 
    252   Widget* widget_;
    253   views::View* root_view_;
    254   OpaqueBrowserFrameViewLayout* layout_manager_;
    255   scoped_ptr<TestLayoutDelegate> delegate_;
    256 
    257   // Widgets:
    258   views::ImageButton* minimize_button_;
    259   views::ImageButton* maximize_button_;
    260   views::ImageButton* restore_button_;
    261   views::ImageButton* close_button_;
    262 
    263   TabIconView* tab_icon_view_;
    264   views::Label* window_title_;
    265 
    266   AvatarLabel* avatar_label_;
    267   AvatarMenuButton* menu_button_;
    268   views::MenuButton* new_avatar_button_;
    269 
    270   DISALLOW_COPY_AND_ASSIGN(OpaqueBrowserFrameViewLayoutTest);
    271 };
    272 
    273 TEST_F(OpaqueBrowserFrameViewLayoutTest, BasicWindow) {
    274   // Tests the layout of a default chrome window with no avatars, no window
    275   // titles, and a tabstrip.
    276   root_view_->Layout();
    277 
    278   ExpectBasicWindowBounds();
    279 
    280   // After some visual inspection, it really does look like the tabstrip is
    281   // initally positioned out of our view.
    282   EXPECT_EQ("-1,13 398x29",
    283             layout_manager_->GetBoundsForTabStrip(
    284                 delegate_->GetTabstripPreferredSize(), kWidth).ToString());
    285   EXPECT_EQ("261x73", layout_manager_->GetMinimumSize(kWidth).ToString());
    286 
    287   // A normal window with no window icon still produces icon bounds for
    288   // Windows, which has a hidden icon that a user can double click on to close
    289   // the window.
    290   EXPECT_EQ("6,4 17x17", layout_manager_->IconBounds().ToString());
    291 }
    292 
    293 TEST_F(OpaqueBrowserFrameViewLayoutTest, BasicWindowMaximized) {
    294   // Tests the layout of a default chrome window with no avatars, no window
    295   // titles, and a tabstrip, but maximized this time.
    296   delegate_->SetWindowState(TestLayoutDelegate::STATE_MAXIMIZED);
    297   root_view_->Layout();
    298 
    299   // Note how the bounds start at the exact top of the window while maximized
    300   // while they start 1 pixel below when unmaximized.
    301   EXPECT_EQ("0,0 0x0", maximize_button_->bounds().ToString());
    302   EXPECT_EQ("403,0 26x18", minimize_button_->bounds().ToString());
    303   EXPECT_EQ("429,0 25x18", restore_button_->bounds().ToString());
    304   EXPECT_EQ("454,0 46x18", close_button_->bounds().ToString());
    305 
    306   EXPECT_EQ("-5,-3 392x29",
    307             layout_manager_->GetBoundsForTabStrip(
    308                 delegate_->GetTabstripPreferredSize(), kWidth).ToString());
    309   EXPECT_EQ("262x61", layout_manager_->GetMinimumSize(kWidth).ToString());
    310 
    311   // In the maximized case, OpaqueBrowserFrameView::NonClientHitTest() uses
    312   // this rect, extended to the top left corner of the window.
    313   EXPECT_EQ("2,0 17x17", layout_manager_->IconBounds().ToString());
    314 }
    315 
    316 TEST_F(OpaqueBrowserFrameViewLayoutTest, MaximizedWithYOffset) {
    317   // Tests the layout of a basic chrome window with the caption buttons slightly
    318   // offset from the top of the screen (as they are on Linux).
    319   layout_manager_->set_extra_caption_y(2);
    320   delegate_->SetWindowState(TestLayoutDelegate::STATE_MAXIMIZED);
    321   root_view_->Layout();
    322 
    323   // Note how the bounds start at the exact top of the window, DESPITE the
    324   // caption Y offset of 2. This ensures that we obey Fitts' Law (the buttons
    325   // are clickable on the top edge of the screen). However, the buttons are 2
    326   // pixels taller, so the images appear to be offset by 2 pixels.
    327   EXPECT_EQ("0,0 0x0", maximize_button_->bounds().ToString());
    328   EXPECT_EQ("403,0 26x20", minimize_button_->bounds().ToString());
    329   EXPECT_EQ("429,0 25x20", restore_button_->bounds().ToString());
    330   EXPECT_EQ("454,0 46x20", close_button_->bounds().ToString());
    331 
    332   EXPECT_EQ("-5,-3 392x29",
    333             layout_manager_->GetBoundsForTabStrip(
    334                 delegate_->GetTabstripPreferredSize(), kWidth).ToString());
    335   EXPECT_EQ("262x61", layout_manager_->GetMinimumSize(kWidth).ToString());
    336 
    337   // In the maximized case, OpaqueBrowserFrameView::NonClientHitTest() uses
    338   // this rect, extended to the top left corner of the window.
    339   EXPECT_EQ("2,0 17x17", layout_manager_->IconBounds().ToString());
    340 }
    341 
    342 TEST_F(OpaqueBrowserFrameViewLayoutTest, WindowButtonsOnLeft) {
    343   // Tests the layout of a chrome window with caption buttons on the left.
    344   std::vector<views::FrameButton> leading_buttons;
    345   std::vector<views::FrameButton> trailing_buttons;
    346   leading_buttons.push_back(views::FRAME_BUTTON_CLOSE);
    347   leading_buttons.push_back(views::FRAME_BUTTON_MINIMIZE);
    348   leading_buttons.push_back(views::FRAME_BUTTON_MAXIMIZE);
    349   layout_manager_->SetButtonOrdering(leading_buttons, trailing_buttons);
    350   root_view_->Layout();
    351 
    352   EXPECT_EQ("73,1 25x18", maximize_button_->bounds().ToString());
    353   EXPECT_EQ("47,1 26x18", minimize_button_->bounds().ToString());
    354   EXPECT_EQ("0,0 0x0", restore_button_->bounds().ToString());
    355   EXPECT_EQ("4,1 43x18", close_button_->bounds().ToString());
    356 
    357   EXPECT_EQ("93,13 398x29",
    358             layout_manager_->GetBoundsForTabStrip(
    359                 delegate_->GetTabstripPreferredSize(), kWidth).ToString());
    360   EXPECT_EQ("261x73", layout_manager_->GetMinimumSize(kWidth).ToString());
    361 
    362   // If the buttons are on the left, there should be no hidden icon for the user
    363   // to double click.
    364   EXPECT_EQ("0,0 0x0", layout_manager_->IconBounds().ToString());
    365 }
    366 
    367 TEST_F(OpaqueBrowserFrameViewLayoutTest, WithoutCaptionButtons) {
    368   // Tests the layout of a default chrome window with no caption buttons (which
    369   // should force the tab strip to be condensed).
    370   delegate_->SetShouldShowCaptionButtons(false);
    371   root_view_->Layout();
    372 
    373   EXPECT_EQ("0,0 0x0", maximize_button_->bounds().ToString());
    374   EXPECT_EQ("0,0 0x0", minimize_button_->bounds().ToString());
    375   EXPECT_EQ("0,0 0x0", restore_button_->bounds().ToString());
    376   EXPECT_EQ("0,0 0x0", close_button_->bounds().ToString());
    377 
    378   EXPECT_EQ("-5,-3 500x29",
    379             layout_manager_->GetBoundsForTabStrip(
    380                 delegate_->GetTabstripPreferredSize(), kWidth).ToString());
    381   EXPECT_EQ("251x61", layout_manager_->GetMinimumSize(kWidth).ToString());
    382 
    383   // A normal window with no window icon still produces icon bounds for
    384   // Windows, which has a hidden icon that a user can double click on to close
    385   // the window.
    386   EXPECT_EQ("2,0 17x17", layout_manager_->IconBounds().ToString());
    387 }
    388 
    389 TEST_F(OpaqueBrowserFrameViewLayoutTest, MaximizedWithoutCaptionButtons) {
    390   // Tests the layout of a maximized chrome window with no caption buttons.
    391   delegate_->SetWindowState(TestLayoutDelegate::STATE_MAXIMIZED);
    392   delegate_->SetShouldShowCaptionButtons(false);
    393   root_view_->Layout();
    394 
    395   EXPECT_EQ("0,0 0x0", maximize_button_->bounds().ToString());
    396   EXPECT_EQ("0,0 0x0", minimize_button_->bounds().ToString());
    397   EXPECT_EQ("0,0 0x0", restore_button_->bounds().ToString());
    398   EXPECT_EQ("0,0 0x0", close_button_->bounds().ToString());
    399 
    400   EXPECT_EQ("-5,-3 500x29",
    401             layout_manager_->GetBoundsForTabStrip(
    402                 delegate_->GetTabstripPreferredSize(), kWidth).ToString());
    403   EXPECT_EQ("251x61", layout_manager_->GetMinimumSize(kWidth).ToString());
    404 
    405   // In the maximized case, OpaqueBrowserFrameView::NonClientHitTest() uses
    406   // this rect, extended to the top left corner of the window.
    407   EXPECT_EQ("2,0 17x17", layout_manager_->IconBounds().ToString());
    408 }
    409 
    410 TEST_F(OpaqueBrowserFrameViewLayoutTest, WithWindowTitleAndIcon) {
    411   // Tests the layout of pop up windows.
    412   delegate_->SetWindowTitle(base::ASCIIToUTF16("Window Title"));
    413   AddWindowTitleIcons();
    414   root_view_->Layout();
    415 
    416   // We should have the right hand side should match the BasicWindow case.
    417   ExpectBasicWindowBounds();
    418 
    419   // Check the location of the tab icon and window title.
    420   EXPECT_EQ("6,3 17x17", tab_icon_view_->bounds().ToString());
    421   EXPECT_EQ("27,3 370x17", window_title_->bounds().ToString());
    422 }
    423 
    424 TEST_F(OpaqueBrowserFrameViewLayoutTest, WindowWithAvatar) {
    425   // Tests a normal tabstrip window with an avatar icon.
    426   AddAvatarButton();
    427   root_view_->Layout();
    428 
    429   ExpectBasicWindowBounds();
    430 
    431   // Check the location of the avatar
    432   EXPECT_EQ("7,11 40x29", menu_button_->bounds().ToString());
    433   EXPECT_EQ("45,13 352x29",
    434             layout_manager_->GetBoundsForTabStrip(
    435                 delegate_->GetTabstripPreferredSize(), kWidth).ToString());
    436   EXPECT_EQ("261x73", layout_manager_->GetMinimumSize(kWidth).ToString());
    437 }
    438 
    439 TEST_F(OpaqueBrowserFrameViewLayoutTest, WindowWithAvatarWithButtonsOnLeft) {
    440   // Tests the layout of a chrome window with an avatar icon and caption buttons
    441   // on the left. The avatar icon should therefore be on the right.
    442   // AddAvatarLabel() also adds the avatar button.
    443   AddAvatarLabel();
    444   std::vector<views::FrameButton> leading_buttons;
    445   std::vector<views::FrameButton> trailing_buttons;
    446   leading_buttons.push_back(views::FRAME_BUTTON_CLOSE);
    447   leading_buttons.push_back(views::FRAME_BUTTON_MINIMIZE);
    448   leading_buttons.push_back(views::FRAME_BUTTON_MAXIMIZE);
    449   layout_manager_->SetButtonOrdering(leading_buttons, trailing_buttons);
    450   root_view_->Layout();
    451 
    452   EXPECT_EQ("73,1 25x18", maximize_button_->bounds().ToString());
    453   EXPECT_EQ("47,1 26x18", minimize_button_->bounds().ToString());
    454   EXPECT_EQ("0,0 0x0", restore_button_->bounds().ToString());
    455   EXPECT_EQ("4,1 43x18", close_button_->bounds().ToString());
    456 
    457   // Check the location of the avatar
    458   EXPECT_EQ("454,11 40x29", menu_button_->bounds().ToString());
    459 
    460   // Check the tab strip bounds.
    461   gfx::Rect tab_strip_bounds = layout_manager_->GetBoundsForTabStrip(
    462       delegate_->GetTabstripPreferredSize(), kWidth);
    463   EXPECT_GT(tab_strip_bounds.x(), maximize_button_->bounds().x());
    464   EXPECT_GT(maximize_button_->bounds().right(), tab_strip_bounds.x());
    465   EXPECT_EQ(13, tab_strip_bounds.y());
    466   EXPECT_EQ(29, tab_strip_bounds.height());
    467   EXPECT_GT(avatar_label_->bounds().x(), tab_strip_bounds.right());
    468   EXPECT_EQ("261x73", layout_manager_->GetMinimumSize(kWidth).ToString());
    469 
    470   // Check the relative location of the avatar label to the avatar. The right
    471   // end of the avatar label should be slightly to the right of the right end of
    472   // the avatar icon.
    473   EXPECT_GT(avatar_label_->bounds().right(), menu_button_->bounds().right());
    474   EXPECT_GT(menu_button_->bounds().x(), avatar_label_->bounds().x());
    475   EXPECT_GT(menu_button_->bounds().bottom(),
    476             avatar_label_->bounds().bottom());
    477   EXPECT_GT(avatar_label_->bounds().y(), menu_button_->bounds().y());
    478 
    479   // This means that the menu will pop out facing the left (if it were to face
    480   // the right, it would go outside the window frame and be clipped).
    481   EXPECT_TRUE(menu_button_->button_on_right());
    482 
    483   // If the buttons are on the left, there should be no hidden icon for the user
    484   // to double click.
    485   EXPECT_EQ("0,0 0x0", layout_manager_->IconBounds().ToString());
    486 }
    487 
    488 TEST_F(OpaqueBrowserFrameViewLayoutTest,
    489        WindowWithAvatarWithoutCaptionButtonsOnLeft) {
    490   // Tests the layout of a chrome window with an avatar icon and no caption
    491   // buttons. However, the caption buttons *would* be on the left if they
    492   // weren't hidden, and therefore, the avatar icon should be on the right.
    493   // The lack of caption buttons should force the tab strip to be condensed.
    494   AddAvatarButton();
    495   std::vector<views::FrameButton> leading_buttons;
    496   std::vector<views::FrameButton> trailing_buttons;
    497   leading_buttons.push_back(views::FRAME_BUTTON_CLOSE);
    498   leading_buttons.push_back(views::FRAME_BUTTON_MINIMIZE);
    499   leading_buttons.push_back(views::FRAME_BUTTON_MAXIMIZE);
    500   layout_manager_->SetButtonOrdering(leading_buttons, trailing_buttons);
    501   delegate_->SetShouldShowCaptionButtons(false);
    502   root_view_->Layout();
    503 
    504   EXPECT_EQ("0,0 0x0", maximize_button_->bounds().ToString());
    505   EXPECT_EQ("0,0 0x0", minimize_button_->bounds().ToString());
    506   EXPECT_EQ("0,0 0x0", restore_button_->bounds().ToString());
    507   EXPECT_EQ("0,0 0x0", close_button_->bounds().ToString());
    508 
    509   // Check the location of the avatar
    510   EXPECT_EQ("458,0 40x24", menu_button_->bounds().ToString());
    511   EXPECT_EQ("-5,-3 458x29",
    512             layout_manager_->GetBoundsForTabStrip(
    513                 delegate_->GetTabstripPreferredSize(), kWidth).ToString());
    514   EXPECT_EQ("251x61", layout_manager_->GetMinimumSize(kWidth).ToString());
    515 
    516   // A normal window with no window icon still produces icon bounds for
    517   // Windows, which has a hidden icon that a user can double click on to close
    518   // the window.
    519   EXPECT_EQ("2,0 17x17", layout_manager_->IconBounds().ToString());
    520 }
    521 
    522 TEST_F(OpaqueBrowserFrameViewLayoutTest, WindowWithNewAvatar) {
    523   // Tests a normal tabstrip window with the new style avatar icon.
    524   AddNewAvatarButton();
    525   root_view_->Layout();
    526 
    527   ExpectBasicWindowBounds();
    528 
    529   // Check the location of the avatar button.
    530   EXPECT_EQ("385,1 12x18", new_avatar_button_->bounds().ToString());
    531   // The new tab button is 39px wide and slides completely under the new
    532   // avatar button, thus increasing the tabstrip by that amount.
    533   EXPECT_EQ("-1,13 420x29",
    534             layout_manager_->GetBoundsForTabStrip(
    535                 delegate_->GetTabstripPreferredSize(), kWidth).ToString());
    536   EXPECT_EQ("261x73", layout_manager_->GetMinimumSize(kWidth).ToString());
    537 }
    538 
    539 TEST_F(OpaqueBrowserFrameViewLayoutTest, WindowWithAvatarLabelAndButtonOnLeft) {
    540   AddAvatarLabel();
    541   root_view_->Layout();
    542 
    543   ExpectBasicWindowBounds();
    544 
    545   // Check the location of the avatar label relative to the avatar button if
    546   // both are displayed on the left side.
    547   // The label height and width depends on the font size and the text displayed.
    548   // This may possibly change, so we don't test it here.
    549   EXPECT_EQ(menu_button_->bounds().x() - 2, avatar_label_->bounds().x());
    550   EXPECT_EQ(
    551       menu_button_->bounds().bottom() - 3 - avatar_label_->bounds().height(),
    552       avatar_label_->bounds().y());
    553 }
    554