Loading libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubbleStackViewTest.kt +72 −0 Original line number Diff line number Diff line Loading @@ -46,6 +46,7 @@ import com.android.wm.shell.shared.animation.PhysicsAnimatorTestUtils import com.google.common.truth.Truth.assertThat import com.google.common.util.concurrent.MoreExecutors.directExecutor import org.junit.After import org.junit.Assert.fail import org.junit.Before import org.junit.Rule import org.junit.Test Loading Loading @@ -311,6 +312,73 @@ class BubbleStackViewTest { } } @EnableFlags(Flags.FLAG_ENABLE_BUBBLE_SWIPE_UP_CLEANUP) @Test fun expandStack_clearsImeRunnable() { val bubble = createAndInflateBubble() InstrumentationRegistry.getInstrumentation().runOnMainSync { bubbleStackView.addBubble(bubble) } InstrumentationRegistry.getInstrumentation().waitForIdleSync() assertThat(bubbleStackView.bubbleCount).isEqualTo(1) // Set up a pending runnable to be cleared bubbleStackViewManager.onImeHidden = Runnable { fail("IME runnable should not be called when IME is hidden") } positioner.setImeVisible(false, 0) InstrumentationRegistry.getInstrumentation().runOnMainSync { // simulate a request from the bubble data listener to expand the stack bubbleStackView.isExpanded = true verify(sysuiProxy).onStackExpandChanged(true) shellExecutor.flushAll() } // Ime runnable is reset assertThat(bubbleStackViewManager.onImeHidden).isNull() } @EnableFlags(Flags.FLAG_ENABLE_BUBBLE_SWIPE_UP_CLEANUP) @Test fun collapseStack_clearsImeRunnable() { val bubble = createAndInflateBubble() InstrumentationRegistry.getInstrumentation().runOnMainSync { bubbleStackView.addBubble(bubble) } InstrumentationRegistry.getInstrumentation().waitForIdleSync() assertThat(bubbleStackView.bubbleCount).isEqualTo(1) positioner.setImeVisible(false, 0) InstrumentationRegistry.getInstrumentation().runOnMainSync { // simulate a request from the bubble data listener to expand the stack bubbleStackView.isExpanded = true verify(sysuiProxy).onStackExpandChanged(true) shellExecutor.flushAll() } // Set up a pending runnable to be cleared bubbleStackViewManager.onImeHidden = Runnable { fail("IME runnable should not be called when IME is hidden") } InstrumentationRegistry.getInstrumentation().runOnMainSync { // simulate a request from the bubble data listener to collapse the stack bubbleStackView.isExpanded = false verify(sysuiProxy).onStackExpandChanged(false) shellExecutor.flushAll() } // Check that the runnable is cleared assertThat(bubbleStackViewManager.onImeHidden).isNull() } @Test fun tapDifferentBubble_shouldReorder() { surfaceSynchronizer.isActive = false Loading Loading @@ -707,6 +775,10 @@ class BubbleStackViewTest { override fun hideCurrentInputMethod(onImeHidden: Runnable?) { this.onImeHidden = onImeHidden } override fun clearImeHiddenRunnable() { this.onImeHidden = null } } private class FakeBubbleExpandListener : BubbleExpandListener { Loading libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java +8 −0 Original line number Diff line number Diff line Loading @@ -662,6 +662,14 @@ public class BubbleController implements ConfigurationChangeListener, } } /** * Allows callers to reset runnable scheduled to run after IME is hidden by * {@link #hideCurrentInputMethod(Runnable)} */ void clearImeHiddenRunnable() { mOnImeHidden = null; } /** * Called when the status bar has become visible or invisible (either permanently or * temporarily). Loading libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java +7 −0 Original line number Diff line number Diff line Loading @@ -2300,6 +2300,13 @@ public class BubbleStackView extends FrameLayout if (mPositioner.isImeVisible()) { hideCurrentInputMethod(onImeHidden); } else { if (Flags.enableBubbleSwipeUpCleanup()) { // Clear out the existing runnable if one was scheduled to run after IME was hidden. // IME hide action can take time or in some cases not trigger at all. And we can // get a second call to expand in during it. Make sure we don't run a previous // runnable in that case. mManager.clearImeHiddenRunnable(); } // the IME is already hidden, so run the runnable immediately onImeHidden.run(); } Loading libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackViewManager.kt +7 −0 Original line number Diff line number Diff line Loading @@ -36,6 +36,9 @@ interface BubbleStackViewManager { /** Requests to hide the current input method. */ fun hideCurrentInputMethod(onImeHidden: Runnable?) /** Allows callers to clear the runnable set by [hideCurrentInputMethod]. */ fun clearImeHiddenRunnable() companion object { @JvmStatic Loading @@ -55,6 +58,10 @@ interface BubbleStackViewManager { override fun hideCurrentInputMethod(onImeHidden: Runnable?) { controller.hideCurrentInputMethod(onImeHidden) } override fun clearImeHiddenRunnable() { controller.clearImeHiddenRunnable() } } } } Loading
libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubbleStackViewTest.kt +72 −0 Original line number Diff line number Diff line Loading @@ -46,6 +46,7 @@ import com.android.wm.shell.shared.animation.PhysicsAnimatorTestUtils import com.google.common.truth.Truth.assertThat import com.google.common.util.concurrent.MoreExecutors.directExecutor import org.junit.After import org.junit.Assert.fail import org.junit.Before import org.junit.Rule import org.junit.Test Loading Loading @@ -311,6 +312,73 @@ class BubbleStackViewTest { } } @EnableFlags(Flags.FLAG_ENABLE_BUBBLE_SWIPE_UP_CLEANUP) @Test fun expandStack_clearsImeRunnable() { val bubble = createAndInflateBubble() InstrumentationRegistry.getInstrumentation().runOnMainSync { bubbleStackView.addBubble(bubble) } InstrumentationRegistry.getInstrumentation().waitForIdleSync() assertThat(bubbleStackView.bubbleCount).isEqualTo(1) // Set up a pending runnable to be cleared bubbleStackViewManager.onImeHidden = Runnable { fail("IME runnable should not be called when IME is hidden") } positioner.setImeVisible(false, 0) InstrumentationRegistry.getInstrumentation().runOnMainSync { // simulate a request from the bubble data listener to expand the stack bubbleStackView.isExpanded = true verify(sysuiProxy).onStackExpandChanged(true) shellExecutor.flushAll() } // Ime runnable is reset assertThat(bubbleStackViewManager.onImeHidden).isNull() } @EnableFlags(Flags.FLAG_ENABLE_BUBBLE_SWIPE_UP_CLEANUP) @Test fun collapseStack_clearsImeRunnable() { val bubble = createAndInflateBubble() InstrumentationRegistry.getInstrumentation().runOnMainSync { bubbleStackView.addBubble(bubble) } InstrumentationRegistry.getInstrumentation().waitForIdleSync() assertThat(bubbleStackView.bubbleCount).isEqualTo(1) positioner.setImeVisible(false, 0) InstrumentationRegistry.getInstrumentation().runOnMainSync { // simulate a request from the bubble data listener to expand the stack bubbleStackView.isExpanded = true verify(sysuiProxy).onStackExpandChanged(true) shellExecutor.flushAll() } // Set up a pending runnable to be cleared bubbleStackViewManager.onImeHidden = Runnable { fail("IME runnable should not be called when IME is hidden") } InstrumentationRegistry.getInstrumentation().runOnMainSync { // simulate a request from the bubble data listener to collapse the stack bubbleStackView.isExpanded = false verify(sysuiProxy).onStackExpandChanged(false) shellExecutor.flushAll() } // Check that the runnable is cleared assertThat(bubbleStackViewManager.onImeHidden).isNull() } @Test fun tapDifferentBubble_shouldReorder() { surfaceSynchronizer.isActive = false Loading Loading @@ -707,6 +775,10 @@ class BubbleStackViewTest { override fun hideCurrentInputMethod(onImeHidden: Runnable?) { this.onImeHidden = onImeHidden } override fun clearImeHiddenRunnable() { this.onImeHidden = null } } private class FakeBubbleExpandListener : BubbleExpandListener { Loading
libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java +8 −0 Original line number Diff line number Diff line Loading @@ -662,6 +662,14 @@ public class BubbleController implements ConfigurationChangeListener, } } /** * Allows callers to reset runnable scheduled to run after IME is hidden by * {@link #hideCurrentInputMethod(Runnable)} */ void clearImeHiddenRunnable() { mOnImeHidden = null; } /** * Called when the status bar has become visible or invisible (either permanently or * temporarily). Loading
libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java +7 −0 Original line number Diff line number Diff line Loading @@ -2300,6 +2300,13 @@ public class BubbleStackView extends FrameLayout if (mPositioner.isImeVisible()) { hideCurrentInputMethod(onImeHidden); } else { if (Flags.enableBubbleSwipeUpCleanup()) { // Clear out the existing runnable if one was scheduled to run after IME was hidden. // IME hide action can take time or in some cases not trigger at all. And we can // get a second call to expand in during it. Make sure we don't run a previous // runnable in that case. mManager.clearImeHiddenRunnable(); } // the IME is already hidden, so run the runnable immediately onImeHidden.run(); } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackViewManager.kt +7 −0 Original line number Diff line number Diff line Loading @@ -36,6 +36,9 @@ interface BubbleStackViewManager { /** Requests to hide the current input method. */ fun hideCurrentInputMethod(onImeHidden: Runnable?) /** Allows callers to clear the runnable set by [hideCurrentInputMethod]. */ fun clearImeHiddenRunnable() companion object { @JvmStatic Loading @@ -55,6 +58,10 @@ interface BubbleStackViewManager { override fun hideCurrentInputMethod(onImeHidden: Runnable?) { controller.hideCurrentInputMethod(onImeHidden) } override fun clearImeHiddenRunnable() { controller.clearImeHiddenRunnable() } } } }