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

Commit 957032e6 authored by Felix Stern's avatar Felix Stern
Browse files

Sync IME visibility to control target, when it changes

When the IME controlTarget changes from a fullscreen app to the RemoteInsetsControlTarget, the visibility from the IME input target should been reported to the controlTarget. Otherwise, they could be out of sync.

Fix: 399191474
Flag: android.view.inputmethod.refactor_insets_controller
Test: atest ImeInsetsSourceProviderTest#testUpdateControlForTarget_remoteInsetsControlTarget
Test: manual:
      Open IME on tablet in fullscreen app
      Enter desktop windowing mode while IME showing
      Verify that IME is still visible
Change-Id: I7cb5dea67c5622856a20c52434c252fd84af89b7
parent 0a40deba
Loading
Loading
Loading
Loading
+8 −4
Original line number Diff line number Diff line
@@ -285,11 +285,15 @@ final class ImeInsetsSourceProvider extends InsetsSourceProvider {
                // If insets target is not available (e.g. RemoteInsetsControlTarget), use current
                // IME input target to update IME request state. For example, switch from a task
                // with showing IME to a split-screen task without showing IME.
                InsetsTarget insetsTarget = target.getWindow();
                if (insetsTarget == null && mServerVisible) {
                    insetsTarget = mDisplayContent.getImeInputTarget();
                InputTarget imeInputTarget = mDisplayContent.getImeInputTarget();
                if (imeInputTarget != target && imeInputTarget != null) {
                    // The controlTarget should be updated with the visibility of the
                    // current IME input target.
                    reportImeInputTargetStateToControlTarget(imeInputTarget, target,
                            statsToken);
                } else {
                    invokeOnImeRequestedChangedListener(target, statsToken);
                }
                invokeOnImeRequestedChangedListener(insetsTarget, statsToken);
            }
        }
    }
+33 −0
Original line number Diff line number Diff line
@@ -21,10 +21,18 @@ import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;

import android.graphics.PixelFormat;
import android.os.RemoteException;
import android.platform.test.annotations.Presubmit;
import android.platform.test.annotations.RequiresFlagsDisabled;
import android.platform.test.annotations.RequiresFlagsEnabled;
import android.view.WindowInsets;
import android.view.inputmethod.Flags;
import android.view.inputmethod.ImeTracker;

@@ -211,4 +219,29 @@ public class ImeInsetsSourceProviderTest extends WindowTestsBase {
        mImeProvider.setFrozen(false);
        assertFalse(mImeProvider.getSource().isVisible());
    }

    @Test
    @RequiresFlagsEnabled(Flags.FLAG_REFACTOR_INSETS_CONTROLLER)
    public void testUpdateControlForTarget_remoteInsetsControlTarget() throws RemoteException {
        final WindowState ime = newWindowBuilder("ime", TYPE_INPUT_METHOD).build();
        makeWindowVisibleAndDrawn(ime);
        mImeProvider.setWindowContainer(ime, null, null);
        mImeProvider.setServerVisible(true);
        mImeProvider.setClientVisible(true);
        final WindowState inputTarget = newWindowBuilder("app", TYPE_APPLICATION).build();
        final var displayWindowInsetsController = spy(createDisplayWindowInsetsController());
        mDisplayContent.setRemoteInsetsController(displayWindowInsetsController);
        final var controlTarget = mDisplayContent.mRemoteInsetsControlTarget;

        inputTarget.setRequestedVisibleTypes(
                WindowInsets.Type.defaultVisible() | WindowInsets.Type.ime());
        mDisplayContent.setImeInputTarget(inputTarget);
        mDisplayContent.setImeControlTarget(controlTarget);

        assertTrue(inputTarget.isRequestedVisible(WindowInsets.Type.ime()));
        assertFalse(controlTarget.isRequestedVisible(WindowInsets.Type.ime()));
        mImeProvider.updateControlForTarget(controlTarget, true /* force */, null /* statsToken */);
        verify(displayWindowInsetsController, times(1)).setImeInputTargetRequestedVisibility(
                eq(true), any());
    }
}