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

Commit 0ce4719f authored by Adam He's avatar Adam He
Browse files

Added ContentCaptureEvent.mergeEvent() method for merging

view_text_changed and view_disappeared events.

Fixes: 124107816
Test: atest CtsContentCaptureServiceTestCases
Test: atest FrameworksCoreTests:android.view.contentcapture.ContentCaptureEventTest
Change-Id: I256906eafc7ecb43e9de5c24cec3a0c7e642eab2
parent 463b5d19
Loading
Loading
Loading
Loading
+41 −0
Original line number Diff line number Diff line
@@ -303,6 +303,47 @@ public final class ContentCaptureEvent implements Parcelable {
        return mText;
    }

    /**
     * Merges event of the same type, either {@link #TYPE_VIEW_TEXT_CHANGED}
     * or {@link #TYPE_VIEW_DISAPPEARED}.
     *
     * @hide
     */
    public void mergeEvent(@NonNull ContentCaptureEvent event) {
        Preconditions.checkNotNull(event);
        final int eventType = event.getType();
        if (mType != eventType) {
            Log.e(TAG, "mergeEvent(" + getTypeAsString(eventType) + ") cannot be merged "
                    + "with different eventType=" + getTypeAsString(mType));
            return;
        }

        if (eventType == TYPE_VIEW_DISAPPEARED) {
            final List<AutofillId> ids = event.getIds();
            final AutofillId id = event.getId();
            if (ids != null) {
                if (id != null) {
                    Log.w(TAG, "got TYPE_VIEW_DISAPPEARED event with both id and ids: " + event);
                }
                for (int i = 0; i < ids.size(); i++) {
                    addAutofillId(ids.get(i));
                }
                return;
            }
            if (id != null) {
                addAutofillId(id);
                return;
            }
            throw new IllegalArgumentException("mergeEvent(): got "
                    + "TYPE_VIEW_DISAPPEARED event with neither id or ids: " + event);
        } else if (eventType == TYPE_VIEW_TEXT_CHANGED) {
            setText(event.getText());
        } else {
            Log.e(TAG, "mergeEvent(" + getTypeAsString(eventType)
                    + ") does not support this event type.");
        }
    }

    /** @hide */
    public void dump(@NonNull PrintWriter pw) {
        pw.print("type="); pw.print(getTypeAsString(mType));
+2 −27
Original line number Diff line number Diff line
@@ -295,8 +295,7 @@ public final class MainContentCaptureSession extends ContentCaptureSession {
                    Log.v(TAG, "Buffering VIEW_TEXT_CHANGED event, updated text="
                            + getSanitizedString(event.getText()));
                }
                // TODO(b/124107816): should call lastEvent.merge(event) instead
                lastEvent.setText(event.getText());
                lastEvent.mergeEvent(event);
                addEvent = false;
            }
        }
@@ -309,7 +308,7 @@ public final class MainContentCaptureSession extends ContentCaptureSession {
                    Log.v(TAG, "Buffering TYPE_VIEW_DISAPPEARED events for session "
                            + lastEvent.getSessionId());
                }
                mergeViewsDisappearedEvent(lastEvent, event);
                lastEvent.mergeEvent(event);
                addEvent = false;
            }
        }
