Revert of Add button to add new FSP services to Files app. (patchset #8 id:140001...
[chromium-blink-merge.git] / chrome / browser / ui / views / tabs / tab_drag_controller_interactive_uitest.cc
blob9be153ab0f329f44d9976e0e9c12f7c5fb97cd51
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.
5 #include "chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.h"
7 #include <algorithm>
9 #include "ash/wm/window_state.h"
10 #include "base/bind.h"
11 #include "base/callback.h"
12 #include "base/command_line.h"
13 #include "base/run_loop.h"
14 #include "base/strings/string_number_conversions.h"
15 #include "chrome/browser/chrome_notification_types.h"
16 #include "chrome/browser/ui/browser.h"
17 #include "chrome/browser/ui/browser_commands.h"
18 #include "chrome/browser/ui/browser_iterator.h"
19 #include "chrome/browser/ui/browser_list.h"
20 #include "chrome/browser/ui/host_desktop.h"
21 #include "chrome/browser/ui/tabs/tab_strip_model.h"
22 #include "chrome/browser/ui/views/frame/browser_view.h"
23 #include "chrome/browser/ui/views/frame/native_browser_frame_factory.h"
24 #include "chrome/browser/ui/views/tabs/tab.h"
25 #include "chrome/browser/ui/views/tabs/tab_drag_controller.h"
26 #include "chrome/browser/ui/views/tabs/tab_strip.h"
27 #include "chrome/test/base/in_process_browser_test.h"
28 #include "chrome/test/base/interactive_test_utils.h"
29 #include "chrome/test/base/ui_test_utils.h"
30 #include "content/public/browser/notification_details.h"
31 #include "content/public/browser/notification_observer.h"
32 #include "content/public/browser/notification_service.h"
33 #include "content/public/browser/notification_source.h"
34 #include "content/public/browser/web_contents.h"
35 #include "ui/base/test/ui_controls.h"
36 #include "ui/gfx/screen.h"
37 #include "ui/views/view.h"
38 #include "ui/views/widget/widget.h"
40 #if defined(USE_AURA) && !defined(OS_CHROMEOS)
41 #include "chrome/browser/ui/views/frame/desktop_browser_frame_aura.h"
42 #include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h"
43 #endif
45 #if defined(USE_ASH)
46 #include "ash/display/display_controller.h"
47 #include "ash/display/display_manager.h"
48 #include "ash/shell.h"
49 #include "ash/test/cursor_manager_test_api.h"
50 #include "ash/wm/coordinate_conversion.h"
51 #include "ash/wm/window_util.h"
52 #include "chrome/browser/ui/views/frame/immersive_mode_controller.h"
53 #include "ui/aura/client/screen_position_client.h"
54 #include "ui/aura/test/event_generator_delegate_aura.h"
55 #include "ui/aura/window_event_dispatcher.h"
56 #include "ui/events/test/event_generator.h"
57 #endif
59 using content::WebContents;
61 namespace test {
63 namespace {
65 const char kTabDragControllerInteractiveUITestUserDataKey[] =
66 "TabDragControllerInteractiveUITestUserData";
68 class TabDragControllerInteractiveUITestUserData
69 : public base::SupportsUserData::Data {
70 public:
71 explicit TabDragControllerInteractiveUITestUserData(int id) : id_(id) {}
72 ~TabDragControllerInteractiveUITestUserData() override {}
73 int id() { return id_; }
75 private:
76 int id_;
79 } // namespace
81 class QuitDraggingObserver : public content::NotificationObserver {
82 public:
83 QuitDraggingObserver() {
84 registrar_.Add(this, chrome::NOTIFICATION_TAB_DRAG_LOOP_DONE,
85 content::NotificationService::AllSources());
88 void Observe(int type,
89 const content::NotificationSource& source,
90 const content::NotificationDetails& details) override {
91 DCHECK_EQ(chrome::NOTIFICATION_TAB_DRAG_LOOP_DONE, type);
92 base::MessageLoopForUI::current()->Quit();
93 delete this;
96 private:
97 ~QuitDraggingObserver() override {}
99 content::NotificationRegistrar registrar_;
101 DISALLOW_COPY_AND_ASSIGN(QuitDraggingObserver);
104 gfx::Point GetCenterInScreenCoordinates(const views::View* view) {
105 gfx::Point center(view->width() / 2, view->height() / 2);
106 views::View::ConvertPointToScreen(view, &center);
107 return center;
110 void SetID(WebContents* web_contents, int id) {
111 web_contents->SetUserData(&kTabDragControllerInteractiveUITestUserDataKey,
112 new TabDragControllerInteractiveUITestUserData(id));
115 void ResetIDs(TabStripModel* model, int start) {
116 for (int i = 0; i < model->count(); ++i)
117 SetID(model->GetWebContentsAt(i), start + i);
120 std::string IDString(TabStripModel* model) {
121 std::string result;
122 for (int i = 0; i < model->count(); ++i) {
123 if (i != 0)
124 result += " ";
125 WebContents* contents = model->GetWebContentsAt(i);
126 TabDragControllerInteractiveUITestUserData* user_data =
127 static_cast<TabDragControllerInteractiveUITestUserData*>(
128 contents->GetUserData(
129 &kTabDragControllerInteractiveUITestUserDataKey));
130 if (user_data)
131 result += base::IntToString(user_data->id());
132 else
133 result += "?";
135 return result;
138 // Creates a listener that quits the message loop when no longer dragging.
139 void QuitWhenNotDraggingImpl() {
140 new QuitDraggingObserver(); // QuitDraggingObserver deletes itself.
143 TabStrip* GetTabStripForBrowser(Browser* browser) {
144 BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser);
145 return static_cast<TabStrip*>(browser_view->tabstrip());
148 } // namespace test
150 using test::GetCenterInScreenCoordinates;
151 using test::SetID;
152 using test::ResetIDs;
153 using test::IDString;
154 using test::GetTabStripForBrowser;
156 TabDragControllerTest::TabDragControllerTest()
157 : native_browser_list(BrowserList::GetInstance(
158 chrome::HOST_DESKTOP_TYPE_NATIVE)) {
161 TabDragControllerTest::~TabDragControllerTest() {
164 void TabDragControllerTest::StopAnimating(TabStrip* tab_strip) {
165 tab_strip->StopAnimating(true);
168 void TabDragControllerTest::AddTabAndResetBrowser(Browser* browser) {
169 AddBlankTabAndShow(browser);
170 StopAnimating(GetTabStripForBrowser(browser));
171 ResetIDs(browser->tab_strip_model(), 0);
174 Browser* TabDragControllerTest::CreateAnotherWindowBrowserAndRelayout() {
175 // Create another browser.
176 Browser* browser2 = CreateBrowser(browser()->profile());
177 ResetIDs(browser2->tab_strip_model(), 100);
179 // Resize the two windows so they're right next to each other.
180 gfx::Rect work_area = gfx::Screen::GetNativeScreen()->GetDisplayNearestWindow(
181 browser()->window()->GetNativeWindow()).work_area();
182 gfx::Size half_size =
183 gfx::Size(work_area.width() / 3 - 10, work_area.height() / 2 - 10);
184 browser()->window()->SetBounds(gfx::Rect(work_area.origin(), half_size));
185 browser2->window()->SetBounds(gfx::Rect(
186 work_area.x() + half_size.width(), work_area.y(),
187 half_size.width(), half_size.height()));
188 return browser2;
191 namespace {
193 enum InputSource {
194 INPUT_SOURCE_MOUSE = 0,
195 INPUT_SOURCE_TOUCH = 1
198 int GetDetachY(TabStrip* tab_strip) {
199 return std::max(TabDragController::kTouchVerticalDetachMagnetism,
200 TabDragController::kVerticalDetachMagnetism) +
201 tab_strip->height() + 1;
204 bool GetIsDragged(Browser* browser) {
205 #if !defined(USE_ASH) || defined(OS_WIN) // TODO(win_ash)
206 return false;
207 #else
208 return ash::wm::GetWindowState(browser->window()->GetNativeWindow())->
209 is_dragged();
210 #endif
213 } // namespace
215 #if defined(USE_ASH) && !defined(OS_WIN) // TODO(win_ash)
216 class ScreenEventGeneratorDelegate
217 : public aura::test::EventGeneratorDelegateAura {
218 public:
219 explicit ScreenEventGeneratorDelegate(aura::Window* root_window)
220 : root_window_(root_window) {}
221 ~ScreenEventGeneratorDelegate() override {}
223 // EventGeneratorDelegateAura overrides:
224 aura::WindowTreeHost* GetHostAt(const gfx::Point& point) const override {
225 return root_window_->GetHost();
228 aura::client::ScreenPositionClient* GetScreenPositionClient(
229 const aura::Window* window) const override {
230 return aura::client::GetScreenPositionClient(root_window_);
233 private:
234 aura::Window* root_window_;
236 DISALLOW_COPY_AND_ASSIGN(ScreenEventGeneratorDelegate);
239 #endif
241 #if !defined(OS_CHROMEOS)
243 // Following classes verify a crash scenario. Specifically on Windows when focus
244 // changes it can trigger capture being lost. This was causing a crash in tab
245 // dragging as it wasn't set up to handle this scenario. These classes
246 // synthesize this scenario.
248 // Allows making ClearNativeFocus() invoke ReleaseCapture().
249 class TestDesktopBrowserFrameAura : public DesktopBrowserFrameAura {
250 public:
251 TestDesktopBrowserFrameAura(
252 BrowserFrame* browser_frame,
253 BrowserView* browser_view)
254 : DesktopBrowserFrameAura(browser_frame, browser_view),
255 release_capture_(false) {}
256 ~TestDesktopBrowserFrameAura() override {}
258 void ReleaseCaptureOnNextClear() {
259 release_capture_ = true;
262 void ClearNativeFocus() override {
263 views::DesktopNativeWidgetAura::ClearNativeFocus();
264 if (release_capture_) {
265 release_capture_ = false;
266 GetWidget()->ReleaseCapture();
270 private:
271 // If true ReleaseCapture() is invoked in ClearNativeFocus().
272 bool release_capture_;
274 DISALLOW_COPY_AND_ASSIGN(TestDesktopBrowserFrameAura);
277 // Factory for creating a TestDesktopBrowserFrameAura.
278 class TestNativeBrowserFrameFactory : public NativeBrowserFrameFactory {
279 public:
280 TestNativeBrowserFrameFactory() {}
281 ~TestNativeBrowserFrameFactory() override {}
283 NativeBrowserFrame* Create(BrowserFrame* browser_frame,
284 BrowserView* browser_view) override {
285 return new TestDesktopBrowserFrameAura(browser_frame, browser_view);
288 private:
289 DISALLOW_COPY_AND_ASSIGN(TestNativeBrowserFrameFactory);
292 class TabDragCaptureLostTest : public TabDragControllerTest {
293 public:
294 TabDragCaptureLostTest() {
295 NativeBrowserFrameFactory::Set(new TestNativeBrowserFrameFactory);
298 private:
299 DISALLOW_COPY_AND_ASSIGN(TabDragCaptureLostTest);
302 // See description above for details.
303 IN_PROC_BROWSER_TEST_F(TabDragCaptureLostTest, ReleaseCaptureOnDrag) {
304 AddTabAndResetBrowser(browser());
306 TabStrip* tab_strip = GetTabStripForBrowser(browser());
307 gfx::Point tab_1_center(GetCenterInScreenCoordinates(tab_strip->tab_at(1)));
308 ASSERT_TRUE(ui_test_utils::SendMouseMoveSync(tab_1_center) &&
309 ui_test_utils::SendMouseEventsSync(
310 ui_controls::LEFT, ui_controls::DOWN));
311 gfx::Point tab_0_center(GetCenterInScreenCoordinates(tab_strip->tab_at(0)));
312 TestDesktopBrowserFrameAura* frame =
313 static_cast<TestDesktopBrowserFrameAura*>(
314 BrowserView::GetBrowserViewForBrowser(browser())->GetWidget()->
315 native_widget_private());
316 // Invoke ReleaseCaptureOnDrag() so that when the drag happens and focus
317 // changes capture is released and the drag cancels.
318 frame->ReleaseCaptureOnNextClear();
319 ASSERT_TRUE(ui_test_utils::SendMouseMoveSync(tab_0_center));
320 EXPECT_FALSE(tab_strip->IsDragSessionActive());
323 IN_PROC_BROWSER_TEST_F(TabDragControllerTest, GestureEndShouldEndDragTest) {
324 AddTabAndResetBrowser(browser());
326 TabStrip* tab_strip = GetTabStripForBrowser(browser());
328 Tab* tab1 = tab_strip->tab_at(1);
329 gfx::Point tab_1_center(tab1->width() / 2, tab1->height() / 2);
331 ui::GestureEvent gesture_tap_down(
332 tab_1_center.x(),
333 tab_1_center.x(),
335 base::TimeDelta(),
336 ui::GestureEventDetails(ui::ET_GESTURE_TAP_DOWN));
337 tab_strip->MaybeStartDrag(tab1, gesture_tap_down,
338 tab_strip->GetSelectionModel());
339 EXPECT_TRUE(TabDragController::IsActive());
341 ui::GestureEvent gesture_end(tab_1_center.x(),
342 tab_1_center.x(),
344 base::TimeDelta(),
345 ui::GestureEventDetails(ui::ET_GESTURE_END));
346 tab_strip->OnGestureEvent(&gesture_end);
347 EXPECT_FALSE(TabDragController::IsActive());
348 EXPECT_FALSE(tab_strip->IsDragSessionActive());
351 #endif
353 class DetachToBrowserTabDragControllerTest
354 : public TabDragControllerTest,
355 public ::testing::WithParamInterface<const char*> {
356 public:
357 DetachToBrowserTabDragControllerTest() {}
359 void SetUpOnMainThread() override {
360 #if defined(OS_CHROMEOS)
361 event_generator_.reset(
362 new ui::test::EventGenerator(ash::Shell::GetPrimaryRootWindow()));
363 #endif
366 InputSource input_source() const {
367 return strstr(GetParam(), "mouse") ?
368 INPUT_SOURCE_MOUSE : INPUT_SOURCE_TOUCH;
371 // Set root window from a point in screen coordinates
372 void SetEventGeneratorRootWindow(const gfx::Point& point) {
373 if (input_source() == INPUT_SOURCE_MOUSE)
374 return;
375 #if defined(OS_CHROMEOS)
376 event_generator_.reset(new ui::test::EventGenerator(
377 new ScreenEventGeneratorDelegate(ash::wm::GetRootWindowAt(point))));
378 #endif
381 // The following methods update one of the mouse or touch input depending upon
382 // the InputSource.
383 bool PressInput(const gfx::Point& location) {
384 if (input_source() == INPUT_SOURCE_MOUSE) {
385 return ui_test_utils::SendMouseMoveSync(location) &&
386 ui_test_utils::SendMouseEventsSync(
387 ui_controls::LEFT, ui_controls::DOWN);
389 #if defined(OS_CHROMEOS)
390 event_generator_->set_current_location(location);
391 event_generator_->PressTouch();
392 #else
393 NOTREACHED();
394 #endif
395 return true;
398 bool PressInput2() {
399 // Second touch input is only used for touch sequence tests.
400 EXPECT_EQ(INPUT_SOURCE_TOUCH, input_source());
401 #if defined(OS_CHROMEOS)
402 event_generator_->set_current_location(
403 event_generator_->current_location());
404 event_generator_->PressTouchId(1);
405 #else
406 NOTREACHED();
407 #endif
408 return true;
411 bool DragInputTo(const gfx::Point& location) {
412 if (input_source() == INPUT_SOURCE_MOUSE)
413 return ui_test_utils::SendMouseMoveSync(location);
414 #if defined(OS_CHROMEOS)
415 event_generator_->MoveTouch(location);
416 #else
417 NOTREACHED();
418 #endif
419 return true;
422 bool DragInputToAsync(const gfx::Point& location) {
423 if (input_source() == INPUT_SOURCE_MOUSE)
424 return ui_controls::SendMouseMove(location.x(), location.y());
425 #if defined(OS_CHROMEOS)
426 event_generator_->MoveTouch(location);
427 #else
428 NOTREACHED();
429 #endif
430 return true;
433 bool DragInputToNotifyWhenDone(int x,
434 int y,
435 const base::Closure& task) {
436 if (input_source() == INPUT_SOURCE_MOUSE)
437 return ui_controls::SendMouseMoveNotifyWhenDone(x, y, task);
438 #if defined(OS_CHROMEOS)
439 base::MessageLoop::current()->PostTask(FROM_HERE, task);
440 event_generator_->MoveTouch(gfx::Point(x, y));
441 #else
442 NOTREACHED();
443 #endif
444 return true;
447 bool DragInputToDelayedNotifyWhenDone(int x,
448 int y,
449 const base::Closure& task,
450 base::TimeDelta delay) {
451 if (input_source() == INPUT_SOURCE_MOUSE)
452 return ui_controls::SendMouseMoveNotifyWhenDone(x, y, task);
453 #if defined(OS_CHROMEOS)
454 base::MessageLoop::current()->PostDelayedTask(FROM_HERE, task, delay);
455 event_generator_->MoveTouch(gfx::Point(x, y));
456 #else
457 NOTREACHED();
458 #endif
459 return true;
462 bool DragInput2ToNotifyWhenDone(int x,
463 int y,
464 const base::Closure& task) {
465 if (input_source() == INPUT_SOURCE_MOUSE)
466 return ui_controls::SendMouseMoveNotifyWhenDone(x, y, task);
467 #if defined(OS_CHROMEOS)
468 base::MessageLoop::current()->PostTask(FROM_HERE, task);
469 event_generator_->MoveTouchId(gfx::Point(x, y), 1);
470 #else
471 NOTREACHED();
472 #endif
473 return true;
476 bool ReleaseInput() {
477 if (input_source() == INPUT_SOURCE_MOUSE) {
478 return ui_test_utils::SendMouseEventsSync(
479 ui_controls::LEFT, ui_controls::UP);
481 #if defined(OS_CHROMEOS)
482 event_generator_->ReleaseTouch();
483 #else
484 NOTREACHED();
485 #endif
486 return true;
489 bool ReleaseInput2() {
490 if (input_source() == INPUT_SOURCE_MOUSE) {
491 return ui_test_utils::SendMouseEventsSync(
492 ui_controls::LEFT, ui_controls::UP);
494 #if defined(OS_CHROMEOS)
495 event_generator_->ReleaseTouchId(1);
496 #else
497 NOTREACHED();
498 #endif
499 return true;
502 bool ReleaseMouseAsync() {
503 return input_source() == INPUT_SOURCE_MOUSE &&
504 ui_controls::SendMouseEvents(ui_controls::LEFT, ui_controls::UP);
507 void QuitWhenNotDragging() {
508 if (input_source() == INPUT_SOURCE_MOUSE) {
509 // Schedule observer to quit message loop when done dragging. This has to
510 // be async so the message loop can run.
511 test::QuitWhenNotDraggingImpl();
512 base::MessageLoop::current()->Run();
513 } else {
514 // Touch events are sync, so we know we're not in a drag session. But some
515 // tests rely on the browser fully closing, which is async. So, run all
516 // pending tasks.
517 base::RunLoop run_loop;
518 run_loop.RunUntilIdle();
522 void AddBlankTabAndShow(Browser* browser) {
523 InProcessBrowserTest::AddBlankTabAndShow(browser);
526 Browser* browser() const { return InProcessBrowserTest::browser(); }
528 private:
529 #if defined(OS_CHROMEOS)
530 scoped_ptr<ui::test::EventGenerator> event_generator_;
531 #endif
533 DISALLOW_COPY_AND_ASSIGN(DetachToBrowserTabDragControllerTest);
536 // Creates a browser with two tabs, drags the second to the first.
537 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest, DragInSameWindow) {
538 // TODO(sky): this won't work with touch as it requires a long press.
539 if (input_source() == INPUT_SOURCE_TOUCH) {
540 VLOG(1) << "Test is DISABLED for touch input.";
541 return;
544 AddTabAndResetBrowser(browser());
546 TabStrip* tab_strip = GetTabStripForBrowser(browser());
547 TabStripModel* model = browser()->tab_strip_model();
549 gfx::Point tab_1_center(GetCenterInScreenCoordinates(tab_strip->tab_at(1)));
550 ASSERT_TRUE(PressInput(tab_1_center));
551 gfx::Point tab_0_center(GetCenterInScreenCoordinates(tab_strip->tab_at(0)));
552 ASSERT_TRUE(DragInputTo(tab_0_center));
553 ASSERT_TRUE(ReleaseInput());
554 EXPECT_EQ("1 0", IDString(model));
555 EXPECT_FALSE(TabDragController::IsActive());
556 EXPECT_FALSE(tab_strip->IsDragSessionActive());
558 // The tab strip should no longer have capture because the drag was ended and
559 // mouse/touch was released.
560 EXPECT_FALSE(tab_strip->GetWidget()->HasCapture());
563 namespace {
565 // Invoked from the nested message loop.
566 void DragToSeparateWindowStep2(DetachToBrowserTabDragControllerTest* test,
567 TabStrip* not_attached_tab_strip,
568 TabStrip* target_tab_strip) {
569 ASSERT_FALSE(not_attached_tab_strip->IsDragSessionActive());
570 ASSERT_FALSE(target_tab_strip->IsDragSessionActive());
571 ASSERT_TRUE(TabDragController::IsActive());
573 // Drag to target_tab_strip. This should stop the nested loop from dragging
574 // the window.
575 gfx::Point target_point(target_tab_strip->width() -1,
576 target_tab_strip->height() / 2);
577 views::View::ConvertPointToScreen(target_tab_strip, &target_point);
578 ASSERT_TRUE(test->DragInputToAsync(target_point));
581 } // namespace
583 #if defined(OS_CHROMEOS) || defined(OS_LINUX)
584 // TODO(sky,sad): Disabled as it fails due to resize locks with a real
585 // compositor. crbug.com/331924
586 #define MAYBE_DragToSeparateWindow DISABLED_DragToSeparateWindow
587 #else
588 #define MAYBE_DragToSeparateWindow DragToSeparateWindow
589 #endif
590 // Creates two browsers, drags from first into second.
591 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest,
592 MAYBE_DragToSeparateWindow) {
593 TabStrip* tab_strip = GetTabStripForBrowser(browser());
595 // Add another tab to browser().
596 AddTabAndResetBrowser(browser());
598 // Create another browser.
599 Browser* browser2 = CreateAnotherWindowBrowserAndRelayout();
600 TabStrip* tab_strip2 = GetTabStripForBrowser(browser2);
602 // Move to the first tab and drag it enough so that it detaches, but not
603 // enough that it attaches to browser2.
604 gfx::Point tab_0_center(GetCenterInScreenCoordinates(tab_strip->tab_at(0)));
605 ASSERT_TRUE(PressInput(tab_0_center));
606 ASSERT_TRUE(DragInputToNotifyWhenDone(
607 tab_0_center.x(), tab_0_center.y() + GetDetachY(tab_strip),
608 base::Bind(&DragToSeparateWindowStep2,
609 this, tab_strip, tab_strip2)));
610 QuitWhenNotDragging();
612 // Should now be attached to tab_strip2.
613 ASSERT_TRUE(tab_strip2->IsDragSessionActive());
614 ASSERT_FALSE(tab_strip->IsDragSessionActive());
615 ASSERT_TRUE(TabDragController::IsActive());
616 EXPECT_FALSE(GetIsDragged(browser()));
618 // Release mouse or touch, stopping the drag session.
619 ASSERT_TRUE(ReleaseInput());
620 ASSERT_FALSE(tab_strip2->IsDragSessionActive());
621 ASSERT_FALSE(tab_strip->IsDragSessionActive());
622 ASSERT_FALSE(TabDragController::IsActive());
623 EXPECT_EQ("100 0", IDString(browser2->tab_strip_model()));
624 EXPECT_EQ("1", IDString(browser()->tab_strip_model()));
625 EXPECT_FALSE(GetIsDragged(browser2));
627 // Both windows should not be maximized
628 EXPECT_FALSE(browser()->window()->IsMaximized());
629 EXPECT_FALSE(browser2->window()->IsMaximized());
631 // The tab strip should no longer have capture because the drag was ended and
632 // mouse/touch was released.
633 EXPECT_FALSE(tab_strip->GetWidget()->HasCapture());
634 EXPECT_FALSE(tab_strip2->GetWidget()->HasCapture());
637 namespace {
639 void DetachToOwnWindowStep2(DetachToBrowserTabDragControllerTest* test) {
640 if (test->input_source() == INPUT_SOURCE_TOUCH)
641 ASSERT_TRUE(test->ReleaseInput());
644 #if defined(OS_CHROMEOS)
645 bool IsWindowPositionManaged(aura::Window* window) {
646 return ash::wm::GetWindowState(window)->window_position_managed();
648 bool HasUserChangedWindowPositionOrSize(aura::Window* window) {
649 return ash::wm::GetWindowState(window)->bounds_changed_by_user();
651 #else
652 bool IsWindowPositionManaged(gfx::NativeWindow window) {
653 return true;
655 bool HasUserChangedWindowPositionOrSize(gfx::NativeWindow window) {
656 return false;
658 #endif
660 } // namespace
662 #if defined(OS_CHROMEOS) || defined(OS_LINUX)
663 // TODO(sky,sad): Disabled as it fails due to resize locks with a real
664 // compositor. crbug.com/331924
665 #define MAYBE_DetachToOwnWindow DISABLED_DetachToOwnWindow
666 #else
667 #define MAYBE_DetachToOwnWindow DetachToOwnWindow
668 #endif
669 // Drags from browser to separate window and releases mouse.
670 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest,
671 MAYBE_DetachToOwnWindow) {
672 const gfx::Rect initial_bounds(browser()->window()->GetBounds());
673 // Add another tab.
674 AddTabAndResetBrowser(browser());
675 TabStrip* tab_strip = GetTabStripForBrowser(browser());
677 // Move to the first tab and drag it enough so that it detaches.
678 gfx::Point tab_0_center(
679 GetCenterInScreenCoordinates(tab_strip->tab_at(0)));
680 ASSERT_TRUE(PressInput(tab_0_center));
681 ASSERT_TRUE(DragInputToNotifyWhenDone(
682 tab_0_center.x(), tab_0_center.y() + GetDetachY(tab_strip),
683 base::Bind(&DetachToOwnWindowStep2, this)));
684 if (input_source() == INPUT_SOURCE_MOUSE) {
685 ASSERT_TRUE(ReleaseMouseAsync());
686 QuitWhenNotDragging();
689 // Should no longer be dragging.
690 ASSERT_FALSE(tab_strip->IsDragSessionActive());
691 ASSERT_FALSE(TabDragController::IsActive());
693 // There should now be another browser.
694 ASSERT_EQ(2u, native_browser_list->size());
695 Browser* new_browser = native_browser_list->get(1);
696 ASSERT_TRUE(new_browser->window()->IsActive());
697 TabStrip* tab_strip2 = GetTabStripForBrowser(new_browser);
698 ASSERT_FALSE(tab_strip2->IsDragSessionActive());
700 EXPECT_EQ("0", IDString(new_browser->tab_strip_model()));
701 EXPECT_EQ("1", IDString(browser()->tab_strip_model()));
703 // The bounds of the initial window should not have changed.
704 EXPECT_EQ(initial_bounds.ToString(),
705 browser()->window()->GetBounds().ToString());
707 EXPECT_FALSE(GetIsDragged(browser()));
708 EXPECT_FALSE(GetIsDragged(new_browser));
709 // After this both windows should still be manageable.
710 EXPECT_TRUE(IsWindowPositionManaged(browser()->window()->GetNativeWindow()));
711 EXPECT_TRUE(IsWindowPositionManaged(
712 new_browser->window()->GetNativeWindow()));
714 // Both windows should not be maximized
715 EXPECT_FALSE(browser()->window()->IsMaximized());
716 EXPECT_FALSE(new_browser->window()->IsMaximized());
718 // The tab strip should no longer have capture because the drag was ended and
719 // mouse/touch was released.
720 EXPECT_FALSE(tab_strip->GetWidget()->HasCapture());
721 EXPECT_FALSE(tab_strip2->GetWidget()->HasCapture());
724 #if defined(OS_CHROMEOS) || defined(OS_LINUX)
725 // TODO(sky,sad): Disabled as it fails due to resize locks with a real
726 // compositor. crbug.com/331924
727 #define MAYBE_DetachToOwnWindowFromMaximizedWindow \
728 DISABLED_DetachToOwnWindowFromMaximizedWindow
729 #else
730 #define MAYBE_DetachToOwnWindowFromMaximizedWindow \
731 DetachToOwnWindowFromMaximizedWindow
732 #endif
733 // Drags from browser to a separate window and releases mouse.
734 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest,
735 MAYBE_DetachToOwnWindowFromMaximizedWindow) {
736 // Maximize the initial browser window.
737 browser()->window()->Maximize();
738 ASSERT_TRUE(browser()->window()->IsMaximized());
740 // Add another tab.
741 AddTabAndResetBrowser(browser());
742 TabStrip* tab_strip = GetTabStripForBrowser(browser());
744 // Move to the first tab and drag it enough so that it detaches.
745 gfx::Point tab_0_center(
746 GetCenterInScreenCoordinates(tab_strip->tab_at(0)));
747 ASSERT_TRUE(PressInput(tab_0_center));
748 ASSERT_TRUE(DragInputToNotifyWhenDone(
749 tab_0_center.x(), tab_0_center.y() + GetDetachY(tab_strip),
750 base::Bind(&DetachToOwnWindowStep2, this)));
751 if (input_source() == INPUT_SOURCE_MOUSE) {
752 ASSERT_TRUE(ReleaseMouseAsync());
753 QuitWhenNotDragging();
756 // Should no longer be dragging.
757 ASSERT_FALSE(tab_strip->IsDragSessionActive());
758 ASSERT_FALSE(TabDragController::IsActive());
760 // There should now be another browser.
761 ASSERT_EQ(2u, native_browser_list->size());
762 Browser* new_browser = native_browser_list->get(1);
763 ASSERT_TRUE(new_browser->window()->IsActive());
764 TabStrip* tab_strip2 = GetTabStripForBrowser(new_browser);
765 ASSERT_FALSE(tab_strip2->IsDragSessionActive());
767 EXPECT_EQ("0", IDString(new_browser->tab_strip_model()));
768 EXPECT_EQ("1", IDString(browser()->tab_strip_model()));
770 // The bounds of the initial window should not have changed.
771 EXPECT_TRUE(browser()->window()->IsMaximized());
773 EXPECT_FALSE(GetIsDragged(browser()));
774 EXPECT_FALSE(GetIsDragged(new_browser));
775 // After this both windows should still be manageable.
776 EXPECT_TRUE(IsWindowPositionManaged(browser()->window()->GetNativeWindow()));
777 EXPECT_TRUE(IsWindowPositionManaged(
778 new_browser->window()->GetNativeWindow()));
780 // The new window should be maximized.
781 EXPECT_TRUE(new_browser->window()->IsMaximized());
784 // Deletes a tab being dragged before the user moved enough to start a drag.
785 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest,
786 DeleteBeforeStartedDragging) {
787 // Add another tab.
788 AddTabAndResetBrowser(browser());
789 TabStrip* tab_strip = GetTabStripForBrowser(browser());
791 // Click on the first tab, but don't move it.
792 gfx::Point tab_0_center(GetCenterInScreenCoordinates(tab_strip->tab_at(0)));
793 ASSERT_TRUE(PressInput(tab_0_center));
795 // Should be dragging.
796 ASSERT_TRUE(tab_strip->IsDragSessionActive());
797 ASSERT_TRUE(TabDragController::IsActive());
799 // Delete the tab being dragged.
800 delete browser()->tab_strip_model()->GetWebContentsAt(0);
802 // Should have canceled dragging.
803 ASSERT_FALSE(tab_strip->IsDragSessionActive());
804 ASSERT_FALSE(TabDragController::IsActive());
806 EXPECT_EQ("1", IDString(browser()->tab_strip_model()));
807 EXPECT_FALSE(GetIsDragged(browser()));
810 #if defined(OS_CHROMEOS)
811 // TODO(sky,sad): Disabled as it fails due to resize locks with a real
812 // compositor. crbug.com/331924
813 #define MAYBE_DeleteTabWhileAttached DISABLED_DeleteTabWhileAttached
814 #else
815 #define MAYBE_DeleteTabWhileAttached DeleteTabWhileAttached
816 #endif
817 // Deletes a tab being dragged while still attached.
818 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest,
819 MAYBE_DeleteTabWhileAttached) {
820 // TODO(sky,sad): Disabled as it fails due to resize locks with a real
821 // compositor. crbug.com/331924
822 if (input_source() == INPUT_SOURCE_MOUSE) {
823 VLOG(1) << "Test is DISABLED for mouse input.";
824 return;
827 // Add another tab.
828 AddTabAndResetBrowser(browser());
829 TabStrip* tab_strip = GetTabStripForBrowser(browser());
831 // Click on the first tab and move it enough so that it starts dragging but is
832 // still attached.
833 gfx::Point tab_0_center(GetCenterInScreenCoordinates(tab_strip->tab_at(0)));
834 ASSERT_TRUE(PressInput(tab_0_center));
835 ASSERT_TRUE(DragInputTo(
836 gfx::Point(tab_0_center.x() + 20, tab_0_center.y())));
838 // Should be dragging.
839 ASSERT_TRUE(tab_strip->IsDragSessionActive());
840 ASSERT_TRUE(TabDragController::IsActive());
842 // Delete the tab being dragged.
843 delete browser()->tab_strip_model()->GetWebContentsAt(0);
845 // Should have canceled dragging.
846 ASSERT_FALSE(tab_strip->IsDragSessionActive());
847 ASSERT_FALSE(TabDragController::IsActive());
849 EXPECT_EQ("1", IDString(browser()->tab_strip_model()));
851 EXPECT_FALSE(GetIsDragged(browser()));
854 namespace {
856 void DeleteWhileDetachedStep2(WebContents* tab) {
857 delete tab;
860 } // namespace
862 #if defined(OS_CHROMEOS)
863 // TODO(sky,sad): Disabled as it fails due to resize locks with a real
864 // compositor. crbug.com/331924
865 #define MAYBE_DeleteTabWhileDetached DISABLED_DeleteTabWhileDetached
866 #else
867 #define MAYBE_DeleteTabWhileDetached DeleteTabWhileDetached
868 #endif
869 // Deletes a tab being dragged after dragging a tab so that a new window is
870 // created.
871 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest,
872 MAYBE_DeleteTabWhileDetached) {
873 // Add another tab.
874 AddTabAndResetBrowser(browser());
875 TabStrip* tab_strip = GetTabStripForBrowser(browser());
877 // Move to the first tab and drag it enough so that it detaches.
878 gfx::Point tab_0_center(GetCenterInScreenCoordinates(tab_strip->tab_at(0)));
879 WebContents* to_delete =
880 browser()->tab_strip_model()->GetWebContentsAt(0);
881 ASSERT_TRUE(PressInput(tab_0_center));
882 ASSERT_TRUE(DragInputToNotifyWhenDone(
883 tab_0_center.x(), tab_0_center.y() + GetDetachY(tab_strip),
884 base::Bind(&DeleteWhileDetachedStep2, to_delete)));
885 QuitWhenNotDragging();
887 // Should not be dragging.
888 ASSERT_FALSE(tab_strip->IsDragSessionActive());
889 ASSERT_FALSE(TabDragController::IsActive());
891 EXPECT_EQ("1", IDString(browser()->tab_strip_model()));
893 EXPECT_FALSE(GetIsDragged(browser()));
896 namespace {
898 void DeleteSourceDetachedStep2(WebContents* tab,
899 const BrowserList* browser_list) {
900 ASSERT_EQ(2u, browser_list->size());
901 Browser* new_browser = browser_list->get(1);
902 // This ends up closing the source window.
903 delete tab;
904 // Cancel the drag.
905 ui_controls::SendKeyPress(new_browser->window()->GetNativeWindow(),
906 ui::VKEY_ESCAPE, false, false, false, false);
909 } // namespace
911 #if defined(OS_CHROMEOS) || defined(OS_LINUX)
912 // TODO(sky,sad): Disabled as it fails due to resize locks with a real
913 // compositor. crbug.com/331924
914 #define MAYBE_DeleteSourceDetached DISABLED_DeleteSourceDetached
915 #else
916 #define MAYBE_DeleteSourceDetached DeleteSourceDetached
917 #endif
918 // Detaches a tab and while detached deletes a tab from the source so that the
919 // source window closes then presses escape to cancel the drag.
920 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest,
921 MAYBE_DeleteSourceDetached) {
922 // Add another tab.
923 AddTabAndResetBrowser(browser());
924 TabStrip* tab_strip = GetTabStripForBrowser(browser());
926 // Move to the first tab and drag it enough so that it detaches.
927 gfx::Point tab_0_center(GetCenterInScreenCoordinates(tab_strip->tab_at(0)));
928 WebContents* to_delete = browser()->tab_strip_model()->GetWebContentsAt(1);
929 ASSERT_TRUE(PressInput(tab_0_center));
930 ASSERT_TRUE(DragInputToNotifyWhenDone(
931 tab_0_center.x(), tab_0_center.y() + GetDetachY(tab_strip),
932 base::Bind(&DeleteSourceDetachedStep2, to_delete, native_browser_list)));
933 QuitWhenNotDragging();
935 // Should not be dragging.
936 ASSERT_EQ(1u, native_browser_list->size());
937 Browser* new_browser = native_browser_list->get(0);
938 ASSERT_FALSE(GetTabStripForBrowser(new_browser)->IsDragSessionActive());
939 ASSERT_FALSE(TabDragController::IsActive());
941 EXPECT_EQ("0", IDString(new_browser->tab_strip_model()));
943 EXPECT_FALSE(GetIsDragged(new_browser));
945 // Remaining browser window should not be maximized
946 EXPECT_FALSE(new_browser->window()->IsMaximized());
949 namespace {
951 void PressEscapeWhileDetachedStep2(const BrowserList* browser_list) {
952 ASSERT_EQ(2u, browser_list->size());
953 Browser* new_browser = browser_list->get(1);
954 ui_controls::SendKeyPress(
955 new_browser->window()->GetNativeWindow(), ui::VKEY_ESCAPE, false, false,
956 false, false);
959 } // namespace
961 #if defined(OS_CHROMEOS) || defined(OS_LINUX)
962 // TODO(sky,sad): Disabled as it fails due to resize locks with a real
963 // compositor. crbug.com/331924
964 #define MAYBE_PressEscapeWhileDetached DISABLED_PressEscapeWhileDetached
965 #else
966 #define MAYBE_PressEscapeWhileDetached PressEscapeWhileDetached
967 #endif
968 // This is disabled until NativeViewHost::Detach really detaches.
969 // Detaches a tab and while detached presses escape to revert the drag.
970 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest,
971 MAYBE_PressEscapeWhileDetached) {
972 // Add another tab.
973 AddTabAndResetBrowser(browser());
974 TabStrip* tab_strip = GetTabStripForBrowser(browser());
976 // Move to the first tab and drag it enough so that it detaches.
977 gfx::Point tab_0_center(GetCenterInScreenCoordinates(tab_strip->tab_at(0)));
978 ASSERT_TRUE(PressInput(tab_0_center));
979 ASSERT_TRUE(DragInputToNotifyWhenDone(
980 tab_0_center.x(), tab_0_center.y() + GetDetachY(tab_strip),
981 base::Bind(&PressEscapeWhileDetachedStep2, native_browser_list)));
982 QuitWhenNotDragging();
984 // Should not be dragging.
985 ASSERT_FALSE(tab_strip->IsDragSessionActive());
986 ASSERT_FALSE(TabDragController::IsActive());
988 // And there should only be one window.
989 EXPECT_EQ(1u, native_browser_list->size());
991 EXPECT_EQ("0 1", IDString(browser()->tab_strip_model()));
993 // Remaining browser window should not be maximized
994 EXPECT_FALSE(browser()->window()->IsMaximized());
996 // The tab strip should no longer have capture because the drag was ended and
997 // mouse/touch was released.
998 EXPECT_FALSE(tab_strip->GetWidget()->HasCapture());
1001 namespace {
1003 void DragAllStep2(DetachToBrowserTabDragControllerTest* test,
1004 const BrowserList* browser_list) {
1005 // Should only be one window.
1006 ASSERT_EQ(1u, browser_list->size());
1007 if (test->input_source() == INPUT_SOURCE_TOUCH) {
1008 ASSERT_TRUE(test->ReleaseInput());
1009 } else {
1010 ASSERT_TRUE(test->ReleaseMouseAsync());
1014 } // namespace
1016 #if defined(OS_CHROMEOS) || defined(OS_LINUX)
1017 // TODO(sky,sad): Disabled as it fails due to resize locks with a real
1018 // compositor. crbug.com/331924
1019 #define MAYBE_DragAll DISABLED_DragAll
1020 #else
1021 #define MAYBE_DragAll DragAll
1022 #endif
1023 // Selects multiple tabs and starts dragging the window.
1024 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest, MAYBE_DragAll) {
1025 // Add another tab.
1026 AddTabAndResetBrowser(browser());
1027 TabStrip* tab_strip = GetTabStripForBrowser(browser());
1028 browser()->tab_strip_model()->AddTabAtToSelection(0);
1029 browser()->tab_strip_model()->AddTabAtToSelection(1);
1031 // Move to the first tab and drag it enough so that it would normally
1032 // detach.
1033 gfx::Point tab_0_center(GetCenterInScreenCoordinates(tab_strip->tab_at(0)));
1034 ASSERT_TRUE(PressInput(tab_0_center));
1035 ASSERT_TRUE(DragInputToNotifyWhenDone(
1036 tab_0_center.x(), tab_0_center.y() + GetDetachY(tab_strip),
1037 base::Bind(&DragAllStep2, this, native_browser_list)));
1038 QuitWhenNotDragging();
1040 // Should not be dragging.
1041 ASSERT_FALSE(tab_strip->IsDragSessionActive());
1042 ASSERT_FALSE(TabDragController::IsActive());
1044 // And there should only be one window.
1045 EXPECT_EQ(1u, native_browser_list->size());
1047 EXPECT_EQ("0 1", IDString(browser()->tab_strip_model()));
1049 EXPECT_FALSE(GetIsDragged(browser()));
1051 // Remaining browser window should not be maximized
1052 EXPECT_FALSE(browser()->window()->IsMaximized());
1055 namespace {
1057 // Invoked from the nested message loop.
1058 void DragAllToSeparateWindowStep2(DetachToBrowserTabDragControllerTest* test,
1059 TabStrip* attached_tab_strip,
1060 TabStrip* target_tab_strip,
1061 const BrowserList* browser_list) {
1062 ASSERT_TRUE(attached_tab_strip->IsDragSessionActive());
1063 ASSERT_FALSE(target_tab_strip->IsDragSessionActive());
1064 ASSERT_TRUE(TabDragController::IsActive());
1065 ASSERT_EQ(2u, browser_list->size());
1067 // Drag to target_tab_strip. This should stop the nested loop from dragging
1068 // the window.
1069 gfx::Point target_point(target_tab_strip->width() - 1,
1070 target_tab_strip->height() / 2);
1071 views::View::ConvertPointToScreen(target_tab_strip, &target_point);
1072 ASSERT_TRUE(test->DragInputToAsync(target_point));
1075 } // namespace
1077 #if defined(OS_CHROMEOS) || defined(OS_LINUX)
1078 // TODO(sky,sad): Disabled as it fails due to resize locks with a real
1079 // compositor. crbug.com/331924
1080 #define MAYBE_DragAllToSeparateWindow DISABLED_DragAllToSeparateWindow
1081 #else
1082 #define MAYBE_DragAllToSeparateWindow DragAllToSeparateWindow
1083 #endif
1084 // Creates two browsers, selects all tabs in first and drags into second.
1085 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest,
1086 MAYBE_DragAllToSeparateWindow) {
1087 TabStrip* tab_strip = GetTabStripForBrowser(browser());
1089 // Add another tab to browser().
1090 AddTabAndResetBrowser(browser());
1092 // Create another browser.
1093 Browser* browser2 = CreateAnotherWindowBrowserAndRelayout();
1094 TabStrip* tab_strip2 = GetTabStripForBrowser(browser2);
1096 browser()->tab_strip_model()->AddTabAtToSelection(0);
1097 browser()->tab_strip_model()->AddTabAtToSelection(1);
1099 // Move to the first tab and drag it enough so that it detaches, but not
1100 // enough that it attaches to browser2.
1101 gfx::Point tab_0_center(
1102 GetCenterInScreenCoordinates(tab_strip->tab_at(0)));
1103 ASSERT_TRUE(PressInput(tab_0_center));
1104 ASSERT_TRUE(DragInputToNotifyWhenDone(
1105 tab_0_center.x(), tab_0_center.y() + GetDetachY(tab_strip),
1106 base::Bind(&DragAllToSeparateWindowStep2, this, tab_strip, tab_strip2,
1107 native_browser_list)));
1108 QuitWhenNotDragging();
1110 // Should now be attached to tab_strip2.
1111 ASSERT_TRUE(tab_strip2->IsDragSessionActive());
1112 ASSERT_TRUE(TabDragController::IsActive());
1113 ASSERT_EQ(1u, native_browser_list->size());
1115 // Release the mouse, stopping the drag session.
1116 ASSERT_TRUE(ReleaseInput());
1117 ASSERT_FALSE(tab_strip2->IsDragSessionActive());
1118 ASSERT_FALSE(TabDragController::IsActive());
1119 EXPECT_EQ("100 0 1", IDString(browser2->tab_strip_model()));
1121 EXPECT_FALSE(GetIsDragged(browser2));
1123 // Remaining browser window should not be maximized
1124 EXPECT_FALSE(browser2->window()->IsMaximized());
1127 namespace {
1129 // Invoked from the nested message loop.
1130 void DragAllToSeparateWindowAndCancelStep2(
1131 DetachToBrowserTabDragControllerTest* test,
1132 TabStrip* attached_tab_strip,
1133 TabStrip* target_tab_strip,
1134 const BrowserList* browser_list) {
1135 ASSERT_TRUE(attached_tab_strip->IsDragSessionActive());
1136 ASSERT_FALSE(target_tab_strip->IsDragSessionActive());
1137 ASSERT_TRUE(TabDragController::IsActive());
1138 ASSERT_EQ(2u, browser_list->size());
1140 // Drag to target_tab_strip. This should stop the nested loop from dragging
1141 // the window.
1142 gfx::Point target_point(target_tab_strip->width() - 1,
1143 target_tab_strip->height() / 2);
1144 views::View::ConvertPointToScreen(target_tab_strip, &target_point);
1145 ASSERT_TRUE(test->DragInputToAsync(target_point));
1148 } // namespace
1150 #if defined(OS_CHROMEOS) || defined(OS_LINUX)
1151 // TODO(sky,sad): Disabled as it fails due to resize locks with a real
1152 // compositor. crbug.com/331924
1153 #define MAYBE_DragAllToSeparateWindowAndCancel \
1154 DISABLED_DragAllToSeparateWindowAndCancel
1155 #else
1156 #define MAYBE_DragAllToSeparateWindowAndCancel DragAllToSeparateWindowAndCancel
1157 #endif
1158 // Creates two browsers, selects all tabs in first, drags into second, then hits
1159 // escape.
1160 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest,
1161 MAYBE_DragAllToSeparateWindowAndCancel) {
1162 TabStrip* tab_strip = GetTabStripForBrowser(browser());
1164 // Add another tab to browser().
1165 AddTabAndResetBrowser(browser());
1167 // Create another browser.
1168 Browser* browser2 = CreateAnotherWindowBrowserAndRelayout();
1169 TabStrip* tab_strip2 = GetTabStripForBrowser(browser2);
1171 browser()->tab_strip_model()->AddTabAtToSelection(0);
1172 browser()->tab_strip_model()->AddTabAtToSelection(1);
1174 // Move to the first tab and drag it enough so that it detaches, but not
1175 // enough that it attaches to browser2.
1176 gfx::Point tab_0_center(
1177 GetCenterInScreenCoordinates(tab_strip->tab_at(0)));
1178 ASSERT_TRUE(PressInput(tab_0_center));
1179 ASSERT_TRUE(DragInputToNotifyWhenDone(
1180 tab_0_center.x(), tab_0_center.y() + GetDetachY(tab_strip),
1181 base::Bind(&DragAllToSeparateWindowAndCancelStep2, this,
1182 tab_strip, tab_strip2, native_browser_list)));
1183 QuitWhenNotDragging();
1185 // Should now be attached to tab_strip2.
1186 ASSERT_TRUE(tab_strip2->IsDragSessionActive());
1187 ASSERT_TRUE(TabDragController::IsActive());
1188 ASSERT_EQ(1u, native_browser_list->size());
1190 // Cancel the drag.
1191 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
1192 browser2, ui::VKEY_ESCAPE, false, false, false, false));
1194 ASSERT_FALSE(tab_strip2->IsDragSessionActive());
1195 ASSERT_FALSE(TabDragController::IsActive());
1196 EXPECT_EQ("100 0 1", IDString(browser2->tab_strip_model()));
1198 // browser() will have been destroyed, but browser2 should remain.
1199 ASSERT_EQ(1u, native_browser_list->size());
1201 EXPECT_FALSE(GetIsDragged(browser2));
1203 // Remaining browser window should not be maximized
1204 EXPECT_FALSE(browser2->window()->IsMaximized());
1207 #if defined(OS_CHROMEOS) || defined(OS_LINUX) || defined(OS_WIN)
1208 // TODO(sky,sad): Disabled as it fails due to resize locks with a real
1209 // compositor. crbug.com/331924
1210 #define MAYBE_DragDirectlyToSecondWindow DISABLED_DragDirectlyToSecondWindow
1211 #else
1212 #define MAYBE_DragDirectlyToSecondWindow DragDirectlyToSecondWindow
1213 #endif
1214 // Creates two browsers, drags from first into the second in such a way that
1215 // no detaching should happen.
1216 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest,
1217 MAYBE_DragDirectlyToSecondWindow) {
1218 TabStrip* tab_strip = GetTabStripForBrowser(browser());
1220 // Add another tab to browser().
1221 AddTabAndResetBrowser(browser());
1223 // Create another browser.
1224 Browser* browser2 = CreateAnotherWindowBrowserAndRelayout();
1225 TabStrip* tab_strip2 = GetTabStripForBrowser(browser2);
1227 // Move the tabstrip down enough so that we can detach.
1228 gfx::Rect bounds(browser2->window()->GetBounds());
1229 bounds.Offset(0, 100);
1230 browser2->window()->SetBounds(bounds);
1232 // Move to the first tab and drag it enough so that it detaches, but not
1233 // enough that it attaches to browser2.
1234 gfx::Point tab_0_center(GetCenterInScreenCoordinates(tab_strip->tab_at(0)));
1235 ASSERT_TRUE(PressInput(tab_0_center));
1237 gfx::Point b2_location(5, 0);
1238 views::View::ConvertPointToScreen(tab_strip2, &b2_location);
1239 ASSERT_TRUE(DragInputTo(b2_location));
1241 // Should now be attached to tab_strip2.
1242 ASSERT_TRUE(tab_strip2->IsDragSessionActive());
1243 ASSERT_FALSE(tab_strip->IsDragSessionActive());
1244 ASSERT_TRUE(TabDragController::IsActive());
1246 // Release the mouse, stopping the drag session.
1247 ASSERT_TRUE(ReleaseInput());
1248 ASSERT_FALSE(tab_strip2->IsDragSessionActive());
1249 ASSERT_FALSE(tab_strip->IsDragSessionActive());
1250 ASSERT_FALSE(TabDragController::IsActive());
1251 EXPECT_EQ("0 100", IDString(browser2->tab_strip_model()));
1252 EXPECT_EQ("1", IDString(browser()->tab_strip_model()));
1254 EXPECT_FALSE(GetIsDragged(browser()));
1255 EXPECT_FALSE(GetIsDragged(browser2));
1257 // Both windows should not be maximized
1258 EXPECT_FALSE(browser()->window()->IsMaximized());
1259 EXPECT_FALSE(browser2->window()->IsMaximized());
1262 #if defined(OS_CHROMEOS) || defined(OS_LINUX)
1263 // TODO(sky,sad): Disabled as it fails due to resize locks with a real
1264 // compositor. crbug.com/331924
1265 #define MAYBE_DragSingleTabToSeparateWindow \
1266 DISABLED_DragSingleTabToSeparateWindow
1267 #else
1268 #define MAYBE_DragSingleTabToSeparateWindow DragSingleTabToSeparateWindow
1269 #endif
1270 // Creates two browsers, the first browser has a single tab and drags into the
1271 // second browser.
1272 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest,
1273 MAYBE_DragSingleTabToSeparateWindow) {
1274 TabStrip* tab_strip = GetTabStripForBrowser(browser());
1276 ResetIDs(browser()->tab_strip_model(), 0);
1278 // Create another browser.
1279 Browser* browser2 = CreateAnotherWindowBrowserAndRelayout();
1280 TabStrip* tab_strip2 = GetTabStripForBrowser(browser2);
1281 const gfx::Rect initial_bounds(browser2->window()->GetBounds());
1283 // Move to the first tab and drag it enough so that it detaches, but not
1284 // enough that it attaches to browser2.
1285 gfx::Point tab_0_center(
1286 GetCenterInScreenCoordinates(tab_strip->tab_at(0)));
1287 ASSERT_TRUE(PressInput(tab_0_center));
1288 ASSERT_TRUE(DragInputToNotifyWhenDone(
1289 tab_0_center.x(), tab_0_center.y() + GetDetachY(tab_strip),
1290 base::Bind(&DragAllToSeparateWindowStep2, this, tab_strip, tab_strip2,
1291 native_browser_list)));
1292 QuitWhenNotDragging();
1294 // Should now be attached to tab_strip2.
1295 ASSERT_TRUE(tab_strip2->IsDragSessionActive());
1296 ASSERT_TRUE(TabDragController::IsActive());
1297 ASSERT_EQ(1u, native_browser_list->size());
1299 // Release the mouse, stopping the drag session.
1300 ASSERT_TRUE(ReleaseInput());
1301 ASSERT_FALSE(tab_strip2->IsDragSessionActive());
1302 ASSERT_FALSE(TabDragController::IsActive());
1303 EXPECT_EQ("100 0", IDString(browser2->tab_strip_model()));
1305 EXPECT_FALSE(GetIsDragged(browser2));
1307 // Remaining browser window should not be maximized
1308 EXPECT_FALSE(browser2->window()->IsMaximized());
1310 // Make sure that the window is still managed and not user moved.
1311 EXPECT_TRUE(IsWindowPositionManaged(browser2->window()->GetNativeWindow()));
1312 EXPECT_FALSE(HasUserChangedWindowPositionOrSize(
1313 browser2->window()->GetNativeWindow()));
1314 // Also make sure that the drag to window position has not changed.
1315 EXPECT_EQ(initial_bounds.ToString(),
1316 browser2->window()->GetBounds().ToString());
1319 namespace {
1321 // Invoked from the nested message loop.
1322 void CancelOnNewTabWhenDraggingStep2(
1323 DetachToBrowserTabDragControllerTest* test,
1324 const BrowserList* browser_list) {
1325 ASSERT_TRUE(TabDragController::IsActive());
1326 ASSERT_EQ(2u, browser_list->size());
1328 // Add another tab. This should trigger exiting the nested loop.
1329 test->AddBlankTabAndShow(browser_list->GetLastActive());
1332 } // namespace
1334 #if defined(OS_CHROMEOS) || defined(OS_LINUX)
1335 // TODO(sky,sad): Disabled as it fails due to resize locks with a real
1336 // compositor. crbug.com/331924
1337 #define MAYBE_CancelOnNewTabWhenDragging DISABLED_CancelOnNewTabWhenDragging
1338 #else
1339 #define MAYBE_CancelOnNewTabWhenDragging CancelOnNewTabWhenDragging
1340 #endif
1341 // Adds another tab, detaches into separate window, adds another tab and
1342 // verifies the run loop ends.
1343 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest,
1344 MAYBE_CancelOnNewTabWhenDragging) {
1345 TabStrip* tab_strip = GetTabStripForBrowser(browser());
1347 // Add another tab to browser().
1348 AddTabAndResetBrowser(browser());
1350 // Move to the first tab and drag it enough so that it detaches.
1351 gfx::Point tab_0_center(
1352 GetCenterInScreenCoordinates(tab_strip->tab_at(0)));
1353 ASSERT_TRUE(PressInput(tab_0_center));
1354 ASSERT_TRUE(DragInputToNotifyWhenDone(
1355 tab_0_center.x(), tab_0_center.y() + GetDetachY(tab_strip),
1356 base::Bind(&CancelOnNewTabWhenDraggingStep2, this, native_browser_list)));
1357 QuitWhenNotDragging();
1359 // Should be two windows and not dragging.
1360 ASSERT_FALSE(TabDragController::IsActive());
1361 ASSERT_EQ(2u, native_browser_list->size());
1362 for (chrome::BrowserIterator it; !it.done(); it.Next()) {
1363 EXPECT_FALSE(GetIsDragged(*it));
1364 // Should not be maximized
1365 EXPECT_FALSE(it->window()->IsMaximized());
1369 #if defined(OS_CHROMEOS)
1370 // TODO(sky,sad): A number of tests below are disabled as they fail due to
1371 // resize locks with a real compositor. crbug.com/331924
1372 namespace {
1374 void DragInMaximizedWindowStep2(DetachToBrowserTabDragControllerTest* test,
1375 Browser* browser,
1376 TabStrip* tab_strip,
1377 const BrowserList* browser_list) {
1378 // There should be another browser.
1379 ASSERT_EQ(2u, browser_list->size());
1380 Browser* new_browser = browser_list->get(1);
1381 EXPECT_NE(browser, new_browser);
1382 ASSERT_TRUE(new_browser->window()->IsActive());
1383 TabStrip* tab_strip2 = GetTabStripForBrowser(new_browser);
1385 ASSERT_TRUE(tab_strip2->IsDragSessionActive());
1386 ASSERT_FALSE(tab_strip->IsDragSessionActive());
1388 // Both windows should be visible.
1389 EXPECT_TRUE(tab_strip->GetWidget()->IsVisible());
1390 EXPECT_TRUE(tab_strip2->GetWidget()->IsVisible());
1392 // Stops dragging.
1393 ASSERT_TRUE(test->ReleaseInput());
1396 } // namespace
1398 // Creates a browser with two tabs, maximizes it, drags the tab out.
1399 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest,
1400 DISABLED_DragInMaximizedWindow) {
1401 AddTabAndResetBrowser(browser());
1402 browser()->window()->Maximize();
1404 TabStrip* tab_strip = GetTabStripForBrowser(browser());
1406 // Move to the first tab and drag it enough so that it detaches.
1407 gfx::Point tab_0_center(
1408 GetCenterInScreenCoordinates(tab_strip->tab_at(0)));
1409 ASSERT_TRUE(PressInput(tab_0_center));
1410 ASSERT_TRUE(DragInputToNotifyWhenDone(
1411 tab_0_center.x(), tab_0_center.y() + GetDetachY(tab_strip),
1412 base::Bind(&DragInMaximizedWindowStep2, this, browser(), tab_strip,
1413 native_browser_list)));
1414 QuitWhenNotDragging();
1416 ASSERT_FALSE(TabDragController::IsActive());
1418 // Should be two browsers.
1419 ASSERT_EQ(2u, native_browser_list->size());
1420 Browser* new_browser = native_browser_list->get(1);
1421 ASSERT_TRUE(new_browser->window()->IsActive());
1423 EXPECT_TRUE(browser()->window()->GetNativeWindow()->IsVisible());
1424 EXPECT_TRUE(new_browser->window()->GetNativeWindow()->IsVisible());
1426 EXPECT_FALSE(GetIsDragged(browser()));
1427 EXPECT_FALSE(GetIsDragged(new_browser));
1429 // The source window should be maximized.
1430 EXPECT_TRUE(browser()->window()->IsMaximized());
1431 // The new window should be maximized.
1432 EXPECT_TRUE(new_browser->window()->IsMaximized());
1435 // Subclass of DetachToBrowserTabDragControllerTest that
1436 // creates multiple displays.
1437 class DetachToBrowserInSeparateDisplayTabDragControllerTest
1438 : public DetachToBrowserTabDragControllerTest {
1439 public:
1440 DetachToBrowserInSeparateDisplayTabDragControllerTest() {}
1441 virtual ~DetachToBrowserInSeparateDisplayTabDragControllerTest() {}
1443 void SetUpCommandLine(base::CommandLine* command_line) override {
1444 DetachToBrowserTabDragControllerTest::SetUpCommandLine(command_line);
1445 // Make screens sufficiently wide to host 2 browsers side by side.
1446 command_line->AppendSwitchASCII("ash-host-window-bounds",
1447 "0+0-600x600,601+0-600x600");
1450 private:
1451 DISALLOW_COPY_AND_ASSIGN(
1452 DetachToBrowserInSeparateDisplayTabDragControllerTest);
1455 // Subclass of DetachToBrowserTabDragControllerTest that runs tests only with
1456 // touch input.
1457 class DetachToBrowserTabDragControllerTestTouch
1458 : public DetachToBrowserTabDragControllerTest {
1459 public:
1460 DetachToBrowserTabDragControllerTestTouch() {}
1461 virtual ~DetachToBrowserTabDragControllerTestTouch() {}
1463 private:
1464 DISALLOW_COPY_AND_ASSIGN(DetachToBrowserTabDragControllerTestTouch);
1467 namespace {
1469 void DragSingleTabToSeparateWindowInSecondDisplayStep3(
1470 DetachToBrowserTabDragControllerTest* test) {
1471 ASSERT_TRUE(test->ReleaseInput());
1474 void DragSingleTabToSeparateWindowInSecondDisplayStep2(
1475 DetachToBrowserTabDragControllerTest* test,
1476 const gfx::Point& target_point) {
1477 ASSERT_TRUE(test->DragInputToNotifyWhenDone(
1478 target_point.x(), target_point.y(),
1479 base::Bind(&DragSingleTabToSeparateWindowInSecondDisplayStep3, test)));
1482 } // namespace
1484 // Drags from browser to a second display and releases input.
1485 IN_PROC_BROWSER_TEST_P(DetachToBrowserInSeparateDisplayTabDragControllerTest,
1486 DISABLED_DragSingleTabToSeparateWindowInSecondDisplay) {
1487 // Add another tab.
1488 AddTabAndResetBrowser(browser());
1489 TabStrip* tab_strip = GetTabStripForBrowser(browser());
1491 // Move to the first tab and drag it enough so that it detaches.
1492 // Then drag it to the final destination on the second screen.
1493 gfx::Point tab_0_center(GetCenterInScreenCoordinates(tab_strip->tab_at(0)));
1494 ASSERT_TRUE(PressInput(tab_0_center));
1495 ASSERT_TRUE(DragInputToNotifyWhenDone(
1496 tab_0_center.x(), tab_0_center.y() + GetDetachY(tab_strip),
1497 base::Bind(&DragSingleTabToSeparateWindowInSecondDisplayStep2,
1498 this, gfx::Point(600 + tab_0_center.x(),
1499 tab_0_center.y()
1500 + GetDetachY(tab_strip)))));
1501 QuitWhenNotDragging();
1503 // Should no longer be dragging.
1504 ASSERT_FALSE(tab_strip->IsDragSessionActive());
1505 ASSERT_FALSE(TabDragController::IsActive());
1507 // There should now be another browser.
1508 ASSERT_EQ(2u, native_browser_list->size());
1509 Browser* new_browser = native_browser_list->get(1);
1510 ASSERT_TRUE(new_browser->window()->IsActive());
1511 TabStrip* tab_strip2 = GetTabStripForBrowser(new_browser);
1512 ASSERT_FALSE(tab_strip2->IsDragSessionActive());
1514 // This other browser should be on the second screen (with mouse drag)
1515 // With the touch input the browser cannot be dragged from one screen
1516 // to another and the window stays on the first screen.
1517 if (input_source() == INPUT_SOURCE_MOUSE) {
1518 aura::Window::Windows roots = ash::Shell::GetAllRootWindows();
1519 ASSERT_EQ(2u, roots.size());
1520 aura::Window* second_root = roots[1];
1521 EXPECT_EQ(second_root,
1522 new_browser->window()->GetNativeWindow()->GetRootWindow());
1525 EXPECT_EQ("0", IDString(new_browser->tab_strip_model()));
1526 EXPECT_EQ("1", IDString(browser()->tab_strip_model()));
1528 // Both windows should not be maximized
1529 EXPECT_FALSE(browser()->window()->IsMaximized());
1530 EXPECT_FALSE(new_browser->window()->IsMaximized());
1533 namespace {
1535 // Invoked from the nested message loop.
1536 void DragTabToWindowInSeparateDisplayStep2(
1537 DetachToBrowserTabDragControllerTest* test,
1538 TabStrip* not_attached_tab_strip,
1539 TabStrip* target_tab_strip) {
1540 ASSERT_FALSE(not_attached_tab_strip->IsDragSessionActive());
1541 ASSERT_FALSE(target_tab_strip->IsDragSessionActive());
1542 ASSERT_TRUE(TabDragController::IsActive());
1544 // Drag to target_tab_strip. This should stop the nested loop from dragging
1545 // the window.
1546 gfx::Point target_point(
1547 GetCenterInScreenCoordinates(target_tab_strip->tab_at(0)));
1549 // Move it close to the beginning of the target tabstrip.
1550 target_point.set_x(
1551 target_point.x() - target_tab_strip->tab_at(0)->width() / 2 + 10);
1552 ASSERT_TRUE(test->DragInputToAsync(target_point));
1555 } // namespace
1557 // Drags from browser to another browser on a second display and releases input.
1558 IN_PROC_BROWSER_TEST_P(DetachToBrowserInSeparateDisplayTabDragControllerTest,
1559 DISABLED_DragTabToWindowInSeparateDisplay) {
1560 // Add another tab.
1561 AddTabAndResetBrowser(browser());
1562 TabStrip* tab_strip = GetTabStripForBrowser(browser());
1564 // Create another browser.
1565 Browser* browser2 = CreateBrowser(browser()->profile());
1566 TabStrip* tab_strip2 = GetTabStripForBrowser(browser2);
1567 ResetIDs(browser2->tab_strip_model(), 100);
1569 // Move the second browser to the second display.
1570 aura::Window::Windows roots = ash::Shell::GetAllRootWindows();
1571 ASSERT_EQ(2u, roots.size());
1572 aura::Window* second_root = roots[1];
1573 gfx::Rect work_area = gfx::Screen::GetNativeScreen()->GetDisplayNearestWindow(
1574 second_root).work_area();
1575 browser2->window()->SetBounds(work_area);
1576 EXPECT_EQ(second_root,
1577 browser2->window()->GetNativeWindow()->GetRootWindow());
1579 // Move to the first tab and drag it enough so that it detaches, but not
1580 // enough that it attaches to browser2.
1581 gfx::Point tab_0_center(GetCenterInScreenCoordinates(tab_strip->tab_at(0)));
1582 ASSERT_TRUE(PressInput(tab_0_center));
1583 ASSERT_TRUE(DragInputToNotifyWhenDone(
1584 tab_0_center.x(), tab_0_center.y() + GetDetachY(tab_strip),
1585 base::Bind(&DragTabToWindowInSeparateDisplayStep2,
1586 this, tab_strip, tab_strip2)));
1587 QuitWhenNotDragging();
1589 // Should now be attached to tab_strip2.
1590 ASSERT_TRUE(tab_strip2->IsDragSessionActive());
1591 ASSERT_FALSE(tab_strip->IsDragSessionActive());
1592 ASSERT_TRUE(TabDragController::IsActive());
1594 // Release the mouse, stopping the drag session.
1595 ASSERT_TRUE(ReleaseInput());
1596 ASSERT_FALSE(tab_strip2->IsDragSessionActive());
1597 ASSERT_FALSE(tab_strip->IsDragSessionActive());
1598 ASSERT_FALSE(TabDragController::IsActive());
1599 EXPECT_EQ("0 100", IDString(browser2->tab_strip_model()));
1600 EXPECT_EQ("1", IDString(browser()->tab_strip_model()));
1602 // Both windows should not be maximized
1603 EXPECT_FALSE(browser()->window()->IsMaximized());
1604 EXPECT_FALSE(browser2->window()->IsMaximized());
1607 // Drags from browser to another browser on a second display and releases input.
1608 IN_PROC_BROWSER_TEST_P(DetachToBrowserInSeparateDisplayTabDragControllerTest,
1609 DISABLED_DragTabToWindowOnSecondDisplay) {
1610 // Add another tab.
1611 AddTabAndResetBrowser(browser());
1612 TabStrip* tab_strip = GetTabStripForBrowser(browser());
1614 // Create another browser.
1615 Browser* browser2 = CreateBrowser(browser()->profile());
1616 TabStrip* tab_strip2 = GetTabStripForBrowser(browser2);
1617 ResetIDs(browser2->tab_strip_model(), 100);
1619 // Move both browsers to the second display.
1620 aura::Window::Windows roots = ash::Shell::GetAllRootWindows();
1621 ASSERT_EQ(2u, roots.size());
1622 aura::Window* second_root = roots[1];
1623 gfx::Rect work_area = gfx::Screen::GetNativeScreen()->GetDisplayNearestWindow(
1624 second_root).work_area();
1625 browser()->window()->SetBounds(work_area);
1627 // position both browser windows side by side on the second screen.
1628 gfx::Rect work_area2(work_area);
1629 work_area.set_width(work_area.width()/2);
1630 browser()->window()->SetBounds(work_area);
1631 work_area2.set_x(work_area2.x() + work_area2.width()/2);
1632 work_area2.set_width(work_area2.width()/2);
1633 browser2->window()->SetBounds(work_area2);
1634 EXPECT_EQ(second_root,
1635 browser()->window()->GetNativeWindow()->GetRootWindow());
1636 EXPECT_EQ(second_root,
1637 browser2->window()->GetNativeWindow()->GetRootWindow());
1639 // Move to the first tab and drag it enough so that it detaches, but not
1640 // enough that it attaches to browser2.
1641 // SetEventGeneratorRootWindow sets correct (second) RootWindow
1642 gfx::Point tab_0_center(GetCenterInScreenCoordinates(tab_strip->tab_at(0)));
1643 SetEventGeneratorRootWindow(tab_0_center);
1644 ASSERT_TRUE(PressInput(tab_0_center));
1645 ASSERT_TRUE(DragInputToNotifyWhenDone(
1646 tab_0_center.x(), tab_0_center.y() + GetDetachY(tab_strip),
1647 base::Bind(&DragTabToWindowInSeparateDisplayStep2,
1648 this, tab_strip, tab_strip2)));
1649 QuitWhenNotDragging();
1651 // Should now be attached to tab_strip2.
1652 ASSERT_TRUE(tab_strip2->IsDragSessionActive());
1653 ASSERT_FALSE(tab_strip->IsDragSessionActive());
1654 ASSERT_TRUE(TabDragController::IsActive());
1656 // Release the mouse, stopping the drag session.
1657 ASSERT_TRUE(ReleaseInput());
1658 ASSERT_FALSE(tab_strip2->IsDragSessionActive());
1659 ASSERT_FALSE(tab_strip->IsDragSessionActive());
1660 ASSERT_FALSE(TabDragController::IsActive());
1661 EXPECT_EQ("0 100", IDString(browser2->tab_strip_model()));
1662 EXPECT_EQ("1", IDString(browser()->tab_strip_model()));
1664 // Both windows should not be maximized
1665 EXPECT_FALSE(browser()->window()->IsMaximized());
1666 EXPECT_FALSE(browser2->window()->IsMaximized());
1669 // Drags from a maximized browser to another non-maximized browser on a second
1670 // display and releases input.
1671 IN_PROC_BROWSER_TEST_P(DetachToBrowserInSeparateDisplayTabDragControllerTest,
1672 DISABLED_DragMaxTabToNonMaxWindowInSeparateDisplay) {
1673 // Add another tab.
1674 AddTabAndResetBrowser(browser());
1675 browser()->window()->Maximize();
1676 TabStrip* tab_strip = GetTabStripForBrowser(browser());
1678 // Create another browser on the second display.
1679 aura::Window::Windows roots = ash::Shell::GetAllRootWindows();
1680 ASSERT_EQ(2u, roots.size());
1681 aura::Window* first_root = roots[0];
1682 aura::Window* second_root = roots[1];
1683 gfx::Rect work_area = gfx::Screen::GetNativeScreen()->GetDisplayNearestWindow(
1684 second_root).work_area();
1685 work_area.Inset(20, 20, 20, 60);
1686 Browser::CreateParams params(browser()->profile(),
1687 browser()->host_desktop_type());
1688 params.initial_show_state = ui::SHOW_STATE_NORMAL;
1689 params.initial_bounds = work_area;
1690 Browser* browser2 = new Browser(params);
1691 AddBlankTabAndShow(browser2);
1693 TabStrip* tab_strip2 = GetTabStripForBrowser(browser2);
1694 ResetIDs(browser2->tab_strip_model(), 100);
1696 EXPECT_EQ(second_root,
1697 browser2->window()->GetNativeWindow()->GetRootWindow());
1698 EXPECT_EQ(first_root,
1699 browser()->window()->GetNativeWindow()->GetRootWindow());
1700 EXPECT_EQ(2, tab_strip->tab_count());
1701 EXPECT_EQ(1, tab_strip2->tab_count());
1703 // Move to the first tab and drag it enough so that it detaches, but not
1704 // enough that it attaches to browser2.
1705 gfx::Point tab_0_center(GetCenterInScreenCoordinates(tab_strip->tab_at(0)));
1706 ASSERT_TRUE(PressInput(tab_0_center));
1707 ASSERT_TRUE(DragInputToNotifyWhenDone(
1708 tab_0_center.x(), tab_0_center.y() + GetDetachY(tab_strip),
1709 base::Bind(&DragTabToWindowInSeparateDisplayStep2,
1710 this, tab_strip, tab_strip2)));
1711 QuitWhenNotDragging();
1713 // Should now be attached to tab_strip2.
1714 ASSERT_TRUE(tab_strip2->IsDragSessionActive());
1715 ASSERT_FALSE(tab_strip->IsDragSessionActive());
1716 ASSERT_TRUE(TabDragController::IsActive());
1718 // Release the mouse, stopping the drag session.
1719 ASSERT_TRUE(ReleaseInput());
1721 // tab should have moved
1722 EXPECT_EQ(1, tab_strip->tab_count());
1723 EXPECT_EQ(2, tab_strip2->tab_count());
1725 ASSERT_FALSE(tab_strip2->IsDragSessionActive());
1726 ASSERT_FALSE(tab_strip->IsDragSessionActive());
1727 ASSERT_FALSE(TabDragController::IsActive());
1728 EXPECT_EQ("0 100", IDString(browser2->tab_strip_model()));
1729 EXPECT_EQ("1", IDString(browser()->tab_strip_model()));
1731 // Source browser should still be maximized, target should not
1732 EXPECT_TRUE(browser()->window()->IsMaximized());
1733 EXPECT_FALSE(browser2->window()->IsMaximized());
1736 // Drags from a restored browser to an immersive fullscreen browser on a
1737 // second display and releases input.
1738 IN_PROC_BROWSER_TEST_P(DetachToBrowserInSeparateDisplayTabDragControllerTest,
1739 DISABLED_DragTabToImmersiveBrowserOnSeparateDisplay) {
1740 // Add another tab.
1741 AddTabAndResetBrowser(browser());
1742 TabStrip* tab_strip = GetTabStripForBrowser(browser());
1744 // Create another browser.
1745 Browser* browser2 = CreateBrowser(browser()->profile());
1746 TabStrip* tab_strip2 = GetTabStripForBrowser(browser2);
1747 ResetIDs(browser2->tab_strip_model(), 100);
1749 // Move the second browser to the second display.
1750 aura::Window::Windows roots = ash::Shell::GetAllRootWindows();
1751 ASSERT_EQ(2u, roots.size());
1752 aura::Window* second_root = roots[1];
1753 gfx::Rect work_area = gfx::Screen::GetNativeScreen()->GetDisplayNearestWindow(
1754 second_root).work_area();
1755 browser2->window()->SetBounds(work_area);
1756 EXPECT_EQ(second_root,
1757 browser2->window()->GetNativeWindow()->GetRootWindow());
1759 // Put the second browser into immersive fullscreen.
1760 BrowserView* browser_view2 = BrowserView::GetBrowserViewForBrowser(browser2);
1761 ImmersiveModeController* immersive_controller2 =
1762 browser_view2->immersive_mode_controller();
1763 immersive_controller2->SetupForTest();
1764 chrome::ToggleFullscreenMode(browser2);
1765 ASSERT_TRUE(immersive_controller2->IsEnabled());
1766 ASSERT_FALSE(immersive_controller2->IsRevealed());
1767 ASSERT_TRUE(tab_strip2->IsImmersiveStyle());
1769 // Move to the first tab and drag it enough so that it detaches, but not
1770 // enough that it attaches to browser2.
1771 gfx::Point tab_0_center(GetCenterInScreenCoordinates(tab_strip->tab_at(0)));
1772 ASSERT_TRUE(PressInput(tab_0_center));
1773 ASSERT_TRUE(DragInputToNotifyWhenDone(
1774 tab_0_center.x(), tab_0_center.y() + GetDetachY(tab_strip),
1775 base::Bind(&DragTabToWindowInSeparateDisplayStep2,
1776 this, tab_strip, tab_strip2)));
1777 QuitWhenNotDragging();
1779 // Should now be attached to tab_strip2.
1780 ASSERT_TRUE(tab_strip2->IsDragSessionActive());
1781 ASSERT_FALSE(tab_strip->IsDragSessionActive());
1782 ASSERT_TRUE(TabDragController::IsActive());
1784 // browser2's top chrome should be revealed and the tab strip should be
1785 // at normal height while user is tragging tabs_strip2's tabs.
1786 ASSERT_TRUE(immersive_controller2->IsRevealed());
1787 ASSERT_FALSE(tab_strip2->IsImmersiveStyle());
1789 // Release the mouse, stopping the drag session.
1790 ASSERT_TRUE(ReleaseInput());
1791 ASSERT_FALSE(tab_strip2->IsDragSessionActive());
1792 ASSERT_FALSE(tab_strip->IsDragSessionActive());
1793 ASSERT_FALSE(TabDragController::IsActive());
1794 EXPECT_EQ("0 100", IDString(browser2->tab_strip_model()));
1795 EXPECT_EQ("1", IDString(browser()->tab_strip_model()));
1797 // Move the mouse off of browser2's top chrome.
1798 aura::Window* primary_root = roots[0];
1799 ASSERT_TRUE(ui_test_utils::SendMouseMoveSync(
1800 primary_root->GetBoundsInScreen().CenterPoint()));
1802 // The first browser window should not be in immersive fullscreen.
1803 // browser2 should still be in immersive fullscreen, but the top chrome should
1804 // no longer be revealed.
1805 BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser());
1806 EXPECT_FALSE(browser_view->immersive_mode_controller()->IsEnabled());
1808 EXPECT_TRUE(immersive_controller2->IsEnabled());
1809 EXPECT_FALSE(immersive_controller2->IsRevealed());
1810 EXPECT_TRUE(tab_strip2->IsImmersiveStyle());
1813 // Subclass of DetachToBrowserTabDragControllerTest that
1814 // creates multiple displays with different device scale factors.
1815 class DifferentDeviceScaleFactorDisplayTabDragControllerTest
1816 : public DetachToBrowserTabDragControllerTest {
1817 public:
1818 DifferentDeviceScaleFactorDisplayTabDragControllerTest() {}
1819 virtual ~DifferentDeviceScaleFactorDisplayTabDragControllerTest() {}
1821 void SetUpCommandLine(base::CommandLine* command_line) override {
1822 DetachToBrowserTabDragControllerTest::SetUpCommandLine(command_line);
1823 command_line->AppendSwitchASCII("ash-host-window-bounds",
1824 "400x400,0+400-800x800*2");
1827 float GetCursorDeviceScaleFactor() const {
1828 ash::test::CursorManagerTestApi cursor_test_api(
1829 ash::Shell::GetInstance()->cursor_manager());
1830 return cursor_test_api.GetCurrentCursor().device_scale_factor();
1833 private:
1834 DISALLOW_COPY_AND_ASSIGN(
1835 DifferentDeviceScaleFactorDisplayTabDragControllerTest);
1838 namespace {
1840 // The points where a tab is dragged in CursorDeviceScaleFactorStep.
1841 const struct DragPoint {
1842 int x;
1843 int y;
1844 } kDragPoints[] = {
1845 {300, 200},
1846 {399, 200},
1847 {500, 200},
1848 {400, 200},
1849 {300, 200},
1852 // The expected device scale factors before the cursor is moved to the
1853 // corresponding kDragPoints in CursorDeviceScaleFactorStep.
1854 const float kDeviceScaleFactorExpectations[] = {
1855 1.0f,
1856 1.0f,
1857 2.0f,
1858 2.0f,
1859 1.0f,
1862 static_assert(
1863 arraysize(kDragPoints) == arraysize(kDeviceScaleFactorExpectations),
1864 "kDragPoints and kDeviceScaleFactorExpectations must have the same "
1865 "number of elements");
1867 // Drags tab to |kDragPoints[index]|, then calls the next step function.
1868 void CursorDeviceScaleFactorStep(
1869 DifferentDeviceScaleFactorDisplayTabDragControllerTest* test,
1870 TabStrip* not_attached_tab_strip,
1871 size_t index) {
1872 ASSERT_FALSE(not_attached_tab_strip->IsDragSessionActive());
1873 ASSERT_TRUE(TabDragController::IsActive());
1875 if (index < arraysize(kDragPoints)) {
1876 EXPECT_EQ(kDeviceScaleFactorExpectations[index],
1877 test->GetCursorDeviceScaleFactor());
1878 const DragPoint p = kDragPoints[index];
1879 ASSERT_TRUE(test->DragInputToNotifyWhenDone(
1880 p.x, p.y, base::Bind(&CursorDeviceScaleFactorStep,
1881 test, not_attached_tab_strip, index + 1)));
1882 } else {
1883 // Finishes a serise of CursorDeviceScaleFactorStep calls and ends drag.
1884 EXPECT_EQ(1.0f, test->GetCursorDeviceScaleFactor());
1885 ASSERT_TRUE(ui_test_utils::SendMouseEventsSync(
1886 ui_controls::LEFT, ui_controls::UP));
1890 } // namespace
1892 // Verifies cursor's device scale factor is updated when a tab is moved across
1893 // displays with different device scale factors (http://crbug.com/154183).
1894 IN_PROC_BROWSER_TEST_P(DifferentDeviceScaleFactorDisplayTabDragControllerTest,
1895 DISABLED_CursorDeviceScaleFactor) {
1896 // Add another tab.
1897 AddTabAndResetBrowser(browser());
1898 TabStrip* tab_strip = GetTabStripForBrowser(browser());
1900 // Move the second browser to the second display.
1901 aura::Window::Windows roots = ash::Shell::GetAllRootWindows();
1902 ASSERT_EQ(2u, roots.size());
1904 // Move to the first tab and drag it enough so that it detaches.
1905 gfx::Point tab_0_center(GetCenterInScreenCoordinates(tab_strip->tab_at(0)));
1906 ASSERT_TRUE(PressInput(tab_0_center));
1907 ASSERT_TRUE(DragInputToNotifyWhenDone(
1908 tab_0_center.x(), tab_0_center.y() + GetDetachY(tab_strip),
1909 base::Bind(&CursorDeviceScaleFactorStep,
1910 this, tab_strip, 0)));
1911 QuitWhenNotDragging();
1914 namespace {
1916 class DetachToBrowserInSeparateDisplayAndCancelTabDragControllerTest
1917 : public TabDragControllerTest {
1918 public:
1919 DetachToBrowserInSeparateDisplayAndCancelTabDragControllerTest() {}
1921 void SetUpCommandLine(base::CommandLine* command_line) override {
1922 TabDragControllerTest::SetUpCommandLine(command_line);
1923 command_line->AppendSwitchASCII("ash-host-window-bounds",
1924 "0+0-250x250,251+0-250x250");
1927 bool Press(const gfx::Point& position) {
1928 return ui_test_utils::SendMouseMoveSync(position) &&
1929 ui_test_utils::SendMouseEventsSync(ui_controls::LEFT,
1930 ui_controls::DOWN);
1933 bool DragTabAndExecuteTaskWhenDone(const gfx::Point& position,
1934 const base::Closure& task) {
1935 return ui_controls::SendMouseMoveNotifyWhenDone(
1936 position.x(), position.y(), task);
1939 void QuitWhenNotDragging() {
1940 test::QuitWhenNotDraggingImpl();
1941 base::MessageLoop::current()->Run();
1944 private:
1945 DISALLOW_COPY_AND_ASSIGN(
1946 DetachToBrowserInSeparateDisplayAndCancelTabDragControllerTest);
1949 // Invoked from the nested message loop.
1950 void CancelDragTabToWindowInSeparateDisplayStep3(
1951 TabStrip* tab_strip,
1952 const BrowserList* browser_list) {
1953 ASSERT_FALSE(tab_strip->IsDragSessionActive());
1954 ASSERT_TRUE(TabDragController::IsActive());
1955 ASSERT_EQ(2u, browser_list->size());
1957 // Switching display mode should cancel the drag operation.
1958 ash::DisplayManager* display_manager =
1959 ash::Shell::GetInstance()->display_manager();
1960 display_manager->AddRemoveDisplay();
1963 // Invoked from the nested message loop.
1964 void CancelDragTabToWindowInSeparateDisplayStep2(
1965 DetachToBrowserInSeparateDisplayAndCancelTabDragControllerTest* test,
1966 TabStrip* tab_strip,
1967 aura::Window* current_root,
1968 gfx::Point final_destination,
1969 const BrowserList* browser_list) {
1970 ASSERT_FALSE(tab_strip->IsDragSessionActive());
1971 ASSERT_TRUE(TabDragController::IsActive());
1972 ASSERT_EQ(2u, browser_list->size());
1974 Browser* new_browser = browser_list->get(1);
1975 EXPECT_EQ(current_root,
1976 new_browser->window()->GetNativeWindow()->GetRootWindow());
1978 ASSERT_TRUE(test->DragTabAndExecuteTaskWhenDone(
1979 final_destination,
1980 base::Bind(&CancelDragTabToWindowInSeparateDisplayStep3,
1981 tab_strip, browser_list)));
1984 } // namespace
1986 // Drags from browser to a second display and releases input.
1987 IN_PROC_BROWSER_TEST_F(
1988 DetachToBrowserInSeparateDisplayAndCancelTabDragControllerTest,
1989 DISABLED_CancelDragTabToWindowIn2ndDisplay) {
1990 // Add another tab.
1991 AddTabAndResetBrowser(browser());
1992 TabStrip* tab_strip = GetTabStripForBrowser(browser());
1994 EXPECT_EQ("0 1", IDString(browser()->tab_strip_model()));
1996 // Move the second browser to the second display.
1997 aura::Window::Windows roots = ash::Shell::GetAllRootWindows();
1998 ASSERT_EQ(2u, roots.size());
1999 gfx::Point final_destination =
2000 gfx::Screen::GetNativeScreen()->GetDisplayNearestWindow(
2001 roots[1]).work_area().CenterPoint();
2003 // Move to the first tab and drag it enough so that it detaches, but not
2004 // enough to move to another display.
2005 gfx::Point tab_0_dst(GetCenterInScreenCoordinates(tab_strip->tab_at(0)));
2006 ASSERT_TRUE(Press(tab_0_dst));
2007 tab_0_dst.Offset(0, GetDetachY(tab_strip));
2008 ASSERT_TRUE(DragTabAndExecuteTaskWhenDone(
2009 tab_0_dst, base::Bind(&CancelDragTabToWindowInSeparateDisplayStep2,
2010 this, tab_strip, roots[0], final_destination,
2011 native_browser_list)));
2012 QuitWhenNotDragging();
2014 ASSERT_EQ(1u, native_browser_list->size());
2015 ASSERT_FALSE(tab_strip->IsDragSessionActive());
2016 ASSERT_FALSE(TabDragController::IsActive());
2017 EXPECT_EQ("0 1", IDString(browser()->tab_strip_model()));
2019 // Release the mouse
2020 ASSERT_TRUE(ui_test_utils::SendMouseEventsSync(
2021 ui_controls::LEFT, ui_controls::UP));
2024 // Drags from browser from a second display to primary and releases input.
2025 IN_PROC_BROWSER_TEST_F(
2026 DetachToBrowserInSeparateDisplayAndCancelTabDragControllerTest,
2027 DISABLED_CancelDragTabToWindowIn1stDisplay) {
2028 aura::Window::Windows roots = ash::Shell::GetAllRootWindows();
2029 ASSERT_EQ(2u, roots.size());
2031 // Add another tab.
2032 AddTabAndResetBrowser(browser());
2033 TabStrip* tab_strip = GetTabStripForBrowser(browser());
2035 EXPECT_EQ("0 1", IDString(browser()->tab_strip_model()));
2036 EXPECT_EQ(roots[0], browser()->window()->GetNativeWindow()->GetRootWindow());
2038 gfx::Rect work_area = gfx::Screen::GetNativeScreen()->
2039 GetDisplayNearestWindow(roots[1]).work_area();
2040 browser()->window()->SetBounds(work_area);
2041 EXPECT_EQ(roots[1], browser()->window()->GetNativeWindow()->GetRootWindow());
2043 // Move the second browser to the display.
2044 gfx::Point final_destination =
2045 gfx::Screen::GetNativeScreen()->GetDisplayNearestWindow(
2046 roots[0]).work_area().CenterPoint();
2048 // Move to the first tab and drag it enough so that it detaches, but not
2049 // enough to move to another display.
2050 gfx::Point tab_0_dst(GetCenterInScreenCoordinates(tab_strip->tab_at(0)));
2051 ASSERT_TRUE(Press(tab_0_dst));
2052 tab_0_dst.Offset(0, GetDetachY(tab_strip));
2053 ASSERT_TRUE(DragTabAndExecuteTaskWhenDone(
2054 tab_0_dst, base::Bind(&CancelDragTabToWindowInSeparateDisplayStep2,
2055 this, tab_strip, roots[1], final_destination,
2056 native_browser_list)));
2057 QuitWhenNotDragging();
2059 ASSERT_EQ(1u, native_browser_list->size());
2060 ASSERT_FALSE(tab_strip->IsDragSessionActive());
2061 ASSERT_FALSE(TabDragController::IsActive());
2062 EXPECT_EQ("0 1", IDString(browser()->tab_strip_model()));
2064 // Release the mouse
2065 ASSERT_TRUE(ui_test_utils::SendMouseEventsSync(
2066 ui_controls::LEFT, ui_controls::UP));
2069 namespace {
2071 void PressSecondFingerWhileDetachedStep2(
2072 DetachToBrowserTabDragControllerTest* test) {
2073 ASSERT_TRUE(TabDragController::IsActive());
2074 ASSERT_EQ(2u, test->native_browser_list->size());
2075 Browser* new_browser = test->native_browser_list->get(1);
2076 ASSERT_TRUE(new_browser->window()->IsActive());
2078 ASSERT_TRUE(test->PressInput2());
2081 } // namespace
2083 // Detaches a tab and while detached presses a second finger.
2084 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTestTouch,
2085 DISABLED_PressSecondFingerWhileDetached) {
2086 gfx::Rect bounds(browser()->window()->GetBounds());
2087 // Add another tab.
2088 AddTabAndResetBrowser(browser());
2089 TabStrip* tab_strip = GetTabStripForBrowser(browser());
2090 EXPECT_EQ("0 1", IDString(browser()->tab_strip_model()));
2092 // Move to the first tab and drag it enough so that it detaches.
2093 gfx::Point tab_0_center(
2094 GetCenterInScreenCoordinates(tab_strip->tab_at(0)));
2095 ASSERT_TRUE(PressInput(tab_0_center));
2096 ASSERT_TRUE(DragInputToDelayedNotifyWhenDone(
2097 tab_0_center.x(), tab_0_center.y() + GetDetachY(tab_strip),
2098 base::Bind(&PressSecondFingerWhileDetachedStep2, this),
2099 base::TimeDelta::FromMilliseconds(60)));
2100 QuitWhenNotDragging();
2102 // The drag should have been reverted.
2103 ASSERT_EQ(1u, native_browser_list->size());
2104 ASSERT_FALSE(tab_strip->IsDragSessionActive());
2105 ASSERT_FALSE(TabDragController::IsActive());
2106 EXPECT_EQ("0 1", IDString(browser()->tab_strip_model()));
2108 ASSERT_TRUE(ReleaseInput());
2109 ASSERT_TRUE(ReleaseInput2());
2112 #if defined(OS_CHROMEOS)
2114 namespace {
2116 void DetachToDockedWindowNextStep(
2117 DetachToBrowserTabDragControllerTest* test,
2118 const gfx::Point& target_point,
2119 int iteration) {
2120 ASSERT_EQ(2u, test->native_browser_list->size());
2121 Browser* new_browser = test->native_browser_list->get(1);
2122 ASSERT_TRUE(new_browser->window()->IsActive());
2124 if (!iteration) {
2125 ASSERT_TRUE(test->ReleaseInput());
2126 return;
2128 ASSERT_TRUE(test->DragInputToNotifyWhenDone(
2129 target_point.x(), target_point.y(),
2130 base::Bind(&DetachToDockedWindowNextStep,
2131 test,
2132 gfx::Point(target_point.x(), 1 + target_point.y()),
2133 iteration - 1)));
2136 } // namespace
2138 // Drags from browser to separate window, docks that window and releases mouse.
2139 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest,
2140 DISABLED_DetachToDockedWindowFromMaximizedWindow) {
2141 // Maximize the initial browser window.
2142 browser()->window()->Maximize();
2143 ASSERT_TRUE(browser()->window()->IsMaximized());
2145 // Add another tab.
2146 AddTabAndResetBrowser(browser());
2147 TabStrip* tab_strip = GetTabStripForBrowser(browser());
2149 // Move to the first tab and drag it enough so that it detaches.
2150 gfx::Point tab_0_center(
2151 GetCenterInScreenCoordinates(tab_strip->tab_at(0)));
2152 ASSERT_TRUE(PressInput(tab_0_center));
2154 // The following matches kMovesBeforeAdjust in snap_sizer.cc
2155 const int kNumIterations = 25 * 5 + 10;
2156 ASSERT_TRUE(DragInputToNotifyWhenDone(
2157 tab_0_center.x(), tab_0_center.y() + GetDetachY(tab_strip),
2158 base::Bind(&DetachToDockedWindowNextStep, this,
2159 gfx::Point(0, tab_0_center.y() + GetDetachY(tab_strip)),
2160 kNumIterations)));
2161 // Continue dragging enough times to go through snapping sequence and dock
2162 // the window.
2163 QuitWhenNotDragging();
2164 // Should no longer be dragging.
2165 ASSERT_FALSE(tab_strip->IsDragSessionActive());
2166 ASSERT_FALSE(TabDragController::IsActive());
2168 // There should now be another browser.
2169 ASSERT_EQ(2u, native_browser_list->size());
2170 Browser* new_browser = native_browser_list->get(1);
2171 ASSERT_TRUE(new_browser->window()->IsActive());
2172 TabStrip* tab_strip2 = GetTabStripForBrowser(new_browser);
2173 ASSERT_FALSE(tab_strip2->IsDragSessionActive());
2175 EXPECT_EQ("0", IDString(new_browser->tab_strip_model()));
2176 EXPECT_EQ("1", IDString(browser()->tab_strip_model()));
2178 // The bounds of the initial window should not have changed.
2179 EXPECT_TRUE(browser()->window()->IsMaximized());
2181 EXPECT_FALSE(GetIsDragged(browser()));
2182 EXPECT_FALSE(GetIsDragged(new_browser));
2183 // After this both windows should still be manageable.
2184 EXPECT_TRUE(IsWindowPositionManaged(browser()->window()->GetNativeWindow()));
2185 EXPECT_TRUE(IsWindowPositionManaged(
2186 new_browser->window()->GetNativeWindow()));
2188 ash::wm::WindowState* window_state =
2189 ash::wm::GetWindowState(new_browser->window()->GetNativeWindow());
2190 // The new window should not be maximized because it gets docked or snapped.
2191 EXPECT_FALSE(new_browser->window()->IsMaximized());
2192 // The new window should be docked and not snapped.
2193 EXPECT_TRUE(window_state->IsDocked());
2194 EXPECT_FALSE(window_state->IsSnapped());
2197 #endif // OS_CHROMEOS
2199 #endif
2201 #if defined(USE_ASH) && defined(OS_CHROMEOS) // TODO(win_ash,linux_ash)
2202 INSTANTIATE_TEST_CASE_P(TabDragging,
2203 DetachToBrowserInSeparateDisplayTabDragControllerTest,
2204 ::testing::Values("mouse", "touch"));
2205 INSTANTIATE_TEST_CASE_P(TabDragging,
2206 DifferentDeviceScaleFactorDisplayTabDragControllerTest,
2207 ::testing::Values("mouse"));
2208 INSTANTIATE_TEST_CASE_P(TabDragging,
2209 DetachToBrowserTabDragControllerTest,
2210 ::testing::Values("mouse", "touch"));
2211 INSTANTIATE_TEST_CASE_P(TabDragging,
2212 DetachToBrowserTabDragControllerTestTouch,
2213 ::testing::Values("touch"));
2214 #elif defined(USE_ASH)
2215 INSTANTIATE_TEST_CASE_P(TabDragging,
2216 DetachToBrowserTabDragControllerTest,
2217 ::testing::Values("mouse"));
2218 #endif