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

Commit b7faccdc authored by Taran Singh's avatar Taran Singh Committed by Android (Google) Code Review
Browse files

Merge changes I6b8787a2,Ie4194051 into main

* changes:
  Version-gate IME show/hide async nature
  Add flag for fixing return of show/hide input
parents 782ffd0b 36aea71d
Loading
Loading
Loading
Loading
+7 −6
Original line number Diff line number Diff line
@@ -323,14 +323,14 @@ final class IInputMethodManagerGlobalInvoker {
    static boolean showSoftInput(@NonNull IInputMethodClient client, @Nullable IBinder windowToken,
            @NonNull ImeTracker.Token statsToken, @InputMethodManager.ShowFlags int flags,
            int lastClickToolType, @Nullable ResultReceiver resultReceiver,
            @SoftInputShowHideReason int reason) {
            @SoftInputShowHideReason int reason, boolean async) {
        final IInputMethodManager service = getService();
        if (service == null) {
            return false;
        }
        try {
            return service.showSoftInput(client, windowToken, statsToken, flags, lastClickToolType,
                    resultReceiver, reason);
                    resultReceiver, reason, async);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
@@ -339,14 +339,15 @@ final class IInputMethodManagerGlobalInvoker {
    @AnyThread
    static boolean hideSoftInput(@NonNull IInputMethodClient client, @Nullable IBinder windowToken,
            @NonNull ImeTracker.Token statsToken, @InputMethodManager.HideFlags int flags,
            @Nullable ResultReceiver resultReceiver, @SoftInputShowHideReason int reason) {
            @Nullable ResultReceiver resultReceiver, @SoftInputShowHideReason int reason,
            boolean async) {
        final IInputMethodManager service = getService();
        if (service == null) {
            return false;
        }
        try {
            return service.hideSoftInput(client, windowToken, statsToken, flags, resultReceiver,
                    reason);
                    reason, async);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
@@ -407,7 +408,7 @@ final class IInputMethodManagerGlobalInvoker {
            @Nullable IRemoteInputConnection remoteInputConnection,
            @Nullable IRemoteAccessibilityInputConnection remoteAccessibilityInputConnection,
            int unverifiedTargetSdkVersion, @UserIdInt int userId,
            @NonNull ImeOnBackInvokedDispatcher imeDispatcher) {
            @NonNull ImeOnBackInvokedDispatcher imeDispatcher, boolean useAsyncShowHideMethod) {
        final IInputMethodManager service = getService();
        if (service == null) {
            return -1;
@@ -416,7 +417,7 @@ final class IInputMethodManagerGlobalInvoker {
            service.startInputOrWindowGainedFocusAsync(startInputReason, client, windowToken,
                    startInputFlags, softInputMode, windowFlags, editorInfo, remoteInputConnection,
                    remoteAccessibilityInputConnection, unverifiedTargetSdkVersion, userId,
                    imeDispatcher, advanceAngGetStartInputSequenceNumber());
                    imeDispatcher, advanceAngGetStartInputSequenceNumber(), useAsyncShowHideMethod);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
+50 −7
Original line number Diff line number Diff line
@@ -56,6 +56,7 @@ import android.annotation.UiThread;
import android.annotation.UserIdInt;
import android.app.ActivityThread;
import android.app.PropertyInvalidatedCache;
import android.app.compat.CompatChanges;
import android.compat.annotation.ChangeId;
import android.compat.annotation.EnabledSince;
import android.compat.annotation.UnsupportedAppUsage;
@@ -440,6 +441,36 @@ public final class InputMethodManager {
    @EnabledSince(targetSdkVersion = Build.VERSION_CODES.TIRAMISU)
    public static final long CLEAR_SHOW_FORCED_FLAG_WHEN_LEAVING = 214016041L; // This is a bug id.

    /**
     * Use async method for {@link InputMethodManager#showSoftInput(View, int, ResultReceiver)},
     * {@link InputMethodManager#showSoftInput(View, int)} and
     * {@link InputMethodManager#hideSoftInputFromWindow(IBinder, int, ResultReceiver)},
     * {@link InputMethodManager#hideSoftInputFromWindow(IBinder, int)} for apps targeting V+.
     * <p>
     * Apps can incorrectly rely on {@link InputMethodManager#showSoftInput(View, int)} and
     * {@link InputMethodManager#hideSoftInputFromWindow(IBinder, int)} method return type
     * to interpret result of a request rather than relying on {@link ResultReceiver}. The return
     * type of the method was never documented to have accurate info of visibility but few apps
     * incorrectly rely on it.
     * <p>
     * Starting Android V, we use async calls into system_server which returns {@code true} if
     * method call was made but return type doesn't guarantee execution.
     * Apps targeting older versions will fallback to existing behavior of calling synchronous
     * methods which had undocumented result in return type.
     *
     * @hide
     */
    @ChangeId
    @EnabledSince(targetSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM)
    private static final long USE_ASYNC_SHOW_HIDE_METHOD = 352594277L; // This is a bug id.

    /**
     * Version-gating is guarded by bug-fix flag.
     */
    private static final boolean ASYNC_SHOW_HIDE_METHOD_ENABLED =
            !Flags.compatchangeForZerojankproxy()
                || CompatChanges.isChangeEnabled(USE_ASYNC_SHOW_HIDE_METHOD);

    /**
     * If {@code true}, avoid calling the
     * {@link com.android.server.inputmethod.InputMethodManagerService InputMethodManagerService}
@@ -2246,6 +2277,8 @@ public final class InputMethodManager {
     *             {@link View#isFocused view focus}, and its containing window has
     *             {@link View#hasWindowFocus window focus}. Otherwise the call fails and
     *             returns {@code false}.
     * @return {@code true} if a request was sent to system_server, {@code false} otherwise. Note:
     * this does not return result of the request. For result use {@param resultReceiver} instead.
     */
    public boolean showSoftInput(View view, @ShowFlags int flags) {
        // Re-dispatch if there is a context mismatch.
@@ -2315,6 +2348,8 @@ public final class InputMethodManager {
     * code you receive may be either {@link #RESULT_UNCHANGED_SHOWN},
     * {@link #RESULT_UNCHANGED_HIDDEN}, {@link #RESULT_SHOWN}, or
     * {@link #RESULT_HIDDEN}.
     * @return {@code true} if a request was sent to system_server, {@code false} otherwise. Note:
     * this does not return result of the request. For result use {@param resultReceiver} instead.
     */
    public boolean showSoftInput(View view, @ShowFlags int flags, ResultReceiver resultReceiver) {
        return showSoftInput(view, flags, resultReceiver, SoftInputShowHideReason.SHOW_SOFT_INPUT);
@@ -2383,7 +2418,8 @@ public final class InputMethodManager {
                        flags,
                        mCurRootView.getLastClickToolType(),
                        resultReceiver,
                        reason);
                        reason,
                        ASYNC_SHOW_HIDE_METHOD_ENABLED);
            }
        }
    }
@@ -2426,7 +2462,8 @@ public final class InputMethodManager {
                    flags,
                    mCurRootView.getLastClickToolType(),
                    resultReceiver,
                    reason);
                    reason,
                    ASYNC_SHOW_HIDE_METHOD_ENABLED);
        }
    }

@@ -2459,6 +2496,9 @@ public final class InputMethodManager {
     *
     * @param windowToken The token of the window that is making the request,
     * as returned by {@link View#getWindowToken() View.getWindowToken()}.
     * @return {@code true} if a request was sent to system_server, {@code false} otherwise. Note:
     * this does not return result of the request. For result use {@link ResultReceiver} in
     * {@link #hideSoftInputFromWindow(IBinder, int, ResultReceiver)} instead.
     */
    public boolean hideSoftInputFromWindow(IBinder windowToken, @HideFlags int flags) {
        return hideSoftInputFromWindow(windowToken, flags, null);
@@ -2487,6 +2527,8 @@ public final class InputMethodManager {
     * code you receive may be either {@link #RESULT_UNCHANGED_SHOWN},
     * {@link #RESULT_UNCHANGED_HIDDEN}, {@link #RESULT_SHOWN}, or
     * {@link #RESULT_HIDDEN}.
     * @return {@code true} if a request was sent to system_server, {@code false} otherwise. Note:
     * this does not return result of the request. For result use {@param resultReceiver} instead.
     */
    public boolean hideSoftInputFromWindow(IBinder windowToken, @HideFlags int flags,
            ResultReceiver resultReceiver) {
@@ -2530,7 +2572,7 @@ public final class InputMethodManager {
                return true;
            } else {
                return IInputMethodManagerGlobalInvoker.hideSoftInput(mClient, windowToken,
                        statsToken, flags, resultReceiver, reason);
                        statsToken, flags, resultReceiver, reason, ASYNC_SHOW_HIDE_METHOD_ENABLED);
            }
        }
    }
@@ -2573,7 +2615,7 @@ public final class InputMethodManager {
            ImeTracker.forLogging().onProgress(statsToken, ImeTracker.PHASE_CLIENT_VIEW_SERVED);

            return IInputMethodManagerGlobalInvoker.hideSoftInput(mClient, view.getWindowToken(),
                    statsToken, flags, null, reason);
                    statsToken, flags, null, reason, ASYNC_SHOW_HIDE_METHOD_ENABLED);
        }
    }

@@ -3350,7 +3392,7 @@ public final class InputMethodManager {
                        servedInputConnection == null ? null
                                : servedInputConnection.asIRemoteAccessibilityInputConnection(),
                        view.getContext().getApplicationInfo().targetSdkVersion, targetUserId,
                        mImeDispatcher);
                        mImeDispatcher, ASYNC_SHOW_HIDE_METHOD_ENABLED);
            } else {
                res = IInputMethodManagerGlobalInvoker.startInputOrWindowGainedFocus(
                        startInputReason, mClient, windowGainingFocus, startInputFlags,
@@ -3653,7 +3695,8 @@ public final class InputMethodManager {
                    statsToken,
                    HIDE_NOT_ALWAYS,
                    null,
                    reason);
                    reason,
                    true /*async */);
        }
    }

@@ -3745,7 +3788,7 @@ public final class InputMethodManager {

            IInputMethodManagerGlobalInvoker.hideSoftInput(mClient, windowToken, statsToken,
                    0 /* flags */, null /* resultReceiver */,
                    SoftInputShowHideReason.HIDE_SOFT_INPUT_BY_INSETS_API);
                    SoftInputShowHideReason.HIDE_SOFT_INPUT_BY_INSETS_API, true /* async */);
        }
    }

+11 −0
Original line number Diff line number Diff line
@@ -136,3 +136,14 @@ flag {
    purpose: PURPOSE_BUGFIX
  }
}

flag {
  name: "compatchange_for_zerojankproxy"
  namespace: "input_method"
  description: "Version-gate the sync/async nature of IMM#show/hideSoftInput() when using zeroJankProxy."
  bug: "352594277"
  is_fixed_read_only: true
  metadata {
    purpose: PURPOSE_BUGFIX
  }
}
+4 −3
Original line number Diff line number Diff line
@@ -76,10 +76,10 @@ interface IInputMethodManager {

    boolean showSoftInput(in IInputMethodClient client, @nullable IBinder windowToken,
            in ImeTracker.Token statsToken, int flags, int lastClickToolType,
            in @nullable ResultReceiver resultReceiver, int reason);
            in @nullable ResultReceiver resultReceiver, int reason, boolean async);
    boolean hideSoftInput(in IInputMethodClient client, @nullable IBinder windowToken,
            in ImeTracker.Token statsToken, int flags,
            in @nullable ResultReceiver resultReceiver, int reason);
            in @nullable ResultReceiver resultReceiver, int reason, boolean async);

    /**
     * A test API for CTS to request hiding the current soft input window, with the request origin
@@ -120,7 +120,8 @@ interface IInputMethodManager {
            in @nullable EditorInfo editorInfo, in @nullable IRemoteInputConnection inputConnection,
            in @nullable IRemoteAccessibilityInputConnection remoteAccessibilityInputConnection,
            int unverifiedTargetSdkVersion, int userId,
            in ImeOnBackInvokedDispatcher imeDispatcher, int startInputSeq);
            in ImeOnBackInvokedDispatcher imeDispatcher, int startInputSeq,
            boolean useAsyncShowHideMethod);

    void showInputMethodPickerFromClient(in IInputMethodClient client,
            int auxiliarySubtypeMode);
+12 −9
Original line number Diff line number Diff line
@@ -116,11 +116,11 @@ final class IInputMethodManagerImpl extends IInputMethodManager.Stub {
        boolean showSoftInput(IInputMethodClient client, IBinder windowToken,
                @Nullable ImeTracker.Token statsToken, @InputMethodManager.ShowFlags int flags,
                @MotionEvent.ToolType int lastClickToolType, ResultReceiver resultReceiver,
                @SoftInputShowHideReason int reason);
                @SoftInputShowHideReason int reason, boolean async);

        boolean hideSoftInput(IInputMethodClient client, IBinder windowToken,
                @Nullable ImeTracker.Token statsToken, @InputMethodManager.HideFlags int flags,
                ResultReceiver resultReceiver, @SoftInputShowHideReason int reason);
                ResultReceiver resultReceiver, @SoftInputShowHideReason int reason, boolean async);

        @PermissionVerified(Manifest.permission.TEST_INPUT_METHOD)
        void hideSoftInputFromServerForTest();
@@ -132,7 +132,8 @@ final class IInputMethodManagerImpl extends IInputMethodManager.Stub {
                @Nullable EditorInfo editorInfo, IRemoteInputConnection inputConnection,
                IRemoteAccessibilityInputConnection remoteAccessibilityInputConnection,
                int unverifiedTargetSdkVersion, @UserIdInt int userId,
                @NonNull ImeOnBackInvokedDispatcher imeDispatcher, int startInputSeq);
                @NonNull ImeOnBackInvokedDispatcher imeDispatcher, int startInputSeq,
                boolean useAsyncShowHideMethod);

        InputBindResult startInputOrWindowGainedFocus(
                @StartInputReason int startInputReason, IInputMethodClient client,
@@ -290,17 +291,17 @@ final class IInputMethodManagerImpl extends IInputMethodManager.Stub {
    public boolean showSoftInput(IInputMethodClient client, IBinder windowToken,
            @NonNull ImeTracker.Token statsToken, @InputMethodManager.ShowFlags int flags,
            @MotionEvent.ToolType int lastClickToolType, ResultReceiver resultReceiver,
            @SoftInputShowHideReason int reason) {
            @SoftInputShowHideReason int reason, boolean async) {
        return mCallback.showSoftInput(client, windowToken, statsToken, flags, lastClickToolType,
                resultReceiver, reason);
                resultReceiver, reason, async);
    }

    @Override
    public boolean hideSoftInput(IInputMethodClient client, IBinder windowToken,
            @NonNull ImeTracker.Token statsToken, @InputMethodManager.HideFlags int flags,
            ResultReceiver resultReceiver, @SoftInputShowHideReason int reason) {
            ResultReceiver resultReceiver, @SoftInputShowHideReason int reason, boolean async) {
        return mCallback.hideSoftInput(client, windowToken, statsToken, flags, resultReceiver,
                reason);
                reason, async);
    }

    @EnforcePermission(Manifest.permission.TEST_INPUT_METHOD)
@@ -336,11 +337,13 @@ final class IInputMethodManagerImpl extends IInputMethodManager.Stub {
            IRemoteInputConnection inputConnection,
            IRemoteAccessibilityInputConnection remoteAccessibilityInputConnection,
            int unverifiedTargetSdkVersion, @UserIdInt int userId,
            @NonNull ImeOnBackInvokedDispatcher imeDispatcher, int startInputSeq) {
            @NonNull ImeOnBackInvokedDispatcher imeDispatcher, int startInputSeq,
            boolean useAsyncShowHideMethod) {
        mCallback.startInputOrWindowGainedFocusAsync(
                startInputReason, client, windowToken, startInputFlags, softInputMode,
                windowFlags, editorInfo, inputConnection, remoteAccessibilityInputConnection,
                unverifiedTargetSdkVersion, userId, imeDispatcher, startInputSeq);
                unverifiedTargetSdkVersion, userId, imeDispatcher, startInputSeq,
                useAsyncShowHideMethod);
    }

    @Override
Loading