@@ -357,30 +356,6 @@ public final class MainContentCaptureSession extends ContentCaptureSession {
        flush(flushReason);
    }

    // TODO(b/124107816): should be ContentCaptureEvent Event.merge(event) instead (which would
    // replace the addAutofillId() method - we would also need unit tests on ContentCaptureEventTest
    // to check these scenarios)
    private void mergeViewsDisappearedEvent(@NonNull ContentCaptureEvent lastEvent,
            @NonNull ContentCaptureEvent event) {
        final List<AutofillId> ids = event.getIds();
        final AutofillId id = event.getId();
        if (ids != null) {
            if (id != null) {
                Log.w(TAG, "got TYPE_VIEW_DISAPPEARED event with both id and ids: " + event);
            }
            for (int i = 0; i < ids.size(); i++) {
                lastEvent.addAutofillId(ids.get(i));
            }
            return;
        }
        if (id != null) {
            lastEvent.addAutofillId(id);
            return;
        }
        throw new IllegalArgumentException(
                "got TYPE_VIEW_DISAPPEARED event with neither id or ids: " + event);
    }

    @UiThread
    private boolean hasStarted() {
        return mState != UNKNOWN_STATE;
+63 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ import static android.view.contentcapture.ContentCaptureEvent.TYPE_CONTEXT_UPDAT
import static android.view.contentcapture.ContentCaptureEvent.TYPE_SESSION_FINISHED;
import static android.view.contentcapture.ContentCaptureEvent.TYPE_SESSION_STARTED;
import static android.view.contentcapture.ContentCaptureEvent.TYPE_VIEW_DISAPPEARED;
import static android.view.contentcapture.ContentCaptureEvent.TYPE_VIEW_TEXT_CHANGED;

import static com.google.common.truth.Truth.assertThat;

@@ -230,6 +231,68 @@ public class ContentCaptureEventTest {
        assertContextUpdatedEvent(clone);
    }

    @Test
    public void testMergeEvent_typeViewTextChanged() {
        final ContentCaptureEvent event = new ContentCaptureEvent("42", TYPE_VIEW_TEXT_CHANGED)
                .setText("test");
        final ContentCaptureEvent event2 = new ContentCaptureEvent("43", TYPE_VIEW_TEXT_CHANGED)
                .setText("empty");

        event.mergeEvent(event2);
        assertThat(event.getText()).isEqualTo(event2.getText());
    }

    @Test
    public void testMergeEvent_typeViewDisappeared() {
        final ContentCaptureEvent event = new ContentCaptureEvent("42", TYPE_VIEW_DISAPPEARED)
                .setAutofillId(new AutofillId(1));
        final ContentCaptureEvent event2 = new ContentCaptureEvent("43", TYPE_VIEW_DISAPPEARED)
                .setAutofillId(new AutofillId(2));
        final ArrayList<AutofillId> autofillIds = new ArrayList<>();
        autofillIds.add(new AutofillId(3));
        autofillIds.add(new AutofillId(4));
        final ContentCaptureEvent event3 = new ContentCaptureEvent("17", TYPE_VIEW_DISAPPEARED)
                .setAutofillIds(autofillIds);

        event.mergeEvent(event2);
        assertThat(event.getIds()).containsExactly(new AutofillId(1), new AutofillId(2));

        event2.mergeEvent(event3);
        assertThat(event2.getIds()).containsExactly(new AutofillId(2), new AutofillId(3),
                new AutofillId(4));
    }

    @Test
    public void testMergeEvent_typeViewDisappeared_noIds() {
        final ContentCaptureEvent event = new ContentCaptureEvent("42", TYPE_VIEW_DISAPPEARED)
                .setAutofillId(new AutofillId(1));
        final ContentCaptureEvent event2 = new ContentCaptureEvent("43", TYPE_VIEW_DISAPPEARED);

        assertThrows(IllegalArgumentException.class, () -> event.mergeEvent(event2));
    }

    @Test
    public void testMergeEvent_nullArgument() {
        final ContentCaptureEvent event = new ContentCaptureEvent("42", TYPE_VIEW_DISAPPEARED);
        assertThrows(NullPointerException.class, () -> event.mergeEvent(null));
    }

    @Test
    public void testMergeEvent_differentEventTypes() {
        final ContentCaptureEvent event = new ContentCaptureEvent("42", TYPE_VIEW_DISAPPEARED)
                .setText("test").setAutofillId(new AutofillId(1));
        final ContentCaptureEvent event2 = new ContentCaptureEvent("17", TYPE_VIEW_TEXT_CHANGED)
                .setText("empty").setAutofillId(new AutofillId(2));

        event.mergeEvent(event2);
        assertThat(event.getText()).isEqualTo("test");
        assertThat(event.getId()).isEqualTo(new AutofillId(1));

        event2.mergeEvent(event);
        assertThat(event2.getText()).isEqualTo("empty");
        assertThat(event2.getId()).isEqualTo(new AutofillId(2));
    }

    private void assertContextUpdatedEvent(ContentCaptureEvent event) {
        assertThat(event.getType()).isEqualTo(TYPE_CONTEXT_UPDATED);
        assertThat(event.getEventTime()).isAtLeast(MY_EPOCH);