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

Commit b53afba8 authored by Felipe Leme's avatar Felipe Leme
Browse files

ContentCapture: new API to notify virtual views deletion on batch.

Test: atest CtsContentCaptureServiceTestCases:LoginActivityTest#testVirtualView_batchDisappear
Bug: 121050915

Change-Id: Ia5fc6b88819866142b883d58ab936b6a38b3288b
parent 3a1d61d7
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -52671,6 +52671,7 @@ package android.view.contentcapture {
    method public final void notifyViewAppeared(android.view.ViewStructure);
    method public final void notifyViewDisappeared(android.view.autofill.AutofillId);
    method public final void notifyViewTextChanged(android.view.autofill.AutofillId, java.lang.CharSequence, int);
    method public final void notifyViewsDisappeared(android.view.autofill.AutofillId, int[]);
    field public static final int FLAG_USER_INPUT = 1; // 0x1
  }
+1 −0
Original line number Diff line number Diff line
@@ -92,6 +92,7 @@ final class ChildContentCaptureSession extends ContentCaptureSession {
            int flags) {
        getMainCaptureSession().notifyViewTextChanged(mId, id, text, flags);
    }

    @Override
    boolean isContentCaptureEnabled() {
        return getMainCaptureSession().isContentCaptureEnabled();
+26 −0
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ import android.view.contentcapture.ViewNode.ViewStructureImpl;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.Preconditions;

import dalvik.system.CloseGuard;
@@ -344,6 +345,31 @@ public abstract class ContentCaptureSession implements AutoCloseable {

    abstract void internalNotifyViewDisappeared(@NonNull AutofillId id);

    /**
     * Notifies the Content Capture Service that many nodes has been removed from a virtual view
     * structure.
     *
     * <p>Should only be called by views that handle their own virtual view hierarchy.
     *
     * @param hostId id of the view hosting the virtual hierarchy.
     * @param virtualIds ids of the virtual children.
     *
     * @throws IllegalArgumentException if the {@code hostId} is an autofill id for a virtual view.
     * @throws IllegalArgumentException if {@code virtualIds} is empty
     */
    public final void notifyViewsDisappeared(@NonNull AutofillId hostId,
            @NonNull int[] virtualIds) {
        Preconditions.checkArgument(!hostId.isVirtual(), "parent cannot be virtual");
        Preconditions.checkArgument(!ArrayUtils.isEmpty(virtualIds), "virtual ids cannot be empty");
        if (!isContentCaptureEnabled()) return;

        // TODO(b/121050915): create a new VIEWS_DISAPPEARED event type, which could also be used
        // to batch delete non-virtual views
        for (int id : virtualIds) {
            internalNotifyViewDisappeared(new AutofillId(hostId, id, getIdAsInt()));
        }
    }

    /**
     * Notifies the Intelligence Service that the value of a text node has been changed.
     *
+16 −0
Original line number Diff line number Diff line
@@ -97,6 +97,22 @@ public class ContentCaptureSessionTest {
        assertThat(structure.getAutofillId()).isEqualTo(childId);
    }

    @Test
    public void testNotifyViewsDisappeared_invalid() {
        // Null parent
        assertThrows(NullPointerException.class,
                () -> mSession1.notifyViewsDisappeared(null, new int[] {42}));
        // Null child
        assertThrows(IllegalArgumentException.class,
                () -> mSession1.notifyViewsDisappeared(new AutofillId(42), null));
        // Empty child
        assertThrows(IllegalArgumentException.class,
                () -> mSession1.notifyViewsDisappeared(new AutofillId(42), new int[] {}));
        // Virtual parent
        assertThrows(IllegalArgumentException.class,
                () -> mSession1.notifyViewsDisappeared(new AutofillId(42, 108), new int[] {666}));
    }

    // Cannot use @Spy because we need to pass the session id on constructor
    private class MyContentCaptureSession extends ContentCaptureSession {