Loading libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopMode.java +12 −0 Original line number Diff line number Diff line Loading @@ -18,9 +18,21 @@ package com.android.wm.shell.desktopmode; import com.android.wm.shell.common.annotations.ExternalThread; import java.util.concurrent.Executor; /** * Interface to interact with desktop mode feature in shell. */ @ExternalThread public interface DesktopMode { /** * Adds a listener to find out about changes in the visibility of freeform tasks. * * @param listener the listener to add. * @param callbackExecutor the executor to call the listener on. */ void addListener(DesktopModeTaskRepository.VisibleTasksListener listener, Executor callbackExecutor); } libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeController.java +20 −1 Original line number Diff line number Diff line Loading @@ -60,6 +60,7 @@ import com.android.wm.shell.transition.Transitions; import java.util.ArrayList; import java.util.Comparator; import java.util.concurrent.Executor; /** * Handles windowing changes when desktop mode system setting changes Loading Loading @@ -132,6 +133,17 @@ public class DesktopModeController implements RemoteCallable<DesktopModeControll return new IDesktopModeImpl(this); } /** * Adds a listener to find out about changes in the visibility of freeform tasks. * * @param listener the listener to add. * @param callbackExecutor the executor to call the listener on. */ public void addListener(DesktopModeTaskRepository.VisibleTasksListener listener, Executor callbackExecutor) { mDesktopModeTaskRepository.addVisibleTasksListener(listener, callbackExecutor); } @VisibleForTesting void updateDesktopModeActive(boolean active) { ProtoLog.d(WM_SHELL_DESKTOP_MODE, "updateDesktopModeActive: active=%s", active); Loading Loading @@ -293,7 +305,14 @@ public class DesktopModeController implements RemoteCallable<DesktopModeControll */ @ExternalThread private final class DesktopModeImpl implements DesktopMode { // Do nothing @Override public void addListener(DesktopModeTaskRepository.VisibleTasksListener listener, Executor callbackExecutor) { mMainExecutor.execute(() -> { DesktopModeController.this.addListener(listener, callbackExecutor); }); } } /** Loading libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeTaskRepository.kt +67 −12 Original line number Diff line number Diff line Loading @@ -16,7 +16,9 @@ package com.android.wm.shell.desktopmode import android.util.ArrayMap import android.util.ArraySet import java.util.concurrent.Executor /** * Keeps track of task data related to desktop mode. Loading @@ -30,20 +32,39 @@ class DesktopModeTaskRepository { * Task gets removed from this list when it vanishes. Or when desktop mode is turned off. */ private val activeTasks = ArraySet<Int>() private val listeners = ArraySet<Listener>() private val visibleTasks = ArraySet<Int>() 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>() /** * Add a [Listener] to be notified of updates to the repository. * Add a [ActiveTasksListener] to be notified of updates to active tasks in the repository. */ fun addListener(listener: Listener) { listeners.add(listener) fun addActiveTaskListener(activeTasksListener: ActiveTasksListener) { activeTasksListeners.add(activeTasksListener) } /** * Remove a previously registered [Listener] * Add a [VisibleTasksListener] to be notified when freeform tasks are visible or not. */ fun removeListener(listener: Listener) { listeners.remove(listener) fun addVisibleTasksListener(visibleTasksListener: VisibleTasksListener, executor: Executor) { visibleTasksListeners.put(visibleTasksListener, executor) executor.execute( Runnable { visibleTasksListener.onVisibilityChanged(visibleTasks.size > 0) }) } /** * Remove a previously registered [ActiveTasksListener] */ fun removeActiveTasksListener(activeTasksListener: ActiveTasksListener) { activeTasksListeners.remove(activeTasksListener) } /** * Remove a previously registered [VisibleTasksListener] */ fun removeVisibleTasksListener(visibleTasksListener: VisibleTasksListener) { visibleTasksListeners.remove(visibleTasksListener) } /** Loading @@ -52,7 +73,7 @@ class DesktopModeTaskRepository { fun addActiveTask(taskId: Int) { val added = activeTasks.add(taskId) if (added) { listeners.onEach { it.onActiveTasksChanged() } activeTasksListeners.onEach { it.onActiveTasksChanged() } } } Loading @@ -62,7 +83,7 @@ class DesktopModeTaskRepository { fun removeActiveTask(taskId: Int) { val removed = activeTasks.remove(taskId) if (removed) { listeners.onEach { it.onActiveTasksChanged() } activeTasksListeners.onEach { it.onActiveTasksChanged() } } } Loading @@ -81,9 +102,43 @@ class DesktopModeTaskRepository { } /** * Defines interface for classes that can listen to changes in repository state. * Updates whether a freeform task with this id is visible or not and notifies listeners. */ fun updateVisibleFreeformTasks(taskId: Int, visible: Boolean) { val prevCount: Int = visibleTasks.size if (visible) { visibleTasks.add(taskId) } else { visibleTasks.remove(taskId) } if (prevCount == 0 && visibleTasks.size == 1 || prevCount > 0 && visibleTasks.size == 0) { for ((listener, executor) in visibleTasksListeners) { executor.execute( Runnable { listener.onVisibilityChanged(visibleTasks.size > 0) }) } } } /** * Defines interface for classes that can listen to changes for active tasks in desktop mode. */ interface ActiveTasksListener { /** * Called when the active tasks change in desktop mode. */ @JvmDefault fun onActiveTasksChanged() {} } /** * Defines interface for classes that can listen to changes for visible tasks in desktop mode. */ interface VisibleTasksListener { /** * Called when the desktop starts or stops showing freeform tasks. */ interface Listener { fun onActiveTasksChanged() @JvmDefault fun onVisibilityChanged(hasVisibleFreeformTasks: Boolean) {} } } libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskListener.java +6 −0 Original line number Diff line number Diff line Loading @@ -90,6 +90,8 @@ public class FreeformTaskListener implements ShellTaskOrganizer.TaskListener { ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE, "Adding active freeform task: #%d", taskInfo.taskId); mDesktopModeTaskRepository.ifPresent(it -> it.addActiveTask(taskInfo.taskId)); mDesktopModeTaskRepository.ifPresent( it -> it.updateVisibleFreeformTasks(taskInfo.taskId, true)); } } Loading @@ -103,6 +105,8 @@ public class FreeformTaskListener implements ShellTaskOrganizer.TaskListener { ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE, "Removing active freeform task: #%d", taskInfo.taskId); mDesktopModeTaskRepository.ifPresent(it -> it.removeActiveTask(taskInfo.taskId)); mDesktopModeTaskRepository.ifPresent( it -> it.updateVisibleFreeformTasks(taskInfo.taskId, false)); } if (!Transitions.ENABLE_SHELL_TRANSITIONS) { Loading @@ -124,6 +128,8 @@ public class FreeformTaskListener implements ShellTaskOrganizer.TaskListener { "Adding active freeform task: #%d", taskInfo.taskId); mDesktopModeTaskRepository.ifPresent(it -> it.addActiveTask(taskInfo.taskId)); } mDesktopModeTaskRepository.ifPresent( it -> it.updateVisibleFreeformTasks(taskInfo.taskId, taskInfo.isVisible)); } } Loading libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java +2 −2 Original line number Diff line number Diff line Loading @@ -68,7 +68,7 @@ import java.util.function.Consumer; * Manages the recent task list from the system, caching it as necessary. */ public class RecentTasksController implements TaskStackListenerCallback, RemoteCallable<RecentTasksController>, DesktopModeTaskRepository.Listener { RemoteCallable<RecentTasksController>, DesktopModeTaskRepository.ActiveTasksListener { private static final String TAG = RecentTasksController.class.getSimpleName(); private final Context mContext; Loading Loading @@ -147,7 +147,7 @@ public class RecentTasksController implements TaskStackListenerCallback, this::createExternalInterface, this); mShellCommandHandler.addDumpCallback(this::dump, this); mTaskStackListener.addListener(this); mDesktopModeTaskRepository.ifPresent(it -> it.addListener(this)); mDesktopModeTaskRepository.ifPresent(it -> it.addActiveTaskListener(this)); } /** Loading Loading
libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopMode.java +12 −0 Original line number Diff line number Diff line Loading @@ -18,9 +18,21 @@ package com.android.wm.shell.desktopmode; import com.android.wm.shell.common.annotations.ExternalThread; import java.util.concurrent.Executor; /** * Interface to interact with desktop mode feature in shell. */ @ExternalThread public interface DesktopMode { /** * Adds a listener to find out about changes in the visibility of freeform tasks. * * @param listener the listener to add. * @param callbackExecutor the executor to call the listener on. */ void addListener(DesktopModeTaskRepository.VisibleTasksListener listener, Executor callbackExecutor); }
libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeController.java +20 −1 Original line number Diff line number Diff line Loading @@ -60,6 +60,7 @@ import com.android.wm.shell.transition.Transitions; import java.util.ArrayList; import java.util.Comparator; import java.util.concurrent.Executor; /** * Handles windowing changes when desktop mode system setting changes Loading Loading @@ -132,6 +133,17 @@ public class DesktopModeController implements RemoteCallable<DesktopModeControll return new IDesktopModeImpl(this); } /** * Adds a listener to find out about changes in the visibility of freeform tasks. * * @param listener the listener to add. * @param callbackExecutor the executor to call the listener on. */ public void addListener(DesktopModeTaskRepository.VisibleTasksListener listener, Executor callbackExecutor) { mDesktopModeTaskRepository.addVisibleTasksListener(listener, callbackExecutor); } @VisibleForTesting void updateDesktopModeActive(boolean active) { ProtoLog.d(WM_SHELL_DESKTOP_MODE, "updateDesktopModeActive: active=%s", active); Loading Loading @@ -293,7 +305,14 @@ public class DesktopModeController implements RemoteCallable<DesktopModeControll */ @ExternalThread private final class DesktopModeImpl implements DesktopMode { // Do nothing @Override public void addListener(DesktopModeTaskRepository.VisibleTasksListener listener, Executor callbackExecutor) { mMainExecutor.execute(() -> { DesktopModeController.this.addListener(listener, callbackExecutor); }); } } /** Loading
libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeTaskRepository.kt +67 −12 Original line number Diff line number Diff line Loading @@ -16,7 +16,9 @@ package com.android.wm.shell.desktopmode import android.util.ArrayMap import android.util.ArraySet import java.util.concurrent.Executor /** * Keeps track of task data related to desktop mode. Loading @@ -30,20 +32,39 @@ class DesktopModeTaskRepository { * Task gets removed from this list when it vanishes. Or when desktop mode is turned off. */ private val activeTasks = ArraySet<Int>() private val listeners = ArraySet<Listener>() private val visibleTasks = ArraySet<Int>() 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>() /** * Add a [Listener] to be notified of updates to the repository. * Add a [ActiveTasksListener] to be notified of updates to active tasks in the repository. */ fun addListener(listener: Listener) { listeners.add(listener) fun addActiveTaskListener(activeTasksListener: ActiveTasksListener) { activeTasksListeners.add(activeTasksListener) } /** * Remove a previously registered [Listener] * Add a [VisibleTasksListener] to be notified when freeform tasks are visible or not. */ fun removeListener(listener: Listener) { listeners.remove(listener) fun addVisibleTasksListener(visibleTasksListener: VisibleTasksListener, executor: Executor) { visibleTasksListeners.put(visibleTasksListener, executor) executor.execute( Runnable { visibleTasksListener.onVisibilityChanged(visibleTasks.size > 0) }) } /** * Remove a previously registered [ActiveTasksListener] */ fun removeActiveTasksListener(activeTasksListener: ActiveTasksListener) { activeTasksListeners.remove(activeTasksListener) } /** * Remove a previously registered [VisibleTasksListener] */ fun removeVisibleTasksListener(visibleTasksListener: VisibleTasksListener) { visibleTasksListeners.remove(visibleTasksListener) } /** Loading @@ -52,7 +73,7 @@ class DesktopModeTaskRepository { fun addActiveTask(taskId: Int) { val added = activeTasks.add(taskId) if (added) { listeners.onEach { it.onActiveTasksChanged() } activeTasksListeners.onEach { it.onActiveTasksChanged() } } } Loading @@ -62,7 +83,7 @@ class DesktopModeTaskRepository { fun removeActiveTask(taskId: Int) { val removed = activeTasks.remove(taskId) if (removed) { listeners.onEach { it.onActiveTasksChanged() } activeTasksListeners.onEach { it.onActiveTasksChanged() } } } Loading @@ -81,9 +102,43 @@ class DesktopModeTaskRepository { } /** * Defines interface for classes that can listen to changes in repository state. * Updates whether a freeform task with this id is visible or not and notifies listeners. */ fun updateVisibleFreeformTasks(taskId: Int, visible: Boolean) { val prevCount: Int = visibleTasks.size if (visible) { visibleTasks.add(taskId) } else { visibleTasks.remove(taskId) } if (prevCount == 0 && visibleTasks.size == 1 || prevCount > 0 && visibleTasks.size == 0) { for ((listener, executor) in visibleTasksListeners) { executor.execute( Runnable { listener.onVisibilityChanged(visibleTasks.size > 0) }) } } } /** * Defines interface for classes that can listen to changes for active tasks in desktop mode. */ interface ActiveTasksListener { /** * Called when the active tasks change in desktop mode. */ @JvmDefault fun onActiveTasksChanged() {} } /** * Defines interface for classes that can listen to changes for visible tasks in desktop mode. */ interface VisibleTasksListener { /** * Called when the desktop starts or stops showing freeform tasks. */ interface Listener { fun onActiveTasksChanged() @JvmDefault fun onVisibilityChanged(hasVisibleFreeformTasks: Boolean) {} } }
libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskListener.java +6 −0 Original line number Diff line number Diff line Loading @@ -90,6 +90,8 @@ public class FreeformTaskListener implements ShellTaskOrganizer.TaskListener { ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE, "Adding active freeform task: #%d", taskInfo.taskId); mDesktopModeTaskRepository.ifPresent(it -> it.addActiveTask(taskInfo.taskId)); mDesktopModeTaskRepository.ifPresent( it -> it.updateVisibleFreeformTasks(taskInfo.taskId, true)); } } Loading @@ -103,6 +105,8 @@ public class FreeformTaskListener implements ShellTaskOrganizer.TaskListener { ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE, "Removing active freeform task: #%d", taskInfo.taskId); mDesktopModeTaskRepository.ifPresent(it -> it.removeActiveTask(taskInfo.taskId)); mDesktopModeTaskRepository.ifPresent( it -> it.updateVisibleFreeformTasks(taskInfo.taskId, false)); } if (!Transitions.ENABLE_SHELL_TRANSITIONS) { Loading @@ -124,6 +128,8 @@ public class FreeformTaskListener implements ShellTaskOrganizer.TaskListener { "Adding active freeform task: #%d", taskInfo.taskId); mDesktopModeTaskRepository.ifPresent(it -> it.addActiveTask(taskInfo.taskId)); } mDesktopModeTaskRepository.ifPresent( it -> it.updateVisibleFreeformTasks(taskInfo.taskId, taskInfo.isVisible)); } } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java +2 −2 Original line number Diff line number Diff line Loading @@ -68,7 +68,7 @@ import java.util.function.Consumer; * Manages the recent task list from the system, caching it as necessary. */ public class RecentTasksController implements TaskStackListenerCallback, RemoteCallable<RecentTasksController>, DesktopModeTaskRepository.Listener { RemoteCallable<RecentTasksController>, DesktopModeTaskRepository.ActiveTasksListener { private static final String TAG = RecentTasksController.class.getSimpleName(); private final Context mContext; Loading Loading @@ -147,7 +147,7 @@ public class RecentTasksController implements TaskStackListenerCallback, this::createExternalInterface, this); mShellCommandHandler.addDumpCallback(this::dump, this); mTaskStackListener.addListener(this); mDesktopModeTaskRepository.ifPresent(it -> it.addListener(this)); mDesktopModeTaskRepository.ifPresent(it -> it.addActiveTaskListener(this)); } /** Loading