Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2c2516af authored by Iris Yang's avatar Iris Yang
Browse files

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
parent 7c8cc6bf
Loading
Loading
Loading
Loading
+9 −3
Original line number Diff line number Diff line
@@ -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();
+22 −12
Original line number Diff line number Diff line
@@ -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