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

Commit f1f6d0c7 authored by Automerger Merge Worker's avatar Automerger Merge Worker Committed by Android (Google) Code Review
Browse files

Merge "Merge "Prevent desktop mode corner handles from triggering back...

Merge "Merge "Prevent desktop mode corner handles from triggering back gesture." into udc-dev am: 331d9987 am: 28ba9135"
parents dd4e0d8f 8ad623a1
Loading
Loading
Loading
Loading
+13 −1
Original line number Diff line number Diff line
@@ -16,9 +16,12 @@

package com.android.wm.shell.desktopmode;

import android.graphics.Region;

import com.android.wm.shell.common.annotations.ExternalThread;

import java.util.concurrent.Executor;
import java.util.function.Consumer;

/**
 * Interface to interact with desktop mode feature in shell.
@@ -32,7 +35,16 @@ public interface DesktopMode {
     * @param listener the listener to add.
     * @param callbackExecutor the executor to call the listener on.
     */
    void addListener(DesktopModeTaskRepository.VisibleTasksListener listener,
    void addVisibleTasksListener(DesktopModeTaskRepository.VisibleTasksListener listener,
            Executor callbackExecutor);

    /**
     * Adds a consumer to listen for Desktop task corner changes. This is used for gesture
     * exclusion. The SparseArray contains a list of four corner resize handles mapped to each
     * desktop task's taskId. The resize handle Rects are stored in the following order:
     * left-top, left-bottom, right-top, right-bottom.
     */
    default void addDesktopGestureExclusionRegionListener(Consumer<Region> listener,
            Executor callbackExecutor) { }

}
+41 −3
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@ import android.app.ActivityManager.RunningTaskInfo;
import android.app.WindowConfiguration;
import android.content.Context;
import android.database.ContentObserver;
import android.graphics.Region;
import android.net.Uri;
import android.os.Handler;
import android.os.IBinder;
@@ -69,6 +70,7 @@ import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.function.Consumer;

/**
 * Handles windowing changes when desktop mode system setting changes
@@ -149,11 +151,21 @@ public class DesktopModeController implements RemoteCallable<DesktopModeControll
     * @param listener the listener to add.
     * @param callbackExecutor the executor to call the listener on.
     */
    public void addListener(DesktopModeTaskRepository.VisibleTasksListener listener,
    public void addVisibleTasksListener(DesktopModeTaskRepository.VisibleTasksListener listener,
            Executor callbackExecutor) {
        mDesktopModeTaskRepository.addVisibleTasksListener(listener, callbackExecutor);
    }

    /**
     * Adds a listener to track changes to corners of desktop mode tasks.
     * @param listener the listener to add.
     * @param callbackExecutor the executor to call the listener on.
     */
    public void addTaskCornerListener(Consumer<Region> listener,
            Executor callbackExecutor) {
        mDesktopModeTaskRepository.setTaskCornerListener(listener, callbackExecutor);
    }

    @VisibleForTesting
    void updateDesktopModeActive(boolean active) {
        ProtoLog.d(WM_SHELL_DESKTOP_MODE, "updateDesktopModeActive: active=%s", active);
@@ -311,6 +323,23 @@ public class DesktopModeController implements RemoteCallable<DesktopModeControll
        }
    }

    /**
     * Update corner rects stored for a specific task
     * @param taskId task to update
     * @param taskCorners task's new corner handles
     */
    public void onTaskCornersChanged(int taskId, Region taskCorners) {
        mDesktopModeTaskRepository.updateTaskCorners(taskId, taskCorners);
    }

    /**
     * Remove corners saved for a task. Likely used due to task closure.
     * @param taskId task to remove
     */
    public void removeCornersForTask(int taskId) {
        mDesktopModeTaskRepository.removeTaskCorners(taskId);
    }

    /**
     * Moves a specifc task to the front.
     * @param taskInfo the task to show in front.
@@ -426,10 +455,19 @@ public class DesktopModeController implements RemoteCallable<DesktopModeControll
    private final class DesktopModeImpl implements DesktopMode {

        @Override
        public void addListener(DesktopModeTaskRepository.VisibleTasksListener listener,
        public void addVisibleTasksListener(
                DesktopModeTaskRepository.VisibleTasksListener listener,
                Executor callbackExecutor) {
            mMainExecutor.execute(() -> {
                DesktopModeController.this.addVisibleTasksListener(listener, callbackExecutor);
            });
        }

        @Override
        public void addDesktopGestureExclusionRegionListener(Consumer<Region> listener,
                Executor callbackExecutor) {
            mMainExecutor.execute(() -> {
                DesktopModeController.this.addListener(listener, callbackExecutor);
                DesktopModeController.this.addTaskCornerListener(listener, callbackExecutor);
            });
        }
    }
+52 −0
Original line number Diff line number Diff line
@@ -16,9 +16,13 @@

package com.android.wm.shell.desktopmode

import android.graphics.Region
import android.util.ArrayMap
import android.util.ArraySet
import android.util.SparseArray
import androidx.core.util.valueIterator
import java.util.concurrent.Executor
import java.util.function.Consumer

/**
 * Keeps track of task data related to desktop mode.
@@ -38,6 +42,10 @@ class DesktopModeTaskRepository {
    private val activeTasksListeners = ArraySet<ActiveTasksListener>()
    // Track visible tasks separately because a task may be part of the desktop but not visible.
    private val visibleTasksListeners = ArrayMap<VisibleTasksListener, Executor>()
    // Track corners of desktop tasks, used to determine gesture exclusion
    private val desktopCorners = SparseArray<Region>()
    private var desktopGestureExclusionListener: Consumer<Region>? = null
    private var desktopGestureExclusionExecutor: Executor? = null

    /**
     * Add a [ActiveTasksListener] to be notified of updates to active tasks in the repository.
@@ -55,6 +63,28 @@ class DesktopModeTaskRepository {
                Runnable { visibleTasksListener.onVisibilityChanged(visibleTasks.size > 0) })
    }

    /**
     * Add a Consumer which will inform other classes of changes to corners for all Desktop tasks.
     */
    fun setTaskCornerListener(cornersListener: Consumer<Region>, executor: Executor) {
        desktopGestureExclusionListener = cornersListener
        desktopGestureExclusionExecutor = executor
        executor.execute {
            desktopGestureExclusionListener?.accept(calculateDesktopExclusionRegion())
        }
    }

    /**
     * Create a new merged region representative of all corners in all desktop tasks.
     */
    private fun calculateDesktopExclusionRegion(): Region {
        val desktopCornersRegion = Region()
        desktopCorners.valueIterator().forEach { taskCorners ->
            desktopCornersRegion.op(taskCorners, Region.Op.UNION)
        }
        return desktopCornersRegion
    }

    /**
     * Remove a previously registered [ActiveTasksListener]
     */
