Loading core/tests/coretests/src/android/view/InsetsControllerTest.java +109 −20 Original line number Diff line number Diff line Loading @@ -69,6 +69,7 @@ import android.view.WindowInsetsController.OnControllableInsetsChangedListener; import android.view.WindowManager.BadTokenException; import android.view.WindowManager.LayoutParams; import android.view.animation.LinearInterpolator; import android.view.inputmethod.Flags; import android.view.inputmethod.ImeTracker; import android.widget.TextView; Loading Loading @@ -136,7 +137,7 @@ public class InsetsControllerTest { mTestHandler = new TestHandler(null, mTestClock); mTestHost = spy(new TestHost(mViewRoot)); mController = new InsetsController(mTestHost, (controller, id, type) -> { if (type == ime()) { if (!Flags.refactorInsetsController() && type == ime()) { return new InsetsSourceConsumer(id, type, controller.getState(), Transaction::new, controller) { Loading Loading @@ -260,7 +261,11 @@ public class InsetsControllerTest { mController.setSystemDrivenInsetsAnimationLoggingListener(loggingListener); mController.getSourceConsumer(ID_IME, ime()).onWindowFocusGained(true); // since there is no focused view, forcefully make IME visible. if (!Flags.refactorInsetsController()) { mController.show(ime(), true /* fromIme */, ImeTracker.Token.empty()); } else { mController.show(ime(), false /* fromIme */, ImeTracker.Token.empty()); } // When using the animation thread, this must not invoke onReady() mViewRoot.getView().getViewTreeObserver().dispatchOnPreDraw(); }); Loading @@ -277,7 +282,12 @@ public class InsetsControllerTest { InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> { mController.getSourceConsumer(ID_IME, ime()).onWindowFocusGained(true); // since there is no focused view, forcefully make IME visible. if (!Flags.refactorInsetsController()) { mController.show(ime(), true /* fromIme */, ImeTracker.Token.empty()); } else { InsetsSourceControl ime = createControl(ID_IME, ime()); mController.onControlsChanged(new InsetsSourceControl[]{ime}); } mController.show(all()); // quickly jump to final state by cancelling it. mController.cancelExistingAnimations(); Loading @@ -299,7 +309,11 @@ public class InsetsControllerTest { mController.onControlsChanged(new InsetsSourceControl[] { ime }); InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> { mController.getSourceConsumer(ID_IME, ime()).onWindowFocusGained(true); if (!Flags.refactorInsetsController()) { mController.show(ime(), true /* fromIme */, ImeTracker.Token.empty()); } else { mController.show(ime(), false /* fromIme */, ImeTracker.Token.empty()); } mController.cancelExistingAnimations(); assertTrue(isRequestedVisible(mController, ime())); mController.hide(ime(), true /* fromIme */, ImeTracker.Token.empty()); Loading Loading @@ -469,7 +483,12 @@ public class InsetsControllerTest { assertFalse(mController.getState().peekSource(ID_IME).isVisible()); // Pretend IME is calling if (!Flags.refactorInsetsController()) { mController.show(ime(), true /* fromIme */, ImeTracker.Token.empty()); } else { InsetsSourceControl ime = createControl(ID_IME, ime()); mController.onControlsChanged(new InsetsSourceControl[]{ime}); } // Gaining control shortly after mController.onControlsChanged(createSingletonControl(ID_IME, ime())); Loading @@ -493,7 +512,12 @@ public class InsetsControllerTest { mController.onControlsChanged(createSingletonControl(ID_IME, ime())); // Pretend IME is calling if (!Flags.refactorInsetsController()) { mController.show(ime(), true /* fromIme */, ImeTracker.Token.empty()); } else { InsetsSourceControl ime = createControl(ID_IME, ime()); mController.onControlsChanged(new InsetsSourceControl[]{ime}); } assertEquals(ANIMATION_TYPE_SHOW, mController.getAnimationType(ime())); mController.cancelExistingAnimations(); Loading Loading @@ -558,7 +582,13 @@ public class InsetsControllerTest { @Test public void testControlImeNotReady() { if (!Flags.refactorInsetsController()) { prepareControls(); } else { // With the flag on, the IME control should not contain a leash, otherwise the custom // animation will start immediately. prepareControls(false /* imeControlHasLeash */); } InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> { WindowInsetsAnimationControlListener listener = mock(WindowInsetsAnimationControlListener.class); Loading @@ -571,7 +601,13 @@ public class InsetsControllerTest { verify(listener, never()).onReady(any(), anyInt()); // Pretend that IME is calling. if (!Flags.refactorInsetsController()) { mController.show(ime(), true /* fromIme */, ImeTracker.Token.empty()); } else { // Send the IME control with leash, so that the animation can start InsetsSourceControl ime = createControl(ID_IME, ime(), true /* hasLeash */); mController.onControlsChanged(new InsetsSourceControl[]{ime}); } // Ready gets deferred until next predraw mViewRoot.getView().getViewTreeObserver().dispatchOnPreDraw(); Loading @@ -583,7 +619,13 @@ public class InsetsControllerTest { @Test public void testControlImeNotReady_controlRevoked() { if (!Flags.refactorInsetsController()) { prepareControls(); } else { // With the flag on, the IME control should not contain a leash, otherwise the custom // animation will start immediately. prepareControls(false /* imeControlHasLeash */); } InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> { WindowInsetsAnimationControlListener listener = mock(WindowInsetsAnimationControlListener.class); Loading @@ -604,7 +646,13 @@ public class InsetsControllerTest { @Test public void testControlImeNotReady_timeout() { if (!Flags.refactorInsetsController()) { prepareControls(); } else { // With the flag on, the IME control should not contain a leash, otherwise the custom // animation will start immediately. prepareControls(false /* imeControlHasLeash */); } InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> { WindowInsetsAnimationControlListener listener = mock(WindowInsetsAnimationControlListener.class); Loading Loading @@ -655,7 +703,11 @@ public class InsetsControllerTest { mController.onControlsChanged(createSingletonControl(ID_IME, ime())); // Pretend IME is calling if (!Flags.refactorInsetsController()) { mController.show(ime(), true /* fromIme */, ImeTracker.Token.empty()); } else { mController.show(ime(), false /* fromIme */, ImeTracker.Token.empty()); } InsetsState copy = new InsetsState(mController.getState(), true /* copySources */); copy.peekSource(ID_IME).setFrame(0, 1, 2, 3); Loading Loading @@ -886,7 +938,11 @@ public class InsetsControllerTest { // Showing invisible ime should only causes insets change once. clearInvocations(mTestHost); if (!Flags.refactorInsetsController()) { mController.show(ime(), true /* fromIme */, ImeTracker.Token.empty()); } else { mController.show(ime(), false /* fromIme */, ImeTracker.Token.empty()); } verify(mTestHost, times(1)).notifyInsetsChanged(); // Sending the same insets state should not cause insets change. Loading Loading @@ -953,7 +1009,11 @@ public class InsetsControllerTest { assertNull(imeInsetsConsumer.getControl()); // Verify IME requested visibility should be updated to IME consumer from controller. if (!Flags.refactorInsetsController()) { mController.show(ime(), true /* fromIme */, ImeTracker.Token.empty()); } else { mController.show(ime(), false /* fromIme */, ImeTracker.Token.empty()); } assertTrue(isRequestedVisible(mController, ime())); mController.hide(ime()); Loading @@ -966,7 +1026,11 @@ public class InsetsControllerTest { prepareControls(); InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> { // show ime as initial state if (!Flags.refactorInsetsController()) { mController.show(ime(), true /* fromIme */, ImeTracker.Token.empty()); } else { mController.show(ime(), false /* fromIme */, ImeTracker.Token.empty()); } mController.cancelExistingAnimations(); // fast forward show animation assertTrue(mController.getState().peekSource(ID_IME).isVisible()); Loading @@ -990,8 +1054,13 @@ public class InsetsControllerTest { public void testImeShowRequestCancelsPredictiveBackPostCommitAnim() { prepareControls(); InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> { InsetsSourceControl ime = createControl(ID_IME, ime()); // show ime as initial state if (!Flags.refactorInsetsController()) { mController.show(ime(), true /* fromIme */, ImeTracker.Token.empty()); } else { mController.show(ime(), false /* fromIme */, ImeTracker.Token.empty()); } mController.cancelExistingAnimations(); // fast forward show animation mViewRoot.getView().getViewTreeObserver().dispatchOnPreDraw(); assertTrue(mController.getState().peekSource(ID_IME).isVisible()); Loading @@ -1008,12 +1077,20 @@ public class InsetsControllerTest { assertEquals(ANIMATION_TYPE_USER, mController.getAnimationType(ime())); // verify show request is ignored during pre commit phase of predictive back anim if (!Flags.refactorInsetsController()) { mController.show(ime(), true /* fromIme */, null /* statsToken */); } else { mController.onControlsChanged(new InsetsSourceControl[]{ime}); } assertEquals(ANIMATION_TYPE_USER, mController.getAnimationType(ime())); // verify show request is applied during post commit phase of predictive back anim mController.setPredictiveBackImeHideAnimInProgress(true); if (!Flags.refactorInsetsController()) { mController.show(ime(), true /* fromIme */, null /* statsToken */); } else { mController.show(ime(), false /* fromIme */, null /* statsToken */); } assertEquals(ANIMATION_TYPE_SHOW, mController.getAnimationType(ime())); // additionally verify that IME ends up visible Loading @@ -1027,7 +1104,11 @@ public class InsetsControllerTest { prepareControls(); InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> { // show ime as initial state if (!Flags.refactorInsetsController()) { mController.show(ime(), true /* fromIme */, ImeTracker.Token.empty()); } else { mController.show(ime(), false /* fromIme */, ImeTracker.Token.empty()); } mController.cancelExistingAnimations(); // fast forward show animation mViewRoot.getView().getViewTreeObserver().dispatchOnPreDraw(); assertTrue(mController.getState().peekSource(ID_IME).isVisible()); Loading Loading @@ -1058,11 +1139,15 @@ public class InsetsControllerTest { } private InsetsSourceControl createControl(int id, @InsetsType int type) { return createControl(id, type, true); } private InsetsSourceControl createControl(int id, @InsetsType int type, boolean hasLeash) { // Simulate binder behavior by copying SurfaceControl. Otherwise, InsetsController will // attempt to release mLeash directly. SurfaceControl copy = new SurfaceControl(mLeash, "InsetsControllerTest.createControl"); return new InsetsSourceControl(id, type, copy, return new InsetsSourceControl(id, type, hasLeash ? copy : null, (type & WindowInsets.Type.defaultVisible()) != 0, new Point(), Insets.NONE); } Loading @@ -1071,9 +1156,13 @@ public class InsetsControllerTest { } private InsetsSourceControl[] prepareControls() { return prepareControls(true); } private InsetsSourceControl[] prepareControls(boolean imeControlHasLeash) { final InsetsSourceControl navBar = createControl(ID_NAVIGATION_BAR, navigationBars()); final InsetsSourceControl statusBar = createControl(ID_STATUS_BAR, statusBars()); final InsetsSourceControl ime = createControl(ID_IME, ime()); final InsetsSourceControl ime = createControl(ID_IME, ime(), imeControlHasLeash); InsetsSourceControl[] controls = new InsetsSourceControl[3]; controls[0] = navBar; Loading services/tests/wmtests/src/com/android/server/wm/ImeInsetsSourceProviderTest.java +6 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,8 @@ import static org.junit.Assert.assertTrue; import android.graphics.PixelFormat; import android.platform.test.annotations.Presubmit; import android.platform.test.annotations.RequiresFlagsDisabled; import android.view.inputmethod.Flags; import android.view.inputmethod.ImeTracker; import androidx.test.filters.SmallTest; Loading Loading @@ -72,6 +74,7 @@ public class ImeInsetsSourceProviderTest extends WindowTestsBase { * Checks that scheduling with all the state set and manually triggering the show does succeed. */ @Test @RequiresFlagsDisabled(Flags.FLAG_REFACTOR_INSETS_CONTROLLER) public void testScheduleShowIme() { final WindowState ime = createWindow(null, TYPE_INPUT_METHOD, "ime"); makeWindowVisibleAndDrawn(ime); Loading Loading @@ -99,6 +102,7 @@ public class ImeInsetsSourceProviderTest extends WindowTestsBase { * all the state becomes available. */ @Test @RequiresFlagsDisabled(Flags.FLAG_REFACTOR_INSETS_CONTROLLER) public void testScheduleShowIme_noInitialState() { final WindowState target = createWindow(null, TYPE_APPLICATION, "app"); Loading Loading @@ -126,6 +130,7 @@ public class ImeInsetsSourceProviderTest extends WindowTestsBase { * does continue and succeed when the runnable is started. */ @Test @RequiresFlagsDisabled(Flags.FLAG_REFACTOR_INSETS_CONTROLLER) public void testScheduleShowIme_delayedAfterPrepareSurfaces() { final WindowState ime = createWindow(null, TYPE_INPUT_METHOD, "ime"); makeWindowVisibleAndDrawn(ime); Loading Loading @@ -158,6 +163,7 @@ public class ImeInsetsSourceProviderTest extends WindowTestsBase { * when the surface placement happens. */ @Test @RequiresFlagsDisabled(Flags.FLAG_REFACTOR_INSETS_CONTROLLER) public void testScheduleShowIme_delayedSurfacePlacement() { final WindowState ime = createWindow(null, TYPE_INPUT_METHOD, "ime"); makeWindowVisibleAndDrawn(ime); Loading services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java +12 −0 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; import static com.android.server.wm.WindowContainer.POSITION_TOP; import static com.android.server.wm.WindowStateAnimator.HAS_DRAWN; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; Loading Loading @@ -202,6 +203,11 @@ public class InsetsStateControllerTest extends WindowTestsBase { getController().onImeControlTargetChanged(base); base.setRequestedVisibleTypes(ime(), ime()); getController().onRequestedVisibleTypesChanged(base, null /* statsToken */); if (android.view.inputmethod.Flags.refactorInsetsController()) { // to set the serverVisibility, the IME needs to be drawn and onPostLayout be called. mImeWindow.mWinAnimator.mDrawState = HAS_DRAWN; getController().onPostLayout(); } // Send our spy window (app) into the system so that we can detect the invocation. final WindowState win = createWindow(null, TYPE_APPLICATION, "app"); Loading Loading @@ -500,6 +506,12 @@ public class InsetsStateControllerTest extends WindowTestsBase { getController().onRequestedVisibleTypesChanged(app, null /* statsToken */); assertTrue(ime.getControllableInsetProvider().getSource().isVisible()); if (android.view.inputmethod.Flags.refactorInsetsController()) { // The IME is only set to shown, after onPostLayout is called and all preconditions // (serverVisible, no givenInsetsPending, etc.) are fulfilled getController().getImeSourceProvider().onPostLayout(); } getController().updateAboveInsetsState(true /* notifyInsetsChange */); assertNotNull(app.getInsetsState().peekSource(ID_IME)); verify(app, atLeastOnce()).notifyInsetsChanged(); Loading Loading
core/tests/coretests/src/android/view/InsetsControllerTest.java +109 −20 Original line number Diff line number Diff line Loading @@ -69,6 +69,7 @@ import android.view.WindowInsetsController.OnControllableInsetsChangedListener; import android.view.WindowManager.BadTokenException; import android.view.WindowManager.LayoutParams; import android.view.animation.LinearInterpolator; import android.view.inputmethod.Flags; import android.view.inputmethod.ImeTracker; import android.widget.TextView; Loading Loading @@ -136,7 +137,7 @@ public class InsetsControllerTest { mTestHandler = new TestHandler(null, mTestClock); mTestHost = spy(new TestHost(mViewRoot)); mController = new InsetsController(mTestHost, (controller, id, type) -> { if (type == ime()) { if (!Flags.refactorInsetsController() && type == ime()) { return new InsetsSourceConsumer(id, type, controller.getState(), Transaction::new, controller) { Loading Loading @@ -260,7 +261,11 @@ public class InsetsControllerTest { mController.setSystemDrivenInsetsAnimationLoggingListener(loggingListener); mController.getSourceConsumer(ID_IME, ime()).onWindowFocusGained(true); // since there is no focused view, forcefully make IME visible. if (!Flags.refactorInsetsController()) { mController.show(ime(), true /* fromIme */, ImeTracker.Token.empty()); } else { mController.show(ime(), false /* fromIme */, ImeTracker.Token.empty()); } // When using the animation thread, this must not invoke onReady() mViewRoot.getView().getViewTreeObserver().dispatchOnPreDraw(); }); Loading @@ -277,7 +282,12 @@ public class InsetsControllerTest { InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> { mController.getSourceConsumer(ID_IME, ime()).onWindowFocusGained(true); // since there is no focused view, forcefully make IME visible. if (!Flags.refactorInsetsController()) { mController.show(ime(), true /* fromIme */, ImeTracker.Token.empty()); } else { InsetsSourceControl ime = createControl(ID_IME, ime()); mController.onControlsChanged(new InsetsSourceControl[]{ime}); } mController.show(all()); // quickly jump to final state by cancelling it. mController.cancelExistingAnimations(); Loading @@ -299,7 +309,11 @@ public class InsetsControllerTest { mController.onControlsChanged(new InsetsSourceControl[] { ime }); InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> { mController.getSourceConsumer(ID_IME, ime()).onWindowFocusGained(true); if (!Flags.refactorInsetsController()) { mController.show(ime(), true /* fromIme */, ImeTracker.Token.empty()); } else { mController.show(ime(), false /* fromIme */, ImeTracker.Token.empty()); } mController.cancelExistingAnimations(); assertTrue(isRequestedVisible(mController, ime())); mController.hide(ime(), true /* fromIme */, ImeTracker.Token.empty()); Loading Loading @@ -469,7 +483,12 @@ public class InsetsControllerTest { assertFalse(mController.getState().peekSource(ID_IME).isVisible()); // Pretend IME is calling if (!Flags.refactorInsetsController()) { mController.show(ime(), true /* fromIme */, ImeTracker.Token.empty()); } else { InsetsSourceControl ime = createControl(ID_IME, ime()); mController.onControlsChanged(new InsetsSourceControl[]{ime}); } // Gaining control shortly after mController.onControlsChanged(createSingletonControl(ID_IME, ime())); Loading @@ -493,7 +512,12 @@ public class InsetsControllerTest { mController.onControlsChanged(createSingletonControl(ID_IME, ime())); // Pretend IME is calling if (!Flags.refactorInsetsController()) { mController.show(ime(), true /* fromIme */, ImeTracker.Token.empty()); } else { InsetsSourceControl ime = createControl(ID_IME, ime()); mController.onControlsChanged(new InsetsSourceControl[]{ime}); } assertEquals(ANIMATION_TYPE_SHOW, mController.getAnimationType(ime())); mController.cancelExistingAnimations(); Loading Loading @@ -558,7 +582,13 @@ public class InsetsControllerTest { @Test public void testControlImeNotReady() { if (!Flags.refactorInsetsController()) { prepareControls(); } else { // With the flag on, the IME control should not contain a leash, otherwise the custom // animation will start immediately. prepareControls(false /* imeControlHasLeash */); } InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> { WindowInsetsAnimationControlListener listener = mock(WindowInsetsAnimationControlListener.class); Loading @@ -571,7 +601,13 @@ public class InsetsControllerTest { verify(listener, never()).onReady(any(), anyInt()); // Pretend that IME is calling. if (!Flags.refactorInsetsController()) { mController.show(ime(), true /* fromIme */, ImeTracker.Token.empty()); } else { // Send the IME control with leash, so that the animation can start InsetsSourceControl ime = createControl(ID_IME, ime(), true /* hasLeash */); mController.onControlsChanged(new InsetsSourceControl[]{ime}); } // Ready gets deferred until next predraw mViewRoot.getView().getViewTreeObserver().dispatchOnPreDraw(); Loading @@ -583,7 +619,13 @@ public class InsetsControllerTest { @Test public void testControlImeNotReady_controlRevoked() { if (!Flags.refactorInsetsController()) { prepareControls(); } else { // With the flag on, the IME control should not contain a leash, otherwise the custom // animation will start immediately. prepareControls(false /* imeControlHasLeash */); } InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> { WindowInsetsAnimationControlListener listener = mock(WindowInsetsAnimationControlListener.class); Loading @@ -604,7 +646,13 @@ public class InsetsControllerTest { @Test public void testControlImeNotReady_timeout() { if (!Flags.refactorInsetsController()) { prepareControls(); } else { // With the flag on, the IME control should not contain a leash, otherwise the custom // animation will start immediately. prepareControls(false /* imeControlHasLeash */); } InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> { WindowInsetsAnimationControlListener listener = mock(WindowInsetsAnimationControlListener.class); Loading Loading @@ -655,7 +703,11 @@ public class InsetsControllerTest { mController.onControlsChanged(createSingletonControl(ID_IME, ime())); // Pretend IME is calling if (!Flags.refactorInsetsController()) { mController.show(ime(), true /* fromIme */, ImeTracker.Token.empty()); } else { mController.show(ime(), false /* fromIme */, ImeTracker.Token.empty()); } InsetsState copy = new InsetsState(mController.getState(), true /* copySources */); copy.peekSource(ID_IME).setFrame(0, 1, 2, 3); Loading Loading @@ -886,7 +938,11 @@ public class InsetsControllerTest { // Showing invisible ime should only causes insets change once. clearInvocations(mTestHost); if (!Flags.refactorInsetsController()) { mController.show(ime(), true /* fromIme */, ImeTracker.Token.empty()); } else { mController.show(ime(), false /* fromIme */, ImeTracker.Token.empty()); } verify(mTestHost, times(1)).notifyInsetsChanged(); // Sending the same insets state should not cause insets change. Loading Loading @@ -953,7 +1009,11 @@ public class InsetsControllerTest { assertNull(imeInsetsConsumer.getControl()); // Verify IME requested visibility should be updated to IME consumer from controller. if (!Flags.refactorInsetsController()) { mController.show(ime(), true /* fromIme */, ImeTracker.Token.empty()); } else { mController.show(ime(), false /* fromIme */, ImeTracker.Token.empty()); } assertTrue(isRequestedVisible(mController, ime())); mController.hide(ime()); Loading @@ -966,7 +1026,11 @@ public class InsetsControllerTest { prepareControls(); InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> { // show ime as initial state if (!Flags.refactorInsetsController()) { mController.show(ime(), true /* fromIme */, ImeTracker.Token.empty()); } else { mController.show(ime(), false /* fromIme */, ImeTracker.Token.empty()); } mController.cancelExistingAnimations(); // fast forward show animation assertTrue(mController.getState().peekSource(ID_IME).isVisible()); Loading @@ -990,8 +1054,13 @@ public class InsetsControllerTest { public void testImeShowRequestCancelsPredictiveBackPostCommitAnim() { prepareControls(); InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> { InsetsSourceControl ime = createControl(ID_IME, ime()); // show ime as initial state if (!Flags.refactorInsetsController()) { mController.show(ime(), true /* fromIme */, ImeTracker.Token.empty()); } else { mController.show(ime(), false /* fromIme */, ImeTracker.Token.empty()); } mController.cancelExistingAnimations(); // fast forward show animation mViewRoot.getView().getViewTreeObserver().dispatchOnPreDraw(); assertTrue(mController.getState().peekSource(ID_IME).isVisible()); Loading @@ -1008,12 +1077,20 @@ public class InsetsControllerTest { assertEquals(ANIMATION_TYPE_USER, mController.getAnimationType(ime())); // verify show request is ignored during pre commit phase of predictive back anim if (!Flags.refactorInsetsController()) { mController.show(ime(), true /* fromIme */, null /* statsToken */); } else { mController.onControlsChanged(new InsetsSourceControl[]{ime}); } assertEquals(ANIMATION_TYPE_USER, mController.getAnimationType(ime())); // verify show request is applied during post commit phase of predictive back anim mController.setPredictiveBackImeHideAnimInProgress(true); if (!Flags.refactorInsetsController()) { mController.show(ime(), true /* fromIme */, null /* statsToken */); } else { mController.show(ime(), false /* fromIme */, null /* statsToken */); } assertEquals(ANIMATION_TYPE_SHOW, mController.getAnimationType(ime())); // additionally verify that IME ends up visible Loading @@ -1027,7 +1104,11 @@ public class InsetsControllerTest { prepareControls(); InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> { // show ime as initial state if (!Flags.refactorInsetsController()) { mController.show(ime(), true /* fromIme */, ImeTracker.Token.empty()); } else { mController.show(ime(), false /* fromIme */, ImeTracker.Token.empty()); } mController.cancelExistingAnimations(); // fast forward show animation mViewRoot.getView().getViewTreeObserver().dispatchOnPreDraw(); assertTrue(mController.getState().peekSource(ID_IME).isVisible()); Loading Loading @@ -1058,11 +1139,15 @@ public class InsetsControllerTest { } private InsetsSourceControl createControl(int id, @InsetsType int type) { return createControl(id, type, true); } private InsetsSourceControl createControl(int id, @InsetsType int type, boolean hasLeash) { // Simulate binder behavior by copying SurfaceControl. Otherwise, InsetsController will // attempt to release mLeash directly. SurfaceControl copy = new SurfaceControl(mLeash, "InsetsControllerTest.createControl"); return new InsetsSourceControl(id, type, copy, return new InsetsSourceControl(id, type, hasLeash ? copy : null, (type & WindowInsets.Type.defaultVisible()) != 0, new Point(), Insets.NONE); } Loading @@ -1071,9 +1156,13 @@ public class InsetsControllerTest { } private InsetsSourceControl[] prepareControls() { return prepareControls(true); } private InsetsSourceControl[] prepareControls(boolean imeControlHasLeash) { final InsetsSourceControl navBar = createControl(ID_NAVIGATION_BAR, navigationBars()); final InsetsSourceControl statusBar = createControl(ID_STATUS_BAR, statusBars()); final InsetsSourceControl ime = createControl(ID_IME, ime()); final InsetsSourceControl ime = createControl(ID_IME, ime(), imeControlHasLeash); InsetsSourceControl[] controls = new InsetsSourceControl[3]; controls[0] = navBar; Loading
services/tests/wmtests/src/com/android/server/wm/ImeInsetsSourceProviderTest.java +6 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,8 @@ import static org.junit.Assert.assertTrue; import android.graphics.PixelFormat; import android.platform.test.annotations.Presubmit; import android.platform.test.annotations.RequiresFlagsDisabled; import android.view.inputmethod.Flags; import android.view.inputmethod.ImeTracker; import androidx.test.filters.SmallTest; Loading Loading @@ -72,6 +74,7 @@ public class ImeInsetsSourceProviderTest extends WindowTestsBase { * Checks that scheduling with all the state set and manually triggering the show does succeed. */ @Test @RequiresFlagsDisabled(Flags.FLAG_REFACTOR_INSETS_CONTROLLER) public void testScheduleShowIme() { final WindowState ime = createWindow(null, TYPE_INPUT_METHOD, "ime"); makeWindowVisibleAndDrawn(ime); Loading Loading @@ -99,6 +102,7 @@ public class ImeInsetsSourceProviderTest extends WindowTestsBase { * all the state becomes available. */ @Test @RequiresFlagsDisabled(Flags.FLAG_REFACTOR_INSETS_CONTROLLER) public void testScheduleShowIme_noInitialState() { final WindowState target = createWindow(null, TYPE_APPLICATION, "app"); Loading Loading @@ -126,6 +130,7 @@ public class ImeInsetsSourceProviderTest extends WindowTestsBase { * does continue and succeed when the runnable is started. */ @Test @RequiresFlagsDisabled(Flags.FLAG_REFACTOR_INSETS_CONTROLLER) public void testScheduleShowIme_delayedAfterPrepareSurfaces() { final WindowState ime = createWindow(null, TYPE_INPUT_METHOD, "ime"); makeWindowVisibleAndDrawn(ime); Loading Loading @@ -158,6 +163,7 @@ public class ImeInsetsSourceProviderTest extends WindowTestsBase { * when the surface placement happens. */ @Test @RequiresFlagsDisabled(Flags.FLAG_REFACTOR_INSETS_CONTROLLER) public void testScheduleShowIme_delayedSurfacePlacement() { final WindowState ime = createWindow(null, TYPE_INPUT_METHOD, "ime"); makeWindowVisibleAndDrawn(ime); Loading
services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java +12 −0 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; import static com.android.server.wm.WindowContainer.POSITION_TOP; import static com.android.server.wm.WindowStateAnimator.HAS_DRAWN; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; Loading Loading @@ -202,6 +203,11 @@ public class InsetsStateControllerTest extends WindowTestsBase { getController().onImeControlTargetChanged(base); base.setRequestedVisibleTypes(ime(), ime()); getController().onRequestedVisibleTypesChanged(base, null /* statsToken */); if (android.view.inputmethod.Flags.refactorInsetsController()) { // to set the serverVisibility, the IME needs to be drawn and onPostLayout be called. mImeWindow.mWinAnimator.mDrawState = HAS_DRAWN; getController().onPostLayout(); } // Send our spy window (app) into the system so that we can detect the invocation. final WindowState win = createWindow(null, TYPE_APPLICATION, "app"); Loading Loading @@ -500,6 +506,12 @@ public class InsetsStateControllerTest extends WindowTestsBase { getController().onRequestedVisibleTypesChanged(app, null /* statsToken */); assertTrue(ime.getControllableInsetProvider().getSource().isVisible()); if (android.view.inputmethod.Flags.refactorInsetsController()) { // The IME is only set to shown, after onPostLayout is called and all preconditions // (serverVisible, no givenInsetsPending, etc.) are fulfilled getController().getImeSourceProvider().onPostLayout(); } getController().updateAboveInsetsState(true /* notifyInsetsChange */); assertNotNull(app.getInsetsState().peekSource(ID_IME)); verify(app, atLeastOnce()).notifyInsetsChanged(); Loading