panel_browsertest.cc revision f8ee788a64d60abd8f2d742a5fdedde054ecd910
1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "base/bind.h"
6#include "base/prefs/pref_service.h"
7#include "base/strings/utf_string_conversions.h"
8#include "chrome/app/chrome_command_ids.h"
9#include "chrome/browser/chrome_notification_types.h"
10#include "chrome/browser/devtools/devtools_window.h"
11#include "chrome/browser/extensions/extension_apitest.h"
12#include "chrome/browser/net/url_request_mock_util.h"
13#include "chrome/browser/prefs/browser_prefs.h"
14#include "chrome/browser/profiles/profile.h"
15#include "chrome/browser/ui/app_modal_dialogs/app_modal_dialog.h"
16#include "chrome/browser/ui/app_modal_dialogs/native_app_modal_dialog.h"
17#include "chrome/browser/ui/browser.h"
18#include "chrome/browser/ui/browser_commands.h"
19#include "chrome/browser/ui/browser_finder.h"
20#include "chrome/browser/ui/browser_iterator.h"
21#include "chrome/browser/ui/browser_window.h"
22#include "chrome/browser/ui/panels/base_panel_browser_test.h"
23#include "chrome/browser/ui/panels/docked_panel_collection.h"
24#include "chrome/browser/ui/panels/native_panel.h"
25#include "chrome/browser/ui/panels/panel.h"
26#include "chrome/browser/ui/panels/panel_manager.h"
27#include "chrome/browser/ui/panels/test_panel_active_state_observer.h"
28#include "chrome/browser/web_applications/web_app.h"
29#include "chrome/common/chrome_switches.h"
30#include "chrome/common/pref_names.h"
31#include "chrome/common/url_constants.h"
32#include "chrome/test/base/interactive_test_utils.h"
33#include "chrome/test/base/ui_test_utils.h"
34#include "content/public/browser/native_web_keyboard_event.h"
35#include "content/public/browser/notification_service.h"
36#include "content/public/browser/web_contents.h"
37#include "content/public/common/url_constants.h"
38#include "content/public/test/browser_test_utils.h"
39#include "content/test/net/url_request_mock_http_job.h"
40#include "extensions/common/constants.h"
41#include "net/base/net_util.h"
42#include "testing/gtest/include/gtest/gtest.h"
43#include "ui/base/hit_test.h"
44#include "ui/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  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
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
506IN_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
541IN_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
598IN_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
606IN_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
615IN_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
625IN_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
678IN_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
838IN_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
881IN_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
950IN_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
990IN_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
1018IN_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
1054IN_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
1088IN_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.
1129IN_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
1198IN_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
1213IN_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
1231IN_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
1257IN_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
1285IN_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
1307IN_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
1318IN_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.
1339IN_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
1379IN_PROC_BROWSER_TEST_F(PanelBrowserTest,
1380                       NonExtensionDomainPanelsCloseOnUninstall) {
1381  // Create a test extension.
1382  base::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(url::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(), extensions::UnloadedExtensionInfo::REASON_UNINSTALL);
1426  content::NotificationService::current()->Notify(
1427      chrome::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED,
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
1440IN_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 base::string16 title_first_close = base::UTF8ToUTF16("TitleFirstClose");
1445  const base::string16 title_second_close =
1446      base::UTF8ToUTF16("TitleSecondClose");
1447
1448  // Create a test panel with web contents loaded.
1449  CreatePanelParams params("PanelTest1", gfx::Rect(0, 0, 300, 300),
1450                           SHOW_AS_ACTIVE);
1451  params.url = ui_test_utils::GetTestUrl(
1452      base::FilePath(kTestDir),
1453      base::FilePath(FILE_PATH_LITERAL("onbeforeunload.html")));
1454  Panel* panel = CreatePanelWithParams(params);
1455  EXPECT_EQ(1, panel_manager->num_panels());
1456
1457  // Close panel and verify it closes despite having a onbeforeunload handler.
1458  CloseWindowAndWait(panel);
1459  EXPECT_EQ(0, panel_manager->num_panels());
1460}
1461
1462// http://crbug.com/175760; several panel tests failing regularly on mac.
1463#if defined(OS_MACOSX)
1464#define MAYBE_SizeClamping DISABLED_SizeClamping
1465#else
1466#define MAYBE_SizeClamping SizeClamping
1467#endif
1468IN_PROC_BROWSER_TEST_F(PanelBrowserTest, MAYBE_SizeClamping) {
1469  // Using '0' sizes is equivalent of not providing sizes in API and causes
1470  // minimum sizes to be applied to facilitate auto-sizing.
1471  CreatePanelParams params("Panel", gfx::Rect(), SHOW_AS_ACTIVE);
1472  Panel* panel = CreatePanelWithParams(params);
1473  EXPECT_EQ(panel->min_size().width(), panel->GetBounds().width());
1474  EXPECT_EQ(panel->min_size().height(), panel->GetBounds().height());
1475  int reasonable_width = panel->min_size().width() + 10;
1476  int reasonable_height = panel->min_size().height() + 20;
1477
1478  panel->Close();
1479
1480  // Using reasonable actual sizes should avoid clamping.
1481  CreatePanelParams params1("Panel1",
1482                            gfx::Rect(0, 0,
1483                                      reasonable_width, reasonable_height),
1484                            SHOW_AS_ACTIVE);
1485  panel = CreatePanelWithParams(params1);
1486  EXPECT_EQ(reasonable_width, panel->GetBounds().width());
1487  EXPECT_EQ(reasonable_height, panel->GetBounds().height());
1488  panel->Close();
1489
1490  // Using just one size should auto-compute some reasonable other size.
1491  int given_height = 200;
1492  CreatePanelParams params2("Panel2", gfx::Rect(0, 0, 0, given_height),
1493                            SHOW_AS_ACTIVE);
1494  panel = CreatePanelWithParams(params2);
1495  EXPECT_GT(panel->GetBounds().width(), 0);
1496  EXPECT_EQ(given_height, panel->GetBounds().height());
1497  panel->Close();
1498}
1499
1500// http://crbug.com/175760; several panel tests failing regularly on mac.
1501// http://crbug.com/179890; TightAutosizeAroundSingleLine broken on Windows by
1502IN_PROC_BROWSER_TEST_F(PanelBrowserTest,
1503                       DISABLED_TightAutosizeAroundSingleLine) {
1504  PanelManager::GetInstance()->enable_auto_sizing(true);
1505  // Using 0 sizes triggers auto-sizing.
1506  CreatePanelParams params("Panel", gfx::Rect(), SHOW_AS_ACTIVE);
1507  params.url = GURL("data:text/html;charset=utf-8,<!doctype html><body>");
1508  Panel* panel = CreatePanelWithParams(params);
1509
1510  // Ensure panel has auto resized to original web content size.
1511  WaitForStableInitialSize initial_resize(panel);
1512  initial_resize.Wait();
1513
1514  int initial_width = panel->GetBounds().width();
1515  int initial_height = panel->GetBounds().height();
1516
1517  // Inject some HTML content into the panel.
1518  WaitForAutoResizeWider enlarge(panel);
1519  EXPECT_TRUE(content::ExecuteScript(
1520      panel->GetWebContents(),
1521      "document.body.innerHTML ="
1522      "    '<nobr>line of text and a <button>Button</button>';"));
1523  enlarge.Wait();
1524
1525  // The panel should have become larger in both dimensions (the minimums
1526  // has to be set to be smaller then a simple 1-line content, so the autosize
1527  // can work correctly.
1528  EXPECT_GT(panel->GetBounds().width(), initial_width);
1529  EXPECT_GT(panel->GetBounds().height(), initial_height);
1530
1531  panel->Close();
1532}
1533
1534// http://crbug.com/175760; several panel tests failing regularly on mac.
1535#if defined(OS_MACOSX)
1536#define MAYBE_DefaultMaxSizeOnDisplaySettingsChange \
1537        DISABLED_DefaultMaxSizeOnDisplaySettingsChange
1538#else
1539#define MAYBE_DefaultMaxSizeOnDisplaySettingsChange \
1540        DefaultMaxSizeOnDisplaySettingsChange
1541#endif
1542IN_PROC_BROWSER_TEST_F(PanelBrowserTest,
1543                       MAYBE_DefaultMaxSizeOnDisplaySettingsChange) {
1544  Panel* panel = CreatePanelWithBounds("1", gfx::Rect(0, 0, 240, 220));
1545
1546  gfx::Size old_max_size = panel->max_size();
1547  gfx::Size old_full_size = panel->full_size();
1548
1549  // Shrink the work area. Expect max size and full size become smaller.
1550  gfx::Rect smaller_work_area(0, 0, 500, 300);
1551  mock_display_settings_provider()->SetPrimaryDisplay(
1552      smaller_work_area, smaller_work_area);
1553  EXPECT_GT(old_max_size.width(), panel->max_size().width());
1554  EXPECT_GT(old_max_size.height(), panel->max_size().height());
1555  EXPECT_GT(smaller_work_area.width(), panel->max_size().width());
1556  EXPECT_GT(smaller_work_area.height(), panel->max_size().height());
1557  EXPECT_GT(old_full_size.width(), panel->full_size().width());
1558  EXPECT_GT(old_full_size.height(), panel->full_size().height());
1559  EXPECT_GE(panel->max_size().width(), panel->full_size().width());
1560  EXPECT_GE(panel->max_size().height(), panel->full_size().height());
1561
1562  panel->Close();
1563}
1564
1565// http://crbug.com/175760; several panel tests failing regularly on mac.
1566#if defined(OS_MACOSX)
1567#define MAYBE_CustomMaxSizeOnDisplaySettingsChange \
1568        DISABLED_CustomMaxSizeOnDisplaySettingsChange
1569#else
1570#define MAYBE_CustomMaxSizeOnDisplaySettingsChange \
1571        CustomMaxSizeOnDisplaySettingsChange
1572#endif
1573IN_PROC_BROWSER_TEST_F(PanelBrowserTest,
1574                       MAYBE_CustomMaxSizeOnDisplaySettingsChange) {
1575  PanelManager* panel_manager = PanelManager::GetInstance();
1576  Panel* panel = CreatePanelWithBounds("1", gfx::Rect(0, 0, 240, 220));
1577
1578  // Trigger custom max size by user resizing.
1579  gfx::Size bigger_size = gfx::Size(550, 400);
1580  gfx::Point mouse_location = panel->GetBounds().origin();
1581  panel_manager->StartResizingByMouse(panel,
1582                                      mouse_location,
1583                                      HTTOPLEFT);
1584  mouse_location.Offset(panel->GetBounds().width() - bigger_size.width(),
1585                        panel->GetBounds().height() - bigger_size.height());
1586  panel_manager->ResizeByMouse(mouse_location);
1587  panel_manager->EndResizingByMouse(false);
1588
1589  gfx::Size old_max_size = panel->max_size();
1590  EXPECT_EQ(bigger_size, old_max_size);
1591  gfx::Size old_full_size = panel->full_size();
1592  EXPECT_EQ(bigger_size, old_full_size);
1593
1594  // Shrink the work area. Expect max size and full size become smaller.
1595  gfx::Rect smaller_work_area(0, 0, 500, 300);
1596  mock_display_settings_provider()->SetPrimaryDisplay(
1597      smaller_work_area, smaller_work_area);
1598  EXPECT_GT(old_max_size.width(), panel->max_size().width());
1599  EXPECT_GT(old_max_size.height(), panel->max_size().height());
1600  EXPECT_GE(smaller_work_area.width(), panel->max_size().width());
1601  EXPECT_EQ(smaller_work_area.height(), panel->max_size().height());
1602  EXPECT_GT(old_full_size.width(), panel->full_size().width());
1603  EXPECT_GT(old_full_size.height(), panel->full_size().height());
1604  EXPECT_GE(panel->max_size().width(), panel->full_size().width());
1605  EXPECT_GE(panel->max_size().height(), panel->full_size().height());
1606  EXPECT_EQ(smaller_work_area.height(), panel->full_size().height());
1607
1608  panel->Close();
1609}
1610
1611IN_PROC_BROWSER_TEST_F(PanelBrowserTest, DevTools) {
1612  // Create a test panel with web contents loaded.
1613  CreatePanelParams params("1", gfx::Rect(0, 0, 200, 220), SHOW_AS_ACTIVE);
1614  GURL url(ui_test_utils::GetTestUrl(
1615      base::FilePath(kTestDir),
1616      base::FilePath(FILE_PATH_LITERAL("update-preferred-size.html"))));
1617  params.url = url;
1618  Panel* panel = CreatePanelWithParams(params);
1619
1620  // Open devtools.
1621  size_t num_browsers = 1;
1622  EXPECT_EQ(num_browsers, chrome::GetBrowserCount(
1623                              browser()->profile(),
1624                              browser()->host_desktop_type()));
1625  content::WindowedNotificationObserver signal(
1626      chrome::NOTIFICATION_BROWSER_WINDOW_READY,
1627      content::NotificationService::AllSources());
1628  EXPECT_TRUE(panel->ExecuteCommandIfEnabled(IDC_DEV_TOOLS));
1629  signal.Wait();
1630
1631  // Check that the new browser window that opened is dev tools window.
1632  ++num_browsers;
1633  EXPECT_EQ(num_browsers, chrome::GetBrowserCount(
1634                              browser()->profile(),
1635                              browser()->host_desktop_type()));
1636  for (chrome::BrowserIterator iter; !iter.done(); iter.Next()) {
1637    if (*iter == browser())
1638      continue;
1639    ASSERT_TRUE((*iter)->is_devtools());
1640  }
1641
1642  panel->Close();
1643}
1644
1645IN_PROC_BROWSER_TEST_F(PanelBrowserTest, DevToolsConsole) {
1646  // Create a test panel with web contents loaded.
1647  CreatePanelParams params("1", gfx::Rect(0, 0, 200, 220), SHOW_AS_ACTIVE);
1648  GURL url(ui_test_utils::GetTestUrl(
1649      base::FilePath(kTestDir),
1650      base::FilePath(FILE_PATH_LITERAL("update-preferred-size.html"))));
1651  params.url = url;
1652  Panel* panel = CreatePanelWithParams(params);
1653
1654  // Open devtools console.
1655  size_t num_browsers = 1;
1656  EXPECT_EQ(num_browsers, chrome::GetBrowserCount(
1657                              browser()->profile(),
1658                              browser()->host_desktop_type()));
1659  content::WindowedNotificationObserver signal(
1660      chrome::NOTIFICATION_BROWSER_WINDOW_READY,
1661      content::NotificationService::AllSources());
1662  EXPECT_TRUE(panel->ExecuteCommandIfEnabled(IDC_DEV_TOOLS_CONSOLE));
1663  signal.Wait();
1664
1665  // Check that the new browser window that opened is dev tools window.
1666  ++num_browsers;
1667  EXPECT_EQ(num_browsers, chrome::GetBrowserCount(
1668                              browser()->profile(),
1669                              browser()->host_desktop_type()));
1670  for (chrome::BrowserIterator iter; !iter.done(); iter.Next()) {
1671    if (*iter == browser())
1672      continue;
1673    ASSERT_TRUE((*iter)->is_devtools());
1674  }
1675
1676  panel->Close();
1677}
1678
1679#if defined(OS_WIN)
1680#define MAYBE_Accelerator Accelerator
1681#else
1682#define MAYBE_Accelerator DISABLED_Accelerator
1683#endif
1684IN_PROC_BROWSER_TEST_F(PanelBrowserTest, MAYBE_Accelerator) {
1685  PanelManager* panel_manager = PanelManager::GetInstance();
1686
1687  // Create a test panel with web contents loaded.
1688  CreatePanelParams params("1", gfx::Rect(), SHOW_AS_ACTIVE);
1689  GURL url(ui_test_utils::GetTestUrl(
1690      base::FilePath(kTestDir),
1691      base::FilePath(FILE_PATH_LITERAL("update-preferred-size.html"))));
1692  params.url = url;
1693  Panel* panel = CreatePanelWithParams(params);
1694  EXPECT_EQ(1, panel_manager->num_panels());
1695
1696  // Close the panel by acclerator.
1697  content::WindowedNotificationObserver signal(
1698      chrome::NOTIFICATION_PANEL_CLOSED,
1699      content::Source<Panel>(panel));
1700#if defined(USE_AURA)
1701  double now = ui::EventTimeForNow().InSecondsF();
1702  content::NativeWebKeyboardEvent key_event(
1703      ui::ET_KEY_PRESSED,
1704      false,
1705      ui::VKEY_W,
1706      ui::EF_CONTROL_DOWN,
1707      now);
1708#elif defined(OS_WIN)
1709  ::MSG key_msg = { NULL, WM_KEYDOWN, ui::VKEY_W, 0 };
1710  content::NativeWebKeyboardEvent key_event(key_msg);
1711  key_event.modifiers = content::NativeWebKeyboardEvent::ControlKey;
1712#else
1713  content::NativeWebKeyboardEvent key_event;
1714#endif
1715  panel->HandleKeyboardEvent(key_event);
1716  signal.Wait();
1717  EXPECT_EQ(0, panel_manager->num_panels());
1718}
1719
1720IN_PROC_BROWSER_TEST_F(PanelBrowserTest,
1721                       HideDockedPanelCreatedBeforeFullScreenMode) {
1722  // Create a docked panel.
1723  Panel* panel = CreatePanel("PanelTest");
1724  scoped_ptr<NativePanelTesting> panel_testing(CreateNativePanelTesting(panel));
1725
1726  // Panel should be visible at first.
1727  EXPECT_TRUE(panel_testing->IsWindowVisible());
1728
1729  // Panel should become hidden when entering full-screen mode.
1730  // Note that this is not needed on Linux because the full-screen window will
1731  // be always placed above any other windows.
1732  mock_display_settings_provider()->EnableFullScreenMode(true);
1733#if defined(OS_LINUX)
1734  EXPECT_TRUE(panel_testing->IsWindowVisible());
1735#else
1736  EXPECT_FALSE(panel_testing->IsWindowVisible());
1737#endif
1738
1739  // Panel should become visible when leaving full-screen mode.
1740  mock_display_settings_provider()->EnableFullScreenMode(false);
1741  EXPECT_TRUE(panel_testing->IsWindowVisible());
1742
1743  PanelManager::GetInstance()->CloseAll();
1744}
1745
1746IN_PROC_BROWSER_TEST_F(PanelBrowserTest,
1747                       HideDockedPanelCreatedOnFullScreenMode) {
1748  // Enable full-screen mode first.
1749  mock_display_settings_provider()->EnableFullScreenMode(true);
1750
1751  // Create a docked panel without waiting for it to be shown since it is not
1752  // supposed to be shown on full-screen mode.
1753  CreatePanelParams params("1", gfx::Rect(0, 0, 250, 200), SHOW_AS_ACTIVE);
1754  params.wait_for_fully_created = false;
1755  Panel* panel = CreatePanelWithParams(params);
1756  scoped_ptr<NativePanelTesting> panel_testing(
1757      CreateNativePanelTesting(panel));
1758
1759  // Panel should not be shown on full-screen mode.
1760  EXPECT_FALSE(panel_testing->IsWindowVisible());
1761
1762  // Panel should become visible when leaving full-screen mode.
1763  mock_display_settings_provider()->EnableFullScreenMode(false);
1764  EXPECT_TRUE(panel_testing->IsWindowVisible());
1765
1766  PanelManager::GetInstance()->CloseAll();
1767}
1768
1769class PanelExtensionApiTest : public ExtensionApiTest {
1770 protected:
1771  virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
1772    ExtensionApiTest::SetUpCommandLine(command_line);
1773    command_line->AppendSwitch(switches::kEnablePanels);
1774  }
1775};
1776
1777#if defined(OS_LINUX) || (!defined(OS_WIN) && defined(USE_AURA)) || \
1778    defined(OS_MACOSX)
1779// Focus test fails if there is no window manager on Linux.
1780// Aura panels have different behavior that do not apply to this test.
1781#define MAYBE_FocusChangeEventOnMinimize DISABLED_FocusChangeEventOnMinimize
1782#else
1783#define MAYBE_FocusChangeEventOnMinimize FocusChangeEventOnMinimize
1784#endif
1785IN_PROC_BROWSER_TEST_F(PanelExtensionApiTest,
1786                       MAYBE_FocusChangeEventOnMinimize) {
1787  // This is needed so the subsequently created panels can be activated.
1788  // On a Mac, it transforms background-only test process into foreground one.
1789  ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
1790  ASSERT_TRUE(RunExtensionTest("panels/focus_change_on_minimize")) << message_;
1791}
1792