Merge "Add API to indicate supported windowing modes on the virtual displays" into tm-dev

This commit is contained in:
TreeHugger Robot
2022-03-11 01:22:20 +00:00
committed by Android (Google) Code Review
7 changed files with 130 additions and 10 deletions

View File

@@ -17,12 +17,14 @@
package android.window;
import android.annotation.NonNull;
import android.app.WindowConfiguration;
import android.content.ComponentName;
import android.content.pm.ActivityInfo;
import android.util.ArraySet;
import java.io.PrintWriter;
import java.util.List;
import java.util.Set;
/**
* Abstract class to control the policies of the windows that can be displayed on the virtual
@@ -45,6 +47,22 @@ public abstract class DisplayWindowPolicyController {
*/
private int mSystemWindowFlags;
/**
* The set of windowing mode that are supported in this display.
* @see android.app.WindowConfiguration.WindowingMode
*/
private final Set<Integer> mSupportedWindowingModes = new ArraySet<>();
/**
* A controller to control the policies of the windows that can be displayed on the virtual
* display.
*/
public DisplayWindowPolicyController() {
synchronized (mSupportedWindowingModes) {
mSupportedWindowingModes.add(WindowConfiguration.WINDOWING_MODE_FULLSCREEN);
}
}
/**
* Returns {@code true} if the given window flags contain the flags that we're interested in.
*/
@@ -62,9 +80,34 @@ public abstract class DisplayWindowPolicyController {
}
/**
* Returns {@code true} if the given activities can be displayed on this virtual display.
* Returns {@code true} if the given windowing mode is supported in this display.
*/
public abstract boolean canContainActivities(@NonNull List<ActivityInfo> activities);
public final boolean isWindowingModeSupported(
@WindowConfiguration.WindowingMode int windowingMode) {
synchronized (mSupportedWindowingModes) {
return mSupportedWindowingModes.contains(windowingMode);
}
}
/**
* Sets the windowing modes are supported in this display.
*
* @param supportedWindowingModes The set of
* {@link android.app.WindowConfiguration.WindowingMode}.
*/
public final void setSupportedWindowingModes(Set<Integer> supportedWindowingModes) {
synchronized (mSupportedWindowingModes) {
mSupportedWindowingModes.clear();
mSupportedWindowingModes.addAll(supportedWindowingModes);
}
}
/**
* Returns {@code true} if the given activities can be displayed on this virtual display and
* the windowing mode is supported.
*/
public abstract boolean canContainActivities(@NonNull List<ActivityInfo> activities,
@WindowConfiguration.WindowingMode int windowingMode);
/**
* Called when an Activity window is layouted with the new changes where contains the

View File

@@ -22,6 +22,7 @@ import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTE
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.WindowConfiguration;
import android.app.compat.CompatChanges;
import android.companion.virtual.VirtualDeviceManager.ActivityListener;
import android.companion.virtual.VirtualDeviceParams;
@@ -119,6 +120,7 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController
@ActivityPolicy int defaultActivityPolicy,
@NonNull ActivityListener activityListener,
@NonNull Consumer<ActivityInfo> activityBlockedCallback) {
super();
mAllowedUsers = allowedUsers;
mAllowedActivities = new ArraySet<>(allowedActivities);
mBlockedActivities = new ArraySet<>(blockedActivities);
@@ -134,7 +136,11 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController
}
@Override
public boolean canContainActivities(@NonNull List<ActivityInfo> activities) {
public boolean canContainActivities(@NonNull List<ActivityInfo> activities,
@WindowConfiguration.WindowingMode int windowingMode) {
if (!isWindowingModeSupported(windowingMode)) {
return false;
}
// Can't display all the activities if any of them don't want to be displayed.
final int activityCount = activities.size();
for (int i = 0; i < activityCount; i++) {

View File

@@ -2914,7 +2914,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
*/
boolean supportsPictureInPicture() {
return mAtmService.mSupportsPictureInPicture && isActivityTypeStandardOrUndefined()
&& info.supportsPictureInPicture();
&& info.supportsPictureInPicture()
&& (mDisplayContent != null && mDisplayContent.mDwpcHelper.isWindowingModeSupported(
WINDOWING_MODE_PINNED));
}
/**

View File

@@ -402,7 +402,8 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
activities.add(r.info);
});
}
if (!displayContent.mDwpcHelper.canContainActivities(activities)) {
if (!displayContent.mDwpcHelper.canContainActivities(activities,
displayContent.getWindowingMode())) {
return false;
}
}

View File

@@ -18,6 +18,7 @@ package com.android.server.wm;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.WindowConfiguration;
import android.content.pm.ActivityInfo;
import android.os.UserHandle;
import android.util.ArraySet;
@@ -63,13 +64,14 @@ class DisplayWindowPolicyControllerHelper {
}
/**
* @see DisplayWindowPolicyController#canContainActivities(List)
* @see DisplayWindowPolicyController#canContainActivities(List, int)
*/
public boolean canContainActivities(@NonNull List<ActivityInfo> activities) {
public boolean canContainActivities(@NonNull List<ActivityInfo> activities,
@WindowConfiguration.WindowingMode int windowingMode) {
if (mDisplayWindowPolicyController == null) {
return true;
}
return mDisplayWindowPolicyController.canContainActivities(activities);
return mDisplayWindowPolicyController.canContainActivities(activities, windowingMode);
}
/**
@@ -126,6 +128,17 @@ class DisplayWindowPolicyControllerHelper {
}
}
/**
* @see DisplayWindowPolicyController#isWindowingModeSupported(int)
*/
public final boolean isWindowingModeSupported(
@WindowConfiguration.WindowingMode int windowingMode) {
if (mDisplayWindowPolicyController == null) {
return true;
}
return mDisplayWindowPolicyController.isWindowingModeSupported(windowingMode);
}
void dump(String prefix, PrintWriter pw) {
if (mDisplayWindowPolicyController != null) {
pw.println();

View File

@@ -2184,11 +2184,17 @@ public class ActivityRecordTests extends WindowTestsBase {
@Test
public void testSupportsPictureInPicture() {
final Task task = new TaskBuilder(mSupervisor)
.setDisplay(mDisplayContent).build();
final ActivityRecord activity = new ActivityBuilder(mAtm)
.setCreateTask(true)
.setTask(task)
.setResizeMode(ActivityInfo.RESIZE_MODE_UNRESIZEABLE)
.setActivityFlags(FLAG_SUPPORTS_PICTURE_IN_PICTURE)
.build();
spyOn(mDisplayContent);
spyOn(mDisplayContent.mDwpcHelper);
doReturn(true).when(mDisplayContent.mDwpcHelper).isWindowingModeSupported(
WINDOWING_MODE_PINNED);
// Device not supports PIP
mAtm.mSupportsPictureInPicture = false;
@@ -2201,6 +2207,15 @@ public class ActivityRecordTests extends WindowTestsBase {
// Activity not supports PIP
activity.info.flags &= ~FLAG_SUPPORTS_PICTURE_IN_PICTURE;
assertFalse(activity.supportsPictureInPicture());
// Activity supports PIP
activity.info.flags |= FLAG_SUPPORTS_PICTURE_IN_PICTURE;
assertTrue(activity.supportsPictureInPicture());
// Display not supports PIP
doReturn(false).when(mDisplayContent.mDwpcHelper).isWindowingModeSupported(
WINDOWING_MODE_PINNED);
assertFalse(activity.supportsPictureInPicture());
}
@Test

View File

@@ -16,13 +16,18 @@
package com.android.server.wm;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.anyInt;
import android.app.WindowConfiguration;
import android.content.ComponentName;
import android.content.pm.ActivityInfo;
import android.os.UserHandle;
@@ -37,6 +42,7 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.List;
import java.util.Set;
/**
* Tests for the {@link DisplayWindowPolicyControllerHelper} class.
@@ -113,6 +119,39 @@ public class DisplayWindowPolicyControllerHelperTests extends WindowTestsBase {
return activity;
}
@Test
public void testIsWindowingModeSupported_noController_returnTrueForAnyWindowingMode() {
doReturn(null).when(mWm.mDisplayManagerInternal)
.getDisplayWindowPolicyController(anyInt());
mSecondaryDisplay = createNewDisplay();
assertFalse(mSecondaryDisplay.mDwpcHelper.hasController());
assertTrue(mSecondaryDisplay.mDwpcHelper.isWindowingModeSupported(WINDOWING_MODE_PINNED));
assertTrue(
mSecondaryDisplay.mDwpcHelper.isWindowingModeSupported(WINDOWING_MODE_FULLSCREEN));
}
@Test
public void testIsWindowingModeSupported_withoutSettingSupportedMode_returnFalse() {
assertFalse(mSecondaryDisplay.mDwpcHelper.isWindowingModeSupported(WINDOWING_MODE_PINNED));
}
@Test
public void testIsWindowingModeSupported_withoutSupportedMode_defaultSupportFullScreen() {
assertTrue(
mSecondaryDisplay.mDwpcHelper.isWindowingModeSupported(WINDOWING_MODE_FULLSCREEN));
}
@Test
public void testIsWindowingModeSupported_setPinnedMode_returnTrue() {
Set<Integer> supportedWindowingMode = new ArraySet<>();
supportedWindowingMode.add(WINDOWING_MODE_PINNED);
mDwpc.setSupportedWindowingModes(supportedWindowingMode);
assertTrue(mSecondaryDisplay.mDwpcHelper.isWindowingModeSupported(WINDOWING_MODE_PINNED));
}
private class TestDisplayWindowPolicyController extends DisplayWindowPolicyController {
ComponentName mTopActivity = null;
@@ -120,7 +159,8 @@ public class DisplayWindowPolicyControllerHelperTests extends WindowTestsBase {
ArraySet<Integer> mRunningUids = new ArraySet<>();
@Override
public boolean canContainActivities(@NonNull List<ActivityInfo> activities) {
public boolean canContainActivities(@NonNull List<ActivityInfo> activities,
@WindowConfiguration.WindowingMode int windowingMode) {
return false;
}