Fix insets animations being skipped when the host view was invisible

In case the insets animation frame will not be scheduled by render
thread when the host window was not visible to user, added
ViewRootInsetsControllerHost#isVisibleToUser to check when invoking
applySurfaceParams to schedule the next frame, if the host was not
visible means we don't have to synchronize with the window host and
just apply the surface transaction on the UI thread directly.

Fix: 206992027
Test: manual as steps
  1) Receive any incoming message
  2) Tap on inline reply to show the keyboard
  3) Tap on the voice input button on the keyboard
  4) when permission dialogue prompts on the screen, expecting both
     notification shade panel collpse animation and IME hiding animation
     are working fine without any stucked frame.

Change-Id: I266587d5a3f136149d116214e2a49de92466ec2e
This commit is contained in:
Ming-Shin Lu 2022-01-04 22:48:15 +08:00
parent d8ea5df381
commit 63a95a2795
2 changed files with 9 additions and 4 deletions

View File

@ -1310,8 +1310,8 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
}
private void cancelAnimation(InsetsAnimationControlRunner control, boolean invokeCallback) {
if (DEBUG) Log.d(TAG, String.format("cancelAnimation of types: %d, animType: %d",
control.getTypes(), control.getAnimationType()));
if (DEBUG) Log.d(TAG, String.format("cancelAnimation of types: %d, animType: %d, host: %s",
control.getTypes(), control.getAnimationType(), mHost.getRootViewTitle()));
if (invokeCallback) {
control.cancel();
}

View File

@ -125,10 +125,11 @@ public class ViewRootInsetsControllerHost implements InsetsController.Host {
if (mApplier == null) {
mApplier = new SyncRtSurfaceTransactionApplier(mViewRoot.mView);
}
if (mViewRoot.mView.isHardwareAccelerated()) {
if (mViewRoot.mView.isHardwareAccelerated() && isVisibleToUser()) {
mApplier.scheduleApply(params);
} else {
// Window doesn't support hardware acceleration, no synchronization for now.
// Synchronization requires hardware acceleration for now.
// If the window isn't visible, drawing is paused and the applier won't run.
// TODO(b/149342281): use mViewRoot.mSurface.getNextFrameNumber() to sync on every
// frame instead.
final SurfaceControl.Transaction t = new SurfaceControl.Transaction();
@ -269,4 +270,8 @@ public class ViewRootInsetsControllerHost implements InsetsController.Host {
}
return null;
}
private boolean isVisibleToUser() {
return mViewRoot.getHostVisibility() == View.VISIBLE;
}
}