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

Commit c271045a authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Use main display assigned to visible background user as fallback display for IME" into main

parents 2ba00c34 26155644
Loading
Loading
Loading
Loading
+21 −3
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@ import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.os.Binder;
import android.os.IBinder;
@@ -58,6 +59,7 @@ import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.inputmethod.SoftInputShowHideReason;
import com.android.server.LocalServices;
import com.android.server.pm.UserManagerInternal;
import com.android.server.wm.WindowManagerInternal;

import java.io.PrintWriter;
@@ -78,6 +80,7 @@ public final class ImeVisibilityStateComputer {
    private final int mUserId;

    private final InputMethodManagerService mService;
    private final UserManagerInternal mUserManagerInternal;
    private final WindowManagerInternal mWindowManagerInternal;

    final InputMethodManagerService.ImeDisplayValidator mImeDisplayValidator;
@@ -188,6 +191,7 @@ public final class ImeVisibilityStateComputer {
    public ImeVisibilityStateComputer(@NonNull InputMethodManagerService service,
            @UserIdInt int userId) {
        this(service,
                LocalServices.getService(UserManagerInternal.class),
                LocalServices.getService(WindowManagerInternal.class),
                LocalServices.getService(WindowManagerInternal.class)::getDisplayImePolicy,
                new ImeVisibilityPolicy(), userId);
@@ -196,11 +200,14 @@ public final class ImeVisibilityStateComputer {
    @VisibleForTesting
    public ImeVisibilityStateComputer(@NonNull InputMethodManagerService service,
            @NonNull Injector injector) {
        this(service, injector.getWmService(), injector.getImeValidator(),
                new ImeVisibilityPolicy(), injector.getUserId());
        this(service, injector.getUserManagerService(), injector.getWmService(),
                injector.getImeValidator(), new ImeVisibilityPolicy(), injector.getUserId());
    }

    interface Injector {
        @NonNull
        UserManagerInternal getUserManagerService();

        @NonNull
        WindowManagerInternal getWmService();

@@ -212,11 +219,13 @@ public final class ImeVisibilityStateComputer {
    }

    private ImeVisibilityStateComputer(InputMethodManagerService service,
            UserManagerInternal userManagerInternal,
            WindowManagerInternal wmService,
            InputMethodManagerService.ImeDisplayValidator imeDisplayValidator,
            ImeVisibilityPolicy imePolicy, @UserIdInt int userId) {
        mUserId = userId;
        mService = service;
        mUserManagerInternal = userManagerInternal;
        mWindowManagerInternal = wmService;
        mImeDisplayValidator = imeDisplayValidator;
        mPolicy = imePolicy;
@@ -337,7 +346,16 @@ public final class ImeVisibilityStateComputer {

    @GuardedBy("ImfLock.class")
    int computeImeDisplayId(@NonNull ImeTargetWindowState state, int displayId) {
        final int displayToShowIme = computeImeDisplayIdForTarget(displayId, mImeDisplayValidator);
        final int displayToShowIme;
        final PackageManager pm = mService.mContext.getPackageManager();
        if (pm.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)
                && mUserManagerInternal.isVisibleBackgroundFullUser(mUserId)
                && Flags.fallbackDisplayForSecondaryUserOnSecondaryDisplay()) {
            displayToShowIme = mService.computeImeDisplayIdForVisibleBackgroundUserOnAutomotive(
                    displayId, mUserId, mImeDisplayValidator);
        } else {
            displayToShowIme = computeImeDisplayIdForTarget(displayId, mImeDisplayValidator);
        }
        state.setImeDisplayId(displayToShowIme);
        final boolean imeHiddenByPolicy = displayToShowIme == INVALID_DISPLAY;
        mPolicy.setImeHiddenByDisplayPolicy(imeHiddenByPolicy);
+27 −4
Original line number Diff line number Diff line
@@ -2345,8 +2345,32 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
     * {@link WindowManager#DISPLAY_IME_POLICY_HIDE}
     */
    static int computeImeDisplayIdForTarget(int displayId, @NonNull ImeDisplayValidator checker) {
        if (displayId == DEFAULT_DISPLAY || displayId == INVALID_DISPLAY) {
            return FALLBACK_DISPLAY_ID;
        return computeImeDisplayIdForTargetInner(displayId, checker, FALLBACK_DISPLAY_ID);
    }

    /**
     * Find the display where the IME should be shown for a visible background user.
     *
     * @param displayId the ID of the display where the IME client target is
     * @param userId the ID of the user who own the IME
     * @param checker   instance of {@link ImeDisplayValidator} which is used for
     *                  checking display config to adjust the final target display
     * @return the ID of the display where the IME should be shown or
     * {@link android.view.Display#INVALID_DISPLAY} if the display has an ImePolicy of
     * {@link WindowManager#DISPLAY_IME_POLICY_HIDE}
     */
    int computeImeDisplayIdForVisibleBackgroundUserOnAutomotive(
            int displayId, @UserIdInt int userId, @NonNull ImeDisplayValidator checker) {
        // Visible background user can be assigned to a secondary display, not the default display.
        // The main display assigned to the user will be used as the fallback display.
        final int mainDisplayId = mUserManagerInternal.getMainDisplayAssignedToUser(userId);
        return computeImeDisplayIdForTargetInner(displayId, checker, mainDisplayId);
    }

    private static int computeImeDisplayIdForTargetInner(
            int displayId, @NonNull ImeDisplayValidator checker, int fallbackDisplayId) {
        if (displayId == fallbackDisplayId || displayId == INVALID_DISPLAY) {
            return fallbackDisplayId;
        }

        // Show IME window on fallback display when the display doesn't support system decorations
@@ -2356,9 +2380,8 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
            return displayId;
        } else if (result == DISPLAY_IME_POLICY_HIDE) {
            return INVALID_DISPLAY;
        } else {
            return FALLBACK_DISPLAY_ID;
        }
        return fallbackDisplayId;
    }

    @GuardedBy("ImfLock.class")
+6 −0
Original line number Diff line number Diff line
@@ -50,6 +50,7 @@ import android.view.inputmethod.InputMethodManager;
import androidx.test.ext.junit.runners.AndroidJUnit4;

import com.android.internal.annotations.GuardedBy;
import com.android.server.pm.UserManagerInternal;
import com.android.server.wm.WindowManagerInternal;

import org.junit.Before;
@@ -73,6 +74,11 @@ public class ImeVisibilityStateComputerTest extends InputMethodManagerServiceTes
    public void setUp() throws RemoteException {
        super.setUp();
        ImeVisibilityStateComputer.Injector injector = new ImeVisibilityStateComputer.Injector() {
            @Override
            public UserManagerInternal getUserManagerService() {
                return mMockUserManagerInternal;
            }

            @Override
            public WindowManagerInternal getWmService() {
                return mMockWindowManagerInternal;
+10 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import android.view.WindowManager;

import androidx.annotation.NonNull;

import com.android.server.pm.UserManagerInternal;
import com.android.server.wm.WindowManagerInternal;

import org.junit.After;
@@ -48,6 +49,9 @@ public final class UserDataRepositoryTest {
    @Mock
    private InputMethodManagerService mMockInputMethodManagerService;

    @Mock
    private UserManagerInternal mMockUserManagerInternal;

    @Mock
    private WindowManagerInternal mMockWindowManagerInternal;

@@ -68,6 +72,12 @@ public final class UserDataRepositoryTest {
        mVisibilityStateComputerFactory = userId -> new ImeVisibilityStateComputer(
                mMockInputMethodManagerService,
                new ImeVisibilityStateComputer.Injector() {
                    @NonNull
                    @Override
                    public UserManagerInternal getUserManagerService() {
                        return mMockUserManagerInternal;
                    }

                    @NonNull
                    @Override
                    public WindowManagerInternal getWmService() {