Loading libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java +5 −1 Original line number Diff line number Diff line Loading @@ -876,8 +876,12 @@ public class ShellTaskOrganizer extends TaskOrganizer implements pkg = info.getTaskInfo().baseActivity.getPackageName(); } Rect bounds = info.getTaskInfo().getConfiguration().windowConfiguration.getBounds(); boolean running = info.getTaskInfo().isRunning; boolean visible = info.getTaskInfo().isVisible; boolean focused = info.getTaskInfo().isFocused; pw.println(innerPrefix + "#" + i + " task=" + key + " listener=" + listener + " wmMode=" + windowingMode + " pkg=" + pkg + " bounds=" + bounds); + " wmMode=" + windowingMode + " pkg=" + pkg + " bounds=" + bounds + " running=" + running + " visible=" + visible + " focused=" + focused); } pw.println(); Loading libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java +2 −1 Original line number Diff line number Diff line Loading @@ -220,13 +220,14 @@ public abstract class WMShellModule { Context context, ShellInit shellInit, ShellTaskOrganizer shellTaskOrganizer, Optional<RecentTasksController> recentTasksController, WindowDecorViewModel<?> windowDecorViewModel) { // TODO(b/238217847): Temporarily add this check here until we can remove the dynamic // override for this controller from the base module ShellInit init = FreeformComponents.isFreeformEnabled(context) ? shellInit : null; return new FreeformTaskListener<>(init, shellTaskOrganizer, return new FreeformTaskListener<>(init, shellTaskOrganizer, recentTasksController, windowDecorViewModel); } Loading libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopMode.java +1 −1 Original line number Diff line number Diff line Loading @@ -50,7 +50,7 @@ public class DesktopMode { Settings.System.DESKTOP_MODE, UserHandle.USER_CURRENT); ProtoLog.d(WM_SHELL_DESKTOP_MODE, "isDesktopModeEnabled=%s", result); return result != 0; } catch (Settings.SettingNotFoundException e) { } catch (Exception e) { ProtoLog.e(WM_SHELL_DESKTOP_MODE, "Failed to read DESKTOP_MODE setting %s", e); return false; } Loading libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskListener.java +26 −0 Original line number Diff line number Diff line Loading @@ -28,12 +28,15 @@ import androidx.annotation.Nullable; import com.android.internal.protolog.common.ProtoLog; import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.desktopmode.DesktopMode; import com.android.wm.shell.protolog.ShellProtoLogGroup; import com.android.wm.shell.recents.RecentTasksController; import com.android.wm.shell.sysui.ShellInit; import com.android.wm.shell.transition.Transitions; import com.android.wm.shell.windowdecor.WindowDecorViewModel; import java.io.PrintWriter; import java.util.Optional; /** * {@link ShellTaskOrganizer.TaskListener} for {@link Loading @@ -46,6 +49,7 @@ public class FreeformTaskListener<T extends AutoCloseable> private static final String TAG = "FreeformTaskListener"; private final ShellTaskOrganizer mShellTaskOrganizer; private final Optional<RecentTasksController> mRecentTasksOptional; private final WindowDecorViewModel<T> mWindowDecorationViewModel; private final SparseArray<State<T>> mTasks = new SparseArray<>(); Loading @@ -60,9 +64,11 @@ public class FreeformTaskListener<T extends AutoCloseable> public FreeformTaskListener( ShellInit shellInit, ShellTaskOrganizer shellTaskOrganizer, Optional<RecentTasksController> recentTasksController, WindowDecorViewModel<T> windowDecorationViewModel) { mShellTaskOrganizer = shellTaskOrganizer; mWindowDecorationViewModel = windowDecorationViewModel; mRecentTasksOptional = recentTasksController; if (shellInit != null) { shellInit.addInitCallback(this::onInit, this); } Loading @@ -83,6 +89,12 @@ public class FreeformTaskListener<T extends AutoCloseable> mWindowDecorationViewModel.createWindowDecoration(taskInfo, leash, t, t); t.apply(); } if (DesktopMode.IS_SUPPORTED && taskInfo.isVisible) { ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE, "Adding active freeform task: #%d", taskInfo.taskId); mRecentTasksOptional.ifPresent(rt -> rt.addActiveFreeformTask(taskInfo.taskId)); } } private State<T> createOrUpdateTaskState(RunningTaskInfo taskInfo, SurfaceControl leash) { Loading Loading @@ -111,6 +123,12 @@ public class FreeformTaskListener<T extends AutoCloseable> taskInfo.taskId); mTasks.remove(taskInfo.taskId); if (DesktopMode.IS_SUPPORTED) { ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE, "Removing active freeform task: #%d", taskInfo.taskId); mRecentTasksOptional.ifPresent(rt -> rt.removeActiveFreeformTask(taskInfo.taskId)); } if (Transitions.ENABLE_SHELL_TRANSITIONS) { // Save window decorations of closing tasks so that we can hand them over to the // transition system if this method happens before the transition. In case where the Loading @@ -131,6 +149,14 @@ public class FreeformTaskListener<T extends AutoCloseable> if (state.mWindowDecoration != null) { mWindowDecorationViewModel.onTaskInfoChanged(state.mTaskInfo, state.mWindowDecoration); } if (DesktopMode.IS_SUPPORTED) { if (taskInfo.isVisible) { ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE, "Adding active freeform task: #%d", taskInfo.taskId); mRecentTasksOptional.ifPresent(rt -> rt.addActiveFreeformTask(taskInfo.taskId)); } } } private State<T> updateTaskInfo(RunningTaskInfo taskInfo) { Loading libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java +48 −3 Original line number Diff line number Diff line Loading @@ -43,6 +43,7 @@ import com.android.wm.shell.common.TaskStackListenerCallback; import com.android.wm.shell.common.TaskStackListenerImpl; import com.android.wm.shell.common.annotations.ExternalThread; import com.android.wm.shell.common.annotations.ShellMainThread; import com.android.wm.shell.desktopmode.DesktopMode; import com.android.wm.shell.protolog.ShellProtoLogGroup; import com.android.wm.shell.sysui.ShellCommandHandler; import com.android.wm.shell.sysui.ShellInit; Loading @@ -52,6 +53,7 @@ import com.android.wm.shell.util.SplitBounds; import java.io.PrintWriter; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; Loading Loading @@ -81,6 +83,15 @@ public class RecentTasksController implements TaskStackListenerCallback, */ private final Map<Integer, SplitBounds> mTaskSplitBoundsMap = new HashMap<>(); /** * Set of taskId's that have been launched in freeform mode. * This includes tasks that are currently running, visible and in freeform mode. And also * includes tasks that are running in the background, are no longer visible, but at some point * were visible to the user. * This is used to decide which freeform apps belong to the user's desktop. */ private final HashSet<Integer> mActiveFreeformTasks = new HashSet<>(); /** * Creates {@link RecentTasksController}, returns {@code null} if the feature is not * supported. Loading Loading @@ -206,6 +217,22 @@ public class RecentTasksController implements TaskStackListenerCallback, notifyRecentTasksChanged(); } /** * Mark a task with given {@code taskId} as active in freeform */ public void addActiveFreeformTask(int taskId) { mActiveFreeformTasks.add(taskId); notifyRecentTasksChanged(); } /** * Remove task with given {@code taskId} from active freeform tasks */ public void removeActiveFreeformTask(int taskId) { mActiveFreeformTasks.remove(taskId); notifyRecentTasksChanged(); } @VisibleForTesting void notifyRecentTasksChanged() { ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENT_TASKS, "Notify recent tasks changed"); Loading Loading @@ -273,6 +300,9 @@ public class RecentTasksController implements TaskStackListenerCallback, rawMapping.put(taskInfo.taskId, taskInfo); } boolean desktopModeActive = DesktopMode.isActive(mContext); ArrayList<ActivityManager.RecentTaskInfo> freeformTasks = new ArrayList<>(); // Pull out the pairs as we iterate back in the list ArrayList<GroupedRecentTaskInfo> recentTasks = new ArrayList<>(); for (int i = 0; i < rawList.size(); i++) { Loading @@ -282,16 +312,31 @@ public class RecentTasksController implements TaskStackListenerCallback, continue; } if (desktopModeActive && mActiveFreeformTasks.contains(taskInfo.taskId)) { // Freeform tasks will be added as a separate entry freeformTasks.add(taskInfo); continue; } final int pairedTaskId = mSplitTasks.get(taskInfo.taskId); if (pairedTaskId != INVALID_TASK_ID && rawMapping.contains(pairedTaskId)) { if (!desktopModeActive && pairedTaskId != INVALID_TASK_ID && rawMapping.contains( pairedTaskId)) { final ActivityManager.RecentTaskInfo pairedTaskInfo = rawMapping.get(pairedTaskId); rawMapping.remove(pairedTaskId); recentTasks.add(new GroupedRecentTaskInfo(taskInfo, pairedTaskInfo, recentTasks.add(GroupedRecentTaskInfo.forSplitTasks(taskInfo, pairedTaskInfo, mTaskSplitBoundsMap.get(pairedTaskId))); } else { recentTasks.add(new GroupedRecentTaskInfo(taskInfo)); recentTasks.add(GroupedRecentTaskInfo.forSingleTask(taskInfo)); } } // Add a special entry for freeform tasks if (!freeformTasks.isEmpty()) { // First task is added separately recentTasks.add(0, GroupedRecentTaskInfo.forFreeformTasks( freeformTasks.toArray(new ActivityManager.RecentTaskInfo[0]))); } return recentTasks; } Loading Loading
libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java +5 −1 Original line number Diff line number Diff line Loading @@ -876,8 +876,12 @@ public class ShellTaskOrganizer extends TaskOrganizer implements pkg = info.getTaskInfo().baseActivity.getPackageName(); } Rect bounds = info.getTaskInfo().getConfiguration().windowConfiguration.getBounds(); boolean running = info.getTaskInfo().isRunning; boolean visible = info.getTaskInfo().isVisible; boolean focused = info.getTaskInfo().isFocused; pw.println(innerPrefix + "#" + i + " task=" + key + " listener=" + listener + " wmMode=" + windowingMode + " pkg=" + pkg + " bounds=" + bounds); + " wmMode=" + windowingMode + " pkg=" + pkg + " bounds=" + bounds + " running=" + running + " visible=" + visible + " focused=" + focused); } pw.println(); Loading
libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java +2 −1 Original line number Diff line number Diff line Loading @@ -220,13 +220,14 @@ public abstract class WMShellModule { Context context, ShellInit shellInit, ShellTaskOrganizer shellTaskOrganizer, Optional<RecentTasksController> recentTasksController, WindowDecorViewModel<?> windowDecorViewModel) { // TODO(b/238217847): Temporarily add this check here until we can remove the dynamic // override for this controller from the base module ShellInit init = FreeformComponents.isFreeformEnabled(context) ? shellInit : null; return new FreeformTaskListener<>(init, shellTaskOrganizer, return new FreeformTaskListener<>(init, shellTaskOrganizer, recentTasksController, windowDecorViewModel); } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopMode.java +1 −1 Original line number Diff line number Diff line Loading @@ -50,7 +50,7 @@ public class DesktopMode { Settings.System.DESKTOP_MODE, UserHandle.USER_CURRENT); ProtoLog.d(WM_SHELL_DESKTOP_MODE, "isDesktopModeEnabled=%s", result); return result != 0; } catch (Settings.SettingNotFoundException e) { } catch (Exception e) { ProtoLog.e(WM_SHELL_DESKTOP_MODE, "Failed to read DESKTOP_MODE setting %s", e); return false; } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskListener.java +26 −0 Original line number Diff line number Diff line Loading @@ -28,12 +28,15 @@ import androidx.annotation.Nullable; import com.android.internal.protolog.common.ProtoLog; import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.desktopmode.DesktopMode; import com.android.wm.shell.protolog.ShellProtoLogGroup; import com.android.wm.shell.recents.RecentTasksController; import com.android.wm.shell.sysui.ShellInit; import com.android.wm.shell.transition.Transitions; import com.android.wm.shell.windowdecor.WindowDecorViewModel; import java.io.PrintWriter; import java.util.Optional; /** * {@link ShellTaskOrganizer.TaskListener} for {@link Loading @@ -46,6 +49,7 @@ public class FreeformTaskListener<T extends AutoCloseable> private static final String TAG = "FreeformTaskListener"; private final ShellTaskOrganizer mShellTaskOrganizer; private final Optional<RecentTasksController> mRecentTasksOptional; private final WindowDecorViewModel<T> mWindowDecorationViewModel; private final SparseArray<State<T>> mTasks = new SparseArray<>(); Loading @@ -60,9 +64,11 @@ public class FreeformTaskListener<T extends AutoCloseable> public FreeformTaskListener( ShellInit shellInit, ShellTaskOrganizer shellTaskOrganizer, Optional<RecentTasksController> recentTasksController, WindowDecorViewModel<T> windowDecorationViewModel) { mShellTaskOrganizer = shellTaskOrganizer; mWindowDecorationViewModel = windowDecorationViewModel; mRecentTasksOptional = recentTasksController; if (shellInit != null) { shellInit.addInitCallback(this::onInit, this); } Loading @@ -83,6 +89,12 @@ public class FreeformTaskListener<T extends AutoCloseable> mWindowDecorationViewModel.createWindowDecoration(taskInfo, leash, t, t); t.apply(); } if (DesktopMode.IS_SUPPORTED && taskInfo.isVisible) { ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE, "Adding active freeform task: #%d", taskInfo.taskId); mRecentTasksOptional.ifPresent(rt -> rt.addActiveFreeformTask(taskInfo.taskId)); } } private State<T> createOrUpdateTaskState(RunningTaskInfo taskInfo, SurfaceControl leash) { Loading Loading @@ -111,6 +123,12 @@ public class FreeformTaskListener<T extends AutoCloseable> taskInfo.taskId); mTasks.remove(taskInfo.taskId); if (DesktopMode.IS_SUPPORTED) { ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE, "Removing active freeform task: #%d", taskInfo.taskId); mRecentTasksOptional.ifPresent(rt -> rt.removeActiveFreeformTask(taskInfo.taskId)); } if (Transitions.ENABLE_SHELL_TRANSITIONS) { // Save window decorations of closing tasks so that we can hand them over to the // transition system if this method happens before the transition. In case where the Loading @@ -131,6 +149,14 @@ public class FreeformTaskListener<T extends AutoCloseable> if (state.mWindowDecoration != null) { mWindowDecorationViewModel.onTaskInfoChanged(state.mTaskInfo, state.mWindowDecoration); } if (DesktopMode.IS_SUPPORTED) { if (taskInfo.isVisible) { ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE, "Adding active freeform task: #%d", taskInfo.taskId); mRecentTasksOptional.ifPresent(rt -> rt.addActiveFreeformTask(taskInfo.taskId)); } } } private State<T> updateTaskInfo(RunningTaskInfo taskInfo) { Loading
libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java +48 −3 Original line number Diff line number Diff line Loading @@ -43,6 +43,7 @@ import com.android.wm.shell.common.TaskStackListenerCallback; import com.android.wm.shell.common.TaskStackListenerImpl; import com.android.wm.shell.common.annotations.ExternalThread; import com.android.wm.shell.common.annotations.ShellMainThread; import com.android.wm.shell.desktopmode.DesktopMode; import com.android.wm.shell.protolog.ShellProtoLogGroup; import com.android.wm.shell.sysui.ShellCommandHandler; import com.android.wm.shell.sysui.ShellInit; Loading @@ -52,6 +53,7 @@ import com.android.wm.shell.util.SplitBounds; import java.io.PrintWriter; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; Loading Loading @@ -81,6 +83,15 @@ public class RecentTasksController implements TaskStackListenerCallback, */ private final Map<Integer, SplitBounds> mTaskSplitBoundsMap = new HashMap<>(); /** * Set of taskId's that have been launched in freeform mode. * This includes tasks that are currently running, visible and in freeform mode. And also * includes tasks that are running in the background, are no longer visible, but at some point * were visible to the user. * This is used to decide which freeform apps belong to the user's desktop. */ private final HashSet<Integer> mActiveFreeformTasks = new HashSet<>(); /** * Creates {@link RecentTasksController}, returns {@code null} if the feature is not * supported. Loading Loading @@ -206,6 +217,22 @@ public class RecentTasksController implements TaskStackListenerCallback, notifyRecentTasksChanged(); } /** * Mark a task with given {@code taskId} as active in freeform */ public void addActiveFreeformTask(int taskId) { mActiveFreeformTasks.add(taskId); notifyRecentTasksChanged(); } /** * Remove task with given {@code taskId} from active freeform tasks */ public void removeActiveFreeformTask(int taskId) { mActiveFreeformTasks.remove(taskId); notifyRecentTasksChanged(); } @VisibleForTesting void notifyRecentTasksChanged() { ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENT_TASKS, "Notify recent tasks changed"); Loading Loading @@ -273,6 +300,9 @@ public class RecentTasksController implements TaskStackListenerCallback, rawMapping.put(taskInfo.taskId, taskInfo); } boolean desktopModeActive = DesktopMode.isActive(mContext); ArrayList<ActivityManager.RecentTaskInfo> freeformTasks = new ArrayList<>(); // Pull out the pairs as we iterate back in the list ArrayList<GroupedRecentTaskInfo> recentTasks = new ArrayList<>(); for (int i = 0; i < rawList.size(); i++) { Loading @@ -282,16 +312,31 @@ public class RecentTasksController implements TaskStackListenerCallback, continue; } if (desktopModeActive && mActiveFreeformTasks.contains(taskInfo.taskId)) { // Freeform tasks will be added as a separate entry freeformTasks.add(taskInfo); continue; } final int pairedTaskId = mSplitTasks.get(taskInfo.taskId); if (pairedTaskId != INVALID_TASK_ID && rawMapping.contains(pairedTaskId)) { if (!desktopModeActive && pairedTaskId != INVALID_TASK_ID && rawMapping.contains( pairedTaskId)) { final ActivityManager.RecentTaskInfo pairedTaskInfo = rawMapping.get(pairedTaskId); rawMapping.remove(pairedTaskId); recentTasks.add(new GroupedRecentTaskInfo(taskInfo, pairedTaskInfo, recentTasks.add(GroupedRecentTaskInfo.forSplitTasks(taskInfo, pairedTaskInfo, mTaskSplitBoundsMap.get(pairedTaskId))); } else { recentTasks.add(new GroupedRecentTaskInfo(taskInfo)); recentTasks.add(GroupedRecentTaskInfo.forSingleTask(taskInfo)); } } // Add a special entry for freeform tasks if (!freeformTasks.isEmpty()) { // First task is added separately recentTasks.add(0, GroupedRecentTaskInfo.forFreeformTasks( freeformTasks.toArray(new ActivityManager.RecentTaskInfo[0]))); } return recentTasks; } Loading