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

Commit 94b56207 authored by Felipe Leme's avatar Felipe Leme
Browse files

Use an optimized findViewNodeByAutofillId(id) to get just one node.

Session was using findViewNodesByAutofillIds(ids) before, which not only was
not optimal, but error prone (for example, it could return a non-empty array
with an empty value).

Test: CtsAutoFillServiceTestCases pass
Fixes: 62532979

Change-Id: If984f1263cc3f2aac1d1e098687fe02d73c55211
parent 04298759
Loading
Loading
Loading
Loading
+28 −4
Original line number Diff line number Diff line
@@ -106,15 +106,15 @@ public final class FillContext implements Parcelable {
    }

    /**
     * Finds {@link ViewNode}s that have the requested ids.
     * Finds {@link ViewNode ViewNodes} that have the requested ids.
     *
     * @param ids The ids of the node to find
     * @param ids The ids of the node to find.
     *
     * @return The nodes indexed in the same way as the ids
     * @return The nodes indexed in the same way as the ids.
     *
     * @hide
     */
    @NonNull public ViewNode[] findViewNodesByAutofillIds(@NonNull AutofillId... ids) {
    @NonNull public ViewNode[] findViewNodesByAutofillIds(@NonNull AutofillId[] ids) {
        final LinkedList<ViewNode> nodesToProcess = new LinkedList<>();
        final ViewNode[] foundNodes = new AssistStructure.ViewNode[ids.length];

@@ -178,6 +178,30 @@ public final class FillContext implements Parcelable {
        return foundNodes;
    }

    /**
     * Finds the {@link ViewNode} that has the requested {@code id}, if any.
     *
     * @hide
     */
    @Nullable public ViewNode findViewNodeByAutofillId(@NonNull AutofillId id) {
        final LinkedList<ViewNode> nodesToProcess = new LinkedList<>();
        final int numWindowNodes = mStructure.getWindowNodeCount();
        for (int i = 0; i < numWindowNodes; i++) {
            nodesToProcess.add(mStructure.getWindowNodeAt(i).getRootViewNode());
        }
        while (!nodesToProcess.isEmpty()) {
            final ViewNode node = nodesToProcess.removeFirst();
            if (id.equals(node.getAutofillId())) {
                return node;
            }
            for (int i = 0; i < node.getChildCount(); i++) {
                nodesToProcess.addLast(node.getChildAt(i));
            }
        }

        return null;
    }

    public static final Parcelable.Creator<FillContext> CREATOR =
            new Parcelable.Creator<FillContext>() {
        @Override
+6 −6
Original line number Diff line number Diff line
@@ -255,7 +255,9 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState

            final ViewNode node = nodes[i];
            if (node == null) {
                Slog.w(TAG, "fillStructureWithAllowedValues(): no node for " + viewState.id);
                if (sVerbose) {
                    Slog.v(TAG, "fillStructureWithAllowedValues(): no node for " + viewState.id);
                }
                continue;
            }

@@ -862,11 +864,9 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
        final int numContexts = mContexts.size();
        for (int i = 0; i < numContexts; i++) {
            final FillContext context = mContexts.get(i);
            // TODO: create a function that gets just one node so it doesn't create an array
            // unnecessarily
            final ViewNode[] nodes = context.findViewNodesByAutofillIds(id);
            if (nodes != null) {
                AutofillValue candidate = nodes[0].getAutofillValue();
            final ViewNode node = context.findViewNodeByAutofillId(id);
            if (node != null) {
                final AutofillValue candidate = node.getAutofillValue();
                if (sDebug) {
                    Slog.d(TAG, "getValueFromContexts(" + id + ") at " + i + ": " + candidate);
                }