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

Commit c5addda3 authored by Nikolas Havrikov's avatar Nikolas Havrikov Committed by Android (Google) Code Review
Browse files

Merge changes I98459c4a,I6ebb2df2,I7d01b25c,I87319101,I5c29f880, ...

* changes:
  Store displayIdToShowIme in an IMMS field
  Remove unused suggestion span cache
  Remove unused method isImeVisible
  Extract and move unbinding visibly to controller
  Extract and move binding visibly to controller
  Move TIME_TO_RECONNECT to binding controller
  Move clear current method caller into controller
parents a99cfec3 5a2b8d3f
Loading
Loading
Loading
Loading
+61 −15
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ import android.os.Trace;
import android.os.UserHandle;
import android.provider.Settings;
import android.util.ArrayMap;
import android.util.EventLog;
import android.util.Slog;
import android.view.IWindowManager;
import android.view.WindowManager;
@@ -49,6 +50,7 @@ import com.android.internal.annotations.GuardedBy;
import com.android.internal.inputmethod.InputBindResult;
import com.android.internal.inputmethod.UnbindReason;
import com.android.internal.view.IInputMethod;
import com.android.server.EventLogTags;
import com.android.server.wm.WindowManagerInternal;

/**
@@ -58,6 +60,9 @@ final class InputMethodBindingController {
    static final boolean DEBUG = false;
    private static final String TAG = InputMethodBindingController.class.getSimpleName();

    /** Time in milliseconds that the IME service has to bind before it is reconnected. */
    static final long TIME_TO_RECONNECT = 3 * 1000;

    @NonNull private final InputMethodManagerService mService;
    @NonNull private final Context mContext;
    @NonNull private final ArrayMap<String, InputMethodInfo> mMethodMap;
