diff options
| author | 2024-07-22 02:01:29 +0000 | |
|---|---|---|
| committer | 2024-07-22 02:01:29 +0000 | |
| commit | b93e18486056ac526c9492ae0379ea6f6824c5d9 (patch) | |
| tree | 49a9a2d0a3f42259ba79b0bab4abcc54904fe115 | |
| parent | 25277060780a6080a54e8daaaf3054a80c3423a6 (diff) | |
| parent | af553affa0130ba06182ced7eeb9ac4a67aa2042 (diff) | |
Merge "Remove server side task positioner" into main
7 files changed, 1 insertions, 1449 deletions
diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java index c26684f60731..cc95518cce39 100644 --- a/services/core/java/com/android/server/wm/Session.java +++ b/services/core/java/com/android/server/wm/Session.java @@ -39,7 +39,6 @@ import static android.view.WindowManager.LayoutParams.isSystemAlertWindowType; import static com.android.internal.protolog.ProtoLogGroup.WM_SHOW_TRANSACTIONS; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TASK_POSITIONING; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; import android.annotation.NonNull; @@ -537,27 +536,11 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient { @Override public boolean startMovingTask(IWindow window, float startX, float startY) { - if (DEBUG_TASK_POSITIONING) Slog.d( - TAG_WM, "startMovingTask: {" + startX + "," + startY + "}"); - - final long ident = Binder.clearCallingIdentity(); - try { - return mService.mTaskPositioningController.startMovingTask(window, startX, startY); - } finally { - Binder.restoreCallingIdentity(ident); - } + return false; } @Override public void finishMovingTask(IWindow window) { - if (DEBUG_TASK_POSITIONING) Slog.d(TAG_WM, "finishMovingTask"); - - final long ident = Binder.clearCallingIdentity(); - try { - mService.mTaskPositioningController.finishTaskPositioning(window); - } finally { - Binder.restoreCallingIdentity(ident); - } } @Override diff --git a/services/core/java/com/android/server/wm/TaskPositioner.java b/services/core/java/com/android/server/wm/TaskPositioner.java deleted file mode 100644 index 972dd2e382cc..000000000000 --- a/services/core/java/com/android/server/wm/TaskPositioner.java +++ /dev/null @@ -1,500 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.wm; - -import static android.app.ActivityTaskManager.RESIZE_MODE_USER; -import static android.app.ActivityTaskManager.RESIZE_MODE_USER_FORCED; -import static android.os.InputConstants.DEFAULT_DISPATCHING_TIMEOUT_MILLIS; -import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER; - -import static com.android.internal.policy.TaskResizingAlgorithm.CTRL_BOTTOM; -import static com.android.internal.policy.TaskResizingAlgorithm.CTRL_LEFT; -import static com.android.internal.policy.TaskResizingAlgorithm.CTRL_NONE; -import static com.android.internal.policy.TaskResizingAlgorithm.CTRL_RIGHT; -import static com.android.internal.policy.TaskResizingAlgorithm.CTRL_TOP; -import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_ORIENTATION; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TASK_POSITIONING; -import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; -import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; -import static com.android.server.wm.WindowManagerService.dipToPixel; -import static com.android.server.wm.WindowState.MINIMUM_VISIBLE_HEIGHT_IN_DP; -import static com.android.server.wm.WindowState.MINIMUM_VISIBLE_WIDTH_IN_DP; - -import static java.util.concurrent.CompletableFuture.completedFuture; - -import android.annotation.NonNull; -import android.graphics.Point; -import android.graphics.Rect; -import android.os.Binder; -import android.os.IBinder; -import android.os.InputConfig; -import android.os.RemoteException; -import android.os.Trace; -import android.util.DisplayMetrics; -import android.util.Slog; -import android.view.BatchedInputEventReceiver; -import android.view.InputApplicationHandle; -import android.view.InputChannel; -import android.view.InputDevice; -import android.view.InputEvent; -import android.view.InputEventReceiver; -import android.view.InputWindowHandle; -import android.view.MotionEvent; -import android.view.WindowManager; - -import com.android.internal.annotations.VisibleForTesting; -import com.android.internal.policy.TaskResizingAlgorithm; -import com.android.internal.policy.TaskResizingAlgorithm.CtrlType; -import com.android.internal.protolog.ProtoLog; - -import java.util.concurrent.CompletableFuture; - -class TaskPositioner implements IBinder.DeathRecipient { - private static final boolean DEBUG_ORIENTATION_VIOLATIONS = false; - private static final String TAG_LOCAL = "TaskPositioner"; - private static final String TAG = TAG_WITH_CLASS_NAME ? TAG_LOCAL : TAG_WM; - - private static Factory sFactory; - - public static final float RESIZING_HINT_ALPHA = 0.5f; - - public static final int RESIZING_HINT_DURATION_MS = 0; - - private final WindowManagerService mService; - private InputEventReceiver mInputEventReceiver; - private DisplayContent mDisplayContent; - private Rect mTmpRect = new Rect(); - private int mMinVisibleWidth; - private int mMinVisibleHeight; - - @VisibleForTesting - Task mTask; - WindowState mWindow; - private boolean mResizing; - private boolean mPreserveOrientation; - private boolean mStartOrientationWasLandscape; - private final Rect mWindowOriginalBounds = new Rect(); - private final Rect mWindowDragBounds = new Rect(); - private final Point mMaxVisibleSize = new Point(); - private float mStartDragX; - private float mStartDragY; - @CtrlType - private int mCtrlType = CTRL_NONE; - @VisibleForTesting - boolean mDragEnded; - IBinder mClientCallback; - - InputChannel mClientChannel; - InputApplicationHandle mDragApplicationHandle; - InputWindowHandle mDragWindowHandle; - - /** Use {@link #create(WindowManagerService)} instead. */ - @VisibleForTesting - TaskPositioner(WindowManagerService service) { - mService = service; - } - - private boolean onInputEvent(InputEvent event) { - // All returns need to be in the try block to make sure the finishInputEvent is - // called correctly. - if (!(event instanceof MotionEvent) - || (event.getSource() & InputDevice.SOURCE_CLASS_POINTER) == 0) { - return false; - } - final MotionEvent motionEvent = (MotionEvent) event; - if (mDragEnded) { - // The drag has ended but the clean-up message has not been processed by - // window manager. Drop events that occur after this until window manager - // has a chance to clean-up the input handle. - return true; - } - - final float newX = motionEvent.getRawX(); - final float newY = motionEvent.getRawY(); - - switch (motionEvent.getAction()) { - case MotionEvent.ACTION_DOWN: { - if (DEBUG_TASK_POSITIONING) { - Slog.w(TAG, "ACTION_DOWN @ {" + newX + ", " + newY + "}"); - } - } - break; - - case MotionEvent.ACTION_MOVE: { - if (DEBUG_TASK_POSITIONING) { - Slog.w(TAG, "ACTION_MOVE @ {" + newX + ", " + newY + "}"); - } - synchronized (mService.mGlobalLock) { - mDragEnded = notifyMoveLocked(newX, newY); - mTask.getDimBounds(mTmpRect); - } - if (!mTmpRect.equals(mWindowDragBounds)) { - Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, - "wm.TaskPositioner.resizeTask"); - mService.mAtmService.resizeTask( - mTask.mTaskId, mWindowDragBounds, RESIZE_MODE_USER); - Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER); - } - } - break; - - case MotionEvent.ACTION_UP: { - if (DEBUG_TASK_POSITIONING) { - Slog.w(TAG, "ACTION_UP @ {" + newX + ", " + newY + "}"); - } - mDragEnded = true; - } - break; - - case MotionEvent.ACTION_CANCEL: { - if (DEBUG_TASK_POSITIONING) { - Slog.w(TAG, "ACTION_CANCEL @ {" + newX + ", " + newY + "}"); - } - mDragEnded = true; - } - break; - } - - if (mDragEnded) { - final boolean wasResizing = mResizing; - synchronized (mService.mGlobalLock) { - endDragLocked(); - mTask.getDimBounds(mTmpRect); - } - if (wasResizing && !mTmpRect.equals(mWindowDragBounds)) { - // We were using fullscreen surface during resizing. Request - // resizeTask() one last time to restore surface to window size. - mService.mAtmService.resizeTask( - mTask.mTaskId, mWindowDragBounds, RESIZE_MODE_USER_FORCED); - } - - // Post back to WM to handle clean-ups. We still need the input - // event handler for the last finishInputEvent()! - mService.mTaskPositioningController.finishTaskPositioning(); - } - return true; - } - - @VisibleForTesting - Rect getWindowDragBounds() { - return mWindowDragBounds; - } - - /** - * @param displayContent The Display that the window being dragged is on. - * @param win The window which will be dragged. - */ - CompletableFuture<Void> register(DisplayContent displayContent, @NonNull WindowState win) { - if (DEBUG_TASK_POSITIONING) { - Slog.d(TAG, "Registering task positioner"); - } - - if (mClientChannel != null) { - Slog.e(TAG, "Task positioner already registered"); - return completedFuture(null); - } - - mDisplayContent = displayContent; - mClientChannel = mService.mInputManager.createInputChannel(TAG); - - mInputEventReceiver = new BatchedInputEventReceiver.SimpleBatchedInputEventReceiver( - mClientChannel, mService.mAnimationHandler.getLooper(), - mService.mAnimator.getChoreographer(), this::onInputEvent); - - mDragApplicationHandle = new InputApplicationHandle(new Binder(), TAG, - DEFAULT_DISPATCHING_TIMEOUT_MILLIS); - - mDragWindowHandle = new InputWindowHandle(mDragApplicationHandle, - displayContent.getDisplayId()); - mDragWindowHandle.name = TAG; - mDragWindowHandle.token = mClientChannel.getToken(); - mDragWindowHandle.layoutParamsType = WindowManager.LayoutParams.TYPE_DRAG; - mDragWindowHandle.dispatchingTimeoutMillis = DEFAULT_DISPATCHING_TIMEOUT_MILLIS; - mDragWindowHandle.ownerPid = WindowManagerService.MY_PID; - mDragWindowHandle.ownerUid = WindowManagerService.MY_UID; - mDragWindowHandle.scaleFactor = 1.0f; - // When dragging the window around, we do not want to steal focus for the window. - mDragWindowHandle.inputConfig = InputConfig.NOT_FOCUSABLE; - - // The drag window cannot receive new touches. - mDragWindowHandle.touchableRegion.setEmpty(); - - // Pause rotations before a drag. - ProtoLog.d(WM_DEBUG_ORIENTATION, "Pausing rotation during re-position"); - mDisplayContent.getDisplayRotation().pause(); - - // Notify InputMonitor to take mDragWindowHandle. - return mService.mTaskPositioningController.showInputSurface(win.getDisplayId()) - .thenRun(() -> { - // The global lock is held by the callers of register but released before the async - // results are waited on. We must acquire the lock in this callback to ensure thread - // safety. - synchronized (mService.mGlobalLock) { - final Rect displayBounds = mTmpRect; - displayContent.getBounds(displayBounds); - final DisplayMetrics displayMetrics = displayContent.getDisplayMetrics(); - mMinVisibleWidth = dipToPixel(MINIMUM_VISIBLE_WIDTH_IN_DP, displayMetrics); - mMinVisibleHeight = dipToPixel(MINIMUM_VISIBLE_HEIGHT_IN_DP, displayMetrics); - mMaxVisibleSize.set(displayBounds.width(), displayBounds.height()); - - mDragEnded = false; - - try { - mClientCallback = win.mClient.asBinder(); - mClientCallback.linkToDeath(this, 0 /* flags */); - } catch (RemoteException e) { - // The caller has died, so clean up TaskPositioningController. - mService.mTaskPositioningController.finishTaskPositioning(); - return; - } - mWindow = win; - mTask = win.getTask(); - } - }); - } - - void unregister() { - if (DEBUG_TASK_POSITIONING) { - Slog.d(TAG, "Unregistering task positioner"); - } - - if (mClientChannel == null) { - Slog.e(TAG, "Task positioner not registered"); - return; - } - - mService.mTaskPositioningController.hideInputSurface(mDisplayContent.getDisplayId()); - mService.mInputManager.removeInputChannel(mClientChannel.getToken()); - - mInputEventReceiver.dispose(); - mInputEventReceiver = null; - mClientChannel.dispose(); - mClientChannel = null; - - mDragWindowHandle = null; - mDragApplicationHandle = null; - mDragEnded = true; - - // Notify InputMonitor to remove mDragWindowHandle. - mDisplayContent.getInputMonitor().updateInputWindowsLw(true /*force*/); - - // Resume rotations after a drag. - ProtoLog.d(WM_DEBUG_ORIENTATION, "Resuming rotation after re-position"); - mDisplayContent.getDisplayRotation().resume(); - mDisplayContent = null; - if (mClientCallback != null) { - mClientCallback.unlinkToDeath(this, 0 /* flags */); - } - mWindow = null; - } - - /** - * Starts moving or resizing the task. This method should be only called from - * {@link TaskPositioningController#startPositioningLocked} or unit tests. - */ - void startDrag(boolean resize, boolean preserveOrientation, float startX, float startY) { - if (DEBUG_TASK_POSITIONING) { - Slog.d(TAG, "startDrag: win=" + mWindow + ", resize=" + resize - + ", preserveOrientation=" + preserveOrientation + ", {" + startX + ", " - + startY + "}"); - } - // Use the bounds of the task which accounts for - // multiple app windows. Don't use any bounds from win itself as it - // may not be the same size as the task. - final Rect startBounds = mTmpRect; - mTask.getBounds(startBounds); - - mCtrlType = CTRL_NONE; - mStartDragX = startX; - mStartDragY = startY; - mPreserveOrientation = preserveOrientation; - - if (resize) { - if (startX < startBounds.left) { - mCtrlType |= CTRL_LEFT; - } - if (startX > startBounds.right) { - mCtrlType |= CTRL_RIGHT; - } - if (startY < startBounds.top) { - mCtrlType |= CTRL_TOP; - } - if (startY > startBounds.bottom) { - mCtrlType |= CTRL_BOTTOM; - } - mResizing = mCtrlType != CTRL_NONE; - } - - // In case of !isDockedInEffect we are using the union of all task bounds. These might be - // made up out of multiple windows which are only partially overlapping. When that happens, - // the orientation from the window of interest to the entire stack might diverge. However - // for now we treat them as the same. - mStartOrientationWasLandscape = startBounds.width() >= startBounds.height(); - mWindowOriginalBounds.set(startBounds); - - // Notify the app that resizing has started, even though we haven't received any new - // bounds yet. This will guarantee that the app starts the backdrop renderer before - // configuration changes which could cause an activity restart. - if (mResizing) { - notifyMoveLocked(startX, startY); - - // The WindowPositionerEventReceiver callbacks are delivered on the same handler so this - // initial resize is always guaranteed to happen before subsequent drag resizes. - mService.mH.post(() -> { - mService.mAtmService.resizeTask( - mTask.mTaskId, startBounds, RESIZE_MODE_USER_FORCED); - }); - } - - // Make sure we always have valid drag bounds even if the drag ends before any move events - // have been handled. - mWindowDragBounds.set(startBounds); - } - - private void endDragLocked() { - mResizing = false; - mTask.setDragResizing(false); - } - - /** Returns true if the move operation should be ended. */ - @VisibleForTesting - boolean notifyMoveLocked(float x, float y) { - if (DEBUG_TASK_POSITIONING) { - Slog.d(TAG, "notifyMoveLocked: {" + x + "," + y + "}"); - } - - if (mCtrlType != CTRL_NONE) { - resizeDrag(x, y); - mTask.setDragResizing(true); - return false; - } - - // This is a moving or scrolling operation. - // Only allow to move in stable area so the target window won't be covered by system bar. - // Though {@link Task#resolveOverrideConfiguration} should also avoid the case. - mDisplayContent.getStableRect(mTmpRect); - // The task may be put in a limited display area. - mTmpRect.intersect(mTask.getRootTask().getParent().getBounds()); - - int nX = (int) x; - int nY = (int) y; - if (!mTmpRect.contains(nX, nY)) { - // For a moving operation we allow the pointer to go out of the stack bounds, but - // use the clamped pointer position for the drag bounds computation. - nX = Math.min(Math.max(nX, mTmpRect.left), mTmpRect.right); - nY = Math.min(Math.max(nY, mTmpRect.top), mTmpRect.bottom); - } - - updateWindowDragBounds(nX, nY, mTmpRect); - return false; - } - - /** - * The user is drag - resizing the window. - * - * @param x The x coordinate of the current drag coordinate. - * @param y the y coordinate of the current drag coordinate. - */ - @VisibleForTesting - void resizeDrag(float x, float y) { - updateDraggedBounds(TaskResizingAlgorithm.resizeDrag(x, y, mStartDragX, mStartDragY, - mWindowOriginalBounds, mCtrlType, mMinVisibleWidth, mMinVisibleHeight, - mMaxVisibleSize, mPreserveOrientation, mStartOrientationWasLandscape)); - } - - private void updateDraggedBounds(Rect newBounds) { - mWindowDragBounds.set(newBounds); - - checkBoundsForOrientationViolations(mWindowDragBounds); - } - - /** - * Validate bounds against orientation violations (if DEBUG_ORIENTATION_VIOLATIONS is set). - * - * @param bounds The bounds to be checked. - */ - private void checkBoundsForOrientationViolations(Rect bounds) { - // When using debug check that we are not violating the given constraints. - if (DEBUG_ORIENTATION_VIOLATIONS) { - if (mStartOrientationWasLandscape != (bounds.width() >= bounds.height())) { - Slog.e(TAG, "Orientation violation detected! should be " - + (mStartOrientationWasLandscape ? "landscape" : "portrait") - + " but is the other"); - } else { - Slog.v(TAG, "new bounds size: " + bounds.width() + " x " + bounds.height()); - } - if (mMinVisibleWidth > bounds.width() || mMinVisibleHeight > bounds.height()) { - Slog.v(TAG, "Minimum requirement violated: Width(min, is)=(" + mMinVisibleWidth - + ", " + bounds.width() + ") Height(min,is)=(" - + mMinVisibleHeight + ", " + bounds.height() + ")"); - } - if (mMaxVisibleSize.x < bounds.width() || mMaxVisibleSize.y < bounds.height()) { - Slog.v(TAG, "Maximum requirement violated: Width(min, is)=(" + mMaxVisibleSize.x - + ", " + bounds.width() + ") Height(min,is)=(" - + mMaxVisibleSize.y + ", " + bounds.height() + ")"); - } - } - } - - private void updateWindowDragBounds(int x, int y, Rect rootTaskBounds) { - final int offsetX = Math.round(x - mStartDragX); - final int offsetY = Math.round(y - mStartDragY); - mWindowDragBounds.set(mWindowOriginalBounds); - // Horizontally, at least mMinVisibleWidth pixels of the window should remain visible. - final int maxLeft = rootTaskBounds.right - mMinVisibleWidth; - final int minLeft = rootTaskBounds.left + mMinVisibleWidth - mWindowOriginalBounds.width(); - - // Vertically, the top mMinVisibleHeight of the window should remain visible. - // (This assumes that the window caption bar is at the top of the window). - final int minTop = rootTaskBounds.top; - final int maxTop = rootTaskBounds.bottom - mMinVisibleHeight; - - mWindowDragBounds.offsetTo( - Math.min(Math.max(mWindowOriginalBounds.left + offsetX, minLeft), maxLeft), - Math.min(Math.max(mWindowOriginalBounds.top + offsetY, minTop), maxTop)); - - if (DEBUG_TASK_POSITIONING) Slog.d(TAG, - "updateWindowDragBounds: " + mWindowDragBounds); - } - - public String toShortString() { - return TAG; - } - - static void setFactory(Factory factory) { - sFactory = factory; - } - - static TaskPositioner create(WindowManagerService service) { - if (sFactory == null) { - sFactory = new Factory() {}; - } - - return sFactory.create(service); - } - - @Override - public void binderDied() { - mService.mTaskPositioningController.finishTaskPositioning(); - } - - interface Factory { - default TaskPositioner create(WindowManagerService service) { - return new TaskPositioner(service); - } - } -} diff --git a/services/core/java/com/android/server/wm/TaskPositioningController.java b/services/core/java/com/android/server/wm/TaskPositioningController.java deleted file mode 100644 index 6f548ab01d74..000000000000 --- a/services/core/java/com/android/server/wm/TaskPositioningController.java +++ /dev/null @@ -1,250 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.wm; - -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TASK_POSITIONING; -import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; - -import static java.util.concurrent.CompletableFuture.completedFuture; - -import android.annotation.Nullable; -import android.graphics.Point; -import android.graphics.Rect; -import android.util.Slog; -import android.view.Display; -import android.view.IWindow; -import android.view.InputWindowHandle; -import android.view.SurfaceControl; - -import java.util.concurrent.CompletableFuture; - -/** - * Controller for task positioning by drag. - */ -class TaskPositioningController { - private final WindowManagerService mService; - private SurfaceControl mInputSurface; - private DisplayContent mPositioningDisplay; - - private @Nullable TaskPositioner mTaskPositioner; - - private final Rect mTmpClipRect = new Rect(); - - boolean isPositioningLocked() { - return mTaskPositioner != null; - } - - final SurfaceControl.Transaction mTransaction; - - InputWindowHandle getDragWindowHandleLocked() { - return mTaskPositioner != null ? mTaskPositioner.mDragWindowHandle : null; - } - - TaskPositioningController(WindowManagerService service) { - mService = service; - mTransaction = service.mTransactionFactory.get(); - } - - void hideInputSurface(int displayId) { - if (mPositioningDisplay != null && mPositioningDisplay.getDisplayId() == displayId - && mInputSurface != null) { - mTransaction.hide(mInputSurface).apply(); - } - } - - /** - * @return a future that completes after window info is sent. - */ - CompletableFuture<Void> showInputSurface(int displayId) { - if (mPositioningDisplay == null || mPositioningDisplay.getDisplayId() != displayId) { - return completedFuture(null); - } - final DisplayContent dc = mService.mRoot.getDisplayContent(displayId); - if (mInputSurface == null) { - mInputSurface = mService.makeSurfaceBuilder(dc.getSession()) - .setContainerLayer() - .setName("Drag and Drop Input Consumer") - .setCallsite("TaskPositioningController.showInputSurface") - .setParent(dc.getOverlayLayer()) - .build(); - } - - final InputWindowHandle h = getDragWindowHandleLocked(); - if (h == null) { - Slog.w(TAG_WM, "Drag is in progress but there is no " - + "drag window handle."); - return completedFuture(null); - } - - final Display display = dc.getDisplay(); - final Point p = new Point(); - display.getRealSize(p); - mTmpClipRect.set(0, 0, p.x, p.y); - - CompletableFuture<Void> result = new CompletableFuture<>(); - mTransaction.show(mInputSurface) - .setInputWindowInfo(mInputSurface, h) - .setLayer(mInputSurface, Integer.MAX_VALUE) - .setPosition(mInputSurface, 0, 0) - .setCrop(mInputSurface, mTmpClipRect) - .addWindowInfosReportedListener(() -> result.complete(null)) - .apply(); - return result; - } - - boolean startMovingTask(IWindow window, float startX, float startY) { - WindowState win = null; - CompletableFuture<Boolean> startPositioningLockedFuture; - synchronized (mService.mGlobalLock) { - win = mService.windowForClientLocked(null, window, false); - startPositioningLockedFuture = - startPositioningLocked( - win, false /*resize*/, false /*preserveOrientation*/, startX, startY); - } - - try { - if (!startPositioningLockedFuture.get()) { - return false; - } - } catch (Exception exception) { - Slog.e(TAG_WM, "Exception thrown while waiting for startPositionLocked future", - exception); - return false; - } - - synchronized (mService.mGlobalLock) { - mService.mAtmService.setFocusedTask(win.getTask().mTaskId); - } - return true; - } - - void handleTapOutsideTask(DisplayContent displayContent, int x, int y) { - mService.mH.post(() -> { - Task task; - CompletableFuture<Boolean> startPositioningLockedFuture; - synchronized (mService.mGlobalLock) { - task = displayContent.findTaskForResizePoint(x, y); - if (task == null || !task.isResizeable()) { - // The task is not resizable, so don't do anything when the user drags the - // the resize handles. - return; - } - startPositioningLockedFuture = - startPositioningLocked(task.getTopVisibleAppMainWindow(), true /*resize*/, - task.preserveOrientationOnResize(), x, y); - } - - try { - if (!startPositioningLockedFuture.get()) { - return; - } - } catch (Exception exception) { - Slog.e(TAG_WM, "Exception thrown while waiting for startPositionLocked future", - exception); - return; - } - - synchronized (mService.mGlobalLock) { - mService.mAtmService.setFocusedTask(task.mTaskId); - } - }); - } - - private CompletableFuture<Boolean> startPositioningLocked(WindowState win, boolean resize, - boolean preserveOrientation, float startX, float startY) { - if (DEBUG_TASK_POSITIONING) - Slog.d(TAG_WM, "startPositioningLocked: " - + "win=" + win + ", resize=" + resize + ", preserveOrientation=" - + preserveOrientation + ", {" + startX + ", " + startY + "}"); - - if (win == null || win.mActivityRecord == null) { - Slog.w(TAG_WM, "startPositioningLocked: Bad window " + win); - return completedFuture(false); - } - if (win.mInputChannel == null) { - Slog.wtf(TAG_WM, "startPositioningLocked: " + win + " has no input channel, " - + " probably being removed"); - return completedFuture(false); - } - - final DisplayContent displayContent = win.getDisplayContent(); - if (displayContent == null) { - Slog.w(TAG_WM, "startPositioningLocked: Invalid display content " + win); - return completedFuture(false); - } - mPositioningDisplay = displayContent; - - mTaskPositioner = TaskPositioner.create(mService); - return mTaskPositioner.register(displayContent, win).thenApply(unused -> { - // The global lock is held by the callers of startPositioningLocked but released before - // the async results are waited on. We must acquire the lock in this callback to ensure - // thread safety. - synchronized (mService.mGlobalLock) { - // We need to grab the touch focus so that the touch events during the - // resizing/scrolling are not sent to the app. 'win' is the main window - // of the app, it may not have focus since there might be other windows - // on top (eg. a dialog window). - WindowState transferTouchFromWin = win; - if (displayContent.mCurrentFocus != null && displayContent.mCurrentFocus != win - && displayContent.mCurrentFocus.mActivityRecord == win.mActivityRecord) { - transferTouchFromWin = displayContent.mCurrentFocus; - } - if (!mService.mInputManager.transferTouchGesture( - transferTouchFromWin.mInputChannel.getToken(), - mTaskPositioner.mClientChannel.getToken())) { - Slog.e(TAG_WM, "startPositioningLocked: Unable to transfer touch focus"); - cleanUpTaskPositioner(); - return false; - } - - mTaskPositioner.startDrag(resize, preserveOrientation, startX, startY); - return true; - } - }); - } - - public void finishTaskPositioning(IWindow window) { - if (mTaskPositioner != null && mTaskPositioner.mClientCallback == window.asBinder()) { - finishTaskPositioning(); - } - } - - void finishTaskPositioning() { - // TaskPositioner attaches the InputEventReceiver to the animation thread. We need to - // dispose the receiver on the same thread to avoid race conditions. - mService.mAnimationHandler.post(() -> { - if (DEBUG_TASK_POSITIONING) Slog.d(TAG_WM, "finishPositioning"); - - synchronized (mService.mGlobalLock) { - cleanUpTaskPositioner(); - mPositioningDisplay = null; - } - }); - } - - private void cleanUpTaskPositioner() { - final TaskPositioner positioner = mTaskPositioner; - if (positioner == null) { - return; - } - - // We need to assign task positioner to null first to indicate that we're finishing task - // positioning. - mTaskPositioner = null; - positioner.unregister(); - } -} diff --git a/services/core/java/com/android/server/wm/WindowManagerDebugConfig.java b/services/core/java/com/android/server/wm/WindowManagerDebugConfig.java index 42b556f77ab6..61253602c066 100644 --- a/services/core/java/com/android/server/wm/WindowManagerDebugConfig.java +++ b/services/core/java/com/android/server/wm/WindowManagerDebugConfig.java @@ -47,7 +47,6 @@ public class WindowManagerDebugConfig { static final boolean DEBUG_LAYOUT_REPEATS = false; static final boolean DEBUG_WINDOW_TRACE = false; static final boolean DEBUG_TASK_MOVEMENT = false; - static final boolean DEBUG_TASK_POSITIONING = false; static final boolean DEBUG_ROOT_TASK = false; static final boolean DEBUG_DISPLAY = false; static final boolean DEBUG_POWER = false; diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index acd8b3f1dbc3..30ea08698250 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -1070,7 +1070,6 @@ public class WindowManagerService extends IWindowManager.Stub /** Whether or not a layout can cause a wake up when theater mode is enabled. */ boolean mAllowTheaterModeWakeFromLayout; - final TaskPositioningController mTaskPositioningController; final DragDropController mDragDropController; /** For frozen screen animations. */ @@ -1428,7 +1427,6 @@ public class WindowManagerService extends IWindowManager.Stub mAllowTheaterModeWakeFromLayout = context.getResources().getBoolean( com.android.internal.R.bool.config_allowTheaterModeWakeFromWindowLayout); - mTaskPositioningController = new TaskPositioningController(this); mDragDropController = new DragDropController(this, mH.getLooper()); mHighRefreshRateDenylist = HighRefreshRateDenylist.create(context.getResources()); diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskPositionerTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskPositionerTests.java deleted file mode 100644 index d5356774ffdb..000000000000 --- a/services/tests/wmtests/src/com/android/server/wm/TaskPositionerTests.java +++ /dev/null @@ -1,526 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.wm; - -import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; -import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION; - -import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; -import static com.android.internal.policy.TaskResizingAlgorithm.MIN_ASPECT; -import static com.android.server.wm.WindowManagerService.dipToPixel; -import static com.android.server.wm.WindowState.MINIMUM_VISIBLE_HEIGHT_IN_DP; -import static com.android.server.wm.WindowState.MINIMUM_VISIBLE_WIDTH_IN_DP; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.verify; - -import android.graphics.Rect; -import android.platform.test.annotations.Presubmit; -import android.util.DisplayMetrics; -import android.util.Log; - -import androidx.test.filters.SmallTest; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - -/** - * Tests for the {@link TaskPositioner} class. - * - * Build/Install/Run: - * atest WmTests:TaskPositionerTests - */ -@SmallTest -@Presubmit -@RunWith(WindowTestRunner.class) -public class TaskPositionerTests extends WindowTestsBase { - - private static final boolean DEBUGGING = false; - private static final String TAG = "TaskPositionerTest"; - - private static final int MOUSE_DELTA_X = 5; - private static final int MOUSE_DELTA_Y = 5; - - private int mMinVisibleWidth; - private int mMinVisibleHeight; - private TaskPositioner mPositioner; - - @Before - public void setUp() { - TaskPositioner.setFactory(null); - - final DisplayMetrics dm = mDisplayContent.getDisplayMetrics(); - - // This should be the same calculation as the TaskPositioner uses. - mMinVisibleWidth = dipToPixel(MINIMUM_VISIBLE_WIDTH_IN_DP, dm); - mMinVisibleHeight = dipToPixel(MINIMUM_VISIBLE_HEIGHT_IN_DP, dm); - removeGlobalMinSizeRestriction(); - - final ActivityRecord activity = new ActivityBuilder(mAtm) - .setCreateTask(true) - .build(); - final WindowState win = createWindow(null, TYPE_BASE_APPLICATION, activity, "window"); - mPositioner = new TaskPositioner(mWm); - mPositioner.register(mDisplayContent, win); - - win.getRootTask().setWindowingMode(WINDOWING_MODE_FREEFORM); - } - - @After - public void tearDown() { - TaskPositioner.setFactory(null); - } - - @Test - public void testOverrideFactory() { - final boolean[] created = new boolean[1]; - created[0] = false; - TaskPositioner.setFactory(new TaskPositioner.Factory() { - @Override - public TaskPositioner create(WindowManagerService service) { - created[0] = true; - return null; - } - }); - - assertNull(TaskPositioner.create(mWm)); - assertTrue(created[0]); - } - - /** This tests that the window can move in all directions. */ - @Test - public void testMoveWindow() { - final Rect displayBounds = mDisplayContent.getBounds(); - final int windowSize = Math.min(displayBounds.width(), displayBounds.height()) / 2; - final int left = displayBounds.centerX() - windowSize / 2; - final int top = displayBounds.centerY() - windowSize / 2; - final Rect r = new Rect(left, top, left + windowSize, top + windowSize); - mPositioner.mTask.setBounds(r); - mPositioner.startDrag(false /* resizing */, false /* preserveOrientation */, left, top); - - // Move upper left. - mPositioner.notifyMoveLocked(left - MOUSE_DELTA_X, top - MOUSE_DELTA_Y); - r.offset(-MOUSE_DELTA_X, -MOUSE_DELTA_Y); - assertBoundsEquals(r, mPositioner.getWindowDragBounds()); - - // Move bottom right. - mPositioner.notifyMoveLocked(left, top); - r.offset(MOUSE_DELTA_X, MOUSE_DELTA_Y); - assertBoundsEquals(r, mPositioner.getWindowDragBounds()); - } - - /** - * This tests that free resizing will allow to change the orientation as well - * as does some basic tests (e.g. dragging in Y only will keep X stable). - */ - @Test - public void testBasicFreeWindowResizing() { - final Rect r = new Rect(100, 220, 700, 520); - final int midY = (r.top + r.bottom) / 2; - mPositioner.mTask.setBounds(r, true); - - // Start a drag resize starting upper left. - mPositioner.startDrag(true /* resizing */, false /* preserveOrientation */, - r.left - MOUSE_DELTA_X, r.top - MOUSE_DELTA_Y); - assertBoundsEquals(r, mPositioner.getWindowDragBounds()); - - // Drag to a good landscape size. - mPositioner.resizeDrag(0.0f, 0.0f); - assertBoundsEquals(new Rect(MOUSE_DELTA_X, MOUSE_DELTA_Y, r.right, r.bottom), - mPositioner.getWindowDragBounds()); - - // Drag to a good portrait size. - mPositioner.resizeDrag(400.0f, 0.0f); - assertBoundsEquals(new Rect(400 + MOUSE_DELTA_X, MOUSE_DELTA_Y, r.right, r.bottom), - mPositioner.getWindowDragBounds()); - - // Drag to a too small size for the width. - mPositioner.resizeDrag(2000.0f, r.top); - assertBoundsEquals( - new Rect(r.right - mMinVisibleWidth, r.top + MOUSE_DELTA_Y, r.right, r.bottom), - mPositioner.getWindowDragBounds()); - - // Drag to a too small size for the height. - mPositioner.resizeDrag(r.left, 2000.0f); - assertBoundsEquals( - new Rect(r.left + MOUSE_DELTA_X, r.bottom - mMinVisibleHeight, r.right, r.bottom), - mPositioner.getWindowDragBounds()); - - // Start a drag resize left and see that only the left coord changes.. - mPositioner.startDrag(true /* resizing */, false /* preserveOrientation */, - r.left - MOUSE_DELTA_X, midY); - - // Drag to the left. - mPositioner.resizeDrag(0.0f, midY); - assertBoundsEquals(new Rect(MOUSE_DELTA_X, r.top, r.right, r.bottom), - mPositioner.getWindowDragBounds()); - - // Drag to the right. - mPositioner.resizeDrag(200.0f, midY); - assertBoundsEquals(new Rect(200 + MOUSE_DELTA_X, r.top, r.right, r.bottom), - mPositioner.getWindowDragBounds()); - - // Drag to the top - mPositioner.resizeDrag(r.left, 0.0f); - assertBoundsEquals(new Rect(r.left + MOUSE_DELTA_X, r.top, r.right, r.bottom), - mPositioner.getWindowDragBounds()); - - // Drag to the bottom - mPositioner.resizeDrag(r.left, 1000.0f); - assertBoundsEquals(new Rect(r.left + MOUSE_DELTA_X, r.top, r.right, r.bottom), - mPositioner.getWindowDragBounds()); - } - - /** - * This tests that by dragging any edge, the fixed / opposite edge(s) remains anchored. - */ - @Test - public void testFreeWindowResizingTestAllEdges() { - final Rect r = new Rect(100, 220, 700, 520); - final int midX = (r.left + r.right) / 2; - final int midY = (r.top + r.bottom) / 2; - mPositioner.mTask.setBounds(r, true); - - // Drag upper left. - mPositioner.startDrag(true /* resizing */, false /* preserveOrientation */, - r.left - MOUSE_DELTA_X, r.top - MOUSE_DELTA_Y); - mPositioner.resizeDrag(0.0f, 0.0f); - assertNotEquals(r.left, mPositioner.getWindowDragBounds().left); - assertEquals(r.right, mPositioner.getWindowDragBounds().right); - assertNotEquals(r.top, mPositioner.getWindowDragBounds().top); - assertEquals(r.bottom, mPositioner.getWindowDragBounds().bottom); - - // Drag upper. - mPositioner.startDrag(true /* resizing */, false /* preserveOrientation */, midX, - r.top - MOUSE_DELTA_Y); - mPositioner.resizeDrag(0.0f, 0.0f); - assertEquals(r.left, mPositioner.getWindowDragBounds().left); - assertEquals(r.right, mPositioner.getWindowDragBounds().right); - assertNotEquals(r.top, mPositioner.getWindowDragBounds().top); - assertEquals(r.bottom, mPositioner.getWindowDragBounds().bottom); - - // Drag upper right. - mPositioner.startDrag(true /* resizing */, false /* preserveOrientation */, - r.right + MOUSE_DELTA_X, r.top - MOUSE_DELTA_Y); - mPositioner.resizeDrag(r.right + 100, 0.0f); - assertEquals(r.left, mPositioner.getWindowDragBounds().left); - assertNotEquals(r.right, mPositioner.getWindowDragBounds().right); - assertNotEquals(r.top, mPositioner.getWindowDragBounds().top); - assertEquals(r.bottom, mPositioner.getWindowDragBounds().bottom); - - // Drag right. - mPositioner.startDrag(true /* resizing */, false /* preserveOrientation */, - r.right + MOUSE_DELTA_X, midY); - mPositioner.resizeDrag(r.right + 100, 0.0f); - assertEquals(r.left, mPositioner.getWindowDragBounds().left); - assertNotEquals(r.right, mPositioner.getWindowDragBounds().right); - assertEquals(r.top, mPositioner.getWindowDragBounds().top); - assertEquals(r.bottom, mPositioner.getWindowDragBounds().bottom); - - // Drag bottom right. - mPositioner.startDrag(true /* resizing */, false /* preserveOrientation */, - r.right + MOUSE_DELTA_X, r.bottom + MOUSE_DELTA_Y); - mPositioner.resizeDrag(r.right + 100, r.bottom + 100); - assertEquals(r.left, mPositioner.getWindowDragBounds().left); - assertNotEquals(r.right, mPositioner.getWindowDragBounds().right); - assertEquals(r.top, mPositioner.getWindowDragBounds().top); - assertNotEquals(r.bottom, mPositioner.getWindowDragBounds().bottom); - - // Drag bottom. - mPositioner.startDrag(true /* resizing */, false /* preserveOrientation */, midX, - r.bottom + MOUSE_DELTA_Y); - mPositioner.resizeDrag(r.right + 100, r.bottom + 100); - assertEquals(r.left, mPositioner.getWindowDragBounds().left); - assertEquals(r.right, mPositioner.getWindowDragBounds().right); - assertEquals(r.top, mPositioner.getWindowDragBounds().top); - assertNotEquals(r.bottom, mPositioner.getWindowDragBounds().bottom); - - // Drag bottom left. - mPositioner.startDrag(true /* resizing */, false /* preserveOrientation */, - r.left - MOUSE_DELTA_X, r.bottom + MOUSE_DELTA_Y); - mPositioner.resizeDrag(0.0f, r.bottom + 100); - assertNotEquals(r.left, mPositioner.getWindowDragBounds().left); - assertEquals(r.right, mPositioner.getWindowDragBounds().right); - assertEquals(r.top, mPositioner.getWindowDragBounds().top); - assertNotEquals(r.bottom, mPositioner.getWindowDragBounds().bottom); - - // Drag left. - mPositioner.startDrag(true /* resizing */, false /* preserveOrientation */, - r.left - MOUSE_DELTA_X, midY); - mPositioner.resizeDrag(0.0f, r.bottom + 100); - assertNotEquals(r.left, mPositioner.getWindowDragBounds().left); - assertEquals(r.right, mPositioner.getWindowDragBounds().right); - assertEquals(r.top, mPositioner.getWindowDragBounds().top); - assertEquals(r.bottom, mPositioner.getWindowDragBounds().bottom); - } - - /** - * This tests that a constrained landscape window will keep the aspect and do the - * right things upon resizing when dragged from the top left corner. - */ - @Test - public void testLandscapePreservedWindowResizingDragTopLeft() { - final Rect r = new Rect(100, 220, 700, 520); - mPositioner.mTask.setBounds(r, true); - - mPositioner.startDrag(true /* resizing */, true /* preserveOrientation */, - r.left - MOUSE_DELTA_X, r.top - MOUSE_DELTA_Y); - assertBoundsEquals(r, mPositioner.getWindowDragBounds()); - - // Drag to a good landscape size. - mPositioner.resizeDrag(0.0f, 0.0f); - assertBoundsEquals(new Rect(MOUSE_DELTA_X, MOUSE_DELTA_Y, r.right, r.bottom), - mPositioner.getWindowDragBounds()); - - // Drag to a good portrait size. - mPositioner.resizeDrag(400.0f, 0.0f); - int width = Math.round((float) (r.bottom - MOUSE_DELTA_Y) * MIN_ASPECT); - assertBoundsEquals(new Rect(r.right - width, MOUSE_DELTA_Y, r.right, r.bottom), - mPositioner.getWindowDragBounds()); - - // Drag to a too small size for the width. - mPositioner.resizeDrag(2000.0f, r.top); - final int w = mMinVisibleWidth; - final int h = Math.round(w / MIN_ASPECT); - assertBoundsEquals(new Rect(r.right - w, r.bottom - h, r.right, r.bottom), - mPositioner.getWindowDragBounds()); - - // Drag to a too small size for the height. - mPositioner.resizeDrag(r.left, 2000.0f); - assertBoundsEquals( - new Rect(r.left + MOUSE_DELTA_X, r.bottom - mMinVisibleHeight, r.right, r.bottom), - mPositioner.getWindowDragBounds()); - } - - /** - * This tests that a constrained landscape window will keep the aspect and do the - * right things upon resizing when dragged from the left corner. - */ - @Test - public void testLandscapePreservedWindowResizingDragLeft() { - final Rect r = new Rect(100, 220, 700, 520); - final int midY = (r.top + r.bottom) / 2; - mPositioner.mTask.setBounds(r, true); - - mPositioner.startDrag(true /* resizing */, true /* preserveOrientation */, - r.left - MOUSE_DELTA_X, midY); - - // Drag to the left. - mPositioner.resizeDrag(0.0f, midY); - assertBoundsEquals(new Rect(MOUSE_DELTA_X, r.top, r.right, r.bottom), - mPositioner.getWindowDragBounds()); - - // Drag to the right. - mPositioner.resizeDrag(200.0f, midY); - assertBoundsEquals(new Rect(200 + MOUSE_DELTA_X, r.top, r.right, r.bottom), - mPositioner.getWindowDragBounds()); - - // Drag all the way to the right and see the height also shrinking. - mPositioner.resizeDrag(2000.0f, midY); - final int w = mMinVisibleWidth; - final int h = Math.round((float) w / MIN_ASPECT); - assertBoundsEquals(new Rect(r.right - w, r.top, r.right, r.top + h), - mPositioner.getWindowDragBounds()); - - // Drag to the top. - mPositioner.resizeDrag(r.left, 0.0f); - assertBoundsEquals(new Rect(r.left + MOUSE_DELTA_X, r.top, r.right, r.bottom), - mPositioner.getWindowDragBounds()); - - // Drag to the bottom. - mPositioner.resizeDrag(r.left, 1000.0f); - assertBoundsEquals(new Rect(r.left + MOUSE_DELTA_X, r.top, r.right, r.bottom), - mPositioner.getWindowDragBounds()); - } - - /** - * This tests that a constrained landscape window will keep the aspect and do the - * right things upon resizing when dragged from the top corner. - */ - @Test - public void testLandscapePreservedWindowResizingDragTop() { - final Rect r = new Rect(100, 220, 700, 520); - final int midX = (r.left + r.right) / 2; - mPositioner.mTask.setBounds(r, true); - - mPositioner.startDrag(true /*resizing*/, true /*preserveOrientation*/, midX, - r.top - MOUSE_DELTA_Y); - - // Drag to the left (no change). - mPositioner.resizeDrag(0.0f, r.top); - assertBoundsEquals(new Rect(r.left, r.top + MOUSE_DELTA_Y, r.right, r.bottom), - mPositioner.getWindowDragBounds()); - - // Drag to the right (no change). - mPositioner.resizeDrag(2000.0f, r.top); - assertBoundsEquals(new Rect(r.left , r.top + MOUSE_DELTA_Y, r.right, r.bottom), - mPositioner.getWindowDragBounds()); - - // Drag to the top. - mPositioner.resizeDrag(300.0f, 0.0f); - int h = r.bottom - MOUSE_DELTA_Y; - int w = Math.max(r.right - r.left, Math.round(h * MIN_ASPECT)); - assertBoundsEquals(new Rect(r.left, MOUSE_DELTA_Y, r.left + w, r.bottom), - mPositioner.getWindowDragBounds()); - - // Drag to the bottom. - mPositioner.resizeDrag(r.left, 1000.0f); - h = mMinVisibleHeight; - assertBoundsEquals(new Rect(r.left, r.bottom - h, r.right, r.bottom), - mPositioner.getWindowDragBounds()); - } - - /** - * This tests that a constrained portrait window will keep the aspect and do the - * right things upon resizing when dragged from the top left corner. - */ - @Test - public void testPortraitPreservedWindowResizingDragTopLeft() { - final Rect r = new Rect(330, 100, 630, 600); - mPositioner.mTask.setBounds(r, true); - - mPositioner.startDrag(true /*resizing*/, true /*preserveOrientation*/, - r.left - MOUSE_DELTA_X, r.top - MOUSE_DELTA_Y); - assertBoundsEquals(r, mPositioner.getWindowDragBounds()); - - // Drag to a good landscape size. - mPositioner.resizeDrag(0.0f, 0.0f); - int height = Math.round((float) (r.right - MOUSE_DELTA_X) * MIN_ASPECT); - assertBoundsEquals(new Rect(MOUSE_DELTA_X, r.bottom - height, r.right, r.bottom), - mPositioner.getWindowDragBounds()); - - // Drag to a good portrait size. - mPositioner.resizeDrag(400.0f, 0.0f); - assertBoundsEquals(new Rect(400 + MOUSE_DELTA_X, MOUSE_DELTA_Y, r.right, r.bottom), - mPositioner.getWindowDragBounds()); - - // Drag to a too small size for the height and the the width shrinking. - mPositioner.resizeDrag(r.left + MOUSE_DELTA_X, 2000.0f); - final int w = Math.max(mMinVisibleWidth, Math.round(mMinVisibleHeight / MIN_ASPECT)); - final int h = Math.max(mMinVisibleHeight, Math.round(w * MIN_ASPECT)); - assertBoundsEquals( - new Rect(r.right - w, r.bottom - h, r.right, r.bottom), - mPositioner.getWindowDragBounds()); - } - - /** - * This tests that a constrained portrait window will keep the aspect and do the - * right things upon resizing when dragged from the left corner. - */ - @Test - public void testPortraitPreservedWindowResizingDragLeft() { - final Rect r = new Rect(330, 100, 630, 600); - final int midY = (r.top + r.bottom) / 2; - mPositioner.mTask.setBounds(r, true); - - mPositioner.startDrag(true /* resizing */, true /* preserveOrientation */, - r.left - MOUSE_DELTA_X, midY); - - // Drag to the left. - mPositioner.resizeDrag(0.0f, midY); - int w = r.right - MOUSE_DELTA_X; - int h = Math.round(w * MIN_ASPECT); - assertBoundsEquals(new Rect(MOUSE_DELTA_X, r.top, r.right, r.top + h), - mPositioner.getWindowDragBounds()); - - // Drag to the right. - mPositioner.resizeDrag(450.0f, midY); - assertBoundsEquals(new Rect(450 + MOUSE_DELTA_X, r.top, r.right, r.bottom), - mPositioner.getWindowDragBounds()); - - // Drag all the way to the right. - mPositioner.resizeDrag(2000.0f, midY); - w = mMinVisibleWidth; - h = Math.max(Math.round((float) w * MIN_ASPECT), r.height()); - assertBoundsEquals(new Rect(r.right - w, r.top, r.right, r.top + h), - mPositioner.getWindowDragBounds()); - - // Drag to the top. - mPositioner.resizeDrag(r.left, 0.0f); - assertBoundsEquals(new Rect(r.left + MOUSE_DELTA_X, r.top, r.right, r.bottom), - mPositioner.getWindowDragBounds()); - - // Drag to the bottom. - mPositioner.resizeDrag(r.left, 1000.0f); - assertBoundsEquals(new Rect(r.left + MOUSE_DELTA_X, r.top, r.right, r.bottom), - mPositioner.getWindowDragBounds()); - } - - /** - * This tests that a constrained portrait window will keep the aspect and do the - * right things upon resizing when dragged from the top corner. - */ - @Test - public void testPortraitPreservedWindowResizingDragTop() { - final Rect r = new Rect(330, 100, 630, 600); - final int midX = (r.left + r.right) / 2; - mPositioner.mTask.setBounds(r, true); - - mPositioner.startDrag(true /* resizing */, true /* preserveOrientation */, midX, - r.top - MOUSE_DELTA_Y); - - // Drag to the left (no change). - mPositioner.resizeDrag(0.0f, r.top); - assertBoundsEquals(new Rect(r.left, r.top + MOUSE_DELTA_Y, r.right, r.bottom), - mPositioner.getWindowDragBounds()); - - // Drag to the right (no change). - mPositioner.resizeDrag(2000.0f, r.top); - assertBoundsEquals(new Rect(r.left , r.top + MOUSE_DELTA_Y, r.right, r.bottom), - mPositioner.getWindowDragBounds()); - - // Drag to the top. - mPositioner.resizeDrag(300.0f, 0.0f); - int h = r.bottom - MOUSE_DELTA_Y; - int w = Math.min(r.width(), Math.round(h / MIN_ASPECT)); - assertBoundsEquals(new Rect(r.left, MOUSE_DELTA_Y, r.left + w, r.bottom), - mPositioner.getWindowDragBounds()); - - // Drag to the bottom. - mPositioner.resizeDrag(r.left, 1000.0f); - h = Math.max(mMinVisibleHeight, Math.round(mMinVisibleWidth * MIN_ASPECT)); - w = Math.round(h / MIN_ASPECT); - assertBoundsEquals(new Rect(r.left, r.bottom - h, r.left + w, r.bottom), - mPositioner.getWindowDragBounds()); - } - - private static void assertBoundsEquals(Rect expected, Rect actual) { - if (DEBUGGING) { - if (!expected.equals(actual)) { - Log.e(TAG, "rect(" + actual.toString() + ") != isRect(" + actual.toString() - + ") " + Log.getStackTraceString(new Throwable())); - } - } - assertEquals(expected, actual); - } - - @Test - public void testFinishingMovingWhenBinderDied() { - spyOn(mWm.mTaskPositioningController); - - mPositioner.startDrag(false, false, 0 /* startX */, 0 /* startY */); - verify(mWm.mTaskPositioningController, never()).finishTaskPositioning(); - mPositioner.binderDied(); - verify(mWm.mTaskPositioningController).finishTaskPositioning(); - } -} diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskPositioningControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskPositioningControllerTests.java deleted file mode 100644 index bfc13d3d2ef2..000000000000 --- a/services/tests/wmtests/src/com/android/server/wm/TaskPositioningControllerTests.java +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.wm; - -import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE; -import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE; -import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION; - -import static com.android.dx.mockito.inline.extended.ExtendedMockito.any; -import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyInt; -import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; -import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock; -import static com.android.dx.mockito.inline.extended.ExtendedMockito.when; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; - -import android.platform.test.annotations.Presubmit; -import android.view.InputChannel; - -import androidx.test.filters.FlakyTest; -import androidx.test.filters.SmallTest; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - -/** - * Tests for the {@link TaskPositioningController} class. - * - * Build/Install/Run: - * atest WmTests:TaskPositioningControllerTests - */ -@SmallTest -@Presubmit -@RunWith(WindowTestRunner.class) -public class TaskPositioningControllerTests extends WindowTestsBase { - private static final int TIMEOUT_MS = 1000; - - private TaskPositioningController mTarget; - private WindowState mWindow; - - @Before - public void setUp() throws Exception { - assertNotNull(mWm.mTaskPositioningController); - mTarget = mWm.mTaskPositioningController; - - when(mWm.mInputManager.transferTouchGesture(any(), any())).thenReturn(true); - - mWindow = createWindow(null, TYPE_BASE_APPLICATION, "window"); - mWindow.getTask().setResizeMode(RESIZE_MODE_RESIZEABLE); - mWindow.mInputChannel = new InputChannel(); - mWm.mWindowMap.put(mWindow.mClient.asBinder(), mWindow); - doReturn(mock(InputMonitor.class)).when(mDisplayContent).getInputMonitor(); - } - - @FlakyTest(bugId = 291067614) - @Test - public void testStartAndFinishPositioning() { - assertFalse(mTarget.isPositioningLocked()); - assertNull(mTarget.getDragWindowHandleLocked()); - - assertTrue(mTarget.startMovingTask(mWindow.mClient, 0, 0)); - - assertTrue(mTarget.isPositioningLocked()); - assertNotNull(mTarget.getDragWindowHandleLocked()); - - mTarget.finishTaskPositioning(); - // Wait until the looper processes finishTaskPositioning. - assertTrue(waitHandlerIdle(mWm.mAnimationHandler, TIMEOUT_MS)); - - assertFalse(mTarget.isPositioningLocked()); - assertNull(mTarget.getDragWindowHandleLocked()); - } - - @Test - public void testFinishPositioningWhenAppRequested() { - assertFalse(mTarget.isPositioningLocked()); - assertNull(mTarget.getDragWindowHandleLocked()); - - assertTrue(mTarget.startMovingTask(mWindow.mClient, 0, 0)); - - assertTrue(mTarget.isPositioningLocked()); - assertNotNull(mTarget.getDragWindowHandleLocked()); - - mTarget.finishTaskPositioning(mWindow.mClient); - // Wait until the looper processes finishTaskPositioning. - assertTrue(waitHandlerIdle(mWm.mAnimationHandler, TIMEOUT_MS)); - - assertFalse(mTarget.isPositioningLocked()); - assertNull(mTarget.getDragWindowHandleLocked()); - } - - @Test - public void testHandleTapOutsideTask() { - assertFalse(mTarget.isPositioningLocked()); - assertNull(mTarget.getDragWindowHandleLocked()); - - final DisplayContent content = mock(DisplayContent.class); - doReturn(mWindow.getTask()).when(content).findTaskForResizePoint(anyInt(), anyInt()); - assertNotNull(mWindow.getTask().getTopVisibleAppMainWindow()); - - mTarget.handleTapOutsideTask(content, 0, 0); - // Wait until the looper processes handleTapOutsideTask. - assertTrue(waitHandlerIdle(mWm.mH, TIMEOUT_MS)); - - assertTrue(mTarget.isPositioningLocked()); - assertNotNull(mTarget.getDragWindowHandleLocked()); - - mTarget.finishTaskPositioning(); - // Wait until the looper processes finishTaskPositioning. - assertTrue(waitHandlerIdle(mWm.mAnimationHandler, TIMEOUT_MS)); - - assertFalse(mTarget.isPositioningLocked()); - assertNull(mTarget.getDragWindowHandleLocked()); - } - - @Test - public void testHandleTapOutsideNonResizableTask() { - assertFalse(mTarget.isPositioningLocked()); - assertNull(mTarget.getDragWindowHandleLocked()); - - final DisplayContent content = mock(DisplayContent.class); - doReturn(mWindow.getTask()).when(content).findTaskForResizePoint(anyInt(), anyInt()); - assertNotNull(mWindow.getTask().getTopVisibleAppMainWindow()); - - mWindow.getTask().setResizeMode(RESIZE_MODE_UNRESIZEABLE); - - mTarget.handleTapOutsideTask(content, 0, 0); - // Wait until the looper processes handleTapOutsideTask. - assertTrue(waitHandlerIdle(mWm.mH, TIMEOUT_MS)); - - assertFalse(mTarget.isPositioningLocked()); - } - -} |