TC: Ensure ABANDON event has an entity type.
Fixes: 80168739
Test: atest android.view.textclassifier
atest android.widget.TextViewActivityTest
Change-Id: I6af99afcfcfd44960b538e45a2da91eb3f09a94f
diff --git a/core/java/android/view/textclassifier/SelectionEvent.java b/core/java/android/view/textclassifier/SelectionEvent.java
index 9ae0c65..374e667 100644
--- a/core/java/android/view/textclassifier/SelectionEvent.java
+++ b/core/java/android/view/textclassifier/SelectionEvent.java
@@ -120,8 +120,8 @@
private final int mAbsoluteStart;
private final int mAbsoluteEnd;
- private final @EntityType String mEntityType;
+ private @EntityType String mEntityType;
private @EventType int mEventType;
private String mPackageName = "";
private String mWidgetType = TextClassifier.WIDGET_TYPE_UNKNOWN;
@@ -392,6 +392,10 @@
return mEntityType;
}
+ void setEntityType(@EntityType String entityType) {
+ mEntityType = Preconditions.checkNotNull(entityType);
+ }
+
/**
* Returns the package name of the app that this event originated in.
*/
diff --git a/core/java/android/view/textclassifier/TextClassificationSession.java b/core/java/android/view/textclassifier/TextClassificationSession.java
index db0202a..cd2806a 100644
--- a/core/java/android/view/textclassifier/TextClassificationSession.java
+++ b/core/java/android/view/textclassifier/TextClassificationSession.java
@@ -163,6 +163,11 @@
case SelectionEvent.EVENT_AUTO_SELECTION:
mSmartEvent = event;
break;
+ case SelectionEvent.ACTION_ABANDON:
+ if (mPrevEvent != null) {
+ event.setEntityType(mPrevEvent.getEntityType());
+ }
+ break;
case SelectionEvent.EVENT_SELECTION_MODIFIED:
if (mPrevEvent != null
&& mPrevEvent.getAbsoluteStart() == event.getAbsoluteStart()
diff --git a/core/tests/coretests/src/android/widget/TextViewActivityTest.java b/core/tests/coretests/src/android/widget/TextViewActivityTest.java
index 267a9c8..c3ef1c8 100644
--- a/core/tests/coretests/src/android/widget/TextViewActivityTest.java
+++ b/core/tests/coretests/src/android/widget/TextViewActivityTest.java
@@ -76,6 +76,7 @@
import android.view.textclassifier.TextClassifier;
import android.view.textclassifier.TextLinks;
import android.view.textclassifier.TextLinksParams;
+import android.view.textclassifier.TextSelection;
import android.widget.espresso.CustomViewActions.RelativeCoordinatesProvider;
import androidx.test.InstrumentationRegistry;
@@ -1020,6 +1021,50 @@
}
@Test
+ public void testSelectionMetricsLogger_abandonEventIncludesEntityType() throws Throwable {
+ final List<SelectionEvent> selectionEvents = new ArrayList<>();
+ final TextClassifier classifier = new TextClassifier() {
+ @Override
+ public void onSelectionEvent(SelectionEvent event) {
+ selectionEvents.add(event);
+ }
+
+ @Override
+ public TextSelection suggestSelection(TextSelection.Request request) {
+ return new TextSelection.Builder(request.getStartIndex(), request.getEndIndex())
+ .setEntityType(TextClassifier.TYPE_PHONE, 1)
+ .build();
+ }
+ };
+ final TextView textView = mActivity.findViewById(R.id.textview);
+ mActivityRule.runOnUiThread(() -> textView.setTextClassifier(classifier));
+ mInstrumentation.waitForIdleSync();
+ final String text = "My number is 987654321";
+
+ onView(withId(R.id.textview)).perform(replaceText(text));
+ onView(withId(R.id.textview)).perform(longPressOnTextAtIndex(text.indexOf('9')));
+ sleepForFloatingToolbarPopup();
+ onView(withId(R.id.textview)).perform(clickOnTextAtIndex(0));
+ mInstrumentation.waitForIdleSync();
+
+ // Abandon event is logged 100ms later. See SelectionActionModeHelper.SelectionTracker
+ final long abandonDelay = 100;
+ final long pollInterval = 10;
+ long waitTime = 0;
+ SelectionEvent lastEvent;
+ do {
+ lastEvent = selectionEvents.get(selectionEvents.size() - 1);
+ if (lastEvent.getEventType() == SelectionEvent.ACTION_ABANDON) {
+ break;
+ }
+ Thread.sleep(pollInterval);
+ waitTime += pollInterval;
+ } while (waitTime < abandonDelay * 10);
+ assertEquals(SelectionEvent.ACTION_ABANDON, lastEvent.getEventType());
+ assertEquals(TextClassifier.TYPE_PHONE, lastEvent.getEntityType());
+ }
+
+ @Test
public void testPastePlainText_menuAction() {
initializeClipboardWithText(TextStyle.STYLED);