@@ -239,7 +244,7 @@ final class InputMethodBindingController {
    }

    /**
     * Indicates whether {@link #getVisibleConnection} is currently in use.
     * Indicates whether {@link #mVisibleConnection} is currently in use.
     */
    boolean isVisibleBound() {
        return mVisibleBound;
@@ -248,11 +253,6 @@ final class InputMethodBindingController {
    /**
     * Used to bring IME service up to visible adjustment while it is being shown.
     */
    @NonNull
    ServiceConnection getVisibleConnection() {
        return mVisibleConnection;
    }

    private final ServiceConnection mVisibleConnection = new ServiceConnection() {
        @Override public void onBindingDied(ComponentName name) {
            synchronized (mMethodMap) {
@@ -334,7 +334,7 @@ final class InputMethodBindingController {
                    // We consider this to be a new bind attempt, since the system
                    // should now try to restart the service for us.
                    mLastBindTime = SystemClock.uptimeMillis();
                    mService.clearClientSessionsLocked();
                    clearCurMethodAndSessionsLocked();
                    mService.clearInputShowRequestLocked();
                    mService.unbindCurrentClientLocked(UnbindReason.DISCONNECT_IME);
                }
@@ -358,11 +358,12 @@ final class InputMethodBindingController {
        }

        mCurId = null;
        mService.clearClientSessionsLocked();
        clearCurMethodAndSessionsLocked();
    }

    @GuardedBy("mMethodMap")
    void clearCurMethodLocked() {
    private void clearCurMethodAndSessionsLocked() {
        mService.clearClientSessionsLocked();
        mCurMethod = null;
        mCurMethodUid = Process.INVALID_UID;
    }
@@ -382,7 +383,7 @@ final class InputMethodBindingController {

    @GuardedBy("mMethodMap")
    @NonNull
    InputBindResult bindCurrentMethodLocked(int displayIdToShowIme) {
    InputBindResult bindCurrentMethodLocked() {
        InputMethodInfo info = mMethodMap.get(mSelectedMethodId);
        if (info == null) {
            throw new IllegalArgumentException("Unknown id: " + mSelectedMethodId);
@@ -394,7 +395,7 @@ final class InputMethodBindingController {
            mCurId = info.getId();
            mLastBindTime = SystemClock.uptimeMillis();

            addFreshWindowTokenLocked(displayIdToShowIme);
            addFreshWindowTokenLocked();
            return new InputBindResult(
                    InputBindResult.ResultCode.SUCCESS_WAITING_IME_BINDING,
                    null, null, mCurId, mCurSeq, false);
@@ -419,7 +420,8 @@ final class InputMethodBindingController {
    }

    @GuardedBy("mMethodMap")
    private void addFreshWindowTokenLocked(int displayIdToShowIme) {
    private void addFreshWindowTokenLocked() {
        int displayIdToShowIme = mService.getDisplayIdToShowIme();
        mCurToken = new Binder();

        mService.setCurTokenDisplayId(displayIdToShowIme);
@@ -438,7 +440,7 @@ final class InputMethodBindingController {
    }

    @GuardedBy("mMethodMap")
    void unbindMainConnectionLocked() {
    private void unbindMainConnectionLocked() {
        mContext.unbindService(mMainConnection);
        mHasConnection = false;
    }
@@ -460,17 +462,61 @@ final class InputMethodBindingController {
    }

    @GuardedBy("mMethodMap")
    boolean bindCurrentInputMethodServiceVisibleConnectionLocked() {
    private boolean bindCurrentInputMethodServiceVisibleConnectionLocked() {
        mVisibleBound = bindCurrentInputMethodServiceLocked(mVisibleConnection,
                IME_VISIBLE_BIND_FLAGS);
        return mVisibleBound;
    }

    @GuardedBy("mMethodMap")
    boolean bindCurrentInputMethodServiceMainConnectionLocked() {
    private boolean bindCurrentInputMethodServiceMainConnectionLocked() {
        mHasConnection = bindCurrentInputMethodServiceLocked(mMainConnection,
                mImeConnectionBindFlags);
        return mHasConnection;
    }

    /**
     * Bind the IME so that it can be shown.
     *
     * <p>
     * Performs a rebind if no binding is achieved in {@link #TIME_TO_RECONNECT} milliseconds.
     */
    @GuardedBy("mMethodMap")
    void setCurrentMethodVisibleLocked() {
        if (mCurMethod != null) {
            if (DEBUG) Slog.d(TAG, "setCurrentMethodVisibleLocked: mCurToken=" + mCurToken);
            if (mHasConnection && !mVisibleBound) {
                bindCurrentInputMethodServiceVisibleConnectionLocked();
            }
            return;
        }

        long bindingDuration = SystemClock.uptimeMillis() - mLastBindTime;
        if (mHasConnection && bindingDuration >= TIME_TO_RECONNECT) {
            // The client has asked to have the input method shown, but
            // we have been sitting here too long with a connection to the
            // service and no interface received, so let's disconnect/connect
            // to try to prod things along.
            EventLog.writeEvent(EventLogTags.IMF_FORCE_RECONNECT_IME, getSelectedMethodId(),
                    bindingDuration, 1);
            Slog.w(TAG, "Force disconnect/connect to the IME in setCurrentMethodVisibleLocked()");
            unbindMainConnectionLocked();
            bindCurrentInputMethodServiceMainConnectionLocked();
        } else {
            if (DEBUG) {
                Slog.d(TAG, "Can't show input: connection = " + mHasConnection + ", time = "
                        + (TIME_TO_RECONNECT - bindingDuration));
            }
        }
    }

    /**
     * Remove the binding needed for the IME to be shown.
     */
    @GuardedBy("mMethodMap")
    void setCurrentMethodNotVisibleLocked() {
        if (mVisibleBound) {
            unbindVisibleConnectionLocked();
        }
    }
}
+23 −54
Original line number Diff line number Diff line
@@ -49,6 +49,8 @@ import static android.view.Display.INVALID_DISPLAY;
import static android.view.WindowManager.DISPLAY_IME_POLICY_HIDE;
import static android.view.WindowManager.DISPLAY_IME_POLICY_LOCAL;

import static com.android.server.inputmethod.InputMethodBindingController.TIME_TO_RECONNECT;

import static java.lang.annotation.RetentionPolicy.SOURCE;

import android.Manifest;
@@ -111,12 +113,10 @@ import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
import android.text.TextUtils;
import android.text.style.SuggestionSpan;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.EventLog;
import android.util.IndentingPrintWriter;
import android.util.LruCache;
import android.util.Pair;
import android.util.PrintWriterPrinter;
import android.util.Printer;
@@ -250,10 +250,6 @@ public class InputMethodManagerService extends IInputMethodManager.Stub

    static final int MSG_NOTIFY_IME_UID_TO_AUDIO_SERVICE = 7000;

    static final long TIME_TO_RECONNECT = 3 * 1000;

    static final int SECURE_SUGGESTION_SPANS_MAX_SIZE = 20;

    private static final int NOT_A_SUBTYPE_ID = InputMethodUtils.NOT_A_SUBTYPE_ID;
    private static final String TAG_TRY_SUPPRESSING_IME_SWITCHER = "TrySuppressingImeSwitcher";
    private static final String HANDLER_THREAD_NAME = "android.imms";
@@ -301,8 +297,6 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
    // lock for this class.
    final ArrayList<InputMethodInfo> mMethodList = new ArrayList<>();
    final ArrayMap<String, InputMethodInfo> mMethodMap = new ArrayMap<>();
    private final LruCache<SuggestionSpan, InputMethodInfo> mSecureSuggestionSpans =
            new LruCache<>(SECURE_SUGGESTION_SPANS_MAX_SIZE);
    final InputMethodSubtypeSwitchingController mSwitchingController;

    /**
@@ -312,13 +306,16 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
    private int mMethodMapUpdateCount = 0;

    /**
     * Indicates whether {@link InputMethodBindingController#getVisibleConnection} is currently
     * in use.
     * The display id for which the latest startInput was called.
     */
    private boolean isVisibleBound() {
        return mBindingController.isVisibleBound();
    @GuardedBy("mMethodMap")
    int getDisplayIdToShowIme() {
        return mDisplayIdToShowIme;
    }

    @GuardedBy("mMethodMap")
    private int mDisplayIdToShowIme = INVALID_DISPLAY;

    // Ongoing notification
    private NotificationManager mNotificationManager;
    KeyguardManager mKeyguardManager;
@@ -2354,10 +2351,10 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
        }
        // Compute the final shown display ID with validated cs.selfReportedDisplayId for this
        // session & other conditions.
        final int displayIdToShowIme = computeImeDisplayIdForTarget(cs.selfReportedDisplayId,
        mDisplayIdToShowIme = computeImeDisplayIdForTarget(cs.selfReportedDisplayId,
                mImeDisplayValidator);

        if (displayIdToShowIme == INVALID_DISPLAY) {
        if (mDisplayIdToShowIme == INVALID_DISPLAY) {
            mImeHiddenByDisplayPolicy = true;
            hideCurrentInputLocked(mCurFocusedWindow, 0, null,
                    SoftInputShowHideReason.HIDE_DISPLAY_IME_POLICY_HIDE);
@@ -2378,7 +2375,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
        // Check if the input method is changing.
        // We expect the caller has already verified that the client is allowed to access this
        // display ID.
        if (isSelectedMethodBound(displayIdToShowIme)) {
        if (isSelectedMethodBound()) {
            if (cs.curSession != null) {
                // Fast case: if we are already connected to the input method,
                // then just return it.
@@ -2394,13 +2391,13 @@ public class InputMethodManagerService extends IInputMethodManager.Stub

        mBindingController.unbindCurrentMethodLocked();

        return mBindingController.bindCurrentMethodLocked(displayIdToShowIme);
        return mBindingController.bindCurrentMethodLocked();
    }

    private boolean isSelectedMethodBound(int displayIdToShowIme) {
    private boolean isSelectedMethodBound() {
        String curId = getCurId();
        return curId != null && curId.equals(getSelectedMethodId())
                && displayIdToShowIme == mCurTokenDisplayId;
                && mDisplayIdToShowIme == mCurTokenDisplayId;
    }

    @GuardedBy("mMethodMap")
@@ -2590,7 +2587,6 @@ public class InputMethodManagerService extends IInputMethodManager.Stub

            finishSessionLocked(mEnabledSession);
            mEnabledSession = null;
            mBindingController.clearCurMethodLocked();
            scheduleNotifyImeUidToAudioService(Process.INVALID_UID);
        }
        hideStatusBarIconLocked();
@@ -3047,42 +3043,20 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
            return false;
        }

        boolean res = false;
        IInputMethod curMethod = getCurMethod();
        if (curMethod != null) {
            if (DEBUG) Slog.d(TAG, "showCurrentInputLocked: mCurToken=" + getCurToken());
        mBindingController.setCurrentMethodVisibleLocked();
        if (getCurMethod() != null) {
            // create a placeholder token for IMS so that IMS cannot inject windows into client app.
            Binder showInputToken = new Binder();
            mShowRequestWindowMap.put(showInputToken, windowToken);
            IInputMethod curMethod = getCurMethod();
            executeOrSendMessage(curMethod, mCaller.obtainMessageIIOOO(MSG_SHOW_SOFT_INPUT,
                    getImeShowFlagsLocked(), reason, curMethod, resultReceiver,
                    showInputToken));
            mInputShown = true;
            if (hasConnection() && !isVisibleBound()) {
                mBindingController.bindCurrentInputMethodServiceVisibleConnectionLocked();
            }
            res = true;
        } else {
            long bindingDuration = SystemClock.uptimeMillis() - getLastBindTime();
            if (hasConnection() && bindingDuration >= TIME_TO_RECONNECT) {
                // The client has asked to have the input method shown, but
                // we have been sitting here too long with a connection to the
                // service and no interface received, so let's disconnect/connect
                // to try to prod things along.
                EventLog.writeEvent(EventLogTags.IMF_FORCE_RECONNECT_IME, getSelectedMethodId(),
                        bindingDuration, 1);
                Slog.w(TAG, "Force disconnect/connect to the IME in showCurrentInputLocked()");
                mBindingController.unbindMainConnectionLocked();
                mBindingController.bindCurrentInputMethodServiceMainConnectionLocked();
            } else {
                if (DEBUG) {
                    Slog.d(TAG, "Can't show input: connection = " + hasConnection() + ", time = "
                            + (TIME_TO_RECONNECT - bindingDuration));
                }
            }
            return true;
        }

        return res;
        return false;
    }

    @Override
@@ -3166,9 +3140,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
        } else {
            res = false;
        }
        if (hasConnection() && isVisibleBound()) {
            mBindingController.unbindVisibleConnectionLocked();
        }
        mBindingController.setCurrentMethodNotVisibleLocked();
        mInputShown = false;
        mShowRequested = false;
        mShowExplicitlyRequested = false;
@@ -3522,10 +3494,6 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
        return mWindowManagerInternal.shouldRestoreImeVisibility(windowToken);
    }

    private boolean isImeVisible() {
        return (mImeWindowVis & InputMethodService.IME_VISIBLE) != 0;
    }

    @GuardedBy("mMethodMap")
    private boolean canShowInputMethodPickerLocked(IInputMethodClient client) {
        // TODO(yukawa): multi-display support.
@@ -5114,7 +5082,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
                    + " client=" + mCurFocusedWindowClient);
            focusedWindowClient = mCurFocusedWindowClient;
            p.println("  mCurId=" + getCurId() + " mHaveConnection=" + hasConnection()
                    + " mBoundToMethod=" + mBoundToMethod + " mVisibleBound=" + isVisibleBound());
                    + " mBoundToMethod=" + mBoundToMethod + " mVisibleBound="
                    + mBindingController.isVisibleBound());
            p.println("  mCurToken=" + getCurToken());
            p.println("  mCurTokenDisplayId=" + mCurTokenDisplayId);
            p.println("  mCurHostInputToken=" + mCurHostInputToken);