Fix flicker with remote animations
There was a race condition where we notified the controlling app already about transition start, which itself started the animation and applied the transform of the first frame. However, a little bit later, we applied the pending transaction from window manager, which overrode the properties again, leading to a flicker. Original CL: ag/3535475 Test: go/wm-smoke Test: Press home button, observe never a flicker Bug: Surprisingly there isn't one yet. Change-Id: I84b2e0fd4dcd7a01687e18f428a8f900ed43d75f
This commit is contained in:
@@ -96,13 +96,17 @@ class RemoteAnimationController {
|
||||
// Scale the timeout with the animator scale the controlling app is using.
|
||||
mHandler.postDelayed(mTimeoutRunnable,
|
||||
(long) (TIMEOUT_MS * mService.getCurrentAnimatorScale()));
|
||||
try {
|
||||
mRemoteAnimationAdapter.getRunner().onAnimationStart(createAnimations(),
|
||||
mFinishedCallback);
|
||||
} catch (RemoteException e) {
|
||||
Slog.e(TAG, "Failed to start remote animation", e);
|
||||
onAnimationFinished();
|
||||
}
|
||||
|
||||
final RemoteAnimationTarget[] animations = createAnimations();
|
||||
mService.mAnimator.addAfterPrepareSurfacesRunnable(() -> {
|
||||
try {
|
||||
mRemoteAnimationAdapter.getRunner().onAnimationStart(animations,
|
||||
mFinishedCallback);
|
||||
} catch (RemoteException e) {
|
||||
Slog.e(TAG, "Failed to start remote animation", e);
|
||||
onAnimationFinished();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private RemoteAnimationTarget[] createAnimations() {
|
||||
|
||||
@@ -588,6 +588,8 @@ class RootWindowContainer extends WindowContainer<DisplayContent> {
|
||||
"<<< CLOSE TRANSACTION performLayoutAndPlaceSurfaces");
|
||||
}
|
||||
|
||||
mService.mAnimator.executeAfterPrepareSurfacesRunnables();
|
||||
|
||||
final WindowSurfacePlacer surfacePlacer = mService.mWindowPlacerLocked;
|
||||
|
||||
// If we are ready to perform an app transition, check through all of the app tokens to be
|
||||
|
||||
@@ -92,6 +92,7 @@ public class WindowAnimator {
|
||||
* executed and the corresponding transaction is closed and applied.
|
||||
*/
|
||||
private final ArrayList<Runnable> mAfterPrepareSurfacesRunnables = new ArrayList<>();
|
||||
private boolean mInExecuteAfterPrepareSurfacesRunnables;
|
||||
|
||||
WindowAnimator(final WindowManagerService service) {
|
||||
mService = service;
|
||||
@@ -434,11 +435,24 @@ public class WindowAnimator {
|
||||
* the corresponding transaction is closed and applied.
|
||||
*/
|
||||
void addAfterPrepareSurfacesRunnable(Runnable r) {
|
||||
// If runnables are already being handled in executeAfterPrepareSurfacesRunnable, then just
|
||||
// immediately execute the runnable passed in.
|
||||
if (mInExecuteAfterPrepareSurfacesRunnables) {
|
||||
r.run();
|
||||
return;
|
||||
}
|
||||
|
||||
mAfterPrepareSurfacesRunnables.add(r);
|
||||
scheduleAnimation();
|
||||
}
|
||||
|
||||
private void executeAfterPrepareSurfacesRunnables() {
|
||||
void executeAfterPrepareSurfacesRunnables() {
|
||||
|
||||
// Don't even think about to start recursing!
|
||||
if (mInExecuteAfterPrepareSurfacesRunnables) {
|
||||
return;
|
||||
}
|
||||
mInExecuteAfterPrepareSurfacesRunnables = true;
|
||||
|
||||
// Traverse in order they were added.
|
||||
final int size = mAfterPrepareSurfacesRunnables.size();
|
||||
@@ -446,5 +460,6 @@ public class WindowAnimator {
|
||||
mAfterPrepareSurfacesRunnables.get(i).run();
|
||||
}
|
||||
mAfterPrepareSurfacesRunnables.clear();
|
||||
mInExecuteAfterPrepareSurfacesRunnables = false;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user