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