Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b977f682 authored by maryam's avatar maryam
Browse files

Rename WindowDecorModelView to reflect purposes

Changed method names in WindowDecorModel Interface to better reflect
their purposes and made onTaskChanging (Previously
setupWindowDecorationForTransition) to handle captionCreation if needed.

Test: Manual Testing and created CaptionWindowDecorViewModelTests
Bug: 257288823
Change-Id: I43672fa37accba97b4ea330e01082d00137a4b01
parent eda61eee
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -82,7 +82,7 @@ public class FreeformTaskListener implements ShellTaskOrganizer.TaskListener {
        mTasks.put(taskInfo.taskId, state);
        if (!Transitions.ENABLE_SHELL_TRANSITIONS) {
            SurfaceControl.Transaction t = new SurfaceControl.Transaction();
            mWindowDecorationViewModel.createWindowDecoration(taskInfo, leash, t, t);
            mWindowDecorationViewModel.onTaskOpening(taskInfo, leash, t, t);
            t.apply();
        }

+7 −15
Original line number Diff line number Diff line
@@ -120,7 +120,7 @@ public class FreeformTaskTransitionObserver implements Transitions.TransitionObs
            TransitionInfo.Change change,
            SurfaceControl.Transaction startT,
            SurfaceControl.Transaction finishT) {
        mWindowDecorViewModel.createWindowDecoration(
        mWindowDecorViewModel.onTaskOpening(
                change.getTaskInfo(), change.getLeash(), startT, finishT);
    }

@@ -128,32 +128,24 @@ public class FreeformTaskTransitionObserver implements Transitions.TransitionObs
            TransitionInfo.Change change,
            SurfaceControl.Transaction startT,
            SurfaceControl.Transaction finishT) {
        mWindowDecorViewModel.setupWindowDecorationForTransition(
                change.getTaskInfo(), startT, finishT);
        mWindowDecorViewModel.onTaskClosing(change.getTaskInfo(), startT, finishT);
    }

    private void onChangeTransitionReady(
            TransitionInfo.Change change,
            SurfaceControl.Transaction startT,
            SurfaceControl.Transaction finishT) {
        mWindowDecorViewModel.setupWindowDecorationForTransition(
                change.getTaskInfo(), startT, finishT);
        mWindowDecorViewModel.onTaskChanging(
                change.getTaskInfo(), change.getLeash(), startT, finishT);
    }

    private void onToFrontTransitionReady(
            TransitionInfo.Change change,
            SurfaceControl.Transaction startT,
            SurfaceControl.Transaction finishT) {
        boolean exists = mWindowDecorViewModel.setupWindowDecorationForTransition(
                change.getTaskInfo(),
                startT,
                finishT);
        if (!exists) {
            // Window caption does not exist, create it
            mWindowDecorViewModel.createWindowDecoration(
        mWindowDecorViewModel.onTaskChanging(
                change.getTaskInfo(), change.getLeash(), startT, finishT);
    }
    }

    @Override
    public void onTransitionStarting(@NonNull IBinder transition) {}
+1 −1
Original line number Diff line number Diff line
@@ -103,7 +103,7 @@ public class FullscreenTaskListener implements ShellTaskOrganizer.TaskListener {
        if (mWindowDecorViewModelOptional.isPresent()) {
            SurfaceControl.Transaction t = new SurfaceControl.Transaction();
            createdWindowDecor = mWindowDecorViewModelOptional.get()
                    .createWindowDecoration(taskInfo, leash, t, t);
                    .onTaskOpening(taskInfo, leash, t, t);
            t.apply();
        }
        if (!createdWindowDecor) {
+114 −42
Original line number Diff line number Diff line
@@ -55,6 +55,8 @@ import com.android.wm.shell.desktopmode.DesktopModeStatus;
import com.android.wm.shell.freeform.FreeformTaskTransitionStarter;
import com.android.wm.shell.transition.Transitions;

import java.util.function.Supplier;

/**
 * View model for the window decoration with a caption and shadows. Works with
 * {@link CaptionWindowDecoration}.
@@ -62,6 +64,8 @@ import com.android.wm.shell.transition.Transitions;

public class CaptionWindowDecorViewModel implements WindowDecorViewModel {
    private static final String TAG = "CaptionViewModel";
    private final CaptionWindowDecoration.Factory mCaptionWindowDecorFactory;
    private final Supplier<InputManager> mInputManagerSupplier;
    private final ActivityTaskManager mActivityTaskManager;
    private final ShellTaskOrganizer mTaskOrganizer;
    private final Context mContext;
@@ -77,6 +81,7 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel {

    private final SparseArray<CaptionWindowDecoration> mWindowDecorByTaskId = new SparseArray<>();
    private final DragStartListenerImpl mDragStartListener = new DragStartListenerImpl();
    private EventReceiverFactory mEventReceiverFactory = new EventReceiverFactory();

    public CaptionWindowDecorViewModel(
            Context context,
@@ -86,6 +91,29 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel {
            DisplayController displayController,
            SyncTransactionQueue syncQueue,
            DesktopModeController desktopModeController) {
        this(
                context,
                mainHandler,
                mainChoreographer,
                taskOrganizer,
                displayController,
                syncQueue,
                desktopModeController,
                new CaptionWindowDecoration.Factory(),
                InputManager::getInstance);
    }

    public CaptionWindowDecorViewModel(
            Context context,
            Handler mainHandler,
            Choreographer mainChoreographer,
            ShellTaskOrganizer taskOrganizer,
            DisplayController displayController,
            SyncTransactionQueue syncQueue,
            DesktopModeController desktopModeController,
            CaptionWindowDecoration.Factory captionWindowDecorFactory,
            Supplier<InputManager> inputManagerSupplier) {

        mContext = context;
        mMainHandler = mainHandler;
        mMainChoreographer = mainChoreographer;
@@ -94,7 +122,13 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel {
        mDisplayController = displayController;
        mSyncQueue = syncQueue;
        mDesktopModeController = desktopModeController;
        mTransitionDragActive = false;

        mCaptionWindowDecorFactory = captionWindowDecorFactory;
        mInputManagerSupplier = inputManagerSupplier;
    }

    void setEventReceiverFactory(EventReceiverFactory eventReceiverFactory) {
        mEventReceiverFactory = eventReceiverFactory;
    }

    @Override
@@ -103,42 +137,13 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel {
    }

    @Override
    public boolean createWindowDecoration(
    public boolean onTaskOpening(
            ActivityManager.RunningTaskInfo taskInfo,
            SurfaceControl taskSurface,
            SurfaceControl.Transaction startT,
            SurfaceControl.Transaction finishT) {
        if (!shouldShowWindowDecor(taskInfo)) return false;
        CaptionWindowDecoration oldDecoration = mWindowDecorByTaskId.get(taskInfo.taskId);
        if (oldDecoration != null) {
            // close the old decoration if it exists to avoid two window decorations being added
            oldDecoration.close();
        }
        final CaptionWindowDecoration windowDecoration = new CaptionWindowDecoration(
                mContext,
                mDisplayController,
                mTaskOrganizer,
                taskInfo,
                taskSurface,
                mMainHandler,
                mMainChoreographer,
                mSyncQueue);
        mWindowDecorByTaskId.put(taskInfo.taskId, windowDecoration);

        TaskPositioner taskPositioner = new TaskPositioner(mTaskOrganizer, windowDecoration,
                mDragStartListener);
        CaptionTouchEventListener touchEventListener =
                new CaptionTouchEventListener(taskInfo, taskPositioner,
                        windowDecoration.getDragDetector());
        windowDecoration.setCaptionListeners(touchEventListener, touchEventListener);
        windowDecoration.setDragResizeCallback(taskPositioner);
        setupWindowDecorationForTransition(taskInfo, startT, finishT);
        if (mInputMonitor == null) {
            mInputMonitor = InputManager.getInstance().monitorGestureInput(
                    "caption-touch", mContext.getDisplayId());
            mEventReceiver = new EventReceiver(
                    mInputMonitor.getInputChannel(), Looper.myLooper());
        }
        createWindowDecoration(taskInfo, taskSurface, startT, finishT);
        return true;
    }

@@ -151,25 +156,45 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel {
    }

    @Override
    public boolean setupWindowDecorationForTransition(
    public void onTaskChanging(
            RunningTaskInfo taskInfo,
            SurfaceControl taskSurface,
            SurfaceControl.Transaction startT,
            SurfaceControl.Transaction finishT) {
        final CaptionWindowDecoration decoration = mWindowDecorByTaskId.get(taskInfo.taskId);
        if (decoration == null) return false;

        if (!shouldShowWindowDecor(taskInfo)) {
            if (decoration != null) {
                destroyWindowDecoration(taskInfo);
            }
            return;
        }

        if (decoration == null) {
            createWindowDecoration(taskInfo, taskSurface, startT, finishT);
        } else {
            decoration.relayout(taskInfo, startT, finishT);
        return true;
        }
    }

    @Override
    public boolean destroyWindowDecoration(RunningTaskInfo taskInfo) {
    public void onTaskClosing(
            RunningTaskInfo taskInfo,
            SurfaceControl.Transaction startT,
            SurfaceControl.Transaction finishT) {
        final CaptionWindowDecoration decoration = mWindowDecorByTaskId.get(taskInfo.taskId);
        if (decoration == null) return;

        decoration.relayout(taskInfo, startT, finishT);
    }

    @Override
    public void destroyWindowDecoration(RunningTaskInfo taskInfo) {
        final CaptionWindowDecoration decoration =
                mWindowDecorByTaskId.removeReturnOld(taskInfo.taskId);
        if (decoration == null) return false;
        if (decoration == null) return;

        decoration.close();
        return true;
    }

    private class CaptionTouchEventListener implements
@@ -217,6 +242,7 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel {
                decoration.setButtonVisibility();
            }
        }

        private void injectBackKey() {
            sendBackEvent(KeyEvent.ACTION_DOWN);
            sendBackEvent(KeyEvent.ACTION_UP);
@@ -302,7 +328,7 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel {
    }

    // InputEventReceiver to listen for touch input outside of caption bounds
    private class EventReceiver extends InputEventReceiver {
    class EventReceiver extends InputEventReceiver {
        EventReceiver(InputChannel channel, Looper looper) {
            super(channel, looper);
        }
@@ -318,8 +344,15 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel {
        }
    }

    class EventReceiverFactory {
        EventReceiver create(InputChannel channel, Looper looper) {
            return new EventReceiver(channel, looper);
        }
    }

    /**
     * Handle MotionEvents relevant to focused task's caption that don't directly touch it
     *
     * @param ev the {@link MotionEvent} received by {@link EventReceiver}
     */
    private void handleReceivedMotionEvent(MotionEvent ev) {
@@ -401,7 +434,6 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel {
        return focusedDecor;
    }


    private boolean shouldShowWindowDecor(RunningTaskInfo taskInfo) {
        if (taskInfo.getWindowingMode() == WINDOWING_MODE_FREEFORM) return true;
        return DesktopModeStatus.IS_SUPPORTED
@@ -410,6 +442,46 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel {
                .getResources().getConfiguration().smallestScreenWidthDp >= 600;
    }

    private void createWindowDecoration(
            ActivityManager.RunningTaskInfo taskInfo,
            SurfaceControl taskSurface,
            SurfaceControl.Transaction startT,
            SurfaceControl.Transaction finishT) {
        CaptionWindowDecoration oldDecoration = mWindowDecorByTaskId.get(taskInfo.taskId);
        if (oldDecoration != null) {
            // close the old decoration if it exists to avoid two window decorations being added
            oldDecoration.close();
        }
        final CaptionWindowDecoration windowDecoration =
                mCaptionWindowDecorFactory.create(
                        mContext,
                        mDisplayController,
                        mTaskOrganizer,
                        taskInfo,
                        taskSurface,
                        mMainHandler,
                        mMainChoreographer,
                        mSyncQueue);
        mWindowDecorByTaskId.put(taskInfo.taskId, windowDecoration);

        TaskPositioner taskPositioner =
                new TaskPositioner(mTaskOrganizer, windowDecoration, mDragStartListener);
        CaptionTouchEventListener touchEventListener =
                new CaptionTouchEventListener(
                        taskInfo, taskPositioner, windowDecoration.getDragDetector());
        windowDecoration.setCaptionListeners(touchEventListener, touchEventListener);
        windowDecoration.setDragResizeCallback(taskPositioner);
        windowDecoration.relayout(taskInfo, startT, finishT);
        if (mInputMonitor == null) {
            InputManager inputManager = mInputManagerSupplier.get();
            mInputMonitor =
                    inputManager.monitorGestureInput("caption-touch", mContext.getDisplayId());
            mEventReceiver =
                    mEventReceiverFactory.create(
                            mInputMonitor.getInputChannel(), Looper.myLooper());
        }
    }

    private class DragStartListenerImpl implements TaskPositioner.DragStartListener {
        @Override
        public void onDragStart(int taskId) {
+36 −9
Original line number Diff line number Diff line
@@ -42,7 +42,8 @@ import com.android.wm.shell.desktopmode.DesktopModeStatus;

/**
 * Defines visuals and behaviors of a window decoration of a caption bar and shadows. It works with
 * {@link CaptionWindowDecorViewModel}. The caption bar contains a handle, back button, and close button.
 * {@link CaptionWindowDecorViewModel}. The caption bar contains a handle, back button, and close
 * button.
 *
 * The shadow's thickness is 20dp when the window is in focus and 5dp when the window isn't.
 */
@@ -242,7 +243,6 @@ public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearL

    /**
     * Sets the visibility of buttons and color of caption based on desktop mode status
     *
     */
    void setButtonVisibility() {
        mDesktopActive = DesktopModeStatus.isActive(mContext);
@@ -313,6 +313,7 @@ public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearL

    /**
     * Close an open handle menu if input is outside of menu coordinates
     *
     * @param ev the tapped point to compare against
     */
    void closeHandleMenuIfNeeded(MotionEvent ev) {
@@ -329,6 +330,7 @@ public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearL

    /**
     * Offset the coordinates of a {@link MotionEvent} to be in the same coordinate space as caption
     *
     * @param ev the {@link MotionEvent} to offset
     * @return the point of the input in local space
     */
@@ -343,6 +345,7 @@ public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearL

    /**
     * Determine if a passed MotionEvent is in a view in caption
     *
     * @param ev       the {@link MotionEvent} to check
     * @param layoutId the id of the view
     * @return {@code true} if event is inside the specified view, {@code false} if not
@@ -363,6 +366,7 @@ public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearL
     * Check a passed MotionEvent if a click has occurred on any button on this caption
     * Note this should only be called when a regular onClick is not possible
     * (i.e. the button was clicked through status bar layer)
     *
     * @param ev the MotionEvent to compare
     */
    void checkClickEvent(MotionEvent ev) {
@@ -399,4 +403,27 @@ public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearL
        closeHandleMenu();
        super.close();
    }

    static class Factory {

        CaptionWindowDecoration create(
                Context context,
                DisplayController displayController,
                ShellTaskOrganizer taskOrganizer,
                ActivityManager.RunningTaskInfo taskInfo,
                SurfaceControl taskSurface,
                Handler handler,
                Choreographer choreographer,
                SyncTransactionQueue syncQueue) {
            return new CaptionWindowDecoration(
                    context,
                    displayController,
                    taskOrganizer,
                    taskInfo,
                    taskSurface,
                    handler,
                    choreographer,
                    syncQueue);
        }
    }
}
Loading