Merge "Fix pip update transaction out of order" into tm-qpr-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
16712430df
@@ -63,6 +63,7 @@ import android.graphics.Rect;
|
|||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
import android.view.Choreographer;
|
||||||
import android.view.Display;
|
import android.view.Display;
|
||||||
import android.view.Surface;
|
import android.view.Surface;
|
||||||
import android.view.SurfaceControl;
|
import android.view.SurfaceControl;
|
||||||
@@ -179,8 +180,10 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
|||||||
// This is necessary in case there was a resize animation ongoing when exit PIP
|
// This is necessary in case there was a resize animation ongoing when exit PIP
|
||||||
// started, in which case the first resize will be skipped to let the exit
|
// started, in which case the first resize will be skipped to let the exit
|
||||||
// operation handle the final resize out of PIP mode. See b/185306679.
|
// operation handle the final resize out of PIP mode. See b/185306679.
|
||||||
finishResize(tx, destinationBounds, direction, animationType);
|
finishResizeDelayedIfNeeded(() -> {
|
||||||
sendOnPipTransitionFinished(direction);
|
finishResize(tx, destinationBounds, direction, animationType);
|
||||||
|
sendOnPipTransitionFinished(direction);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -196,6 +199,39 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finishes resizing the PiP, delaying the operation if it has to be synced with the PiP menu.
|
||||||
|
*
|
||||||
|
* This is done to avoid a race condition between the last transaction applied in
|
||||||
|
* onPipAnimationUpdate and the finishResize in onPipAnimationEnd. The transaction in
|
||||||
|
* onPipAnimationUpdate is applied directly from WmShell, while onPipAnimationEnd creates a
|
||||||
|
* WindowContainerTransaction in finishResize, which is to be applied by WmCore later. Normally,
|
||||||
|
* the WCT should be the last transaction to finish the animation. However, it may happen that
|
||||||
|
* it gets applied *before* the transaction created by the last onPipAnimationUpdate. This
|
||||||
|
* happens only when the PiP surface transaction has to be synced with the PiP menu due to the
|
||||||
|
* necessity for a delay when syncing the PiP surface animation with the PiP menu surface
|
||||||
|
* animation and redrawing the PiP menu contents. As a result, the PiP surface gets scaled after
|
||||||
|
* the new bounds are applied by WmCore, which makes the PiP surface have unexpected bounds.
|
||||||
|
*
|
||||||
|
* To avoid this, we delay the finishResize operation until
|
||||||
|
* the next frame. This aligns the last onAnimationUpdate transaction with the WCT application.
|
||||||
|
*/
|
||||||
|
private void finishResizeDelayedIfNeeded(Runnable finishResizeRunnable) {
|
||||||
|
if (!shouldSyncPipTransactionWithMenu()) {
|
||||||
|
finishResizeRunnable.run();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delay the finishResize to the next frame
|
||||||
|
Choreographer.getInstance().postCallback(Choreographer.CALLBACK_COMMIT, () -> {
|
||||||
|
mMainExecutor.execute(finishResizeRunnable);
|
||||||
|
}, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean shouldSyncPipTransactionWithMenu() {
|
||||||
|
return mPipMenuController.isMenuVisible();
|
||||||
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
final PipTransitionController.PipTransitionCallback mPipTransitionCallback =
|
final PipTransitionController.PipTransitionCallback mPipTransitionCallback =
|
||||||
new PipTransitionController.PipTransitionCallback() {
|
new PipTransitionController.PipTransitionCallback() {
|
||||||
@@ -221,7 +257,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
|||||||
@Override
|
@Override
|
||||||
public boolean handlePipTransaction(SurfaceControl leash,
|
public boolean handlePipTransaction(SurfaceControl leash,
|
||||||
SurfaceControl.Transaction tx, Rect destinationBounds) {
|
SurfaceControl.Transaction tx, Rect destinationBounds) {
|
||||||
if (mPipMenuController.isMenuVisible()) {
|
if (shouldSyncPipTransactionWithMenu()) {
|
||||||
mPipMenuController.movePipMenu(leash, tx, destinationBounds);
|
mPipMenuController.movePipMenu(leash, tx, destinationBounds);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -1223,7 +1259,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
|||||||
mSurfaceTransactionHelper
|
mSurfaceTransactionHelper
|
||||||
.crop(tx, mLeash, toBounds)
|
.crop(tx, mLeash, toBounds)
|
||||||
.round(tx, mLeash, mPipTransitionState.isInPip());
|
.round(tx, mLeash, mPipTransitionState.isInPip());
|
||||||
if (mPipMenuController.isMenuVisible()) {
|
if (shouldSyncPipTransactionWithMenu()) {
|
||||||
mPipMenuController.resizePipMenu(mLeash, tx, toBounds);
|
mPipMenuController.resizePipMenu(mLeash, tx, toBounds);
|
||||||
} else {
|
} else {
|
||||||
tx.apply();
|
tx.apply();
|
||||||
@@ -1265,7 +1301,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
|||||||
mSurfaceTransactionHelper
|
mSurfaceTransactionHelper
|
||||||
.scale(tx, mLeash, startBounds, toBounds, degrees)
|
.scale(tx, mLeash, startBounds, toBounds, degrees)
|
||||||
.round(tx, mLeash, startBounds, toBounds);
|
.round(tx, mLeash, startBounds, toBounds);
|
||||||
if (mPipMenuController.isMenuVisible()) {
|
if (shouldSyncPipTransactionWithMenu()) {
|
||||||
mPipMenuController.movePipMenu(mLeash, tx, toBounds);
|
mPipMenuController.movePipMenu(mLeash, tx, toBounds);
|
||||||
} else {
|
} else {
|
||||||
tx.apply();
|
tx.apply();
|
||||||
|
|||||||
Reference in New Issue
Block a user