summaryrefslogtreecommitdiff
path: root/core/java
diff options
context:
space:
mode:
authorJan Althaus <jalt@google.com>2018-02-02 09:20:14 +0100
committerJan Althaus <jalt@google.com>2018-02-05 16:56:52 +0100
commit92c6decbb8e39f9b5ffae38528f47fcebabf7d44 (patch)
treede8686b4182870fdc4fccf7ac0a8ec31800430c5 /core/java
parentfd673f32393aed9ee20a3ffe9cf882307198811d (diff)
Logging for linkify selections
Bug: 67629726, 70246800 Test: Manually validated, ran CTS tests, and framework tests Change-Id: Icd41f1e171767bc466f47c87a6ab611185745fd4
Diffstat (limited to 'core/java')
-rw-r--r--core/java/android/view/textclassifier/logging/DefaultLogger.java30
-rw-r--r--core/java/android/view/textclassifier/logging/Logger.java21
-rw-r--r--core/java/android/view/textclassifier/logging/SelectionEvent.java21
-rw-r--r--core/java/android/widget/SelectionActionModeHelper.java21
4 files changed, 76 insertions, 17 deletions
diff --git a/core/java/android/view/textclassifier/logging/DefaultLogger.java b/core/java/android/view/textclassifier/logging/DefaultLogger.java
index 6b848351cbf6..0fd4ab9a88f5 100644
--- a/core/java/android/view/textclassifier/logging/DefaultLogger.java
+++ b/core/java/android/view/textclassifier/logging/DefaultLogger.java
@@ -79,7 +79,7 @@ public final class DefaultLogger extends Logger {
Preconditions.checkNotNull(event);
final LogMaker log = new LogMaker(MetricsEvent.TEXT_SELECTION_SESSION)
.setType(getLogType(event))
- .setSubtype(MetricsEvent.TEXT_SELECTION_INVOCATION_MANUAL)
+ .setSubtype(getLogSubType(event))
.setPackageName(event.getPackageName())
.addTaggedData(START_EVENT_DELTA, event.getDurationSinceSessionStart())
.addTaggedData(PREV_EVENT_DELTA, event.getDurationSincePreviousEvent())
@@ -136,6 +136,17 @@ public final class DefaultLogger extends Logger {
}
}
+ private static int getLogSubType(SelectionEvent event) {
+ switch (event.getInvocationMethod()) {
+ case SelectionEvent.INVOCATION_MANUAL:
+ return MetricsEvent.TEXT_SELECTION_INVOCATION_MANUAL;
+ case SelectionEvent.INVOCATION_LINK:
+ return MetricsEvent.TEXT_SELECTION_INVOCATION_LINK;
+ default:
+ return MetricsEvent.TEXT_SELECTION_INVOCATION_UNKNOWN;
+ }
+ }
+
private static String getLogTypeString(int logType) {
switch (logType) {
case MetricsEvent.ACTION_TEXT_SELECTION_OVERTYPE:
@@ -175,6 +186,17 @@ public final class DefaultLogger extends Logger {
}
}
+ private static String getLogSubTypeString(int logSubType) {
+ switch (logSubType) {
+ case MetricsEvent.TEXT_SELECTION_INVOCATION_MANUAL:
+ return "MANUAL";
+ case MetricsEvent.TEXT_SELECTION_INVOCATION_LINK:
+ return "LINK";
+ default:
+ return UNKNOWN;
+ }
+ }
+
private static void debugLog(LogMaker log) {
if (!DEBUG_LOG_ENABLED) return;
@@ -192,6 +214,7 @@ public final class DefaultLogger extends Logger {
final String model = Objects.toString(log.getTaggedData(MODEL_NAME), UNKNOWN);
final String entity = Objects.toString(log.getTaggedData(ENTITY_TYPE), UNKNOWN);
final String type = getLogTypeString(log.getType());
+ final String subType = getLogSubTypeString(log.getSubtype());
final int smartStart = Integer.parseInt(
Objects.toString(log.getTaggedData(SMART_START), ZERO));
final int smartEnd = Integer.parseInt(
@@ -201,8 +224,9 @@ public final class DefaultLogger extends Logger {
final int eventEnd = Integer.parseInt(
Objects.toString(log.getTaggedData(EVENT_END), ZERO));
- Log.d(LOG_TAG, String.format("%2d: %s/%s, range=%d,%d - smart_range=%d,%d (%s/%s)",
- index, type, entity, eventStart, eventEnd, smartStart, smartEnd, widget, model));
+ Log.d(LOG_TAG, String.format("%2d: %s/%s/%s, range=%d,%d - smart_range=%d,%d (%s/%s)",
+ index, type, subType, entity, eventStart, eventEnd, smartStart, smartEnd, widget,
+ model));
}
/**
diff --git a/core/java/android/view/textclassifier/logging/Logger.java b/core/java/android/view/textclassifier/logging/Logger.java
index 40e4d8ce1a77..4448b2b5b494 100644
--- a/core/java/android/view/textclassifier/logging/Logger.java
+++ b/core/java/android/view/textclassifier/logging/Logger.java
@@ -71,6 +71,7 @@ public abstract class Logger {
public static final String WIDGET_CUSTOM_UNSELECTABLE_TEXTVIEW = "nosel-customview";
public static final String WIDGET_UNKNOWN = "unknown";
+ private @SelectionEvent.InvocationMethod int mInvocationMethod;
private SelectionEvent mPrevEvent;
private SelectionEvent mSmartEvent;
private SelectionEvent mStartEvent;
@@ -124,16 +125,19 @@ public abstract class Logger {
/**
* Logs a "selection started" event.
*
+ * @param invocationMethod the way the selection was triggered
* @param start the token index of the selected token
*/
- public final void logSelectionStartedEvent(int start) {
+ public final void logSelectionStartedEvent(
+ @SelectionEvent.InvocationMethod int invocationMethod, int start) {
if (mConfig == null) {
return;
}
+ mInvocationMethod = invocationMethod;
logEvent(new SelectionEvent(
start, start + 1, SelectionEvent.EVENT_SELECTION_STARTED,
- TextClassifier.TYPE_UNKNOWN, NO_SIGNATURE, mConfig));
+ TextClassifier.TYPE_UNKNOWN, mInvocationMethod, NO_SIGNATURE, mConfig));
}
/**
@@ -152,7 +156,7 @@ public abstract class Logger {
logEvent(new SelectionEvent(
start, end, SelectionEvent.EVENT_SELECTION_MODIFIED,
- TextClassifier.TYPE_UNKNOWN, NO_SIGNATURE, mConfig));
+ TextClassifier.TYPE_UNKNOWN, mInvocationMethod, NO_SIGNATURE, mConfig));
}
/**
@@ -179,7 +183,7 @@ public abstract class Logger {
final String signature = classification.getSignature();
logEvent(new SelectionEvent(
start, end, SelectionEvent.EVENT_SELECTION_MODIFIED,
- entityType, signature, mConfig));
+ entityType, mInvocationMethod, signature, mConfig));
}
/**
@@ -213,7 +217,8 @@ public abstract class Logger {
? selection.getEntity(0)
: TextClassifier.TYPE_UNKNOWN;
final String signature = selection.getSignature();
- logEvent(new SelectionEvent(start, end, eventType, entityType, signature, mConfig));
+ logEvent(new SelectionEvent(start, end, eventType, entityType, mInvocationMethod, signature,
+ mConfig));
}
/**
@@ -234,7 +239,8 @@ public abstract class Logger {
}
logEvent(new SelectionEvent(
- start, end, actionType, TextClassifier.TYPE_UNKNOWN, NO_SIGNATURE, mConfig));
+ start, end, actionType, TextClassifier.TYPE_UNKNOWN, mInvocationMethod,
+ NO_SIGNATURE, mConfig));
}
/**
@@ -265,7 +271,8 @@ public abstract class Logger {
? classification.getEntity(0)
: TextClassifier.TYPE_UNKNOWN;
final String signature = classification.getSignature();
- logEvent(new SelectionEvent(start, end, actionType, entityType, signature, mConfig));
+ logEvent(new SelectionEvent(start, end, actionType, entityType, mInvocationMethod,
+ signature, mConfig));
}
private void logEvent(@NonNull SelectionEvent event) {
diff --git a/core/java/android/view/textclassifier/logging/SelectionEvent.java b/core/java/android/view/textclassifier/logging/SelectionEvent.java
index f40b65571142..a8de3088d8cc 100644
--- a/core/java/android/view/textclassifier/logging/SelectionEvent.java
+++ b/core/java/android/view/textclassifier/logging/SelectionEvent.java
@@ -98,6 +98,16 @@ public final class SelectionEvent {
/** Something else other than User or the default TextClassifier triggered a selection. */
public static final int EVENT_AUTO_SELECTION = 5;
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({INVOCATION_MANUAL, INVOCATION_LINK})
+ public @interface InvocationMethod {}
+
+ /** Selection was invoked by the user long pressing, double tapping, or dragging to select. */
+ public static final int INVOCATION_MANUAL = 1;
+ /** Selection was invoked by the user tapping on a link. */
+ public static final int INVOCATION_LINK = 2;
+
private final int mAbsoluteStart;
private final int mAbsoluteEnd;
private final @EventType int mEventType;
@@ -105,6 +115,7 @@ public final class SelectionEvent {
@Nullable private final String mWidgetVersion;
private final String mPackageName;
private final String mWidgetType;
+ private final @InvocationMethod int mInvocationMethod;
// These fields should only be set by creator of a SelectionEvent.
private String mSignature;
@@ -121,7 +132,7 @@ public final class SelectionEvent {
SelectionEvent(
int start, int end,
@EventType int eventType, @EntityType String entityType,
- String signature, Logger.Config config) {
+ @InvocationMethod int invocationMethod, String signature, Logger.Config config) {
Preconditions.checkArgument(end >= start, "end cannot be less than start");
mAbsoluteStart = start;
mAbsoluteEnd = end;
@@ -132,6 +143,7 @@ public final class SelectionEvent {
mWidgetVersion = config.getWidgetVersion();
mPackageName = Preconditions.checkNotNull(config.getPackageName());
mWidgetType = Preconditions.checkNotNull(config.getWidgetType());
+ mInvocationMethod = invocationMethod;
}
int getAbsoluteStart() {
@@ -180,6 +192,13 @@ public final class SelectionEvent {
}
/**
+ * Returns the way the selection mode was invoked.
+ */
+ public @InvocationMethod int getInvocationMethod() {
+ return mInvocationMethod;
+ }
+
+ /**
* Returns the signature of the text classifier result associated with this event.
*/
public String getSignature() {
diff --git a/core/java/android/widget/SelectionActionModeHelper.java b/core/java/android/widget/SelectionActionModeHelper.java
index 2e354c1eee1f..9ff5f5910677 100644
--- a/core/java/android/widget/SelectionActionModeHelper.java
+++ b/core/java/android/widget/SelectionActionModeHelper.java
@@ -111,7 +111,8 @@ public final class SelectionActionModeHelper {
mSelectionTracker.onOriginalSelection(
getText(mTextView),
mTextView.getSelectionStart(),
- mTextView.getSelectionEnd());
+ mTextView.getSelectionEnd(),
+ false /*isLink*/);
cancelAsyncTask();
if (skipTextClassification()) {
startSelectionActionMode(null);
@@ -134,7 +135,11 @@ public final class SelectionActionModeHelper {
* Starts Link ActionMode.
*/
public void startLinkActionModeAsync(TextLinks.TextLink textLink) {
- //TODO: tracking/logging
+ mSelectionTracker.onOriginalSelection(
+ getText(mTextView),
+ mTextView.getSelectionStart(),
+ mTextView.getSelectionEnd(),
+ true /*isLink*/);
cancelAsyncTask();
if (skipTextClassification()) {
startLinkActionMode(null);
@@ -483,7 +488,8 @@ public final class SelectionActionModeHelper {
/**
* Called when the original selection happens, before smart selection is triggered.
*/
- public void onOriginalSelection(CharSequence text, int selectionStart, int selectionEnd) {
+ public void onOriginalSelection(
+ CharSequence text, int selectionStart, int selectionEnd, boolean isLink) {
// If we abandoned a selection and created a new one very shortly after, we may still
// have a pending request to log ABANDON, which we flush here.
mDelayedLogAbandon.flush();
@@ -492,7 +498,8 @@ public final class SelectionActionModeHelper {
mOriginalEnd = mSelectionEnd = selectionEnd;
mAllowReset = false;
maybeInvalidateLogger();
- mLogger.logSelectionStarted(text, selectionStart);
+ mLogger.logSelectionStarted(text, selectionStart,
+ isLink ? SelectionEvent.INVOCATION_LINK : SelectionEvent.INVOCATION_MANUAL);
}
/**
@@ -675,7 +682,9 @@ public final class SelectionActionModeHelper {
return Logger.WIDGET_UNSELECTABLE_TEXTVIEW;
}
- public void logSelectionStarted(CharSequence text, int index) {
+ public void logSelectionStarted(
+ CharSequence text, int index,
+ @SelectionEvent.InvocationMethod int invocationMethod) {
try {
Preconditions.checkNotNull(text);
Preconditions.checkArgumentInRange(index, 0, text.length(), "index");
@@ -684,7 +693,7 @@ public final class SelectionActionModeHelper {
}
mTokenIterator.setText(mText);
mStartIndex = index;
- mLogger.logSelectionStartedEvent(0);
+ mLogger.logSelectionStartedEvent(invocationMethod, 0);
} catch (Exception e) {
// Avoid crashes due to logging.
Log.d(LOG_TAG, e.getMessage());