diff options
9 files changed, 97 insertions, 6 deletions
diff --git a/core/java/android/window/DisplayWindowPolicyController.java b/core/java/android/window/DisplayWindowPolicyController.java index d3cc918c2a29..a5aefd5157ce 100644 --- a/core/java/android/window/DisplayWindowPolicyController.java +++ b/core/java/android/window/DisplayWindowPolicyController.java @@ -126,6 +126,11 @@ public abstract class DisplayWindowPolicyController { ActivityInfo activityInfo, int windowFlags, int systemWindowFlags); /** + * Returns {@code true} if the tasks which is on this virtual display can be showed on Recents. + */ + public abstract boolean canShowTasksInRecents(); + + /** * This is called when the top activity of the display is changed. */ public void onTopActivityChanged(ComponentName topActivity, int uid) {} diff --git a/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java b/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java index 0b437446826a..4473a095063a 100644 --- a/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java +++ b/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java @@ -16,6 +16,8 @@ package com.android.server.companion.virtual; +import static android.companion.AssociationRequest.DEVICE_PROFILE_APP_STREAMING; +import static android.companion.AssociationRequest.DEVICE_PROFILE_AUTOMOTIVE_PROJECTION; import static android.content.pm.ActivityInfo.FLAG_CAN_DISPLAY_ON_REMOTE_DEVICES; import static android.view.WindowManager.LayoutParams.FLAG_SECURE; import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS; @@ -24,6 +26,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.app.WindowConfiguration; import android.app.compat.CompatChanges; +import android.companion.AssociationRequest; import android.companion.virtual.VirtualDeviceManager.ActivityListener; import android.companion.virtual.VirtualDeviceParams; import android.companion.virtual.VirtualDeviceParams.ActivityPolicy; @@ -95,6 +98,7 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController private final Handler mHandler = new Handler(Looper.getMainLooper()); private final ArraySet<RunningAppsChangedListener> mRunningAppsChangedListener = new ArraySet<>(); + private final @AssociationRequest.DeviceProfile String mDeviceProfile; /** * Creates a window policy controller that is generic to the different use cases of virtual @@ -119,6 +123,7 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController * is not populated in this callback and is always {@link Display#INVALID_DISPLAY}. * @param activityBlockedCallback Callback that is called when an activity is blocked from * launching. + * @param deviceProfile The {@link AssociationRequest.DeviceProfile} of this virtual device. */ public GenericWindowPolicyController(int windowFlags, int systemWindowFlags, @NonNull ArraySet<UserHandle> allowedUsers, @@ -128,7 +133,8 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController @NonNull Set<ComponentName> blockedActivities, @ActivityPolicy int defaultActivityPolicy, @NonNull ActivityListener activityListener, - @NonNull Consumer<ActivityInfo> activityBlockedCallback) { + @NonNull Consumer<ActivityInfo> activityBlockedCallback, + @AssociationRequest.DeviceProfile String deviceProfile) { super(); mAllowedUsers = allowedUsers; mAllowedCrossTaskNavigations = new ArraySet<>(allowedCrossTaskNavigations); @@ -139,6 +145,7 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController mActivityBlockedCallback = activityBlockedCallback; setInterestedWindowFlags(windowFlags, systemWindowFlags); mActivityListener = activityListener; + mDeviceProfile = deviceProfile; } /** Register a listener for running applications changes. */ @@ -248,6 +255,18 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController }); } + @Override + public boolean canShowTasksInRecents() { + // TODO(b/234075973) : Remove this once proper API is ready. + switch (mDeviceProfile) { + case DEVICE_PROFILE_AUTOMOTIVE_PROJECTION: + return false; + case DEVICE_PROFILE_APP_STREAMING: + default: + return true; + } + } + /** * Returns true if an app with the given UID has an activity running on the virtual display for * this controller. diff --git a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java index 638b3aeef544..33fd83bf6bd7 100644 --- a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java +++ b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java @@ -557,7 +557,8 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub mParams.getBlockedActivities(), mParams.getDefaultActivityPolicy(), createListenerAdapter(displayId), - activityInfo -> onActivityBlocked(displayId, activityInfo)); + activityInfo -> onActivityBlocked(displayId, activityInfo), + mAssociationInfo.getDeviceProfile()); gwpc.registerRunningAppsChangedListener(/* listener= */ this); mWindowPolicyControllers.put(displayId, gwpc); return gwpc; diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index c60dfa1ed8ba..ebe0efbbf140 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -224,6 +224,7 @@ import android.view.WindowInsets; import android.view.WindowManager; import android.view.WindowManager.DisplayImePolicy; import android.view.WindowManagerPolicyConstants.PointerEventListener; +import android.window.DisplayWindowPolicyController; import android.window.IDisplayAreaOrganizer; import android.window.TransitionRequestInfo; @@ -1959,6 +1960,16 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp } /** + * @see DisplayWindowPolicyController#canShowTasksInRecents() + */ + boolean canShowTasksInRecents() { + if (mDwpcHelper == null) { + return true; + } + return mDwpcHelper.canShowTasksInRecents(); + } + + /** * Applies the rotation transaction. This must be called after {@link #updateRotationUnchecked} * (if it returned {@code true}) to actually finish the rotation. * diff --git a/services/core/java/com/android/server/wm/DisplayWindowPolicyControllerHelper.java b/services/core/java/com/android/server/wm/DisplayWindowPolicyControllerHelper.java index 2deb8286f95f..5d4904264056 100644 --- a/services/core/java/com/android/server/wm/DisplayWindowPolicyControllerHelper.java +++ b/services/core/java/com/android/server/wm/DisplayWindowPolicyControllerHelper.java @@ -152,6 +152,16 @@ class DisplayWindowPolicyControllerHelper { return mDisplayWindowPolicyController.isWindowingModeSupported(windowingMode); } + /** + * @see DisplayWindowPolicyController#canShowTasksInRecents() + */ + public final boolean canShowTasksInRecents() { + if (mDisplayWindowPolicyController == null) { + return true; + } + return mDisplayWindowPolicyController.canShowTasksInRecents(); + } + void dump(String prefix, PrintWriter pw) { if (mDisplayWindowPolicyController != null) { pw.println(); diff --git a/services/core/java/com/android/server/wm/RecentTasks.java b/services/core/java/com/android/server/wm/RecentTasks.java index e259238c2879..4860762a5f7f 100644 --- a/services/core/java/com/android/server/wm/RecentTasks.java +++ b/services/core/java/com/android/server/wm/RecentTasks.java @@ -1390,6 +1390,13 @@ class RecentTasks { return false; } + // Ignore the task if it is started on a display which is not allow to show its tasks on + // Recents. + if (task.getDisplayContent() != null + && !task.getDisplayContent().canShowTasksInRecents()) { + return false; + } + return true; } @@ -1399,13 +1406,19 @@ class RecentTasks { private boolean isInVisibleRange(Task task, int taskIndex, int numVisibleTasks, boolean skipExcludedCheck) { if (!skipExcludedCheck) { - // Keep the most recent task even if it is excluded from recents + // Keep the most recent task of home display even if it is excluded from recents. final boolean isExcludeFromRecents = (task.getBaseIntent().getFlags() & FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS; if (isExcludeFromRecents) { - if (DEBUG_RECENTS_TRIM_TASKS) Slog.d(TAG, "\texcludeFromRecents=true"); - return taskIndex == 0; + if (DEBUG_RECENTS_TRIM_TASKS) { + Slog.d(TAG, + "\texcludeFromRecents=true, taskIndex = " + taskIndex + + ", isOnHomeDisplay: " + task.isOnHomeDisplay()); + } + // The Recents is only supported on default display now, we should only keep the + // most recent task of home display. + return (task.isOnHomeDisplay() && taskIndex == 0); } } diff --git a/services/tests/servicestests/src/com/android/server/companion/virtual/audio/VirtualAudioControllerTest.java b/services/tests/servicestests/src/com/android/server/companion/virtual/audio/VirtualAudioControllerTest.java index cd836c77076d..e2c3a94fc187 100644 --- a/services/tests/servicestests/src/com/android/server/companion/virtual/audio/VirtualAudioControllerTest.java +++ b/services/tests/servicestests/src/com/android/server/companion/virtual/audio/VirtualAudioControllerTest.java @@ -16,6 +16,7 @@ package com.android.server.companion.virtual.audio; +import static android.companion.AssociationRequest.DEVICE_PROFILE_APP_STREAMING; import static android.media.AudioAttributes.FLAG_SECURE; import static android.media.AudioPlaybackConfiguration.PLAYER_STATE_STARTED; import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS; @@ -81,7 +82,8 @@ public class VirtualAudioControllerTest { /* blockedActivities= */ new ArraySet<>(), VirtualDeviceParams.ACTIVITY_POLICY_DEFAULT_ALLOWED, /* activityListener= */ null, - /* activityBlockedCallback= */ null); + /* activityBlockedCallback= */ null, + /* deviceProfile= */ DEVICE_PROFILE_APP_STREAMING); } @Test diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayWindowPolicyControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayWindowPolicyControllerTests.java index 02009b75e319..47c217651e78 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayWindowPolicyControllerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayWindowPolicyControllerTests.java @@ -242,5 +242,10 @@ public class DisplayWindowPolicyControllerTests extends WindowTestsBase { mRunningUids.clear(); mRunningUids.addAll(runningUids); } + + @Override + public boolean canShowTasksInRecents() { + return true; + } } } diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java index 284728397c9f..feb1c6fa6b5c 100644 --- a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java @@ -691,6 +691,20 @@ public class RecentTasksTest extends WindowTestsBase { } @Test + public void testVisibleTasks_excludedFromRecents_nonDefaultDisplayTaskNotVisible() { + Task excludedTaskOnVirtualDisplay = createTaskBuilder(".excludedTaskOnVirtualDisplay") + .setFlags(FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) + .build(); + excludedTaskOnVirtualDisplay.mUserSetupComplete = true; + doReturn(false).when(excludedTaskOnVirtualDisplay).isOnHomeDisplay(); + mRecentTasks.add(mTasks.get(0)); + mRecentTasks.add(excludedTaskOnVirtualDisplay); + + // Expect that the first visible excluded-from-recents task is visible + assertGetRecentTasksOrder(0 /* flags */, mTasks.get(0)); + } + + @Test public void testVisibleTasks_excludedFromRecents_withExcluded() { // Create some set of tasks, some of which are visible and some are not Task t1 = createTaskBuilder("com.android.pkg1", ".Task1").build(); @@ -802,6 +816,17 @@ public class RecentTasksTest extends WindowTestsBase { } @Test + public void testVisibleTask_displayCanNotShowTaskFromRecents_expectNotVisible() { + final DisplayContent displayContent = addNewDisplayContentAt(DisplayContent.POSITION_TOP); + doReturn(false).when(displayContent).canShowTasksInRecents(); + final Task task = displayContent.getDefaultTaskDisplayArea().createRootTask( + WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */); + mRecentTasks.add(task); + + assertFalse(mRecentTasks.isVisibleRecentTask(task)); + } + + @Test public void testFreezeTaskListOrder_reorderExistingTask() { // Add some tasks mRecentTasks.add(mTasks.get(0)); |