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