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

Commit faaa2cd9 authored by Yohei Yukawa's avatar Yohei Yukawa
Browse files

Restore the legacy protocol between IMMS and KeyboardLayoutManager

This is a follow up CL to my previous CL [1], which hooked up per-user
call flows in IMMS including the following methods.

 * setInputMethodLocked()
 * setSelectedInputMethodAndSubtypeLocked()

Let's see what went wrong.

InputManagerInternal has the following method so that IMMS can keep
notifying about what is the latest InptuMethodSubtype for each user.

  void onInputMethodSubtypeChangedForKeyboardLayoutMapping(
      @UserIdInt int userId,
      @Nullable InputMethodSubtypeHandle subtypeHandle,
      @Nullable InputMethodSubtype subtype)

Before my CL [1], IMMS had invoked the above method in two cases.

 A. when the current IME's subtype is updated
 B. when the current IME is switched from another user

It turns out that KeyboardLayoutManager has relied on the above
behavior, and it is not yet compatible with concurrent multi-user.

As a short term solution, with this CL both A and B are emulated in
the InputMethodManagerService side.

Longer term solutioins are going to be discussed at Bug 357663774.

 [1]: I9d4615e6da979204c21555e040a687163c1460ab
      fbeeb934

Fix: 356879517
Test: manually verified
Flag: EXEMPT bug fix
Change-Id: Iac268d3da463904a058ce44e403ca1cae691eedf
parent fc53eaec
Loading
Loading
Loading
Loading
+22 −0
Original line number Diff line number Diff line
@@ -1355,6 +1355,17 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
        }
        updateFromSettingsLocked(true, newUserId);

        // Special workaround for b/356879517.
        // KeyboardLayoutManager still expects onInputMethodSubtypeChangedForKeyboardLayoutMapping
        // to be called back upon IME user switching, while we are actively deprecating the concept
        // of "current IME user" at b/350386877.
        // TODO(b/356879517): Come up with a way to avoid this special handling.
        if (newUserData.mSubtypeForKeyboardLayoutMapping != null) {
            final var subtypeHandleAndSubtype = newUserData.mSubtypeForKeyboardLayoutMapping;
            mInputManagerInternal.onInputMethodSubtypeChangedForKeyboardLayoutMapping(
                    newUserId, subtypeHandleAndSubtype.first, subtypeHandleAndSubtype.second);
        }

        if (initialUserSwitch) {
            InputMethodUtils.setNonSelectedSystemImesDisabledUntilUsed(
                    getPackageManagerForUser(mContext, newUserId),
@@ -2938,6 +2949,17 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
                        ? subtype : null;
        final InputMethodSubtypeHandle newSubtypeHandle = normalizedSubtype != null
                ? InputMethodSubtypeHandle.of(imi, normalizedSubtype) : null;

        final var userData = getUserData(userId);

        // A workaround for b/356879517. KeyboardLayoutManager has relied on an implementation
        // detail that IMMS triggers this callback only for the current IME user.
        // TODO(b/357663774): Figure out how to better handle this scenario.
        userData.mSubtypeForKeyboardLayoutMapping =
                Pair.create(newSubtypeHandle, normalizedSubtype);
        if (userId != mCurrentUserId) {
            return;
        }
        mInputManagerInternal.onInputMethodSubtypeChangedForKeyboardLayoutMapping(
                userId, newSubtypeHandle, normalizedSubtype);
    }
+13 −0
Original line number Diff line number Diff line
@@ -19,14 +19,17 @@ package com.android.server.inputmethod;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.util.Pair;
import android.util.SparseArray;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.ImeTracker;
import android.view.inputmethod.InputMethodSubtype;
import android.window.ImeOnBackInvokedDispatcher;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.inputmethod.IRemoteAccessibilityInputConnection;
import com.android.internal.inputmethod.IRemoteInputConnection;
import com.android.internal.inputmethod.InputMethodSubtypeHandle;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -148,6 +151,16 @@ final class UserData {
    @NonNull
    String mLastEnabledInputMethodsStr = "";

    /**
     * A temporary solution to Bug 356879517, where we need to emulate the previous single-user mode
     * behavior for KeyboardLayoutManager.
     *
     * <p>TODO(b/357663774): Remove this workaround</p>
     */
    @GuardedBy("ImfLock.class")
    @Nullable
    Pair<InputMethodSubtypeHandle, InputMethodSubtype> mSubtypeForKeyboardLayoutMapping;

    /**
     * {@code true} when the IME is responsible for drawing the navigation bar and its buttons.
     */