diff options
author | Selim Cinek <cinek@google.com> | 2019-10-01 12:06:05 -0700 |
---|---|---|
committer | android-build-team Robot <android-build-team-robot@google.com> | 2019-11-16 00:27:06 +0000 |
commit | 8412b9f24a75b9d070dec92da755cd27ead13306 (patch) | |
tree | 5a3a26d7b90a25c9aec0fcee6714a66839bd8cad | |
parent | bfeaf4e4a824d467cf755a3f7b47bd10cda42286 (diff) | |
download | base-8412b9f24a75b9d070dec92da755cd27ead13306.tar.gz |
Dismissed keyguard gone runnables when aborting
Previously those actions could linger around
and lead to a variety of bugs.
Also fixed an issue when gutsManager calls were overlapping
to protect against these issues
Fixes: 130885521
Test: atest SystemUITests
Test: see bug description
Change-Id: Iffe37e6d48bbc9c26ba92f362d7b67bf743c7c28
(cherry picked from commit 300dcfb7c3ebcfcba2e76de6ce16f2b0309e2e6d)
4 files changed, 51 insertions, 6 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGuts.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGuts.java index 4700baae8fab..18d436ff7659 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGuts.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGuts.java @@ -421,7 +421,7 @@ public class NotificationGuts extends FrameLayout { } /** Listener for animations executed in {@link #animateClose(int, int, boolean)}. */ - private static class AnimateCloseListener extends AnimatorListenerAdapter { + private class AnimateCloseListener extends AnimatorListenerAdapter { final View mView; private final GutsContent mGutsContent; @@ -433,8 +433,10 @@ public class NotificationGuts extends FrameLayout { @Override public void onAnimationEnd(Animator animation) { super.onAnimationEnd(animation); - mView.setVisibility(View.GONE); - mGutsContent.onFinishedClosing(); + if (!isExposed()) { + mView.setVisibility(View.GONE); + mGutsContent.onFinishedClosing(); + } } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java index 8f7671a5dd96..719ec3215d42 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java @@ -100,6 +100,7 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx protected String mKeyToRemoveOnGutsClosed; private StatusBar mStatusBar; + private Runnable mOpenRunnable; @Inject public NotificationGutsManager( @@ -343,6 +344,7 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx public void closeAndSaveGuts(boolean removeLeavebehinds, boolean force, boolean removeControls, int x, int y, boolean resetMenu) { if (mNotificationGutsExposed != null) { + mNotificationGutsExposed.removeCallbacks(mOpenRunnable); mNotificationGutsExposed.closeControls(removeLeavebehinds, removeControls, x, y, force); } if (resetMenu) { @@ -445,7 +447,7 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx // ensure that it's laid but not visible until actually laid out guts.setVisibility(View.INVISIBLE); // Post to ensure the the guts are properly laid out. - guts.post(new Runnable() { + mOpenRunnable = new Runnable() { @Override public void run() { if (row.getWindowToken() == null) { @@ -470,7 +472,8 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx mListContainer.onHeightChanged(row, true /* needsAnimation */); mGutsMenuItem = menuItem; } - }); + }; + guts.post(mOpenRunnable); return true; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java index 0c47d1468a7f..68ee8bbbb69b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java @@ -62,6 +62,8 @@ import com.android.systemui.statusbar.policy.KeyguardMonitorImpl; import java.io.PrintWriter; import java.util.ArrayList; +import androidx.annotation.VisibleForTesting; + /** * Manages creating, showing, hiding and resetting the keyguard within the status bar. Calls back * via {@link ViewMediatorCallback} to poke the wake lock and report that the keyguard is done, @@ -161,6 +163,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb private boolean mLastLockVisible; private OnDismissAction mAfterKeyguardGoneAction; + private Runnable mKeyguardGoneCancelAction; private final ArrayList<Runnable> mAfterKeyguardGoneRunnables = new ArrayList<>(); // Dismiss action to be launched when we stop dozing or the keyguard is gone. @@ -328,10 +331,20 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb return false; } - private void hideBouncer(boolean destroyView) { + @VisibleForTesting + void hideBouncer(boolean destroyView) { if (mBouncer == null) { return; } + if (mShowing) { + // If we were showing the bouncer and then aborting, we need to also clear out any + // potential actions unless we actually unlocked. + mAfterKeyguardGoneAction = null; + if (mKeyguardGoneCancelAction != null) { + mKeyguardGoneCancelAction.run(); + mKeyguardGoneCancelAction = null; + } + } mBouncer.hide(destroyView); cancelPendingWakeupAction(); } @@ -364,6 +377,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb mBouncer.showWithDismissAction(r, cancelAction); } else { mAfterKeyguardGoneAction = r; + mKeyguardGoneCancelAction = cancelAction; mBouncer.show(false /* resetSecuritySelection */); } } @@ -671,6 +685,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb mAfterKeyguardGoneAction.onDismiss(); mAfterKeyguardGoneAction = null; } + mKeyguardGoneCancelAction = null; for (int i = 0; i < mAfterKeyguardGoneRunnables.size(); i++) { mAfterKeyguardGoneRunnables.get(i).run(); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java index 63f653b0b303..0da0e7647707 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java @@ -221,6 +221,31 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase { verify(mStatusBar, never()).animateKeyguardUnoccluding(); } + @Test + public void testHiding_cancelsGoneRunnable() { + OnDismissAction action = mock(OnDismissAction.class); + Runnable cancelAction = mock(Runnable.class); + mStatusBarKeyguardViewManager.dismissWithAction(action, cancelAction, + true /* afterKeyguardGone */); + + mStatusBarKeyguardViewManager.hideBouncer(true); + mStatusBarKeyguardViewManager.hide(0, 30); + verify(action, never()).onDismiss(); + verify(cancelAction).run(); + } + + @Test + public void testHiding_doesntCancelWhenShowing() { + OnDismissAction action = mock(OnDismissAction.class); + Runnable cancelAction = mock(Runnable.class); + mStatusBarKeyguardViewManager.dismissWithAction(action, cancelAction, + true /* afterKeyguardGone */); + + mStatusBarKeyguardViewManager.hide(0, 30); + verify(action).onDismiss(); + verify(cancelAction, never()).run(); + } + private class TestableStatusBarKeyguardViewManager extends StatusBarKeyguardViewManager { public TestableStatusBarKeyguardViewManager(Context context, |