@@ -166,6 +196,28 @@ class DesktopModeTaskRepository {
        freeformTasksInZOrder.remove(taskId)
    }

    /**
     * Updates the active desktop corners; if desktopCorners has been accepted by
     * desktopCornersListener, it will be updated in the appropriate classes.
     */
    fun updateTaskCorners(taskId: Int, taskCorners: Region) {
        desktopCorners.put(taskId, taskCorners)
        desktopGestureExclusionExecutor?.execute {
            desktopGestureExclusionListener?.accept(calculateDesktopExclusionRegion())
        }
    }

    /**
     * Removes the active desktop corners for the specified task; if desktopCorners has been
     * accepted by desktopCornersListener, it will be updated in the appropriate classes.
     */
    fun removeTaskCorners(taskId: Int) {
        desktopCorners.delete(taskId)
        desktopGestureExclusionExecutor?.execute {
            desktopGestureExclusionListener?.accept(calculateDesktopExclusionRegion())
        }
    }

    /**
     * Defines interface for classes that can listen to changes for active tasks in desktop mode.
     */
+45 −3
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import android.app.WindowConfiguration.WindowingMode
import android.content.Context
import android.graphics.Point
import android.graphics.Rect
import android.graphics.Region
import android.os.IBinder
import android.os.SystemProperties
import android.view.SurfaceControl
@@ -487,6 +488,20 @@ class DesktopTasksController(
        return 2 * getStatusBarHeight(taskInfo)
    }

    /**
     * Update the corner region for a specified task
     */
    fun onTaskCornersChanged(taskId: Int, corner: Region) {
        desktopModeTaskRepository.updateTaskCorners(taskId, corner)
    }

    /**
     * Remove a previously tracked corner region for a specified task.
     */
    fun removeCornersForTask(taskId: Int) {
        desktopModeTaskRepository.removeTaskCorners(taskId)
    }


    /**
     * Adds a listener to find out about changes in the visibility of freeform tasks.
@@ -494,20 +509,47 @@ class DesktopTasksController(
     * @param listener the listener to add.
     * @param callbackExecutor the executor to call the listener on.
     */
    fun addListener(listener: VisibleTasksListener, callbackExecutor: Executor) {
    fun addVisibleTasksListener(listener: VisibleTasksListener, callbackExecutor: Executor) {
        desktopModeTaskRepository.addVisibleTasksListener(listener, callbackExecutor)
    }

    /**
     * Adds a listener to track changes to desktop task corners
     *
     * @param listener the listener to add.
     * @param callbackExecutor the executor to call the listener on.
     */
    fun setTaskCornerListener(
            listener: Consumer<Region>,
            callbackExecutor: Executor
    ) {
        desktopModeTaskRepository.setTaskCornerListener(listener, callbackExecutor)
    }

    /** The interface for calls from outside the shell, within the host process. */
    @ExternalThread
    private inner class DesktopModeImpl : DesktopMode {
        override fun addListener(listener: VisibleTasksListener, callbackExecutor: Executor) {
        override fun addVisibleTasksListener(
                listener: VisibleTasksListener,
                callbackExecutor: Executor
        ) {
            mainExecutor.execute {
                this@DesktopTasksController.addVisibleTasksListener(listener, callbackExecutor)
            }
        }

        override fun addDesktopGestureExclusionRegionListener(
                listener: Consumer<Region>,
                callbackExecutor: Executor
        ) {
            mainExecutor.execute {
                this@DesktopTasksController.addListener(listener, callbackExecutor)
                this@DesktopTasksController.setTaskCornerListener(listener, callbackExecutor)
            }
        }
    }



    /** The interface for calls from outside the host process. */
    @BinderThread
    private class IDesktopModeImpl(private var controller: DesktopTasksController?) :
+23 −2
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ import android.content.Context;
import android.content.res.Resources;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.Region;
import android.hardware.input.InputManager;
import android.os.Handler;
import android.os.IBinder;
@@ -69,6 +70,7 @@ import com.android.wm.shell.desktopmode.DesktopTasksController;
import com.android.wm.shell.freeform.FreeformTaskTransitionStarter;
import com.android.wm.shell.splitscreen.SplitScreenController;
import com.android.wm.shell.transition.Transitions;
import com.android.wm.shell.windowdecor.DesktopModeWindowDecoration.TaskCornersListener;

import java.util.Optional;
import java.util.function.Supplier;
@@ -95,9 +97,11 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {

    private SparseArray<EventReceiver> mEventReceiversByDisplay = new SparseArray<>();

    private final TaskCornersListener mCornersListener = new TaskCornersListenerImpl();

    private final SparseArray<DesktopModeWindowDecoration> mWindowDecorByTaskId =
            new SparseArray<>();
    private final DragStartListenerImpl mDragStartListener = new DragStartListenerImpl();
    private final DragListenerImpl mDragStartListener = new DragListenerImpl();
    private final InputMonitorFactory mInputMonitorFactory;
    private TaskOperations mTaskOperations;
    private final Supplier<SurfaceControl.Transaction> mTransactionFactory;
@@ -779,6 +783,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
        final DesktopModeTouchEventListener touchEventListener =
                new DesktopModeTouchEventListener(taskInfo, taskPositioner);
        windowDecoration.setCaptionListeners(touchEventListener, touchEventListener);
        windowDecoration.setCornersListener(mCornersListener);
        windowDecoration.setDragPositioningCallback(taskPositioner);
        windowDecoration.setDragDetector(touchEventListener.mDragDetector);
        windowDecoration.relayout(taskInfo, startT, finishT,
@@ -786,7 +791,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
        incrementEventReceiverTasks(taskInfo.displayId);
    }

    private class DragStartListenerImpl implements TaskPositioner.DragStartListener {
    private class DragListenerImpl implements TaskPositioner.DragStartListener {
        @Override
        public void onDragStart(int taskId) {
            mWindowDecorByTaskId.get(taskId).closeHandleMenu();
@@ -798,6 +803,22 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
            return inputManager.monitorGestureInput("caption-touch", context.getDisplayId());
        }
    }

    private class TaskCornersListenerImpl
            implements DesktopModeWindowDecoration.TaskCornersListener {

        @Override
        public void onTaskCornersChanged(int taskId, Region corner) {
            mDesktopModeController.ifPresent(d -> d.onTaskCornersChanged(taskId, corner));
            mDesktopTasksController.ifPresent(d -> d.onTaskCornersChanged(taskId, corner));
        }

        @Override
        public void onTaskCornersRemoved(int taskId) {
            mDesktopModeController.ifPresent(d -> d.removeCornersForTask(taskId));
            mDesktopTasksController.ifPresent(d -> d.removeCornersForTask(taskId));
        }
    }
}

Loading