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

Commit fb499317 authored by Wilson Wu's avatar Wilson Wu Committed by Android (Google) Code Review
Browse files

Merge "Fix wrong ime parent in embedded activity" into udc-dev

parents da896af6 44cab451
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -4589,7 +4589,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
     */
    @VisibleForTesting
    SurfaceControl computeImeParent() {
        if (!ImeTargetVisibilityPolicy.isReadyToComputeImeParent(mImeLayeringTarget,
        if (!ImeTargetVisibilityPolicy.isValidToComputeImeParent(mImeLayeringTarget,
                mImeInputTarget)) {
            return null;
        }
+31 −3
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.server.wm;

import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;

import android.annotation.Nullable;
import android.os.IBinder;
import android.view.WindowManager;

@@ -50,10 +51,12 @@ public abstract class ImeTargetVisibilityPolicy {
     * Called when {@link DisplayContent#computeImeParent()} to check if it's valid to keep
     * computing the ime parent.
     *
     * @param imeLayeringTarget The window which IME target to layer on top of it.
     * @param imeInputTarget The window which start the input connection, receive input from IME.
     * @return {@code true} to keep computing the ime parent, {@code false} to defer this operation
     */
    public static boolean isReadyToComputeImeParent(WindowState imeLayeringTarget,
            InputTarget imeInputTarget) {
    public static boolean isValidToComputeImeParent(@Nullable WindowState imeLayeringTarget,
            @Nullable InputTarget imeInputTarget) {
        if (imeLayeringTarget == null) {
            return false;
        }
@@ -69,7 +72,9 @@ public abstract class ImeTargetVisibilityPolicy {
        boolean imeLayeringTargetMayUseIme =
                WindowManager.LayoutParams.mayUseInputMethod(imeLayeringTarget.mAttrs.flags)
                        || imeLayeringTarget.mAttrs.type == TYPE_APPLICATION_STARTING;

        if (isImeTargetMismatchOnEmbedding(imeLayeringTarget, imeInputTarget)) {
            return true;
        }
        // Do not change parent if the window hasn't requested IME.
        var inputAndLayeringTargetsDisagree = (imeInputTarget == null
                || imeLayeringTarget.mActivityRecord != imeInputTarget.getActivityRecord());
@@ -77,4 +82,27 @@ public abstract class ImeTargetVisibilityPolicy {

        return !inputTargetStale;
    }

    private static boolean isImeTargetMismatchOnEmbedding(
            @Nullable WindowState imeLayeringTarget, @Nullable InputTarget imeInputTarget) {
        if (imeInputTarget == null || imeLayeringTarget == null) {
            return false;
        }
        final ActivityRecord inputTargetRecord = imeInputTarget.getActivityRecord();
        final ActivityRecord layeringTargetRecord = imeLayeringTarget.getActivityRecord();
        final WindowState inputTargetWindow = imeInputTarget.getWindowState();
        if (inputTargetRecord == null || layeringTargetRecord == null
                || inputTargetWindow == null) {
            return false;
        }
        final boolean isImeTargetEmbedded = inputTargetRecord.isEmbedded()
                && layeringTargetRecord.isEmbedded();
        // The IME layering target is calculated by the window hierarchy in DisplayContent.
        // The layering target and input target may be different when the window hasn't started
        // input connection, WMS hasn't received the target which reported from IMMS. We basically
        // won't update IME parent for better IME transition.
        // But in activity embedding, tapping a window won't update it to the top window so the IME
        // layering target may higher than input target. Update IME parent for this case.
        return isImeTargetEmbedded && imeLayeringTarget.compareTo(inputTargetWindow) > 0;
    }
}
+31 −0
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;

import static com.android.dx.mockito.inline.extended.ExtendedMockito.any;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
@@ -613,4 +614,34 @@ public class TaskFragmentTest extends WindowTestsBase {
        assertEquals(SCREEN_ORIENTATION_UNSPECIFIED, tf1.getOrientation(SCREEN_ORIENTATION_UNSET));
        assertEquals(SCREEN_ORIENTATION_UNSPECIFIED, task.getOrientation(SCREEN_ORIENTATION_UNSET));
    }

    @Test
    public void testUpdateImeParentForActivityEmbedding() {
        // Setup two activities in ActivityEmbedding.
        final Task task = createTask(mDisplayContent);
        final TaskFragment tf0 = new TaskFragmentBuilder(mAtm)
                .setParentTask(task)
                .createActivityCount(1)
                .setOrganizer(mOrganizer)
                .setFragmentToken(new Binder())
                .build();
        final TaskFragment tf1 = new TaskFragmentBuilder(mAtm)
                .setParentTask(task)
                .createActivityCount(1)
                .setOrganizer(mOrganizer)
                .setFragmentToken(new Binder())
                .build();
        final ActivityRecord activity0 = tf0.getTopMostActivity();
        final ActivityRecord activity1 = tf1.getTopMostActivity();
        final WindowState win0 = createWindow(null, TYPE_BASE_APPLICATION, activity0, "win0");
        final WindowState win1 = createWindow(null, TYPE_BASE_APPLICATION, activity1, "win1");
        doReturn(false).when(mDisplayContent).shouldImeAttachedToApp();

        mDisplayContent.setImeInputTarget(win0);
        mDisplayContent.setImeLayeringTarget(win1);

        // The ImeParent should be the display.
        assertEquals(mDisplayContent.getImeContainer().getParent().getSurfaceControl(),
                mDisplayContent.computeImeParent());
    }
}