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

Commit 4bcb01a3 authored by Felipe Leme's avatar Felipe Leme
Browse files

New Autofill API: SaveCallback.onSuccess(IntentSender).

This overloaded method is useful for cases where the service needs to launch
an activity (for example, to unlock the user's vault), in which case it's
launched from the context of the activity being filled.

Test: atest CtsAutoFillServiceTestCases:SimpleSaveActivityTest#testSave_launchIntent
Test: atest CtsAutoFillServiceTestCases
Fixes: 69458616

Change-Id: I41bf5fd4954c38051e3275f2e8500a00dcf24724
parent 71b4882d
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -37499,6 +37499,7 @@ package android.service.autofill {
  public final class SaveCallback {
    method public void onFailure(java.lang.CharSequence);
    method public void onSuccess();
    method public void onSuccess(android.content.IntentSender);
  }
  public final class SaveInfo implements android.os.Parcelable {
+3 −1
Original line number Diff line number Diff line
@@ -16,12 +16,14 @@

package android.service.autofill;

import android.content.IntentSender;

/**
 * Interface to receive the result of a save request.
 *
 * @hide
 */
interface ISaveCallback {
    void onSuccess();
    void onSuccess(in IntentSender intentSender);
    void onFailure(CharSequence message);
}
+28 −9
Original line number Diff line number Diff line
@@ -16,9 +16,14 @@

package android.service.autofill;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.Activity;
import android.content.IntentSender;
import android.os.RemoteException;

import com.android.internal.util.Preconditions;

/**
 * Handles save requests from the {@link AutofillService} into the {@link Activity} being
 * autofilled.
@@ -32,22 +37,37 @@ public final class SaveCallback {
        mCallback = callback;
    }

    /**
     * Notifies the Android System that an
     * {@link AutofillService#onSaveRequest(SaveRequest, SaveCallback)} was successfully handled
     * by the service.
     */
    public void onSuccess() {
        onSuccessInternal(null);
    }

    /**
     * Notifies the Android System that an
     * {@link AutofillService#onSaveRequest(SaveRequest, SaveCallback)} was successfully handled
     * by the service.
     *
     * <p>If the service could not handle the request right away&mdash;for example, because it must
     * launch an activity asking the user to authenticate first or because the network is
     * down&mdash;it should still call {@link #onSuccess()}.
     * <p>This method is useful when the service requires extra work&mdash;for example, launching an
     * activity asking the user to authenticate first &mdash;before it can process the request,
     * as the intent will be launched from the context of the activity being autofilled and hence
     * will be part of that activity's stack.
     *
     * @throws RuntimeException if an error occurred while calling the Android System.
     * @param intentSender intent that will be launched from the context of activity being
     * autofilled.
     */
    public void onSuccess() {
    public void onSuccess(@NonNull IntentSender intentSender) {
        onSuccessInternal(Preconditions.checkNotNull(intentSender));
    }

    private void onSuccessInternal(@Nullable IntentSender intentSender) {
        assertNotCalled();
        mCalled = true;
        try {
            mCallback.onSuccess();
            mCallback.onSuccess(intentSender);
        } catch (RemoteException e) {
            e.rethrowAsRuntimeException();
        }
@@ -63,11 +83,10 @@ public final class SaveCallback {
     * the {@link SaveRequest} and call {@link #onSuccess()} instead.
     *
     * <p><b>Note:</b> The Android System displays an UI with the supplied error message; if
     * you prefer to show your own message, call {@link #onSuccess()} instead.
     * you prefer to show your own message, call {@link #onSuccess()} or
     * {@link #onSuccess(IntentSender)} instead.
     *
     * @param message error message to be displayed to the user.
     *
     * @throws RuntimeException if an error occurred while calling the Android System.
     */
    public void onFailure(CharSequence message) {
        assertNotCalled();
+2 −1
Original line number Diff line number Diff line
@@ -3761,7 +3761,8 @@ message MetricsEvent {
    FIELD_AUTOFILL_NUM_IDS = 917;

    // ACTION: An autofill service was reqiested to save data
    // Type TYPE_SUCCESS: The request succeeded
    // Type TYPE_SUCCESS: The request succeeded right away
    // Type TYPE_OPEN: The request succeeded but the service launched an IntentSender
    // Type TYPE_FAILURE: The request failed
    // Package: Package of app that was autofilled
    // Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request
+9 −5
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import android.annotation.Nullable;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentSender;
import android.content.ServiceConnection;
import android.os.Handler;
import android.os.IBinder;
@@ -100,7 +101,8 @@ final class RemoteFillService implements DeathRecipient {
                @NonNull String servicePackageName);
        void onFillRequestFailure(@Nullable CharSequence message,
                @NonNull String servicePackageName);
        void onSaveRequestSuccess(@NonNull String servicePackageName);
        void onSaveRequestSuccess(@NonNull String servicePackageName,
                @Nullable IntentSender intentSender);
        void onSaveRequestFailure(@Nullable CharSequence message,
                @NonNull String servicePackageName);
        void onServiceDied(RemoteFillService service);
@@ -308,10 +310,11 @@ final class RemoteFillService implements DeathRecipient {
        });
    }

    private void dispatchOnSaveRequestSuccess(PendingRequest pendingRequest) {
    private void dispatchOnSaveRequestSuccess(PendingRequest pendingRequest,
            IntentSender intentSender) {
        mHandler.getHandler().post(() -> {
            if (handleResponseCallbackCommon(pendingRequest)) {
                mCallbacks.onSaveRequestSuccess(mComponentName.getPackageName());
                mCallbacks.onSaveRequestSuccess(mComponentName.getPackageName(), intentSender);
            }
        });
    }
@@ -624,12 +627,13 @@ final class RemoteFillService implements DeathRecipient {

            mCallback = new ISaveCallback.Stub() {
                @Override
                public void onSuccess() {
                public void onSuccess(IntentSender intentSender) {
                    if (!finish()) return;

                    final RemoteFillService remoteService = getService();
                    if (remoteService != null) {
                        remoteService.dispatchOnSaveRequestSuccess(PendingSaveRequest.this);
                        remoteService.dispatchOnSaveRequestSuccess(PendingSaveRequest.this,
                                intentSender);
                    }
                }

Loading