Loading core/java/android/inputmethodservice/InputMethodService.java +2 −0 Original line number Diff line number Diff line Loading @@ -990,6 +990,8 @@ public class InputMethodService extends AbstractInputMethodService { } Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); if (android.view.inputmethod.Flags.refactorInsetsController()) { // After the IME window was hidden, we can remove its surface scheduleImeSurfaceRemoval(); // The hide request first finishes the animation and then proceeds to the server // side, finally reaching here, marking this the end state. ImeTracker.forLogging().onHidden(statsToken); Loading core/java/android/view/InsetsController.java +5 −1 Original line number Diff line number Diff line Loading @@ -1299,8 +1299,12 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation // Handle the pending show request for other insets types since the IME insets // has being requested hidden. handlePendingControlRequest(statsToken); if (!Flags.refactorInsetsController()) { // the surface can't be removed until the end of the animation. This is handled by // IMMS after the window was requested to be hidden. getImeSourceConsumer().removeSurface(); } } applyAnimation(typesReady, false /* show */, fromIme, false /* skipsCallbacks */, statsToken); } Loading core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java +3 −1 Original line number Diff line number Diff line Loading @@ -230,7 +230,9 @@ public class InsetsSourceConsumerTest { new InsetsSourceControl(ID_STATUS_BAR, statusBars(), mLeash, false /* initialVisible */, new Point(), Insets.NONE), new int[1], hideTypes, new int[1], new int[1]); if (!android.view.inputmethod.Flags.refactorInsetsController()) { assertTrue(mRemoveSurfaceCalled); } assertEquals(0, hideTypes[0]); }); Loading libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java +7 −3 Original line number Diff line number Diff line Loading @@ -324,10 +324,12 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged } applyVisibilityToLeash(imeSourceControl); } if (!android.view.inputmethod.Flags.refactorInsetsController()) { if (!mImeShowing) { removeImeSurface(mDisplayId); } } } } else { if (!android.view.inputmethod.Flags.refactorInsetsController() && mAnimation != null) { Loading Loading @@ -663,7 +665,9 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged ImeTracker.forLogging().onProgress(mStatsToken, ImeTracker.PHASE_WM_ANIMATION_RUNNING); t.hide(animatingLeash); if (!android.view.inputmethod.Flags.refactorInsetsController()) { removeImeSurface(mDisplayId); } if (android.view.inputmethod.Flags.refactorInsetsController()) { setVisibleDirectly(false /* visible */, statsToken); } Loading services/tests/InputMethodSystemServerTests/src/com/android/inputmethodservice/InputMethodServiceTest.java +60 −0 Original line number Diff line number Diff line Loading @@ -40,10 +40,14 @@ import android.content.res.Configuration; import android.graphics.Insets; import android.os.Build; import android.os.RemoteException; import android.platform.test.annotations.RequiresFlagsEnabled; import android.platform.test.flag.junit.DeviceFlagsValueProvider; import android.provider.Settings; import android.server.wm.WindowManagerStateHelper; import android.util.Log; import android.view.View; import android.view.WindowInsets; import android.view.WindowInsetsAnimation; import android.view.WindowManagerGlobal; import android.view.inputmethod.EditorInfo; import android.view.inputmethod.Flags; Loading Loading @@ -72,6 +76,7 @@ import org.junit.Test; import org.junit.rules.TestName; import org.junit.runner.RunWith; import java.util.List; import java.util.Objects; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; Loading Loading @@ -244,6 +249,61 @@ public class InputMethodServiceTest { EVENT_HIDE, true /* eventExpected */, false /* shown */, "IME is not shown"); } /** * This checks that the surface is removed after the window was hidden in * InputMethodService#hideSoftInput */ @Test @RequiresFlagsEnabled(Flags.FLAG_REFACTOR_INSETS_CONTROLLER) public void testSurfaceRemovedAfterHideSoftInput() { setShowImeWithHardKeyboard(true /* enabled */); // Triggers to show IME via public API. verifyInputViewStatusOnMainSync(() -> mActivity.showImeWithWindowInsetsController(), EVENT_SHOW, true /* eventExpected */, true /* shown */, "IME is shown"); assertWithMessage("IME is shown").that(mInputMethodService.isInputViewShown()).isTrue(); final var window = mInputMethodService.getWindow().getWindow(); assertWithMessage("IME window exists").that(window).isNotNull(); assertWithMessage("IME window showing").that( window.getDecorView().getVisibility()).isEqualTo(View.VISIBLE); mActivity.getWindow().getDecorView().setWindowInsetsAnimationCallback( new WindowInsetsAnimation.Callback( WindowInsetsAnimation.Callback.DISPATCH_MODE_CONTINUE_ON_SUBTREE) { @NonNull @Override public WindowInsetsAnimation.Bounds onStart( @NonNull WindowInsetsAnimation animation, @NonNull WindowInsetsAnimation.Bounds bounds) { return super.onStart(animation, bounds); } @NonNull @Override public WindowInsets onProgress(@NonNull WindowInsets insets, @NonNull List<WindowInsetsAnimation> runningAnimations) { assertWithMessage("IME surface not removed during the animation").that( window.getDecorView().getVisibility()).isEqualTo(View.VISIBLE); return insets; } @Override public void onEnd(@NonNull WindowInsetsAnimation animation) { assertWithMessage( "IME surface not removed before the end of the animation").that( window.getDecorView().getVisibility()).isEqualTo(View.VISIBLE); super.onEnd(animation); } }); // Triggers to hide IME via public API. verifyInputViewStatusOnMainSync(() -> mActivity.hideImeWithWindowInsetsController(), EVENT_HIDE, true /* eventExpected */, false /* shown */, "IME is not shown"); eventually(() -> assertWithMessage("IME window not showing").that( window.getDecorView().getVisibility()).isEqualTo(View.GONE)); } /** * This checks the result of calling IMS#requestShowSelf and IMS#requestHideSelf. */ Loading Loading
core/java/android/inputmethodservice/InputMethodService.java +2 −0 Original line number Diff line number Diff line Loading @@ -990,6 +990,8 @@ public class InputMethodService extends AbstractInputMethodService { } Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); if (android.view.inputmethod.Flags.refactorInsetsController()) { // After the IME window was hidden, we can remove its surface scheduleImeSurfaceRemoval(); // The hide request first finishes the animation and then proceeds to the server // side, finally reaching here, marking this the end state. ImeTracker.forLogging().onHidden(statsToken); Loading
core/java/android/view/InsetsController.java +5 −1 Original line number Diff line number Diff line Loading @@ -1299,8 +1299,12 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation // Handle the pending show request for other insets types since the IME insets // has being requested hidden. handlePendingControlRequest(statsToken); if (!Flags.refactorInsetsController()) { // the surface can't be removed until the end of the animation. This is handled by // IMMS after the window was requested to be hidden. getImeSourceConsumer().removeSurface(); } } applyAnimation(typesReady, false /* show */, fromIme, false /* skipsCallbacks */, statsToken); } Loading
core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java +3 −1 Original line number Diff line number Diff line Loading @@ -230,7 +230,9 @@ public class InsetsSourceConsumerTest { new InsetsSourceControl(ID_STATUS_BAR, statusBars(), mLeash, false /* initialVisible */, new Point(), Insets.NONE), new int[1], hideTypes, new int[1], new int[1]); if (!android.view.inputmethod.Flags.refactorInsetsController()) { assertTrue(mRemoveSurfaceCalled); } assertEquals(0, hideTypes[0]); }); Loading
libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java +7 −3 Original line number Diff line number Diff line Loading @@ -324,10 +324,12 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged } applyVisibilityToLeash(imeSourceControl); } if (!android.view.inputmethod.Flags.refactorInsetsController()) { if (!mImeShowing) { removeImeSurface(mDisplayId); } } } } else { if (!android.view.inputmethod.Flags.refactorInsetsController() && mAnimation != null) { Loading Loading @@ -663,7 +665,9 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged ImeTracker.forLogging().onProgress(mStatsToken, ImeTracker.PHASE_WM_ANIMATION_RUNNING); t.hide(animatingLeash); if (!android.view.inputmethod.Flags.refactorInsetsController()) { removeImeSurface(mDisplayId); } if (android.view.inputmethod.Flags.refactorInsetsController()) { setVisibleDirectly(false /* visible */, statsToken); } Loading
services/tests/InputMethodSystemServerTests/src/com/android/inputmethodservice/InputMethodServiceTest.java +60 −0 Original line number Diff line number Diff line Loading @@ -40,10 +40,14 @@ import android.content.res.Configuration; import android.graphics.Insets; import android.os.Build; import android.os.RemoteException; import android.platform.test.annotations.RequiresFlagsEnabled; import android.platform.test.flag.junit.DeviceFlagsValueProvider; import android.provider.Settings; import android.server.wm.WindowManagerStateHelper; import android.util.Log; import android.view.View; import android.view.WindowInsets; import android.view.WindowInsetsAnimation; import android.view.WindowManagerGlobal; import android.view.inputmethod.EditorInfo; import android.view.inputmethod.Flags; Loading Loading @@ -72,6 +76,7 @@ import org.junit.Test; import org.junit.rules.TestName; import org.junit.runner.RunWith; import java.util.List; import java.util.Objects; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; Loading Loading @@ -244,6 +249,61 @@ public class InputMethodServiceTest { EVENT_HIDE, true /* eventExpected */, false /* shown */, "IME is not shown"); } /** * This checks that the surface is removed after the window was hidden in * InputMethodService#hideSoftInput */ @Test @RequiresFlagsEnabled(Flags.FLAG_REFACTOR_INSETS_CONTROLLER) public void testSurfaceRemovedAfterHideSoftInput() { setShowImeWithHardKeyboard(true /* enabled */); // Triggers to show IME via public API. verifyInputViewStatusOnMainSync(() -> mActivity.showImeWithWindowInsetsController(), EVENT_SHOW, true /* eventExpected */, true /* shown */, "IME is shown"); assertWithMessage("IME is shown").that(mInputMethodService.isInputViewShown()).isTrue(); final var window = mInputMethodService.getWindow().getWindow(); assertWithMessage("IME window exists").that(window).isNotNull(); assertWithMessage("IME window showing").that( window.getDecorView().getVisibility()).isEqualTo(View.VISIBLE); mActivity.getWindow().getDecorView().setWindowInsetsAnimationCallback( new WindowInsetsAnimation.Callback( WindowInsetsAnimation.Callback.DISPATCH_MODE_CONTINUE_ON_SUBTREE) { @NonNull @Override public WindowInsetsAnimation.Bounds onStart( @NonNull WindowInsetsAnimation animation, @NonNull WindowInsetsAnimation.Bounds bounds) { return super.onStart(animation, bounds); } @NonNull @Override public WindowInsets onProgress(@NonNull WindowInsets insets, @NonNull List<WindowInsetsAnimation> runningAnimations) { assertWithMessage("IME surface not removed during the animation").that( window.getDecorView().getVisibility()).isEqualTo(View.VISIBLE); return insets; } @Override public void onEnd(@NonNull WindowInsetsAnimation animation) { assertWithMessage( "IME surface not removed before the end of the animation").that( window.getDecorView().getVisibility()).isEqualTo(View.VISIBLE); super.onEnd(animation); } }); // Triggers to hide IME via public API. verifyInputViewStatusOnMainSync(() -> mActivity.hideImeWithWindowInsetsController(), EVENT_HIDE, true /* eventExpected */, false /* shown */, "IME is not shown"); eventually(() -> assertWithMessage("IME window not showing").that( window.getDecorView().getVisibility()).isEqualTo(View.GONE)); } /** * This checks the result of calling IMS#requestShowSelf and IMS#requestHideSelf. */ Loading