From b5594c6538a01a5d463b3e158d805db022b0aca5 Mon Sep 17 00:00:00 2001 From: Tony Huang Date: Fri, 25 Mar 2022 14:49:31 +0800 Subject: [PATCH] Fix NPE when rotation after split dismissed Because drag to dismissed will not call SplitDecorManager#onResized so mShown status will be wrong. Reset some flag in release and also add some null check to avoid NPE. Also refine some function params and naming to avoid confuse. Fix: 226551765 Test: follow bug repro step and check no NPE Test: pass existing tests Change-Id: Ife592e176ef67c5df79be0a81509531ffcbd1b39 --- .../shell/common/split/SplitDecorManager.java | 44 ++++++++++++------- .../shell/splitscreen/StageCoordinator.java | 4 +- .../shell/splitscreen/StageTaskListener.java | 4 +- 3 files changed, 33 insertions(+), 19 deletions(-) diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitDecorManager.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitDecorManager.java index a10ee6af42134..3ac7cbfe9c2e6 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitDecorManager.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitDecorManager.java @@ -124,6 +124,9 @@ public class SplitDecorManager extends WindowlessWindowManager { /** Releases the surfaces for split decor. */ public void release(SurfaceControl.Transaction t) { + if (mFadeAnimator != null && mFadeAnimator.isRunning()) { + mFadeAnimator.cancel(); + } if (mViewHost != null) { mViewHost.release(); mViewHost = null; @@ -139,6 +142,8 @@ public class SplitDecorManager extends WindowlessWindowManager { mHostLeash = null; mIcon = null; mResizingIconView = null; + mIsResizing = false; + mShown = false; } /** Showing resizing hint. */ @@ -181,13 +186,13 @@ public class SplitDecorManager extends WindowlessWindowManager { if (mFadeAnimator != null && mFadeAnimator.isRunning()) { mFadeAnimator.cancel(); } - startFadeAnimation(show, false /* releaseLeash */); + startFadeAnimation(show, false /* isResized */); mShown = show; } } /** Stops showing resizing hint. */ - public void onResized(Rect newBounds, SurfaceControl.Transaction t) { + public void onResized(SurfaceControl.Transaction t) { if (mResizingIconView == null) { return; } @@ -200,7 +205,7 @@ public class SplitDecorManager extends WindowlessWindowManager { mFadeAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { - releaseLeash(finishT); + releaseDecor(finishT); finishT.apply(); finishT.close(); } @@ -212,22 +217,25 @@ public class SplitDecorManager extends WindowlessWindowManager { mFadeAnimator.cancel(); } if (mShown) { - startFadeAnimation(false /* show */, true /* releaseLeash */); - mShown = false; + startFadeAnimation(false /* show */, true /* isResized */); } else { - // Surface is hidden so release it directly. - releaseLeash(t); + // Decor surface is hidden so release it directly. + releaseDecor(t); } } - private void startFadeAnimation(boolean show, boolean releaseLeash) { + private void startFadeAnimation(boolean show, boolean isResized) { final SurfaceControl.Transaction animT = new SurfaceControl.Transaction(); mFadeAnimator = ValueAnimator.ofFloat(0f, 1f); mFadeAnimator.setDuration(FADE_DURATION); mFadeAnimator.addUpdateListener(valueAnimator-> { final float progress = (float) valueAnimator.getAnimatedValue(); - animT.setAlpha(mBackgroundLeash, show ? progress : 1 - progress); - animT.setAlpha(mIconLeash, show ? progress : 1 - progress); + if (mBackgroundLeash != null) { + animT.setAlpha(mBackgroundLeash, show ? progress : 1 - progress); + } + if (mIconLeash != null) { + animT.setAlpha(mIconLeash, show ? progress : 1 - progress); + } animT.apply(); }); mFadeAnimator.addListener(new AnimatorListenerAdapter() { @@ -241,19 +249,25 @@ public class SplitDecorManager extends WindowlessWindowManager { @Override public void onAnimationEnd(@NonNull Animator animation) { if (!show) { - animT.hide(mBackgroundLeash).hide(mIconLeash).apply(); + if (mBackgroundLeash != null) { + animT.hide(mBackgroundLeash); + } + if (mIconLeash != null) { + animT.hide(mIconLeash); + } } - if (releaseLeash) { - releaseLeash(animT); - animT.apply(); + if (isResized) { + releaseDecor(animT); } + animT.apply(); animT.close(); } }); mFadeAnimator.start(); } - private void releaseLeash(SurfaceControl.Transaction t) { + /** Release or hide decor hint. */ + private void releaseDecor(SurfaceControl.Transaction t) { if (mBackgroundLeash != null) { t.remove(mBackgroundLeash); mBackgroundLeash = null; diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java index ec1ddf0777958..880693de78919 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java @@ -1072,8 +1072,8 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler, mSyncQueue.queue(wct); mSyncQueue.runInSync(t -> { updateSurfaceBounds(layout, t); - mMainStage.onResized(getMainStageBounds(), t); - mSideStage.onResized(getSideStageBounds(), t); + mMainStage.onResized(t); + mSideStage.onResized(t); }); mLogger.logResize(mSplitLayout.getDividerPositionAsFraction()); } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java index 5f0cd01f54160..fb0eebdf0ac92 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java @@ -319,9 +319,9 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener { } } - void onResized(Rect newBounds, SurfaceControl.Transaction t) { + void onResized(SurfaceControl.Transaction t) { if (mSplitDecorManager != null) { - mSplitDecorManager.onResized(newBounds, t); + mSplitDecorManager.onResized(t); } }