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

Commit f995a92f authored by Ming-Shin Lu's avatar Ming-Shin Lu Committed by Android (Google) Code Review
Browse files

Merge changes Ib00124b3,Ie850a67c

* changes:
  Refine WindowManagerInternal#getDisplayImePolicy
  Reduce potential lock contention during start input
parents 12ac577c 2c174780
Loading
Loading
Loading
Loading
+41 −35
Original line number Diff line number Diff line
@@ -2347,11 +2347,20 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
                curId, getSequenceNumberLocked(), suppressesSpellChecker);
    }

    /**
     * Called by {@link #startInputOrWindowGainedFocusInternalLocked} to bind/unbind/attach the
     * selected InputMethod to the given focused IME client.
     *
     * Note that this should be called after validating if the IME client has IME focus.
     *
     * @see WindowManagerInternal#hasInputMethodClientFocus(IBinder, int, int, int)
     */
    @GuardedBy("ImfLock.class")
    @NonNull
    InputBindResult startInputUncheckedLocked(@NonNull ClientState cs, IInputContext inputContext,
            @NonNull EditorInfo attribute, @StartInputFlags int startInputFlags,
            @StartInputReason int startInputReason, int unverifiedTargetSdkVersion) {
    private InputBindResult startInputUncheckedLocked(@NonNull ClientState cs,
            IInputContext inputContext, @NonNull EditorInfo attribute,
            @StartInputFlags int startInputFlags, @StartInputReason int startInputReason,
            int unverifiedTargetSdkVersion) {
        // If no method is currently selected, do nothing.
        String selectedMethodId = getSelectedMethodIdLocked();
        if (selectedMethodId == null) {
@@ -2373,10 +2382,6 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
            return InputBindResult.INVALID_PACKAGE_NAME;
        }

        if (!mWindowManagerInternal.isUidAllowedOnDisplay(cs.selfReportedDisplayId, cs.uid)) {
            // Wait, the client no longer has access to the display.
            return InputBindResult.INVALID_DISPLAY_ID;
        }
        // Compute the final shown display ID with validated cs.selfReportedDisplayId for this
        // session & other conditions.
        mDisplayIdToShowIme = computeImeDisplayIdForTarget(cs.selfReportedDisplayId,
@@ -3200,14 +3205,11 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
                    // be made before input is started in it.
                    final ClientState cs = mClients.get(client.asBinder());
                    if (cs == null) {
                        throw new IllegalArgumentException(
                                "unknown client " + client.asBinder());
                        throw new IllegalArgumentException("unknown client " + client.asBinder());
                    }
                    if (!mWindowManagerInternal.isInputMethodClientFocus(cs.uid, cs.pid,
                            cs.selfReportedDisplayId)) {
                    if (!isImeClientFocused(windowToken, cs)) {
                        if (DEBUG) {
                            Slog.w(TAG,
                                    "Ignoring hideSoftInput of uid " + uid + ": " + client);
                            Slog.w(TAG, "Ignoring hideSoftInput of uid " + uid + ": " + client);
                        }
                        return false;
                    }
@@ -3277,6 +3279,12 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
        return res;
    }

    private boolean isImeClientFocused(IBinder windowToken, ClientState cs) {
        final int imeClientFocus = mWindowManagerInternal.hasInputMethodClientFocus(
                windowToken, cs.uid, cs.pid, cs.selfReportedDisplayId);
        return imeClientFocus == WindowManagerInternal.ImeClientFocusResult.HAS_IME_FOCUS;
    }

    @NonNull
    @Override
    public InputBindResult startInputOrWindowGainedFocus(
@@ -3370,21 +3378,18 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
                    + " unverifiedTargetSdkVersion=" + unverifiedTargetSdkVersion);
        }

        final int windowDisplayId = mWindowManagerInternal.getDisplayIdForWindow(windowToken);

        final ClientState cs = mClients.get(client.asBinder());
        if (cs == null) {
            throw new IllegalArgumentException("unknown client " + client.asBinder());
        }
        if (cs.selfReportedDisplayId != windowDisplayId) {
            Slog.e(TAG, "startInputOrWindowGainedFocusInternal: display ID mismatch."
                    + " from client:" + cs.selfReportedDisplayId
                    + " from window:" + windowDisplayId);
            return InputBindResult.DISPLAY_ID_MISMATCH;
        }

        if (!mWindowManagerInternal.isInputMethodClientFocus(cs.uid, cs.pid,
                cs.selfReportedDisplayId)) {
        final int imeClientFocus = mWindowManagerInternal.hasInputMethodClientFocus(
                windowToken, cs.uid, cs.pid, cs.selfReportedDisplayId);
        switch (imeClientFocus) {
            case WindowManagerInternal.ImeClientFocusResult.DISPLAY_ID_MISMATCH:
                Slog.e(TAG, "startInputOrWindowGainedFocusInternal: display ID mismatch.");
                return InputBindResult.DISPLAY_ID_MISMATCH;
            case WindowManagerInternal.ImeClientFocusResult.NOT_IME_TARGET_WINDOW:
                // Check with the window manager to make sure this client actually
                // has a window with focus.  If not, reject.  This is thread safe
                // because if the focus changes some time before or after, the
@@ -3395,6 +3400,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
                            + " (uid=" + cs.uid + " pid=" + cs.pid + ")");
                }
                return InputBindResult.NOT_IME_TARGET_WINDOW;
            case WindowManagerInternal.ImeClientFocusResult.INVALID_DISPLAY_ID:
                return InputBindResult.INVALID_DISPLAY_ID;
        }

        if (mUserSwitchHandlerTask != null) {
@@ -3622,8 +3629,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
            if (cs == null) {
                throw new IllegalArgumentException("unknown client " + client.asBinder());
            }
            if (!mWindowManagerInternal.isInputMethodClientFocus(cs.uid, cs.pid,
                    cs.selfReportedDisplayId)) {
            if (!isImeClientFocused(mCurFocusedWindow, cs)) {
                Slog.w(TAG, String.format("Ignoring %s of uid %d : %s", methodName, uid, client));
                return false;
            }
+4 −0
Original line number Diff line number Diff line
@@ -2001,6 +2001,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
    }

    void configureDisplayPolicy() {
        mRootWindowContainer.updateDisplayImePolicyCache();
        mDisplayPolicy.updateConfigurationAndScreenSizeDependentBehaviors();
        mDisplayRotation.configure(mBaseDisplayWidth, mBaseDisplayHeight);
    }
@@ -3939,6 +3940,9 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
        }
    }

    // IMPORTANT: When introducing new dependencies in this method, make sure that
    // changes to those result in RootWindowContainer.updateDisplayImePolicyCache()
    // being called.
    @DisplayImePolicy int getImePolicy() {
        if (!isTrusted()) {
            return DISPLAY_IME_POLICY_FALLBACK_DISPLAY;
+8 −0
Original line number Diff line number Diff line
@@ -165,6 +165,7 @@ import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Set;
@@ -2530,9 +2531,16 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
            // Drop any cached DisplayInfos associated with this display id - the values are now
            // out of date given this display changed event.
            mWmService.mPossibleDisplayInfoMapper.removePossibleDisplayInfos(displayId);
            updateDisplayImePolicyCache();
        }
    }

    void updateDisplayImePolicyCache() {
        ArrayMap<Integer, Integer> displayImePolicyMap = new ArrayMap<>();
        forAllDisplays(dc -> displayImePolicyMap.put(dc.getDisplayId(), dc.getImePolicy()));
        mWmService.mDisplayImePolicyCache = Collections.unmodifiableMap(displayImePolicyMap);
    }

    /** Update lists of UIDs that are present on displays and have access to them. */
    void updateUIDsPresentOnDisplay() {
        mDisplayAccessUIDs.clear();
+21 −1
Original line number Diff line number Diff line
@@ -16,6 +16,9 @@

package com.android.server.wm;

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

import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.ClipData;
@@ -40,6 +43,7 @@ import com.android.internal.policy.KeyInterceptionInfo;
import com.android.server.input.InputManagerService;
import com.android.server.policy.WindowManagerPolicy;

import java.lang.annotation.Retention;
import java.util.List;
import java.util.Set;

@@ -609,6 +613,7 @@ public abstract class WindowManagerInternal {
    /**
     * Checks whether the specified IME client has IME focus or not.
     *
     * @param windowToken The window token of the input method client
     * @param uid UID of the process to be queried
     * @param pid PID of the process to be queried
     * @param displayId Display ID reported from the client. Note that this method also verifies
@@ -616,7 +621,22 @@ public abstract class WindowManagerInternal {
     * @return {@code true} if the IME client specified with {@code uid}, {@code pid}, and
     *         {@code displayId} has IME focus
     */
    public abstract boolean isInputMethodClientFocus(int uid, int pid, int displayId);
    public abstract @ImeClientFocusResult int hasInputMethodClientFocus(IBinder windowToken,
            int uid, int pid, int displayId);

    @Retention(SOURCE)
    @IntDef({
            ImeClientFocusResult.HAS_IME_FOCUS,
            ImeClientFocusResult.NOT_IME_TARGET_WINDOW,
            ImeClientFocusResult.DISPLAY_ID_MISMATCH,
            ImeClientFocusResult.INVALID_DISPLAY_ID
    })
    public @interface ImeClientFocusResult {
        int HAS_IME_FOCUS = 0;
        int NOT_IME_TARGET_WINDOW = -1;
        int DISPLAY_ID_MISMATCH = -2;
        int INVALID_DISPLAY_ID = -3;
    }

    /**
     * Checks whether the given {@code uid} is allowed to use the given {@code displayId} or not.
+38 −19
Original line number Diff line number Diff line
@@ -586,6 +586,13 @@ public class WindowManagerService extends IWindowManager.Stub
     */
    final ArrayList<WindowState> mResizingWindows = new ArrayList<>();

    /**
     * Mapping of displayId to {@link DisplayImePolicy}.
     * Note that this can be accessed without holding the lock.
     */
    volatile Map<Integer, Integer> mDisplayImePolicyCache = Collections.unmodifiableMap(
            new ArrayMap<>());

    /**
     * Windows whose surface should be destroyed.
     */
@@ -6897,6 +6904,7 @@ public class WindowManagerService extends IWindowManager.Stub
    void setForceDesktopModeOnExternalDisplays(boolean forceDesktopModeOnExternalDisplays) {
        synchronized (mGlobalLock) {
            mForceDesktopModeOnExternalDisplays = forceDesktopModeOnExternalDisplays;
            mRoot.updateDisplayImePolicyCache();
        }
    }

@@ -7328,16 +7336,14 @@ public class WindowManagerService extends IWindowManager.Stub
        if (!checkCallingPermission(INTERNAL_SYSTEM_WINDOW, "getDisplayImePolicy()")) {
            throw new SecurityException("Requires INTERNAL_SYSTEM_WINDOW permission");
        }
        final DisplayContent dc = mRoot.getDisplayContent(displayId);
        if (dc == null) {
        final Map<Integer, Integer> displayImePolicyCache = mDisplayImePolicyCache;
        if (!displayImePolicyCache.containsKey(displayId)) {
            ProtoLog.w(WM_ERROR,
                    "Attempted to get IME policy of a display that does not exist: %d",
                    displayId);
            return DISPLAY_IME_POLICY_FALLBACK_DISPLAY;
        }
        synchronized (mGlobalLock) {
            return dc.getImePolicy();
        }
        return displayImePolicyCache.get(displayId);
    }

    @Override
@@ -7686,19 +7692,32 @@ public class WindowManagerService extends IWindowManager.Stub
        }

        @Override
        public boolean isInputMethodClientFocus(int uid, int pid, int displayId) {
        public @ImeClientFocusResult int hasInputMethodClientFocus(IBinder windowToken,
                int uid, int pid, int displayId) {
            if (displayId == Display.INVALID_DISPLAY) {
                return false;
                return ImeClientFocusResult.INVALID_DISPLAY_ID;
            }
            synchronized (mGlobalLock) {
                final DisplayContent displayContent = mRoot.getTopFocusedDisplayContent();
                final WindowState window = mWindowMap.get(windowToken);
                if (window == null) {
                    return ImeClientFocusResult.NOT_IME_TARGET_WINDOW;
                }
                final int tokenDisplayId = window.getDisplayContent().getDisplayId();
                if (tokenDisplayId != displayId) {
                    Slog.e(TAG, "isInputMethodClientFocus: display ID mismatch."
                            + " from client: " + displayId
                            + " from window: " + tokenDisplayId);
                    return ImeClientFocusResult.DISPLAY_ID_MISMATCH;
                }
                if (displayContent == null
                        || displayContent.getDisplayId() != displayId
                        || !displayContent.hasAccess(uid)) {
                    return false;
                    return ImeClientFocusResult.INVALID_DISPLAY_ID;
                }

                if (displayContent.isInputMethodClientFocus(uid, pid)) {
                    return true;
                    return ImeClientFocusResult.HAS_IME_FOCUS;
                }
                // Okay, how about this...  what is the current focus?
                // It seems in some cases we may not have moved the IM
@@ -7711,10 +7730,11 @@ public class WindowManagerService extends IWindowManager.Stub
                final WindowState currentFocus = displayContent.mCurrentFocus;
                if (currentFocus != null && currentFocus.mSession.mUid == uid
                        && currentFocus.mSession.mPid == pid) {
                    return currentFocus.canBeImeTarget();
                    return currentFocus.canBeImeTarget() ? ImeClientFocusResult.HAS_IME_FOCUS
                            : ImeClientFocusResult.NOT_IME_TARGET_WINDOW;
                }
            }
            return false;
            return ImeClientFocusResult.NOT_IME_TARGET_WINDOW;
        }

        @Override
@@ -7813,10 +7833,8 @@ public class WindowManagerService extends IWindowManager.Stub

        @Override
        public @DisplayImePolicy int getDisplayImePolicy(int displayId) {
            synchronized (mGlobalLock) {
            return WindowManagerService.this.getDisplayImePolicy(displayId);
        }
        }

        @Override
        public void addNonHighRefreshRatePackage(@NonNull String packageName) {
@@ -8710,21 +8728,22 @@ public class WindowManagerService extends IWindowManager.Stub
    }

    boolean shouldRestoreImeVisibility(IBinder imeTargetWindowToken) {
        final Task imeTargetWindowTask;
        synchronized (mGlobalLock) {
            final WindowState imeTargetWindow = mWindowMap.get(imeTargetWindowToken);
            if (imeTargetWindow == null) {
                return false;
            }
            final Task imeTargetWindowTask = imeTargetWindow.getTask();
            imeTargetWindowTask = imeTargetWindow.getTask();
            if (imeTargetWindowTask == null) {
                return false;
            }
        }
        final TaskSnapshot snapshot = getTaskSnapshot(imeTargetWindowTask.mTaskId,
                imeTargetWindowTask.mUserId, false /* isLowResolution */,
                false /* restoreFromDisk */);
        return snapshot != null && snapshot.hasImeSurface();
    }
    }

    @Override
    public int getImeDisplayId() {