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

Commit 81cbe29a authored by TYM Tsai's avatar TYM Tsai
Browse files

Handle input method switch properly for inline suggestions

Expired the old response while received input method subtype changed.
When user next tap on an autofill field, trigger a new fill request for
the new input method.

Bug: 150483555
Test: manual switch imput method
Test: atest CtsAutoFillServiceTestCases
Change-Id: I97be067db3a79d2481c05aeb59875ec24514199d
parent 81fd5037
Loading
Loading
Loading
Loading
+23 −0
Original line number Diff line number Diff line
@@ -249,6 +249,9 @@ public final class AutofillManagerService
        resolver.registerContentObserver(Settings.Global.getUriFor(
                Settings.Global.AUTOFILL_MAX_VISIBLE_DATASETS), false, observer,
                UserHandle.USER_ALL);
        resolver.registerContentObserver(Settings.Secure.getUriFor(
                Settings.Secure.SELECTED_INPUT_METHOD_SUBTYPE), false, observer,
                UserHandle.USER_ALL);
    }

    @Override // from AbstractMasterSystemService
@@ -263,6 +266,9 @@ public final class AutofillManagerService
            case Settings.Global.AUTOFILL_MAX_VISIBLE_DATASETS:
                setMaxVisibleDatasetsFromSettings();
                break;
            case Settings.Secure.SELECTED_INPUT_METHOD_SUBTYPE:
                handleInputMethodSwitch(userId);
                break;
            default:
                Slog.w(TAG, "Unexpected property (" + property + "); updating cache instead");
                // fall through
@@ -273,6 +279,23 @@ public final class AutofillManagerService
        }
    }

    private void handleInputMethodSwitch(@UserIdInt int userId) {
        // TODO(b/156903336): Used the SettingsObserver with a background thread maybe slow to
        // respond to the IME switch in certain situations.
        // See: services/core/java/com/android/server/FgThread.java
        // In particular, the shared background thread could be doing relatively long-running
        // operations like saving state to disk (in addition to simply being a background priority),
        // which can cause operations scheduled on it to be delayed for a user-noticeable amount
        // of time.

        synchronized (mLock) {
            final AutofillManagerServiceImpl service = peekServiceForUserLocked(userId);
            if (service != null) {
                service.onSwitchInputMethod();
            }
        }
    }

    private void onDeviceConfigChange(@NonNull Set<String> keys) {
        for (String key : keys) {
            switch (key) {
+10 −0
Original line number Diff line number Diff line
@@ -1564,6 +1564,16 @@ final class AutofillManagerServiceImpl
        }
    }

    void onSwitchInputMethod() {
        synchronized (mLock) {
            final int sessionCount = mSessions.size();
            for (int i = 0; i < sessionCount; i++) {
                final Session session = mSessions.valueAt(i);
                session.onSwitchInputMethodLocked();
            }
        }
    }

    @Override
    public String toString() {
        return "AutofillManagerServiceImpl: [userId=" + mUserId
+37 −0
Original line number Diff line number Diff line
@@ -311,6 +311,43 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
     */
    private final AssistDataReceiverImpl mAssistReceiver = new AssistDataReceiverImpl();

    void onSwitchInputMethodLocked() {
        if (mExpiredResponse) {
            return;
        }

        if (shouldExpireResponseOnInputMethodSwitch()) {
            // Set the old response expired, so the next action (ACTION_VIEW_ENTERED) can trigger
            // a new fill request.
            mExpiredResponse = true;
        }
    }

    private boolean shouldExpireResponseOnInputMethodSwitch() {
        // One of below cases will need a new fill request to update the inline spec for the new
        // input method.
        // 1. The autofill provider supports inline suggestion and the render service is available.
        // 2. Had triggered the augmented autofill and the render service is available. Whether the
        // augmented autofill triggered by:
        //    a. Augmented autofill only
        //    b. The autofill provider respond null
        if (mService.getRemoteInlineSuggestionRenderServiceLocked() == null) {
            return false;
        }

        if (isInlineSuggestionsEnabledByAutofillProviderLocked()) {
            return true;
        }

        final ViewState state = mViewStates.get(mCurrentViewId);
        if (state != null
                && (state.getState() & ViewState.STATE_TRIGGERED_AUGMENTED_AUTOFILL) != 0) {
            return true;
        }

        return false;
    }

    /**
     * TODO(b/151867668): improve how asynchronous data dependencies are handled, without using
     * CountDownLatch.