summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Adrian Roos <roosa@google.com> 2020-06-05 17:06:07 +0200
committer Adrian Roos <roosa@google.com> 2020-06-05 17:15:26 +0200
commit021f4a71402a9e0dba34dcbb8e56cf851b74fd2e (patch)
tree03418082f9f6b97f967197f78a16b8dbfaa86571
parentb0033693a89923a80f9973e41b45ddcef2ec7ae9 (diff)
Insets: Fix stuck mPendingFrame
Fixes an issue where the mPendingFrame was not properly cleared if we re-applied the current frame. Fixes: 156762386 Test: InsetsSourceConsumerTest Change-Id: I9f0ebfafac44e1b4b87ea9d3408e64ba34bca2ec
-rw-r--r--core/java/android/view/InsetsSourceConsumer.java10
-rw-r--r--core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java49
2 files changed, 57 insertions, 2 deletions
diff --git a/core/java/android/view/InsetsSourceConsumer.java b/core/java/android/view/InsetsSourceConsumer.java
index df3ac8787b57..eb1d50a6e48c 100644
--- a/core/java/android/view/InsetsSourceConsumer.java
+++ b/core/java/android/view/InsetsSourceConsumer.java
@@ -21,6 +21,8 @@ import static android.view.InsetsController.AnimationType;
import static android.view.InsetsState.getDefaultVisibility;
import static android.view.InsetsState.toPublicType;
+import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE;
+
import android.annotation.IntDef;
import android.annotation.Nullable;
import android.graphics.Rect;
@@ -253,10 +255,13 @@ public class InsetsSourceConsumer {
// no-op for types that always return ShowResult#SHOW_IMMEDIATELY.
}
- void updateSource(InsetsSource newSource) {
+ @VisibleForTesting(visibility = PACKAGE)
+ public void updateSource(InsetsSource newSource) {
InsetsSource source = mState.peekSource(mType);
if (source == null || mController.getAnimationType(mType) == ANIMATION_TYPE_NONE
|| source.getFrame().equals(newSource.getFrame())) {
+ mPendingFrame = null;
+ mPendingVisibleFrame = null;
mState.addSource(newSource);
return;
}
@@ -273,7 +278,8 @@ public class InsetsSourceConsumer {
mState.addSource(newSource);
}
- boolean notifyAnimationFinished() {
+ @VisibleForTesting(visibility = PACKAGE)
+ public boolean notifyAnimationFinished() {
if (mPendingFrame != null) {
InsetsSource source = mState.getSource(mType);
source.setFrame(mPendingFrame);
diff --git a/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java b/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java
index 25f94131f820..bf7f339a8484 100644
--- a/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java
+++ b/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java
@@ -16,6 +16,9 @@
package android.view;
+import static android.view.InsetsController.ANIMATION_TYPE_NONE;
+import static android.view.InsetsController.ANIMATION_TYPE_USER;
+import static android.view.InsetsState.ITYPE_IME;
import static android.view.InsetsState.ITYPE_STATUS_BAR;
import static android.view.WindowInsets.Type.statusBars;
@@ -23,14 +26,18 @@ import static junit.framework.Assert.assertEquals;
import static junit.framework.TestCase.assertFalse;
import static junit.framework.TestCase.assertTrue;
+import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.when;
import android.app.Instrumentation;
import android.content.Context;
import android.graphics.Point;
+import android.graphics.Rect;
import android.platform.test.annotations.Presubmit;
import android.view.SurfaceControl.Transaction;
import android.view.WindowManager.BadTokenException;
@@ -122,6 +129,48 @@ public class InsetsSourceConsumerTest {
}
@Test
+ public void testPendingStates() {
+ InsetsState state = new InsetsState();
+ InsetsController controller = mock(InsetsController.class);
+ InsetsSourceConsumer consumer = new InsetsSourceConsumer(
+ ITYPE_IME, state, null, controller);
+
+ when(controller.getAnimationType(anyInt())).thenReturn(ANIMATION_TYPE_NONE);
+
+ InsetsSource source = new InsetsSource(ITYPE_IME);
+ source.setFrame(0, 1, 2, 3);
+ consumer.updateSource(new InsetsSource(source));
+
+ when(controller.getAnimationType(anyInt())).thenReturn(ANIMATION_TYPE_USER);
+
+ // While we're animating, updates are delayed
+ source.setFrame(4, 5, 6, 7);
+ consumer.updateSource(new InsetsSource(source));
+ assertEquals(new Rect(0, 1, 2, 3), state.peekSource(ITYPE_IME).getFrame());
+
+ // Finish the animation, now the pending frame should be applied
+ when(controller.getAnimationType(anyInt())).thenReturn(ANIMATION_TYPE_NONE);
+ assertTrue(consumer.notifyAnimationFinished());
+ assertEquals(new Rect(4, 5, 6, 7), state.peekSource(ITYPE_IME).getFrame());
+
+ when(controller.getAnimationType(anyInt())).thenReturn(ANIMATION_TYPE_USER);
+
+ // Animating again, updates are delayed
+ source.setFrame(8, 9, 10, 11);
+ consumer.updateSource(new InsetsSource(source));
+ assertEquals(new Rect(4, 5, 6, 7), state.peekSource(ITYPE_IME).getFrame());
+
+ // Updating with the current frame triggers a different code path, verify this clears
+ // the pending 8, 9, 10, 11 frame:
+ source.setFrame(4, 5, 6, 7);
+ consumer.updateSource(new InsetsSource(source));
+
+ when(controller.getAnimationType(anyInt())).thenReturn(ANIMATION_TYPE_NONE);
+ assertFalse(consumer.notifyAnimationFinished());
+ assertEquals(new Rect(4, 5, 6, 7), state.peekSource(ITYPE_IME).getFrame());
+ }
+
+ @Test
public void testRestore() {
InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
mConsumer.setControl(null, new int[1], new int[1]);