Exit desktop mode on dragging a task to the top of the screen.

This CL is part of the effort to implement desktop mode changes based on
drag gestures.

Bug: 247551213
Test: Drag a freeform task to the status bar area, confirm it exits
desktop mode for all tasks.

Change-Id: I44c147a4187466f98ab8f15e0bb050a56fbbe415
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
index e784261d..9edace1 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
@@ -188,14 +188,16 @@
             @ShellMainThread Choreographer mainChoreographer,
             ShellTaskOrganizer taskOrganizer,
             DisplayController displayController,
-            SyncTransactionQueue syncQueue) {
+            SyncTransactionQueue syncQueue,
+            @DynamicOverride DesktopModeController desktopModeController) {
         return new CaptionWindowDecorViewModel(
                         context,
                         mainHandler,
                         mainChoreographer,
                         taskOrganizer,
                         displayController,
-                        syncQueue);
+                        syncQueue,
+                        desktopModeController);
     }
 
     //
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeController.java
index 9474cfe..99739c4 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeController.java
@@ -177,6 +177,25 @@
     }
 
     /**
+     * Turn desktop mode on or off
+     * @param active the desired state for desktop mode setting
+     */
+    public void setDesktopModeActive(boolean active) {
+        int value = active ? 1 : 0;
+        Settings.System.putInt(mContext.getContentResolver(), Settings.System.DESKTOP_MODE, value);
+    }
+
+    /**
+     * Returns the windowing mode of the display area with the specified displayId.
+     * @param displayId
+     * @return
+     */
+    public int getDisplayAreaWindowingMode(int displayId) {
+        return mRootTaskDisplayAreaOrganizer.getDisplayAreaInfo(displayId)
+                .configuration.windowConfiguration.getWindowingMode();
+    }
+
+    /**
      * A {@link ContentObserver} for listening to changes to {@link Settings.System#DESKTOP_MODE}
      */
     private final class SettingsObserver extends ContentObserver {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java
index 9c7131a..5b37945 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java
@@ -36,6 +36,7 @@
 import com.android.wm.shell.ShellTaskOrganizer;
 import com.android.wm.shell.common.DisplayController;
 import com.android.wm.shell.common.SyncTransactionQueue;
+import com.android.wm.shell.desktopmode.DesktopModeController;
 import com.android.wm.shell.desktopmode.DesktopModeStatus;
 import com.android.wm.shell.freeform.FreeformTaskTransitionStarter;
 import com.android.wm.shell.transition.Transitions;
@@ -53,6 +54,7 @@
     private final DisplayController mDisplayController;
     private final SyncTransactionQueue mSyncQueue;
     private FreeformTaskTransitionStarter mTransitionStarter;
+    private DesktopModeController mDesktopModeController;
 
     public CaptionWindowDecorViewModel(
             Context context,
@@ -60,7 +62,8 @@
             Choreographer mainChoreographer,
             ShellTaskOrganizer taskOrganizer,
             DisplayController displayController,
-            SyncTransactionQueue syncQueue) {
+            SyncTransactionQueue syncQueue,
+            DesktopModeController desktopModeController) {
         mContext = context;
         mMainHandler = mainHandler;
         mMainChoreographer = mainChoreographer;
@@ -68,6 +71,7 @@
         mTaskOrganizer = taskOrganizer;
         mDisplayController = displayController;
         mSyncQueue = syncQueue;
+        mDesktopModeController = desktopModeController;
     }
 
     @Override
@@ -210,8 +214,10 @@
         }
 
         private void handleEventForMove(MotionEvent e) {
-            if (mTaskOrganizer.getRunningTaskInfo(mTaskId).getWindowingMode()
-                    == WINDOWING_MODE_FULLSCREEN) {
+            RunningTaskInfo taskInfo = mTaskOrganizer.getRunningTaskInfo(mTaskId);
+            int windowingMode =  mDesktopModeController
+                    .getDisplayAreaWindowingMode(taskInfo.displayId);
+            if (windowingMode == WINDOWING_MODE_FULLSCREEN) {
                 return;
             }
             switch (e.getActionMasked()) {
@@ -229,8 +235,14 @@
                 case MotionEvent.ACTION_UP:
                 case MotionEvent.ACTION_CANCEL: {
                     int dragPointerIdx = e.findPointerIndex(mDragPointerId);
+                    int statusBarHeight = mDisplayController.getDisplayLayout(taskInfo.displayId)
+                            .stableInsets().top;
                     mDragResizeCallback.onDragResizeEnd(
                             e.getRawX(dragPointerIdx), e.getRawY(dragPointerIdx));
+                    if (e.getRawY(dragPointerIdx) <= statusBarHeight
+                            && windowingMode == WINDOWING_MODE_FREEFORM) {
+                        mDesktopModeController.setDesktopModeActive(false);
+                    }
                     break;
                 }
             }