panel_browsertest.cc revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
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/utf_string_conversions.h"
8#include "chrome/app/chrome_command_ids.h"
9#include "chrome/browser/devtools/devtools_window.h"
10#include "chrome/browser/extensions/extension_apitest.h"
11#include "chrome/browser/net/url_request_mock_util.h"
12#include "chrome/browser/prefs/browser_prefs.h"
13#include "chrome/browser/profiles/profile.h"
14#include "chrome/browser/ui/app_modal_dialogs/app_modal_dialog.h"
15#include "chrome/browser/ui/app_modal_dialogs/native_app_modal_dialog.h"
16#include "chrome/browser/ui/browser.h"
17#include "chrome/browser/ui/browser_commands.h"
18#include "chrome/browser/ui/browser_finder.h"
19#include "chrome/browser/ui/browser_iterator.h"
20#include "chrome/browser/ui/browser_window.h"
21#include "chrome/browser/ui/panels/base_panel_browser_test.h"
22#include "chrome/browser/ui/panels/docked_panel_collection.h"
23#include "chrome/browser/ui/panels/native_panel.h"
24#include "chrome/browser/ui/panels/panel.h"
25#include "chrome/browser/ui/panels/panel_manager.h"
26#include "chrome/browser/ui/panels/test_panel_active_state_observer.h"
27#include "chrome/browser/web_applications/web_app.h"
28#include "chrome/common/chrome_notification_types.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
47using content::WebContents;
48
49class 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
257IN_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  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
322IN_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
343IN_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
355class 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
371class 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
389class 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
408IN_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
473IN_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#if defined(OS_LINUX) || defined(OS_WIN)
507// There is no animations on Linux, by design (http://crbug.com/144074).
508// And there are intermittent/flaky failures on windows try bots
509// (http://crbug.com/179069).
510#define MAYBE_AnimateBounds DISABLED_AnimateBounds
511#else
512#define MAYBE_AnimateBounds AnimateBounds
513#endif
514IN_PROC_BROWSER_TEST_F(PanelBrowserTest, MAYBE_AnimateBounds) {
515  Panel* panel = CreatePanelWithBounds("PanelTest", gfx::Rect(0, 0, 100, 100));
516  scoped_ptr<NativePanelTesting> panel_testing(
517      CreateNativePanelTesting(panel));
518
519  // Validates that no animation should be triggered when the panel is being
520  // dragged.
521  gfx::Point mouse_location(panel->GetBounds().origin());
522  panel_testing->PressLeftMouseButtonTitlebar(mouse_location);
523  panel_testing->DragTitlebar(mouse_location + gfx::Vector2d(-100, 5));
524  EXPECT_FALSE(panel_testing->IsAnimatingBounds());
525  panel_testing->FinishDragTitlebar();
526
527  // Set bounds with animation.
528  gfx::Rect bounds = gfx::Rect(10, 20, 150, 160);
529  panel->SetPanelBounds(bounds);
530  EXPECT_TRUE(panel_testing->IsAnimatingBounds());
531  WaitForBoundsAnimationFinished(panel);
532  EXPECT_FALSE(panel_testing->IsAnimatingBounds());
533  EXPECT_EQ(bounds, panel->GetBounds());
534
535  // Set bounds without animation.
536  bounds = gfx::Rect(30, 40, 200, 220);
537  panel->SetPanelBoundsInstantly(bounds);
538  EXPECT_FALSE(panel_testing->IsAnimatingBounds());
539  EXPECT_EQ(bounds, panel->GetBounds());
540
541  panel->Close();
542}
543
544IN_PROC_BROWSER_TEST_F(PanelBrowserTest, RestoredBounds) {
545  Panel* panel = CreatePanelWithBounds("PanelTest", gfx::Rect(0, 0, 100, 100));
546  EXPECT_EQ(Panel::EXPANDED, panel->expansion_state());
547  EXPECT_EQ(panel->GetBounds(), panel->GetRestoredBounds());
548
549  panel->SetExpansionState(Panel::MINIMIZED);
550  EXPECT_EQ(Panel::MINIMIZED, panel->expansion_state());
551  gfx::Rect bounds = panel->GetBounds();
552  gfx::Rect restored = panel->GetRestoredBounds();
553  EXPECT_EQ(bounds.x(), restored.x());
554  EXPECT_GT(bounds.y(), restored.y());
555  EXPECT_EQ(bounds.width(), restored.width());
556  EXPECT_LT(bounds.height(), restored.height());
557
558  panel->SetExpansionState(Panel::TITLE_ONLY);
559  EXPECT_EQ(Panel::TITLE_ONLY, panel->expansion_state());
560  bounds = panel->GetBounds();
561  restored = panel->GetRestoredBounds();
562  EXPECT_EQ(bounds.x(), restored.x());
563  EXPECT_GT(bounds.y(), restored.y());
564  EXPECT_EQ(bounds.width(), restored.width());
565  EXPECT_LT(bounds.height(), restored.height());
566
567  panel->SetExpansionState(Panel::MINIMIZED);
568  EXPECT_EQ(Panel::MINIMIZED, panel->expansion_state());
569  bounds = panel->GetBounds();
570  restored = panel->GetRestoredBounds();
571  EXPECT_EQ(bounds.x(), restored.x());
572  EXPECT_GT(bounds.y(), restored.y());
573  EXPECT_EQ(bounds.width(), restored.width());
574  EXPECT_LT(bounds.height(), restored.height());
575
576  panel->SetExpansionState(Panel::EXPANDED);
577  EXPECT_EQ(panel->GetBounds(), panel->GetRestoredBounds());
578
579  // Verify that changing the panel bounds does not affect the restored height.
580  int saved_restored_height = restored.height();
581  panel->SetExpansionState(Panel::MINIMIZED);
582  bounds = gfx::Rect(10, 20, 300, 400);
583  panel->SetPanelBounds(bounds);
584  EXPECT_EQ(saved_restored_height, panel->GetRestoredBounds().height());
585
586  panel->SetExpansionState(Panel::TITLE_ONLY);
587  bounds = gfx::Rect(20, 30, 100, 200);
588  panel->SetPanelBounds(bounds);
589  EXPECT_EQ(saved_restored_height, panel->GetRestoredBounds().height());
590
591  panel->SetExpansionState(Panel::EXPANDED);
592  bounds = gfx::Rect(40, 60, 300, 400);
593  panel->SetPanelBounds(bounds);
594  EXPECT_EQ(saved_restored_height, panel->GetRestoredBounds().height());
595  panel->set_full_size(bounds.size());
596  EXPECT_NE(saved_restored_height, panel->GetRestoredBounds().height());
597
598  panel->Close();
599}
600
601IN_PROC_BROWSER_TEST_F(PanelBrowserTest, MinimizeRestore) {
602  // Test with one panel.
603  CreatePanelWithBounds("PanelTest1", gfx::Rect(0, 0, 100, 100));
604  TestMinimizeRestore();
605
606  PanelManager::GetInstance()->CloseAll();
607}
608
609IN_PROC_BROWSER_TEST_F(PanelBrowserTest, MinimizeRestoreTwoPanels) {
610  // Test with two panels.
611  CreatePanelWithBounds("PanelTest1", gfx::Rect(0, 0, 100, 100));
612  CreatePanelWithBounds("PanelTest2", gfx::Rect(0, 0, 110, 110));
613  TestMinimizeRestore();
614
615  PanelManager::GetInstance()->CloseAll();
616}
617
618IN_PROC_BROWSER_TEST_F(PanelBrowserTest, MinimizeRestoreThreePanels) {
619  // Test with three panels.
620  CreatePanelWithBounds("PanelTest1", gfx::Rect(0, 0, 100, 100));
621  CreatePanelWithBounds("PanelTest2", gfx::Rect(0, 0, 110, 110));
622  CreatePanelWithBounds("PanelTest3", gfx::Rect(0, 0, 120, 120));
623  TestMinimizeRestore();
624
625  PanelManager::GetInstance()->CloseAll();
626}
627
628IN_PROC_BROWSER_TEST_F(PanelBrowserTest, MinimizeRestoreButtonClick) {
629  // Test with three panels.
630  Panel* panel1 = CreatePanel("PanelTest1");
631  Panel* panel2 = CreatePanel("PanelTest2");
632  Panel* panel3 = CreatePanel("PanelTest3");
633  EXPECT_FALSE(panel1->IsMinimized());
634  EXPECT_FALSE(panel2->IsMinimized());
635  EXPECT_FALSE(panel3->IsMinimized());
636
637  // Click restore button on an expanded panel. Expect no change.
638  panel1->OnRestoreButtonClicked(panel::NO_MODIFIER);
639  EXPECT_FALSE(panel1->IsMinimized());
640  EXPECT_FALSE(panel2->IsMinimized());
641  EXPECT_FALSE(panel3->IsMinimized());
642
643  // Click minimize button on an expanded panel. Only that panel will minimize.
644  panel1->OnMinimizeButtonClicked(panel::NO_MODIFIER);
645  EXPECT_TRUE(panel1->IsMinimized());
646  EXPECT_FALSE(panel2->IsMinimized());
647  EXPECT_FALSE(panel3->IsMinimized());
648
649  // Click minimize button on a minimized panel. Expect no change.
650  panel1->OnMinimizeButtonClicked(panel::NO_MODIFIER);
651  EXPECT_TRUE(panel1->IsMinimized());
652  EXPECT_FALSE(panel2->IsMinimized());
653  EXPECT_FALSE(panel3->IsMinimized());
654
655  // Minimize all panels by clicking minimize button on an expanded panel
656  // with the apply-all modifier.
657  panel2->OnMinimizeButtonClicked(panel::APPLY_TO_ALL);
658  EXPECT_TRUE(panel1->IsMinimized());
659  EXPECT_TRUE(panel2->IsMinimized());
660  EXPECT_TRUE(panel3->IsMinimized());
661
662  // Click restore button on a minimized panel. Only that panel will restore.
663  panel2->OnRestoreButtonClicked(panel::NO_MODIFIER);
664  EXPECT_TRUE(panel1->IsMinimized());
665  EXPECT_FALSE(panel2->IsMinimized());
666  EXPECT_TRUE(panel3->IsMinimized());
667
668  // Restore all panels by clicking restore button on a minimized panel.
669  panel3->OnRestoreButtonClicked(panel::APPLY_TO_ALL);
670  EXPECT_FALSE(panel1->IsMinimized());
671  EXPECT_FALSE(panel2->IsMinimized());
672  EXPECT_FALSE(panel3->IsMinimized());
673}
674
675IN_PROC_BROWSER_TEST_F(PanelBrowserTest, RestoreAllWithTitlebarClick) {
676  // Test with three panels.
677  Panel* panel1 = CreatePanel("PanelTest1");
678  Panel* panel2 = CreatePanel("PanelTest2");
679  Panel* panel3 = CreatePanel("PanelTest3");
680  EXPECT_FALSE(panel1->IsMinimized());
681  EXPECT_FALSE(panel2->IsMinimized());
682  EXPECT_FALSE(panel3->IsMinimized());
683
684  scoped_ptr<NativePanelTesting> test_panel1(
685      CreateNativePanelTesting(panel1));
686  scoped_ptr<NativePanelTesting> test_panel2(
687      CreateNativePanelTesting(panel2));
688  scoped_ptr<NativePanelTesting> test_panel3(
689      CreateNativePanelTesting(panel3));
690
691  // Click on an expanded panel's titlebar using the apply-all modifier.
692  // Verify expansion state is unchanged.
693  test_panel2->PressLeftMouseButtonTitlebar(panel2->GetBounds().origin(),
694                                            panel::APPLY_TO_ALL);
695  test_panel2->ReleaseMouseButtonTitlebar(panel::APPLY_TO_ALL);
696  EXPECT_FALSE(panel1->IsMinimized());
697  EXPECT_FALSE(panel2->IsMinimized());
698  EXPECT_FALSE(panel3->IsMinimized());
699
700  // Click on a minimized panel's titlebar using the apply-all modifier.
701  panel1->Minimize();
702  panel2->Minimize();
703  panel3->Minimize();
704  EXPECT_TRUE(panel1->IsMinimized());
705  EXPECT_TRUE(panel2->IsMinimized());
706  EXPECT_TRUE(panel3->IsMinimized());
707
708  // Nothing changes until mouse is released.
709  test_panel1->PressLeftMouseButtonTitlebar(panel1->GetBounds().origin(),
710                                            panel::APPLY_TO_ALL);
711  EXPECT_TRUE(panel1->IsMinimized());
712  EXPECT_TRUE(panel2->IsMinimized());
713  EXPECT_TRUE(panel3->IsMinimized());
714  // Verify all panels restored when mouse is released.
715  test_panel1->ReleaseMouseButtonTitlebar(panel::APPLY_TO_ALL);
716  EXPECT_FALSE(panel1->IsMinimized());
717  EXPECT_FALSE(panel2->IsMinimized());
718  EXPECT_FALSE(panel3->IsMinimized());
719
720  // Minimize a single panel. Then click on expanded panel with apply-all
721  // modifier. Verify nothing changes.
722  panel1->Minimize();
723  EXPECT_TRUE(panel1->IsMinimized());
724  EXPECT_FALSE(panel2->IsMinimized());
725  EXPECT_FALSE(panel3->IsMinimized());
726
727  test_panel2->PressLeftMouseButtonTitlebar(panel2->GetBounds().origin(),
728                                            panel::APPLY_TO_ALL);
729  test_panel2->ReleaseMouseButtonTitlebar(panel::APPLY_TO_ALL);
730  EXPECT_TRUE(panel1->IsMinimized());
731  EXPECT_FALSE(panel2->IsMinimized());
732  EXPECT_FALSE(panel3->IsMinimized());
733
734  // Minimize another panel. Then click on a minimized panel with apply-all
735  // modifier to restore all panels.
736  panel2->Minimize();
737  EXPECT_TRUE(panel1->IsMinimized());
738  EXPECT_TRUE(panel2->IsMinimized());
739  EXPECT_FALSE(panel3->IsMinimized());
740
741  test_panel2->PressLeftMouseButtonTitlebar(panel2->GetBounds().origin(),
742                                            panel::APPLY_TO_ALL);
743  test_panel2->ReleaseMouseButtonTitlebar(panel::APPLY_TO_ALL);
744  EXPECT_FALSE(panel1->IsMinimized());
745  EXPECT_FALSE(panel2->IsMinimized());
746  EXPECT_FALSE(panel3->IsMinimized());
747
748  // Click on the single minimized panel. Verify all are restored.
749  panel1->Minimize();
750  EXPECT_TRUE(panel1->IsMinimized());
751  EXPECT_FALSE(panel2->IsMinimized());
752  EXPECT_FALSE(panel3->IsMinimized());
753
754  test_panel1->PressLeftMouseButtonTitlebar(panel1->GetBounds().origin(),
755                                            panel::APPLY_TO_ALL);
756  test_panel1->ReleaseMouseButtonTitlebar(panel::APPLY_TO_ALL);
757  EXPECT_FALSE(panel1->IsMinimized());
758  EXPECT_FALSE(panel2->IsMinimized());
759  EXPECT_FALSE(panel3->IsMinimized());
760
761  // Click on the single expanded panel. Verify nothing changes.
762  panel1->Minimize();
763  panel3->Minimize();
764  EXPECT_TRUE(panel1->IsMinimized());
765  EXPECT_FALSE(panel2->IsMinimized());
766  EXPECT_TRUE(panel3->IsMinimized());
767
768  test_panel2->PressLeftMouseButtonTitlebar(panel2->GetBounds().origin(),
769                                            panel::APPLY_TO_ALL);
770  test_panel2->ReleaseMouseButtonTitlebar(panel::APPLY_TO_ALL);
771  EXPECT_TRUE(panel1->IsMinimized());
772  EXPECT_FALSE(panel2->IsMinimized());
773  EXPECT_TRUE(panel3->IsMinimized());
774
775  // Hover over a minimized panel and click on the titlebar while it is in
776  // title-only mode. Should restore all panels.
777  panel2->Minimize();
778  EXPECT_TRUE(panel1->IsMinimized());
779  EXPECT_TRUE(panel2->IsMinimized());
780  EXPECT_TRUE(panel3->IsMinimized());
781
782  MoveMouseAndWaitForExpansionStateChange(panel2, panel2->GetBounds().origin());
783  EXPECT_EQ(Panel::TITLE_ONLY, panel1->expansion_state());
784  EXPECT_EQ(Panel::TITLE_ONLY, panel2->expansion_state());
785  EXPECT_EQ(Panel::TITLE_ONLY, panel3->expansion_state());
786
787  test_panel3->PressLeftMouseButtonTitlebar(panel3->GetBounds().origin(),
788                                            panel::APPLY_TO_ALL);
789  test_panel3->ReleaseMouseButtonTitlebar(panel::APPLY_TO_ALL);
790  EXPECT_FALSE(panel1->IsMinimized());
791  EXPECT_FALSE(panel2->IsMinimized());
792  EXPECT_FALSE(panel3->IsMinimized());
793
794  // Draw attention to a minimized panel. Click on a minimized panel that is
795  // not drawing attention. Verify restore all applies without affecting
796  // draw attention.
797  panel1->Minimize();
798  panel2->Minimize();
799  panel3->Minimize();
800  EXPECT_TRUE(panel1->IsMinimized());
801  EXPECT_TRUE(panel2->IsMinimized());
802  EXPECT_TRUE(panel3->IsMinimized());
803
804  panel1->FlashFrame(true);
805  EXPECT_TRUE(panel1->IsDrawingAttention());
806
807  test_panel2->PressLeftMouseButtonTitlebar(panel2->GetBounds().origin(),
808                                            panel::APPLY_TO_ALL);
809  test_panel2->ReleaseMouseButtonTitlebar(panel::APPLY_TO_ALL);
810  EXPECT_FALSE(panel1->IsMinimized());
811  EXPECT_FALSE(panel2->IsMinimized());
812  EXPECT_FALSE(panel3->IsMinimized());
813  EXPECT_TRUE(panel1->IsDrawingAttention());
814
815  // Restore all panels by clicking on the minimized panel that is drawing
816  // attention. Verify restore all applies and clears draw attention.
817  panel1->Minimize();
818  panel2->Minimize();
819  panel3->Minimize();
820  EXPECT_TRUE(panel1->IsMinimized());
821  EXPECT_TRUE(panel2->IsMinimized());
822  EXPECT_TRUE(panel3->IsMinimized());
823
824  test_panel1->PressLeftMouseButtonTitlebar(panel1->GetBounds().origin(),
825                                            panel::APPLY_TO_ALL);
826  test_panel1->ReleaseMouseButtonTitlebar(panel::APPLY_TO_ALL);
827  EXPECT_FALSE(panel1->IsMinimized());
828  EXPECT_FALSE(panel2->IsMinimized());
829  EXPECT_FALSE(panel3->IsMinimized());
830  EXPECT_FALSE(panel1->IsDrawingAttention());
831
832  PanelManager::GetInstance()->CloseAll();
833}
834
835IN_PROC_BROWSER_TEST_F(PanelBrowserTest,
836                       MinimizeRestoreOnAutoHidingDesktopBar) {
837  PanelManager* panel_manager = PanelManager::GetInstance();
838  DockedPanelCollection* docked_collection = panel_manager->docked_collection();
839  int expected_bottom_on_expanded = docked_collection->work_area().bottom();
840  int expected_bottom_on_title_only = expected_bottom_on_expanded;
841  int expected_bottom_on_minimized = expected_bottom_on_expanded;
842
843  // Turn on auto-hiding.
844  static const int bottom_bar_thickness = 40;
845  mock_display_settings_provider()->EnableAutoHidingDesktopBar(
846      DisplaySettingsProvider::DESKTOP_BAR_ALIGNED_BOTTOM,
847      true,
848      bottom_bar_thickness);
849  expected_bottom_on_title_only -= bottom_bar_thickness;
850
851  Panel* panel = CreatePanel("1");
852  int initial_height = panel->GetBounds().height();
853
854  EXPECT_EQ(Panel::EXPANDED, panel->expansion_state());
855  EXPECT_EQ(expected_bottom_on_expanded, panel->GetBounds().bottom());
856
857  panel->Minimize();
858  WaitForBoundsAnimationFinished(panel);
859  EXPECT_EQ(Panel::MINIMIZED, panel->expansion_state());
860  EXPECT_EQ(panel::kMinimizedPanelHeight, panel->GetBounds().height());
861  EXPECT_EQ(expected_bottom_on_minimized, panel->GetBounds().bottom());
862
863  panel->SetExpansionState(Panel::TITLE_ONLY);
864  WaitForBoundsAnimationFinished(panel);
865  EXPECT_EQ(Panel::TITLE_ONLY, panel->expansion_state());
866  EXPECT_EQ(panel::kTitlebarHeight, panel->GetBounds().height());
867  EXPECT_EQ(expected_bottom_on_title_only, panel->GetBounds().bottom());
868
869  panel->Restore();
870  WaitForBoundsAnimationFinished(panel);
871  EXPECT_EQ(Panel::EXPANDED, panel->expansion_state());
872  EXPECT_EQ(initial_height, panel->GetBounds().height());
873  EXPECT_EQ(expected_bottom_on_expanded, panel->GetBounds().bottom());
874
875  panel->Close();
876}
877
878IN_PROC_BROWSER_TEST_F(PanelBrowserTest, ChangeAutoHideTaskBarThickness) {
879  PanelManager* manager = PanelManager::GetInstance();
880  DockedPanelCollection* docked_collection = manager->docked_collection();
881  int initial_starting_right_position =
882      docked_collection->StartingRightPosition();
883
884  int bottom_bar_thickness = 20;
885  int right_bar_thickness = 30;
886  mock_display_settings_provider()->EnableAutoHidingDesktopBar(
887      DisplaySettingsProvider::DESKTOP_BAR_ALIGNED_BOTTOM,
888      true,
889      bottom_bar_thickness);
890  mock_display_settings_provider()->EnableAutoHidingDesktopBar(
891      DisplaySettingsProvider::DESKTOP_BAR_ALIGNED_RIGHT,
892      true,
893      right_bar_thickness);
894  EXPECT_EQ(initial_starting_right_position,
895            docked_collection->StartingRightPosition());
896
897  Panel* panel = CreatePanel("PanelTest");
898  panel->SetExpansionState(Panel::TITLE_ONLY);
899  WaitForBoundsAnimationFinished(panel);
900
901  EXPECT_EQ(docked_collection->work_area().bottom() - bottom_bar_thickness,
902            panel->GetBounds().bottom());
903  EXPECT_EQ(docked_collection->StartingRightPosition(),
904            panel->GetBounds().right());
905
906  initial_starting_right_position = docked_collection->StartingRightPosition();
907  int bottom_bar_thickness_delta = 10;
908  bottom_bar_thickness += bottom_bar_thickness_delta;
909  int right_bar_thickness_delta = 15;
910  right_bar_thickness += right_bar_thickness_delta;
911  mock_display_settings_provider()->SetDesktopBarThickness(
912      DisplaySettingsProvider::DESKTOP_BAR_ALIGNED_BOTTOM,
913      bottom_bar_thickness);
914  mock_display_settings_provider()->SetDesktopBarThickness(
915      DisplaySettingsProvider::DESKTOP_BAR_ALIGNED_RIGHT,
916      right_bar_thickness);
917  MessageLoopForUI::current()->RunUntilIdle();
918  EXPECT_EQ(initial_starting_right_position,
919            docked_collection->StartingRightPosition());
920  EXPECT_EQ(docked_collection->work_area().bottom() - bottom_bar_thickness,
921            panel->GetBounds().bottom());
922  EXPECT_EQ(docked_collection->StartingRightPosition(),
923            panel->GetBounds().right());
924
925  initial_starting_right_position = docked_collection->StartingRightPosition();
926  bottom_bar_thickness_delta = 20;
927  bottom_bar_thickness -= bottom_bar_thickness_delta;
928  right_bar_thickness_delta = 10;
929  right_bar_thickness -= right_bar_thickness_delta;
930  mock_display_settings_provider()->SetDesktopBarThickness(
931      DisplaySettingsProvider::DESKTOP_BAR_ALIGNED_BOTTOM,
932      bottom_bar_thickness);
933  mock_display_settings_provider()->SetDesktopBarThickness(
934      DisplaySettingsProvider::DESKTOP_BAR_ALIGNED_RIGHT,
935      right_bar_thickness);
936  MessageLoopForUI::current()->RunUntilIdle();
937  EXPECT_EQ(docked_collection->StartingRightPosition(),
938            initial_starting_right_position);
939  EXPECT_EQ(docked_collection->work_area().bottom() - bottom_bar_thickness,
940            panel->GetBounds().bottom());
941  EXPECT_EQ(docked_collection->StartingRightPosition(),
942            panel->GetBounds().right());
943
944  panel->Close();
945}
946
947// http://crbug.com/143247
948#if !defined(OS_WIN)
949#define MAYBE_ActivatePanelOrTabbedWindow DISABLED_ActivatePanelOrTabbedWindow
950#else
951#define MAYBE_ActivatePanelOrTabbedWindow ActivatePanelOrTabbedWindow
952#endif
953IN_PROC_BROWSER_TEST_F(PanelBrowserTest, MAYBE_ActivatePanelOrTabbedWindow) {
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)
984#define MAYBE_ActivateDeactivateBasic ActivateDeactivateBasic
985#else
986#define MAYBE_ActivateDeactivateBasic DISABLED_ActivateDeactivateBasic
987#endif
988IN_PROC_BROWSER_TEST_F(PanelBrowserTest, MAYBE_ActivateDeactivateBasic) {
989  // Create an active panel.
990  Panel* panel = CreatePanel("PanelTest");
991  scoped_ptr<NativePanelTesting> native_panel_testing(
992      CreateNativePanelTesting(panel));
993
994  WaitForPanelActiveState(panel, SHOW_AS_ACTIVE);  // doublecheck active state
995  EXPECT_TRUE(native_panel_testing->VerifyActiveState(true));
996
997  // Deactivate the panel.
998  panel->Deactivate();
999  WaitForPanelActiveState(panel, SHOW_AS_INACTIVE);
1000  EXPECT_TRUE(native_panel_testing->VerifyActiveState(false));
1001
1002  // This test does not reactivate the panel because the panel might not be
1003  // reactivated programmatically once it is deactivated.
1004}
1005
1006// http://crbug.com/143247
1007#if !defined(OS_WIN)
1008#define MAYBE_ActivateDeactivateMultiple DISABLED_ActivateDeactivateMultiple
1009#else
1010#define MAYBE_ActivateDeactivateMultiple ActivateDeactivateMultiple
1011#endif
1012IN_PROC_BROWSER_TEST_F(PanelBrowserTest, MAYBE_ActivateDeactivateMultiple) {
1013  BrowserWindow* tabbed_window = browser()->window();
1014
1015  // Create 4 panels in the following screen layout:
1016  //    P3  P2  P1  P0
1017  const int kNumPanels = 4;
1018  for (int i = 0; i < kNumPanels; ++i)
1019    CreatePanelWithBounds(MakePanelName(i), gfx::Rect(0, 0, 100, 100));
1020  const std::vector<Panel*>& panels = PanelManager::GetInstance()->panels();
1021
1022  std::vector<bool> expected_active_states;
1023  std::vector<bool> last_active_states;
1024
1025  // The last created panel, P3, should be active.
1026  expected_active_states = ProduceExpectedActiveStates(3);
1027  EXPECT_EQ(expected_active_states, GetAllPanelActiveStates());
1028  EXPECT_FALSE(tabbed_window->IsActive());
1029
1030  // Activating P1 should cause P3 to lose focus.
1031  panels[1]->Activate();
1032  last_active_states = expected_active_states;
1033  expected_active_states = ProduceExpectedActiveStates(1);
1034  WaitForPanelActiveStates(last_active_states, expected_active_states);
1035  EXPECT_EQ(expected_active_states, GetAllPanelActiveStates());
1036
1037  // Minimizing inactive panel P2 should not affect other panels' active states.
1038  panels[2]->SetExpansionState(Panel::MINIMIZED);
1039  EXPECT_EQ(expected_active_states, GetAllPanelActiveStates());
1040  EXPECT_FALSE(tabbed_window->IsActive());
1041}
1042
1043// http://crbug.com/143247
1044#if !defined(OS_WIN)
1045#define MAYBE_DrawAttentionBasic DISABLED_DrawAttentionBasic
1046#else
1047#define MAYBE_DrawAttentionBasic DrawAttentionBasic
1048#endif
1049IN_PROC_BROWSER_TEST_F(PanelBrowserTest, MAYBE_DrawAttentionBasic) {
1050  CreatePanelParams params("Initially Inactive", gfx::Rect(), SHOW_AS_INACTIVE);
1051  Panel* panel = CreatePanelWithParams(params);
1052  scoped_ptr<NativePanelTesting> native_panel_testing(
1053      CreateNativePanelTesting(panel));
1054
1055  // Test that the attention is drawn when the expanded panel is not in focus.
1056  EXPECT_EQ(Panel::EXPANDED, panel->expansion_state());
1057  EXPECT_FALSE(panel->IsActive());
1058  EXPECT_FALSE(panel->IsDrawingAttention());
1059  panel->FlashFrame(true);
1060  EXPECT_TRUE(panel->IsDrawingAttention());
1061  EXPECT_TRUE(native_panel_testing->VerifyDrawingAttention());
1062
1063  // Stop drawing attention.
1064  panel->FlashFrame(false);
1065  EXPECT_FALSE(panel->IsDrawingAttention());
1066  EXPECT_FALSE(native_panel_testing->VerifyDrawingAttention());
1067
1068  // Draw attention, then minimize. Titlebar should remain visible.
1069  panel->FlashFrame(true);
1070  EXPECT_TRUE(panel->IsDrawingAttention());
1071
1072  panel->Minimize();
1073  EXPECT_TRUE(panel->IsDrawingAttention());
1074  EXPECT_EQ(Panel::TITLE_ONLY, panel->expansion_state());
1075
1076  // Stop drawing attention. Titlebar should no longer be visible.
1077  panel->FlashFrame(false);
1078  EXPECT_FALSE(panel->IsDrawingAttention());
1079  EXPECT_EQ(Panel::MINIMIZED, panel->expansion_state());
1080
1081  panel->Close();
1082}
1083
1084// http://crbug.com/143247
1085#if !defined(OS_WIN)
1086#define MAYBE_DrawAttentionWhileMinimized DISABLED_DrawAttentionWhileMinimized
1087#else
1088#define MAYBE_DrawAttentionWhileMinimized DrawAttentionWhileMinimized
1089#endif
1090IN_PROC_BROWSER_TEST_F(PanelBrowserTest, MAYBE_DrawAttentionWhileMinimized) {
1091  // Create 3 panels so we end up with an inactive panel that can
1092  // be made to draw attention.
1093  Panel* panel = CreatePanel("test panel1");
1094  Panel* panel2 = CreatePanel("test panel2");
1095  Panel* panel3 = CreatePanel("test panel3");
1096
1097  scoped_ptr<NativePanelTesting> native_panel_testing(
1098      CreateNativePanelTesting(panel));
1099
1100  // Test that the attention is drawn and the title-bar is brought up when the
1101  // minimized panel is drawing attention.
1102  panel->Minimize();
1103  EXPECT_EQ(Panel::MINIMIZED, panel->expansion_state());
1104  panel->FlashFrame(true);
1105  EXPECT_TRUE(panel->IsDrawingAttention());
1106  EXPECT_EQ(Panel::TITLE_ONLY, panel->expansion_state());
1107  EXPECT_TRUE(native_panel_testing->VerifyDrawingAttention());
1108
1109  // Test that we cannot bring up other minimized panel if the mouse is over
1110  // the panel that draws attension.
1111  panel2->Minimize();
1112  gfx::Point hover_point(panel->GetBounds().origin());
1113  MoveMouse(hover_point);
1114  EXPECT_EQ(Panel::TITLE_ONLY, panel->expansion_state());
1115  EXPECT_EQ(Panel::MINIMIZED, panel2->expansion_state());
1116
1117  // Test that we cannot bring down the panel that is drawing the attention.
1118  hover_point.set_y(hover_point.y() - 200);
1119  MoveMouse(hover_point);
1120  EXPECT_EQ(Panel::TITLE_ONLY, panel->expansion_state());
1121
1122  // Test that the attention is cleared when activated.
1123  panel->Activate();
1124  WaitForPanelActiveState(panel, SHOW_AS_ACTIVE);
1125  EXPECT_FALSE(panel->IsDrawingAttention());
1126  EXPECT_EQ(Panel::EXPANDED, panel->expansion_state());
1127  EXPECT_FALSE(native_panel_testing->VerifyDrawingAttention());
1128
1129  panel->Close();
1130  panel2->Close();
1131  panel3->Close();
1132}
1133
1134// http://crbug.com/175760; several panel tests failing regularly on mac.
1135#if defined(OS_MACOSX)
1136#define MAYBE_StopDrawingAttentionWhileMinimized \
1137  DISABLED_StopDrawingAttentionWhileMinimized
1138#else
1139#define MAYBE_StopDrawingAttentionWhileMinimized \
1140  StopDrawingAttentionWhileMinimized
1141#endif
1142// Verify that minimized state of a panel is correct after draw attention
1143// is stopped when there are other minimized panels.
1144IN_PROC_BROWSER_TEST_F(PanelBrowserTest,
1145                       MAYBE_StopDrawingAttentionWhileMinimized) {
1146  Panel* panel1 = CreatePanel("panel1");
1147  Panel* panel2 = CreatePanel("panel2");
1148
1149  panel1->Minimize();
1150  EXPECT_EQ(Panel::MINIMIZED, panel1->expansion_state());
1151  panel2->Minimize();
1152  EXPECT_EQ(Panel::MINIMIZED, panel2->expansion_state());
1153
1154  // Verify panel returns to minimized state when no longer drawing attention.
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::MINIMIZED, panel1->expansion_state());
1162
1163  // Hover over other minimized panel to bring up titlebars.
1164  gfx::Point hover_point(panel2->GetBounds().origin());
1165  MoveMouseAndWaitForExpansionStateChange(panel1, hover_point);
1166  EXPECT_EQ(Panel::TITLE_ONLY, panel1->expansion_state());
1167  EXPECT_EQ(Panel::TITLE_ONLY, panel2->expansion_state());
1168
1169  // Verify panel keeps titlebar visible when no longer drawing attention
1170  // if titlebars are up.
1171  panel1->FlashFrame(true);
1172  EXPECT_TRUE(panel1->IsDrawingAttention());
1173  EXPECT_EQ(Panel::TITLE_ONLY, panel1->expansion_state());
1174
1175  panel1->FlashFrame(false);
1176  EXPECT_FALSE(panel1->IsDrawingAttention());
1177  EXPECT_EQ(Panel::TITLE_ONLY, panel1->expansion_state());
1178
1179  // Move mouse away. All panels should return to minimized state.
1180  hover_point.set_y(hover_point.y() - 200);
1181  MoveMouseAndWaitForExpansionStateChange(panel1, hover_point);
1182  EXPECT_EQ(Panel::MINIMIZED, panel1->expansion_state());
1183  EXPECT_EQ(Panel::MINIMIZED, panel2->expansion_state());
1184
1185  // Verify minimized panel that is drawing attention stays in title-only mode
1186  // after attention is cleared if mouse is in the titlebar area.
1187  panel1->FlashFrame(true);
1188  EXPECT_TRUE(panel1->IsDrawingAttention());
1189  EXPECT_EQ(Panel::TITLE_ONLY, panel1->expansion_state());
1190
1191  gfx::Point hover_point_in_panel(panel1->GetBounds().origin());
1192  MoveMouse(hover_point_in_panel);
1193
1194  panel1->FlashFrame(false);
1195  EXPECT_FALSE(panel1->IsDrawingAttention());
1196  EXPECT_EQ(Panel::TITLE_ONLY, panel1->expansion_state());
1197  EXPECT_EQ(Panel::MINIMIZED, panel2->expansion_state());
1198
1199  // Typical user scenario will detect the mouse in the panel
1200  // after attention is cleared, causing titles to pop up, so
1201  // we simulate that here.
1202  MoveMouseAndWaitForExpansionStateChange(panel2, hover_point_in_panel);
1203  EXPECT_EQ(Panel::TITLE_ONLY, panel1->expansion_state());
1204  EXPECT_EQ(Panel::TITLE_ONLY, panel2->expansion_state());
1205
1206  // Move mouse away and panels should go back to fully minimized state.
1207  MoveMouseAndWaitForExpansionStateChange(panel1, hover_point);
1208  EXPECT_EQ(Panel::MINIMIZED, panel1->expansion_state());
1209  EXPECT_EQ(Panel::MINIMIZED, panel2->expansion_state());
1210
1211  panel1->Close();
1212  panel2->Close();
1213}
1214
1215IN_PROC_BROWSER_TEST_F(PanelBrowserTest, DrawAttentionWhenActive) {
1216  CreatePanelParams params("Initially Active", gfx::Rect(), SHOW_AS_ACTIVE);
1217  Panel* panel = CreatePanelWithParams(params);
1218  scoped_ptr<NativePanelTesting> native_panel_testing(
1219      CreateNativePanelTesting(panel));
1220
1221  // Test that the attention should not be drawn if the expanded panel is in
1222  // focus.
1223  EXPECT_EQ(Panel::EXPANDED, panel->expansion_state());
1224  WaitForPanelActiveState(panel, SHOW_AS_ACTIVE);  // doublecheck active state
1225  EXPECT_FALSE(panel->IsDrawingAttention());
1226  panel->FlashFrame(true);
1227  EXPECT_FALSE(panel->IsDrawingAttention());
1228  EXPECT_FALSE(native_panel_testing->VerifyDrawingAttention());
1229
1230  panel->Close();
1231}
1232
1233// http://crbug.com/143247
1234#if !defined(OS_WIN)
1235#define MAYBE_DrawAttentionResetOnActivate DISABLED_DrawAttentionResetOnActivate
1236#else
1237#define MAYBE_DrawAttentionResetOnActivate DrawAttentionResetOnActivate
1238#endif
1239IN_PROC_BROWSER_TEST_F(PanelBrowserTest, MAYBE_DrawAttentionResetOnActivate) {
1240  // Create 2 panels so we end up with an inactive panel that can
1241  // be made to draw attention.
1242  Panel* panel = CreatePanel("test panel1");
1243  Panel* panel2 = CreatePanel("test panel2");
1244  WaitForPanelActiveState(panel, SHOW_AS_INACTIVE);
1245
1246  scoped_ptr<NativePanelTesting> native_panel_testing(
1247      CreateNativePanelTesting(panel));
1248
1249  panel->FlashFrame(true);
1250  EXPECT_TRUE(panel->IsDrawingAttention());
1251  EXPECT_TRUE(native_panel_testing->VerifyDrawingAttention());
1252
1253  // Test that the attention is cleared when panel gets focus.
1254  panel->Activate();
1255  WaitForPanelActiveState(panel, SHOW_AS_ACTIVE);
1256  EXPECT_FALSE(panel->IsDrawingAttention());
1257  EXPECT_FALSE(native_panel_testing->VerifyDrawingAttention());
1258
1259  panel->Close();
1260  panel2->Close();
1261}
1262
1263// http://crbug.com/143247
1264#if !defined(OS_WIN)
1265#define MAYBE_DrawAttentionMinimizedNotResetOnActivate DISABLED_DrawAttentionMinimizedNotResetOnActivate
1266#else
1267#define MAYBE_DrawAttentionMinimizedNotResetOnActivate DrawAttentionMinimizedNotResetOnActivate
1268#endif
1269IN_PROC_BROWSER_TEST_F(PanelBrowserTest,
1270                       MAYBE_DrawAttentionMinimizedNotResetOnActivate) {
1271  // Create 2 panels so we end up with an inactive panel that can
1272  // be made to draw attention.
1273  Panel* panel1 = CreatePanel("test panel1");
1274  Panel* panel2 = CreatePanel("test panel2");
1275  WaitForPanelActiveState(panel1, SHOW_AS_INACTIVE);
1276
1277  panel1->Minimize();
1278  EXPECT_TRUE(panel1->IsMinimized());
1279  panel1->FlashFrame(true);
1280  EXPECT_TRUE(panel1->IsDrawingAttention());
1281
1282  // Simulate panel being activated while minimized. Cannot call
1283  // Activate() as that expands the panel.
1284  panel1->OnActiveStateChanged(true);
1285  EXPECT_TRUE(panel1->IsDrawingAttention());  // Unchanged.
1286
1287  // Unminimize panel to show that attention would have been cleared
1288  // if panel had not been minimized.
1289  panel1->Restore();
1290  EXPECT_FALSE(panel1->IsMinimized());
1291  EXPECT_TRUE(panel1->IsDrawingAttention());  // Unchanged.
1292
1293  panel1->OnActiveStateChanged(true);
1294  EXPECT_FALSE(panel1->IsDrawingAttention());  // Attention cleared.
1295
1296  panel1->Close();
1297  panel2->Close();
1298}
1299
1300// http://crbug.com/143247
1301#if !defined(OS_WIN)
1302#define MAYBE_DrawAttentionResetOnClick DISABLED_DrawAttentionResetOnClick
1303#else
1304#define MAYBE_DrawAttentionResetOnClick DrawAttentionResetOnClick
1305#endif
1306IN_PROC_BROWSER_TEST_F(PanelBrowserTest, MAYBE_DrawAttentionResetOnClick) {
1307  // Create 2 panels so we end up with an inactive panel that can
1308  // be made to draw attention.
1309  Panel* panel = CreatePanel("test panel1");
1310  Panel* panel2 = CreatePanel("test panel2");
1311  WaitForPanelActiveState(panel, SHOW_AS_INACTIVE);
1312
1313  scoped_ptr<NativePanelTesting> native_panel_testing(
1314      CreateNativePanelTesting(panel));
1315
1316  panel->FlashFrame(true);
1317  EXPECT_TRUE(panel->IsDrawingAttention());
1318  EXPECT_TRUE(native_panel_testing->VerifyDrawingAttention());
1319
1320  // Test that the attention is cleared when panel gets focus.
1321  native_panel_testing->PressLeftMouseButtonTitlebar(
1322      panel->GetBounds().origin());
1323  native_panel_testing->ReleaseMouseButtonTitlebar();
1324
1325  WaitForPanelActiveState(panel, SHOW_AS_ACTIVE);
1326  EXPECT_FALSE(panel->IsDrawingAttention());
1327  EXPECT_FALSE(native_panel_testing->VerifyDrawingAttention());
1328
1329  panel->Close();
1330  panel2->Close();
1331}
1332
1333// http://crbug.com/175760; several panel tests failing regularly on mac.
1334#if defined(OS_MACOSX)
1335#define MAYBE_MinimizeImmediatelyAfterRestore \
1336  DISABLED_MinimizeImmediatelyAfterRestore
1337#else
1338#define MAYBE_MinimizeImmediatelyAfterRestore MinimizeImmediatelyAfterRestore
1339#endif
1340IN_PROC_BROWSER_TEST_F(PanelBrowserTest,
1341                       MAYBE_MinimizeImmediatelyAfterRestore) {
1342  CreatePanelParams params("Panel Test", gfx::Rect(), SHOW_AS_ACTIVE);
1343  Panel* panel = CreatePanelWithParams(params);
1344  scoped_ptr<NativePanelTesting> native_panel_testing(
1345      CreateNativePanelTesting(panel));
1346
1347  PanelActiveStateObserver signal(panel, false);
1348  panel->Minimize();  // this should deactivate.
1349  signal.Wait();
1350  EXPECT_EQ(Panel::MINIMIZED, panel->expansion_state());
1351
1352  panel->Restore();
1353  EXPECT_EQ(Panel::EXPANDED, panel->expansion_state());
1354
1355  // Verify that minimizing a panel right after expansion works.
1356  panel->Minimize();
1357  EXPECT_EQ(Panel::MINIMIZED, panel->expansion_state());
1358
1359  panel->Close();
1360}
1361
1362IN_PROC_BROWSER_TEST_F(PanelBrowserTest, FocusLostOnMinimize) {
1363  CreatePanelParams params("Initially Active", gfx::Rect(), SHOW_AS_ACTIVE);
1364  Panel* panel = CreatePanelWithParams(params);
1365  EXPECT_EQ(Panel::EXPANDED, panel->expansion_state());
1366
1367  PanelActiveStateObserver signal(panel, false);
1368  panel->Minimize();
1369  signal.Wait();
1370  panel->Close();
1371}
1372
1373// http://crbug.com/143247
1374#if !defined(OS_WIN)
1375#define MAYBE_CreateInactiveSwitchToActive DISABLED_CreateInactiveSwitchToActive
1376#else
1377#define MAYBE_CreateInactiveSwitchToActive CreateInactiveSwitchToActive
1378#endif
1379IN_PROC_BROWSER_TEST_F(PanelBrowserTest, MAYBE_CreateInactiveSwitchToActive) {
1380  // Compiz will not activate initially inactive window.
1381  if (SkipTestIfCompizWM())
1382    return;
1383
1384  CreatePanelParams params("Initially Inactive", gfx::Rect(), SHOW_AS_INACTIVE);
1385  Panel* panel = CreatePanelWithParams(params);
1386
1387  panel->Activate();
1388  WaitForPanelActiveState(panel, SHOW_AS_ACTIVE);
1389
1390  panel->Close();
1391}
1392
1393// TODO(dimich): try/enable on other platforms. See bug 103253 for details on
1394// why this is disabled on windows.
1395#if defined(OS_MACOSX)
1396#define MAYBE_MinimizeTwoPanelsWithoutTabbedWindow \
1397    MinimizeTwoPanelsWithoutTabbedWindow
1398#else
1399#define MAYBE_MinimizeTwoPanelsWithoutTabbedWindow \
1400    DISABLED_MinimizeTwoPanelsWithoutTabbedWindow
1401#endif
1402
1403// When there are 2 panels and no chrome window, minimizing one panel does
1404// not expand/focuses another.
1405IN_PROC_BROWSER_TEST_F(PanelBrowserTest,
1406                       MAYBE_MinimizeTwoPanelsWithoutTabbedWindow) {
1407  CreatePanelParams params("Initially Inactive", gfx::Rect(), SHOW_AS_INACTIVE);
1408  Panel* panel1 = CreatePanelWithParams(params);
1409  Panel* panel2 = CreatePanelWithParams(params);
1410
1411  // Close main tabbed window.
1412  content::WindowedNotificationObserver signal(
1413      chrome::NOTIFICATION_BROWSER_CLOSED,
1414      content::Source<Browser>(browser()));
1415  chrome::CloseWindow(browser());
1416  signal.Wait();
1417
1418  EXPECT_EQ(Panel::EXPANDED, panel1->expansion_state());
1419  EXPECT_EQ(Panel::EXPANDED, panel2->expansion_state());
1420  panel1->Activate();
1421  WaitForPanelActiveState(panel1, SHOW_AS_ACTIVE);
1422
1423  panel1->SetExpansionState(Panel::MINIMIZED);
1424  MessageLoop::current()->RunUntilIdle();
1425  WaitForPanelActiveState(panel1, SHOW_AS_INACTIVE);
1426  EXPECT_EQ(Panel::MINIMIZED, panel1->expansion_state());
1427
1428  panel2->SetExpansionState(Panel::MINIMIZED);
1429  MessageLoop::current()->RunUntilIdle();
1430  WaitForPanelActiveState(panel2, SHOW_AS_INACTIVE);
1431  EXPECT_EQ(Panel::MINIMIZED, panel2->expansion_state());
1432
1433  // Verify that panel1 is still minimized and not active.
1434  WaitForPanelActiveState(panel1, SHOW_AS_INACTIVE);
1435  EXPECT_EQ(Panel::MINIMIZED, panel1->expansion_state());
1436
1437  // Another check for the same.
1438  EXPECT_FALSE(panel1->IsActive());
1439  EXPECT_FALSE(panel2->IsActive());
1440
1441  panel1->Close();
1442  panel2->Close();
1443}
1444
1445// http://crbug.com/143247
1446#if !defined(OS_WIN)
1447#define MAYBE_NonExtensionDomainPanelsCloseOnUninstall DISABLED_NonExtensionDomainPanelsCloseOnUninstall
1448#else
1449#define MAYBE_NonExtensionDomainPanelsCloseOnUninstall NonExtensionDomainPanelsCloseOnUninstall
1450#endif
1451IN_PROC_BROWSER_TEST_F(PanelBrowserTest,
1452                       MAYBE_NonExtensionDomainPanelsCloseOnUninstall) {
1453  // Create a test extension.
1454  DictionaryValue empty_value;
1455  scoped_refptr<extensions::Extension> extension =
1456      CreateExtension(FILE_PATH_LITERAL("TestExtension"),
1457                      extensions::Manifest::INVALID_LOCATION, empty_value);
1458  std::string extension_app_name =
1459      web_app::GenerateApplicationNameFromExtensionId(extension->id());
1460
1461  PanelManager* panel_manager = PanelManager::GetInstance();
1462  EXPECT_EQ(0, panel_manager->num_panels());
1463
1464  // Create a panel with the extension as host.
1465  CreatePanelParams params(extension_app_name, gfx::Rect(), SHOW_AS_INACTIVE);
1466  std::string extension_domain_url(extensions::kExtensionScheme);
1467  extension_domain_url += "://";
1468  extension_domain_url += extension->id();
1469  extension_domain_url += "/hello.html";
1470  params.url = GURL(extension_domain_url);
1471  Panel* panel = CreatePanelWithParams(params);
1472  EXPECT_EQ(1, panel_manager->num_panels());
1473
1474  // Create a panel with a non-extension host.
1475  CreatePanelParams params1(extension_app_name, gfx::Rect(), SHOW_AS_INACTIVE);
1476  params1.url = GURL(chrome::kAboutBlankURL);
1477  Panel* panel1 = CreatePanelWithParams(params1);
1478  EXPECT_EQ(2, panel_manager->num_panels());
1479
1480  // Create another extension and a panel from that extension.
1481  scoped_refptr<extensions::Extension> extension_other =
1482      CreateExtension(FILE_PATH_LITERAL("TestExtensionOther"),
1483                      extensions::Manifest::INVALID_LOCATION, empty_value);
1484  std::string extension_app_name_other =
1485      web_app::GenerateApplicationNameFromExtensionId(extension_other->id());
1486  Panel* panel_other = CreatePanel(extension_app_name_other);
1487
1488  content::WindowedNotificationObserver signal(
1489      chrome::NOTIFICATION_PANEL_CLOSED,
1490      content::Source<Panel>(panel));
1491  content::WindowedNotificationObserver signal1(
1492      chrome::NOTIFICATION_PANEL_CLOSED,
1493      content::Source<Panel>(panel1));
1494
1495  // Send unload notification on the first extension.
1496  extensions::UnloadedExtensionInfo details(extension,
1497                                extension_misc::UNLOAD_REASON_UNINSTALL);
1498  content::NotificationService::current()->Notify(
1499      chrome::NOTIFICATION_EXTENSION_UNLOADED,
1500      content::Source<Profile>(browser()->profile()),
1501      content::Details<extensions::UnloadedExtensionInfo>(&details));
1502
1503  // Wait for the panels opened by the first extension to close.
1504  signal.Wait();
1505  signal1.Wait();
1506
1507  // Verify that the panel that's left is the panel from the second extension.
1508  EXPECT_EQ(panel_other, panel_manager->panels()[0]);
1509  panel_other->Close();
1510}
1511
1512IN_PROC_BROWSER_TEST_F(PanelBrowserTest, OnBeforeUnloadOnClose) {
1513  PanelManager* panel_manager = PanelManager::GetInstance();
1514  EXPECT_EQ(0, panel_manager->num_panels()); // No panels initially.
1515
1516  const string16 title_first_close = UTF8ToUTF16("TitleFirstClose");
1517  const string16 title_second_close = UTF8ToUTF16("TitleSecondClose");
1518
1519  // Create a test panel with web contents loaded.
1520  CreatePanelParams params("PanelTest1", gfx::Rect(0, 0, 300, 300),
1521                           SHOW_AS_ACTIVE);
1522  params.url = ui_test_utils::GetTestUrl(
1523      base::FilePath(kTestDir),
1524      base::FilePath(FILE_PATH_LITERAL("onbeforeunload.html")));
1525  Panel* panel = CreatePanelWithParams(params);
1526  EXPECT_EQ(1, panel_manager->num_panels());
1527
1528  // Close panel and verify it closes despite having a onbeforeunload handler.
1529  CloseWindowAndWait(panel);
1530  EXPECT_EQ(0, panel_manager->num_panels());
1531}
1532
1533// http://crbug.com/175760; several panel tests failing regularly on mac.
1534#if defined(OS_MACOSX)
1535#define MAYBE_SizeClamping DISABLED_SizeClamping
1536#else
1537#define MAYBE_SizeClamping SizeClamping
1538#endif
1539IN_PROC_BROWSER_TEST_F(PanelBrowserTest, MAYBE_SizeClamping) {
1540  // Using '0' sizes is equivalent of not providing sizes in API and causes
1541  // minimum sizes to be applied to facilitate auto-sizing.
1542  CreatePanelParams params("Panel", gfx::Rect(), SHOW_AS_ACTIVE);
1543  Panel* panel = CreatePanelWithParams(params);
1544  EXPECT_EQ(panel->min_size().width(), panel->GetBounds().width());
1545  EXPECT_EQ(panel->min_size().height(), panel->GetBounds().height());
1546  int reasonable_width = panel->min_size().width() + 10;
1547  int reasonable_height = panel->min_size().height() + 20;
1548
1549  panel->Close();
1550
1551  // Using reasonable actual sizes should avoid clamping.
1552  CreatePanelParams params1("Panel1",
1553                            gfx::Rect(0, 0,
1554                                      reasonable_width, reasonable_height),
1555                            SHOW_AS_ACTIVE);
1556  panel = CreatePanelWithParams(params1);
1557  EXPECT_EQ(reasonable_width, panel->GetBounds().width());
1558  EXPECT_EQ(reasonable_height, panel->GetBounds().height());
1559  panel->Close();
1560
1561  // Using just one size should auto-compute some reasonable other size.
1562  int given_height = 200;
1563  CreatePanelParams params2("Panel2", gfx::Rect(0, 0, 0, given_height),
1564                            SHOW_AS_ACTIVE);
1565  panel = CreatePanelWithParams(params2);
1566  EXPECT_GT(panel->GetBounds().width(), 0);
1567  EXPECT_EQ(given_height, panel->GetBounds().height());
1568  panel->Close();
1569}
1570
1571// http://crbug.com/175760; several panel tests failing regularly on mac.
1572// http://crbug.com/179890; TightAutosizeAroundSingleLine broken on Windows by
1573// WebKit roll.
1574#if defined(OS_MACOSX) || defined(OS_WIN)
1575#define MAYBE_TightAutosizeAroundSingleLine \
1576        DISABLED_TightAutosizeAroundSingleLine
1577#else
1578#define MAYBE_TightAutosizeAroundSingleLine TightAutosizeAroundSingleLine
1579#endif
1580IN_PROC_BROWSER_TEST_F(PanelBrowserTest,
1581                       MAYBE_TightAutosizeAroundSingleLine) {
1582  PanelManager::GetInstance()->enable_auto_sizing(true);
1583  // Using 0 sizes triggers auto-sizing.
1584  CreatePanelParams params("Panel", gfx::Rect(), SHOW_AS_ACTIVE);
1585  params.url = GURL("data:text/html;charset=utf-8,<!doctype html><body>");
1586  Panel* panel = CreatePanelWithParams(params);
1587
1588  // Ensure panel has auto resized to original web content size.
1589  WaitForStableInitialSize initial_resize(panel);
1590  initial_resize.Wait();
1591
1592  int initial_width = panel->GetBounds().width();
1593  int initial_height = panel->GetBounds().height();
1594
1595  // Inject some HTML content into the panel.
1596  WaitForAutoResizeWider enlarge(panel);
1597  EXPECT_TRUE(content::ExecuteScript(
1598      panel->GetWebContents(),
1599      "document.body.innerHTML ="
1600      "    '<nobr>line of text and a <button>Button</button>';"));
1601  enlarge.Wait();
1602
1603  // The panel should have become larger in both dimensions (the minimums
1604  // has to be set to be smaller then a simple 1-line content, so the autosize
1605  // can work correctly.
1606  EXPECT_GT(panel->GetBounds().width(), initial_width);
1607  EXPECT_GT(panel->GetBounds().height(), initial_height);
1608
1609  panel->Close();
1610}
1611
1612// http://crbug.com/175760; several panel tests failing regularly on mac.
1613#if defined(OS_MACOSX)
1614#define MAYBE_DefaultMaxSizeOnDisplaySettingsChange \
1615        DISABLED_DefaultMaxSizeOnDisplaySettingsChange
1616#else
1617#define MAYBE_DefaultMaxSizeOnDisplaySettingsChange \
1618        DefaultMaxSizeOnDisplaySettingsChange
1619#endif
1620IN_PROC_BROWSER_TEST_F(PanelBrowserTest,
1621                       MAYBE_DefaultMaxSizeOnDisplaySettingsChange) {
1622  Panel* panel = CreatePanelWithBounds("1", gfx::Rect(0, 0, 240, 220));
1623
1624  gfx::Size old_max_size = panel->max_size();
1625  gfx::Size old_full_size = panel->full_size();
1626
1627  // Shrink the work area. Expect max size and full size become smaller.
1628  gfx::Rect smaller_work_area(0, 0, 500, 300);
1629  mock_display_settings_provider()->SetPrimaryDisplay(
1630      smaller_work_area, smaller_work_area);
1631  EXPECT_GT(old_max_size.width(), panel->max_size().width());
1632  EXPECT_GT(old_max_size.height(), panel->max_size().height());
1633  EXPECT_GT(smaller_work_area.width(), panel->max_size().width());
1634  EXPECT_GT(smaller_work_area.height(), panel->max_size().height());
1635  EXPECT_GT(old_full_size.width(), panel->full_size().width());
1636  EXPECT_GT(old_full_size.height(), panel->full_size().height());
1637  EXPECT_GE(panel->max_size().width(), panel->full_size().width());
1638  EXPECT_GE(panel->max_size().height(), panel->full_size().height());
1639
1640  panel->Close();
1641}
1642
1643// http://crbug.com/175760; several panel tests failing regularly on mac.
1644#if defined(OS_MACOSX)
1645#define MAYBE_CustomMaxSizeOnDisplaySettingsChange \
1646        DISABLED_CustomMaxSizeOnDisplaySettingsChange
1647#else
1648#define MAYBE_CustomMaxSizeOnDisplaySettingsChange \
1649        CustomMaxSizeOnDisplaySettingsChange
1650#endif
1651IN_PROC_BROWSER_TEST_F(PanelBrowserTest,
1652                       MAYBE_CustomMaxSizeOnDisplaySettingsChange) {
1653  PanelManager* panel_manager = PanelManager::GetInstance();
1654  Panel* panel = CreatePanelWithBounds("1", gfx::Rect(0, 0, 240, 220));
1655
1656  // Trigger custom max size by user resizing.
1657  gfx::Size bigger_size = gfx::Size(550, 400);
1658  gfx::Point mouse_location = panel->GetBounds().origin();
1659  panel_manager->StartResizingByMouse(panel,
1660                                      mouse_location,
1661                                      panel::RESIZE_TOP_LEFT);
1662  mouse_location.Offset(panel->GetBounds().width() - bigger_size.width(),
1663                        panel->GetBounds().height() - bigger_size.height());
1664  panel_manager->ResizeByMouse(mouse_location);
1665  panel_manager->EndResizingByMouse(false);
1666
1667  gfx::Size old_max_size = panel->max_size();
1668  EXPECT_EQ(bigger_size, old_max_size);
1669  gfx::Size old_full_size = panel->full_size();
1670  EXPECT_EQ(bigger_size, old_full_size);
1671
1672  // Shrink the work area. Expect max size and full size become smaller.
1673  gfx::Rect smaller_work_area(0, 0, 500, 300);
1674  mock_display_settings_provider()->SetPrimaryDisplay(
1675      smaller_work_area, smaller_work_area);
1676  EXPECT_GT(old_max_size.width(), panel->max_size().width());
1677  EXPECT_GT(old_max_size.height(), panel->max_size().height());
1678  EXPECT_GE(smaller_work_area.width(), panel->max_size().width());
1679  EXPECT_EQ(smaller_work_area.height(), panel->max_size().height());
1680  EXPECT_GT(old_full_size.width(), panel->full_size().width());
1681  EXPECT_GT(old_full_size.height(), panel->full_size().height());
1682  EXPECT_GE(panel->max_size().width(), panel->full_size().width());
1683  EXPECT_GE(panel->max_size().height(), panel->full_size().height());
1684  EXPECT_EQ(smaller_work_area.height(), panel->full_size().height());
1685
1686  panel->Close();
1687}
1688
1689// http://crbug.com/175760; several panel tests failing regularly on mac.
1690#if defined(OS_MACOSX)
1691#define MAYBE_DevTools DISABLED_DevTools
1692#else
1693#define MAYBE_DevTools DevTools
1694#endif
1695IN_PROC_BROWSER_TEST_F(PanelBrowserTest, DevTools) {
1696  // Create a test panel with web contents loaded.
1697  CreatePanelParams params("1", gfx::Rect(0, 0, 200, 220), SHOW_AS_ACTIVE);
1698  GURL url(ui_test_utils::GetTestUrl(
1699      base::FilePath(kTestDir),
1700      base::FilePath(FILE_PATH_LITERAL("update-preferred-size.html"))));
1701  params.url = url;
1702  Panel* panel = CreatePanelWithParams(params);
1703
1704  // Open devtools.
1705  size_t num_browsers = 1;
1706  EXPECT_EQ(num_browsers, chrome::GetBrowserCount(
1707                              browser()->profile(),
1708                              browser()->host_desktop_type()));
1709  content::WindowedNotificationObserver signal(
1710      chrome::NOTIFICATION_BROWSER_WINDOW_READY,
1711      content::NotificationService::AllSources());
1712  EXPECT_TRUE(panel->ExecuteCommandIfEnabled(IDC_DEV_TOOLS));
1713  signal.Wait();
1714
1715  // Check that the new browser window that opened is dev tools window.
1716  ++num_browsers;
1717  EXPECT_EQ(num_browsers, chrome::GetBrowserCount(
1718                              browser()->profile(),
1719                              browser()->host_desktop_type()));
1720  for (chrome::BrowserIterator iter; !iter.done(); iter.Next()) {
1721    if (*iter == browser())
1722      continue;
1723    ASSERT_TRUE((*iter)->is_devtools());
1724  }
1725
1726  panel->Close();
1727}
1728
1729// http://crbug.com/175760; several panel tests failing regularly on mac.
1730#if defined(OS_MACOSX)
1731#define MAYBE_DevToolsConsole DISABLED_DevToolsConsole
1732#else
1733#define MAYBE_DevToolsConsole DevToolsConsole
1734#endif
1735IN_PROC_BROWSER_TEST_F(PanelBrowserTest, DevToolsConsole) {
1736  // Create a test panel with web contents loaded.
1737  CreatePanelParams params("1", gfx::Rect(0, 0, 200, 220), SHOW_AS_ACTIVE);
1738  GURL url(ui_test_utils::GetTestUrl(
1739      base::FilePath(kTestDir),
1740      base::FilePath(FILE_PATH_LITERAL("update-preferred-size.html"))));
1741  params.url = url;
1742  Panel* panel = CreatePanelWithParams(params);
1743
1744  // Open devtools console.
1745  size_t num_browsers = 1;
1746  EXPECT_EQ(num_browsers, chrome::GetBrowserCount(
1747                              browser()->profile(),
1748                              browser()->host_desktop_type()));
1749  content::WindowedNotificationObserver signal(
1750      chrome::NOTIFICATION_BROWSER_WINDOW_READY,
1751      content::NotificationService::AllSources());
1752  EXPECT_TRUE(panel->ExecuteCommandIfEnabled(IDC_DEV_TOOLS_CONSOLE));
1753  signal.Wait();
1754
1755  // Check that the new browser window that opened is dev tools window.
1756  ++num_browsers;
1757  EXPECT_EQ(num_browsers, chrome::GetBrowserCount(
1758                              browser()->profile(),
1759                              browser()->host_desktop_type()));
1760  for (chrome::BrowserIterator iter; !iter.done(); iter.Next()) {
1761    if (*iter == browser())
1762      continue;
1763    ASSERT_TRUE((*iter)->is_devtools());
1764  }
1765
1766  panel->Close();
1767}
1768
1769#if defined(OS_WIN)
1770#define MAYBE_Accelerator Accelerator
1771#else
1772#define MAYBE_Accelerator DISABLED_Accelerator
1773#endif
1774IN_PROC_BROWSER_TEST_F(PanelBrowserTest, MAYBE_Accelerator) {
1775  PanelManager* panel_manager = PanelManager::GetInstance();
1776
1777  // Create a test panel with web contents loaded.
1778  CreatePanelParams params("1", gfx::Rect(), SHOW_AS_ACTIVE);
1779  GURL url(ui_test_utils::GetTestUrl(
1780      base::FilePath(kTestDir),
1781      base::FilePath(FILE_PATH_LITERAL("update-preferred-size.html"))));
1782  params.url = url;
1783  Panel* panel = CreatePanelWithParams(params);
1784  EXPECT_EQ(1, panel_manager->num_panels());
1785
1786  // Close the panel by acclerator.
1787  content::WindowedNotificationObserver signal(
1788      chrome::NOTIFICATION_PANEL_CLOSED,
1789      content::Source<Panel>(panel));
1790#if defined(USE_AURA)
1791  double now = ui::EventTimeForNow().InSecondsF();
1792  content::NativeWebKeyboardEvent key_event(
1793      ui::ET_KEY_PRESSED,
1794      false,
1795      ui::VKEY_W,
1796      ui::EF_CONTROL_DOWN,
1797      now);
1798#elif defined(OS_WIN)
1799  ::MSG key_msg = { NULL, WM_KEYDOWN, ui::VKEY_W, 0 };
1800  content::NativeWebKeyboardEvent key_event(key_msg);
1801  key_event.modifiers = content::NativeWebKeyboardEvent::ControlKey;
1802#else
1803  content::NativeWebKeyboardEvent key_event;
1804#endif
1805  panel->HandleKeyboardEvent(key_event);
1806  signal.Wait();
1807  EXPECT_EQ(0, panel_manager->num_panels());
1808}
1809
1810class PanelExtensionApiTest : public ExtensionApiTest {
1811 protected:
1812  virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
1813    ExtensionApiTest::SetUpCommandLine(command_line);
1814    command_line->AppendSwitch(switches::kEnablePanels);
1815  }
1816};
1817
1818#if defined(OS_LINUX) || (!defined(OS_WIN) && defined(USE_AURA)) || \
1819    defined(OS_MACOSX)
1820// Focus test fails if there is no window manager on Linux.
1821// Aura panels have different behavior that do not apply to this test.
1822#define MAYBE_FocusChangeEventOnMinimize DISABLED_FocusChangeEventOnMinimize
1823#else
1824#define MAYBE_FocusChangeEventOnMinimize FocusChangeEventOnMinimize
1825#endif
1826IN_PROC_BROWSER_TEST_F(PanelExtensionApiTest,
1827                       MAYBE_FocusChangeEventOnMinimize) {
1828  // This is needed so the subsequently created panels can be activated.
1829  // On a Mac, it transforms background-only test process into foreground one.
1830  ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
1831  ASSERT_TRUE(RunExtensionTest("panels/focus_change_on_minimize")) << message_;
1832}
1833