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

Commit 2dccbf2d authored by Svetoslav Ganov's avatar Svetoslav Ganov Committed by Android (Google) Code Review
Browse files

Merge "Scrollable inline keyboard suggestions"

parents a39b118f 17d9d2f2
Loading
Loading
Loading
Loading
+41 −29
Original line number Diff line number Diff line
@@ -31,7 +31,6 @@ import android.content.ComponentName;
import android.content.Intent;
import android.graphics.Rect;
import android.os.Build;
import android.os.Bundle;
import android.os.CancellationSignal;
import android.os.Handler;
import android.os.IBinder;
@@ -93,7 +92,7 @@ public abstract class AugmentedAutofillService extends Service {
    // Used for metrics / debug only
    private ComponentName mServiceComponentName;

    private final IAugmentedAutofillService mInterface = new IAugmentedAutofillService.Stub() {
    private final class AugmentedAutofillServiceImpl extends IAugmentedAutofillService.Stub {

        @Override
        public void onConnected(boolean debug, boolean verbose) {
@@ -137,7 +136,7 @@ public abstract class AugmentedAutofillService extends Service {
    public final IBinder onBind(Intent intent) {
        mServiceComponentName = intent.getComponent();
        if (SERVICE_INTERFACE.equals(intent.getAction())) {
            return mInterface.asBinder();
            return new AugmentedAutofillServiceImpl();
        }
        Log.w(TAG, "Tried to bind to wrong intent (should be " + SERVICE_INTERFACE + ": " + intent);
        return null;
@@ -352,11 +351,13 @@ public abstract class AugmentedAutofillService extends Service {
        static final int REPORT_EVENT_NO_RESPONSE = 1;
        static final int REPORT_EVENT_UI_SHOWN = 2;
        static final int REPORT_EVENT_UI_DESTROYED = 3;
        static final int REPORT_EVENT_INLINE_RESPONSE = 4;

        @IntDef(prefix = { "REPORT_EVENT_" }, value = {
                REPORT_EVENT_NO_RESPONSE,
                REPORT_EVENT_UI_SHOWN,
                REPORT_EVENT_UI_DESTROYED
                REPORT_EVENT_UI_DESTROYED,
                REPORT_EVENT_INLINE_RESPONSE
        })
        @Retention(RetentionPolicy.SOURCE)
        @interface ReportEvent{}
@@ -365,8 +366,8 @@ public abstract class AugmentedAutofillService extends Service {
        private final Object mLock = new Object();
        private final IAugmentedAutofillManagerClient mClient;
        private final int mSessionId;
        public final int taskId;
        public final ComponentName componentName;
        public final int mTaskId;
        public final ComponentName mComponentName;
        // Used for metrics / debug only
        private String mServicePackageName;
        @GuardedBy("mLock")
@@ -406,8 +407,8 @@ public abstract class AugmentedAutofillService extends Service {
            mSessionId = sessionId;
            mClient = IAugmentedAutofillManagerClient.Stub.asInterface(client);
            mCallback = callback;
            this.taskId = taskId;
            this.componentName = componentName;
            mTaskId = taskId;
            mComponentName = componentName;
            mServicePackageName = serviceComponentName.getPackageName();
            mFocusedId = focusedId;
            mFocusedValue = focusedValue;
@@ -514,22 +515,24 @@ public abstract class AugmentedAutofillService extends Service {
            }
        }

        public void onInlineSuggestionsDataReady(@NonNull List<Dataset> inlineSuggestionsData,
                @Nullable Bundle clientState) {
        void reportResult(@Nullable List<Dataset> inlineSuggestionsData) {
            try {
                mCallback.onSuccess(inlineSuggestionsData.toArray(new Dataset[]{}), clientState);
                final Dataset[] inlineSuggestions = (inlineSuggestionsData != null)
                        ? inlineSuggestionsData.toArray(new Dataset[inlineSuggestionsData.size()])
                        : null;
                mCallback.onSuccess(inlineSuggestions);
            } catch (RemoteException e) {
                Log.e(TAG, "Error calling back with the inline suggestions data: " + e);
            }
        }

        // Used (mostly) for metrics.
        public void report(@ReportEvent int event) {
            if (sVerbose) Log.v(TAG, "report(): " + event);
        void logEvent(@ReportEvent int event) {
            if (sVerbose) Log.v(TAG, "returnAndLogResult(): " + event);
            long duration = -1;
            int type = MetricsEvent.TYPE_UNKNOWN;

            switch (event) {
                case REPORT_EVENT_NO_RESPONSE:
                case REPORT_EVENT_NO_RESPONSE: {
                    type = MetricsEvent.TYPE_SUCCESS;
                    if (mFirstOnSuccessTime == 0) {
                        mFirstOnSuccessTime = SystemClock.elapsedRealtime();
@@ -538,40 +541,49 @@ public abstract class AugmentedAutofillService extends Service {
                            Log.d(TAG, "Service responded nothing in " + formatDuration(duration));
                        }
                    }
                    try {
                        mCallback.onSuccess(/* inlineSuggestionsData= */null, /* clientState=*/
                                null);
                    } catch (RemoteException e) {
                        Log.e(TAG, "Error reporting success: " + e);
                } break;

                case REPORT_EVENT_INLINE_RESPONSE: {
                    // TODO: Define a constant and log this event
                    // type = MetricsEvent.TYPE_SUCCESS_INLINE;
                    if (mFirstOnSuccessTime == 0) {
                        mFirstOnSuccessTime = SystemClock.elapsedRealtime();
                        duration = mFirstOnSuccessTime - mFirstRequestTime;
                        if (sDebug) {
                            Log.d(TAG, "Service responded nothing in " + formatDuration(duration));
                        }
                    }
                    break;
                case REPORT_EVENT_UI_SHOWN:
                } break;

                case REPORT_EVENT_UI_SHOWN: {
                    type = MetricsEvent.TYPE_OPEN;
                    if (mUiFirstShownTime == 0) {
                        mUiFirstShownTime = SystemClock.elapsedRealtime();
                        duration = mUiFirstShownTime - mFirstRequestTime;
                        if (sDebug) Log.d(TAG, "UI shown in " + formatDuration(duration));
                    }
                    break;
                case REPORT_EVENT_UI_DESTROYED:
                } break;

                case REPORT_EVENT_UI_DESTROYED: {
                    type = MetricsEvent.TYPE_CLOSE;
                    if (mUiFirstDestroyedTime == 0) {
                        mUiFirstDestroyedTime = SystemClock.elapsedRealtime();
                        duration = mUiFirstDestroyedTime - mFirstRequestTime;
                        if (sDebug) Log.d(TAG, "UI destroyed in " + formatDuration(duration));
                    }
                    break;
                } break;

                default:
                    Log.w(TAG, "invalid event reported: " + event);
            }
            logResponse(type, mServicePackageName, componentName, mSessionId, duration);
            logResponse(type, mServicePackageName, mComponentName, mSessionId, duration);
        }

        public void dump(@NonNull String prefix, @NonNull PrintWriter pw) {
            pw.print(prefix); pw.print("sessionId: "); pw.println(mSessionId);
            pw.print(prefix); pw.print("taskId: "); pw.println(taskId);
            pw.print(prefix); pw.print("taskId: "); pw.println(mTaskId);
            pw.print(prefix); pw.print("component: ");
            pw.println(componentName.flattenToShortString());
            pw.println(mComponentName.flattenToShortString());
            pw.print(prefix); pw.print("focusedId: "); pw.println(mFocusedId);
            if (mFocusedValue != null) {
                pw.print(prefix); pw.print("focusedValue: "); pw.println(mFocusedValue);
+4 −2
Original line number Diff line number Diff line
@@ -54,13 +54,15 @@ public final class FillCallback {
        if (sDebug) Log.d(TAG, "onSuccess(): " + response);

        if (response == null) {
            mProxy.report(AutofillProxy.REPORT_EVENT_NO_RESPONSE);
            mProxy.logEvent(AutofillProxy.REPORT_EVENT_NO_RESPONSE);
            mProxy.reportResult(null /*inlineSuggestions*/);
            return;
        }

        List<Dataset> inlineSuggestions = response.getInlineSuggestions();
        if (inlineSuggestions != null && !inlineSuggestions.isEmpty()) {
            mProxy.onInlineSuggestionsDataReady(inlineSuggestions, response.getClientState());
            mProxy.logEvent(AutofillProxy.REPORT_EVENT_INLINE_RESPONSE);
            mProxy.reportResult(inlineSuggestions);
            return;
        }

+5 −4
Original line number Diff line number Diff line
@@ -62,12 +62,13 @@ public final class FillController {

        try {
            mProxy.autofill(values);
        } catch (RemoteException e) {
            e.rethrowAsRuntimeException();
        }

        final FillWindow fillWindow = mProxy.getFillWindow();
        if (fillWindow != null) {
            fillWindow.destroy();
        }
        } catch (RemoteException e) {
            e.rethrowAsRuntimeException();
        }
    }
}
+2 −2
Original line number Diff line number Diff line
@@ -53,7 +53,7 @@ public final class FillRequest {
     * Gets the task of the activity associated with this request.
     */
    public int getTaskId() {
        return mProxy.taskId;
        return mProxy.mTaskId;
    }

    /**
@@ -61,7 +61,7 @@ public final class FillRequest {
     */
    @NonNull
    public ComponentName getActivityComponent() {
        return mProxy.componentName;
        return mProxy.mComponentName;
    }

    /**
+27 −14
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import static android.service.autofill.augmented.AugmentedAutofillService.sVerbo
import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.graphics.Rect;
@@ -41,6 +42,7 @@ import com.android.internal.util.Preconditions;
import dalvik.system.CloseGuard;

import java.io.PrintWriter;
import java.lang.ref.WeakReference;

/**
 * Handle to a window used to display the augmented autofill UI.
@@ -70,23 +72,22 @@ public final class FillWindow implements AutoCloseable {
    private final CloseGuard mCloseGuard = CloseGuard.get();

    private final @NonNull Handler mUiThreadHandler = new Handler(Looper.getMainLooper());
    private final @NonNull FillWindowPresenter mFillWindowPresenter = new FillWindowPresenter();

    @GuardedBy("mLock")
    private WindowManager mWm;
    private @NonNull WindowManager mWm;
    @GuardedBy("mLock")
    private View mFillView;
    @GuardedBy("mLock")
    private boolean mShowing;
    @GuardedBy("mLock")
    private Rect mBounds;
    private @Nullable Rect mBounds;

    @GuardedBy("mLock")
    private boolean mUpdateCalled;
    @GuardedBy("mLock")
    private boolean mDestroyed;

    private AutofillProxy mProxy;
    private @NonNull AutofillProxy mProxy;

    /**
     * Updates the content of the window.
@@ -172,11 +173,11 @@ public final class FillWindow implements AutoCloseable {
                try {
                    mProxy.requestShowFillUi(mBounds.right - mBounds.left,
                            mBounds.bottom - mBounds.top,
                            /*anchorBounds=*/ null, mFillWindowPresenter);
                            /*anchorBounds=*/ null, new FillWindowPresenter(this));
                } catch (RemoteException e) {
                    Log.w(TAG, "Error requesting to show fill window", e);
                }
                mProxy.report(AutofillProxy.REPORT_EVENT_UI_SHOWN);
                mProxy.logEvent(AutofillProxy.REPORT_EVENT_UI_SHOWN);
            }
        }
    }
@@ -244,7 +245,7 @@ public final class FillWindow implements AutoCloseable {
            if (mUpdateCalled) {
                mFillView.setOnClickListener(null);
                hide();
                mProxy.report(AutofillProxy.REPORT_EVENT_UI_DESTROYED);
                mProxy.logEvent(AutofillProxy.REPORT_EVENT_UI_DESTROYED);
            }
            mDestroyed = true;
            mCloseGuard.close();
@@ -254,9 +255,7 @@ public final class FillWindow implements AutoCloseable {
    @Override
    protected void finalize() throws Throwable {
        try {
            if (mCloseGuard != null) {
            mCloseGuard.warnIfOpen();
            }
            destroy();
        } finally {
            super.finalize();
@@ -289,22 +288,36 @@ public final class FillWindow implements AutoCloseable {

    /** @hide */
    @Override
    public void close() throws Exception {
    public void close() {
        destroy();
    }

    private final class FillWindowPresenter extends IAutofillWindowPresenter.Stub {
    private static final class FillWindowPresenter extends IAutofillWindowPresenter.Stub {
        private final @NonNull WeakReference<FillWindow> mFillWindowReference;

        FillWindowPresenter(@NonNull FillWindow fillWindow) {
            mFillWindowReference = new WeakReference<>(fillWindow);
        }

        @Override
        public void show(WindowManager.LayoutParams p, Rect transitionEpicenter,
                boolean fitsSystemWindows, int layoutDirection) {
            if (sDebug) Log.d(TAG, "FillWindowPresenter.show()");
            mUiThreadHandler.sendMessage(obtainMessage(FillWindow::handleShow, FillWindow.this, p));
            final FillWindow fillWindow = mFillWindowReference.get();
            if (fillWindow != null) {
                fillWindow.mUiThreadHandler.sendMessage(
                        obtainMessage(FillWindow::handleShow, fillWindow, p));
            }
        }

        @Override
        public void hide(Rect transitionEpicenter) {
            if (sDebug) Log.d(TAG, "FillWindowPresenter.hide()");
            mUiThreadHandler.sendMessage(obtainMessage(FillWindow::handleHide, FillWindow.this));
            final FillWindow fillWindow = mFillWindowReference.get();
            if (fillWindow != null) {
                fillWindow.mUiThreadHandler.sendMessage(
                        obtainMessage(FillWindow::handleHide, fillWindow));
            }
        }
    }
}
Loading