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

Commit b66cfe8a authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Added support to authentication."

parents ca003429 436ab6a9
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -35671,17 +35671,25 @@ package android.service.autofill {
    ctor public AutoFillService();
    method public final android.os.IBinder onBind(android.content.Intent);
    method public void onConnected();
    method public void onDatasetAuthenticationRequest(android.os.Bundle, int);
    method public void onDisconnected();
    method public abstract void onFillRequest(android.app.assist.AssistStructure, android.os.Bundle, android.os.CancellationSignal, android.service.autofill.FillCallback);
    method public void onFillResponseAuthenticationRequest(android.os.Bundle, int);
    method public abstract void onSaveRequest(android.app.assist.AssistStructure, android.os.Bundle, android.os.CancellationSignal, android.service.autofill.SaveCallback);
    field public static final java.lang.String EXTRA_DATASET_EXTRAS = "android.service.autofill.extra.DATASET_EXTRAS";
    field public static final java.lang.String EXTRA_RESPONSE_EXTRAS = "android.service.autofill.extra.RESPONSE_EXTRAS";
    field public static final int FLAG_AUTHENTICATION_ERROR = 4; // 0x4
    field public static final int FLAG_AUTHENTICATION_REQUESTED = 1; // 0x1
    field public static final int FLAG_AUTHENTICATION_SUCCESS = 2; // 0x2
    field public static final int FLAG_FINGERPRINT_AUTHENTICATION_NOT_AVAILABLE = 8; // 0x8
    field public static final java.lang.String SERVICE_INTERFACE = "android.service.autofill.AutoFillService";
    field public static final java.lang.String SERVICE_META_DATA = "android.autofill";
  }
  public final class FillCallback {
    method public void onDatasetAuthentication(android.view.autofill.Dataset, int);
    method public void onFailure(java.lang.CharSequence);
    method public void onFillResponseAuthentication(int);
    method public void onSuccess(android.view.autofill.FillResponse);
  }
