Home | History | Annotate | Download | only in panels
      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 "base/bind.h"
      6 #include "base/prefs/pref_service.h"
      7 #include "base/strings/utf_string_conversions.h"
      8 #include "chrome/app/chrome_command_ids.h"
      9 #include "chrome/browser/chrome_notification_types.h"
     10 #include "chrome/browser/devtools/devtools_window.h"
     11 #include "chrome/browser/extensions/extension_apitest.h"
     12 #include "chrome/browser/net/url_request_mock_util.h"
     13 #include "chrome/browser/prefs/browser_prefs.h"
     14 #include "chrome/browser/profiles/profile.h"
     15 #include "chrome/browser/ui/app_modal_dialogs/app_modal_dialog.h"
     16 #include "chrome/browser/ui/app_modal_dialogs/native_app_modal_dialog.h"
     17 #include "chrome/browser/ui/browser.h"
     18 #include "chrome/browser/ui/browser_commands.h"
     19 #include "chrome/browser/ui/browser_finder.h"
     20 #include "chrome/browser/ui/browser_iterator.h"
     21 #include "chrome/browser/ui/browser_window.h"
     22 #include "chrome/browser/ui/panels/base_panel_browser_test.h"
     23 #include "chrome/browser/ui/panels/docked_panel_collection.h"
     24 #include "chrome/browser/ui/panels/native_panel.h"
     25 #include "chrome/browser/ui/panels/panel.h"
     26 #include "chrome/browser/ui/panels/panel_manager.h"
     27 #include "chrome/browser/ui/panels/test_panel_active_state_observer.h"
     28 #include "chrome/browser/web_applications/web_app.h"
     29 #include "chrome/common/chrome_switches.h"
     30 #include "chrome/common/pref_names.h"
     31 #include "chrome/common/url_constants.h"
     32 #include "chrome/test/base/interactive_test_utils.h"
     33 #include "chrome/test/base/ui_test_utils.h"
     34 #include "content/public/browser/native_web_keyboard_event.h"
     35 #include "content/public/browser/notification_service.h"
     36 #include "content/public/browser/web_contents.h"
     37 #include "content/public/common/url_constants.h"
     38 #include "content/public/test/browser_test_utils.h"
     39 #include "content/test/net/url_request_mock_http_job.h"
     40 #include "extensions/common/constants.h"
     41 #include "net/base/net_util.h"
     42 #include "testing/gtest/include/gtest/gtest.h"
     43 #include "ui/events/event_utils.h"
     44 #include "ui/gfx/screen.h"
     45 
     46 using content::WebContents;
     47 
     48 class PanelBrowserTest : public BasePanelBrowserTest {
     49  public:
     50   PanelBrowserTest() : BasePanelBrowserTest() {
     51   }
     52 
     53  protected:
     54   // Helper function for debugging.
     55   void PrintAllPanelBounds() {
     56     const std::vector<Panel*>& panels = PanelManager::GetInstance()->panels();
     57     DLOG(WARNING) << "PanelBounds:";
     58     for (size_t i = 0; i < panels.size(); ++i) {
     59       DLOG(WARNING) << "#=" << i
     60                     << ", ptr=" << panels[i]
     61                     << ", x=" << panels[i]->GetBounds().x()
     62                     << ", y=" << panels[i]->GetBounds().y()
     63                     << ", width=" << panels[i]->GetBounds().width()
     64                     << ", height" << panels[i]->GetBounds().height();
     65     }
     66   }
     67 
     68   std::vector<gfx::Rect> GetAllPanelBounds() {
     69     std::vector<Panel*> panels = PanelManager::GetInstance()->panels();
     70     std::vector<gfx::Rect> bounds;
     71     for (size_t i = 0; i < panels.size(); i++)
     72       bounds.push_back(panels[i]->GetBounds());
     73     return bounds;
     74   }
     75 
     76   std::vector<gfx::Rect> AddXDeltaToBounds(const std::vector<gfx::Rect>& bounds,
     77                                            const std::vector<int>& delta_x) {
     78     std::vector<gfx::Rect> new_bounds = bounds;
     79     for (size_t i = 0; i < bounds.size(); ++i)
     80       new_bounds[i].Offset(delta_x[i], 0);
     81     return new_bounds;
     82   }
     83 
     84   std::vector<Panel::ExpansionState> GetAllPanelExpansionStates() {
     85     std::vector<Panel*> panels = PanelManager::GetInstance()->panels();
     86     std::vector<Panel::ExpansionState> expansion_states;
     87     for (size_t i = 0; i < panels.size(); i++)
     88       expansion_states.push_back(panels[i]->expansion_state());
     89     return expansion_states;
     90   }
     91 
     92   std::vector<bool> GetAllPanelActiveStates() {
     93     std::vector<Panel*> panels = PanelManager::GetInstance()->panels();
     94     std::vector<bool> active_states;
     95     for (size_t i = 0; i < panels.size(); i++)
     96       active_states.push_back(panels[i]->IsActive());
     97     return active_states;
     98   }
     99 
    100   std::vector<bool> ProduceExpectedActiveStates(
    101       int expected_active_panel_index) {
    102     std::vector<Panel*> panels = PanelManager::GetInstance()->panels();
    103     std::vector<bool> active_states;
    104     for (int i = 0; i < static_cast<int>(panels.size()); i++)
    105       active_states.push_back(i == expected_active_panel_index);
    106     return active_states;
    107   }
    108 
    109   void WaitForPanelActiveStates(const std::vector<bool>& old_states,
    110                                 const std::vector<bool>& new_states) {
    111     DCHECK(old_states.size() == new_states.size());
    112     std::vector<Panel*> panels = PanelManager::GetInstance()->panels();
    113     for (size_t i = 0; i < old_states.size(); i++) {
    114       if (old_states[i] != new_states[i]){
    115         WaitForPanelActiveState(
    116             panels[i], new_states[i] ? SHOW_AS_ACTIVE : SHOW_AS_INACTIVE);
    117       }
    118     }
    119   }
    120 
    121   void TestMinimizeRestore() {
    122     // This constant is used to generate a point 'sufficiently higher then
    123     // top edge of the panel'. On some platforms (Mac) we extend hover area
    124     // a bit above the minimized panel as well, so it takes significant
    125     // distance to 'move mouse out' of the hover-sensitive area.
    126     const int kFarEnoughFromHoverArea = 153;
    127 
    128     PanelManager* panel_manager = PanelManager::GetInstance();
    129     std::vector<Panel*> panels = panel_manager->panels();
    130     std::vector<gfx::Rect> test_begin_bounds = GetAllPanelBounds();
    131     std::vector<gfx::Rect> expected_bounds = test_begin_bounds;
    132     std::vector<Panel::ExpansionState> expected_expansion_states(
    133         panels.size(), Panel::EXPANDED);
    134     std::vector<NativePanelTesting*> native_panels_testing(panels.size());
    135     for (size_t i = 0; i < panels.size(); ++i) {
    136       native_panels_testing[i] = CreateNativePanelTesting(panels[i]);
    137     }
    138 
    139     // Verify titlebar click does not minimize.
    140     for (size_t index = 0; index < panels.size(); ++index) {
    141       // Press left mouse button.  Verify nothing changed.
    142       native_panels_testing[index]->PressLeftMouseButtonTitlebar(
    143           panels[index]->GetBounds().origin());
    144       EXPECT_EQ(expected_bounds, GetAllPanelBounds());
    145       EXPECT_EQ(expected_expansion_states, GetAllPanelExpansionStates());
    146 
    147       // Release mouse button.  Verify nothing changed.
    148       native_panels_testing[index]->ReleaseMouseButtonTitlebar();
    149       EXPECT_EQ(expected_bounds, GetAllPanelBounds());
    150       EXPECT_EQ(expected_expansion_states, GetAllPanelExpansionStates());
    151     }
    152 
    153     // Minimize all panels for next stage in test.
    154     for (size_t index = 0; index < panels.size(); ++index) {
    155       panels[index]->Minimize();
    156       expected_bounds[index].set_height(panel::kMinimizedPanelHeight);
    157       expected_bounds[index].set_y(
    158           test_begin_bounds[index].y() +
    159           test_begin_bounds[index].height() - panel::kMinimizedPanelHeight);
    160       expected_expansion_states[index] = Panel::MINIMIZED;
    161       EXPECT_EQ(expected_bounds, GetAllPanelBounds());
    162       EXPECT_EQ(expected_expansion_states, GetAllPanelExpansionStates());
    163     }
    164 
    165     // Setup bounds and expansion states for minimized and titlebar-only
    166     // states.
    167     std::vector<Panel::ExpansionState> titlebar_exposed_states(
    168         panels.size(), Panel::TITLE_ONLY);
    169     std::vector<gfx::Rect> minimized_bounds = expected_bounds;
    170     std::vector<Panel::ExpansionState> minimized_states(
    171         panels.size(), Panel::MINIMIZED);
    172     std::vector<gfx::Rect> titlebar_exposed_bounds = test_begin_bounds;
    173     for (size_t index = 0; index < panels.size(); ++index) {
    174       titlebar_exposed_bounds[index].set_height(
    175           panels[index]->native_panel()->TitleOnlyHeight());
    176       titlebar_exposed_bounds[index].set_y(
    177           test_begin_bounds[index].y() +
    178           test_begin_bounds[index].height() -
    179           panels[index]->native_panel()->TitleOnlyHeight());
    180     }
    181 
    182     // Test hover.  All panels are currently in minimized state.
    183     EXPECT_EQ(minimized_states, GetAllPanelExpansionStates());
    184     for (size_t index = 0; index < panels.size(); ++index) {
    185       // Hover mouse on minimized panel.
    186       // Verify titlebar is exposed on all panels.
    187       gfx::Point hover_point(panels[index]->GetBounds().origin());
    188       MoveMouseAndWaitForExpansionStateChange(panels[index], hover_point);
    189       EXPECT_EQ(titlebar_exposed_bounds, GetAllPanelBounds());
    190       EXPECT_EQ(titlebar_exposed_states, GetAllPanelExpansionStates());
    191 
    192       // Hover mouse above the panel. Verify all panels are minimized.
    193       hover_point.set_y(
    194           panels[index]->GetBounds().y() - kFarEnoughFromHoverArea);
    195       MoveMouseAndWaitForExpansionStateChange(panels[index], hover_point);
    196       EXPECT_EQ(minimized_bounds, GetAllPanelBounds());
    197       EXPECT_EQ(minimized_states, GetAllPanelExpansionStates());
    198 
    199       // Hover mouse below minimized panel.
    200       // Verify titlebar is exposed on all panels.
    201       hover_point.set_y(panels[index]->GetBounds().y() +
    202                         panels[index]->GetBounds().height() + 5);
    203       MoveMouseAndWaitForExpansionStateChange(panels[index], hover_point);
    204       EXPECT_EQ(titlebar_exposed_bounds, GetAllPanelBounds());
    205       EXPECT_EQ(titlebar_exposed_states, GetAllPanelExpansionStates());
    206 
    207       // Hover below titlebar exposed panel.  Verify nothing changed.
    208       hover_point.set_y(panels[index]->GetBounds().y() +
    209                         panels[index]->GetBounds().height() + 6);
    210       MoveMouse(hover_point);
    211       EXPECT_EQ(titlebar_exposed_bounds, GetAllPanelBounds());
    212       EXPECT_EQ(titlebar_exposed_states, GetAllPanelExpansionStates());
    213 
    214       // Hover mouse above panel.  Verify all panels are minimized.
    215       hover_point.set_y(
    216           panels[index]->GetBounds().y() - kFarEnoughFromHoverArea);
    217       MoveMouseAndWaitForExpansionStateChange(panels[index], hover_point);
    218       EXPECT_EQ(minimized_bounds, GetAllPanelBounds());
    219       EXPECT_EQ(minimized_states, GetAllPanelExpansionStates());
    220     }
    221 
    222     // Test restore.  All panels are currently in minimized state.
    223     for (size_t index = 0; index < panels.size(); ++index) {
    224       // Hover on the last panel.  This is to test the case of clicking on the
    225       // panel when it's in titlebar exposed state.
    226       if (index == panels.size() - 1)
    227         MoveMouse(minimized_bounds[index].origin());
    228 
    229       // Click minimized or title bar exposed panel as the case may be.
    230       // Verify panel is restored to its original size.
    231       native_panels_testing[index]->PressLeftMouseButtonTitlebar(
    232           panels[index]->GetBounds().origin());
    233       native_panels_testing[index]->ReleaseMouseButtonTitlebar();
    234       expected_bounds[index].set_height(
    235           test_begin_bounds[index].height());
    236       expected_bounds[index].set_y(test_begin_bounds[index].y());
    237       expected_expansion_states[index] = Panel::EXPANDED;
    238       EXPECT_EQ(expected_bounds, GetAllPanelBounds());
    239       EXPECT_EQ(expected_expansion_states, GetAllPanelExpansionStates());
    240 
    241       // Hover again on the last panel which is now restored, to reset the
    242       // titlebar exposed state.
    243       if (index == panels.size() - 1)
    244         MoveMouse(minimized_bounds[index].origin());
    245     }
    246 
    247     // The below could be separate tests, just adding a TODO here for tracking.
    248     // TODO(prasadt): Add test for dragging when in titlebar exposed state.
    249     // TODO(prasadt): Add test in presence of auto hiding task bar.
    250 
    251     for (size_t i = 0; i < panels.size(); ++i)
    252       delete native_panels_testing[i];
    253   }
    254 };
    255 
    256 IN_PROC_BROWSER_TEST_F(PanelBrowserTest, CheckDockedPanelProperties) {
    257   PanelManager* panel_manager = PanelManager::GetInstance();
    258   DockedPanelCollection* docked_collection = panel_manager->docked_collection();
    259 
    260   // Create 3 docked panels that are in expanded, title-only or minimized states
    261   // respectively.
    262   Panel* panel1 = CreatePanelWithBounds("1", gfx::Rect(0, 0, 100, 100));
    263   Panel* panel2 = CreatePanelWithBounds("2", gfx::Rect(0, 0, 100, 100));
    264   Panel* panel3 = CreatePanelWithBounds("3", gfx::Rect(0, 0, 100, 100));
    265   panel2->SetExpansionState(Panel::TITLE_ONLY);
    266   EXPECT_EQ(Panel::TITLE_ONLY, panel2->expansion_state());
    267   panel3->SetExpansionState(Panel::MINIMIZED);
    268   EXPECT_EQ(Panel::MINIMIZED, panel3->expansion_state());
    269   scoped_ptr<NativePanelTesting> panel1_testing(
    270       CreateNativePanelTesting(panel1));
    271   scoped_ptr<NativePanelTesting> panel2_testing(
    272       CreateNativePanelTesting(panel2));
    273   scoped_ptr<NativePanelTesting> panel3_testing(
    274       CreateNativePanelTesting(panel3));
    275 
    276   // Ensure that the layout message can get a chance to be processed so that
    277   // the button visibility can be updated.
    278   base::MessageLoop::current()->RunUntilIdle();
    279 
    280   EXPECT_EQ(3, panel_manager->num_panels());
    281   EXPECT_TRUE(docked_collection->HasPanel(panel1));
    282   EXPECT_TRUE(docked_collection->HasPanel(panel2));
    283   EXPECT_TRUE(docked_collection->HasPanel(panel3));
    284 
    285   EXPECT_EQ(Panel::EXPANDED, panel1->expansion_state());
    286   EXPECT_EQ(Panel::TITLE_ONLY, panel2->expansion_state());
    287   EXPECT_EQ(Panel::MINIMIZED, panel3->expansion_state());
    288 
    289   EXPECT_TRUE(panel1->IsAlwaysOnTop());
    290   EXPECT_TRUE(panel2->IsAlwaysOnTop());
    291   EXPECT_TRUE(panel3->IsAlwaysOnTop());
    292 
    293   EXPECT_TRUE(panel1_testing->IsButtonVisible(panel::CLOSE_BUTTON));
    294   EXPECT_TRUE(panel2_testing->IsButtonVisible(panel::CLOSE_BUTTON));
    295   EXPECT_TRUE(panel3_testing->IsButtonVisible(panel::CLOSE_BUTTON));
    296 
    297   EXPECT_TRUE(panel1_testing->IsButtonVisible(panel::MINIMIZE_BUTTON));
    298   EXPECT_FALSE(panel2_testing->IsButtonVisible(panel::MINIMIZE_BUTTON));
    299   EXPECT_FALSE(panel3_testing->IsButtonVisible(panel::MINIMIZE_BUTTON));
    300 
    301   EXPECT_FALSE(panel1_testing->IsButtonVisible(panel::RESTORE_BUTTON));
    302   EXPECT_TRUE(panel2_testing->IsButtonVisible(panel::RESTORE_BUTTON));
    303   EXPECT_TRUE(panel3_testing->IsButtonVisible(panel::RESTORE_BUTTON));
    304 
    305   // Expanded panel cannot be resized at the bottom.
    306   EXPECT_EQ(panel::RESIZABLE_EXCEPT_BOTTOM, panel1->CanResizeByMouse());
    307   EXPECT_EQ(panel::NOT_RESIZABLE, panel2->CanResizeByMouse());
    308   EXPECT_EQ(panel::NOT_RESIZABLE, panel3->CanResizeByMouse());
    309 
    310   EXPECT_EQ(panel::TOP_ROUNDED, panel1_testing->GetWindowCornerStyle());
    311   EXPECT_EQ(panel::TOP_ROUNDED, panel1_testing->GetWindowCornerStyle());
    312   EXPECT_EQ(panel::TOP_ROUNDED, panel3_testing->GetWindowCornerStyle());
    313 
    314   EXPECT_EQ(Panel::USE_PANEL_ATTENTION, panel1->attention_mode());
    315   EXPECT_EQ(Panel::USE_PANEL_ATTENTION, panel2->attention_mode());
    316   EXPECT_EQ(Panel::USE_PANEL_ATTENTION, panel3->attention_mode());
    317 
    318   panel_manager->CloseAll();
    319 }
    320 
    321 IN_PROC_BROWSER_TEST_F(PanelBrowserTest, CreatePanel) {
    322   PanelManager* panel_manager = PanelManager::GetInstance();
    323   EXPECT_EQ(0, panel_manager->num_panels()); // No panels initially.
    324 
    325   Panel* panel = CreatePanel("PanelTest");
    326   EXPECT_EQ(1, panel_manager->num_panels());
    327 
    328   gfx::Rect bounds = panel->GetBounds();
    329   EXPECT_GT(bounds.x(), 0);
    330   EXPECT_GT(bounds.y(), 0);
    331   EXPECT_GT(bounds.width(), 0);
    332   EXPECT_GT(bounds.height(), 0);
    333 
    334   EXPECT_EQ(bounds.right(),
    335             panel_manager->docked_collection()->StartingRightPosition());
    336 
    337   CloseWindowAndWait(panel);
    338 
    339   EXPECT_EQ(0, panel_manager->num_panels());
    340 }
    341 
    342 IN_PROC_BROWSER_TEST_F(PanelBrowserTest, CreateBigPanel) {
    343   gfx::Rect work_area = PanelManager::GetInstance()->
    344       display_settings_provider()->GetPrimaryWorkArea();
    345   Panel* panel = CreatePanelWithBounds("BigPanel", work_area);
    346   gfx::Rect bounds = panel->GetBounds();
    347   EXPECT_EQ(panel->max_size().width(), bounds.width());
    348   EXPECT_LT(bounds.width(), work_area.width());
    349   EXPECT_EQ(panel->max_size().height(), bounds.height());
    350   EXPECT_LT(bounds.height(), work_area.height());
    351   panel->Close();
    352 }
    353 
    354 class WaitForStableInitialSize : public TestPanelNotificationObserver {
    355  public:
    356   explicit WaitForStableInitialSize(Panel* panel)
    357       : TestPanelNotificationObserver(
    358           chrome::NOTIFICATION_PANEL_COLLECTION_UPDATED,
    359           content::NotificationService::AllSources()),
    360         panel_(panel) {}
    361   virtual ~WaitForStableInitialSize() {}
    362 
    363  protected:
    364   virtual bool AtExpectedState() OVERRIDE {
    365     return panel_->GetBounds().height() > panel_->TitleOnlyHeight();
    366   }
    367   Panel* panel_;
    368 };
    369 
    370 class WaitForAutoResizeWider : public TestPanelNotificationObserver {
    371  public:
    372   explicit WaitForAutoResizeWider(Panel* panel)
    373       : TestPanelNotificationObserver(
    374           chrome::NOTIFICATION_PANEL_COLLECTION_UPDATED,
    375           content::NotificationService::AllSources()),
    376         panel_(panel),
    377         initial_size_(panel->GetBounds().size()) {}
    378   virtual ~WaitForAutoResizeWider() {}
    379 
    380  protected:
    381   virtual bool AtExpectedState() OVERRIDE {
    382     return panel_->GetBounds().width() > initial_size_.width();
    383   }
    384   Panel* panel_;
    385   gfx::Size initial_size_;
    386 };
    387 
    388 class WaitForAutoResizeNarrower : public TestPanelNotificationObserver {
    389  public:
    390   explicit WaitForAutoResizeNarrower(Panel* panel)
    391       : TestPanelNotificationObserver(
    392           chrome::NOTIFICATION_PANEL_COLLECTION_UPDATED,
    393           content::NotificationService::AllSources()),
    394         panel_(panel),
    395         initial_size_(panel->GetBounds().size()) {}
    396   virtual ~WaitForAutoResizeNarrower() {}
    397 
    398  protected:
    399   virtual bool AtExpectedState() OVERRIDE {
    400     return panel_->GetBounds().width() < initial_size_.width();
    401   }
    402   Panel* panel_;
    403   gfx::Size initial_size_;
    404 };
    405 
    406 // crbug.com/160504
    407 IN_PROC_BROWSER_TEST_F(PanelBrowserTest, DISABLED_AutoResize) {
    408   PanelManager* panel_manager = PanelManager::GetInstance();
    409   panel_manager->enable_auto_sizing(true);
    410   // Bigger space is needed by this test.
    411   mock_display_settings_provider()->SetPrimaryDisplay(
    412       gfx::Rect(0, 0, 1200, 900), gfx::Rect(0, 0, 1200, 900));
    413 
    414   // Create a test panel with web contents loaded.
    415   CreatePanelParams params("PanelTest1", gfx::Rect(), SHOW_AS_ACTIVE);
    416   GURL url(ui_test_utils::GetTestUrl(
    417       base::FilePath(kTestDir),
    418       base::FilePath(FILE_PATH_LITERAL("update-preferred-size.html"))));
    419   params.url = url;
    420   Panel* panel = CreatePanelWithParams(params);
    421 
    422   // Ensure panel has auto resized to original web content size.
    423   // The resize will update the docked panel collection.
    424   WaitForStableInitialSize initial_resize(panel);
    425   initial_resize.Wait();
    426   gfx::Rect initial_bounds = panel->GetBounds();
    427 
    428   // Expand the test page. The resize will update the docked panel collection.
    429   WaitForAutoResizeWider enlarge(panel);
    430   EXPECT_TRUE(content::ExecuteScript(
    431       panel->GetWebContents(), "changeSize(50);"));
    432   enlarge.Wait();
    433   gfx::Rect bounds_on_grow = panel->GetBounds();
    434   EXPECT_GT(bounds_on_grow.width(), initial_bounds.width());
    435   EXPECT_EQ(bounds_on_grow.height(), initial_bounds.height());
    436 
    437   // Shrink the test page. The resize will update the docked panel collection.
    438   WaitForAutoResizeNarrower shrink(panel);
    439   EXPECT_TRUE(content::ExecuteScript(
    440       panel->GetWebContents(), "changeSize(-30);"));
    441   shrink.Wait();
    442   gfx::Rect bounds_on_shrink = panel->GetBounds();
    443   EXPECT_LT(bounds_on_shrink.width(), bounds_on_grow.width());
    444   EXPECT_GT(bounds_on_shrink.width(), initial_bounds.width());
    445   EXPECT_EQ(bounds_on_shrink.height(), initial_bounds.height());
    446 
    447   // Verify resizing turns off auto-resizing and panel no longer auto-resizes.
    448   gfx::Rect previous_bounds = panel->GetBounds();
    449   // These should be identical because the panel is expanded.
    450   EXPECT_EQ(previous_bounds.size(), panel->GetRestoredBounds().size());
    451   gfx::Size new_size(previous_bounds.size());
    452   new_size.Enlarge(5, 5);
    453   gfx::Rect new_bounds(previous_bounds.origin(), new_size);
    454   panel->SetBounds(new_bounds);
    455   EXPECT_FALSE(panel->auto_resizable());
    456   EXPECT_EQ(new_bounds.size(), panel->GetBounds().size());
    457   EXPECT_EQ(new_bounds.size(), panel->GetRestoredBounds().size());
    458 
    459   // Turn back on auto-resize and verify that panel auto resizes.
    460   content::WindowedNotificationObserver auto_resize_enabled(
    461       chrome::NOTIFICATION_PANEL_COLLECTION_UPDATED,
    462       content::NotificationService::AllSources());
    463   panel->SetAutoResizable(true);
    464   auto_resize_enabled.Wait();
    465   gfx::Rect bounds_auto_resize_enabled = panel->GetBounds();
    466   EXPECT_EQ(bounds_on_shrink.width(), bounds_auto_resize_enabled.width());
    467   EXPECT_EQ(bounds_on_shrink.height(), bounds_auto_resize_enabled.height());
    468 
    469   panel->Close();
    470 }
    471 
    472 IN_PROC_BROWSER_TEST_F(PanelBrowserTest, ResizePanel) {
    473   PanelManager* panel_manager = PanelManager::GetInstance();
    474   panel_manager->enable_auto_sizing(true);
    475 
    476   Panel* panel = CreatePanel("TestPanel");
    477   EXPECT_TRUE(panel->auto_resizable());
    478   EXPECT_EQ(Panel::EXPANDED, panel->expansion_state());
    479 
    480   // Verify resizing turns off auto-resizing and that it works.
    481   gfx::Rect original_bounds = panel->GetBounds();
    482   // These should be identical because the panel is expanded.
    483   EXPECT_EQ(original_bounds.size(), panel->GetRestoredBounds().size());
    484   gfx::Size new_size(original_bounds.size());
    485   new_size.Enlarge(5, 5);
    486   gfx::Rect new_bounds(original_bounds.origin(), new_size);
    487   panel->SetBounds(new_bounds);
    488   EXPECT_FALSE(panel->auto_resizable());
    489   EXPECT_EQ(new_bounds.size(), panel->GetBounds().size());
    490   EXPECT_EQ(new_bounds.size(), panel->GetRestoredBounds().size());
    491 
    492   // Verify current height unaffected when panel is not expanded.
    493   panel->SetExpansionState(Panel::MINIMIZED);
    494   int original_height = panel->GetBounds().height();
    495   new_size.Enlarge(5, 5);
    496   new_bounds.set_size(new_size);
    497   panel->SetBounds(new_bounds);
    498   EXPECT_EQ(new_bounds.size().width(), panel->GetBounds().width());
    499   EXPECT_EQ(original_height, panel->GetBounds().height());
    500   EXPECT_EQ(new_bounds.size(), panel->GetRestoredBounds().size());
    501 
    502   panel->Close();
    503 }
    504 
    505 IN_PROC_BROWSER_TEST_F(PanelBrowserTest, AnimateBounds) {
    506   // Create a detached panel, instead of docked panel because it cannot be
    507   // moved to any location.
    508   Panel* panel = CreateDetachedPanel("1", gfx::Rect(200, 100, 100, 100));
    509   scoped_ptr<NativePanelTesting> panel_testing(
    510       CreateNativePanelTesting(panel));
    511 
    512   // Validates that no animation should be triggered when the panel is being
    513   // dragged.
    514   gfx::Point mouse_location(panel->GetBounds().origin());
    515   panel_testing->PressLeftMouseButtonTitlebar(mouse_location);
    516   panel_testing->DragTitlebar(mouse_location + gfx::Vector2d(-100, 5));
    517   EXPECT_FALSE(panel_testing->IsAnimatingBounds());
    518   panel_testing->FinishDragTitlebar();
    519 
    520   // Set bounds with animation.
    521   gfx::Rect bounds = gfx::Rect(10, 20, 150, 160);
    522   panel->SetPanelBounds(bounds);
    523   // There is no animation on Linux, by design.
    524 #if !defined(OS_LINUX)
    525   EXPECT_TRUE(panel_testing->IsAnimatingBounds());
    526   WaitForBoundsAnimationFinished(panel);
    527 #endif
    528   EXPECT_FALSE(panel_testing->IsAnimatingBounds());
    529   EXPECT_EQ(bounds, panel->GetBounds());
    530 
    531   // Set bounds without animation.
    532   bounds = gfx::Rect(30, 40, 200, 220);
    533   panel->SetPanelBoundsInstantly(bounds);
    534   EXPECT_FALSE(panel_testing->IsAnimatingBounds());
    535   EXPECT_EQ(bounds, panel->GetBounds());
    536 
    537   panel->Close();
    538 }
    539 
    540 IN_PROC_BROWSER_TEST_F(PanelBrowserTest, RestoredBounds) {
    541   Panel* panel = CreatePanelWithBounds("PanelTest", gfx::Rect(0, 0, 100, 100));
    542   EXPECT_EQ(Panel::EXPANDED, panel->expansion_state());
    543   EXPECT_EQ(panel->GetBounds(), panel->GetRestoredBounds());
    544 
    545   panel->SetExpansionState(Panel::MINIMIZED);
    546   EXPECT_EQ(Panel::MINIMIZED, panel->expansion_state());
    547   gfx::Rect bounds = panel->GetBounds();
    548   gfx::Rect restored = panel->GetRestoredBounds();
    549   EXPECT_EQ(bounds.x(), restored.x());
    550   EXPECT_GT(bounds.y(), restored.y());
    551   EXPECT_EQ(bounds.width(), restored.width());
    552   EXPECT_LT(bounds.height(), restored.height());
    553 
    554   panel->SetExpansionState(Panel::TITLE_ONLY);
    555   EXPECT_EQ(Panel::TITLE_ONLY, panel->expansion_state());
    556   bounds = panel->GetBounds();
    557   restored = panel->GetRestoredBounds();
    558   EXPECT_EQ(bounds.x(), restored.x());
    559   EXPECT_GT(bounds.y(), restored.y());
    560   EXPECT_EQ(bounds.width(), restored.width());
    561   EXPECT_LT(bounds.height(), restored.height());
    562 
    563   panel->SetExpansionState(Panel::MINIMIZED);
    564   EXPECT_EQ(Panel::MINIMIZED, panel->expansion_state());
    565   bounds = panel->GetBounds();
    566   restored = panel->GetRestoredBounds();
    567   EXPECT_EQ(bounds.x(), restored.x());
    568   EXPECT_GT(bounds.y(), restored.y());
    569   EXPECT_EQ(bounds.width(), restored.width());
    570   EXPECT_LT(bounds.height(), restored.height());
    571 
    572   panel->SetExpansionState(Panel::EXPANDED);
    573   EXPECT_EQ(panel->GetBounds(), panel->GetRestoredBounds());
    574 
    575   // Verify that changing the panel bounds does not affect the restored height.
    576   int saved_restored_height = restored.height();
    577   panel->SetExpansionState(Panel::MINIMIZED);
    578   bounds = gfx::Rect(10, 20, 300, 400);
    579   panel->SetPanelBounds(bounds);
    580   EXPECT_EQ(saved_restored_height, panel->GetRestoredBounds().height());
    581 
    582   panel->SetExpansionState(Panel::TITLE_ONLY);
    583   bounds = gfx::Rect(20, 30, 100, 200);
    584   panel->SetPanelBounds(bounds);
    585   EXPECT_EQ(saved_restored_height, panel->GetRestoredBounds().height());
    586 
    587   panel->SetExpansionState(Panel::EXPANDED);
    588   bounds = gfx::Rect(40, 60, 300, 400);
    589   panel->SetPanelBounds(bounds);
    590   EXPECT_EQ(saved_restored_height, panel->GetRestoredBounds().height());
    591   panel->set_full_size(bounds.size());
    592   EXPECT_NE(saved_restored_height, panel->GetRestoredBounds().height());
    593 
    594   panel->Close();
    595 }
    596 
    597 IN_PROC_BROWSER_TEST_F(PanelBrowserTest, MinimizeRestore) {
    598   // Test with one panel.
    599   CreatePanelWithBounds("PanelTest1", gfx::Rect(0, 0, 100, 100));
    600   TestMinimizeRestore();
    601 
    602   PanelManager::GetInstance()->CloseAll();
    603 }
    604 
    605 IN_PROC_BROWSER_TEST_F(PanelBrowserTest, MinimizeRestoreTwoPanels) {
    606   // Test with two panels.
    607   CreatePanelWithBounds("PanelTest1", gfx::Rect(0, 0, 100, 100));
    608   CreatePanelWithBounds("PanelTest2", gfx::Rect(0, 0, 110, 110));
    609   TestMinimizeRestore();
    610 
    611   PanelManager::GetInstance()->CloseAll();
    612 }
    613 
    614 IN_PROC_BROWSER_TEST_F(PanelBrowserTest, MinimizeRestoreThreePanels) {
    615   // Test with three panels.
    616   CreatePanelWithBounds("PanelTest1", gfx::Rect(0, 0, 100, 100));
    617   CreatePanelWithBounds("PanelTest2", gfx::Rect(0, 0, 110, 110));
    618   CreatePanelWithBounds("PanelTest3", gfx::Rect(0, 0, 120, 120));
    619   TestMinimizeRestore();
    620 
    621   PanelManager::GetInstance()->CloseAll();
    622 }
    623 
    624 IN_PROC_BROWSER_TEST_F(PanelBrowserTest, MinimizeRestoreButtonClick) {
    625   // Test with three panels.
    626   Panel* panel1 = CreatePanel("PanelTest1");
    627   Panel* panel2 = CreatePanel("PanelTest2");
    628   Panel* panel3 = CreatePanel("PanelTest3");
    629   EXPECT_FALSE(panel1->IsMinimized());
    630   EXPECT_FALSE(panel2->IsMinimized());
    631   EXPECT_FALSE(panel3->IsMinimized());
    632 
    633   // Click restore button on an expanded panel. Expect no change.
    634   panel1->OnRestoreButtonClicked(panel::NO_MODIFIER);
    635   EXPECT_FALSE(panel1->IsMinimized());
    636   EXPECT_FALSE(panel2->IsMinimized());
    637   EXPECT_FALSE(panel3->IsMinimized());
    638 
    639   // Click minimize button on an expanded panel. Only that panel will minimize.
    640   panel1->OnMinimizeButtonClicked(panel::NO_MODIFIER);
    641   EXPECT_TRUE(panel1->IsMinimized());
    642   EXPECT_FALSE(panel2->IsMinimized());
    643   EXPECT_FALSE(panel3->IsMinimized());
    644 
    645   // Click minimize button on a minimized panel. Expect no change.
    646   panel1->OnMinimizeButtonClicked(panel::NO_MODIFIER);
    647   EXPECT_TRUE(panel1->IsMinimized());
    648   EXPECT_FALSE(panel2->IsMinimized());
    649   EXPECT_FALSE(panel3->IsMinimized());
    650 
    651   // Minimize all panels by clicking minimize button on an expanded panel
    652   // with the apply-all modifier.
    653   panel2->OnMinimizeButtonClicked(panel::APPLY_TO_ALL);
    654   EXPECT_TRUE(panel1->IsMinimized());
    655   EXPECT_TRUE(panel2->IsMinimized());
    656   EXPECT_TRUE(panel3->IsMinimized());
    657 
    658   // Click restore button on a minimized panel. Only that panel will restore.
    659   panel2->OnRestoreButtonClicked(panel::NO_MODIFIER);
    660   EXPECT_TRUE(panel1->IsMinimized());
    661   EXPECT_FALSE(panel2->IsMinimized());
    662   EXPECT_TRUE(panel3->IsMinimized());
    663 
    664   // Restore all panels by clicking restore button on a minimized panel.
    665   panel3->OnRestoreButtonClicked(panel::APPLY_TO_ALL);
    666   EXPECT_FALSE(panel1->IsMinimized());
    667   EXPECT_FALSE(panel2->IsMinimized());
    668   EXPECT_FALSE(panel3->IsMinimized());
    669 }
    670 
    671 // http://crbug.com/243891 flaky on Linux
    672 #if defined(OS_LINUX)
    673 #define MAYBE_RestoreAllWithTitlebarClick DISABLED_RestoreAllWithTitlebarClick
    674 #else
    675 #define MAYBE_RestoreAllWithTitlebarClick RestoreAllWithTitlebarClick
    676 #endif
    677 IN_PROC_BROWSER_TEST_F(PanelBrowserTest, MAYBE_RestoreAllWithTitlebarClick) {
    678   // Test with three panels.
    679   Panel* panel1 = CreatePanel("PanelTest1");
    680   Panel* panel2 = CreatePanel("PanelTest2");
    681   Panel* panel3 = CreatePanel("PanelTest3");
    682   EXPECT_FALSE(panel1->IsMinimized());
    683   EXPECT_FALSE(panel2->IsMinimized());
    684   EXPECT_FALSE(panel3->IsMinimized());
    685 
    686   scoped_ptr<NativePanelTesting> test_panel1(
    687       CreateNativePanelTesting(panel1));
    688   scoped_ptr<NativePanelTesting> test_panel2(
    689       CreateNativePanelTesting(panel2));
    690   scoped_ptr<NativePanelTesting> test_panel3(
    691       CreateNativePanelTesting(panel3));
    692 
    693   // Click on an expanded panel's titlebar using the apply-all modifier.
    694   // Verify expansion state is unchanged.
    695   test_panel2->PressLeftMouseButtonTitlebar(panel2->GetBounds().origin(),
    696                                             panel::APPLY_TO_ALL);
    697   test_panel2->ReleaseMouseButtonTitlebar(panel::APPLY_TO_ALL);
    698   EXPECT_FALSE(panel1->IsMinimized());
    699   EXPECT_FALSE(panel2->IsMinimized());
    700   EXPECT_FALSE(panel3->IsMinimized());
    701 
    702   // Click on a minimized panel's titlebar using the apply-all modifier.
    703   panel1->Minimize();
    704   panel2->Minimize();
    705   panel3->Minimize();
    706   EXPECT_TRUE(panel1->IsMinimized());
    707   EXPECT_TRUE(panel2->IsMinimized());
    708   EXPECT_TRUE(panel3->IsMinimized());
    709 
    710   // Nothing changes until mouse is released.
    711   test_panel1->PressLeftMouseButtonTitlebar(panel1->GetBounds().origin(),
    712                                             panel::APPLY_TO_ALL);
    713   EXPECT_TRUE(panel1->IsMinimized());
    714   EXPECT_TRUE(panel2->IsMinimized());
    715   EXPECT_TRUE(panel3->IsMinimized());
    716   // Verify all panels restored when mouse is released.
    717   test_panel1->ReleaseMouseButtonTitlebar(panel::APPLY_TO_ALL);
    718   EXPECT_FALSE(panel1->IsMinimized());
    719   EXPECT_FALSE(panel2->IsMinimized());
    720   EXPECT_FALSE(panel3->IsMinimized());
    721 
    722   // Minimize a single panel. Then click on expanded panel with apply-all
    723   // modifier. Verify nothing changes.
    724   panel1->Minimize();
    725   EXPECT_TRUE(panel1->IsMinimized());
    726   EXPECT_FALSE(panel2->IsMinimized());
    727   EXPECT_FALSE(panel3->IsMinimized());
    728 
    729   test_panel2->PressLeftMouseButtonTitlebar(panel2->GetBounds().origin(),
    730                                             panel::APPLY_TO_ALL);
    731   test_panel2->ReleaseMouseButtonTitlebar(panel::APPLY_TO_ALL);
    732   EXPECT_TRUE(panel1->IsMinimized());
    733   EXPECT_FALSE(panel2->IsMinimized());
    734   EXPECT_FALSE(panel3->IsMinimized());
    735 
    736   // Minimize another panel. Then click on a minimized panel with apply-all
    737   // modifier to restore all panels.
    738   panel2->Minimize();
    739   EXPECT_TRUE(panel1->IsMinimized());
    740   EXPECT_TRUE(panel2->IsMinimized());
    741   EXPECT_FALSE(panel3->IsMinimized());
    742 
    743   test_panel2->PressLeftMouseButtonTitlebar(panel2->GetBounds().origin(),
    744                                             panel::APPLY_TO_ALL);
    745   test_panel2->ReleaseMouseButtonTitlebar(panel::APPLY_TO_ALL);
    746   EXPECT_FALSE(panel1->IsMinimized());
    747   EXPECT_FALSE(panel2->IsMinimized());
    748   EXPECT_FALSE(panel3->IsMinimized());
    749 
    750   // Click on the single minimized panel. Verify all are restored.
    751   panel1->Minimize();
    752   EXPECT_TRUE(panel1->IsMinimized());
    753   EXPECT_FALSE(panel2->IsMinimized());
    754   EXPECT_FALSE(panel3->IsMinimized());
    755 
    756   test_panel1->PressLeftMouseButtonTitlebar(panel1->GetBounds().origin(),
    757                                             panel::APPLY_TO_ALL);
    758   test_panel1->ReleaseMouseButtonTitlebar(panel::APPLY_TO_ALL);
    759   EXPECT_FALSE(panel1->IsMinimized());
    760   EXPECT_FALSE(panel2->IsMinimized());
    761   EXPECT_FALSE(panel3->IsMinimized());
    762 
    763   // Click on the single expanded panel. Verify nothing changes.
    764   panel1->Minimize();
    765   panel3->Minimize();
    766   EXPECT_TRUE(panel1->IsMinimized());
    767   EXPECT_FALSE(panel2->IsMinimized());
    768   EXPECT_TRUE(panel3->IsMinimized());
    769 
    770   test_panel2->PressLeftMouseButtonTitlebar(panel2->GetBounds().origin(),
    771                                             panel::APPLY_TO_ALL);
    772   test_panel2->ReleaseMouseButtonTitlebar(panel::APPLY_TO_ALL);
    773   EXPECT_TRUE(panel1->IsMinimized());
    774   EXPECT_FALSE(panel2->IsMinimized());
    775   EXPECT_TRUE(panel3->IsMinimized());
    776 
    777   // Hover over a minimized panel and click on the titlebar while it is in
    778   // title-only mode. Should restore all panels.
    779   panel2->Minimize();
    780   EXPECT_TRUE(panel1->IsMinimized());
    781   EXPECT_TRUE(panel2->IsMinimized());
    782   EXPECT_TRUE(panel3->IsMinimized());
    783 
    784   MoveMouseAndWaitForExpansionStateChange(panel2, panel2->GetBounds().origin());
    785   EXPECT_EQ(Panel::TITLE_ONLY, panel1->expansion_state());
    786   EXPECT_EQ(Panel::TITLE_ONLY, panel2->expansion_state());
    787   EXPECT_EQ(Panel::TITLE_ONLY, panel3->expansion_state());
    788 
    789   test_panel3->PressLeftMouseButtonTitlebar(panel3->GetBounds().origin(),
    790                                             panel::APPLY_TO_ALL);
    791   test_panel3->ReleaseMouseButtonTitlebar(panel::APPLY_TO_ALL);
    792   EXPECT_FALSE(panel1->IsMinimized());
    793   EXPECT_FALSE(panel2->IsMinimized());
    794   EXPECT_FALSE(panel3->IsMinimized());
    795 
    796   // Draw attention to a minimized panel. Click on a minimized panel that is
    797   // not drawing attention. Verify restore all applies without affecting
    798   // draw attention.
    799   panel1->Minimize();
    800   panel2->Minimize();
    801   panel3->Minimize();
    802   EXPECT_TRUE(panel1->IsMinimized());
    803   EXPECT_TRUE(panel2->IsMinimized());
    804   EXPECT_TRUE(panel3->IsMinimized());
    805 
    806   panel1->FlashFrame(true);
    807   EXPECT_TRUE(panel1->IsDrawingAttention());
    808 
    809   test_panel2->PressLeftMouseButtonTitlebar(panel2->GetBounds().origin(),
    810                                             panel::APPLY_TO_ALL);
    811   test_panel2->ReleaseMouseButtonTitlebar(panel::APPLY_TO_ALL);
    812   EXPECT_FALSE(panel1->IsMinimized());
    813   EXPECT_FALSE(panel2->IsMinimized());
    814   EXPECT_FALSE(panel3->IsMinimized());
    815   EXPECT_TRUE(panel1->IsDrawingAttention());
    816 
    817   // Restore all panels by clicking on the minimized panel that is drawing
    818   // attention. Verify restore all applies and clears draw attention.
    819   panel1->Minimize();
    820   panel2->Minimize();
    821   panel3->Minimize();
    822   EXPECT_TRUE(panel1->IsMinimized());
    823   EXPECT_TRUE(panel2->IsMinimized());
    824   EXPECT_TRUE(panel3->IsMinimized());
    825 
    826   test_panel1->PressLeftMouseButtonTitlebar(panel1->GetBounds().origin(),
    827                                             panel::APPLY_TO_ALL);
    828   test_panel1->ReleaseMouseButtonTitlebar(panel::APPLY_TO_ALL);
    829   EXPECT_FALSE(panel1->IsMinimized());
    830   EXPECT_FALSE(panel2->IsMinimized());
    831   EXPECT_FALSE(panel3->IsMinimized());
    832   EXPECT_FALSE(panel1->IsDrawingAttention());
    833 
    834   PanelManager::GetInstance()->CloseAll();
    835 }
    836 
    837 IN_PROC_BROWSER_TEST_F(PanelBrowserTest,
    838                        MinimizeRestoreOnAutoHidingDesktopBar) {
    839   PanelManager* panel_manager = PanelManager::GetInstance();
    840   DockedPanelCollection* docked_collection = panel_manager->docked_collection();
    841   int expected_bottom_on_expanded = docked_collection->work_area().bottom();
    842   int expected_bottom_on_title_only = expected_bottom_on_expanded;
    843   int expected_bottom_on_minimized = expected_bottom_on_expanded;
    844 
    845   // Turn on auto-hiding.
    846   static const int bottom_bar_thickness = 40;
    847   mock_display_settings_provider()->EnableAutoHidingDesktopBar(
    848       DisplaySettingsProvider::DESKTOP_BAR_ALIGNED_BOTTOM,
    849       true,
    850       bottom_bar_thickness);
    851   expected_bottom_on_title_only -= bottom_bar_thickness;
    852 
    853   Panel* panel = CreatePanel("1");
    854   int initial_height = panel->GetBounds().height();
    855 
    856   EXPECT_EQ(Panel::EXPANDED, panel->expansion_state());
    857   EXPECT_EQ(expected_bottom_on_expanded, panel->GetBounds().bottom());
    858 
    859   panel->Minimize();
    860   WaitForBoundsAnimationFinished(panel);
    861   EXPECT_EQ(Panel::MINIMIZED, panel->expansion_state());
    862   EXPECT_EQ(panel::kMinimizedPanelHeight, panel->GetBounds().height());
    863   EXPECT_EQ(expected_bottom_on_minimized, panel->GetBounds().bottom());
    864 
    865   panel->SetExpansionState(Panel::TITLE_ONLY);
    866   WaitForBoundsAnimationFinished(panel);
    867   EXPECT_EQ(Panel::TITLE_ONLY, panel->expansion_state());
    868   EXPECT_EQ(panel::kTitlebarHeight, panel->GetBounds().height());
    869   EXPECT_EQ(expected_bottom_on_title_only, panel->GetBounds().bottom());
    870 
    871   panel->Restore();
    872   WaitForBoundsAnimationFinished(panel);
    873   EXPECT_EQ(Panel::EXPANDED, panel->expansion_state());
    874   EXPECT_EQ(initial_height, panel->GetBounds().height());
    875   EXPECT_EQ(expected_bottom_on_expanded, panel->GetBounds().bottom());
    876 
    877   panel->Close();
    878 }
    879 
    880 IN_PROC_BROWSER_TEST_F(PanelBrowserTest, ChangeAutoHideTaskBarThickness) {
    881   PanelManager* manager = PanelManager::GetInstance();
    882   DockedPanelCollection* docked_collection = manager->docked_collection();
    883   int initial_starting_right_position =
    884       docked_collection->StartingRightPosition();
    885 
    886   int bottom_bar_thickness = 20;
    887   int right_bar_thickness = 30;
    888   mock_display_settings_provider()->EnableAutoHidingDesktopBar(
    889       DisplaySettingsProvider::DESKTOP_BAR_ALIGNED_BOTTOM,
    890       true,
    891       bottom_bar_thickness);
    892   mock_display_settings_provider()->EnableAutoHidingDesktopBar(
    893       DisplaySettingsProvider::DESKTOP_BAR_ALIGNED_RIGHT,
    894       true,
    895       right_bar_thickness);
    896   EXPECT_EQ(initial_starting_right_position,
    897             docked_collection->StartingRightPosition());
    898 
    899   Panel* panel = CreatePanel("PanelTest");
    900   panel->SetExpansionState(Panel::TITLE_ONLY);
    901   WaitForBoundsAnimationFinished(panel);
    902 
    903   EXPECT_EQ(docked_collection->work_area().bottom() - bottom_bar_thickness,
    904             panel->GetBounds().bottom());
    905   EXPECT_EQ(docked_collection->StartingRightPosition(),
    906             panel->GetBounds().right());
    907 
    908   initial_starting_right_position = docked_collection->StartingRightPosition();
    909   int bottom_bar_thickness_delta = 10;
    910   bottom_bar_thickness += bottom_bar_thickness_delta;
    911   int right_bar_thickness_delta = 15;
    912   right_bar_thickness += right_bar_thickness_delta;
    913   mock_display_settings_provider()->SetDesktopBarThickness(
    914       DisplaySettingsProvider::DESKTOP_BAR_ALIGNED_BOTTOM,
    915       bottom_bar_thickness);
    916   mock_display_settings_provider()->SetDesktopBarThickness(
    917       DisplaySettingsProvider::DESKTOP_BAR_ALIGNED_RIGHT,
    918       right_bar_thickness);
    919   base::MessageLoopForUI::current()->RunUntilIdle();
    920   EXPECT_EQ(initial_starting_right_position,
    921             docked_collection->StartingRightPosition());
    922   EXPECT_EQ(docked_collection->work_area().bottom() - bottom_bar_thickness,
    923             panel->GetBounds().bottom());
    924   EXPECT_EQ(docked_collection->StartingRightPosition(),
    925             panel->GetBounds().right());
    926 
    927   initial_starting_right_position = docked_collection->StartingRightPosition();
    928   bottom_bar_thickness_delta = 20;
    929   bottom_bar_thickness -= bottom_bar_thickness_delta;
    930   right_bar_thickness_delta = 10;
    931   right_bar_thickness -= right_bar_thickness_delta;
    932   mock_display_settings_provider()->SetDesktopBarThickness(
    933       DisplaySettingsProvider::DESKTOP_BAR_ALIGNED_BOTTOM,
    934       bottom_bar_thickness);
    935   mock_display_settings_provider()->SetDesktopBarThickness(
    936       DisplaySettingsProvider::DESKTOP_BAR_ALIGNED_RIGHT,
    937       right_bar_thickness);
    938   base::MessageLoopForUI::current()->RunUntilIdle();
    939   EXPECT_EQ(docked_collection->StartingRightPosition(),
    940             initial_starting_right_position);
    941   EXPECT_EQ(docked_collection->work_area().bottom() - bottom_bar_thickness,
    942             panel->GetBounds().bottom());
    943   EXPECT_EQ(docked_collection->StartingRightPosition(),
    944             panel->GetBounds().right());
    945 
    946   panel->Close();
    947 }
    948 
    949 IN_PROC_BROWSER_TEST_F(PanelBrowserTest, ActivatePanelOrTabbedWindow) {
    950   if (!WmSupportWindowActivation()) {
    951     LOG(WARNING) << "Skipping test due to WM problems.";
    952     return;
    953   }
    954 
    955   Panel* panel1 = CreatePanel("Panel1");
    956   Panel* panel2 = CreatePanel("Panel2");
    957 
    958   // Activate main tabbed window.
    959   browser()->window()->Activate();
    960   WaitForPanelActiveState(panel2, SHOW_AS_INACTIVE);
    961 
    962   // Activate a panel.
    963   panel2->Activate();
    964   WaitForPanelActiveState(panel2, SHOW_AS_ACTIVE);
    965 
    966   // Activate the main tabbed window back.
    967   browser()->window()->Activate();
    968   WaitForPanelActiveState(panel2, SHOW_AS_INACTIVE);
    969 
    970   // Activate another panel.
    971   panel1->Activate();
    972   WaitForPanelActiveState(panel1, SHOW_AS_ACTIVE);
    973   WaitForPanelActiveState(panel2, SHOW_AS_INACTIVE);
    974 
    975   // Switch focus between panels.
    976   panel2->Activate();
    977   WaitForPanelActiveState(panel2, SHOW_AS_ACTIVE);
    978   WaitForPanelActiveState(panel1, SHOW_AS_INACTIVE);
    979 
    980   PanelManager::GetInstance()->CloseAll();
    981 }
    982 
    983 // TODO(jianli): To be enabled for other platforms.
    984 #if defined(OS_WIN) || defined(OS_LINUX)
    985 #define MAYBE_ActivateDeactivateBasic ActivateDeactivateBasic
    986 #else
    987 #define MAYBE_ActivateDeactivateBasic DISABLED_ActivateDeactivateBasic
    988 #endif
    989 IN_PROC_BROWSER_TEST_F(PanelBrowserTest, MAYBE_ActivateDeactivateBasic) {
    990   if (!WmSupportWindowActivation()) {
    991     LOG(WARNING) << "Skipping test due to WM problems.";
    992     return;
    993   }
    994 
    995   // Create an active panel.
    996   Panel* panel = CreatePanel("PanelTest");
    997   scoped_ptr<NativePanelTesting> native_panel_testing(
    998       CreateNativePanelTesting(panel));
    999 
   1000   WaitForPanelActiveState(panel, SHOW_AS_ACTIVE);  // doublecheck active state
   1001   EXPECT_TRUE(native_panel_testing->VerifyActiveState(true));
   1002 
   1003   // Deactivate the panel.
   1004   panel->Deactivate();
   1005   WaitForPanelActiveState(panel, SHOW_AS_INACTIVE);
   1006 
   1007   // On GTK there is no way to deactivate a window. So the Deactivate() call
   1008   // above does not actually deactivate the window, but simply lowers it.
   1009 #if !defined(OS_LINUX)
   1010   EXPECT_TRUE(native_panel_testing->VerifyActiveState(false));
   1011 #endif
   1012 
   1013   // This test does not reactivate the panel because the panel might not be
   1014   // reactivated programmatically once it is deactivated.
   1015 }
   1016 
   1017 IN_PROC_BROWSER_TEST_F(PanelBrowserTest, ActivateDeactivateMultiple) {
   1018   if (!WmSupportWindowActivation()) {
   1019     LOG(WARNING) << "Skipping test due to WM problems.";
   1020     return;
   1021   }
   1022 
   1023   BrowserWindow* tabbed_window = browser()->window();
   1024 
   1025   // Create 4 panels in the following screen layout:
   1026   //    P3  P2  P1  P0
   1027   const int kNumPanels = 4;
   1028   for (int i = 0; i < kNumPanels; ++i)
   1029     CreatePanelWithBounds(MakePanelName(i), gfx::Rect(0, 0, 100, 100));
   1030   const std::vector<Panel*>& panels = PanelManager::GetInstance()->panels();
   1031 
   1032   std::vector<bool> expected_active_states;
   1033   std::vector<bool> last_active_states;
   1034 
   1035   // The last created panel, P3, should be active.
   1036   expected_active_states = ProduceExpectedActiveStates(3);
   1037   EXPECT_EQ(expected_active_states, GetAllPanelActiveStates());
   1038   EXPECT_FALSE(tabbed_window->IsActive());
   1039 
   1040   // Activating P1 should cause P3 to lose focus.
   1041   panels[1]->Activate();
   1042   last_active_states = expected_active_states;
   1043   expected_active_states = ProduceExpectedActiveStates(1);
   1044   WaitForPanelActiveStates(last_active_states, expected_active_states);
   1045   EXPECT_EQ(expected_active_states, GetAllPanelActiveStates());
   1046 
   1047   // Minimizing inactive panel P2 should not affect other panels' active states.
   1048   panels[2]->SetExpansionState(Panel::MINIMIZED);
   1049   EXPECT_EQ(expected_active_states, GetAllPanelActiveStates());
   1050   EXPECT_FALSE(tabbed_window->IsActive());
   1051 }
   1052 
   1053 IN_PROC_BROWSER_TEST_F(PanelBrowserTest, DrawAttentionBasic) {
   1054   Panel* panel = CreateInactivePanel("P1");
   1055   scoped_ptr<NativePanelTesting> native_panel_testing(
   1056       CreateNativePanelTesting(panel));
   1057 
   1058   // Test that the attention is drawn when the expanded panel is not in focus.
   1059   EXPECT_EQ(Panel::EXPANDED, panel->expansion_state());
   1060   EXPECT_FALSE(panel->IsActive());
   1061   EXPECT_FALSE(panel->IsDrawingAttention());
   1062   panel->FlashFrame(true);
   1063   EXPECT_TRUE(panel->IsDrawingAttention());
   1064   EXPECT_TRUE(native_panel_testing->VerifyDrawingAttention());
   1065 
   1066   // Stop drawing attention.
   1067   panel->FlashFrame(false);
   1068   EXPECT_FALSE(panel->IsDrawingAttention());
   1069   EXPECT_FALSE(native_panel_testing->VerifyDrawingAttention());
   1070 
   1071   // Draw attention, then minimize. Titlebar should remain visible.
   1072   panel->FlashFrame(true);
   1073   EXPECT_TRUE(panel->IsDrawingAttention());
   1074 
   1075   panel->Minimize();
   1076   EXPECT_TRUE(panel->IsDrawingAttention());
   1077   EXPECT_EQ(Panel::TITLE_ONLY, panel->expansion_state());
   1078 
   1079   // Stop drawing attention. Titlebar should no longer be visible.
   1080   panel->FlashFrame(false);
   1081   EXPECT_FALSE(panel->IsDrawingAttention());
   1082   EXPECT_EQ(Panel::MINIMIZED, panel->expansion_state());
   1083 
   1084   panel->Close();
   1085 }
   1086 
   1087 IN_PROC_BROWSER_TEST_F(PanelBrowserTest, DrawAttentionWhileMinimized) {
   1088   Panel* panel1 = CreateInactivePanel("P1");
   1089   Panel* panel2 = CreateInactivePanel("P2");
   1090 
   1091   scoped_ptr<NativePanelTesting> native_panel1_testing(
   1092       CreateNativePanelTesting(panel1));
   1093 
   1094   // Test that the attention is drawn and the title-bar is brought up when the
   1095   // minimized panel is drawing attention.
   1096   panel1->Minimize();
   1097   EXPECT_EQ(Panel::MINIMIZED, panel1->expansion_state());
   1098   panel1->FlashFrame(true);
   1099   EXPECT_TRUE(panel1->IsDrawingAttention());
   1100   EXPECT_EQ(Panel::TITLE_ONLY, panel1->expansion_state());
   1101   EXPECT_TRUE(native_panel1_testing->VerifyDrawingAttention());
   1102 
   1103   // Test that we cannot bring up other minimized panel if the mouse is over
   1104   // the panel that draws attension.
   1105   panel2->Minimize();
   1106   gfx::Point hover_point(panel1->GetBounds().origin());
   1107   MoveMouse(hover_point);
   1108   EXPECT_EQ(Panel::TITLE_ONLY, panel1->expansion_state());
   1109   EXPECT_EQ(Panel::MINIMIZED, panel2->expansion_state());
   1110 
   1111   // Test that we cannot bring down the panel that is drawing the attention.
   1112   hover_point.set_y(hover_point.y() - 200);
   1113   MoveMouse(hover_point);
   1114   EXPECT_EQ(Panel::TITLE_ONLY, panel1->expansion_state());
   1115 
   1116   // Test that the attention is cleared when activated.
   1117   panel1->Activate();
   1118   WaitForPanelActiveState(panel1, SHOW_AS_ACTIVE);
   1119   EXPECT_FALSE(panel1->IsDrawingAttention());
   1120   EXPECT_EQ(Panel::EXPANDED, panel1->expansion_state());
   1121   EXPECT_FALSE(native_panel1_testing->VerifyDrawingAttention());
   1122 
   1123   PanelManager::GetInstance()->CloseAll();
   1124 }
   1125 
   1126 // Verify that minimized state of a panel is correct after draw attention
   1127 // is stopped when there are other minimized panels.
   1128 IN_PROC_BROWSER_TEST_F(PanelBrowserTest, StopDrawingAttentionWhileMinimized) {
   1129   Panel* panel1 = CreateInactivePanel("P1");
   1130   Panel* panel2 = CreateInactivePanel("P2");
   1131 
   1132   panel1->Minimize();
   1133   EXPECT_EQ(Panel::MINIMIZED, panel1->expansion_state());
   1134   panel2->Minimize();
   1135   EXPECT_EQ(Panel::MINIMIZED, panel2->expansion_state());
   1136 
   1137   // Verify panel returns to minimized state when no longer drawing attention.
   1138   panel1->FlashFrame(true);
   1139   EXPECT_TRUE(panel1->IsDrawingAttention());
   1140   EXPECT_EQ(Panel::TITLE_ONLY, panel1->expansion_state());
   1141 
   1142   panel1->FlashFrame(false);
   1143   EXPECT_FALSE(panel1->IsDrawingAttention());
   1144   EXPECT_EQ(Panel::MINIMIZED, panel1->expansion_state());
   1145 
   1146   // Hover over other minimized panel to bring up titlebars.
   1147   gfx::Point hover_point(panel2->GetBounds().origin());
   1148   MoveMouseAndWaitForExpansionStateChange(panel1, hover_point);
   1149   EXPECT_EQ(Panel::TITLE_ONLY, panel1->expansion_state());
   1150   EXPECT_EQ(Panel::TITLE_ONLY, panel2->expansion_state());
   1151 
   1152   // Verify panel keeps titlebar visible when no longer drawing attention
   1153   // if titlebars are up.
   1154   panel1->FlashFrame(true);
   1155   EXPECT_TRUE(panel1->IsDrawingAttention());
   1156   EXPECT_EQ(Panel::TITLE_ONLY, panel1->expansion_state());
   1157 
   1158   panel1->FlashFrame(false);
   1159   EXPECT_FALSE(panel1->IsDrawingAttention());
   1160   EXPECT_EQ(Panel::TITLE_ONLY, panel1->expansion_state());
   1161 
   1162   // Move mouse away. All panels should return to minimized state.
   1163   hover_point.set_y(hover_point.y() - 200);
   1164   MoveMouseAndWaitForExpansionStateChange(panel1, hover_point);
   1165   EXPECT_EQ(Panel::MINIMIZED, panel1->expansion_state());
   1166   EXPECT_EQ(Panel::MINIMIZED, panel2->expansion_state());
   1167 
   1168   // Verify minimized panel that is drawing attention stays in title-only mode
   1169   // after attention is cleared if mouse is in the titlebar area.
   1170   panel1->FlashFrame(true);
   1171   EXPECT_TRUE(panel1->IsDrawingAttention());
   1172   EXPECT_EQ(Panel::TITLE_ONLY, panel1->expansion_state());
   1173 
   1174   gfx::Point hover_point_in_panel(panel1->GetBounds().origin());
   1175   MoveMouse(hover_point_in_panel);
   1176 
   1177   panel1->FlashFrame(false);
   1178   EXPECT_FALSE(panel1->IsDrawingAttention());
   1179   EXPECT_EQ(Panel::TITLE_ONLY, panel1->expansion_state());
   1180   EXPECT_EQ(Panel::MINIMIZED, panel2->expansion_state());
   1181 
   1182   // Typical user scenario will detect the mouse in the panel
   1183   // after attention is cleared, causing titles to pop up, so
   1184   // we simulate that here.
   1185   MoveMouseAndWaitForExpansionStateChange(panel2, hover_point_in_panel);
   1186   EXPECT_EQ(Panel::TITLE_ONLY, panel1->expansion_state());
   1187   EXPECT_EQ(Panel::TITLE_ONLY, panel2->expansion_state());
   1188 
   1189   // Move mouse away and panels should go back to fully minimized state.
   1190   MoveMouseAndWaitForExpansionStateChange(panel1, hover_point);
   1191   EXPECT_EQ(Panel::MINIMIZED, panel1->expansion_state());
   1192   EXPECT_EQ(Panel::MINIMIZED, panel2->expansion_state());
   1193 
   1194   PanelManager::GetInstance()->CloseAll();
   1195 }
   1196 
   1197 IN_PROC_BROWSER_TEST_F(PanelBrowserTest, DrawAttentionWhenActive) {
   1198   // Create an active panel.
   1199   Panel* panel = CreatePanel("P1");
   1200   scoped_ptr<NativePanelTesting> native_panel_testing(
   1201       CreateNativePanelTesting(panel));
   1202 
   1203   // Test that the attention should not be drawn if the expanded panel is in
   1204   // focus.
   1205   panel->FlashFrame(true);
   1206   EXPECT_FALSE(panel->IsDrawingAttention());
   1207   EXPECT_FALSE(native_panel_testing->VerifyDrawingAttention());
   1208 
   1209   panel->Close();
   1210 }
   1211 
   1212 IN_PROC_BROWSER_TEST_F(PanelBrowserTest, DrawAttentionResetOnActivate) {
   1213   Panel* panel = CreateInactivePanel("P1");
   1214   scoped_ptr<NativePanelTesting> native_panel_testing(
   1215       CreateNativePanelTesting(panel));
   1216 
   1217   panel->FlashFrame(true);
   1218   EXPECT_TRUE(panel->IsDrawingAttention());
   1219   EXPECT_TRUE(native_panel_testing->VerifyDrawingAttention());
   1220 
   1221   // Test that the attention is cleared when panel gets focus.
   1222   panel->Activate();
   1223   WaitForPanelActiveState(panel, SHOW_AS_ACTIVE);
   1224   EXPECT_FALSE(panel->IsDrawingAttention());
   1225   EXPECT_FALSE(native_panel_testing->VerifyDrawingAttention());
   1226 
   1227   panel->Close();
   1228 }
   1229 
   1230 IN_PROC_BROWSER_TEST_F(PanelBrowserTest,
   1231                        DrawAttentionMinimizedNotResetOnActivate) {
   1232   Panel* panel = CreateInactivePanel("P1");
   1233 
   1234   panel->Minimize();
   1235   EXPECT_TRUE(panel->IsMinimized());
   1236   panel->FlashFrame(true);
   1237   EXPECT_TRUE(panel->IsDrawingAttention());
   1238 
   1239   // Simulate panel being activated while minimized. Cannot call
   1240   // Activate() as that expands the panel.
   1241   panel->OnActiveStateChanged(true);
   1242   EXPECT_TRUE(panel->IsDrawingAttention());  // Unchanged.
   1243 
   1244   // Unminimize panel to show that attention would have been cleared
   1245   // if panel had not been minimized.
   1246   panel->Restore();
   1247   EXPECT_FALSE(panel->IsMinimized());
   1248   EXPECT_TRUE(panel->IsDrawingAttention());  // Unchanged.
   1249 
   1250   panel->OnActiveStateChanged(true);
   1251   EXPECT_FALSE(panel->IsDrawingAttention());  // Attention cleared.
   1252 
   1253   panel->Close();
   1254 }
   1255 
   1256 IN_PROC_BROWSER_TEST_F(PanelBrowserTest, DrawAttentionResetOnClick) {
   1257   Panel* panel = CreateInactivePanel("P1");
   1258   scoped_ptr<NativePanelTesting> native_panel_testing(
   1259       CreateNativePanelTesting(panel));
   1260 
   1261   panel->FlashFrame(true);
   1262   EXPECT_TRUE(panel->IsDrawingAttention());
   1263   EXPECT_TRUE(native_panel_testing->VerifyDrawingAttention());
   1264 
   1265   // Test that the attention is cleared when panel gets focus.
   1266   native_panel_testing->PressLeftMouseButtonTitlebar(
   1267       panel->GetBounds().origin());
   1268   native_panel_testing->ReleaseMouseButtonTitlebar();
   1269 
   1270   WaitForPanelActiveState(panel, SHOW_AS_ACTIVE);
   1271   EXPECT_FALSE(panel->IsDrawingAttention());
   1272   EXPECT_FALSE(native_panel_testing->VerifyDrawingAttention());
   1273 
   1274   panel->Close();
   1275 }
   1276 
   1277 // http://crbug.com/175760; several panel tests failing regularly on mac.
   1278 #if defined(OS_MACOSX)
   1279 #define MAYBE_MinimizeImmediatelyAfterRestore \
   1280   DISABLED_MinimizeImmediatelyAfterRestore
   1281 #else
   1282 #define MAYBE_MinimizeImmediatelyAfterRestore MinimizeImmediatelyAfterRestore
   1283 #endif
   1284 IN_PROC_BROWSER_TEST_F(PanelBrowserTest,
   1285                        MAYBE_MinimizeImmediatelyAfterRestore) {
   1286   CreatePanelParams params("Panel Test", gfx::Rect(), SHOW_AS_ACTIVE);
   1287   Panel* panel = CreatePanelWithParams(params);
   1288   scoped_ptr<NativePanelTesting> native_panel_testing(
   1289       CreateNativePanelTesting(panel));
   1290 
   1291   PanelActiveStateObserver signal(panel, false);
   1292   panel->Minimize();  // this should deactivate.
   1293   signal.Wait();
   1294   EXPECT_EQ(Panel::MINIMIZED, panel->expansion_state());
   1295 
   1296   panel->Restore();
   1297   EXPECT_EQ(Panel::EXPANDED, panel->expansion_state());
   1298 
   1299   // Verify that minimizing a panel right after expansion works.
   1300   panel->Minimize();
   1301   EXPECT_EQ(Panel::MINIMIZED, panel->expansion_state());
   1302 
   1303   panel->Close();
   1304 }
   1305 
   1306 IN_PROC_BROWSER_TEST_F(PanelBrowserTest, FocusLostOnMinimize) {
   1307   CreatePanelParams params("Initially Active", gfx::Rect(), SHOW_AS_ACTIVE);
   1308   Panel* panel = CreatePanelWithParams(params);
   1309   EXPECT_EQ(Panel::EXPANDED, panel->expansion_state());
   1310 
   1311   PanelActiveStateObserver signal(panel, false);
   1312   panel->Minimize();
   1313   signal.Wait();
   1314   panel->Close();
   1315 }
   1316 
   1317 IN_PROC_BROWSER_TEST_F(PanelBrowserTest, CreateInactiveSwitchToActive) {
   1318   Panel* panel = CreateInactivePanel("1");
   1319 
   1320   panel->Activate();
   1321   WaitForPanelActiveState(panel, SHOW_AS_ACTIVE);
   1322 
   1323   panel->Close();
   1324 }
   1325 
   1326 // TODO(dimich): try/enable on other platforms. See bug 103253 for details on
   1327 // why this is disabled on windows.
   1328 #if defined(OS_MACOSX)
   1329 #define MAYBE_MinimizeTwoPanelsWithoutTabbedWindow \
   1330     MinimizeTwoPanelsWithoutTabbedWindow
   1331 #else
   1332 #define MAYBE_MinimizeTwoPanelsWithoutTabbedWindow \
   1333     DISABLED_MinimizeTwoPanelsWithoutTabbedWindow
   1334 #endif
   1335 
   1336 // When there are 2 panels and no chrome window, minimizing one panel does
   1337 // not expand/focuses another.
   1338 IN_PROC_BROWSER_TEST_F(PanelBrowserTest,
   1339                        MAYBE_MinimizeTwoPanelsWithoutTabbedWindow) {
   1340   CreatePanelParams params("Initially Inactive", gfx::Rect(), SHOW_AS_INACTIVE);
   1341   Panel* panel1 = CreatePanelWithParams(params);
   1342   Panel* panel2 = CreatePanelWithParams(params);
   1343 
   1344   // Close main tabbed window.
   1345   content::WindowedNotificationObserver signal(
   1346       chrome::NOTIFICATION_BROWSER_CLOSED,
   1347       content::Source<Browser>(browser()));
   1348   chrome::CloseWindow(browser());
   1349   signal.Wait();
   1350 
   1351   EXPECT_EQ(Panel::EXPANDED, panel1->expansion_state());
   1352   EXPECT_EQ(Panel::EXPANDED, panel2->expansion_state());
   1353   panel1->Activate();
   1354   WaitForPanelActiveState(panel1, SHOW_AS_ACTIVE);
   1355 
   1356   panel1->SetExpansionState(Panel::MINIMIZED);
   1357   base::MessageLoop::current()->RunUntilIdle();
   1358   WaitForPanelActiveState(panel1, SHOW_AS_INACTIVE);
   1359   EXPECT_EQ(Panel::MINIMIZED, panel1->expansion_state());
   1360 
   1361   panel2->SetExpansionState(Panel::MINIMIZED);
   1362   base::MessageLoop::current()->RunUntilIdle();
   1363   WaitForPanelActiveState(panel2, SHOW_AS_INACTIVE);
   1364   EXPECT_EQ(Panel::MINIMIZED, panel2->expansion_state());
   1365 
   1366   // Verify that panel1 is still minimized and not active.
   1367   WaitForPanelActiveState(panel1, SHOW_AS_INACTIVE);
   1368   EXPECT_EQ(Panel::MINIMIZED, panel1->expansion_state());
   1369 
   1370   // Another check for the same.
   1371   EXPECT_FALSE(panel1->IsActive());
   1372   EXPECT_FALSE(panel2->IsActive());
   1373 
   1374   panel1->Close();
   1375   panel2->Close();
   1376 }
   1377 
   1378 IN_PROC_BROWSER_TEST_F(PanelBrowserTest,
   1379                        NonExtensionDomainPanelsCloseOnUninstall) {
   1380   // Create a test extension.
   1381   DictionaryValue empty_value;
   1382   scoped_refptr<extensions::Extension> extension =
   1383       CreateExtension(FILE_PATH_LITERAL("TestExtension"),
   1384                       extensions::Manifest::INTERNAL, empty_value);
   1385   std::string extension_app_name =
   1386       web_app::GenerateApplicationNameFromExtensionId(extension->id());
   1387 
   1388   PanelManager* panel_manager = PanelManager::GetInstance();
   1389   EXPECT_EQ(0, panel_manager->num_panels());
   1390 
   1391   // Create a panel with the extension as host.
   1392   CreatePanelParams params(extension_app_name, gfx::Rect(), SHOW_AS_ACTIVE);
   1393   std::string extension_domain_url(extensions::kExtensionScheme);
   1394   extension_domain_url += "://";
   1395   extension_domain_url += extension->id();
   1396   extension_domain_url += "/hello.html";
   1397   params.url = GURL(extension_domain_url);
   1398   Panel* panel = CreatePanelWithParams(params);
   1399   EXPECT_EQ(1, panel_manager->num_panels());
   1400 
   1401   // Create a panel with a non-extension host.
   1402   CreatePanelParams params1(extension_app_name, gfx::Rect(), SHOW_AS_ACTIVE);
   1403   params1.url = GURL(content::kAboutBlankURL);
   1404   Panel* panel1 = CreatePanelWithParams(params1);
   1405   EXPECT_EQ(2, panel_manager->num_panels());
   1406 
   1407   // Create another extension and a panel from that extension.
   1408   scoped_refptr<extensions::Extension> extension_other =
   1409       CreateExtension(FILE_PATH_LITERAL("TestExtensionOther"),
   1410                       extensions::Manifest::INTERNAL, empty_value);
   1411   std::string extension_app_name_other =
   1412       web_app::GenerateApplicationNameFromExtensionId(extension_other->id());
   1413   Panel* panel_other = CreatePanel(extension_app_name_other);
   1414 
   1415   content::WindowedNotificationObserver signal(
   1416       chrome::NOTIFICATION_PANEL_CLOSED,
   1417       content::Source<Panel>(panel));
   1418   content::WindowedNotificationObserver signal1(
   1419       chrome::NOTIFICATION_PANEL_CLOSED,
   1420       content::Source<Panel>(panel1));
   1421 
   1422   // Send unload notification on the first extension.
   1423   extensions::UnloadedExtensionInfo details(
   1424       extension.get(), extensions::UnloadedExtensionInfo::REASON_UNINSTALL);
   1425   content::NotificationService::current()->Notify(
   1426       chrome::NOTIFICATION_EXTENSION_UNLOADED,
   1427       content::Source<Profile>(browser()->profile()),
   1428       content::Details<extensions::UnloadedExtensionInfo>(&details));
   1429 
   1430   // Wait for the panels opened by the first extension to close.
   1431   signal.Wait();
   1432   signal1.Wait();
   1433 
   1434   // Verify that the panel that's left is the panel from the second extension.
   1435   EXPECT_EQ(panel_other, panel_manager->panels()[0]);
   1436   panel_other->Close();
   1437 }
   1438 
   1439 IN_PROC_BROWSER_TEST_F(PanelBrowserTest, OnBeforeUnloadOnClose) {
   1440   PanelManager* panel_manager = PanelManager::GetInstance();
   1441   EXPECT_EQ(0, panel_manager->num_panels()); // No panels initially.
   1442 
   1443   const base::string16 title_first_close = UTF8ToUTF16("TitleFirstClose");
   1444   const base::string16 title_second_close = UTF8ToUTF16("TitleSecondClose");
   1445 
   1446   // Create a test panel with web contents loaded.
   1447   CreatePanelParams params("PanelTest1", gfx::Rect(0, 0, 300, 300),
   1448                            SHOW_AS_ACTIVE);
   1449   params.url = ui_test_utils::GetTestUrl(
   1450       base::FilePath(kTestDir),
   1451       base::FilePath(FILE_PATH_LITERAL("onbeforeunload.html")));
   1452   Panel* panel = CreatePanelWithParams(params);
   1453   EXPECT_EQ(1, panel_manager->num_panels());
   1454 
   1455   // Close panel and verify it closes despite having a onbeforeunload handler.
   1456   CloseWindowAndWait(panel);
   1457   EXPECT_EQ(0, panel_manager->num_panels());
   1458 }
   1459 
   1460 // http://crbug.com/175760; several panel tests failing regularly on mac.
   1461 #if defined(OS_MACOSX)
   1462 #define MAYBE_SizeClamping DISABLED_SizeClamping
   1463 #else
   1464 #define MAYBE_SizeClamping SizeClamping
   1465 #endif
   1466 IN_PROC_BROWSER_TEST_F(PanelBrowserTest, MAYBE_SizeClamping) {
   1467   // Using '0' sizes is equivalent of not providing sizes in API and causes
   1468   // minimum sizes to be applied to facilitate auto-sizing.
   1469   CreatePanelParams params("Panel", gfx::Rect(), SHOW_AS_ACTIVE);
   1470   Panel* panel = CreatePanelWithParams(params);
   1471   EXPECT_EQ(panel->min_size().width(), panel->GetBounds().width());
   1472   EXPECT_EQ(panel->min_size().height(), panel->GetBounds().height());
   1473   int reasonable_width = panel->min_size().width() + 10;
   1474   int reasonable_height = panel->min_size().height() + 20;
   1475 
   1476   panel->Close();
   1477 
   1478   // Using reasonable actual sizes should avoid clamping.
   1479   CreatePanelParams params1("Panel1",
   1480                             gfx::Rect(0, 0,
   1481                                       reasonable_width, reasonable_height),
   1482                             SHOW_AS_ACTIVE);
   1483   panel = CreatePanelWithParams(params1);
   1484   EXPECT_EQ(reasonable_width, panel->GetBounds().width());
   1485   EXPECT_EQ(reasonable_height, panel->GetBounds().height());
   1486   panel->Close();
   1487 
   1488   // Using just one size should auto-compute some reasonable other size.
   1489   int given_height = 200;
   1490   CreatePanelParams params2("Panel2", gfx::Rect(0, 0, 0, given_height),
   1491                             SHOW_AS_ACTIVE);
   1492   panel = CreatePanelWithParams(params2);
   1493   EXPECT_GT(panel->GetBounds().width(), 0);
   1494   EXPECT_EQ(given_height, panel->GetBounds().height());
   1495   panel->Close();
   1496 }
   1497 
   1498 // http://crbug.com/175760; several panel tests failing regularly on mac.
   1499 // http://crbug.com/179890; TightAutosizeAroundSingleLine broken on Windows by
   1500 IN_PROC_BROWSER_TEST_F(PanelBrowserTest,
   1501                        DISABLED_TightAutosizeAroundSingleLine) {
   1502   PanelManager::GetInstance()->enable_auto_sizing(true);
   1503   // Using 0 sizes triggers auto-sizing.
   1504   CreatePanelParams params("Panel", gfx::Rect(), SHOW_AS_ACTIVE);
   1505   params.url = GURL("data:text/html;charset=utf-8,<!doctype html><body>");
   1506   Panel* panel = CreatePanelWithParams(params);
   1507 
   1508   // Ensure panel has auto resized to original web content size.
   1509   WaitForStableInitialSize initial_resize(panel);
   1510   initial_resize.Wait();
   1511 
   1512   int initial_width = panel->GetBounds().width();
   1513   int initial_height = panel->GetBounds().height();
   1514 
   1515   // Inject some HTML content into the panel.
   1516   WaitForAutoResizeWider enlarge(panel);
   1517   EXPECT_TRUE(content::ExecuteScript(
   1518       panel->GetWebContents(),
   1519       "document.body.innerHTML ="
   1520       "    '<nobr>line of text and a <button>Button</button>';"));
   1521   enlarge.Wait();
   1522 
   1523   // The panel should have become larger in both dimensions (the minimums
   1524   // has to be set to be smaller then a simple 1-line content, so the autosize
   1525   // can work correctly.
   1526   EXPECT_GT(panel->GetBounds().width(), initial_width);
   1527   EXPECT_GT(panel->GetBounds().height(), initial_height);
   1528 
   1529   panel->Close();
   1530 }
   1531 
   1532 // http://crbug.com/175760; several panel tests failing regularly on mac.
   1533 #if defined(OS_MACOSX)
   1534 #define MAYBE_DefaultMaxSizeOnDisplaySettingsChange \
   1535         DISABLED_DefaultMaxSizeOnDisplaySettingsChange
   1536 #else
   1537 #define MAYBE_DefaultMaxSizeOnDisplaySettingsChange \
   1538         DefaultMaxSizeOnDisplaySettingsChange
   1539 #endif
   1540 IN_PROC_BROWSER_TEST_F(PanelBrowserTest,
   1541                        MAYBE_DefaultMaxSizeOnDisplaySettingsChange) {
   1542   Panel* panel = CreatePanelWithBounds("1", gfx::Rect(0, 0, 240, 220));
   1543 
   1544   gfx::Size old_max_size = panel->max_size();
   1545   gfx::Size old_full_size = panel->full_size();
   1546 
   1547   // Shrink the work area. Expect max size and full size become smaller.
   1548   gfx::Rect smaller_work_area(0, 0, 500, 300);
   1549   mock_display_settings_provider()->SetPrimaryDisplay(
   1550       smaller_work_area, smaller_work_area);
   1551   EXPECT_GT(old_max_size.width(), panel->max_size().width());
   1552   EXPECT_GT(old_max_size.height(), panel->max_size().height());
   1553   EXPECT_GT(smaller_work_area.width(), panel->max_size().width());
   1554   EXPECT_GT(smaller_work_area.height(), panel->max_size().height());
   1555   EXPECT_GT(old_full_size.width(), panel->full_size().width());
   1556   EXPECT_GT(old_full_size.height(), panel->full_size().height());
   1557   EXPECT_GE(panel->max_size().width(), panel->full_size().width());
   1558   EXPECT_GE(panel->max_size().height(), panel->full_size().height());
   1559 
   1560   panel->Close();
   1561 }
   1562 
   1563 // http://crbug.com/175760; several panel tests failing regularly on mac.
   1564 #if defined(OS_MACOSX)
   1565 #define MAYBE_CustomMaxSizeOnDisplaySettingsChange \
   1566         DISABLED_CustomMaxSizeOnDisplaySettingsChange
   1567 #else
   1568 #define MAYBE_CustomMaxSizeOnDisplaySettingsChange \
   1569         CustomMaxSizeOnDisplaySettingsChange
   1570 #endif
   1571 IN_PROC_BROWSER_TEST_F(PanelBrowserTest,
   1572                        MAYBE_CustomMaxSizeOnDisplaySettingsChange) {
   1573   PanelManager* panel_manager = PanelManager::GetInstance();
   1574   Panel* panel = CreatePanelWithBounds("1", gfx::Rect(0, 0, 240, 220));
   1575 
   1576   // Trigger custom max size by user resizing.
   1577   gfx::Size bigger_size = gfx::Size(550, 400);
   1578   gfx::Point mouse_location = panel->GetBounds().origin();
   1579   panel_manager->StartResizingByMouse(panel,
   1580                                       mouse_location,
   1581                                       panel::RESIZE_TOP_LEFT);
   1582   mouse_location.Offset(panel->GetBounds().width() - bigger_size.width(),
   1583                         panel->GetBounds().height() - bigger_size.height());
   1584   panel_manager->ResizeByMouse(mouse_location);
   1585   panel_manager->EndResizingByMouse(false);
   1586 
   1587   gfx::Size old_max_size = panel->max_size();
   1588   EXPECT_EQ(bigger_size, old_max_size);
   1589   gfx::Size old_full_size = panel->full_size();
   1590   EXPECT_EQ(bigger_size, old_full_size);
   1591 
   1592   // Shrink the work area. Expect max size and full size become smaller.
   1593   gfx::Rect smaller_work_area(0, 0, 500, 300);
   1594   mock_display_settings_provider()->SetPrimaryDisplay(
   1595       smaller_work_area, smaller_work_area);
   1596   EXPECT_GT(old_max_size.width(), panel->max_size().width());
   1597   EXPECT_GT(old_max_size.height(), panel->max_size().height());
   1598   EXPECT_GE(smaller_work_area.width(), panel->max_size().width());
   1599   EXPECT_EQ(smaller_work_area.height(), panel->max_size().height());
   1600   EXPECT_GT(old_full_size.width(), panel->full_size().width());
   1601   EXPECT_GT(old_full_size.height(), panel->full_size().height());
   1602   EXPECT_GE(panel->max_size().width(), panel->full_size().width());
   1603   EXPECT_GE(panel->max_size().height(), panel->full_size().height());
   1604   EXPECT_EQ(smaller_work_area.height(), panel->full_size().height());
   1605 
   1606   panel->Close();
   1607 }
   1608 
   1609 IN_PROC_BROWSER_TEST_F(PanelBrowserTest, DevTools) {
   1610   // Create a test panel with web contents loaded.
   1611   CreatePanelParams params("1", gfx::Rect(0, 0, 200, 220), SHOW_AS_ACTIVE);
   1612   GURL url(ui_test_utils::GetTestUrl(
   1613       base::FilePath(kTestDir),
   1614       base::FilePath(FILE_PATH_LITERAL("update-preferred-size.html"))));
   1615   params.url = url;
   1616   Panel* panel = CreatePanelWithParams(params);
   1617 
   1618   // Open devtools.
   1619   size_t num_browsers = 1;
   1620   EXPECT_EQ(num_browsers, chrome::GetBrowserCount(
   1621                               browser()->profile(),
   1622                               browser()->host_desktop_type()));
   1623   content::WindowedNotificationObserver signal(
   1624       chrome::NOTIFICATION_BROWSER_WINDOW_READY,
   1625       content::NotificationService::AllSources());
   1626   EXPECT_TRUE(panel->ExecuteCommandIfEnabled(IDC_DEV_TOOLS));
   1627   signal.Wait();
   1628 
   1629   // Check that the new browser window that opened is dev tools window.
   1630   ++num_browsers;
   1631   EXPECT_EQ(num_browsers, chrome::GetBrowserCount(
   1632                               browser()->profile(),
   1633                               browser()->host_desktop_type()));
   1634   for (chrome::BrowserIterator iter; !iter.done(); iter.Next()) {
   1635     if (*iter == browser())
   1636       continue;
   1637     ASSERT_TRUE((*iter)->is_devtools());
   1638   }
   1639 
   1640   panel->Close();
   1641 }
   1642 
   1643 IN_PROC_BROWSER_TEST_F(PanelBrowserTest, DevToolsConsole) {
   1644   // Create a test panel with web contents loaded.
   1645   CreatePanelParams params("1", gfx::Rect(0, 0, 200, 220), SHOW_AS_ACTIVE);
   1646   GURL url(ui_test_utils::GetTestUrl(
   1647       base::FilePath(kTestDir),
   1648       base::FilePath(FILE_PATH_LITERAL("update-preferred-size.html"))));
   1649   params.url = url;
   1650   Panel* panel = CreatePanelWithParams(params);
   1651 
   1652   // Open devtools console.
   1653   size_t num_browsers = 1;
   1654   EXPECT_EQ(num_browsers, chrome::GetBrowserCount(
   1655                               browser()->profile(),
   1656                               browser()->host_desktop_type()));
   1657   content::WindowedNotificationObserver signal(
   1658       chrome::NOTIFICATION_BROWSER_WINDOW_READY,
   1659       content::NotificationService::AllSources());
   1660   EXPECT_TRUE(panel->ExecuteCommandIfEnabled(IDC_DEV_TOOLS_CONSOLE));
   1661   signal.Wait();
   1662 
   1663   // Check that the new browser window that opened is dev tools window.
   1664   ++num_browsers;
   1665   EXPECT_EQ(num_browsers, chrome::GetBrowserCount(
   1666                               browser()->profile(),
   1667                               browser()->host_desktop_type()));
   1668   for (chrome::BrowserIterator iter; !iter.done(); iter.Next()) {
   1669     if (*iter == browser())
   1670       continue;
   1671     ASSERT_TRUE((*iter)->is_devtools());
   1672   }
   1673 
   1674   panel->Close();
   1675 }
   1676 
   1677 #if defined(OS_WIN)
   1678 #define MAYBE_Accelerator Accelerator
   1679 #else
   1680 #define MAYBE_Accelerator DISABLED_Accelerator
   1681 #endif
   1682 IN_PROC_BROWSER_TEST_F(PanelBrowserTest, MAYBE_Accelerator) {
   1683   PanelManager* panel_manager = PanelManager::GetInstance();
   1684 
   1685   // Create a test panel with web contents loaded.
   1686   CreatePanelParams params("1", gfx::Rect(), SHOW_AS_ACTIVE);
   1687   GURL url(ui_test_utils::GetTestUrl(
   1688       base::FilePath(kTestDir),
   1689       base::FilePath(FILE_PATH_LITERAL("update-preferred-size.html"))));
   1690   params.url = url;
   1691   Panel* panel = CreatePanelWithParams(params);
   1692   EXPECT_EQ(1, panel_manager->num_panels());
   1693 
   1694   // Close the panel by acclerator.
   1695   content::WindowedNotificationObserver signal(
   1696       chrome::NOTIFICATION_PANEL_CLOSED,
   1697       content::Source<Panel>(panel));
   1698 #if defined(USE_AURA)
   1699   double now = ui::EventTimeForNow().InSecondsF();
   1700   content::NativeWebKeyboardEvent key_event(
   1701       ui::ET_KEY_PRESSED,
   1702       false,
   1703       ui::VKEY_W,
   1704       ui::EF_CONTROL_DOWN,
   1705       now);
   1706 #elif defined(OS_WIN)
   1707   ::MSG key_msg = { NULL, WM_KEYDOWN, ui::VKEY_W, 0 };
   1708   content::NativeWebKeyboardEvent key_event(key_msg);
   1709   key_event.modifiers = content::NativeWebKeyboardEvent::ControlKey;
   1710 #else
   1711   content::NativeWebKeyboardEvent key_event;
   1712 #endif
   1713   panel->HandleKeyboardEvent(key_event);
   1714   signal.Wait();
   1715   EXPECT_EQ(0, panel_manager->num_panels());
   1716 }
   1717 
   1718 IN_PROC_BROWSER_TEST_F(PanelBrowserTest,
   1719                        HideDockedPanelCreatedBeforeFullScreenMode) {
   1720   // Create a docked panel.
   1721   Panel* panel = CreatePanel("PanelTest");
   1722   scoped_ptr<NativePanelTesting> panel_testing(CreateNativePanelTesting(panel));
   1723 
   1724   // Panel should be visible at first.
   1725   EXPECT_TRUE(panel_testing->IsWindowVisible());
   1726 
   1727   // Panel should become hidden when entering full-screen mode.
   1728   // Note that this is not needed on Linux because the full-screen window will
   1729   // be always placed above any other windows.
   1730   mock_display_settings_provider()->EnableFullScreenMode(true);
   1731 #if defined(OS_LINUX)
   1732   EXPECT_TRUE(panel_testing->IsWindowVisible());
   1733 #else
   1734   EXPECT_FALSE(panel_testing->IsWindowVisible());
   1735 #endif
   1736 
   1737   // Panel should become visible when leaving full-screen mode.
   1738   mock_display_settings_provider()->EnableFullScreenMode(false);
   1739   EXPECT_TRUE(panel_testing->IsWindowVisible());
   1740 
   1741   PanelManager::GetInstance()->CloseAll();
   1742 }
   1743 
   1744 IN_PROC_BROWSER_TEST_F(PanelBrowserTest,
   1745                        HideDockedPanelCreatedOnFullScreenMode) {
   1746   // Enable full-screen mode first.
   1747   mock_display_settings_provider()->EnableFullScreenMode(true);
   1748 
   1749   // Create a docked panel without waiting for it to be shown since it is not
   1750   // supposed to be shown on full-screen mode.
   1751   CreatePanelParams params("1", gfx::Rect(0, 0, 250, 200), SHOW_AS_ACTIVE);
   1752   params.wait_for_fully_created = false;
   1753   Panel* panel = CreatePanelWithParams(params);
   1754   scoped_ptr<NativePanelTesting> panel_testing(
   1755       CreateNativePanelTesting(panel));
   1756 
   1757   // Panel should not be shown on full-screen mode.
   1758   EXPECT_FALSE(panel_testing->IsWindowVisible());
   1759 
   1760   // Panel should become visible when leaving full-screen mode.
   1761   mock_display_settings_provider()->EnableFullScreenMode(false);
   1762   EXPECT_TRUE(panel_testing->IsWindowVisible());
   1763 
   1764   PanelManager::GetInstance()->CloseAll();
   1765 }
   1766 
   1767 class PanelExtensionApiTest : public ExtensionApiTest {
   1768  protected:
   1769   virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
   1770     ExtensionApiTest::SetUpCommandLine(command_line);
   1771     command_line->AppendSwitch(switches::kEnablePanels);
   1772   }
   1773 };
   1774 
   1775 #if defined(OS_LINUX) || (!defined(OS_WIN) && defined(USE_AURA)) || \
   1776     defined(OS_MACOSX)
   1777 // Focus test fails if there is no window manager on Linux.
   1778 // Aura panels have different behavior that do not apply to this test.
   1779 #define MAYBE_FocusChangeEventOnMinimize DISABLED_FocusChangeEventOnMinimize
   1780 #else
   1781 #define MAYBE_FocusChangeEventOnMinimize FocusChangeEventOnMinimize
   1782 #endif
   1783 IN_PROC_BROWSER_TEST_F(PanelExtensionApiTest,
   1784                        MAYBE_FocusChangeEventOnMinimize) {
   1785   // This is needed so the subsequently created panels can be activated.
   1786   // On a Mac, it transforms background-only test process into foreground one.
   1787   ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
   1788   ASSERT_TRUE(RunExtensionTest("panels/focus_change_on_minimize")) << message_;
   1789 }
   1790