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 <package> 27
Test: adb shell appops stop <package> 27
Change-Id: I19489e3db18aeabfac8bbd3df0a04b7d85f5a697
This commit is contained in:
Sergey Nikolaienkov
2020-10-02 07:08:26 +00:00
parent 79523b5afa
commit 38f85b72c6

View File

@@ -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);