Merge "Fix PiP Shell Transitions" into sc-v2-dev
This commit is contained in:
@@ -1141,6 +1141,12 @@
|
||||
"group": "WM_DEBUG_BOOT",
|
||||
"at": "com\/android\/server\/wm\/WindowManagerService.java"
|
||||
},
|
||||
"-863438038": {
|
||||
"message": "Aborting Transition: %d",
|
||||
"level": "VERBOSE",
|
||||
"group": "WM_DEBUG_WINDOW_TRANSITIONS",
|
||||
"at": "com\/android\/server\/wm\/Transition.java"
|
||||
},
|
||||
"-861859917": {
|
||||
"message": "Attempted to add window to a display that does not exist: %d. Aborting.",
|
||||
"level": "WARN",
|
||||
|
||||
@@ -282,6 +282,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
||||
mMainExecutor.execute(() -> {
|
||||
mTaskOrganizer.addListenerForType(this, TASK_LISTENER_TYPE_PIP);
|
||||
});
|
||||
mPipTransitionController.setPipOrganizer(this);
|
||||
displayController.addDisplayWindowListener(this);
|
||||
}
|
||||
|
||||
@@ -349,6 +350,10 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
||||
}
|
||||
}
|
||||
|
||||
public ActivityManager.RunningTaskInfo getTaskInfo() {
|
||||
return mTaskInfo;
|
||||
}
|
||||
|
||||
public SurfaceControl getSurfaceControl() {
|
||||
return mLeash;
|
||||
}
|
||||
@@ -716,6 +721,9 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
||||
mOnDisplayIdChangeCallback.accept(Display.DEFAULT_DISPLAY);
|
||||
}
|
||||
|
||||
if (Transitions.ENABLE_SHELL_TRANSITIONS) {
|
||||
mPipTransitionController.forceFinishTransition();
|
||||
}
|
||||
final PipAnimationController.PipTransitionAnimator<?> animator =
|
||||
mPipAnimationController.getCurrentAnimator();
|
||||
if (animator != null) {
|
||||
|
||||
@@ -32,17 +32,18 @@ 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.ActivityManager;
|
||||
import android.app.TaskInfo;
|
||||
import android.content.Context;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.Rect;
|
||||
import android.os.IBinder;
|
||||
import android.util.Log;
|
||||
import android.view.Surface;
|
||||
import android.view.SurfaceControl;
|
||||
import android.window.TransitionInfo;
|
||||
import android.window.TransitionRequestInfo;
|
||||
import android.window.WindowContainerTransaction;
|
||||
import android.window.WindowContainerTransactionCallback;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
@@ -57,11 +58,14 @@ import com.android.wm.shell.transition.Transitions;
|
||||
*/
|
||||
public class PipTransition extends PipTransitionController {
|
||||
|
||||
private static final String TAG = PipTransition.class.getSimpleName();
|
||||
|
||||
private final PipTransitionState mPipTransitionState;
|
||||
private final int mEnterExitAnimationDuration;
|
||||
private @PipAnimationController.AnimationType int mOneShotAnimationType = ANIM_TYPE_BOUNDS;
|
||||
private Transitions.TransitionFinishCallback mFinishCallback;
|
||||
private Rect mExitDestinationBounds = new Rect();
|
||||
private IBinder mExitTransition = null;
|
||||
|
||||
public PipTransition(Context context,
|
||||
PipBoundsState pipBoundsState,
|
||||
@@ -96,7 +100,7 @@ public class PipTransition extends PipTransitionController {
|
||||
public void startTransition(Rect destinationBounds, WindowContainerTransaction out) {
|
||||
if (destinationBounds != null) {
|
||||
mExitDestinationBounds.set(destinationBounds);
|
||||
mTransitions.startTransition(TRANSIT_EXIT_PIP, out, this);
|
||||
mExitTransition = mTransitions.startTransition(TRANSIT_EXIT_PIP, out, this);
|
||||
} else {
|
||||
mTransitions.startTransition(TRANSIT_REMOVE_PIP, out, this);
|
||||
}
|
||||
@@ -109,14 +113,19 @@ public class PipTransition extends PipTransitionController {
|
||||
@android.annotation.NonNull SurfaceControl.Transaction finishTransaction,
|
||||
@android.annotation.NonNull Transitions.TransitionFinishCallback finishCallback) {
|
||||
|
||||
if (info.getType() == TRANSIT_EXIT_PIP && info.getChanges().size() == 1) {
|
||||
final TransitionInfo.Change change = info.getChanges().get(0);
|
||||
mFinishCallback = finishCallback;
|
||||
startTransaction.apply();
|
||||
boolean success = startExpandAnimation(change.getTaskInfo(), change.getLeash(),
|
||||
new Rect(mExitDestinationBounds));
|
||||
mExitDestinationBounds.setEmpty();
|
||||
return success;
|
||||
if (mExitTransition == transition || info.getType() == TRANSIT_EXIT_PIP) {
|
||||
mExitTransition = null;
|
||||
if (info.getChanges().size() == 1) {
|
||||
final TransitionInfo.Change change = info.getChanges().get(0);
|
||||
mFinishCallback = finishCallback;
|
||||
startTransaction.apply();
|
||||
boolean success = startExpandAnimation(change.getTaskInfo(), change.getLeash(),
|
||||
new Rect(mExitDestinationBounds));
|
||||
mExitDestinationBounds.setEmpty();
|
||||
return success;
|
||||
} else {
|
||||
Log.e(TAG, "Got an exit-pip transition with unexpected change-list");
|
||||
}
|
||||
}
|
||||
|
||||
if (info.getType() == TRANSIT_REMOVE_PIP) {
|
||||
@@ -182,27 +191,59 @@ public class PipTransition extends PipTransitionController {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTransitionMerged(@NonNull IBinder transition) {
|
||||
if (transition != mExitTransition) {
|
||||
return;
|
||||
}
|
||||
// This means an expand happened before enter-pip finished and we are now "merging" a
|
||||
// no-op transition that happens to match our exit-pip.
|
||||
boolean cancelled = false;
|
||||
if (mPipAnimationController.getCurrentAnimator() != null) {
|
||||
mPipAnimationController.getCurrentAnimator().cancel();
|
||||
cancelled = true;
|
||||
}
|
||||
// Unset exitTransition AFTER cancel so that finishResize knows we are merging.
|
||||
mExitTransition = null;
|
||||
if (!cancelled) return;
|
||||
final ActivityManager.RunningTaskInfo taskInfo = mPipOrganizer.getTaskInfo();
|
||||
if (taskInfo != null) {
|
||||
startExpandAnimation(taskInfo, mPipOrganizer.getSurfaceControl(),
|
||||
new Rect(mExitDestinationBounds));
|
||||
}
|
||||
mExitDestinationBounds.setEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFinishResize(TaskInfo taskInfo, Rect destinationBounds,
|
||||
@PipAnimationController.TransitionDirection int direction,
|
||||
SurfaceControl.Transaction tx) {
|
||||
@Nullable SurfaceControl.Transaction tx) {
|
||||
|
||||
if (isInPipDirection(direction)) {
|
||||
mPipTransitionState.setTransitionState(PipTransitionState.ENTERED_PIP);
|
||||
}
|
||||
WindowContainerTransaction wct = new WindowContainerTransaction();
|
||||
prepareFinishResizeTransaction(taskInfo, destinationBounds,
|
||||
direction, tx, wct);
|
||||
mFinishCallback.onTransitionFinished(wct, new WindowContainerTransactionCallback() {
|
||||
@Override
|
||||
public void onTransactionReady(int id, @NonNull SurfaceControl.Transaction t) {
|
||||
t.merge(tx);
|
||||
t.apply();
|
||||
// If there is an expected exit transition, then the exit will be "merged" into this
|
||||
// transition so don't fire the finish-callback in that case.
|
||||
if (mExitTransition == null && mFinishCallback != null) {
|
||||
WindowContainerTransaction wct = new WindowContainerTransaction();
|
||||
prepareFinishResizeTransaction(taskInfo, destinationBounds,
|
||||
direction, wct);
|
||||
if (tx != null) {
|
||||
wct.setBoundsChangeTransaction(taskInfo.token, tx);
|
||||
}
|
||||
});
|
||||
mFinishCallback.onTransitionFinished(wct, null /* wctCallback */);
|
||||
mFinishCallback = null;
|
||||
}
|
||||
finishResizeForMenu(destinationBounds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forceFinishTransition() {
|
||||
if (mFinishCallback == null) return;
|
||||
mFinishCallback.onTransitionFinished(null /* wct */, null /* wctCallback */);
|
||||
mFinishCallback = null;
|
||||
}
|
||||
|
||||
private boolean startExpandAnimation(final TaskInfo taskInfo, final SurfaceControl leash,
|
||||
final Rect destinationBounds) {
|
||||
PipAnimationController.PipTransitionAnimator animator =
|
||||
@@ -243,7 +284,7 @@ public class PipTransition extends PipTransitionController {
|
||||
startTransaction.merge(tx);
|
||||
startTransaction.apply();
|
||||
mPipBoundsState.setBounds(destinationBounds);
|
||||
onFinishResize(taskInfo, destinationBounds, TRANSITION_DIRECTION_TO_PIP, tx);
|
||||
onFinishResize(taskInfo, destinationBounds, TRANSITION_DIRECTION_TO_PIP, null /* tx */);
|
||||
sendOnPipTransitionFinished(TRANSITION_DIRECTION_TO_PIP);
|
||||
mFinishCallback = null;
|
||||
mPipTransitionState.setInSwipePipToHomeTransition(false);
|
||||
@@ -292,7 +333,6 @@ public class PipTransition extends PipTransitionController {
|
||||
|
||||
private void prepareFinishResizeTransaction(TaskInfo taskInfo, Rect destinationBounds,
|
||||
@PipAnimationController.TransitionDirection int direction,
|
||||
SurfaceControl.Transaction tx,
|
||||
WindowContainerTransaction wct) {
|
||||
Rect taskBounds = null;
|
||||
if (isInPipDirection(direction)) {
|
||||
|
||||
@@ -49,6 +49,7 @@ public abstract class PipTransitionController implements Transitions.TransitionH
|
||||
protected final Transitions mTransitions;
|
||||
private final Handler mMainHandler;
|
||||
private final List<PipTransitionCallback> mPipTransitionCallbacks = new ArrayList<>();
|
||||
protected PipTaskOrganizer mPipOrganizer;
|
||||
|
||||
protected final PipAnimationController.PipAnimationCallback mPipAnimationCallback =
|
||||
new PipAnimationController.PipAnimationCallback() {
|
||||
@@ -103,6 +104,13 @@ public abstract class PipTransitionController implements Transitions.TransitionH
|
||||
// Default implementation does nothing.
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the transition animation can't continue (eg. task is removed during
|
||||
* animation)
|
||||
*/
|
||||
public void forceFinishTransition() {
|
||||
}
|
||||
|
||||
public PipTransitionController(PipBoundsState pipBoundsState,
|
||||
PipMenuController pipMenuController, PipBoundsAlgorithm pipBoundsAlgorithm,
|
||||
PipAnimationController pipAnimationController, Transitions transitions,
|
||||
@@ -119,6 +127,10 @@ public abstract class PipTransitionController implements Transitions.TransitionH
|
||||
}
|
||||
}
|
||||
|
||||
void setPipOrganizer(PipTaskOrganizer pto) {
|
||||
mPipOrganizer = pto;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers {@link PipTransitionCallback} to receive transition callbacks.
|
||||
*/
|
||||
|
||||
@@ -1565,7 +1565,7 @@ class ActivityStarter {
|
||||
// transition based on a sub-action.
|
||||
// Only do the create here (and defer requestStart) since startActivityInner might abort.
|
||||
final TransitionController transitionController = r.mTransitionController;
|
||||
final Transition newTransition = (!transitionController.isCollecting()
|
||||
Transition newTransition = (!transitionController.isCollecting()
|
||||
&& transitionController.getTransitionPlayer() != null)
|
||||
? transitionController.createTransition(TRANSIT_OPEN) : null;
|
||||
RemoteTransition remoteTransition = r.takeRemoteTransition();
|
||||
@@ -1620,6 +1620,10 @@ class ActivityStarter {
|
||||
// The activity is started new rather than just brought forward, so record
|
||||
// it as an existence change.
|
||||
transitionController.collectExistenceChange(r);
|
||||
} else if (result == START_DELIVERED_TO_TOP && newTransition != null) {
|
||||
// We just delivered to top, so there isn't an actual transition here
|
||||
newTransition.abort();
|
||||
newTransition = null;
|
||||
}
|
||||
if (isTransient) {
|
||||
// `r` isn't guaranteed to be the actual relevant activity, so we must wait
|
||||
|
||||
@@ -469,6 +469,7 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
|
||||
if (mState != STATE_COLLECTING) {
|
||||
throw new IllegalStateException("Too late to abort.");
|
||||
}
|
||||
ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS, "Aborting Transition: %d", mSyncId);
|
||||
mController.dispatchLegacyAppTransitionCancelled();
|
||||
mState = STATE_ABORT;
|
||||
// Syncengine abort will call through to onTransactionReady()
|
||||
|
||||
Reference in New Issue
Block a user