Cros splitscreen: Double tapping behavior.

Currently double tapping only works when there are two snapped windows,
and double tapping will swap these two windows' positions. This CL makes
the double tapping work for single snapped window case, i.e., the other
side of the screen is occupied by overview. Double tapping will swap the
position of the snapped window and the overview window grid.

Bug: 827422
Change-Id: I5c7208d6e10d76066ae531b9f9652631f4ec6818
Reviewed-on: https://chromium-review.googlesource.com/1003047
Commit-Queue: Xiaoqian Dai <xdai@chromium.org>
Reviewed-by: Mitsuru Oshima <oshima@chromium.org>
Cr-Commit-Position: refs/heads/master@{#549352}
diff --git a/ash/wm/overview/window_selector_unittest.cc b/ash/wm/overview/window_selector_unittest.cc
index 77a3e99..cebf52f 100644
--- a/ash/wm/overview/window_selector_unittest.cc
+++ b/ash/wm/overview/window_selector_unittest.cc
@@ -4266,4 +4266,36 @@
   EXPECT_TRUE(window4->layer()->GetTargetTransform().IsIdentity());
 }
 
+// Test that when split view and overview are both active at the same time,
+// double tapping on the divider can swap the window's position with the
+// overview window grid's postion.
+TEST_F(SplitViewWindowSelectorTest, SwapWindowAndOverviewGrid) {
+  const gfx::Rect bounds(0, 0, 400, 400);
+  std::unique_ptr<aura::Window> window1(CreateWindow(bounds));
+  std::unique_ptr<aura::Window> window2(CreateWindow(bounds));
+
+  ToggleOverview();
+  const int grid_index = 0;
+  WindowSelectorItem* selector_item1 =
+      GetWindowItemForWindow(grid_index, window1.get());
+  DragWindowTo(selector_item1, gfx::Point(0, 0));
+  EXPECT_EQ(split_view_controller()->state(),
+            SplitViewController::LEFT_SNAPPED);
+  EXPECT_EQ(split_view_controller()->default_snap_position(),
+            SplitViewController::LEFT);
+  EXPECT_TRUE(window_selector_controller()->IsSelecting());
+  EXPECT_EQ(GetGridBounds(),
+            split_view_controller()->GetSnappedWindowBoundsInScreen(
+                window1.get(), SplitViewController::RIGHT));
+
+  split_view_controller()->SwapWindows();
+  EXPECT_EQ(split_view_controller()->state(),
+            SplitViewController::RIGHT_SNAPPED);
+  EXPECT_EQ(split_view_controller()->default_snap_position(),
+            SplitViewController::RIGHT);
+  EXPECT_EQ(GetGridBounds(),
+            split_view_controller()->GetSnappedWindowBoundsInScreen(
+                window1.get(), SplitViewController::LEFT));
+}
+
 }  // namespace ash
diff --git a/ash/wm/splitview/split_view_controller.cc b/ash/wm/splitview/split_view_controller.cc
index 661ceec..09b059a 100644
--- a/ash/wm/splitview/split_view_controller.cc
+++ b/ash/wm/splitview/split_view_controller.cc
@@ -282,18 +282,20 @@
 }
 
 void SplitViewController::SwapWindows() {
-  if (state_ != BOTH_SNAPPED)
-    return;
-
-  DCHECK(left_window_ && right_window_);
+  DCHECK(IsSplitViewModeActive());
 
   aura::Window* new_left_window = right_window_;
   aura::Window* new_right_window = left_window_;
   left_window_ = new_left_window;
   right_window_ = new_right_window;
 
+  // Update |default_snap_position_| if necessary.
+  if (!left_window_ || !right_window_)
+    default_snap_position_ = left_window_ ? LEFT : RIGHT;
+
   MoveDividerToClosestFixedPosition();
   UpdateSnappedWindowsAndDividerBounds();
+  UpdateSplitViewStateAndNotifyObservers();
 
   base::RecordAction(
       base::UserMetricsAction("SplitView_DoubleTapDividerSwapWindows"));