Check whether a display supported pip when an activity try to enter pip

ActivityRecord#supportsPictureInPicture() will also be called when an
activity sets PictureInPictureParams, this cause an issue if an activity
is trying to set pip params but it doesn't enter pip.

We should only block an activity enter pip on specified display instead
of telling caller that the Activity doesn't support pip.

Bug: 224699616
Test: manually, atest WmTests:ActivityRecordTests
Change-Id: Id8eb421ebab57e6c022650f3e820175531a2e8fc
This commit is contained in:
Iris Yang
2022-03-15 08:33:51 +00:00
parent 7c8cc6bf19
commit 2c2516afc7
2 changed files with 31 additions and 15 deletions

View File

@@ -2915,9 +2915,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
*/
boolean supportsPictureInPicture() {
return mAtmService.mSupportsPictureInPicture && isActivityTypeStandardOrUndefined()
&& info.supportsPictureInPicture()
&& (mDisplayContent != null && mDisplayContent.mDwpcHelper.isWindowingModeSupported(
WINDOWING_MODE_PINNED));
&& info.supportsPictureInPicture();
}
/**
@@ -3015,6 +3013,14 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
return false;
}
// Check to see if PiP is supported for the display this container is on.
if (mDisplayContent != null && !mDisplayContent.mDwpcHelper.isWindowingModeSupported(
WINDOWING_MODE_PINNED)) {
Slog.w(TAG, "Display " + mDisplayContent.getDisplayId()
+ " doesn't support enter picture-in-picture mode. caller = " + caller);
return false;
}
boolean isCurrentAppLocked =
mAtmService.getLockTaskModeState() != LOCK_TASK_MODE_NONE;
final TaskDisplayArea taskDisplayArea = getDisplayArea();

View File

@@ -16,6 +16,8 @@
package com.android.server.wm;
import static android.app.AppOpsManager.MODE_ALLOWED;
import static android.app.AppOpsManager.OP_PICTURE_IN_PICTURE;
import static android.app.TaskInfo.CAMERA_COMPAT_CONTROL_DISMISSED;
import static android.app.TaskInfo.CAMERA_COMPAT_CONTROL_HIDDEN;
import static android.app.TaskInfo.CAMERA_COMPAT_CONTROL_TREATMENT_APPLIED;
@@ -110,6 +112,7 @@ import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.never;
import android.app.ActivityOptions;
import android.app.AppOpsManager;
import android.app.ICompatCameraControlCallback;
import android.app.PictureInPictureParams;
import android.app.servertransaction.ActivityConfigurationChangeItem;
@@ -2184,17 +2187,11 @@ public class ActivityRecordTests extends WindowTestsBase {
@Test
public void testSupportsPictureInPicture() {
final Task task = new TaskBuilder(mSupervisor)
.setDisplay(mDisplayContent).build();
final ActivityRecord activity = new ActivityBuilder(mAtm)
.setTask(task)
.setCreateTask(true)
.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;
@@ -2207,15 +2204,28 @@ 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());
@Test
public void testCheckEnterPictureInPictureState_displayNotSupportedPip() {
final Task task = new TaskBuilder(mSupervisor)
.setDisplay(mDisplayContent).build();
final ActivityRecord activity = new ActivityBuilder(mAtm)
.setTask(task)
.setResizeMode(ActivityInfo.RESIZE_MODE_UNRESIZEABLE)
.setActivityFlags(FLAG_SUPPORTS_PICTURE_IN_PICTURE)
.build();
mAtm.mSupportsPictureInPicture = true;
AppOpsManager appOpsManager = mAtm.getAppOpsManager();
doReturn(MODE_ALLOWED).when(appOpsManager).checkOpNoThrow(eq(OP_PICTURE_IN_PICTURE),
anyInt(), any());
doReturn(false).when(mAtm).shouldDisableNonVrUiLocked();
// Display not supports PIP
spyOn(mDisplayContent.mDwpcHelper);
doReturn(false).when(mDisplayContent.mDwpcHelper).isWindowingModeSupported(
WINDOWING_MODE_PINNED);
assertFalse(activity.supportsPictureInPicture());
assertFalse(activity.checkEnterPictureInPictureState("TEST", false /* beforeStopping */));
}
@Test