summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
author Galia Peycheva <galinap@google.com> 2022-11-02 09:31:31 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2022-11-02 09:31:31 +0000
commit71bf4aaf9e469f922b365ec05da59e2d2b39119b (patch)
tree55359b395aa4c0078977c2870291a389a3e29a7b /libs
parent269cef1fd5dbf97a4b1fb6fa831dd4e66f78172a (diff)
parentc3ebae4ca884a1b56930b322d171d06b675fbe4d (diff)
Merge "Fix pip update transaction out of order" into tm-qpr-dev
Diffstat (limited to 'libs')
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipMenuController.java6
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java40
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipMenuController.java12
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuController.java12
4 files changed, 65 insertions, 5 deletions
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipMenuController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipMenuController.java
index 16f1d1c2944c..f81c9f80830a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipMenuController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipMenuController.java
@@ -23,6 +23,7 @@ import static android.view.WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityManager.RunningTaskInfo;
import android.app.RemoteAction;
@@ -70,6 +71,11 @@ public interface PipMenuController {
void setAppActions(List<RemoteAction> appActions, RemoteAction closeAction);
/**
+ * Wait until the next frame to run the given Runnable.
+ */
+ void runWithNextFrame(@NonNull Runnable runnable);
+
+ /**
* Resize the PiP menu with the given bounds. The PiP SurfaceControl is given if there is a
* need to synchronize the movements on the same frame as PiP.
*/
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
index f170e774739f..2d7c5ce6feb5 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
@@ -179,8 +179,10 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
// 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
// operation handle the final resize out of PIP mode. See b/185306679.
- finishResize(tx, destinationBounds, direction, animationType);
- sendOnPipTransitionFinished(direction);
+ finishResizeDelayedIfNeeded(() -> {
+ finishResize(tx, destinationBounds, direction, animationType);
+ sendOnPipTransitionFinished(direction);
+ });
}
}
@@ -196,6 +198,34 @@ 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
+ * onAnimationUpdate and the finishResize in onAnimationEnd. finishResize creates a
+ * WindowContainerTransaction, which is to be applied by WmCore later. It may happen that it
+ * gets applied before the transaction created by the last onAnimationUpdate. As a result of
+ * this, the PiP surface may get 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.
+ *
+ * The race only happens 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, the PiP menu surface and
+ * the PiP menu contents.
+ */
+ private void finishResizeDelayedIfNeeded(Runnable finishResizeRunnable) {
+ if (!shouldSyncPipTransactionWithMenu()) {
+ finishResizeRunnable.run();
+ return;
+ }
+ mPipMenuController.runWithNextFrame(finishResizeRunnable);
+ }
+
+ private boolean shouldSyncPipTransactionWithMenu() {
+ return mPipMenuController.isMenuVisible();
+ }
+
@VisibleForTesting
final PipTransitionController.PipTransitionCallback mPipTransitionCallback =
new PipTransitionController.PipTransitionCallback() {
@@ -221,7 +251,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
@Override
public boolean handlePipTransaction(SurfaceControl leash,
SurfaceControl.Transaction tx, Rect destinationBounds) {
- if (mPipMenuController.isMenuVisible()) {
+ if (shouldSyncPipTransactionWithMenu()) {
mPipMenuController.movePipMenu(leash, tx, destinationBounds);
return true;
}
@@ -1223,7 +1253,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
mSurfaceTransactionHelper
.crop(tx, mLeash, toBounds)
.round(tx, mLeash, mPipTransitionState.isInPip());
- if (mPipMenuController.isMenuVisible()) {
+ if (shouldSyncPipTransactionWithMenu()) {
mPipMenuController.resizePipMenu(mLeash, tx, toBounds);
} else {
tx.apply();
@@ -1265,7 +1295,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
mSurfaceTransactionHelper
.scale(tx, mLeash, startBounds, toBounds, degrees)
.round(tx, mLeash, startBounds, toBounds);
- if (mPipMenuController.isMenuVisible()) {
+ if (shouldSyncPipTransactionWithMenu()) {
mPipMenuController.movePipMenu(mLeash, tx, toBounds);
} else {
tx.apply();
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipMenuController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipMenuController.java
index 281ea530e9e1..27902b2231ba 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipMenuController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipMenuController.java
@@ -305,6 +305,18 @@ public class PhonePipMenuController implements PipMenuController {
showResizeHandle);
}
+ @Override
+ public void runWithNextFrame(Runnable runnable) {
+ if (mPipMenuView == null || mPipMenuView.getViewRootImpl() == null) {
+ runnable.run();
+ }
+
+ mPipMenuView.getViewRootImpl().registerRtFrameCallback(frame -> {
+ mMainHandler.post(runnable);
+ });
+ mPipMenuView.invalidate();
+ }
+
/**
* Move the PiP menu, which does a translation and possibly a scale transformation.
*/
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuController.java
index 4ce45e142c64..7d4b43be4f73 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuController.java
@@ -466,6 +466,18 @@ public class TvPipMenuController implements PipMenuController, TvPipMenuView.Lis
}
@Override
+ public void runWithNextFrame(Runnable runnable) {
+ if (mPipMenuView == null || mPipMenuView.getViewRootImpl() == null) {
+ runnable.run();
+ }
+
+ mPipMenuView.getViewRootImpl().registerRtFrameCallback(frame -> {
+ mMainHandler.post(runnable);
+ });
+ mPipMenuView.invalidate();
+ }
+
+ @Override
public void movePipMenu(SurfaceControl pipLeash, SurfaceControl.Transaction transaction,
Rect pipDestBounds) {
if (DEBUG) {