From 38f85b72c6cc2c3a884d1040f994c51bc2688fba Mon Sep 17 00:00:00 2001 From: Sergey Nikolaienkov Date: Fri, 2 Oct 2020 07:08:26 +0000 Subject: [PATCH] Fix mic indicator crash when animation gets cancelled Take into account the fact that when ValueAnimator#cancel() is called the listener receives the onAnimationEnd() as well as the onAnimationCancel(). The fact that we did not destinguish between the scenarios when the animation is fully completed and when the animation was cancelled led to the crash in the AudioRecordingDisclosureBar. This CL fixes the crash by handling these two cases differently. Bug: 166578426 Test: make, flash Test: adb shell appops start 27 Test: adb shell appops stop 27 Change-Id: I19489e3db18aeabfac8bbd3df0a04b7d85f5a697 --- .../AudioRecordingDisclosureBar.java | 34 ++++++++++++++----- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tv/micdisclosure/AudioRecordingDisclosureBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tv/micdisclosure/AudioRecordingDisclosureBar.java index 7aeca64ba9e87..c9d1b71bca777 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/tv/micdisclosure/AudioRecordingDisclosureBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/tv/micdisclosure/AudioRecordingDisclosureBar.java @@ -284,25 +284,28 @@ public class AudioRecordingDisclosureBar implements mAnimator.setTarget(mIndicatorView); mAnimator.setProperty(View.ALPHA); mAnimator.addListener(new AnimatorListenerAdapter() { + boolean mCancelled; + @Override public void onAnimationStart(Animator animation, boolean isReverse) { - if (DEBUG) Log.d(TAG, "onAnimationStart"); + if (DEBUG) Log.d(TAG, "AnimatorListenerAdapter#onAnimationStart"); + mCancelled = false; } @Override public void onAnimationCancel(Animator animation) { - if (DEBUG) Log.d(TAG, "onAnimationCancel"); + if (DEBUG) Log.d(TAG, "AnimatorListenerAdapter#onAnimationCancel"); + mCancelled = true; } @Override public void onAnimationEnd(Animator animation) { - if (DEBUG) Log.d(TAG, "onAnimationEnd"); - - if (mState == STATE_APPEARING) { - mState = STATE_SHOWN; - } else if (mState == STATE_DISAPPEARING) { - removeIndicatorView(); - mState = STATE_NOT_SHOWN; + if (DEBUG) Log.d(TAG, "AnimatorListenerAdapter#onAnimationEnd"); + // When ValueAnimator#cancel() is called it always calls onAnimationCancel(...) + // and then onAnimationEnd(...). We, however, only want to proceed here if the + // animation ended "naturally". + if (!mCancelled) { + onAnimationFinished(); } } }); @@ -319,6 +322,17 @@ public class AudioRecordingDisclosureBar implements mAnimator.start(); } + private void onAnimationFinished() { + if (DEBUG) Log.d(TAG, "onAnimationFinished"); + + if (mState == STATE_APPEARING) { + mState = STATE_SHOWN; + } else if (mState == STATE_DISAPPEARING) { + removeIndicatorView(); + mState = STATE_NOT_SHOWN; + } + } + private boolean hasActiveRecorders() { for (int index = mAudioActivityObservers.length - 1; index >= 0; index--) { for (String activePackage : mAudioActivityObservers[index].getActivePackages()) { @@ -330,6 +344,8 @@ public class AudioRecordingDisclosureBar implements } private void removeIndicatorView() { + if (DEBUG) Log.d(TAG, "removeIndicatorView"); + final WindowManager windowManager = (WindowManager) mContext.getSystemService( Context.WINDOW_SERVICE); windowManager.removeView(mIndicatorView);