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