[go: nahoru, domu]

18e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang/*
28e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang * Copyright (C) 2015 The Android Open Source Project
38e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang *
48e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang * Licensed under the Apache License, Version 2.0 (the "License");
58e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang * you may not use this file except in compliance with the License.
68e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang * You may obtain a copy of the License at
78e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang *
88e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang *      http://www.apache.org/licenses/LICENSE-2.0
98e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang *
108e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang * Unless required by applicable law or agreed to in writing, software
118e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang * distributed under the License is distributed on an "AS IS" BASIS,
128e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang * See the License for the specific language governing permissions and
148e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang * limitations under the License.
158e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang */
168e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang
178e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhangpackage com.android.server.wm;
188e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang
1959a73ca331a786f95e08a99bbd16fbdf59280ae0Wale Ogunwaleimport static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT;
2059a73ca331a786f95e08a99bbd16fbdf59280ae0Wale Ogunwaleimport static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
2187b21722c2336490ecf8b66f6acfc46ce8cc6f46Chong Zhangimport static android.app.ActivityManager.RESIZE_MODE_USER;
226de2ae81ce0988625bcffc37475810a015e76ff9Chong Zhangimport static android.app.ActivityManager.RESIZE_MODE_USER_FORCED;
230bd180d8880b3d1b9677f154c034a2af840b4796Filip Gruszczynskiimport static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
24228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwaleimport static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
25cad05a0a1f6643d19a556ebacf70a0130a524d6dWale Ogunwaleimport static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
260bd180d8880b3d1b9677f154c034a2af840b4796Filip Gruszczynskiimport static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
270bd180d8880b3d1b9677f154c034a2af840b4796Filip Gruszczynskiimport static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TASK_POSITIONING;
280bd180d8880b3d1b9677f154c034a2af840b4796Filip Gruszczynskiimport static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
290bd180d8880b3d1b9677f154c034a2af840b4796Filip Gruszczynskiimport static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
300bd180d8880b3d1b9677f154c034a2af840b4796Filip Gruszczynskiimport static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
3157b6ccecc07274884b425839691fa04274b832bcFilip Gruszczynskiimport static com.android.server.wm.WindowManagerService.dipToPixel;
320b46f3c72c324bc9b8890ed9b81951bbeec70fddJorim Jaggiimport static com.android.server.wm.DragResizeMode.DRAG_RESIZE_MODE_FREEFORM;
33231b06e7d302762a2680fd5f15b41ec7848a439fWale Ogunwaleimport static com.android.server.wm.WindowState.MINIMUM_VISIBLE_HEIGHT_IN_DP;
34231b06e7d302762a2680fd5f15b41ec7848a439fWale Ogunwaleimport static com.android.server.wm.WindowState.MINIMUM_VISIBLE_WIDTH_IN_DP;
358e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang
368e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhangimport android.annotation.IntDef;
378e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhangimport android.graphics.Point;
388e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhangimport android.graphics.Rect;
398e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhangimport android.os.Looper;
408e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhangimport android.os.Process;
418e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhangimport android.os.RemoteException;
42cad05a0a1f6643d19a556ebacf70a0130a524d6dWale Ogunwaleimport android.os.Trace;
438e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhangimport android.util.DisplayMetrics;
448e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhangimport android.util.Slog;
450bd180d8880b3d1b9677f154c034a2af840b4796Filip Gruszczynskiimport android.view.BatchedInputEventReceiver;
464f52bc6f78085bc40110bce5cc485f715223556eWale Ogunwaleimport android.view.Choreographer;
478e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhangimport android.view.Display;
48228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwaleimport android.view.DisplayInfo;
498e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhangimport android.view.InputChannel;
508e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhangimport android.view.InputDevice;
518e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhangimport android.view.InputEvent;
528e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhangimport android.view.MotionEvent;
53228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwaleimport android.view.SurfaceControl;
548e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhangimport android.view.WindowManager;
558e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang
56228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwaleimport com.android.server.input.InputApplicationHandle;
57228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwaleimport com.android.server.input.InputWindowHandle;
58228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwaleimport com.android.server.wm.WindowManagerService.H;
59228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwale
60228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwaleimport java.lang.annotation.Retention;
61228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwaleimport java.lang.annotation.RetentionPolicy;
62228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwale
63228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwaleclass TaskPositioner implements DimLayer.DimLayerUser {
64bc5425cdb9b302fe4c746bd79de87f56dadb9955Jorim Jaggi    private static final String TAG_LOCAL = "TaskPositioner";
65bc5425cdb9b302fe4c746bd79de87f56dadb9955Jorim Jaggi    private static final String TAG = TAG_WITH_CLASS_NAME ? TAG_LOCAL : TAG_WM;
668e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang
67228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwale    // The margin the pointer position has to be within the side of the screen to be
68228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwale    // considered at the side of the screen.
6957b6ccecc07274884b425839691fa04274b832bcFilip Gruszczynski    static final int SIDE_MARGIN_DIP = 100;
70228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwale
718e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang    @IntDef(flag = true,
728e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang            value = {
738e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang                    CTRL_NONE,
748e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang                    CTRL_LEFT,
758e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang                    CTRL_RIGHT,
768e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang                    CTRL_TOP,
778e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang                    CTRL_BOTTOM
788e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang            })
798e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang    @Retention(RetentionPolicy.SOURCE)
808e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang    @interface CtrlType {}
818e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang
828e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang    private static final int CTRL_NONE   = 0x0;
838e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang    private static final int CTRL_LEFT   = 0x1;
848e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang    private static final int CTRL_RIGHT  = 0x2;
858e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang    private static final int CTRL_TOP    = 0x4;
868e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang    private static final int CTRL_BOTTOM = 0x8;
878e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang
8864b6b448694de6d65b8748c396e99dd83d216b1aFilip Gruszczynski    public static final float RESIZING_HINT_ALPHA = 0.5f;
8964b6b448694de6d65b8748c396e99dd83d216b1aFilip Gruszczynski
9064b6b448694de6d65b8748c396e99dd83d216b1aFilip Gruszczynski    public static final int RESIZING_HINT_DURATION_MS = 0;
9164b6b448694de6d65b8748c396e99dd83d216b1aFilip Gruszczynski
928e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang    private final WindowManagerService mService;
938e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang    private WindowPositionerEventReceiver mInputEventReceiver;
948e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang    private Display mDisplay;
958e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang    private final DisplayMetrics mDisplayMetrics = new DisplayMetrics();
96228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwale    private DimLayer mDimLayer;
97228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwale    @CtrlType
98228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwale    private int mCurrentDimSide;
99228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwale    private Rect mTmpRect = new Rect();
100228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwale    private int mSideMargin;
101b8051b8d0dfc69f334eaf717a43d76867d3f0f8cWale Ogunwale    private int mMinVisibleWidth;
102b8051b8d0dfc69f334eaf717a43d76867d3f0f8cWale Ogunwale    private int mMinVisibleHeight;
1038e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang
1043005e75585dcda30b64603e320e0711b583624ddChong Zhang    private Task mTask;
10509b21efb97d539543259b33e2da9d4c7a41966c8Chong Zhang    private boolean mResizing;
1068e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang    private final Rect mWindowOriginalBounds = new Rect();
1078e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang    private final Rect mWindowDragBounds = new Rect();
1088e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang    private float mStartDragX;
1098e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang    private float mStartDragY;
1108e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang    @CtrlType
1118e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang    private int mCtrlType = CTRL_NONE;
1126a804b815dc20f902ebac6598b3556912c94ed52Wale Ogunwale    private boolean mDragEnded = false;
1138e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang
1148e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang    InputChannel mServerChannel;
1158e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang    InputChannel mClientChannel;
1168e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang    InputApplicationHandle mDragApplicationHandle;
1178e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang    InputWindowHandle mDragWindowHandle;
1188e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang
1194f52bc6f78085bc40110bce5cc485f715223556eWale Ogunwale    private final class WindowPositionerEventReceiver extends BatchedInputEventReceiver {
1204f52bc6f78085bc40110bce5cc485f715223556eWale Ogunwale        public WindowPositionerEventReceiver(
1214f52bc6f78085bc40110bce5cc485f715223556eWale Ogunwale                InputChannel inputChannel, Looper looper, Choreographer choreographer) {
1224f52bc6f78085bc40110bce5cc485f715223556eWale Ogunwale            super(inputChannel, looper, choreographer);
1238e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang        }
1248e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang
1258e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang        @Override
1268e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang        public void onInputEvent(InputEvent event) {
1278e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang            if (!(event instanceof MotionEvent)
1288e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang                    || (event.getSource() & InputDevice.SOURCE_CLASS_POINTER) == 0) {
1298e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang                return;
1308e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang            }
1318e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang            final MotionEvent motionEvent = (MotionEvent) event;
1328e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang            boolean handled = false;
1338e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang
1348e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang            try {
1356a804b815dc20f902ebac6598b3556912c94ed52Wale Ogunwale                if (mDragEnded) {
1366a804b815dc20f902ebac6598b3556912c94ed52Wale Ogunwale                    // The drag has ended but the clean-up message has not been processed by
1376a804b815dc20f902ebac6598b3556912c94ed52Wale Ogunwale                    // window manager. Drop events that occur after this until window manager
1386a804b815dc20f902ebac6598b3556912c94ed52Wale Ogunwale                    // has a chance to clean-up the input handle.
1396a804b815dc20f902ebac6598b3556912c94ed52Wale Ogunwale                    handled = true;
1406a804b815dc20f902ebac6598b3556912c94ed52Wale Ogunwale                    return;
1416a804b815dc20f902ebac6598b3556912c94ed52Wale Ogunwale                }
1426a804b815dc20f902ebac6598b3556912c94ed52Wale Ogunwale
1438e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang                final float newX = motionEvent.getRawX();
1448e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang                final float newY = motionEvent.getRawY();
1458e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang
1468e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang                switch (motionEvent.getAction()) {
1478e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang                    case MotionEvent.ACTION_DOWN: {
1488e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang                        if (DEBUG_TASK_POSITIONING) {
1498e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang                            Slog.w(TAG, "ACTION_DOWN @ {" + newX + ", " + newY + "}");
1508e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang                        }
1518e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang                    } break;
1528e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang
1538e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang                    case MotionEvent.ACTION_MOVE: {
1548e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang                        if (DEBUG_TASK_POSITIONING){
1558e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang                            Slog.w(TAG, "ACTION_MOVE @ {" + newX + ", " + newY + "}");
1568e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang                        }
1578e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang                        synchronized (mService.mWindowMap) {
1586a804b815dc20f902ebac6598b3556912c94ed52Wale Ogunwale                            mDragEnded = notifyMoveLocked(newX, newY);
1594c9ba52acad52f1c1087415e04b2a17614707e40Chong Zhang                            mTask.getDimBounds(mTmpRect);
16004ad7b14987f16dc28a9cdcf07de22cb01a5ac95Wale Ogunwale                        }
16104ad7b14987f16dc28a9cdcf07de22cb01a5ac95Wale Ogunwale                        if (!mTmpRect.equals(mWindowDragBounds)) {
16204ad7b14987f16dc28a9cdcf07de22cb01a5ac95Wale Ogunwale                            Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER,
16304ad7b14987f16dc28a9cdcf07de22cb01a5ac95Wale Ogunwale                                    "wm.TaskPositioner.resizeTask");
16404ad7b14987f16dc28a9cdcf07de22cb01a5ac95Wale Ogunwale                            try {
16504ad7b14987f16dc28a9cdcf07de22cb01a5ac95Wale Ogunwale                                mService.mActivityManager.resizeTask(
16604ad7b14987f16dc28a9cdcf07de22cb01a5ac95Wale Ogunwale                                        mTask.mTaskId, mWindowDragBounds, RESIZE_MODE_USER);
16704ad7b14987f16dc28a9cdcf07de22cb01a5ac95Wale Ogunwale                            } catch (RemoteException e) {
16804ad7b14987f16dc28a9cdcf07de22cb01a5ac95Wale Ogunwale                            }
16904ad7b14987f16dc28a9cdcf07de22cb01a5ac95Wale Ogunwale                            Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
1708e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang                        }
1718e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang                    } break;
1728e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang
1738e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang                    case MotionEvent.ACTION_UP: {
1748e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang                        if (DEBUG_TASK_POSITIONING) {
1758e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang                            Slog.w(TAG, "ACTION_UP @ {" + newX + ", " + newY + "}");
1768e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang                        }
1776a804b815dc20f902ebac6598b3556912c94ed52Wale Ogunwale                        mDragEnded = true;
1788e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang                    } break;
1798e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang
1808e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang                    case MotionEvent.ACTION_CANCEL: {
1818e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang                        if (DEBUG_TASK_POSITIONING) {
1828e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang                            Slog.w(TAG, "ACTION_CANCEL @ {" + newX + ", " + newY + "}");
1838e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang                        }
1846a804b815dc20f902ebac6598b3556912c94ed52Wale Ogunwale                        mDragEnded = true;
1858e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang                    } break;
1868e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang                }
1878e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang
1886a804b815dc20f902ebac6598b3556912c94ed52Wale Ogunwale                if (mDragEnded) {
18904ad7b14987f16dc28a9cdcf07de22cb01a5ac95Wale Ogunwale                    final boolean wasResizing = mResizing;
1903005e75585dcda30b64603e320e0711b583624ddChong Zhang                    synchronized (mService.mWindowMap) {
1913005e75585dcda30b64603e320e0711b583624ddChong Zhang                        endDragLocked();
1923005e75585dcda30b64603e320e0711b583624ddChong Zhang                    }
19309b21efb97d539543259b33e2da9d4c7a41966c8Chong Zhang                    try {
19404ad7b14987f16dc28a9cdcf07de22cb01a5ac95Wale Ogunwale                        if (wasResizing) {
1953005e75585dcda30b64603e320e0711b583624ddChong Zhang                            // We were using fullscreen surface during resizing. Request
1963005e75585dcda30b64603e320e0711b583624ddChong Zhang                            // resizeTask() one last time to restore surface to window size.
1973005e75585dcda30b64603e320e0711b583624ddChong Zhang                            mService.mActivityManager.resizeTask(
1986de2ae81ce0988625bcffc37475810a015e76ff9Chong Zhang                                    mTask.mTaskId, mWindowDragBounds, RESIZE_MODE_USER_FORCED);
1993005e75585dcda30b64603e320e0711b583624ddChong Zhang                        }
2003005e75585dcda30b64603e320e0711b583624ddChong Zhang
2013005e75585dcda30b64603e320e0711b583624ddChong Zhang                        if (mCurrentDimSide != CTRL_NONE) {
2023005e75585dcda30b64603e320e0711b583624ddChong Zhang                            final int createMode = mCurrentDimSide == CTRL_LEFT
2033005e75585dcda30b64603e320e0711b583624ddChong Zhang                                    ? DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT
2043005e75585dcda30b64603e320e0711b583624ddChong Zhang                                    : DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT;
2053005e75585dcda30b64603e320e0711b583624ddChong Zhang                            mService.mActivityManager.moveTaskToDockedStack(
2069ea2f7ba3155a455724f64e2d6a964ad4e99dfa5Jorim Jaggi                                    mTask.mTaskId, createMode, true /*toTop*/, true /* animate */,
207a4d92a01521e560d00616b483143f2d07ebd755bWale Ogunwale                                    null /* initialBounds */, false /* moveHomeStackFront */);
2083005e75585dcda30b64603e320e0711b583624ddChong Zhang                        }
20909b21efb97d539543259b33e2da9d4c7a41966c8Chong Zhang                    } catch(RemoteException e) {}
2103005e75585dcda30b64603e320e0711b583624ddChong Zhang
2118e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang                    // Post back to WM to handle clean-ups. We still need the input
2128e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang                    // event handler for the last finishInputEvent()!
2138e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang                    mService.mH.sendEmptyMessage(H.FINISH_TASK_POSITIONING);
2148e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang                }
2158e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang                handled = true;
2168e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang            } catch (Exception e) {
2178e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang                Slog.e(TAG, "Exception caught by drag handleMotion", e);
2188e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang            } finally {
2198e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang                finishInputEvent(event, handled);
2208e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang            }
2218e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang        }
2228e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang    }
2238e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang
2248e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang    TaskPositioner(WindowManagerService service) {
2258e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang        mService = service;
2268e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang    }
2278e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang
2288e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang    /**
2298e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang     * @param display The Display that the window being dragged is on.
2308e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang     */
2318e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang    void register(Display display) {
2328e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang        if (DEBUG_TASK_POSITIONING) {
2338e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang            Slog.d(TAG, "Registering task positioner");
2348e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang        }
2358e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang
2368e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang        if (mClientChannel != null) {
2378e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang            Slog.e(TAG, "Task positioner already registered");
2388e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang            return;
2398e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang        }
2408e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang
2418e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang        mDisplay = display;
2428e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang        mDisplay.getMetrics(mDisplayMetrics);
2438e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang        final InputChannel[] channels = InputChannel.openInputChannelPair(TAG);
2448e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang        mServerChannel = channels[0];
2458e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang        mClientChannel = channels[1];
2468e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang        mService.mInputManager.registerInputChannel(mServerChannel, null);
2478e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang
2484f52bc6f78085bc40110bce5cc485f715223556eWale Ogunwale        mInputEventReceiver = new WindowPositionerEventReceiver(
2494f52bc6f78085bc40110bce5cc485f715223556eWale Ogunwale                mClientChannel, mService.mH.getLooper(), mService.mChoreographer);
2508e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang
2518e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang        mDragApplicationHandle = new InputApplicationHandle(null);
2528e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang        mDragApplicationHandle.name = TAG;
2538e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang        mDragApplicationHandle.dispatchingTimeoutNanos =
2548e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang                WindowManagerService.DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
2558e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang
2568e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang        mDragWindowHandle = new InputWindowHandle(mDragApplicationHandle, null,
2578e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang                mDisplay.getDisplayId());
2588e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang        mDragWindowHandle.name = TAG;
2598e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang        mDragWindowHandle.inputChannel = mServerChannel;
26057b6ccecc07274884b425839691fa04274b832bcFilip Gruszczynski        mDragWindowHandle.layer = mService.getDragLayerLocked();
2618e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang        mDragWindowHandle.layoutParamsFlags = 0;
2628e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang        mDragWindowHandle.layoutParamsType = WindowManager.LayoutParams.TYPE_DRAG;
2638e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang        mDragWindowHandle.dispatchingTimeoutNanos =
2648e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang                WindowManagerService.DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
2658e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang        mDragWindowHandle.visible = true;
2668e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang        mDragWindowHandle.canReceiveKeys = false;
2678e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang        mDragWindowHandle.hasFocus = true;
2688e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang        mDragWindowHandle.hasWallpaper = false;
2698e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang        mDragWindowHandle.paused = false;
2708e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang        mDragWindowHandle.ownerPid = Process.myPid();
2718e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang        mDragWindowHandle.ownerUid = Process.myUid();
2728e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang        mDragWindowHandle.inputFeatures = 0;
2738e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang        mDragWindowHandle.scaleFactor = 1.0f;
2748e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang
2758e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang        // The drag window cannot receive new touches.
2768e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang        mDragWindowHandle.touchableRegion.setEmpty();
2778e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang
2788e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang        // The drag window covers the entire display
2798e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang        mDragWindowHandle.frameLeft = 0;
2808e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang        mDragWindowHandle.frameTop = 0;
2818e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang        final Point p = new Point();
2828e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang        mDisplay.getRealSize(p);
2838e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang        mDragWindowHandle.frameRight = p.x;
2848e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang        mDragWindowHandle.frameBottom = p.y;
2858e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang
2868e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang        // Pause rotations before a drag.
2870bd180d8880b3d1b9677f154c034a2af840b4796Filip Gruszczynski        if (DEBUG_ORIENTATION) {
2888e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang            Slog.d(TAG, "Pausing rotation during re-position");
2898e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang        }
2908e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang        mService.pauseRotationLocked();
291228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwale
292bc5425cdb9b302fe4c746bd79de87f56dadb9955Jorim Jaggi        mDimLayer = new DimLayer(mService, this, mDisplay.getDisplayId(), TAG_LOCAL);
29357b6ccecc07274884b425839691fa04274b832bcFilip Gruszczynski        mSideMargin = dipToPixel(SIDE_MARGIN_DIP, mDisplayMetrics);
29457b6ccecc07274884b425839691fa04274b832bcFilip Gruszczynski        mMinVisibleWidth = dipToPixel(MINIMUM_VISIBLE_WIDTH_IN_DP, mDisplayMetrics);
29557b6ccecc07274884b425839691fa04274b832bcFilip Gruszczynski        mMinVisibleHeight = dipToPixel(MINIMUM_VISIBLE_HEIGHT_IN_DP, mDisplayMetrics);
2966a804b815dc20f902ebac6598b3556912c94ed52Wale Ogunwale
2976a804b815dc20f902ebac6598b3556912c94ed52Wale Ogunwale        mDragEnded = false;
2988e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang    }
2998e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang
3008e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang    void unregister() {
3018e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang        if (DEBUG_TASK_POSITIONING) {
3028e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang            Slog.d(TAG, "Unregistering task positioner");
3038e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang        }
3048e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang
3058e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang        if (mClientChannel == null) {
3068e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang            Slog.e(TAG, "Task positioner not registered");
3078e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang            return;
3088e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang        }
3098e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang
3108e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang        mService.mInputManager.unregisterInputChannel(mServerChannel);
3118e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang
3128e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang        mInputEventReceiver.dispose();
3138e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang        mInputEventReceiver = null;
3148e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang        mClientChannel.dispose();
3158e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang        mServerChannel.dispose();
3168e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang        mClientChannel = null;
3178e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang        mServerChannel = null;
3188e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang
3198e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang        mDragWindowHandle = null;
3208e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang        mDragApplicationHandle = null;
3218e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang        mDisplay = null;
3228e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang
323228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwale        if (mDimLayer != null) {
324228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwale            mDimLayer.destroySurface();
325228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwale            mDimLayer = null;
326228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwale        }
327228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwale        mCurrentDimSide = CTRL_NONE;
3286a804b815dc20f902ebac6598b3556912c94ed52Wale Ogunwale        mDragEnded = true;
329228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwale
3308e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang        // Resume rotations after a drag.
3310bd180d8880b3d1b9677f154c034a2af840b4796Filip Gruszczynski        if (DEBUG_ORIENTATION) {
3328e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang            Slog.d(TAG, "Resuming rotation after re-position");
3338e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang        }
3348e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang        mService.resumeRotationLocked();
3358e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang    }
3368e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang
3378e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang    void startDragLocked(WindowState win, boolean resize, float startX, float startY) {
338228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwale        if (DEBUG_TASK_POSITIONING) {
339228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwale            Slog.d(TAG, "startDragLocked: win=" + win + ", resize=" + resize
3408e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang                + ", {" + startX + ", " + startY + "}");
3418e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang        }
3428e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang        mCtrlType = CTRL_NONE;
343d8ceb85512f8dc2dac6ef07fc72f89a75095e3d7Chong Zhang        mTask = win.getTask();
344d8ceb85512f8dc2dac6ef07fc72f89a75095e3d7Chong Zhang        mStartDragX = startX;
345d8ceb85512f8dc2dac6ef07fc72f89a75095e3d7Chong Zhang        mStartDragY = startY;
346d8ceb85512f8dc2dac6ef07fc72f89a75095e3d7Chong Zhang
347b15758ab7a6481717d0d29612e870d7241061c31Chong Zhang        if (mTask.isDockedInEffect()) {
348b15758ab7a6481717d0d29612e870d7241061c31Chong Zhang            // If this is a docked task or if task size is affected by docked stack changing size,
349b15758ab7a6481717d0d29612e870d7241061c31Chong Zhang            // we can only be here if the task is not resizeable and we're handling a two-finger
350b15758ab7a6481717d0d29612e870d7241061c31Chong Zhang            // scrolling. Use the original task bounds to position the task, the dim bounds
351b15758ab7a6481717d0d29612e870d7241061c31Chong Zhang            // is cropped and doesn't move.
352b15758ab7a6481717d0d29612e870d7241061c31Chong Zhang            mTask.getBounds(mTmpRect);
353b15758ab7a6481717d0d29612e870d7241061c31Chong Zhang        } else {
354b15758ab7a6481717d0d29612e870d7241061c31Chong Zhang            // Use the dim bounds, not the original task bounds. The cursor
355b15758ab7a6481717d0d29612e870d7241061c31Chong Zhang            // movement should be calculated relative to the visible bounds.
356b15758ab7a6481717d0d29612e870d7241061c31Chong Zhang            // Also, use the dim bounds of the task which accounts for
357b15758ab7a6481717d0d29612e870d7241061c31Chong Zhang            // multiple app windows. Don't use any bounds from win itself as it
358b15758ab7a6481717d0d29612e870d7241061c31Chong Zhang            // may not be the same size as the task.
359b15758ab7a6481717d0d29612e870d7241061c31Chong Zhang            mTask.getDimBounds(mTmpRect);
360b15758ab7a6481717d0d29612e870d7241061c31Chong Zhang        }
361d8ceb85512f8dc2dac6ef07fc72f89a75095e3d7Chong Zhang
3628e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang        if (resize) {
363d8ceb85512f8dc2dac6ef07fc72f89a75095e3d7Chong Zhang            if (startX < mTmpRect.left) {
3648e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang                mCtrlType |= CTRL_LEFT;
3658e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang            }
366d8ceb85512f8dc2dac6ef07fc72f89a75095e3d7Chong Zhang            if (startX > mTmpRect.right) {
3678e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang                mCtrlType |= CTRL_RIGHT;
3688e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang            }
369d8ceb85512f8dc2dac6ef07fc72f89a75095e3d7Chong Zhang            if (startY < mTmpRect.top) {
3708e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang                mCtrlType |= CTRL_TOP;
3718e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang            }
372d8ceb85512f8dc2dac6ef07fc72f89a75095e3d7Chong Zhang            if (startY > mTmpRect.bottom) {
3738e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang                mCtrlType |= CTRL_BOTTOM;
3748e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang            }
37509b21efb97d539543259b33e2da9d4c7a41966c8Chong Zhang            mResizing = true;
3768e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang        }
3778e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang
378d8ceb85512f8dc2dac6ef07fc72f89a75095e3d7Chong Zhang        mWindowOriginalBounds.set(mTmpRect);
3793005e75585dcda30b64603e320e0711b583624ddChong Zhang    }
3803005e75585dcda30b64603e320e0711b583624ddChong Zhang
3813005e75585dcda30b64603e320e0711b583624ddChong Zhang    private void endDragLocked() {
3823005e75585dcda30b64603e320e0711b583624ddChong Zhang        mResizing = false;
3830b46f3c72c324bc9b8890ed9b81951bbeec70fddJorim Jaggi        mTask.setDragResizing(false, DRAG_RESIZE_MODE_FREEFORM);
3848e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang    }
3858e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang
386b8051b8d0dfc69f334eaf717a43d76867d3f0f8cWale Ogunwale    /** Returns true if the move operation should be ended. */
387b8051b8d0dfc69f334eaf717a43d76867d3f0f8cWale Ogunwale    private boolean notifyMoveLocked(float x, float y) {
3888e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang        if (DEBUG_TASK_POSITIONING) {
389b15758ab7a6481717d0d29612e870d7241061c31Chong Zhang            Slog.d(TAG, "notifyMoveLocked: {" + x + "," + y + "}");
3908e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang        }
3918e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang
3928e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang        if (mCtrlType != CTRL_NONE) {
3938e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang            // This is a resizing operation.
3948e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang            final int deltaX = Math.round(x - mStartDragX);
3958e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang            final int deltaY = Math.round(y - mStartDragY);
3968e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang            int left = mWindowOriginalBounds.left;
3978e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang            int top = mWindowOriginalBounds.top;
3988e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang            int right = mWindowOriginalBounds.right;
3998e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang            int bottom = mWindowOriginalBounds.bottom;
4008e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang            if ((mCtrlType & CTRL_LEFT) != 0) {
401b8051b8d0dfc69f334eaf717a43d76867d3f0f8cWale Ogunwale                left = Math.min(left + deltaX, right - mMinVisibleWidth);
4028e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang            }
4038e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang            if ((mCtrlType & CTRL_TOP) != 0) {
404b8051b8d0dfc69f334eaf717a43d76867d3f0f8cWale Ogunwale                top = Math.min(top + deltaY, bottom - mMinVisibleHeight);
4058e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang            }
4068e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang            if ((mCtrlType & CTRL_RIGHT) != 0) {
407b8051b8d0dfc69f334eaf717a43d76867d3f0f8cWale Ogunwale                right = Math.max(left + mMinVisibleWidth, right + deltaX);
4088e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang            }
4098e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang            if ((mCtrlType & CTRL_BOTTOM) != 0) {
410b8051b8d0dfc69f334eaf717a43d76867d3f0f8cWale Ogunwale                bottom = Math.max(top + mMinVisibleHeight, bottom + deltaY);
4118e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang            }
4128e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang            mWindowDragBounds.set(left, top, right, bottom);
4130b46f3c72c324bc9b8890ed9b81951bbeec70fddJorim Jaggi            mTask.setDragResizing(true, DRAG_RESIZE_MODE_FREEFORM);
414b8051b8d0dfc69f334eaf717a43d76867d3f0f8cWale Ogunwale            return false;
415228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwale        }
416b8051b8d0dfc69f334eaf717a43d76867d3f0f8cWale Ogunwale
417b8051b8d0dfc69f334eaf717a43d76867d3f0f8cWale Ogunwale        // This is a moving operation.
4184c9ba52acad52f1c1087415e04b2a17614707e40Chong Zhang        mTask.mStack.getDimBounds(mTmpRect);
419b15758ab7a6481717d0d29612e870d7241061c31Chong Zhang
420b15758ab7a6481717d0d29612e870d7241061c31Chong Zhang        // If this is a non-resizeable task put into side-by-side mode, we are
421b15758ab7a6481717d0d29612e870d7241061c31Chong Zhang        // handling a two-finger scrolling action. No need to shrink the bounds.
422b15758ab7a6481717d0d29612e870d7241061c31Chong Zhang        if (!mTask.isDockedInEffect()) {
423b15758ab7a6481717d0d29612e870d7241061c31Chong Zhang            mTmpRect.inset(mMinVisibleWidth, mMinVisibleHeight);
424b15758ab7a6481717d0d29612e870d7241061c31Chong Zhang        }
425b15758ab7a6481717d0d29612e870d7241061c31Chong Zhang
426b15758ab7a6481717d0d29612e870d7241061c31Chong Zhang        boolean dragEnded = false;
427b15758ab7a6481717d0d29612e870d7241061c31Chong Zhang        final int nX = (int) x;
428b15758ab7a6481717d0d29612e870d7241061c31Chong Zhang        final int nY = (int) y;
429b15758ab7a6481717d0d29612e870d7241061c31Chong Zhang        if (!mTmpRect.contains(nX, nY)) {
430b8051b8d0dfc69f334eaf717a43d76867d3f0f8cWale Ogunwale            // We end the moving operation if position is outside the stack bounds.
431b15758ab7a6481717d0d29612e870d7241061c31Chong Zhang            // In this case we need to clamp the position to stack bounds and calculate
432b15758ab7a6481717d0d29612e870d7241061c31Chong Zhang            // the final window drag bounds.
433b15758ab7a6481717d0d29612e870d7241061c31Chong Zhang            x = Math.min(Math.max(x, mTmpRect.left), mTmpRect.right);
434b15758ab7a6481717d0d29612e870d7241061c31Chong Zhang            y = Math.min(Math.max(y, mTmpRect.top), mTmpRect.bottom);
435b15758ab7a6481717d0d29612e870d7241061c31Chong Zhang            dragEnded = true;
436b8051b8d0dfc69f334eaf717a43d76867d3f0f8cWale Ogunwale        }
437b15758ab7a6481717d0d29612e870d7241061c31Chong Zhang
438b15758ab7a6481717d0d29612e870d7241061c31Chong Zhang        updateWindowDragBounds(nX, nY);
439b15758ab7a6481717d0d29612e870d7241061c31Chong Zhang        updateDimLayerVisibility(nX);
440b15758ab7a6481717d0d29612e870d7241061c31Chong Zhang        return dragEnded;
441b15758ab7a6481717d0d29612e870d7241061c31Chong Zhang    }
442b15758ab7a6481717d0d29612e870d7241061c31Chong Zhang
443b15758ab7a6481717d0d29612e870d7241061c31Chong Zhang    private void updateWindowDragBounds(int x, int y) {
444b8051b8d0dfc69f334eaf717a43d76867d3f0f8cWale Ogunwale        mWindowDragBounds.set(mWindowOriginalBounds);
445b15758ab7a6481717d0d29612e870d7241061c31Chong Zhang        if (mTask.isDockedInEffect()) {
446b15758ab7a6481717d0d29612e870d7241061c31Chong Zhang            // Offset the bounds without clamp, the bounds will be shifted later
447b15758ab7a6481717d0d29612e870d7241061c31Chong Zhang            // by window manager before applying the scrolling.
448b15758ab7a6481717d0d29612e870d7241061c31Chong Zhang            if (mService.mCurConfiguration.orientation == ORIENTATION_LANDSCAPE) {
449b15758ab7a6481717d0d29612e870d7241061c31Chong Zhang                mWindowDragBounds.offset(Math.round(x - mStartDragX), 0);
450b15758ab7a6481717d0d29612e870d7241061c31Chong Zhang            } else {
451b15758ab7a6481717d0d29612e870d7241061c31Chong Zhang                mWindowDragBounds.offset(0, Math.round(y - mStartDragY));
452b15758ab7a6481717d0d29612e870d7241061c31Chong Zhang            }
453b15758ab7a6481717d0d29612e870d7241061c31Chong Zhang        } else {
454b15758ab7a6481717d0d29612e870d7241061c31Chong Zhang            mWindowDragBounds.offset(Math.round(x - mStartDragX), Math.round(y - mStartDragY));
455b15758ab7a6481717d0d29612e870d7241061c31Chong Zhang        }
456b15758ab7a6481717d0d29612e870d7241061c31Chong Zhang        if (DEBUG_TASK_POSITIONING) Slog.d(TAG,
457b15758ab7a6481717d0d29612e870d7241061c31Chong Zhang                "updateWindowDragBounds: " + mWindowDragBounds);
458228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwale    }
459228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwale
460228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwale    private void updateDimLayerVisibility(int x) {
461228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwale        @CtrlType
462228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwale        int dimSide = getDimSide(x);
463228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwale        if (dimSide == mCurrentDimSide) {
464228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwale            return;
465228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwale        }
466228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwale
467228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwale        mCurrentDimSide = dimSide;
468228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwale
469228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwale        if (SHOW_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION updateDimLayerVisibility");
470228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwale        SurfaceControl.openTransaction();
471228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwale        if (mCurrentDimSide == CTRL_NONE) {
472228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwale            mDimLayer.hide();
473228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwale        } else {
474228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwale            showDimLayer();
475228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwale        }
476228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwale        SurfaceControl.closeTransaction();
477228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwale    }
478228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwale
479228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwale    /**
480228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwale     * Returns the side of the screen the dim layer should be shown.
481228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwale     * @param x horizontal coordinate used to determine if the dim layer should be shown
482228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwale     * @return Returns {@link #CTRL_LEFT} if the dim layer should be shown on the left half of the
483228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwale     * screen, {@link #CTRL_RIGHT} if on the right side, or {@link #CTRL_NONE} if the dim layer
484228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwale     * shouldn't be shown.
485228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwale     */
486228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwale    private int getDimSide(int x) {
4873005e75585dcda30b64603e320e0711b583624ddChong Zhang        if (mTask.mStack.mStackId != FREEFORM_WORKSPACE_STACK_ID
4883005e75585dcda30b64603e320e0711b583624ddChong Zhang                || !mTask.mStack.isFullscreen()
489228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwale                || mService.mCurConfiguration.orientation != ORIENTATION_LANDSCAPE) {
490228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwale            return CTRL_NONE;
491228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwale        }
492228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwale
4934c9ba52acad52f1c1087415e04b2a17614707e40Chong Zhang        mTask.mStack.getDimBounds(mTmpRect);
494228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwale        if (x - mSideMargin <= mTmpRect.left) {
495228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwale            return CTRL_LEFT;
496228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwale        }
497228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwale        if (x + mSideMargin >= mTmpRect.right) {
498228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwale            return CTRL_RIGHT;
499228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwale        }
500228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwale
501228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwale        return CTRL_NONE;
502228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwale    }
503228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwale
504228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwale    private void showDimLayer() {
5054c9ba52acad52f1c1087415e04b2a17614707e40Chong Zhang        mTask.mStack.getDimBounds(mTmpRect);
506228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwale        if (mCurrentDimSide == CTRL_LEFT) {
507228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwale            mTmpRect.right = mTmpRect.centerX();
508228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwale        } else if (mCurrentDimSide == CTRL_RIGHT) {
509228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwale            mTmpRect.left = mTmpRect.centerX();
5108e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang        }
511228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwale
512228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwale        mDimLayer.setBounds(mTmpRect);
51357b6ccecc07274884b425839691fa04274b832bcFilip Gruszczynski        mDimLayer.show(mService.getDragLayerLocked(), RESIZING_HINT_ALPHA,
51457b6ccecc07274884b425839691fa04274b832bcFilip Gruszczynski                RESIZING_HINT_DURATION_MS);
515228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwale    }
516228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwale
517228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwale    @Override /** {@link DimLayer.DimLayerUser} */
51829bfbb878d54db14204e9b02dc17bfc6e127b6b2Wale Ogunwale    public boolean dimFullscreen() {
51929bfbb878d54db14204e9b02dc17bfc6e127b6b2Wale Ogunwale        return isFullscreen();
52029bfbb878d54db14204e9b02dc17bfc6e127b6b2Wale Ogunwale    }
52129bfbb878d54db14204e9b02dc17bfc6e127b6b2Wale Ogunwale
52229bfbb878d54db14204e9b02dc17bfc6e127b6b2Wale Ogunwale    boolean isFullscreen() {
523228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwale        return false;
524228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwale    }
525228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwale
526228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwale    @Override /** {@link DimLayer.DimLayerUser} */
527228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwale    public DisplayInfo getDisplayInfo() {
5283005e75585dcda30b64603e320e0711b583624ddChong Zhang        return mTask.mStack.getDisplayInfo();
5298e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang    }
5308e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang
5310689ae903628f12ff073376b655b9d972533796bFilip Gruszczynski    @Override
5324c9ba52acad52f1c1087415e04b2a17614707e40Chong Zhang    public void getDimBounds(Rect out) {
5330689ae903628f12ff073376b655b9d972533796bFilip Gruszczynski        // This dim layer user doesn't need this.
5340689ae903628f12ff073376b655b9d972533796bFilip Gruszczynski    }
5350689ae903628f12ff073376b655b9d972533796bFilip Gruszczynski
5360689ae903628f12ff073376b655b9d972533796bFilip Gruszczynski    @Override
5370689ae903628f12ff073376b655b9d972533796bFilip Gruszczynski    public String toShortString() {
5380689ae903628f12ff073376b655b9d972533796bFilip Gruszczynski        return TAG;
5390689ae903628f12ff073376b655b9d972533796bFilip Gruszczynski    }
540228d40474dc74289e5796a28c8e4c0b1a7ead40cWale Ogunwale}
541