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