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

Commit 81cfa1f9 authored by Reema Bajwa's avatar Reema Bajwa
Browse files

Use the credential req & callback set on view

Test: Deployed & tested locally
Bug: 326315532

Change-Id: Ic7f3a1432af1db61c23d1343c4ed80fbe7e288c7
parent 3419b5ef
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -913,6 +913,7 @@ public class AssistStructure implements Parcelable {
            if ((flags&FLAGS_HAS_EXTRAS) != 0) {
                mExtras = in.readBundle();
            }
            mGetCredentialRequest = in.readTypedObject(GetCredentialRequest.CREATOR);
        }

        /**
@@ -1149,6 +1150,7 @@ public class AssistStructure implements Parcelable {
            if ((flags&FLAGS_HAS_EXTRAS) != 0) {
                out.writeBundle(mExtras);
            }
            out.writeTypedObject(mGetCredentialRequest, flags);
            return flags;
        }

+11 −1
Original line number Diff line number Diff line
@@ -7034,7 +7034,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
            @NonNull OutcomeReceiver<GetCredentialResponse, GetCredentialException> callback) {
        Preconditions.checkNotNull(request, "request must not be null");
        Preconditions.checkNotNull(callback, "request must not be null");
        mViewCredentialHandler = new ViewCredentialHandler(request, callback);
    }
@@ -9914,6 +9913,17 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
        }
    }
    /**
     * @hide
     */
    public void onGetCredentialResponse(GetCredentialResponse response) {
        if (getCredentialManagerCallback() == null) {
            Log.w(AUTOFILL_LOG_TAG, "onGetCredentialResponse called but no callback found");
            return;
        }
        getCredentialManagerCallback().onResult(response);
    }
    /**
     * Gets the unique, logical identifier of this view in the activity, for autofill purposes.
     *
+74 −13
Original line number Diff line number Diff line
@@ -50,6 +50,7 @@ import android.content.Intent;
import android.content.IntentSender;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.credentials.GetCredentialResponse;
import android.graphics.Rect;
import android.metrics.LogMaker;
import android.os.Build;
@@ -2925,6 +2926,65 @@ public final class AutofillManager {
        }
    }

    private void onGetCredentialResponse(int sessionId, AutofillId id,
            GetCredentialResponse response) {
        synchronized (mLock) {
            if (sessionId != mSessionId) {
                Log.w(TAG, "onGetCredentialResponse afm sessionIds don't match");
                return;
            }

            final AutofillClient client = getClient();
            if (client == null) {
                Log.w(TAG, "onGetCredentialResponse afm client id null");
                return;
            }
            ArrayList<AutofillId> failedIds = new ArrayList<>();
            final View[] views = client.autofillClientFindViewsByAutofillIdTraversal(
                    Helper.toArray(new ArrayList<>(Collections.singleton(id))));
            if (views == null || views.length == 0) {
                Log.w(TAG, "onGetCredentialResponse afm client view not found");
                return;
            }

            final View view = views[0];
            if (view == null) {
                Log.i(TAG, "onGetCredentialResponse View is null");

                // Most likely view has been removed after the initial request was sent to the
                // the service; this is fine, but we need to update the view status in the
                // server side so it can be triggered again.
                Log.d(TAG, "onGetCredentialResponse(): no View with id " + id);
                failedIds.add(id);
            }
            if (id.isVirtualInt()) {
                Log.i(TAG, "onGetCredentialResponse afm client id is virtual");
                // TODO(b/326314286): Handle virtual views
            } else {
                Log.i(TAG, "onGetCredentialResponse afm client id is NOT virtual");
                view.onGetCredentialResponse(response);
            }
            handleFailedIdsLocked(failedIds);
        }
    }

    @GuardedBy("mLock")
    private void handleFailedIdsLocked(ArrayList<AutofillId> failedIds) {
        if (failedIds != null && !failedIds.isEmpty()) {
            if (sVerbose) {
                Log.v(TAG, "autofill(): total failed views: " + failedIds);
            }
            try {
                mService.setAutofillFailure(mSessionId, failedIds, mContext.getUserId());
            } catch (RemoteException e) {
                // In theory, we could ignore this error since it's not a big deal, but
                // in reality, we rather crash the app anyways, as the failure could be
                // a consequence of something going wrong on the server side...
                throw e.rethrowFromSystemServer();
            }
        }
    }

    private void autofill(int sessionId, List<AutofillId> ids, List<AutofillValue> values,
            boolean hideHighlight) {
        synchronized (mLock) {
@@ -2991,19 +3051,7 @@ public final class AutofillManager {
                }
            }

            if (failedIds != null) {
                if (sVerbose) {
                    Log.v(TAG, "autofill(): total failed views: " + failedIds);
                }
                try {
                    mService.setAutofillFailure(mSessionId, failedIds, mContext.getUserId());
                } catch (RemoteException e) {
                    // In theory, we could ignore this error since it's not a big deal, but
                    // in reality, we rather crash the app anyways, as the failure could be
                    // a consequence of something going wrong on the server side...
                    throw e.rethrowFromSystemServer();
                }
            }
            handleFailedIdsLocked(failedIds);

            if (virtualValues != null) {
                for (int i = 0; i < virtualValues.size(); i++) {
@@ -3431,6 +3479,10 @@ public final class AutofillManager {
        if (view == null) {
            return false;
        }
        if (view.getViewCredentialHandler() != null) {
            return true;
        }

        String[] hints = view.getAutofillHints();
        if (hints == null) {
            return false;
@@ -4320,6 +4372,15 @@ public final class AutofillManager {
            }
        }

        @Override
        public void onGetCredentialResponse(int sessionId, AutofillId id,
                GetCredentialResponse response) {
            final AutofillManager afm = mAfm.get();
            if (afm != null) {
                afm.post(() -> afm.onGetCredentialResponse(sessionId, id, response));
            }
        }

        @Override
        public void autofillContent(int sessionId, AutofillId id, ClipData content) {
            final AutofillManager afm = mAfm.get();
+4 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import android.content.ClipData;
import android.content.ComponentName;
import android.content.Intent;
import android.content.IntentSender;
import android.credentials.GetCredentialResponse;
import android.graphics.Rect;
import android.os.IBinder;
import android.view.autofill.AutofillId;
@@ -48,6 +49,9 @@ oneway interface IAutoFillManagerClient {
    void autofill(int sessionId, in List<AutofillId> ids, in List<AutofillValue> values,
            boolean hideHighlight);

     void onGetCredentialResponse(int sessionId, in AutofillId id,
                 in GetCredentialResponse response);

    /**
     * Autofills the activity with rich content data (e.g. an image) from a dataset.
     */
+6 −2
Original line number Diff line number Diff line
@@ -607,10 +607,14 @@ class CredentialAutofillService : AutofillService() {
            autofillId: AutofillId,
            responseClientState: Bundle
    ): MutableList<CredentialOption> {
        if (viewNode.credentialManagerRequest != null &&
                viewNode.credentialManagerCallback != null) {
        if (viewNode.credentialManagerRequest != null) {
            val options = viewNode.credentialManagerRequest?.getCredentialOptions()
            if (options != null) {
                for (option in options) {
                    option.candidateQueryData.putParcelable(
                            CredentialProviderService.EXTRA_AUTOFILL_ID, autofillId
                    )
                }
                return options
            }
        }
Loading