Use DeviceProfile to determine whether to exclude tasks from Recent
For Android Auto, tasks should exclude from Recents by default. For App streaming device profile, tasks should be showed from Recents. This change also keep the most recent task of "Default display" in Recents even if it's excluded from Recents. Bug: 232385935 Test: atest WmTests:RecentTasksTest Change-Id: Ic01ed6bbae1f2b77f8664196cbc59b248f5ec3b4
This commit is contained in:
@@ -125,6 +125,11 @@ public abstract class DisplayWindowPolicyController {
|
||||
public abstract boolean keepActivityOnWindowFlagsChanged(
|
||||
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.
|
||||
*/
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -1958,6 +1959,16 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
|
||||
return mDisplayRotation.updateRotationUnchecked(false /* forceUpdate */);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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.
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -242,5 +242,10 @@ public class DisplayWindowPolicyControllerTests extends WindowTestsBase {
|
||||
mRunningUids.clear();
|
||||
mRunningUids.addAll(runningUids);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canShowTasksInRecents() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -690,6 +690,20 @@ public class RecentTasksTest extends WindowTestsBase {
|
||||
assertGetRecentTasksOrder(0 /* flags */, excludedTask1);
|
||||
}
|
||||
|
||||
@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
|
||||
@@ -801,6 +815,17 @@ public class RecentTasksTest extends WindowTestsBase {
|
||||
mRecentTasks.isVisibleRecentTask(task));
|
||||
}
|
||||
|
||||
@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
|
||||
|
||||
Reference in New Issue
Block a user