Revert "[PiP2] Implement Content-PiP2"
This reverts commit 9a17f933696e397d1e9097c02414d8becccb0e44.
Reason for revert: b/420674781
Bug: 400459203
Change-Id: Ifeb589e58b7667a34b4fc3f7ea621db3fcdf13f1
diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java
index 24056f8..fc258b79 100644
--- a/core/java/android/app/ActivityOptions.java
+++ b/core/java/android/app/ActivityOptions.java
@@ -1340,7 +1340,6 @@
final ActivityOptions opts = new ActivityOptions();
opts.mLaunchIntoPipParams = new PictureInPictureParams.Builder(pictureInPictureParams)
.setIsLaunchIntoPip(true)
- .setAutoEnterEnabled(true)
.build();
return opts;
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java
index 83a22285..aee0909 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java
@@ -144,14 +144,14 @@
/**
* Called when the Shell wants to start an exit-via-expand from Pip transition/animation.
*/
- public void startExpandTransition(WindowContainerTransaction wct, boolean toSplit) {
+ public void startExpandTransition(WindowContainerTransaction out, boolean toSplit) {
// Default implementation does nothing.
}
/**
* Called when the Shell wants to start a remove Pip transition/animation.
*/
- public void startRemoveTransition(WindowContainerTransaction wct, boolean withFadeout) {
+ public void startRemoveTransition(boolean withFadeout) {
// Default implementation does nothing.
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipController.java
index 4bf4d54..8ca9280 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipController.java
@@ -614,9 +614,6 @@
mPipUiEventLogger.log(
PipUiEventLogger.PipUiEventEnum.PICTURE_IN_PICTURE_AUTO_ENTER);
mPipTransitionState.resetSwipePipToHomeState();
- } else if (taskInfo != null && taskInfo.launchIntoPipHostTaskId != -1) {
- mPipUiEventLogger.log(
- PipUiEventLogger.PipUiEventEnum.PICTURE_IN_PICTURE_ENTER_CONTENT_PIP);
} else {
mPipUiEventLogger.log(PipUiEventLogger.PipUiEventEnum.PICTURE_IN_PICTURE_ENTER);
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipMotionHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipMotionHelper.java
index 7e67caf..4c3ee98 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipMotionHelper.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipMotionHelper.java
@@ -356,14 +356,7 @@
}
cancelPhysicsAnimation();
mMenuController.hideMenu(ANIM_TYPE_NONE, false /* resize */);
-
- boolean isContentPip = mPipTransitionState.getPipTaskInfo() != null
- && mPipTransitionState.getPipTaskInfo().launchIntoPipHostTaskId != -1;
- if (isContentPip) {
- mPipScheduler.scheduleRemovePip(true /* withFadeout */);
- } else {
- mPipScheduler.scheduleExitPipViaExpand();
- }
+ mPipScheduler.scheduleExitPipViaExpand();
}
/**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java
index 4ef33d8..74f90454 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java
@@ -16,10 +16,7 @@
package com.android.wm.shell.pip2.phone;
-import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
-
import android.app.PictureInPictureParams;
-import android.app.TaskInfo;
import android.content.Context;
import android.graphics.Rect;
import android.os.Bundle;
@@ -131,39 +128,18 @@
wct.setBounds(pipTaskToken, null);
wct.setWindowingMode(pipTaskToken, mPipDesktopState.getOutPipWindowingMode());
- final TaskInfo pipTaskInfo = mPipTransitionState.getPipTaskInfo();
mDesktopPipTransitionController.ifPresent(c -> {
// In multi-activity case, windowing mode change will reparent to original host task, so
// we have to update the parent windowing mode to what is expected.
c.maybeUpdateParentInWct(wct,
- pipTaskInfo.lastParentTaskIdBeforePip);
+ mPipTransitionState.getPipTaskInfo().lastParentTaskIdBeforePip);
// In multi-desks case, we have to reparent the task to the root desk.
- c.maybeReparentTaskToDesk(wct, pipTaskInfo.taskId);
+ c.maybeReparentTaskToDesk(wct, mPipTransitionState.getPipTaskInfo().taskId);
});
return wct;
}
- @Nullable
- private WindowContainerTransaction getRemovePipTransaction() {
- WindowContainerToken pipTaskToken = mPipTransitionState.getPipTaskToken();
- if (pipTaskToken == null) {
- return null;
- }
- WindowContainerTransaction wct = new WindowContainerTransaction();
- wct.setBounds(pipTaskToken, null);
- wct.setWindowingMode(pipTaskToken, WINDOWING_MODE_UNDEFINED);
- wct.reorder(pipTaskToken, false);
-
- final TaskInfo pipTaskInfo = mPipTransitionState.getPipTaskInfo();
- if (pipTaskInfo.launchIntoPipHostTaskId != -1) {
- // If the current PiP session was entered through content-PiP,
- // then relaunch the original host task too.
- wct.startTask(pipTaskInfo.launchIntoPipHostTaskId, null /* ActivityOptions */);
- }
- return wct;
- }
-
/**
* Schedules exit PiP via expand transition.
*/
@@ -183,6 +159,7 @@
null /* taskInfo */, SplitScreenConstants.SPLIT_POSITION_UNDEFINED);
}
});
+
boolean toSplit = !wct.isEmpty();
wct.merge(expandWct, true /* transfer */);
mPipTransitionController.startExpandTransition(wct, toSplit);
@@ -193,7 +170,7 @@
public void scheduleRemovePip(boolean withFadeout) {
mMainExecutor.execute(() -> {
if (!mPipTransitionState.isInPip()) return;
- mPipTransitionController.startRemoveTransition(getRemovePipTransaction(), withFadeout);
+ mPipTransitionController.startRemoveTransition(withFadeout);
});
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java
index d450b55..a64d3de 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java
@@ -18,6 +18,7 @@
import static android.app.WindowConfiguration.ROTATION_UNDEFINED;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
+import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.view.Surface.ROTATION_0;
import static android.view.Surface.ROTATION_270;
import static android.view.Surface.ROTATION_90;
@@ -79,7 +80,6 @@
import com.android.wm.shell.pip2.PipSurfaceTransactionHelper;
import com.android.wm.shell.pip2.animation.PipAlphaAnimator;
import com.android.wm.shell.pip2.animation.PipEnterAnimator;
-import com.android.wm.shell.pip2.phone.transition.ContentPipHandler;
import com.android.wm.shell.pip2.phone.transition.PipDisplayChangeObserver;
import com.android.wm.shell.pip2.phone.transition.PipExpandHandler;
import com.android.wm.shell.pip2.phone.transition.PipTransitionUtils;
@@ -144,7 +144,6 @@
// Internal state and relevant cached info
//
private final PipExpandHandler mExpandHandler;
- private final ContentPipHandler mContentPipHandler;
private final PipDisplayChangeObserver mPipDisplayChangeObserver;
private Transitions.TransitionFinishCallback mFinishCallback;
@@ -192,8 +191,6 @@
pipBoundsState, pipBoundsAlgorithm,
pipTransitionState, pipDisplayLayoutState, pipDesktopState, pipInteractionHandler,
splitScreenControllerOptional);
- mContentPipHandler = new ContentPipHandler(mContext, mPipSurfaceTransactionHelper,
- pipTransitionState);
mPipDisplayChangeObserver = new PipDisplayChangeObserver(pipTransitionState,
pipBoundsState);
}
@@ -216,15 +213,16 @@
//
@Override
- public void startExpandTransition(WindowContainerTransaction wct, boolean toSplit) {
- if (wct == null) return;
+ public void startExpandTransition(WindowContainerTransaction out, boolean toSplit) {
+ if (out == null) return;
mPipTransitionState.setState(PipTransitionState.EXITING_PIP);
mExitViaExpandTransition = mTransitions.startTransition(toSplit ? TRANSIT_EXIT_PIP_TO_SPLIT
- : TRANSIT_EXIT_PIP, wct, this);
+ : TRANSIT_EXIT_PIP, out, this);
}
@Override
- public void startRemoveTransition(WindowContainerTransaction wct, boolean withFadeout) {
+ public void startRemoveTransition(boolean withFadeout) {
+ final WindowContainerTransaction wct = getRemovePipTransaction();
if (wct == null) return;
mPipTransitionState.setState(PipTransitionState.EXITING_PIP);
mPendingRemoveWithFadeout = withFadeout;
@@ -335,10 +333,6 @@
return handleSwipePipToHomeTransition(info, startTransaction, finishTransaction,
finishCallback);
}
- if (mContentPipHandler.startAnimation(transition, info,
- startTransaction, finishTransaction, finishCallback)) {
- return true;
- }
if (isLegacyEnter(info)) {
// If this is a legacy-enter-pip (auto-enter is off and PiP activity went to pause),
// then we should run an ALPHA type (cross-fade) animation.
@@ -858,6 +852,19 @@
return wct;
}
+ @Nullable
+ private WindowContainerTransaction getRemovePipTransaction() {
+ WindowContainerToken pipTaskToken = mPipTransitionState.getPipTaskToken();
+ if (pipTaskToken == null) {
+ return null;
+ }
+ WindowContainerTransaction wct = new WindowContainerTransaction();
+ wct.setBounds(pipTaskToken, null);
+ wct.setWindowingMode(pipTaskToken, WINDOWING_MODE_UNDEFINED);
+ wct.reorder(pipTaskToken, false);
+ return wct;
+ }
+
private boolean isAutoEnterInButtonNavigation(@NonNull TransitionRequestInfo requestInfo) {
final ActivityManager.RunningTaskInfo pipTask = requestInfo.getPipChange() != null
? requestInfo.getPipChange().getTaskInfo() : null;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransitionState.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransitionState.java
index fff9d10..9ebf2cb 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransitionState.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransitionState.java
@@ -429,12 +429,6 @@
@VisibleForTesting
boolean shouldTransitionToState(@TransitionState int newState) {
switch (newState) {
- case SCHEDULED_ENTER_PIP:
- // This state only makes sense when we are not initially in PiP or not entering PiP.
- // PiP can also be replaced upon direct enter, but scheduling like this can happen
- // while an animation is running if PiP is not idle, so we should not
- // disrupt the state machine while an animation is in between its state updates.
- return (!isInPip() && mState != ENTERING_PIP) || isPipStateIdle();
case SCHEDULED_BOUNDS_CHANGE:
// Allow scheduling bounds change only when both of these are true:
// - while in PiP, except for if another bounds change was scheduled but hasn't
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/transition/ContentPipHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/transition/ContentPipHandler.java
deleted file mode 100644
index d9cb7c1..0000000
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/transition/ContentPipHandler.java
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Copyright (C) 2025 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.wm.shell.pip2.phone.transition;
-
-import static com.android.wm.shell.pip2.phone.transition.PipTransitionUtils.getPipChange;
-
-import android.content.Context;
-import android.graphics.Rect;
-import android.os.IBinder;
-import android.view.SurfaceControl;
-import android.window.TransitionInfo;
-import android.window.TransitionRequestInfo;
-import android.window.WindowContainerTransaction;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
-
-import com.android.internal.protolog.ProtoLog;
-import com.android.wm.shell.R;
-import com.android.wm.shell.common.pip.PipBoundsAlgorithm;
-import com.android.wm.shell.pip2.PipSurfaceTransactionHelper;
-import com.android.wm.shell.pip2.animation.PipResizeAnimator;
-import com.android.wm.shell.pip2.phone.PipTransitionState;
-import com.android.wm.shell.protolog.ShellProtoLogGroup;
-import com.android.wm.shell.shared.TransitionUtil;
-import com.android.wm.shell.transition.Transitions;
-
-/**
- * Handles Content-PiP entry CUJ, where an app starts a new PiP-ing activity with launch-into-pip
- * activity option.
- *
- * <p>The PiP activity is expected to immediately draw in PiP-mode before the animation starts,
- * which requires a different handling and animation to other enter PiP transitions.
- */
-public class ContentPipHandler implements Transitions.TransitionHandler {
- private final Context mContext;
- private final PipSurfaceTransactionHelper mPipSurfaceTransactionHelper;
- private final PipTransitionState mPipTransitionState;
-
- @Nullable
- private Transitions.TransitionFinishCallback mFinishCallback;
- private PipResizeAnimatorSupplier mPipResizeAnimatorSupplier;
-
- private final int mEnterAnimationDuration;
-
- public ContentPipHandler(Context context,
- PipSurfaceTransactionHelper pipSurfaceTransactionHelper,
- PipTransitionState pipTransitionState) {
- mContext = context;
- mPipSurfaceTransactionHelper = pipSurfaceTransactionHelper;
- mPipTransitionState = pipTransitionState;
- mPipResizeAnimatorSupplier = PipResizeAnimator::new;
- mEnterAnimationDuration = context.getResources()
- .getInteger(R.integer.config_pipEnterAnimationDuration);
- }
-
- @Nullable
- @Override
- public WindowContainerTransaction handleRequest(@NonNull IBinder transition,
- @NonNull TransitionRequestInfo request) {
- // Content-PiP enter handleRequest filter is invariant from
- // that of auto-enter in button-navigation mode.
- return null;
- }
-
- @Override
- public boolean startAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info,
- @NonNull SurfaceControl.Transaction startTransaction,
- @NonNull SurfaceControl.Transaction finishTransaction,
- @NonNull Transitions.TransitionFinishCallback finishCallback) {
- if (isContentPipEnter(info)) {
- return startEnterContentPipAnimation(transition, info, startTransaction,
- finishTransaction, finishCallback);
- }
- return false;
- }
-
- private boolean isContentPipEnter(@android.annotation.NonNull TransitionInfo info) {
- final TransitionInfo.Change pipChange = getPipChange(info);
- if (pipChange == null || pipChange.getTaskInfo() == null) {
- return false;
- }
- return pipChange.getTaskInfo().launchIntoPipHostTaskId != -1
- && TransitionUtil.isOpeningMode(pipChange.getMode());
- }
-
- private boolean startEnterContentPipAnimation(@NonNull IBinder transition,
- @NonNull TransitionInfo info,
- @NonNull SurfaceControl.Transaction startTransaction,
- @NonNull SurfaceControl.Transaction finishTransaction,
- @NonNull Transitions.TransitionFinishCallback finishCallback) {
- final TransitionInfo.Change pipChange = getPipChange(info);
- if (pipChange == null || pipChange.getTaskInfo() == null) return false;
- mFinishCallback = finishCallback;
-
- final Rect startBounds = pipChange.getStartAbsBounds();
- final Rect endBounds = pipChange.getEndAbsBounds();
-
- final Rect srcRectHint = PipBoundsAlgorithm.getValidSourceHintRect(
- pipChange.getTaskInfo().getPictureInPictureParams(),
- pipChange.getStartAbsBounds(), pipChange.getEndAbsBounds());
- if (srcRectHint != null) {
- startBounds.set(srcRectHint);
- startTransaction.setWindowCrop(pipChange.getLeash(),
- endBounds.width(), endBounds.height());
- finishTransaction.setWindowCrop(pipChange.getLeash(),
- endBounds.width(), endBounds.height());
- }
-
- final PipResizeAnimator animator = mPipResizeAnimatorSupplier.get(mContext,
- mPipSurfaceTransactionHelper, pipChange.getLeash(), startTransaction,
- finishTransaction, endBounds, startBounds, endBounds,
- mEnterAnimationDuration, 0f /* delta */);
- animator.setAnimationEndCallback(this::finishTransition);
- animator.start();
- return true;
- }
-
- private void finishTransition() {
- final int currentState = mPipTransitionState.getState();
- if (currentState != PipTransitionState.ENTERING_PIP) {
- ProtoLog.e(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
- "Unexpected state %s as we are finishing an enter content-pip transition",
- mPipTransitionState);
- }
- mPipTransitionState.setState(PipTransitionState.ENTERED_PIP);
-
- if (mFinishCallback != null) {
- // Need to unset mFinishCallback first because onTransitionFinished can re-enter this
- // handler if there is a pending PiP animation.
- final Transitions.TransitionFinishCallback finishCallback = mFinishCallback;
- mFinishCallback = null;
- finishCallback.onTransitionFinished(null /* finishWct */);
- }
- }
-
- @VisibleForTesting
- interface PipResizeAnimatorSupplier {
- PipResizeAnimator get(@NonNull Context context,
- @NonNull PipSurfaceTransactionHelper pipSurfaceTransactionHelper,
- @NonNull SurfaceControl leash,
- @Nullable SurfaceControl.Transaction startTransaction,
- @Nullable SurfaceControl.Transaction finishTransaction,
- @NonNull Rect baseBounds,
- @NonNull Rect startBounds,
- @NonNull Rect endBounds,
- int duration,
- float delta);
- }
-
- @VisibleForTesting
- void setPipResizeAnimatorSupplier(PipResizeAnimatorSupplier supplier) {
- mPipResizeAnimatorSupplier = supplier;
- }
-}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/PipSchedulerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/PipSchedulerTest.java
index 678c879..a5b9f3b 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/PipSchedulerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/PipSchedulerTest.java
@@ -210,8 +210,6 @@
@Test
public void removePipAfterAnimation() {
setMockPipTaskToken();
- ActivityManager.RunningTaskInfo pipTaskInfo = getTaskInfoWithLastParentBeforePip(1);
- when(mMockPipTransitionState.getPipTaskInfo()).thenReturn(pipTaskInfo);
mPipScheduler.scheduleRemovePip(true /* withFadeout */);
@@ -219,8 +217,8 @@
assertNotNull(mRunnableArgumentCaptor.getValue());
mRunnableArgumentCaptor.getValue().run();
- verify(mMockPipTransitionController, times(1)).startRemoveTransition(
- any(WindowContainerTransaction.class), eq(true) /* withFadeout */);
+ verify(mMockPipTransitionController, times(1))
+ .startRemoveTransition(true /* withFadeout */);
}
@Test
@@ -410,8 +408,6 @@
private ActivityManager.RunningTaskInfo getTaskInfoWithLastParentBeforePip(int lastParentId) {
final ActivityManager.RunningTaskInfo taskInfo = new ActivityManager.RunningTaskInfo();
taskInfo.lastParentTaskIdBeforePip = lastParentId;
- // pick an invalid host task id by default
- taskInfo.launchIntoPipHostTaskId = -1;
return taskInfo;
}
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/transition/ContentPipHandlerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/transition/ContentPipHandlerTest.java
deleted file mode 100644
index 60d4651..0000000
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/transition/ContentPipHandlerTest.java
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * Copyright (C) 2025 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.wm.shell.pip2.phone.transition;
-
-import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
-import static android.view.WindowManager.TRANSIT_OPEN;
-
-import static com.android.wm.shell.pip2.phone.PipTransitionState.ENTERED_PIP;
-import static com.android.wm.shell.pip2.phone.PipTransitionState.ENTERING_PIP;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.ArgumentMatchers.isNull;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-import static org.mockito.kotlin.VerificationKt.never;
-import static org.mockito.kotlin.VerificationKt.times;
-
-import android.app.ActivityManager;
-import android.app.PictureInPictureParams;
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.Rect;
-import android.os.Binder;
-import android.os.IBinder;
-import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
-import android.view.SurfaceControl;
-import android.window.TransitionInfo;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.platform.app.InstrumentationRegistry;
-
-import com.android.wm.shell.R;
-import com.android.wm.shell.pip2.PipSurfaceTransactionHelper;
-import com.android.wm.shell.pip2.animation.PipResizeAnimator;
-import com.android.wm.shell.pip2.phone.PipTransitionState;
-import com.android.wm.shell.transition.TransitionInfoBuilder;
-import com.android.wm.shell.transition.Transitions;
-
-import junit.framework.Assert;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Captor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-/**
- * Unit test against {@link ContentPipHandler}
- */
-
-@SmallTest
-@TestableLooper.RunWithLooper
-@RunWith(AndroidTestingRunner.class)
-public class ContentPipHandlerTest {
- @Mock private Context mContext;
- @Mock private PipSurfaceTransactionHelper mPipSurfaceTransactionHelper;
- @Mock private PipTransitionState mPipTransitionState;
- @Mock private SurfaceControl mPipLeash;
- @Mock private PipResizeAnimator mPipResizeAnimator;
-
- @Mock private SurfaceControl.Transaction mStartTx;
- @Mock private SurfaceControl.Transaction mFinishTx;
-
- private static final Rect APP_BOUNDS = new Rect(0, 0, 500, 1000);
- private static final Rect SOURCE_RECT = new Rect(0, 0, 500, 500);
- private static final Rect END_BOUNDS = new Rect(0, 0, 100, 100);
- private static final int ENTER_DURATION = 100;
-
- private ContentPipHandler mContentPipHandler;
- @Captor
- private ArgumentCaptor<Runnable> mAnimatorCallbackArgumentCaptor;
-
- @Before
- public void setup() {
- MockitoAnnotations.initMocks(this);
-
- final Resources res = mock(Resources.class);
- when(res.getInteger(eq(R.integer.config_pipEnterAnimationDuration)))
- .thenReturn(ENTER_DURATION);
- when(mContext.getResources()).thenReturn(res);
-
- mContentPipHandler = new ContentPipHandler(mContext, mPipSurfaceTransactionHelper,
- mPipTransitionState);
- mContentPipHandler.setPipResizeAnimatorSupplier((context, pipSurfaceTransactionHelper,
- leash, startTransaction, finishTransaction, baseBounds, startBounds, endBounds,
- duration, delta) -> mPipResizeAnimator);
-
- when(mStartTx.setWindowCrop(any(SurfaceControl.class),
- any(Rect.class))).thenReturn(mStartTx);
- when(mFinishTx.setWindowCrop(any(SurfaceControl.class),
- any(Rect.class))).thenReturn(mFinishTx);
- }
-
- @Test
- public void startAnimation_enterContentPip_resizeIntoPipBounds() {
- // set the state to ENTERING_PIP
- when(mPipTransitionState.getState()).thenReturn(ENTERING_PIP);
-
- // create transition info with a content PiP change that has a valid src-rect-hint
- final PictureInPictureParams params = new PictureInPictureParams.Builder()
- .setSourceRectHint(SOURCE_RECT).build();
- final ActivityManager.RunningTaskInfo taskInfo =
- createPipTaskInfo(1, 2, params);
- final TransitionInfo info = getEnterPipTransitionInfo(taskInfo, APP_BOUNDS, END_BOUNDS);
-
- final IBinder transitionToken = new Binder();
- final Transitions.TransitionFinishCallback finishCallback =
- mock(Transitions.TransitionFinishCallback.class);
- mContentPipHandler.startAnimation(transitionToken, info, mStartTx, mFinishTx,
- finishCallback);
-
- verify(mStartTx, times(1)).setWindowCrop(eq(mPipLeash),
- eq(END_BOUNDS.width()), eq(END_BOUNDS.height()));
- verify(mFinishTx, times(1)).setWindowCrop(eq(mPipLeash),
- eq(END_BOUNDS.width()), eq(END_BOUNDS.height()));
-
- // check whether finish callback is scheduled to run at the end.
- verify(mPipResizeAnimator, times(1))
- .setAnimationEndCallback(mAnimatorCallbackArgumentCaptor.capture());
- InstrumentationRegistry.getInstrumentation()
- .runOnMainSync(mAnimatorCallbackArgumentCaptor.getValue());
-
- verify(mPipTransitionState, times(1)).setState(ENTERED_PIP);
- verify(finishCallback, times(1)).onTransitionFinished(isNull());
-
- // verify that the animator actually starts
- verify(mPipResizeAnimator, times(1)).start();
- }
-
- @Test
- public void startAnimation_enterNonContentPip_returnFalse() {
- // set the state to ENTERING_PIP
- when(mPipTransitionState.getState()).thenReturn(ENTERING_PIP);
-
- // create transition info with a content PiP change that has a valid src-rect-hint
- final PictureInPictureParams params = new PictureInPictureParams.Builder()
- .setSourceRectHint(SOURCE_RECT).build();
- final ActivityManager.RunningTaskInfo taskInfo =
- createPipTaskInfo(1, -1, params);
- final TransitionInfo info = getEnterPipTransitionInfo(taskInfo, APP_BOUNDS, END_BOUNDS);
-
- final IBinder transitionToken = new Binder();
- final Transitions.TransitionFinishCallback finishCallback =
- mock(Transitions.TransitionFinishCallback.class);
- final boolean didHandle = mContentPipHandler.startAnimation(transitionToken,
- info, mStartTx, mFinishTx, finishCallback);
-
- Assert.assertFalse(didHandle);
-
- verify(mPipTransitionState, never()).setState(ENTERED_PIP);
- verify(finishCallback, never()).onTransitionFinished(isNull());
-
- // verify that the animator actually starts
- verify(mPipResizeAnimator, never()).start();
- }
-
- private TransitionInfo getEnterPipTransitionInfo(
- ActivityManager.RunningTaskInfo pipTaskInfo, Rect startBounds, Rect endBounds) {
- final TransitionInfo info = new TransitionInfoBuilder(TRANSIT_OPEN)
- .addChange(TRANSIT_OPEN, pipTaskInfo).build();
- final TransitionInfo.Change pipChange = info.getChanges().getFirst();
- pipChange.setStartAbsBounds(startBounds);
- pipChange.setEndAbsBounds(endBounds);
- pipChange.setLeash(mPipLeash);
- return info;
- }
-
- private static ActivityManager.RunningTaskInfo createPipTaskInfo(int taskId,
- int launchIntoPipHostTaskId,
- PictureInPictureParams params) {
- ActivityManager.RunningTaskInfo taskInfo = new ActivityManager.RunningTaskInfo();
- taskInfo.taskId = taskId;
- taskInfo.launchIntoPipHostTaskId = launchIntoPipHostTaskId;
- taskInfo.configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_PINNED);
- taskInfo.pictureInPictureParams = params;
- return taskInfo;
- }
-}
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 85ba953..6fdf1f9 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -3305,10 +3305,6 @@
return false;
}
- if (getOptions() != null && getOptions().isLaunchIntoPip()) {
- return true;
- }
-
boolean isCurrentAppLocked =
mAtmService.getLockTaskModeState() != LOCK_TASK_MODE_NONE;
final TaskDisplayArea taskDisplayArea = getDisplayArea();
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index 1dd1aa9..389b73f 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -78,7 +78,6 @@
import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.ActivityTaskManagerService.ANIMATE;
-import static com.android.server.wm.ActivityTaskManagerService.isPip2ExperimentEnabled;
import static com.android.server.wm.ActivityTaskSupervisor.DEFER_RESUME;
import static com.android.server.wm.ActivityTaskSupervisor.ON_TOP;
import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_DEFAULT;
@@ -2170,12 +2169,8 @@
if (mOptions != null && mOptions.isLaunchIntoPip()
&& sourceRecord != null && sourceRecord.getTask() == mStartActivity.getTask()
&& balVerdict.allows()) {
- if (isPip2ExperimentEnabled()) {
- mService.setPipCandidateIfNeeded(mStartActivity);
- } else {
- mRootWindowContainer.moveActivityToPinnedRootTask(mStartActivity,
- sourceRecord, "launch-into-pip", null /* bounds */);
- }
+ mRootWindowContainer.moveActivityToPinnedRootTask(mStartActivity,
+ sourceRecord, "launch-into-pip", null /* bounds */);
}
mSupervisor.getBackgroundActivityLaunchController()
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index bdcb978..32cb8a5 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -3799,28 +3799,21 @@
}
/**
- * Sets a PiP candidate into an already collecting transition if needed.
+ * Prepare to enter PiP mode after {@link TransitionController#requestStartDisplayTransition}.
*
- * <p>Marking an activity as a PiP candidate in a collecting transition, will dispatch
- * info about this activity to Shell when the transition is sent to Shell via
- * requestStartTransition.</p>
- *
- * <p>This makes sense when an activity is either auto-enter PiP activity is requested to be
- * launched into PiP as soon as the activity starts. For these cases, it makes sense to try and
- * enter PiP in an already collecting transition instead of creating a separate TRANSIT_PIP.</p>
- *
- * @param r activity to be set as a PiP-ing candidate in an already collecting transition
+ * @param r activity auto entering pip
+ * @return true if the activity is about to auto-enter pip or is already in pip mode.
*/
- boolean setPipCandidateIfNeeded(@NonNull ActivityRecord r) {
+ boolean prepareAutoEnterPictureAndPictureMode(ActivityRecord r) {
// If the activity is already in picture in picture mode, then just return early
if (r.inPinnedWindowingMode()) {
return true;
}
if (r.canAutoEnterPip() && getTransitionController().getCollectingTransition() != null) {
- // If there is a collecting transition, try to signal a potential PiP candidate
- // for Shell to consider when that transition is being requested.
// This will be used later to construct TransitionRequestInfo for Shell to resolve.
+ // It will also be passed into a direct moveActivityToPinnedRootTask() call via
+ // startTransition()
getTransitionController().getCollectingTransition().setPipActivity(r);
return true;
}
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 66a75f8..06c1339 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -2234,6 +2234,10 @@
// TODO(remove-legacy-transit): Move this to the `singleActivity` case when removing
// legacy transit.
rootTask.setRootTaskWindowingMode(WINDOWING_MODE_PINNED);
+ if (isPip2ExperimentEnabled() && bounds != null) {
+ // set the final pip bounds in advance if pip2 is enabled
+ rootTask.setBounds(bounds);
+ }
// Set the launch bounds for launch-into-pip Activity on the root task.
if (r.getOptions() != null && r.getOptions().isLaunchIntoPip()) {
@@ -2241,17 +2245,8 @@
// We do this early in the process to make sure the right snapshot is used for
// entering content-pip animation.
mWindowManager.mTaskSnapshotController.recordSnapshot(task);
- if (!isPip2ExperimentEnabled()) {
- // PiP2 always supplies bounds from Shell, so we can skip this.
- rootTask.setBounds(r.pictureInPictureArgs.getSourceRectHint());
- }
+ rootTask.setBounds(r.pictureInPictureArgs.getSourceRectHint());
}
-
- if (isPip2ExperimentEnabled() && bounds != null) {
- // set the final pip bounds in advance if pip2 is enabled
- rootTask.setBounds(bounds);
- }
-
rootTask.setDeferTaskAppear(false);
if (!isPip2ExperimentEnabled()) {
diff --git a/services/core/java/com/android/server/wm/TaskFragment.java b/services/core/java/com/android/server/wm/TaskFragment.java
index 5f47f62d..366e5ac 100644
--- a/services/core/java/com/android/server/wm/TaskFragment.java
+++ b/services/core/java/com/android/server/wm/TaskFragment.java
@@ -1895,7 +1895,7 @@
if (prev.attachedToProcess()) {
if (shouldAutoPip && ActivityTaskManagerService.isPip2ExperimentEnabled()) {
prev.mPauseSchedulePendingForPip = true;
- boolean willAutoPip = mAtmService.setPipCandidateIfNeeded(prev);
+ boolean willAutoPip = mAtmService.prepareAutoEnterPictureAndPictureMode(prev);
ProtoLog.d(WM_DEBUG_STATES, "Auto-PIP allowed, requesting PIP mode "
+ "via requestStartTransition(): %s, willAutoPip: %b", prev, willAutoPip);
} else if (shouldAutoPip) {
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
index edb7c5e..43e479b 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
@@ -97,7 +97,6 @@
import android.os.RemoteException;
import android.platform.test.annotations.EnableFlags;
import android.platform.test.annotations.Presubmit;
-import android.platform.test.annotations.RequiresFlagsDisabled;
import android.provider.DeviceConfig;
import android.service.voice.IVoiceInteractionSession;
import android.util.Pair;
@@ -1530,8 +1529,7 @@
}
@Test
- @RequiresFlagsDisabled(com.android.wm.shell.Flags.FLAG_ENABLE_PIP2)
- public void testStartLaunchIntoPipActivity_setLaunchIntoPipHostActivity() {
+ public void testStartLaunchIntoPipActivity() {
final ActivityStarter starter = prepareStarter(0, false);
// Create an activity from ActivityOptions#makeLaunchIntoPip