Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e3a3cd83 authored by Ming-Shin Lu's avatar Ming-Shin Lu
Browse files

Fix WIC#hide(ime()) no-op when IME insets not controllable

When the app is in multi-windowing mode (e.g. Bubble or split-screen),
calling WIC#show(ime()) isn't update IME requested visiblity to IME
insets consumer due to the app unable to control the IME insets, even
though IME ends up showing by invoking requestShow from consumer, the
requested visible state is still be invisible.

This affects when the app calling WIC#hide(ime()) next time, the call
will be no-op since no previous requested visible state.

To fix this, ensure in InsetsController#collectSourceControls could call
consumer.show(fromIme) to update IME requested visiblity,
even though the result of requestShow was IME_SHOW_DELAYED by IME insets
not controllable.

Fix: 235157568
Test: manual as following steps
   1) make and install WindowInsetsTests
   2) Launch WindowInsetsTests from all apps.
   3) Launch another app and enter split-screen mode
   4) Choose WindowInsetsTests task to be bottom split-task
   5) In Window Insets Tests main activity, press
      "Window Insets Controller" button
   6) Press "IME INVISIBLE" button to show IME
   7) When IME is visible, press "IME VISIBLE" button to verify
      IME will be hidden
Test: atest InsetsControllerTest#\
       testImeRequestedVisibleWhenImeNotControllable
Change-Id: I8f70dd8bdf24f4a08bcc6f975b13b69988bd69f3
parent 0d6e4b90
Loading
Loading
Loading
Loading
+2 −3
Original line number Diff line number Diff line
@@ -1159,7 +1159,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
            final InsetsSourceConsumer consumer = getSourceConsumer(internalTypes.valueAt(i));
            boolean show = animationType == ANIMATION_TYPE_SHOW
                    || animationType == ANIMATION_TYPE_USER;
            boolean canRun = false;
            boolean canRun = true;
            if (show) {
                // Show request
                if (fromIme) {
@@ -1169,7 +1169,6 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
                }
                switch(consumer.requestShow(fromIme)) {
                    case ShowResult.SHOW_IMMEDIATELY:
                        canRun = true;
                        break;
                    case ShowResult.IME_SHOW_DELAYED:
                        imeReady = false;
@@ -1180,6 +1179,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
                                + fromIme);
                        // IME cannot be shown (since it didn't have focus), proceed
                        // with animation of other types.
                        canRun = false;
                        break;
                }
            } else {
@@ -1189,7 +1189,6 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
                if (!fromIme) {
                    consumer.notifyHidden();
                }
                canRun = true;
            }
            if (!canRun) {
                if (WARN) Log.w(TAG, String.format(
+17 −0
Original line number Diff line number Diff line
@@ -914,6 +914,23 @@ public class InsetsControllerTest {
        });
    }

    @Test
    public void testImeRequestedVisibleWhenImeNotControllable() {
        InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
            // Simulate IME insets is not controllable
            mController.onControlsChanged(new InsetsSourceControl[0]);
            final InsetsSourceConsumer imeInsetsConsumer = mController.getSourceConsumer(ITYPE_IME);
            assertNull(imeInsetsConsumer.getControl());

            // Verify IME requested visibility should be updated to IME consumer from controller.
            mController.show(ime());
            assertTrue(imeInsetsConsumer.isRequestedVisible());

            mController.hide(ime());
            assertFalse(imeInsetsConsumer.isRequestedVisible());
        });
    }

    private void waitUntilNextFrame() throws Exception {
        final CountDownLatch latch = new CountDownLatch(1);
        Choreographer.getMainThreadInstance().postCallback(Choreographer.CALLBACK_COMMIT,