Merge "PiP: Move enter-PiP on-pause logic." into sc-v2-dev

This commit is contained in:
Ben Lin
2021-06-17 21:50:11 +00:00
committed by Android (Google) Code Review
9 changed files with 91 additions and 14 deletions

View File

@@ -394,6 +394,11 @@ public interface WindowManager extends ViewManager {
* @hide
*/
int TRANSIT_KEYGUARD_UNOCCLUDE = 9;
/**
* A window is starting to enter PiP.
* @hide
*/
int TRANSIT_PIP = 10;
/**
* The first slot for custom transition types. Callers (like Shell) can make use of custom
* transition types for dealing with special cases. These types are effectively ignored by
@@ -403,7 +408,7 @@ public interface WindowManager extends ViewManager {
* implementation.
* @hide
*/
int TRANSIT_FIRST_CUSTOM = 10;
int TRANSIT_FIRST_CUSTOM = 11;
/**
* @hide
@@ -419,6 +424,7 @@ public interface WindowManager extends ViewManager {
TRANSIT_KEYGUARD_GOING_AWAY,
TRANSIT_KEYGUARD_OCCLUDE,
TRANSIT_KEYGUARD_UNOCCLUDE,
TRANSIT_PIP,
TRANSIT_FIRST_CUSTOM
})
@Retention(RetentionPolicy.SOURCE)

View File

@@ -463,6 +463,15 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
}
private void removePipImmediately() {
if (Transitions.ENABLE_SHELL_TRANSITIONS) {
final WindowContainerTransaction wct = new WindowContainerTransaction();
wct.setBounds(mToken, null);
wct.setWindowingMode(mToken, WINDOWING_MODE_UNDEFINED);
wct.reorder(mToken, false);
mPipTransitionController.startTransition(null, wct);
return;
}
try {
// Reset the task bounds first to ensure the activity configuration is reset as well
final WindowContainerTransaction wct = new WindowContainerTransaction();
@@ -524,6 +533,8 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
if (Transitions.ENABLE_SHELL_TRANSITIONS) {
if (mOneShotAnimationType == ANIM_TYPE_BOUNDS) {
mPipMenuController.attach(mLeash);
} else if (mOneShotAnimationType == ANIM_TYPE_ALPHA) {
mOneShotAnimationType = ANIM_TYPE_BOUNDS;
}
return;
}

View File

@@ -18,6 +18,7 @@ package com.android.wm.shell.pip;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.view.WindowManager.TRANSIT_PIP;
import static android.window.TransitionInfo.FLAG_IS_WALLPAPER;
import static com.android.wm.shell.pip.PipAnimationController.ANIM_TYPE_ALPHA;
@@ -27,6 +28,7 @@ import static com.android.wm.shell.pip.PipAnimationController.TRANSITION_DIRECTI
import static com.android.wm.shell.pip.PipAnimationController.isInPipDirection;
import static com.android.wm.shell.pip.PipAnimationController.isOutPipDirection;
import static com.android.wm.shell.transition.Transitions.TRANSIT_EXIT_PIP;
import static com.android.wm.shell.transition.Transitions.TRANSIT_REMOVE_PIP;
import android.app.TaskInfo;
import android.content.Context;
@@ -73,10 +75,28 @@ public class PipTransition extends PipTransitionController {
.getInteger(R.integer.config_pipResizeAnimationDuration);
}
@Override
public void setIsFullAnimation(boolean isFullAnimation) {
setOneShotAnimationType(isFullAnimation ? ANIM_TYPE_BOUNDS : ANIM_TYPE_ALPHA);
}
/**
* Sets the preferred animation type for one time.
* This is typically used to set the animation type to
* {@link PipAnimationController#ANIM_TYPE_ALPHA}.
*/
private void setOneShotAnimationType(@PipAnimationController.AnimationType int animationType) {
mOneShotAnimationType = animationType;
}
@Override
public void startTransition(Rect destinationBounds, WindowContainerTransaction out) {
mExitDestinationBounds.set(destinationBounds);
mTransitions.startTransition(TRANSIT_EXIT_PIP, out, this);
if (destinationBounds != null) {
mExitDestinationBounds.set(destinationBounds);
mTransitions.startTransition(TRANSIT_EXIT_PIP, out, this);
} else {
mTransitions.startTransition(TRANSIT_REMOVE_PIP, out, this);
}
}
@Override
@@ -96,6 +116,14 @@ public class PipTransition extends PipTransitionController {
return success;
}
if (info.getType() == TRANSIT_REMOVE_PIP) {
startTransaction.apply();
finishTransaction.setWindowCrop(info.getChanges().get(0).getLeash(),
mPipBoundsState.getDisplayBounds());
finishCallback.onTransitionFinished(null, null);
return true;
}
// Search for an Enter PiP transition (along with a show wallpaper one)
TransitionInfo.Change enterPip = null;
TransitionInfo.Change wallpaper = null;
@@ -129,13 +157,23 @@ public class PipTransition extends PipTransitionController {
@Override
public WindowContainerTransaction handleRequest(@NonNull IBinder transition,
@NonNull TransitionRequestInfo request) {
return null;
if (request.getType() == TRANSIT_PIP) {
WindowContainerTransaction wct = new WindowContainerTransaction();
mPipTransitionState.setTransitionState(PipTransitionState.ENTRY_SCHEDULED);
final Rect destinationBounds = mPipBoundsAlgorithm.getEntryDestinationBounds();
wct.setActivityWindowingMode(request.getTriggerTask().token, WINDOWING_MODE_UNDEFINED);
wct.setBounds(request.getTriggerTask().token, destinationBounds);
return wct;
} else {
return null;
}
}
@Override
public void onFinishResize(TaskInfo taskInfo, Rect destinationBounds,
@PipAnimationController.TransitionDirection int direction,
SurfaceControl.Transaction tx) {
if (isInPipDirection(direction)) {
mPipTransitionState.setTransitionState(PipTransitionState.ENTERED_PIP);
}
@@ -185,6 +223,9 @@ public class PipTransition extends PipTransitionController {
0 /* startingAngle */, Surface.ROTATION_0);
} else if (mOneShotAnimationType == ANIM_TYPE_ALPHA) {
startTransaction.setAlpha(leash, 0f);
// PiP menu is attached late in the process here to avoid any artifacts on the leash
// caused by addShellRoot when in gesture navigation mode.
mPipMenuController.attach(leash);
animator = mPipAnimationController.getAnimator(taskInfo, leash, destinationBounds,
0f, 1f);
mOneShotAnimationType = ANIM_TYPE_BOUNDS;

View File

@@ -100,6 +100,15 @@ public abstract class PipTransitionController implements Transitions.TransitionH
SurfaceControl.Transaction tx) {
}
/**
* Called to inform the transition that the animation should start with the assumption that
* PiP is not animating from its original bounds, but rather a continuation of another
* animation. For example, gesture navigation would first fade out the PiP activity, and the
* transition should be responsible to animate in (such as fade in) the PiP.
*/
public void setIsFullAnimation(boolean isFullAnimation) {
}
/**
* Called when the Shell wants to starts a transition/animation.
*/

View File

@@ -67,6 +67,7 @@ import com.android.wm.shell.pip.IPip;
import com.android.wm.shell.pip.IPipAnimationListener;
import com.android.wm.shell.pip.PinnedStackListenerForwarder;
import com.android.wm.shell.pip.Pip;
import com.android.wm.shell.pip.PipAnimationController;
import com.android.wm.shell.pip.PipBoundsAlgorithm;
import com.android.wm.shell.pip.PipBoundsState;
import com.android.wm.shell.pip.PipMediaController;
@@ -528,6 +529,8 @@ public class PipController implements PipTransitionController.PipTransitionCallb
private void setPinnedStackAnimationType(int animationType) {
mPipTaskOrganizer.setOneShotAnimationType(animationType);
mPipTransitionController.setIsFullAnimation(
animationType == PipAnimationController.ANIM_TYPE_BOUNDS);
}
private void setPinnedStackAnimationListener(IPipAnimationListener callback) {

View File

@@ -77,9 +77,12 @@ public class Transitions implements RemoteCallable<Transitions> {
/** Transition type for launching 2 tasks simultaneously. */
public static final int TRANSIT_SPLIT_SCREEN_PAIR_OPEN = TRANSIT_FIRST_CUSTOM + 2;
/** Transition type for exiting PIP via the Shell, either via Expand or Dismiss. */
/** Transition type for exiting PIP via the Shell, via pressing the expand button. */
public static final int TRANSIT_EXIT_PIP = TRANSIT_FIRST_CUSTOM + 3;
/** Transition type for removing PIP via the Shell, either via Dismiss bubble or Close. */
public static final int TRANSIT_REMOVE_PIP = TRANSIT_FIRST_CUSTOM + 4;
private final WindowOrganizer mOrganizer;
private final Context mContext;
private final ShellExecutor mMainExecutor;

View File

@@ -4530,6 +4530,10 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
}
}
boolean getDeferHidingClient() {
return mDeferHidingClient;
}
@Override
boolean isVisible() {
// If the activity isn't hidden then it is considered visible and there is no need to check
@@ -5248,13 +5252,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
supportsEnterPipOnTaskSwitch = false;
break;
case RESUMED:
// If the app is capable of entering PIP, we should try pausing it now
// so it can PIP correctly.
if (deferHidingClient) {
getTaskFragment().startPausing(false /* uiSleeping */,
null /* resuming */, "makeInvisible");
break;
}
case INITIALIZING:
case PAUSING:
case PAUSED:

View File

@@ -36,10 +36,10 @@ import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SUSTAINED_PERFORMANCE_MODE;
import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG;
import static android.view.WindowManager.LayoutParams.TYPE_NOTIFICATION_SHADE;
import static android.view.WindowManager.TRANSIT_CHANGE;
import static android.view.WindowManager.TRANSIT_CLOSE;
import static android.view.WindowManager.TRANSIT_FLAG_APP_CRASHED;
import static android.view.WindowManager.TRANSIT_NONE;
import static android.view.WindowManager.TRANSIT_PIP;
import static android.view.WindowManager.TRANSIT_TO_BACK;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_FOCUS_LIGHT;
@@ -2177,7 +2177,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
// display area, so reparent.
rootTask.reparent(taskDisplayArea, true /* onTop */);
}
mService.getTransitionController().requestTransitionIfNeeded(TRANSIT_CHANGE, rootTask);
mService.getTransitionController().requestTransitionIfNeeded(TRANSIT_PIP, rootTask);
// Defer the windowing mode change until after the transition to prevent the activity
// from doing work and changing the activity visuals while animating

View File

@@ -300,6 +300,13 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
for (int i = 0; i < mParticipants.size(); ++i) {
final ActivityRecord ar = mParticipants.valueAt(i).asActivityRecord();
if (ar != null && !ar.isVisibleRequested()) {
// If activity is capable of entering PiP, give it a chance to enter it now.
if (ar.getDeferHidingClient() && ar.getTask() != null) {
mController.mAtm.mTaskSupervisor.mUserLeaving = true;
ar.getTaskFragment().startPausing(false /* uiSleeping */, null /* resuming */,
"finishTransition");
mController.mAtm.mTaskSupervisor.mUserLeaving = false;
}
ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS,
" Commit activity becoming invisible: %s", ar);
ar.commitVisibility(false /* visible */, false /* performLayout */);