@@ -46298,6 +46306,8 @@ package android.view.autofill {
  public static final class Dataset.Builder {
    ctor public Dataset.Builder(java.lang.CharSequence);
    method public android.view.autofill.Dataset build();
    method public android.view.autofill.Dataset.Builder requiresCustomAuthentication(android.os.Bundle, int);
    method public android.view.autofill.Dataset.Builder requiresFingerprintAuthentication(android.hardware.fingerprint.FingerprintManager.CryptoObject, android.os.Bundle, int);
    method public android.view.autofill.Dataset.Builder setExtras(android.os.Bundle);
    method public android.view.autofill.Dataset.Builder setValue(android.view.autofill.AutoFillId, android.view.autofill.AutoFillValue);
  }
@@ -46313,6 +46323,8 @@ package android.view.autofill {
    method public android.view.autofill.FillResponse.Builder addDataset(android.view.autofill.Dataset);
    method public android.view.autofill.FillResponse.Builder addSavableFields(android.view.autofill.AutoFillId...);
    method public android.view.autofill.FillResponse build();
    method public android.view.autofill.FillResponse.Builder requiresCustomAuthentication(android.os.Bundle, int);
    method public android.view.autofill.FillResponse.Builder requiresFingerprintAuthentication(android.hardware.fingerprint.FingerprintManager.CryptoObject, android.os.Bundle, int);
    method public android.view.autofill.FillResponse.Builder setExtras(android.os.Bundle);
  }
+12 −0
Original line number Diff line number Diff line
@@ -38691,17 +38691,25 @@ package android.service.autofill {
    ctor public AutoFillService();
    method public final android.os.IBinder onBind(android.content.Intent);
    method public void onConnected();
    method public void onDatasetAuthenticationRequest(android.os.Bundle, int);
    method public void onDisconnected();
    method public abstract void onFillRequest(android.app.assist.AssistStructure, android.os.Bundle, android.os.CancellationSignal, android.service.autofill.FillCallback);
    method public void onFillResponseAuthenticationRequest(android.os.Bundle, int);
    method public abstract void onSaveRequest(android.app.assist.AssistStructure, android.os.Bundle, android.os.CancellationSignal, android.service.autofill.SaveCallback);
    field public static final java.lang.String EXTRA_DATASET_EXTRAS = "android.service.autofill.extra.DATASET_EXTRAS";
    field public static final java.lang.String EXTRA_RESPONSE_EXTRAS = "android.service.autofill.extra.RESPONSE_EXTRAS";
    field public static final int FLAG_AUTHENTICATION_ERROR = 4; // 0x4
    field public static final int FLAG_AUTHENTICATION_REQUESTED = 1; // 0x1
    field public static final int FLAG_AUTHENTICATION_SUCCESS = 2; // 0x2
    field public static final int FLAG_FINGERPRINT_AUTHENTICATION_NOT_AVAILABLE = 8; // 0x8
    field public static final java.lang.String SERVICE_INTERFACE = "android.service.autofill.AutoFillService";
    field public static final java.lang.String SERVICE_META_DATA = "android.autofill";
  }
  public final class FillCallback {
    method public void onDatasetAuthentication(android.view.autofill.Dataset, int);
    method public void onFailure(java.lang.CharSequence);
    method public void onFillResponseAuthentication(int);
    method public void onSuccess(android.view.autofill.FillResponse);
  }
@@ -49687,6 +49695,8 @@ package android.view.autofill {
  public static final class Dataset.Builder {
    ctor public Dataset.Builder(java.lang.CharSequence);
    method public android.view.autofill.Dataset build();
    method public android.view.autofill.Dataset.Builder requiresCustomAuthentication(android.os.Bundle, int);
    method public android.view.autofill.Dataset.Builder requiresFingerprintAuthentication(android.hardware.fingerprint.FingerprintManager.CryptoObject, android.os.Bundle, int);
    method public android.view.autofill.Dataset.Builder setExtras(android.os.Bundle);
    method public android.view.autofill.Dataset.Builder setValue(android.view.autofill.AutoFillId, android.view.autofill.AutoFillValue);
  }
@@ -49702,6 +49712,8 @@ package android.view.autofill {
    method public android.view.autofill.FillResponse.Builder addDataset(android.view.autofill.Dataset);
    method public android.view.autofill.FillResponse.Builder addSavableFields(android.view.autofill.AutoFillId...);
    method public android.view.autofill.FillResponse build();
    method public android.view.autofill.FillResponse.Builder requiresCustomAuthentication(android.os.Bundle, int);
    method public android.view.autofill.FillResponse.Builder requiresFingerprintAuthentication(android.hardware.fingerprint.FingerprintManager.CryptoObject, android.os.Bundle, int);
    method public android.view.autofill.FillResponse.Builder setExtras(android.os.Bundle);
  }
+12 −0
Original line number Diff line number Diff line
@@ -35805,17 +35805,25 @@ package android.service.autofill {
    ctor public AutoFillService();
    method public final android.os.IBinder onBind(android.content.Intent);
    method public void onConnected();
    method public void onDatasetAuthenticationRequest(android.os.Bundle, int);
    method public void onDisconnected();
    method public abstract void onFillRequest(android.app.assist.AssistStructure, android.os.Bundle, android.os.CancellationSignal, android.service.autofill.FillCallback);
    method public void onFillResponseAuthenticationRequest(android.os.Bundle, int);
    method public abstract void onSaveRequest(android.app.assist.AssistStructure, android.os.Bundle, android.os.CancellationSignal, android.service.autofill.SaveCallback);
    field public static final java.lang.String EXTRA_DATASET_EXTRAS = "android.service.autofill.extra.DATASET_EXTRAS";
    field public static final java.lang.String EXTRA_RESPONSE_EXTRAS = "android.service.autofill.extra.RESPONSE_EXTRAS";
    field public static final int FLAG_AUTHENTICATION_ERROR = 4; // 0x4
    field public static final int FLAG_AUTHENTICATION_REQUESTED = 1; // 0x1
    field public static final int FLAG_AUTHENTICATION_SUCCESS = 2; // 0x2
    field public static final int FLAG_FINGERPRINT_AUTHENTICATION_NOT_AVAILABLE = 8; // 0x8
    field public static final java.lang.String SERVICE_INTERFACE = "android.service.autofill.AutoFillService";
    field public static final java.lang.String SERVICE_META_DATA = "android.autofill";
  }
  public final class FillCallback {
    method public void onDatasetAuthentication(android.view.autofill.Dataset, int);
    method public void onFailure(java.lang.CharSequence);
    method public void onFillResponseAuthentication(int);
    method public void onSuccess(android.view.autofill.FillResponse);
  }
@@ -46609,6 +46617,8 @@ package android.view.autofill {
  public static final class Dataset.Builder {
    ctor public Dataset.Builder(java.lang.CharSequence);
    method public android.view.autofill.Dataset build();
    method public android.view.autofill.Dataset.Builder requiresCustomAuthentication(android.os.Bundle, int);
    method public android.view.autofill.Dataset.Builder requiresFingerprintAuthentication(android.hardware.fingerprint.FingerprintManager.CryptoObject, android.os.Bundle, int);
    method public android.view.autofill.Dataset.Builder setExtras(android.os.Bundle);
    method public android.view.autofill.Dataset.Builder setValue(android.view.autofill.AutoFillId, android.view.autofill.AutoFillValue);
  }
@@ -46624,6 +46634,8 @@ package android.view.autofill {
    method public android.view.autofill.FillResponse.Builder addDataset(android.view.autofill.Dataset);
    method public android.view.autofill.FillResponse.Builder addSavableFields(android.view.autofill.AutoFillId...);
    method public android.view.autofill.FillResponse build();
    method public android.view.autofill.FillResponse.Builder requiresCustomAuthentication(android.os.Bundle, int);
    method public android.view.autofill.FillResponse.Builder requiresFingerprintAuthentication(android.hardware.fingerprint.FingerprintManager.CryptoObject, android.os.Bundle, int);
    method public android.view.autofill.FillResponse.Builder setExtras(android.os.Bundle);
  }
+1 −1
Original line number Diff line number Diff line
@@ -1074,7 +1074,7 @@ public class FingerprintManager {

        @Override // binder call
        public void onAuthenticationFailed(long deviceId) {
            mHandler.obtainMessage(MSG_AUTHENTICATION_FAILED).sendToTarget();;
            mHandler.obtainMessage(MSG_AUTHENTICATION_FAILED).sendToTarget();
        }

        @Override // binder call
+150 −4
Original line number Diff line number Diff line
@@ -30,11 +30,17 @@ import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.view.autofill.AutoFillId;
import android.view.autofill.Dataset;
import android.view.autofill.FillResponse;

import com.android.internal.os.HandlerCaller;
import com.android.internal.os.SomeArgs;

import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;

//TODO(b/33197203): improve javadoc (of both class and methods); in particular, make sure the
//life-cycle (and how state could be maintained on server-side) is well documented.

@@ -48,6 +54,9 @@ public abstract class AutoFillService extends Service {
    private static final String TAG = "AutoFillService";
    static final boolean DEBUG = true; // TODO(b/33197203): set to false once stable

    // TODO(b/33197203): check for device's memory size instead of DEBUG?
    static final boolean DEBUG_PENDING_CALLBACKS = DEBUG;

    /**
     * The {@link Intent} that must be declared as handled by the service.
     * To be supported, the service must also require the
@@ -73,6 +82,7 @@ public abstract class AutoFillService extends Service {
    // Internal bundle keys.
    /** @hide */ public static final String KEY_CALLBACK = "callback";
    /** @hide */ public static final String KEY_SAVABLE_IDS = "savable_ids";
    /** @hide */ public static final String EXTRA_CRYPTO_OBJECT_ID = "crypto_object_id";

    // Prefix for public bundle keys.
    private static final String KEY_PREFIX = "android.service.autofill.extra.";
@@ -93,10 +103,32 @@ public abstract class AutoFillService extends Service {
     */
    public static final String EXTRA_DATASET_EXTRAS = KEY_PREFIX + "DATASET_EXTRAS";

    /**
     * Used to indicate the user selected an action that requires authentication.
     */
    public static final int FLAG_AUTHENTICATION_REQUESTED = 1 << 0;

    /**
     * Used to indicate the user authentication succeeded.
     */
    public static final int FLAG_AUTHENTICATION_SUCCESS = 1 << 1;

    /**
     * Used to indicate the user authentication failed.
     */
    public static final int FLAG_AUTHENTICATION_ERROR = 1 << 2;

    /**
     * Used when the service requested Fingerprint authentication but such option is not available.
     */
    public static final int FLAG_FINGERPRINT_AUTHENTICATION_NOT_AVAILABLE  = 1 << 3;

    // Handler messages.
    private static final int MSG_CONNECT = 1;
    private static final int MSG_AUTO_FILL_ACTIVITY = 2;
    private static final int MSG_DISCONNECT = 3;
    private static final int MSG_DISCONNECT = 2;
    private static final int MSG_AUTO_FILL_ACTIVITY = 3;
    private static final int MSG_AUTHENTICATE_FILL_RESPONSE = 4;
    private static final int MSG_AUTHENTICATE_DATASET = 5;

    private final IAutoFillService mInterface = new IAutoFillService.Stub() {

@@ -108,6 +140,22 @@ public abstract class AutoFillService extends Service {
                    .sendToTarget();
        }

        @Override
        public void authenticateFillResponse(Bundle extras, int flags) {
            final Message msg = mHandlerCaller.obtainMessage(MSG_AUTHENTICATE_FILL_RESPONSE);
            msg.arg1 = flags;
            msg.obj = extras;
            mHandlerCaller.sendMessage(msg);
        }

        @Override
        public void authenticateDataset(Bundle extras, int flags) {
            final Message msg = mHandlerCaller.obtainMessage(MSG_AUTHENTICATE_DATASET);
            msg.arg1 = flags;
            msg.obj = extras;
            mHandlerCaller.sendMessage(msg);
        }

        @Override
        public void onConnected() {
            mHandlerCaller.sendMessage(mHandlerCaller.obtainMessage(MSG_CONNECT));
@@ -135,6 +183,16 @@ public abstract class AutoFillService extends Service {
                    final IAutoFillServerCallback callback = (IAutoFillServerCallback) args.arg3;
                    requestAutoFill(callback, structure, extras, flags);
                    break;
                } case MSG_AUTHENTICATE_FILL_RESPONSE: {
                    final int flags = msg.arg1;
                    final Bundle extras = (Bundle) msg.obj;
                    onFillResponseAuthenticationRequest(extras, flags);
                    break;
                } case MSG_AUTHENTICATE_DATASET: {
                    final int flags = msg.arg1;
                    final Bundle extras = (Bundle) msg.obj;
                    onDatasetAuthenticationRequest(extras, flags);
                    break;
                } case MSG_DISCONNECT: {
                    onDisconnected();
                    break;
@@ -147,6 +205,10 @@ public abstract class AutoFillService extends Service {

    private HandlerCaller mHandlerCaller;

    // User for debugging purposes
    private final List<CallbackHelper.Dumpable> mPendingCallbacks =
            DEBUG_PENDING_CALLBACKS ? new ArrayList<>() : null;

    /**
     * {@inheritDoc}
     *
@@ -211,16 +273,84 @@ public abstract class AutoFillService extends Service {
    public abstract void onSaveRequest(AssistStructure structure,
            Bundle data, CancellationSignal cancellationSignal, SaveCallback callback);

    /**
     * Called as result of the user action for a {@link FillResponse} that required authentication.
     *
     * <p>When the {@link FillResponse} required authentication through
     * {@link android.view.autofill.FillResponse.Builder#requiresCustomAuthentication(Bundle, int)}, this
     * call indicates the user is requesting the service to authenticate him/her (and {@code flags}
     * contains {@link #FLAG_AUTHENTICATION_REQUESTED}), and {@code extras} contains the
     * {@link Bundle} passed to that method.
     *
     * <p>When the {@link FillResponse} required authentication through
     * {@link android.view.autofill.FillResponse.Builder#requiresFingerprintAuthentication(
     * android.hardware.fingerprint.FingerprintManager.CryptoObject, Bundle, int)},
     * {@code flags} this call contains the result of the fingerprint authentication (such as
     * {@link #FLAG_AUTHENTICATION_SUCCESS}, {@link #FLAG_AUTHENTICATION_ERROR}, and
     * {@link #FLAG_FINGERPRINT_AUTHENTICATION_NOT_AVAILABLE}) and {@code extras} contains the
     * {@link Bundle} passed to that method.
     */
    public void onFillResponseAuthenticationRequest(@SuppressWarnings("unused") Bundle extras,
            int flags) {
        if (DEBUG) Log.d(TAG, "onFillResponseAuthenticationRequest(): flags=" + flags);
    }

    /**
     * Called as result of the user action for a {@link Dataset} that required authentication.
     *
     * <p>When the {@link Dataset} required authentication through
     * {@link android.view.autofill.Dataset.Builder#requiresCustomAuthentication(Bundle, int)}, this
     * call indicates the user is requesting the service to authenticate him/her (and {@code flags}
     * contains {@link #FLAG_AUTHENTICATION_REQUESTED}), and {@code extras} contains the
     * {@link Bundle} passed to that method.
     *
     * <p>When the {@link Dataset} required authentication through
     * {@link android.view.autofill.Dataset.Builder#requiresFingerprintAuthentication(
     * android.hardware.fingerprint.FingerprintManager.CryptoObject, Bundle, int)},
     * {@code flags} this call contains the result of the fingerprint authentication (such as
     * {@link #FLAG_AUTHENTICATION_SUCCESS}, {@link #FLAG_AUTHENTICATION_ERROR}, and
     * {@link #FLAG_FINGERPRINT_AUTHENTICATION_NOT_AVAILABLE}) and {@code extras} contains the
     * {@link Bundle} passed to that method.
     */
    public void onDatasetAuthenticationRequest(@SuppressWarnings("unused") Bundle extras,
            int flags) {
        if (DEBUG) Log.d(TAG, "onDatasetAuthenticationRequest(): flags=" + flags);
    }

    // TODO(b/33197203): make it final and create another method classes could extend so it's
    // guaranteed to dump the pending callbacks?
    @Override
    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
        if (mPendingCallbacks != null) {
            pw.print("Number of pending callbacks: "); pw.println(mPendingCallbacks.size());
            final String prefix = "  ";
            for (int i = 0; i < mPendingCallbacks.size(); i++) {
                final CallbackHelper.Dumpable cb = mPendingCallbacks.get(i);
                pw.print('#'); pw.print(i + 1); pw.println(':');
                cb.dump(prefix, pw);
            }
            pw.println();
        } else {
            pw.println("Dumping disabled");
        }
    }

    private void requestAutoFill(IAutoFillServerCallback callback, AssistStructure structure,
            Bundle data, int flags) {
        switch (flags) {
            case AUTO_FILL_FLAG_TYPE_FILL:
                final FillCallback fillCallback = new FillCallback(callback);
                if (DEBUG_PENDING_CALLBACKS) {
                    addPendingCallback(fillCallback);
                }
                // TODO(b/33197203): hook up the cancelationSignal
                onFillRequest(structure, data, new CancellationSignal(), fillCallback);
                break;
            case AUTO_FILL_FLAG_TYPE_SAVE:
                final SaveCallback saveCallback = new SaveCallback(callback);
                if (DEBUG_PENDING_CALLBACKS) {
                    addPendingCallback(saveCallback);
                }
                // TODO(b/33197203): hook up the cancelationSignal
                onSaveRequest(structure, data, new CancellationSignal(), saveCallback);
                break;
@@ -229,6 +359,22 @@ public abstract class AutoFillService extends Service {
        }
    }

    private void addPendingCallback(CallbackHelper.Dumpable callback) {
        if (mPendingCallbacks == null) {
            // Shouldn't happend since call is controlled by DEBUG_PENDING_CALLBACKS guard.
            Log.wtf(TAG, "addPendingCallback(): mPendingCallbacks not set");
            return;
        }

        if (DEBUG) Log.d(TAG, "Adding pending callback: " + callback);

        callback.setFinalizer(() -> {
            if (DEBUG) Log.d(TAG, "Removing pending callback: " + callback);
            mPendingCallbacks.remove(callback);
        });
        mPendingCallbacks.add(callback);
    }

    /**
     * Called when the Android system disconnects from the service.
     *
Loading